SessionTest.php 52 KB

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