SessionTest.php 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474
  1. <?php
  2. /**
  3. * Copyright (c) 2013 Robin Appelman <icewind@owncloud.com>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace Test\User;
  9. use OC\AppFramework\Http\Request;
  10. use OC\Authentication\Token\DefaultTokenMapper;
  11. use OC\Authentication\Token\DefaultTokenProvider;
  12. use OC\Authentication\Token\IProvider;
  13. use OC\Authentication\Token\IToken;
  14. use OC\Security\Bruteforce\Throttler;
  15. use OC\Session\Memory;
  16. use OC\User\Manager;
  17. use OC\User\Session;
  18. use OC\User\User;
  19. use OCA\DAV\Connector\Sabre\Auth;
  20. use OCP\AppFramework\Utility\ITimeFactory;
  21. use OCP\EventDispatcher\IEventDispatcher;
  22. use OCP\IConfig;
  23. use OCP\ILogger;
  24. use OCP\IRequest;
  25. use OCP\ISession;
  26. use OCP\IUser;
  27. use OCP\Lockdown\ILockdownManager;
  28. use OCP\Security\ICrypto;
  29. use OCP\Security\ISecureRandom;
  30. use OCP\User\Events\PostLoginEvent;
  31. use PHPUnit\Framework\MockObject\MockObject;
  32. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  33. /**
  34. * @group DB
  35. * @package Test\User
  36. */
  37. class SessionTest extends \Test\TestCase {
  38. /** @var ITimeFactory|MockObject */
  39. private $timeFactory;
  40. /** @var DefaultTokenProvider|MockObject */
  41. protected $tokenProvider;
  42. /** @var IConfig|MockObject */
  43. private $config;
  44. /** @var Throttler|MockObject */
  45. private $throttler;
  46. /** @var ISecureRandom|MockObject */
  47. private $random;
  48. /** @var Manager|MockObject */
  49. private $manager;
  50. /** @var ISession|MockObject */
  51. private $session;
  52. /** @var Session|MockObject */
  53. private $userSession;
  54. /** @var ILockdownManager|MockObject */
  55. private $lockdownManager;
  56. /** @var ILogger|MockObject */
  57. private $logger;
  58. /** @var IEventDispatcher|MockObject */
  59. private $dispatcher;
  60. protected function setUp(): void {
  61. parent::setUp();
  62. $this->timeFactory = $this->createMock(ITimeFactory::class);
  63. $this->timeFactory->expects($this->any())
  64. ->method('getTime')
  65. ->willReturn(10000);
  66. $this->tokenProvider = $this->createMock(IProvider::class);
  67. $this->config = $this->createMock(IConfig::class);
  68. $this->throttler = $this->createMock(Throttler::class);
  69. $this->random = $this->createMock(ISecureRandom::class);
  70. $this->manager = $this->createMock(Manager::class);
  71. $this->session = $this->createMock(ISession::class);
  72. $this->lockdownManager = $this->createMock(ILockdownManager::class);
  73. $this->logger = $this->createMock(ILogger::class);
  74. $this->dispatcher = $this->createMock(IEventDispatcher::class);
  75. $this->userSession = $this->getMockBuilder(Session::class)
  76. ->setConstructorArgs([
  77. $this->manager,
  78. $this->session,
  79. $this->timeFactory,
  80. $this->tokenProvider,
  81. $this->config,
  82. $this->random,
  83. $this->lockdownManager,
  84. $this->logger,
  85. $this->dispatcher
  86. ])
  87. ->setMethods([
  88. 'setMagicInCookie',
  89. ])
  90. ->getMock();
  91. \OC_User::setIncognitoMode(false);
  92. }
  93. public function testGetUser() {
  94. $token = new \OC\Authentication\Token\DefaultToken();
  95. $token->setLoginName('User123');
  96. $token->setLastCheck(200);
  97. $expectedUser = $this->createMock(IUser::class);
  98. $expectedUser->expects($this->any())
  99. ->method('getUID')
  100. ->willReturn('user123');
  101. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  102. $session->expects($this->at(0))
  103. ->method('get')
  104. ->with('user_id')
  105. ->willReturn($expectedUser->getUID());
  106. $sessionId = 'abcdef12345';
  107. $manager = $this->getMockBuilder('\OC\User\Manager')
  108. ->disableOriginalConstructor()
  109. ->getMock();
  110. $session->expects($this->at(1))
  111. ->method('get')
  112. ->with('app_password')
  113. ->willReturn(null); // No password set -> browser session
  114. $session->expects($this->once())
  115. ->method('getId')
  116. ->willReturn($sessionId);
  117. $this->tokenProvider->expects($this->once())
  118. ->method('getToken')
  119. ->with($sessionId)
  120. ->willReturn($token);
  121. $this->tokenProvider->expects($this->once())
  122. ->method('getPassword')
  123. ->with($token, $sessionId)
  124. ->willReturn('passme');
  125. $manager->expects($this->once())
  126. ->method('checkPassword')
  127. ->with('User123', 'passme')
  128. ->willReturn(true);
  129. $expectedUser->expects($this->once())
  130. ->method('isEnabled')
  131. ->willReturn(true);
  132. $this->tokenProvider->expects($this->once())
  133. ->method('updateTokenActivity')
  134. ->with($token);
  135. $manager->expects($this->once())
  136. ->method('get')
  137. ->with($expectedUser->getUID())
  138. ->willReturn($expectedUser);
  139. $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  140. $user = $userSession->getUser();
  141. $this->assertSame($expectedUser, $user);
  142. $this->assertSame(10000, $token->getLastCheck());
  143. }
  144. public function isLoggedInData() {
  145. return [
  146. [true],
  147. [false],
  148. ];
  149. }
  150. /**
  151. * @dataProvider isLoggedInData
  152. */
  153. public function testIsLoggedIn($isLoggedIn) {
  154. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  155. $manager = $this->createMock(Manager::class);
  156. $userSession = $this->getMockBuilder(Session::class)
  157. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  158. ->setMethods([
  159. 'getUser'
  160. ])
  161. ->getMock();
  162. $user = new User('sepp', null, $this->createMock(EventDispatcherInterface::class));
  163. $userSession->expects($this->once())
  164. ->method('getUser')
  165. ->willReturn($isLoggedIn ? $user : null);
  166. $this->assertEquals($isLoggedIn, $userSession->isLoggedIn());
  167. }
  168. public function testSetUser() {
  169. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  170. $session->expects($this->once())
  171. ->method('set')
  172. ->with('user_id', 'foo');
  173. $manager = $this->createMock(Manager::class);
  174. $backend = $this->createMock(\Test\Util\User\Dummy::class);
  175. $user = $this->createMock(IUser::class);
  176. $user->expects($this->once())
  177. ->method('getUID')
  178. ->willReturn('foo');
  179. $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  180. $userSession->setUser($user);
  181. }
  182. public function testLoginValidPasswordEnabled() {
  183. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  184. $session->expects($this->once())
  185. ->method('regenerateId');
  186. $this->tokenProvider->expects($this->once())
  187. ->method('getToken')
  188. ->with('bar')
  189. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  190. $session->expects($this->exactly(2))
  191. ->method('set')
  192. ->with($this->callback(function ($key) {
  193. switch ($key) {
  194. case 'user_id':
  195. case 'loginname':
  196. return true;
  197. break;
  198. default:
  199. return false;
  200. break;
  201. }
  202. }, 'foo'));
  203. $managerMethods = get_class_methods(Manager::class);
  204. //keep following methods intact in order to ensure hooks are working
  205. $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
  206. $manager = $this->getMockBuilder(Manager::class)
  207. ->setMethods($mockedManagerMethods)
  208. ->setConstructorArgs([
  209. $this->config,
  210. $this->createMock(EventDispatcherInterface::class),
  211. $this->createMock(IEventDispatcher::class)
  212. ])
  213. ->getMock();
  214. $backend = $this->createMock(\Test\Util\User\Dummy::class);
  215. $user = $this->createMock(IUser::class);
  216. $user->expects($this->any())
  217. ->method('isEnabled')
  218. ->willReturn(true);
  219. $user->expects($this->any())
  220. ->method('getUID')
  221. ->willReturn('foo');
  222. $user->expects($this->once())
  223. ->method('updateLastLoginTimestamp');
  224. $manager->expects($this->once())
  225. ->method('checkPasswordNoLogging')
  226. ->with('foo', 'bar')
  227. ->willReturn($user);
  228. $userSession = $this->getMockBuilder(Session::class)
  229. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  230. ->setMethods([
  231. 'prepareUserLogin'
  232. ])
  233. ->getMock();
  234. $userSession->expects($this->once())
  235. ->method('prepareUserLogin');
  236. $this->dispatcher->expects($this->once())
  237. ->method('dispatchTyped')
  238. ->with(
  239. $this->callback(function (PostLoginEvent $e) {
  240. return $e->getUser()->getUID() === 'foo' &&
  241. $e->getPassword() === 'bar' &&
  242. $e->isTokenLogin() === false;
  243. })
  244. );
  245. $userSession->login('foo', 'bar');
  246. $this->assertEquals($user, $userSession->getUser());
  247. }
  248. public function testLoginValidPasswordDisabled() {
  249. $this->expectException(\OC\User\LoginException::class);
  250. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  251. $session->expects($this->never())
  252. ->method('set');
  253. $session->expects($this->once())
  254. ->method('regenerateId');
  255. $this->tokenProvider->expects($this->once())
  256. ->method('getToken')
  257. ->with('bar')
  258. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  259. $managerMethods = get_class_methods(\OC\User\Manager::class);
  260. //keep following methods intact in order to ensure hooks are working
  261. $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
  262. $manager = $this->getMockBuilder(Manager::class)
  263. ->setMethods($mockedManagerMethods)
  264. ->setConstructorArgs([
  265. $this->config,
  266. $this->createMock(EventDispatcherInterface::class),
  267. $this->createMock(IEventDispatcher::class)
  268. ])
  269. ->getMock();
  270. $user = $this->createMock(IUser::class);
  271. $user->expects($this->any())
  272. ->method('isEnabled')
  273. ->willReturn(false);
  274. $user->expects($this->never())
  275. ->method('updateLastLoginTimestamp');
  276. $manager->expects($this->once())
  277. ->method('checkPasswordNoLogging')
  278. ->with('foo', 'bar')
  279. ->willReturn($user);
  280. $this->dispatcher->expects($this->never())
  281. ->method('dispatch');
  282. $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  283. $userSession->login('foo', 'bar');
  284. }
  285. public function testLoginInvalidPassword() {
  286. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  287. $managerMethods = get_class_methods(\OC\User\Manager::class);
  288. //keep following methods intact in order to ensure hooks are working
  289. $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
  290. $manager = $this->getMockBuilder(Manager::class)
  291. ->setMethods($mockedManagerMethods)
  292. ->setConstructorArgs([
  293. $this->config,
  294. $this->createMock(EventDispatcherInterface::class),
  295. $this->createMock(IEventDispatcher::class)
  296. ])
  297. ->getMock();
  298. $backend = $this->createMock(\Test\Util\User\Dummy::class);
  299. $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  300. $user = $this->createMock(IUser::class);
  301. $session->expects($this->never())
  302. ->method('set');
  303. $session->expects($this->once())
  304. ->method('regenerateId');
  305. $this->tokenProvider->expects($this->once())
  306. ->method('getToken')
  307. ->with('bar')
  308. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  309. $user->expects($this->never())
  310. ->method('isEnabled');
  311. $user->expects($this->never())
  312. ->method('updateLastLoginTimestamp');
  313. $manager->expects($this->once())
  314. ->method('checkPasswordNoLogging')
  315. ->with('foo', 'bar')
  316. ->willReturn(false);
  317. $this->dispatcher->expects($this->never())
  318. ->method('dispatch');
  319. $userSession->login('foo', 'bar');
  320. }
  321. public function testLoginNonExisting() {
  322. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  323. $manager = $this->createMock(Manager::class);
  324. $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  325. $session->expects($this->never())
  326. ->method('set');
  327. $session->expects($this->once())
  328. ->method('regenerateId');
  329. $this->tokenProvider->expects($this->once())
  330. ->method('getToken')
  331. ->with('bar')
  332. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  333. $manager->expects($this->once())
  334. ->method('checkPasswordNoLogging')
  335. ->with('foo', 'bar')
  336. ->willReturn(false);
  337. $userSession->login('foo', 'bar');
  338. }
  339. /**
  340. * When using a device token, the loginname must match the one that was used
  341. * when generating the token on the browser.
  342. */
  343. public function testLoginWithDifferentTokenLoginName() {
  344. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  345. $manager = $this->createMock(Manager::class);
  346. $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  347. $username = 'user123';
  348. $token = new \OC\Authentication\Token\DefaultToken();
  349. $token->setLoginName($username);
  350. $session->expects($this->never())
  351. ->method('set');
  352. $session->expects($this->once())
  353. ->method('regenerateId');
  354. $this->tokenProvider->expects($this->once())
  355. ->method('getToken')
  356. ->with('bar')
  357. ->willReturn($token);
  358. $manager->expects($this->once())
  359. ->method('checkPasswordNoLogging')
  360. ->with('foo', 'bar')
  361. ->willReturn(false);
  362. $userSession->login('foo', 'bar');
  363. }
  364. public function testLogClientInNoTokenPasswordWith2fa() {
  365. $this->expectException(\OC\Authentication\Exceptions\PasswordLoginForbiddenException::class);
  366. $manager = $this->createMock(Manager::class);
  367. $session = $this->createMock(ISession::class);
  368. $request = $this->createMock(IRequest::class);
  369. /** @var \OC\User\Session $userSession */
  370. $userSession = $this->getMockBuilder(Session::class)
  371. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  372. ->setMethods(['login', 'supportsCookies', 'createSessionToken', 'getUser'])
  373. ->getMock();
  374. $this->tokenProvider->expects($this->once())
  375. ->method('getToken')
  376. ->with('doe')
  377. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  378. $this->config->expects($this->once())
  379. ->method('getSystemValue')
  380. ->with('token_auth_enforced', false)
  381. ->willReturn(true);
  382. $request
  383. ->expects($this->any())
  384. ->method('getRemoteAddress')
  385. ->willReturn('192.168.0.1');
  386. $this->throttler
  387. ->expects($this->once())
  388. ->method('sleepDelay')
  389. ->with('192.168.0.1');
  390. $this->throttler
  391. ->expects($this->any())
  392. ->method('getDelay')
  393. ->with('192.168.0.1')
  394. ->willReturn(0);
  395. $userSession->logClientIn('john', 'doe', $request, $this->throttler);
  396. }
  397. public function testLogClientInUnexist() {
  398. $manager = $this->createMock(Manager::class);
  399. $session = $this->createMock(ISession::class);
  400. $request = $this->createMock(IRequest::class);
  401. /** @var Session $userSession */
  402. $userSession = $this->getMockBuilder(Session::class)
  403. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  404. ->setMethods(['login', 'supportsCookies', 'createSessionToken', 'getUser'])
  405. ->getMock();
  406. $this->tokenProvider->expects($this->once())
  407. ->method('getToken')
  408. ->with('doe')
  409. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  410. $this->config->expects($this->once())
  411. ->method('getSystemValue')
  412. ->with('token_auth_enforced', false)
  413. ->willReturn(false);
  414. $manager->method('getByEmail')
  415. ->with('unexist')
  416. ->willReturn([]);
  417. $this->assertFalse($userSession->logClientIn('unexist', 'doe', $request, $this->throttler));
  418. }
  419. public function testLogClientInWithTokenPassword() {
  420. $manager = $this->createMock(Manager::class);
  421. $session = $this->createMock(ISession::class);
  422. $request = $this->createMock(IRequest::class);
  423. /** @var \OC\User\Session $userSession */
  424. $userSession = $this->getMockBuilder(Session::class)
  425. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  426. ->setMethods(['isTokenPassword', 'login', 'supportsCookies', 'createSessionToken', 'getUser'])
  427. ->getMock();
  428. $userSession->expects($this->once())
  429. ->method('isTokenPassword')
  430. ->willReturn(true);
  431. $userSession->expects($this->once())
  432. ->method('login')
  433. ->with('john', 'I-AM-AN-APP-PASSWORD')
  434. ->willReturn(true);
  435. $session->expects($this->once())
  436. ->method('set')
  437. ->with('app_password', 'I-AM-AN-APP-PASSWORD');
  438. $request
  439. ->expects($this->any())
  440. ->method('getRemoteAddress')
  441. ->willReturn('192.168.0.1');
  442. $this->throttler
  443. ->expects($this->once())
  444. ->method('sleepDelay')
  445. ->with('192.168.0.1');
  446. $this->throttler
  447. ->expects($this->any())
  448. ->method('getDelay')
  449. ->with('192.168.0.1')
  450. ->willReturn(0);
  451. $this->assertTrue($userSession->logClientIn('john', 'I-AM-AN-APP-PASSWORD', $request, $this->throttler));
  452. }
  453. public function testLogClientInNoTokenPasswordNo2fa() {
  454. $this->expectException(\OC\Authentication\Exceptions\PasswordLoginForbiddenException::class);
  455. $manager = $this->createMock(Manager::class);
  456. $session = $this->createMock(ISession::class);
  457. $request = $this->createMock(IRequest::class);
  458. /** @var \OC\User\Session $userSession */
  459. $userSession = $this->getMockBuilder(Session::class)
  460. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  461. ->setMethods(['login', 'isTwoFactorEnforced'])
  462. ->getMock();
  463. $this->tokenProvider->expects($this->once())
  464. ->method('getToken')
  465. ->with('doe')
  466. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  467. $this->config->expects($this->once())
  468. ->method('getSystemValue')
  469. ->with('token_auth_enforced', false)
  470. ->willReturn(false);
  471. $userSession->expects($this->once())
  472. ->method('isTwoFactorEnforced')
  473. ->with('john')
  474. ->willReturn(true);
  475. $request
  476. ->expects($this->any())
  477. ->method('getRemoteAddress')
  478. ->willReturn('192.168.0.1');
  479. $this->throttler
  480. ->expects($this->once())
  481. ->method('sleepDelay')
  482. ->with('192.168.0.1');
  483. $this->throttler
  484. ->expects($this->any())
  485. ->method('getDelay')
  486. ->with('192.168.0.1')
  487. ->willReturn(0);
  488. $userSession->logClientIn('john', 'doe', $request, $this->throttler);
  489. }
  490. public function testRememberLoginValidToken() {
  491. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  492. $managerMethods = get_class_methods(\OC\User\Manager::class);
  493. //keep following methods intact in order to ensure hooks are working
  494. $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
  495. $manager = $this->getMockBuilder(Manager::class)
  496. ->setMethods($mockedManagerMethods)
  497. ->setConstructorArgs([
  498. $this->config,
  499. $this->createMock(EventDispatcherInterface::class),
  500. $this->createMock(IEventDispatcher::class)
  501. ])
  502. ->getMock();
  503. $userSession = $this->getMockBuilder(Session::class)
  504. //override, otherwise tests will fail because of setcookie()
  505. ->setMethods(['setMagicInCookie', 'setLoginName'])
  506. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  507. ->getMock();
  508. $user = $this->createMock(IUser::class);
  509. $token = 'goodToken';
  510. $oldSessionId = 'sess321';
  511. $sessionId = 'sess123';
  512. $session->expects($this->once())
  513. ->method('regenerateId');
  514. $manager->expects($this->once())
  515. ->method('get')
  516. ->with('foo')
  517. ->willReturn($user);
  518. $this->config->expects($this->once())
  519. ->method('getUserKeys')
  520. ->with('foo', 'login_token')
  521. ->willReturn([$token]);
  522. $this->config->expects($this->once())
  523. ->method('deleteUserValue')
  524. ->with('foo', 'login_token', $token);
  525. $this->random->expects($this->once())
  526. ->method('generate')
  527. ->with(32)
  528. ->willReturn('abcdefg123456');
  529. $this->config->expects($this->once())
  530. ->method('setUserValue')
  531. ->with('foo', 'login_token', 'abcdefg123456', 10000);
  532. $tokenObject = $this->createMock(IToken::class);
  533. $tokenObject->expects($this->once())
  534. ->method('getLoginName')
  535. ->willReturn('foobar');
  536. $tokenObject->method('getId')
  537. ->willReturn(42);
  538. $session->expects($this->once())
  539. ->method('getId')
  540. ->willReturn($sessionId);
  541. $this->tokenProvider->expects($this->once())
  542. ->method('renewSessionToken')
  543. ->with($oldSessionId, $sessionId)
  544. ->willReturn($tokenObject);
  545. $this->tokenProvider->expects($this->never())
  546. ->method('getToken');
  547. $user->expects($this->any())
  548. ->method('getUID')
  549. ->willReturn('foo');
  550. $userSession->expects($this->once())
  551. ->method('setMagicInCookie');
  552. $user->expects($this->once())
  553. ->method('updateLastLoginTimestamp');
  554. $setUID = false;
  555. $session
  556. ->method('set')
  557. ->willReturnCallback(function ($k, $v) use (&$setUID) {
  558. if ($k === 'user_id' && $v === 'foo') {
  559. $setUID = true;
  560. }
  561. });
  562. $userSession->expects($this->once())
  563. ->method('setLoginName')
  564. ->willReturn('foobar');
  565. $granted = $userSession->loginWithCookie('foo', $token, $oldSessionId);
  566. $this->assertTrue($setUID);
  567. $this->assertTrue($granted);
  568. }
  569. public function testRememberLoginInvalidSessionToken() {
  570. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  571. $managerMethods = get_class_methods(\OC\User\Manager::class);
  572. //keep following methods intact in order to ensure hooks are working
  573. $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
  574. $manager = $this->getMockBuilder(Manager::class)
  575. ->setMethods($mockedManagerMethods)
  576. ->setConstructorArgs([
  577. $this->config,
  578. $this->createMock(EventDispatcherInterface::class),
  579. $this->createMock(IEventDispatcher::class)
  580. ])
  581. ->getMock();
  582. $userSession = $this->getMockBuilder(Session::class)
  583. //override, otherwise tests will fail because of setcookie()
  584. ->setMethods(['setMagicInCookie'])
  585. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  586. ->getMock();
  587. $user = $this->createMock(IUser::class);
  588. $token = 'goodToken';
  589. $oldSessionId = 'sess321';
  590. $sessionId = 'sess123';
  591. $session->expects($this->once())
  592. ->method('regenerateId');
  593. $manager->expects($this->once())
  594. ->method('get')
  595. ->with('foo')
  596. ->willReturn($user);
  597. $this->config->expects($this->once())
  598. ->method('getUserKeys')
  599. ->with('foo', 'login_token')
  600. ->willReturn([$token]);
  601. $this->config->expects($this->once())
  602. ->method('deleteUserValue')
  603. ->with('foo', 'login_token', $token);
  604. $this->config->expects($this->once())
  605. ->method('setUserValue'); // TODO: mock new random value
  606. $session->expects($this->once())
  607. ->method('getId')
  608. ->willReturn($sessionId);
  609. $this->tokenProvider->expects($this->once())
  610. ->method('renewSessionToken')
  611. ->with($oldSessionId, $sessionId)
  612. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  613. $user->expects($this->never())
  614. ->method('getUID')
  615. ->willReturn('foo');
  616. $userSession->expects($this->never())
  617. ->method('setMagicInCookie');
  618. $user->expects($this->never())
  619. ->method('updateLastLoginTimestamp');
  620. $session->expects($this->never())
  621. ->method('set')
  622. ->with('user_id', 'foo');
  623. $granted = $userSession->loginWithCookie('foo', $token, $oldSessionId);
  624. $this->assertFalse($granted);
  625. }
  626. public function testRememberLoginInvalidToken() {
  627. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  628. $managerMethods = get_class_methods(\OC\User\Manager::class);
  629. //keep following methods intact in order to ensure hooks are working
  630. $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
  631. $manager = $this->getMockBuilder(Manager::class)
  632. ->setMethods($mockedManagerMethods)
  633. ->setConstructorArgs([
  634. $this->config,
  635. $this->createMock(EventDispatcherInterface::class),
  636. $this->createMock(IEventDispatcher::class)
  637. ])
  638. ->getMock();
  639. $userSession = $this->getMockBuilder(Session::class)
  640. //override, otherwise tests will fail because of setcookie()
  641. ->setMethods(['setMagicInCookie'])
  642. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  643. ->getMock();
  644. $user = $this->createMock(IUser::class);
  645. $token = 'goodToken';
  646. $oldSessionId = 'sess321';
  647. $session->expects($this->once())
  648. ->method('regenerateId');
  649. $manager->expects($this->once())
  650. ->method('get')
  651. ->with('foo')
  652. ->willReturn($user);
  653. $this->config->expects($this->once())
  654. ->method('getUserKeys')
  655. ->with('foo', 'login_token')
  656. ->willReturn(['anothertoken']);
  657. $this->config->expects($this->never())
  658. ->method('deleteUserValue')
  659. ->with('foo', 'login_token', $token);
  660. $this->tokenProvider->expects($this->never())
  661. ->method('renewSessionToken');
  662. $userSession->expects($this->never())
  663. ->method('setMagicInCookie');
  664. $user->expects($this->never())
  665. ->method('updateLastLoginTimestamp');
  666. $session->expects($this->never())
  667. ->method('set')
  668. ->with('user_id', 'foo');
  669. $granted = $userSession->loginWithCookie('foo', $token, $oldSessionId);
  670. $this->assertFalse($granted);
  671. }
  672. public function testRememberLoginInvalidUser() {
  673. $session = $this->getMockBuilder(Memory::class)->setConstructorArgs([''])->getMock();
  674. $managerMethods = get_class_methods(\OC\User\Manager::class);
  675. //keep following methods intact in order to ensure hooks are working
  676. $mockedManagerMethods = array_diff($managerMethods, ['__construct', 'emit', 'listen']);
  677. $manager = $this->getMockBuilder(Manager::class)
  678. ->setMethods($mockedManagerMethods)
  679. ->setConstructorArgs([
  680. $this->config,
  681. $this->createMock(EventDispatcherInterface::class),
  682. $this->createMock(IEventDispatcher::class)
  683. ])
  684. ->getMock();
  685. $userSession = $this->getMockBuilder(Session::class)
  686. //override, otherwise tests will fail because of setcookie()
  687. ->setMethods(['setMagicInCookie'])
  688. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  689. ->getMock();
  690. $token = 'goodToken';
  691. $oldSessionId = 'sess321';
  692. $session->expects($this->once())
  693. ->method('regenerateId');
  694. $manager->expects($this->once())
  695. ->method('get')
  696. ->with('foo')
  697. ->willReturn(null);
  698. $this->config->expects($this->never())
  699. ->method('getUserKeys')
  700. ->with('foo', 'login_token')
  701. ->willReturn(['anothertoken']);
  702. $this->tokenProvider->expects($this->never())
  703. ->method('renewSessionToken');
  704. $userSession->expects($this->never())
  705. ->method('setMagicInCookie');
  706. $session->expects($this->never())
  707. ->method('set')
  708. ->with('user_id', 'foo');
  709. $granted = $userSession->loginWithCookie('foo', $token, $oldSessionId);
  710. $this->assertFalse($granted);
  711. }
  712. public function testActiveUserAfterSetSession() {
  713. $users = [
  714. 'foo' => new User('foo', null, $this->createMock(EventDispatcherInterface::class)),
  715. 'bar' => new User('bar', null, $this->createMock(EventDispatcherInterface::class))
  716. ];
  717. $manager = $this->getMockBuilder('\OC\User\Manager')
  718. ->disableOriginalConstructor()
  719. ->getMock();
  720. $manager->expects($this->any())
  721. ->method('get')
  722. ->willReturnCallback(function ($uid) use ($users) {
  723. return $users[$uid];
  724. });
  725. $session = new Memory('');
  726. $session->set('user_id', 'foo');
  727. $userSession = $this->getMockBuilder(Session::class)
  728. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  729. ->setMethods([
  730. 'validateSession'
  731. ])
  732. ->getMock();
  733. $userSession->expects($this->any())
  734. ->method('validateSession');
  735. $this->assertEquals($users['foo'], $userSession->getUser());
  736. $session2 = new Memory('');
  737. $session2->set('user_id', 'bar');
  738. $userSession->setSession($session2);
  739. $this->assertEquals($users['bar'], $userSession->getUser());
  740. }
  741. public function testCreateSessionToken() {
  742. $manager = $this->createMock(Manager::class);
  743. $session = $this->createMock(ISession::class);
  744. $user = $this->createMock(IUser::class);
  745. $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  746. $random = $this->createMock(ISecureRandom::class);
  747. $config = $this->createMock(IConfig::class);
  748. $csrf = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenManager')
  749. ->disableOriginalConstructor()
  750. ->getMock();
  751. $request = new \OC\AppFramework\Http\Request([
  752. 'server' => [
  753. 'HTTP_USER_AGENT' => 'Firefox',
  754. ]
  755. ], $random, $config, $csrf);
  756. $uid = 'user123';
  757. $loginName = 'User123';
  758. $password = 'passme';
  759. $sessionId = 'abcxyz';
  760. $manager->expects($this->once())
  761. ->method('get')
  762. ->with($uid)
  763. ->willReturn($user);
  764. $session->expects($this->once())
  765. ->method('getId')
  766. ->willReturn($sessionId);
  767. $this->tokenProvider->expects($this->once())
  768. ->method('getToken')
  769. ->with($password)
  770. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  771. $this->tokenProvider->expects($this->once())
  772. ->method('generateToken')
  773. ->with($sessionId, $uid, $loginName, $password, 'Firefox', IToken::TEMPORARY_TOKEN, IToken::DO_NOT_REMEMBER);
  774. $this->assertTrue($userSession->createSessionToken($request, $uid, $loginName, $password));
  775. }
  776. public function testCreateRememberedSessionToken() {
  777. $manager = $this->createMock(Manager::class);
  778. $session = $this->createMock(ISession::class);
  779. $user = $this->createMock(IUser::class);
  780. $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  781. $random = $this->createMock(ISecureRandom::class);
  782. $config = $this->createMock(IConfig::class);
  783. $csrf = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenManager')
  784. ->disableOriginalConstructor()
  785. ->getMock();
  786. $request = new \OC\AppFramework\Http\Request([
  787. 'server' => [
  788. 'HTTP_USER_AGENT' => 'Firefox',
  789. ]
  790. ], $random, $config, $csrf);
  791. $uid = 'user123';
  792. $loginName = 'User123';
  793. $password = 'passme';
  794. $sessionId = 'abcxyz';
  795. $manager->expects($this->once())
  796. ->method('get')
  797. ->with($uid)
  798. ->willReturn($user);
  799. $session->expects($this->once())
  800. ->method('getId')
  801. ->willReturn($sessionId);
  802. $this->tokenProvider->expects($this->once())
  803. ->method('getToken')
  804. ->with($password)
  805. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  806. $this->tokenProvider->expects($this->once())
  807. ->method('generateToken')
  808. ->with($sessionId, $uid, $loginName, $password, 'Firefox', IToken::TEMPORARY_TOKEN, IToken::REMEMBER);
  809. $this->assertTrue($userSession->createSessionToken($request, $uid, $loginName, $password, true));
  810. }
  811. public function testCreateSessionTokenWithTokenPassword() {
  812. $manager = $this->getMockBuilder('\OC\User\Manager')
  813. ->disableOriginalConstructor()
  814. ->getMock();
  815. $session = $this->createMock(ISession::class);
  816. $token = $this->createMock(IToken::class);
  817. $user = $this->createMock(IUser::class);
  818. $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  819. $random = $this->createMock(ISecureRandom::class);
  820. $config = $this->createMock(IConfig::class);
  821. $csrf = $this->getMockBuilder('\OC\Security\CSRF\CsrfTokenManager')
  822. ->disableOriginalConstructor()
  823. ->getMock();
  824. $request = new \OC\AppFramework\Http\Request([
  825. 'server' => [
  826. 'HTTP_USER_AGENT' => 'Firefox',
  827. ]
  828. ], $random, $config, $csrf);
  829. $uid = 'user123';
  830. $loginName = 'User123';
  831. $password = 'iamatoken';
  832. $realPassword = 'passme';
  833. $sessionId = 'abcxyz';
  834. $manager->expects($this->once())
  835. ->method('get')
  836. ->with($uid)
  837. ->willReturn($user);
  838. $session->expects($this->once())
  839. ->method('getId')
  840. ->willReturn($sessionId);
  841. $this->tokenProvider->expects($this->once())
  842. ->method('getToken')
  843. ->with($password)
  844. ->willReturn($token);
  845. $this->tokenProvider->expects($this->once())
  846. ->method('getPassword')
  847. ->with($token, $password)
  848. ->willReturn($realPassword);
  849. $this->tokenProvider->expects($this->once())
  850. ->method('generateToken')
  851. ->with($sessionId, $uid, $loginName, $realPassword, 'Firefox', IToken::TEMPORARY_TOKEN, IToken::DO_NOT_REMEMBER);
  852. $this->assertTrue($userSession->createSessionToken($request, $uid, $loginName, $password));
  853. }
  854. public function testCreateSessionTokenWithNonExistentUser() {
  855. $manager = $this->getMockBuilder('\OC\User\Manager')
  856. ->disableOriginalConstructor()
  857. ->getMock();
  858. $session = $this->createMock(ISession::class);
  859. $userSession = new \OC\User\Session($manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  860. $request = $this->createMock(IRequest::class);
  861. $uid = 'user123';
  862. $loginName = 'User123';
  863. $password = 'passme';
  864. $manager->expects($this->once())
  865. ->method('get')
  866. ->with($uid)
  867. ->willReturn(null);
  868. $this->assertFalse($userSession->createSessionToken($request, $uid, $loginName, $password));
  869. }
  870. public function testTryTokenLoginWithDisabledUser() {
  871. $this->expectException(\OC\User\LoginException::class);
  872. $manager = $this->getMockBuilder('\OC\User\Manager')
  873. ->disableOriginalConstructor()
  874. ->getMock();
  875. $session = new Memory('');
  876. $token = new \OC\Authentication\Token\DefaultToken();
  877. $token->setLoginName('fritz');
  878. $token->setUid('fritz0');
  879. $token->setLastCheck(100); // Needs check
  880. $user = $this->createMock(IUser::class);
  881. $userSession = $this->getMockBuilder(Session::class)
  882. ->setMethods(['logout'])
  883. ->setConstructorArgs([$manager, $session, $this->timeFactory, $this->tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  884. ->getMock();
  885. $request = $this->createMock(IRequest::class);
  886. $request->expects($this->once())
  887. ->method('getHeader')
  888. ->with('Authorization')
  889. ->willReturn('Bearer xxxxx');
  890. $this->tokenProvider->expects($this->once())
  891. ->method('getToken')
  892. ->with('xxxxx')
  893. ->willReturn($token);
  894. $manager->expects($this->once())
  895. ->method('get')
  896. ->with('fritz0')
  897. ->willReturn($user);
  898. $user->expects($this->once())
  899. ->method('isEnabled')
  900. ->willReturn(false);
  901. $userSession->tryTokenLogin($request);
  902. }
  903. public function testValidateSessionDisabledUser() {
  904. $userManager = $this->createMock(Manager::class);
  905. $session = $this->createMock(ISession::class);
  906. $timeFactory = $this->createMock(ITimeFactory::class);
  907. $tokenProvider = $this->createMock(IProvider::class);
  908. $userSession = $this->getMockBuilder(Session::class)
  909. ->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  910. ->setMethods(['logout'])
  911. ->getMock();
  912. $user = $this->createMock(IUser::class);
  913. $token = new \OC\Authentication\Token\DefaultToken();
  914. $token->setLoginName('susan');
  915. $token->setLastCheck(20);
  916. $session->expects($this->once())
  917. ->method('get')
  918. ->with('app_password')
  919. ->willReturn('APP-PASSWORD');
  920. $tokenProvider->expects($this->once())
  921. ->method('getToken')
  922. ->with('APP-PASSWORD')
  923. ->willReturn($token);
  924. $timeFactory->expects($this->once())
  925. ->method('getTime')
  926. ->willReturn(1000); // more than 5min since last check
  927. $tokenProvider->expects($this->once())
  928. ->method('getPassword')
  929. ->with($token, 'APP-PASSWORD')
  930. ->willReturn('123456');
  931. $userManager->expects($this->never())
  932. ->method('checkPassword');
  933. $user->expects($this->once())
  934. ->method('isEnabled')
  935. ->willReturn(false);
  936. $tokenProvider->expects($this->once())
  937. ->method('invalidateToken')
  938. ->with('APP-PASSWORD');
  939. $userSession->expects($this->once())
  940. ->method('logout');
  941. $userSession->setUser($user);
  942. $this->invokePrivate($userSession, 'validateSession');
  943. }
  944. public function testValidateSessionNoPassword() {
  945. $userManager = $this->createMock(Manager::class);
  946. $session = $this->createMock(ISession::class);
  947. $timeFactory = $this->createMock(ITimeFactory::class);
  948. $tokenProvider = $this->createMock(IProvider::class);
  949. $userSession = $this->getMockBuilder(Session::class)
  950. ->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  951. ->setMethods(['logout'])
  952. ->getMock();
  953. $user = $this->createMock(IUser::class);
  954. $token = new \OC\Authentication\Token\DefaultToken();
  955. $token->setLastCheck(20);
  956. $session->expects($this->once())
  957. ->method('get')
  958. ->with('app_password')
  959. ->willReturn('APP-PASSWORD');
  960. $tokenProvider->expects($this->once())
  961. ->method('getToken')
  962. ->with('APP-PASSWORD')
  963. ->willReturn($token);
  964. $timeFactory->expects($this->once())
  965. ->method('getTime')
  966. ->willReturn(1000); // more than 5min since last check
  967. $tokenProvider->expects($this->once())
  968. ->method('getPassword')
  969. ->with($token, 'APP-PASSWORD')
  970. ->will($this->throwException(new \OC\Authentication\Exceptions\PasswordlessTokenException()));
  971. $this->invokePrivate($userSession, 'validateSession', [$user]);
  972. $this->assertEquals(1000, $token->getLastCheck());
  973. }
  974. public function testValidateSessionInvalidPassword() {
  975. $userManager = $this->createMock(Manager::class);
  976. $session = $this->createMock(ISession::class);
  977. $timeFactory = $this->createMock(ITimeFactory::class);
  978. $tokenProvider = $this->createMock(IProvider::class);
  979. $userSession = $this->getMockBuilder(Session::class)
  980. ->setConstructorArgs([$userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher])
  981. ->setMethods(['logout'])
  982. ->getMock();
  983. $user = $this->createMock(IUser::class);
  984. $token = new \OC\Authentication\Token\DefaultToken();
  985. $token->setLoginName('susan');
  986. $token->setLastCheck(20);
  987. $session->expects($this->once())
  988. ->method('get')
  989. ->with('app_password')
  990. ->willReturn('APP-PASSWORD');
  991. $tokenProvider->expects($this->once())
  992. ->method('getToken')
  993. ->with('APP-PASSWORD')
  994. ->willReturn($token);
  995. $timeFactory->expects($this->once())
  996. ->method('getTime')
  997. ->willReturn(1000); // more than 5min since last check
  998. $tokenProvider->expects($this->once())
  999. ->method('getPassword')
  1000. ->with($token, 'APP-PASSWORD')
  1001. ->willReturn('123456');
  1002. $userManager->expects($this->once())
  1003. ->method('checkPassword')
  1004. ->with('susan', '123456')
  1005. ->willReturn(false);
  1006. $user->expects($this->once())
  1007. ->method('isEnabled')
  1008. ->willReturn(true);
  1009. $tokenProvider->expects($this->never())
  1010. ->method('invalidateToken');
  1011. $tokenProvider->expects($this->once())
  1012. ->method('markPasswordInvalid')
  1013. ->with($token, 'APP-PASSWORD');
  1014. $userSession->expects($this->once())
  1015. ->method('logout');
  1016. $userSession->setUser($user);
  1017. $this->invokePrivate($userSession, 'validateSession');
  1018. }
  1019. public function testUpdateSessionTokenPassword() {
  1020. $userManager = $this->createMock(Manager::class);
  1021. $session = $this->createMock(ISession::class);
  1022. $timeFactory = $this->createMock(ITimeFactory::class);
  1023. $tokenProvider = $this->createMock(IProvider::class);
  1024. $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  1025. $password = '123456';
  1026. $sessionId = 'session1234';
  1027. $token = new \OC\Authentication\Token\DefaultToken();
  1028. $session->expects($this->once())
  1029. ->method('getId')
  1030. ->willReturn($sessionId);
  1031. $tokenProvider->expects($this->once())
  1032. ->method('getToken')
  1033. ->with($sessionId)
  1034. ->willReturn($token);
  1035. $tokenProvider->expects($this->once())
  1036. ->method('setPassword')
  1037. ->with($token, $sessionId, $password);
  1038. $userSession->updateSessionTokenPassword($password);
  1039. }
  1040. public function testUpdateSessionTokenPasswordNoSessionAvailable() {
  1041. $userManager = $this->createMock(Manager::class);
  1042. $session = $this->createMock(ISession::class);
  1043. $timeFactory = $this->createMock(ITimeFactory::class);
  1044. $tokenProvider = $this->createMock(IProvider::class);
  1045. $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  1046. $session->expects($this->once())
  1047. ->method('getId')
  1048. ->will($this->throwException(new \OCP\Session\Exceptions\SessionNotAvailableException()));
  1049. $userSession->updateSessionTokenPassword('1234');
  1050. }
  1051. public function testUpdateSessionTokenPasswordInvalidTokenException() {
  1052. $userManager = $this->createMock(Manager::class);
  1053. $session = $this->createMock(ISession::class);
  1054. $timeFactory = $this->createMock(ITimeFactory::class);
  1055. $tokenProvider = $this->createMock(IProvider::class);
  1056. $userSession = new \OC\User\Session($userManager, $session, $timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  1057. $password = '123456';
  1058. $sessionId = 'session1234';
  1059. $token = new \OC\Authentication\Token\DefaultToken();
  1060. $session->expects($this->once())
  1061. ->method('getId')
  1062. ->willReturn($sessionId);
  1063. $tokenProvider->expects($this->once())
  1064. ->method('getToken')
  1065. ->with($sessionId)
  1066. ->willReturn($token);
  1067. $tokenProvider->expects($this->once())
  1068. ->method('setPassword')
  1069. ->with($token, $sessionId, $password)
  1070. ->will($this->throwException(new \OC\Authentication\Exceptions\InvalidTokenException()));
  1071. $userSession->updateSessionTokenPassword($password);
  1072. }
  1073. public function testUpdateAuthTokenLastCheck() {
  1074. $manager = $this->createMock(Manager::class);
  1075. $session = $this->createMock(ISession::class);
  1076. $request = $this->createMock(IRequest::class);
  1077. $token = new \OC\Authentication\Token\DefaultToken();
  1078. $token->setUid('john');
  1079. $token->setLoginName('john');
  1080. $token->setLastActivity(100);
  1081. $token->setLastCheck(100);
  1082. $mapper = $this->getMockBuilder(DefaultTokenMapper::class)
  1083. ->disableOriginalConstructor()
  1084. ->getMock();
  1085. $crypto = $this->createMock(ICrypto::class);
  1086. $logger = $this->createMock(ILogger::class);
  1087. $tokenProvider = new DefaultTokenProvider($mapper, $crypto, $this->config, $logger, $this->timeFactory);
  1088. /** @var \OC\User\Session $userSession */
  1089. $userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  1090. $mapper->expects($this->any())
  1091. ->method('getToken')
  1092. ->willReturn($token);
  1093. $mapper->expects($this->once())
  1094. ->method('update');
  1095. $request
  1096. ->expects($this->any())
  1097. ->method('getRemoteAddress')
  1098. ->willReturn('192.168.0.1');
  1099. $this->throttler
  1100. ->expects($this->once())
  1101. ->method('sleepDelay')
  1102. ->with('192.168.0.1');
  1103. $this->throttler
  1104. ->expects($this->any())
  1105. ->method('getDelay')
  1106. ->with('192.168.0.1')
  1107. ->willReturn(0);
  1108. $this->timeFactory
  1109. ->expects($this->any())
  1110. ->method('getTime')
  1111. ->willReturn(100);
  1112. $manager->method('getByEmail')
  1113. ->with('john')
  1114. ->willReturn([]);
  1115. $userSession->logClientIn('john', 'doe', $request, $this->throttler);
  1116. $this->assertEquals(10000, $token->getLastActivity());
  1117. $this->assertEquals(10000, $token->getLastCheck());
  1118. }
  1119. public function testNoUpdateAuthTokenLastCheckRecent() {
  1120. $manager = $this->createMock(Manager::class);
  1121. $session = $this->createMock(ISession::class);
  1122. $request = $this->createMock(IRequest::class);
  1123. $token = new \OC\Authentication\Token\DefaultToken();
  1124. $token->setUid('john');
  1125. $token->setLoginName('john');
  1126. $token->setLastActivity(10000);
  1127. $token->setLastCheck(100);
  1128. $mapper = $this->getMockBuilder(DefaultTokenMapper::class)
  1129. ->disableOriginalConstructor()
  1130. ->getMock();
  1131. $crypto = $this->createMock(ICrypto::class);
  1132. $logger = $this->createMock(ILogger::class);
  1133. $tokenProvider = new DefaultTokenProvider($mapper, $crypto, $this->config, $logger, $this->timeFactory);
  1134. /** @var \OC\User\Session $userSession */
  1135. $userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  1136. $mapper->expects($this->any())
  1137. ->method('getToken')
  1138. ->willReturn($token);
  1139. $mapper->expects($this->never())
  1140. ->method('update');
  1141. $request
  1142. ->expects($this->any())
  1143. ->method('getRemoteAddress')
  1144. ->willReturn('192.168.0.1');
  1145. $this->throttler
  1146. ->expects($this->once())
  1147. ->method('sleepDelay')
  1148. ->with('192.168.0.1');
  1149. $this->throttler
  1150. ->expects($this->any())
  1151. ->method('getDelay')
  1152. ->with('192.168.0.1')
  1153. ->willReturn(0);
  1154. $this->timeFactory
  1155. ->expects($this->any())
  1156. ->method('getTime')
  1157. ->willReturn(100);
  1158. $manager->method('getByEmail')
  1159. ->with('john')
  1160. ->willReturn([]);
  1161. $userSession->logClientIn('john', 'doe', $request, $this->throttler);
  1162. }
  1163. public function testCreateRememberMeToken() {
  1164. $user = $this->createMock(IUser::class);
  1165. $user
  1166. ->expects($this->exactly(2))
  1167. ->method('getUID')
  1168. ->willReturn('UserUid');
  1169. $this->random
  1170. ->expects($this->once())
  1171. ->method('generate')
  1172. ->with(32)
  1173. ->willReturn('LongRandomToken');
  1174. $this->config
  1175. ->expects($this->once())
  1176. ->method('setUserValue')
  1177. ->with('UserUid', 'login_token', 'LongRandomToken', 10000);
  1178. $this->userSession
  1179. ->expects($this->once())
  1180. ->method('setMagicInCookie')
  1181. ->with('UserUid', 'LongRandomToken');
  1182. $this->userSession->createRememberMeToken($user);
  1183. }
  1184. public function testTryBasicAuthLoginValid() {
  1185. $request = $this->createMock(Request::class);
  1186. $request->method('__get')
  1187. ->willReturn([
  1188. 'PHP_AUTH_USER' => 'username',
  1189. 'PHP_AUTH_PW' => 'password',
  1190. ]);
  1191. $request->method('__isset')
  1192. ->with('server')
  1193. ->willReturn(true);
  1194. $davAuthenticatedSet = false;
  1195. $lastPasswordConfirmSet = false;
  1196. $this->session
  1197. ->method('set')
  1198. ->willReturnCallback(function ($k, $v) use (&$davAuthenticatedSet, &$lastPasswordConfirmSet) {
  1199. switch ($k) {
  1200. case Auth::DAV_AUTHENTICATED:
  1201. $davAuthenticatedSet = $v;
  1202. return;
  1203. case 'last-password-confirm':
  1204. $lastPasswordConfirmSet = 1000;
  1205. return;
  1206. default:
  1207. throw new \Exception();
  1208. }
  1209. });
  1210. $userSession = $this->getMockBuilder(Session::class)
  1211. ->setConstructorArgs([
  1212. $this->manager,
  1213. $this->session,
  1214. $this->timeFactory,
  1215. $this->tokenProvider,
  1216. $this->config,
  1217. $this->random,
  1218. $this->lockdownManager,
  1219. $this->logger,
  1220. $this->dispatcher
  1221. ])
  1222. ->setMethods([
  1223. 'logClientIn',
  1224. 'getUser',
  1225. ])
  1226. ->getMock();
  1227. /** @var Session|MockObject */
  1228. $userSession->expects($this->once())
  1229. ->method('logClientIn')
  1230. ->with(
  1231. $this->equalTo('username'),
  1232. $this->equalTo('password'),
  1233. $this->equalTo($request),
  1234. $this->equalTo($this->throttler)
  1235. )->willReturn(true);
  1236. $user = $this->createMock(IUser::class);
  1237. $user->method('getUID')->willReturn('username');
  1238. $userSession->expects($this->once())
  1239. ->method('getUser')
  1240. ->willReturn($user);
  1241. $this->assertTrue($userSession->tryBasicAuthLogin($request, $this->throttler));
  1242. $this->assertSame('username', $davAuthenticatedSet);
  1243. $this->assertSame(1000, $lastPasswordConfirmSet);
  1244. }
  1245. public function testTryBasicAuthLoginNoLogin() {
  1246. $request = $this->createMock(Request::class);
  1247. $request->method('__get')
  1248. ->willReturn([]);
  1249. $request->method('__isset')
  1250. ->with('server')
  1251. ->willReturn(true);
  1252. $this->session->expects($this->never())
  1253. ->method($this->anything());
  1254. $userSession = $this->getMockBuilder(Session::class)
  1255. ->setConstructorArgs([
  1256. $this->manager,
  1257. $this->session,
  1258. $this->timeFactory,
  1259. $this->tokenProvider,
  1260. $this->config,
  1261. $this->random,
  1262. $this->lockdownManager,
  1263. $this->logger,
  1264. $this->dispatcher
  1265. ])
  1266. ->setMethods([
  1267. 'logClientIn',
  1268. ])
  1269. ->getMock();
  1270. /** @var Session|MockObject */
  1271. $userSession->expects($this->never())
  1272. ->method('logClientIn');
  1273. $this->assertFalse($userSession->tryBasicAuthLogin($request, $this->throttler));
  1274. }
  1275. public function testUpdateTokens() {
  1276. $this->tokenProvider->expects($this->once())
  1277. ->method('updatePasswords')
  1278. ->with('uid', 'pass');
  1279. $this->userSession->updateTokens('uid', 'pass');
  1280. }
  1281. }