PublicAuthTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\DAV\Tests\unit\Connector;
  8. use OCA\DAV\Connector\Sabre\PublicAuth;
  9. use OCP\IRequest;
  10. use OCP\ISession;
  11. use OCP\Security\Bruteforce\IThrottler;
  12. use OCP\Share\Exceptions\ShareNotFound;
  13. use OCP\Share\IManager;
  14. use OCP\Share\IShare;
  15. use Psr\Log\LoggerInterface;
  16. /**
  17. * Class PublicAuthTest
  18. *
  19. * @group DB
  20. *
  21. * @package OCA\DAV\Tests\unit\Connector
  22. */
  23. class PublicAuthTest extends \Test\TestCase {
  24. /** @var ISession|MockObject */
  25. private $session;
  26. /** @var IRequest|MockObject */
  27. private $request;
  28. /** @var IManager|MockObject */
  29. private $shareManager;
  30. /** @var PublicAuth */
  31. private $auth;
  32. /** @var IThrottler|MockObject */
  33. private $throttler;
  34. /** @var LoggerInterface|MockObject */
  35. private $logger;
  36. /** @var string */
  37. private $oldUser;
  38. protected function setUp(): void {
  39. parent::setUp();
  40. $this->session = $this->createMock(ISession::class);
  41. $this->request = $this->createMock(IRequest::class);
  42. $this->shareManager = $this->createMock(IManager::class);
  43. $this->throttler = $this->createMock(IThrottler::class);
  44. $this->logger = $this->createMock(LoggerInterface::class);
  45. $this->auth = new PublicAuth(
  46. $this->request,
  47. $this->shareManager,
  48. $this->session,
  49. $this->throttler,
  50. $this->logger,
  51. );
  52. // Store current user
  53. $this->oldUser = \OC_User::getUser();
  54. }
  55. protected function tearDown(): void {
  56. \OC_User::setIncognitoMode(false);
  57. // Set old user
  58. \OC_User::setUserId($this->oldUser);
  59. \OC_Util::setupFS($this->oldUser);
  60. parent::tearDown();
  61. }
  62. public function testGetToken(): void {
  63. $this->request->method('getPathInfo')
  64. ->willReturn('/dav/files/GX9HSGQrGE');
  65. $result = $this->invokePrivate($this->auth, 'getToken');
  66. $this->assertSame('GX9HSGQrGE', $result);
  67. }
  68. public function testGetTokenInvalid(): void {
  69. $this->request->method('getPathInfo')
  70. ->willReturn('/dav/files');
  71. $this->expectException(\Sabre\DAV\Exception\NotFound::class);
  72. $this->invokePrivate($this->auth, 'getToken');
  73. }
  74. public function testCheckTokenValidShare(): void {
  75. $this->request->method('getPathInfo')
  76. ->willReturn('/dav/files/GX9HSGQrGE');
  77. $share = $this->getMockBuilder(IShare::class)
  78. ->disableOriginalConstructor()
  79. ->getMock();
  80. $share->method('getPassword')->willReturn(null);
  81. $this->shareManager->expects($this->once())
  82. ->method('getShareByToken')
  83. ->with('GX9HSGQrGE')
  84. ->willReturn($share);
  85. $result = $this->invokePrivate($this->auth, 'checkToken');
  86. $this->assertSame([true, 'principals/GX9HSGQrGE'], $result);
  87. }
  88. public function testCheckTokenInvalidShare(): void {
  89. $this->request->method('getPathInfo')
  90. ->willReturn('/dav/files/GX9HSGQrGE');
  91. $this->shareManager
  92. ->expects($this->once())
  93. ->method('getShareByToken')
  94. ->with('GX9HSGQrGE')
  95. ->will($this->throwException(new ShareNotFound()));
  96. $this->expectException(\Sabre\DAV\Exception\NotFound::class);
  97. $this->invokePrivate($this->auth, 'checkToken');
  98. }
  99. public function testCheckTokenAlreadyAuthenticated(): void {
  100. $this->request->method('getPathInfo')
  101. ->willReturn('/dav/files/GX9HSGQrGE');
  102. $share = $this->getMockBuilder(IShare::class)
  103. ->disableOriginalConstructor()
  104. ->getMock();
  105. $share->method('getShareType')->willReturn(42);
  106. $this->shareManager->expects($this->once())
  107. ->method('getShareByToken')
  108. ->with('GX9HSGQrGE')
  109. ->willReturn($share);
  110. $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
  111. $this->session->method('get')->with('public_link_authenticated')->willReturn('42');
  112. $result = $this->invokePrivate($this->auth, 'checkToken');
  113. $this->assertSame([true, 'principals/GX9HSGQrGE'], $result);
  114. }
  115. public function testCheckTokenPasswordNotAuthenticated(): void {
  116. $this->request->method('getPathInfo')
  117. ->willReturn('/dav/files/GX9HSGQrGE');
  118. $share = $this->getMockBuilder(IShare::class)
  119. ->disableOriginalConstructor()
  120. ->getMock();
  121. $share->method('getPassword')->willReturn('password');
  122. $share->method('getShareType')->willReturn(42);
  123. $this->shareManager->expects($this->once())
  124. ->method('getShareByToken')
  125. ->with('GX9HSGQrGE')
  126. ->willReturn($share);
  127. $this->session->method('exists')->with('public_link_authenticated')->willReturn(false);
  128. $this->expectException(\Sabre\DAV\Exception\NotAuthenticated::class);
  129. $this->invokePrivate($this->auth, 'checkToken');
  130. }
  131. public function testCheckTokenPasswordAuthenticatedWrongShare(): void {
  132. $this->request->method('getPathInfo')
  133. ->willReturn('/dav/files/GX9HSGQrGE');
  134. $share = $this->getMockBuilder(IShare::class)
  135. ->disableOriginalConstructor()
  136. ->getMock();
  137. $share->method('getPassword')->willReturn('password');
  138. $share->method('getShareType')->willReturn(42);
  139. $this->shareManager->expects($this->once())
  140. ->method('getShareByToken')
  141. ->with('GX9HSGQrGE')
  142. ->willReturn($share);
  143. $this->session->method('exists')->with('public_link_authenticated')->willReturn(false);
  144. $this->session->method('get')->with('public_link_authenticated')->willReturn('43');
  145. $this->expectException(\Sabre\DAV\Exception\NotAuthenticated::class);
  146. $this->invokePrivate($this->auth, 'checkToken');
  147. }
  148. public function testNoShare(): void {
  149. $this->request->method('getPathInfo')
  150. ->willReturn('/dav/files/GX9HSGQrGE');
  151. $this->shareManager->expects($this->once())
  152. ->method('getShareByToken')
  153. ->with('GX9HSGQrGE')
  154. ->willThrowException(new ShareNotFound());
  155. $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']);
  156. $this->assertFalse($result);
  157. }
  158. public function testShareNoPassword(): void {
  159. $this->request->method('getPathInfo')
  160. ->willReturn('/dav/files/GX9HSGQrGE');
  161. $share = $this->getMockBuilder(IShare::class)
  162. ->disableOriginalConstructor()
  163. ->getMock();
  164. $share->method('getPassword')->willReturn(null);
  165. $this->shareManager->expects($this->once())
  166. ->method('getShareByToken')
  167. ->with('GX9HSGQrGE')
  168. ->willReturn($share);
  169. $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']);
  170. $this->assertTrue($result);
  171. }
  172. public function testSharePasswordFancyShareType(): void {
  173. $this->request->method('getPathInfo')
  174. ->willReturn('/dav/files/GX9HSGQrGE');
  175. $share = $this->getMockBuilder(IShare::class)
  176. ->disableOriginalConstructor()
  177. ->getMock();
  178. $share->method('getPassword')->willReturn('password');
  179. $share->method('getShareType')->willReturn(42);
  180. $this->shareManager->expects($this->once())
  181. ->method('getShareByToken')
  182. ->with('GX9HSGQrGE')
  183. ->willReturn($share);
  184. $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']);
  185. $this->assertFalse($result);
  186. }
  187. public function testSharePasswordRemote(): void {
  188. $this->request->method('getPathInfo')
  189. ->willReturn('/dav/files/GX9HSGQrGE');
  190. $share = $this->getMockBuilder(IShare::class)
  191. ->disableOriginalConstructor()
  192. ->getMock();
  193. $share->method('getPassword')->willReturn('password');
  194. $share->method('getShareType')->willReturn(IShare::TYPE_REMOTE);
  195. $this->shareManager->expects($this->once())
  196. ->method('getShareByToken')
  197. ->with('GX9HSGQrGE')
  198. ->willReturn($share);
  199. $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']);
  200. $this->assertTrue($result);
  201. }
  202. public function testSharePasswordLinkValidPassword(): void {
  203. $this->request->method('getPathInfo')
  204. ->willReturn('/dav/files/GX9HSGQrGE');
  205. $share = $this->getMockBuilder(IShare::class)
  206. ->disableOriginalConstructor()
  207. ->getMock();
  208. $share->method('getPassword')->willReturn('password');
  209. $share->method('getShareType')->willReturn(IShare::TYPE_LINK);
  210. $this->shareManager->expects($this->once())
  211. ->method('getShareByToken')
  212. ->with('GX9HSGQrGE')
  213. ->willReturn($share);
  214. $this->shareManager->expects($this->once())
  215. ->method('checkPassword')->with(
  216. $this->equalTo($share),
  217. $this->equalTo('password')
  218. )->willReturn(true);
  219. $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']);
  220. $this->assertTrue($result);
  221. }
  222. public function testSharePasswordMailValidPassword(): void {
  223. $this->request->method('getPathInfo')
  224. ->willReturn('/dav/files/GX9HSGQrGE');
  225. $share = $this->getMockBuilder(IShare::class)
  226. ->disableOriginalConstructor()
  227. ->getMock();
  228. $share->method('getPassword')->willReturn('password');
  229. $share->method('getShareType')->willReturn(IShare::TYPE_EMAIL);
  230. $this->shareManager->expects($this->once())
  231. ->method('getShareByToken')
  232. ->with('GX9HSGQrGE')
  233. ->willReturn($share);
  234. $this->shareManager->expects($this->once())
  235. ->method('checkPassword')->with(
  236. $this->equalTo($share),
  237. $this->equalTo('password')
  238. )->willReturn(true);
  239. $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']);
  240. $this->assertTrue($result);
  241. }
  242. public function testInvalidSharePasswordLinkValidSession(): void {
  243. $this->request->method('getPathInfo')
  244. ->willReturn('/dav/files/GX9HSGQrGE');
  245. $share = $this->getMockBuilder(IShare::class)
  246. ->disableOriginalConstructor()
  247. ->getMock();
  248. $share->method('getPassword')->willReturn('password');
  249. $share->method('getShareType')->willReturn(IShare::TYPE_LINK);
  250. $share->method('getId')->willReturn('42');
  251. $this->shareManager->expects($this->once())
  252. ->method('getShareByToken')
  253. ->with('GX9HSGQrGE')
  254. ->willReturn($share);
  255. $this->shareManager->expects($this->once())
  256. ->method('checkPassword')
  257. ->with(
  258. $this->equalTo($share),
  259. $this->equalTo('password')
  260. )->willReturn(false);
  261. $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
  262. $this->session->method('get')->with('public_link_authenticated')->willReturn('42');
  263. $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']);
  264. $this->assertTrue($result);
  265. }
  266. public function testSharePasswordLinkInvalidSession(): void {
  267. $this->request->method('getPathInfo')
  268. ->willReturn('/dav/files/GX9HSGQrGE');
  269. $share = $this->getMockBuilder(IShare::class)
  270. ->disableOriginalConstructor()
  271. ->getMock();
  272. $share->method('getPassword')->willReturn('password');
  273. $share->method('getShareType')->willReturn(IShare::TYPE_LINK);
  274. $share->method('getId')->willReturn('42');
  275. $this->shareManager->expects($this->once())
  276. ->method('getShareByToken')
  277. ->with('GX9HSGQrGE')
  278. ->willReturn($share);
  279. $this->shareManager->expects($this->once())
  280. ->method('checkPassword')
  281. ->with(
  282. $this->equalTo($share),
  283. $this->equalTo('password')
  284. )->willReturn(false);
  285. $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
  286. $this->session->method('get')->with('public_link_authenticated')->willReturn('43');
  287. $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']);
  288. $this->assertFalse($result);
  289. }
  290. public function testSharePasswordMailInvalidSession(): void {
  291. $this->request->method('getPathInfo')
  292. ->willReturn('/dav/files/GX9HSGQrGE');
  293. $share = $this->getMockBuilder(IShare::class)
  294. ->disableOriginalConstructor()
  295. ->getMock();
  296. $share->method('getPassword')->willReturn('password');
  297. $share->method('getShareType')->willReturn(IShare::TYPE_EMAIL);
  298. $share->method('getId')->willReturn('42');
  299. $this->shareManager->expects($this->once())
  300. ->method('getShareByToken')
  301. ->with('GX9HSGQrGE')
  302. ->willReturn($share);
  303. $this->shareManager->expects($this->once())
  304. ->method('checkPassword')
  305. ->with(
  306. $this->equalTo($share),
  307. $this->equalTo('password')
  308. )->willReturn(false);
  309. $this->session->method('exists')->with('public_link_authenticated')->willReturn(true);
  310. $this->session->method('get')->with('public_link_authenticated')->willReturn('43');
  311. $result = $this->invokePrivate($this->auth, 'validateUserPass', ['username', 'password']);
  312. $this->assertFalse($result);
  313. }
  314. }