SessionTest.php 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466
  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. ->willReturn(5);
  1104. $this->timeFactory
  1105. ->expects($this->any())
  1106. ->method('getTime')
  1107. ->willReturn(100);
  1108. $manager->method('getByEmail')
  1109. ->with('john')
  1110. ->willReturn([]);
  1111. $userSession->logClientIn('john', 'doe', $request, $this->throttler);
  1112. $this->assertEquals(10000, $token->getLastActivity());
  1113. $this->assertEquals(10000, $token->getLastCheck());
  1114. }
  1115. public function testNoUpdateAuthTokenLastCheckRecent() {
  1116. $manager = $this->createMock(Manager::class);
  1117. $session = $this->createMock(ISession::class);
  1118. $request = $this->createMock(IRequest::class);
  1119. $token = new \OC\Authentication\Token\DefaultToken();
  1120. $token->setUid('john');
  1121. $token->setLoginName('john');
  1122. $token->setLastActivity(10000);
  1123. $token->setLastCheck(100);
  1124. $mapper = $this->getMockBuilder(DefaultTokenMapper::class)
  1125. ->disableOriginalConstructor()
  1126. ->getMock();
  1127. $crypto = $this->createMock(ICrypto::class);
  1128. $logger = $this->createMock(ILogger::class);
  1129. $tokenProvider = new DefaultTokenProvider($mapper, $crypto, $this->config, $logger, $this->timeFactory);
  1130. /** @var \OC\User\Session $userSession */
  1131. $userSession = new Session($manager, $session, $this->timeFactory, $tokenProvider, $this->config, $this->random, $this->lockdownManager, $this->logger, $this->dispatcher);
  1132. $mapper->expects($this->any())
  1133. ->method('getToken')
  1134. ->willReturn($token);
  1135. $mapper->expects($this->never())
  1136. ->method('update');
  1137. $request
  1138. ->expects($this->any())
  1139. ->method('getRemoteAddress')
  1140. ->willReturn('192.168.0.1');
  1141. $this->throttler
  1142. ->expects($this->once())
  1143. ->method('sleepDelay')
  1144. ->with('192.168.0.1')
  1145. ->willReturn(5);
  1146. $this->timeFactory
  1147. ->expects($this->any())
  1148. ->method('getTime')
  1149. ->willReturn(100);
  1150. $manager->method('getByEmail')
  1151. ->with('john')
  1152. ->willReturn([]);
  1153. $userSession->logClientIn('john', 'doe', $request, $this->throttler);
  1154. }
  1155. public function testCreateRememberMeToken() {
  1156. $user = $this->createMock(IUser::class);
  1157. $user
  1158. ->expects($this->exactly(2))
  1159. ->method('getUID')
  1160. ->willReturn('UserUid');
  1161. $this->random
  1162. ->expects($this->once())
  1163. ->method('generate')
  1164. ->with(32)
  1165. ->willReturn('LongRandomToken');
  1166. $this->config
  1167. ->expects($this->once())
  1168. ->method('setUserValue')
  1169. ->with('UserUid', 'login_token', 'LongRandomToken', 10000);
  1170. $this->userSession
  1171. ->expects($this->once())
  1172. ->method('setMagicInCookie')
  1173. ->with('UserUid', 'LongRandomToken');
  1174. $this->userSession->createRememberMeToken($user);
  1175. }
  1176. public function testTryBasicAuthLoginValid() {
  1177. $request = $this->createMock(Request::class);
  1178. $request->method('__get')
  1179. ->willReturn([
  1180. 'PHP_AUTH_USER' => 'username',
  1181. 'PHP_AUTH_PW' => 'password',
  1182. ]);
  1183. $request->method('__isset')
  1184. ->with('server')
  1185. ->willReturn(true);
  1186. $davAuthenticatedSet = false;
  1187. $lastPasswordConfirmSet = false;
  1188. $this->session
  1189. ->method('set')
  1190. ->willReturnCallback(function ($k, $v) use (&$davAuthenticatedSet, &$lastPasswordConfirmSet) {
  1191. switch ($k) {
  1192. case Auth::DAV_AUTHENTICATED:
  1193. $davAuthenticatedSet = $v;
  1194. return;
  1195. case 'last-password-confirm':
  1196. $lastPasswordConfirmSet = 1000;
  1197. return;
  1198. default:
  1199. throw new \Exception();
  1200. }
  1201. });
  1202. $userSession = $this->getMockBuilder(Session::class)
  1203. ->setConstructorArgs([
  1204. $this->manager,
  1205. $this->session,
  1206. $this->timeFactory,
  1207. $this->tokenProvider,
  1208. $this->config,
  1209. $this->random,
  1210. $this->lockdownManager,
  1211. $this->logger,
  1212. $this->dispatcher
  1213. ])
  1214. ->setMethods([
  1215. 'logClientIn',
  1216. 'getUser',
  1217. ])
  1218. ->getMock();
  1219. /** @var Session|MockObject */
  1220. $userSession->expects($this->once())
  1221. ->method('logClientIn')
  1222. ->with(
  1223. $this->equalTo('username'),
  1224. $this->equalTo('password'),
  1225. $this->equalTo($request),
  1226. $this->equalTo($this->throttler)
  1227. )->willReturn(true);
  1228. $user = $this->createMock(IUser::class);
  1229. $user->method('getUID')->willReturn('username');
  1230. $userSession->expects($this->once())
  1231. ->method('getUser')
  1232. ->willReturn($user);
  1233. $this->assertTrue($userSession->tryBasicAuthLogin($request, $this->throttler));
  1234. $this->assertSame('username', $davAuthenticatedSet);
  1235. $this->assertSame(1000, $lastPasswordConfirmSet);
  1236. }
  1237. public function testTryBasicAuthLoginNoLogin() {
  1238. $request = $this->createMock(Request::class);
  1239. $request->method('__get')
  1240. ->willReturn([]);
  1241. $request->method('__isset')
  1242. ->with('server')
  1243. ->willReturn(true);
  1244. $this->session->expects($this->never())
  1245. ->method($this->anything());
  1246. $userSession = $this->getMockBuilder(Session::class)
  1247. ->setConstructorArgs([
  1248. $this->manager,
  1249. $this->session,
  1250. $this->timeFactory,
  1251. $this->tokenProvider,
  1252. $this->config,
  1253. $this->random,
  1254. $this->lockdownManager,
  1255. $this->logger,
  1256. $this->dispatcher
  1257. ])
  1258. ->setMethods([
  1259. 'logClientIn',
  1260. ])
  1261. ->getMock();
  1262. /** @var Session|MockObject */
  1263. $userSession->expects($this->never())
  1264. ->method('logClientIn');
  1265. $this->assertFalse($userSession->tryBasicAuthLogin($request, $this->throttler));
  1266. }
  1267. public function testUpdateTokens() {
  1268. $this->tokenProvider->expects($this->once())
  1269. ->method('updatePasswords')
  1270. ->with('uid', 'pass');
  1271. $this->userSession->updateTokens('uid', 'pass');
  1272. }
  1273. }