TokenUserContextTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Webapi\Test\Unit\Model\Authorization;
  7. use Magento\Webapi\Model\Authorization\TokenUserContext;
  8. use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
  9. use Magento\Authorization\Model\UserContextInterface;
  10. use Magento\Integration\Model\Oauth\TokenFactory;
  11. use Magento\Integration\Model\Oauth\Token;
  12. use Magento\Integration\Api\IntegrationServiceInterface;
  13. use Magento\Framework\Webapi\Request;
  14. use Magento\Integration\Helper\Oauth\Data as OauthHelper;
  15. use Magento\Framework\Stdlib\DateTime\DateTime as Date;
  16. use Magento\Framework\Stdlib\DateTime;
  17. use Magento\Integration\Model\Integration;
  18. /**
  19. * Tests for TokenUserContext.
  20. */
  21. class TokenUserContextTest extends \PHPUnit\Framework\TestCase
  22. {
  23. /**
  24. * @var ObjectManager
  25. */
  26. protected $objectManager;
  27. /**
  28. * @var TokenUserContext
  29. */
  30. protected $tokenUserContext;
  31. /**
  32. * @var TokenFactory|\PHPUnit_Framework_MockObject_MockObject
  33. */
  34. protected $tokenFactory;
  35. /**
  36. * @var IntegrationServiceInterface|\PHPUnit_Framework_MockObject_MockObject
  37. */
  38. protected $integrationService;
  39. /**
  40. * @var Request|\PHPUnit_Framework_MockObject_MockObject
  41. */
  42. protected $request;
  43. /**
  44. * @var OauthHelper|\PHPUnit_Framework_MockObject_MockObject
  45. */
  46. private $oauthHelperMock;
  47. /**
  48. * @var Date|\PHPUnit_Framework_MockObject_MockObject
  49. */
  50. private $dateMock;
  51. /**
  52. * @var DateTime|\PHPUnit_Framework_MockObject_MockObject
  53. */
  54. private $dateTimeMock;
  55. protected function setUp()
  56. {
  57. $this->objectManager = new ObjectManager($this);
  58. $this->request = $this->getMockBuilder(Request::class)
  59. ->disableOriginalConstructor()
  60. ->setMethods(['getHeader'])
  61. ->getMock();
  62. $this->tokenFactory = $this->getMockBuilder(TokenFactory::class)
  63. ->disableOriginalConstructor()
  64. ->setMethods(['create'])
  65. ->getMock();
  66. $this->integrationService = $this->getMockBuilder(IntegrationServiceInterface::class)
  67. ->disableOriginalConstructor()
  68. ->setMethods(
  69. [
  70. 'findByName',
  71. 'update',
  72. 'create',
  73. 'get',
  74. 'findByConsumerId',
  75. 'findActiveIntegrationByConsumerId',
  76. 'delete',
  77. 'getSelectedResources',
  78. ]
  79. )
  80. ->getMock();
  81. $this->oauthHelperMock = $this->getMockBuilder(OauthHelper::class)
  82. ->disableOriginalConstructor()
  83. ->setMethods(['getAdminTokenLifetime', 'getCustomerTokenLifetime'])
  84. ->getMock();
  85. $this->dateMock = $this->getMockBuilder(Date::class)
  86. ->disableOriginalConstructor()
  87. ->setMethods(['gmtTimestamp'])
  88. ->getMock();
  89. $this->dateTimeMock = $this->getMockBuilder(DateTime::class)
  90. ->disableOriginalConstructor()
  91. ->setMethods(['strToTime'])
  92. ->getMock();
  93. $this->dateTimeMock->expects($this->any())
  94. ->method('strToTime')
  95. ->will(
  96. $this->returnCallback(
  97. function ($str) {
  98. return strtotime($str);
  99. }
  100. )
  101. );
  102. $this->tokenUserContext = $this->objectManager->getObject(
  103. TokenUserContext::class,
  104. [
  105. 'request' => $this->request,
  106. 'tokenFactory' => $this->tokenFactory,
  107. 'integrationService' => $this->integrationService,
  108. 'oauthHelper' => $this->oauthHelperMock,
  109. 'date' => $this->dateMock,
  110. 'dateTime' => $this->dateTimeMock,
  111. ]
  112. );
  113. }
  114. public function testNoAuthorizationHeader()
  115. {
  116. $this->request->expects($this->once())
  117. ->method('getHeader')
  118. ->with('Authorization')
  119. ->will($this->returnValue(null));
  120. $this->assertNull($this->tokenUserContext->getUserType());
  121. $this->assertNull($this->tokenUserContext->getUserId());
  122. }
  123. public function testNoTokenInHeader()
  124. {
  125. $this->request->expects($this->once())
  126. ->method('getHeader')
  127. ->with('Authorization')
  128. ->will($this->returnValue('Bearer'));
  129. $this->assertNull($this->tokenUserContext->getUserType());
  130. $this->assertNull($this->tokenUserContext->getUserId());
  131. }
  132. public function testNotBearerToken()
  133. {
  134. $this->request->expects($this->once())
  135. ->method('getHeader')
  136. ->with('Authorization')
  137. ->will($this->returnValue('Access'));
  138. $this->assertNull($this->tokenUserContext->getUserType());
  139. $this->assertNull($this->tokenUserContext->getUserId());
  140. }
  141. public function testNoTokenInDatabase()
  142. {
  143. $bearerToken = 'bearer1234';
  144. $this->request->expects($this->once())
  145. ->method('getHeader')
  146. ->with('Authorization')
  147. ->will($this->returnValue("Bearer {$bearerToken}"));
  148. $token = $this->getMockBuilder(Token::class)
  149. ->disableOriginalConstructor()
  150. ->setMethods(['loadByToken', 'getId', '__wakeup'])
  151. ->getMock();
  152. $this->tokenFactory->expects($this->once())
  153. ->method('create')
  154. ->will($this->returnValue($token));
  155. $token->expects($this->once())
  156. ->method('loadByToken')
  157. ->with($bearerToken)
  158. ->will($this->returnSelf());
  159. $token->expects($this->once())
  160. ->method('getId')
  161. ->will($this->returnValue(null));
  162. $this->assertNull($this->tokenUserContext->getUserType());
  163. $this->assertNull($this->tokenUserContext->getUserId());
  164. }
  165. public function testRevokedToken()
  166. {
  167. $bearerToken = 'bearer1234';
  168. $this->request->expects($this->once())
  169. ->method('getHeader')
  170. ->with('Authorization')
  171. ->will($this->returnValue("Bearer {$bearerToken}"));
  172. $token = $this->getMockBuilder(Token::class)
  173. ->disableOriginalConstructor()
  174. ->setMethods(['loadByToken', 'getId', 'getRevoked', '__wakeup'])
  175. ->getMock();
  176. $this->tokenFactory->expects($this->once())
  177. ->method('create')
  178. ->will($this->returnValue($token));
  179. $token->expects($this->once())
  180. ->method('loadByToken')
  181. ->with($bearerToken)
  182. ->will($this->returnSelf());
  183. $token->expects($this->once())
  184. ->method('getId')
  185. ->will($this->returnValue(1));
  186. $token->expects($this->once())
  187. ->method('getRevoked')
  188. ->will($this->returnValue(1));
  189. $this->assertNull($this->tokenUserContext->getUserType());
  190. $this->assertNull($this->tokenUserContext->getUserId());
  191. }
  192. /**
  193. * @dataProvider getValidTokenData
  194. */
  195. public function testValidToken($userType, $userId, $expectedUserType, $expectedUserId)
  196. {
  197. $bearerToken = 'bearer1234';
  198. $this->request->expects($this->once())
  199. ->method('getHeader')
  200. ->with('Authorization')
  201. ->will($this->returnValue("Bearer {$bearerToken}"));
  202. $token = $this->getMockBuilder(Token::class)
  203. ->disableOriginalConstructor()
  204. ->setMethods(
  205. [
  206. 'loadByToken',
  207. 'getId',
  208. 'getUserType',
  209. 'getCustomerId',
  210. 'getAdminId',
  211. '__wakeup',
  212. 'getCreatedAt',
  213. ]
  214. )->getMock();
  215. $this->tokenFactory->expects($this->once())
  216. ->method('create')
  217. ->will($this->returnValue($token));
  218. $token->expects($this->once())
  219. ->method('loadByToken')
  220. ->with($bearerToken)
  221. ->will($this->returnSelf());
  222. $token->expects($this->once())
  223. ->method('getId')
  224. ->will($this->returnValue(1));
  225. $token->expects($this->any())
  226. ->method('getUserType')
  227. ->will($this->returnValue($userType));
  228. $token->expects($this->any())
  229. ->method('getCreatedAt')
  230. ->willReturn(date('Y-m-d H:i:s', time()));
  231. switch ($userType) {
  232. case UserContextInterface::USER_TYPE_INTEGRATION:
  233. $integration = $this->getMockBuilder(Integration::class)
  234. ->disableOriginalConstructor()
  235. ->setMethods(['getId', '__wakeup'])
  236. ->getMock();
  237. $integration->expects($this->once())
  238. ->method('getId')
  239. ->will($this->returnValue($userId));
  240. $this->integrationService->expects($this->once())
  241. ->method('findByConsumerId')
  242. ->will($this->returnValue($integration));
  243. break;
  244. case UserContextInterface::USER_TYPE_ADMIN:
  245. $token->expects($this->once())
  246. ->method('getAdminId')
  247. ->will($this->returnValue($userId));
  248. break;
  249. case UserContextInterface::USER_TYPE_CUSTOMER:
  250. $token->expects($this->once())
  251. ->method('getCustomerId')
  252. ->will($this->returnValue($userId));
  253. break;
  254. }
  255. $this->assertEquals($expectedUserType, $this->tokenUserContext->getUserType());
  256. $this->assertEquals($expectedUserId, $this->tokenUserContext->getUserId());
  257. /* check again to make sure that the above methods were only called once */
  258. $this->assertEquals($expectedUserType, $this->tokenUserContext->getUserType());
  259. $this->assertEquals($expectedUserId, $this->tokenUserContext->getUserId());
  260. }
  261. /**
  262. * @return array
  263. */
  264. public function getValidTokenData()
  265. {
  266. return [
  267. 'admin token' => [
  268. UserContextInterface::USER_TYPE_ADMIN,
  269. 1234,
  270. UserContextInterface::USER_TYPE_ADMIN,
  271. 1234,
  272. ],
  273. 'customer token' => [
  274. UserContextInterface::USER_TYPE_CUSTOMER,
  275. 1234,
  276. UserContextInterface::USER_TYPE_CUSTOMER,
  277. 1234,
  278. ],
  279. 'integration token' => [
  280. UserContextInterface::USER_TYPE_INTEGRATION,
  281. 1234,
  282. UserContextInterface::USER_TYPE_INTEGRATION,
  283. 1234,
  284. ],
  285. 'guest user type' => [
  286. UserContextInterface::USER_TYPE_GUEST,
  287. 1234,
  288. null,
  289. null,
  290. ]
  291. ];
  292. }
  293. /**
  294. * @param array $tokenData
  295. * @param int $tokenTtl
  296. * @param int $currentTime
  297. * @param int|null $expectedUserType
  298. * @param int|null $expectedUserId
  299. * @return void
  300. * @dataProvider getExpiredTestTokenData
  301. */
  302. public function testExpiredToken(
  303. array $tokenData,
  304. int $tokenTtl,
  305. int $currentTime,
  306. $expectedUserType,
  307. $expectedUserId
  308. ) {
  309. $bearerToken = 'bearer1234';
  310. $this->dateMock->expects($this->any())
  311. ->method('gmtTimestamp')
  312. ->willReturn($currentTime);
  313. $this->request->expects($this->once())
  314. ->method('getHeader')
  315. ->with('Authorization')
  316. ->will($this->returnValue("Bearer {$bearerToken}"));
  317. $token = $this->getMockBuilder(Token::class)
  318. ->disableOriginalConstructor()
  319. ->setMethods(
  320. [
  321. 'loadByToken',
  322. 'getCreatedAt',
  323. 'getId',
  324. 'getUserType',
  325. 'getCustomerId',
  326. 'getAdminId',
  327. '__wakeup',
  328. ]
  329. )->getMock();
  330. $token->expects($this->once())
  331. ->method('loadByToken')
  332. ->with($bearerToken)
  333. ->will($this->returnSelf());
  334. $token->expects($this->any())
  335. ->method('getId')
  336. ->will($this->returnValue(1));
  337. $token->expects($this->any())
  338. ->method('getUserType')
  339. ->will($this->returnValue($tokenData['user_type']));
  340. $token->expects($this->any())
  341. ->method('getCreatedAt')
  342. ->willReturn($tokenData['created_at']);
  343. $this->tokenFactory->expects($this->once())
  344. ->method('create')
  345. ->will($this->returnValue($token));
  346. $this->oauthHelperMock->expects($this->any())
  347. ->method('getAdminTokenLifetime')
  348. ->willReturn($tokenTtl);
  349. $this->oauthHelperMock->expects($this->any())
  350. ->method('getCustomerTokenLifetime')
  351. ->willReturn($tokenTtl);
  352. switch ($tokenData['user_type']) {
  353. case UserContextInterface::USER_TYPE_INTEGRATION:
  354. $integration = $this->getMockBuilder(Integration::class)
  355. ->disableOriginalConstructor()
  356. ->setMethods(['getId', '__wakeup'])
  357. ->getMock();
  358. $integration->expects($this->any())
  359. ->method('getId')
  360. ->will($this->returnValue($tokenData['user_id']));
  361. $this->integrationService->expects($this->any())
  362. ->method('findByConsumerId')
  363. ->will($this->returnValue($integration));
  364. break;
  365. case UserContextInterface::USER_TYPE_ADMIN:
  366. $token->expects($this->any())
  367. ->method('getAdminId')
  368. ->will($this->returnValue($tokenData['user_id']));
  369. break;
  370. case UserContextInterface::USER_TYPE_CUSTOMER:
  371. $token->expects($this->any())
  372. ->method('getCustomerId')
  373. ->will($this->returnValue($tokenData['user_id']));
  374. break;
  375. }
  376. $this->assertEquals($expectedUserType, $this->tokenUserContext->getUserType());
  377. $this->assertEquals($expectedUserId, $this->tokenUserContext->getUserId());
  378. /* check again to make sure that the above method loadByToken in only called once */
  379. $this->assertEquals($expectedUserType, $this->tokenUserContext->getUserType());
  380. $this->assertEquals($expectedUserId, $this->tokenUserContext->getUserId());
  381. }
  382. /**
  383. * Data provider for expired token test.
  384. *
  385. * @return array
  386. */
  387. public function getExpiredTestTokenData()
  388. {
  389. $time = time();
  390. return [
  391. 'token_expired_admin' => [
  392. 'tokenData' => [
  393. 'user_type' => UserContextInterface::USER_TYPE_ADMIN,
  394. 'user_id' => 1234,
  395. 'created_at' => date('Y-m-d H:i:s', $time - 3600 - 400),
  396. ],
  397. 'tokenTtl' => 1,
  398. 'currentTime' => $time,
  399. 'expectedUserType' => null,
  400. 'expectedUserId' => null,
  401. ],
  402. 'token_vigent_admin' => [
  403. 'tokenData' => [
  404. 'user_type' => UserContextInterface::USER_TYPE_ADMIN,
  405. 'user_id' => 1234,
  406. 'created_at' => date('Y-m-d H:i:s', $time - 400),
  407. ],
  408. 'tokenTtl' => 1,
  409. 'currentTime' => $time,
  410. 'expectedUserType' => UserContextInterface::USER_TYPE_ADMIN,
  411. 'expectedUserId' => 1234,
  412. ],
  413. 'token_expired_customer' => [
  414. 'tokenData' => [
  415. 'user_type' => UserContextInterface::USER_TYPE_CUSTOMER,
  416. 'user_id' => 1234,
  417. 'created_at' => date('Y-m-d H:i:s', $time - 3600 - 400),
  418. ],
  419. 'tokenTtl' => 1,
  420. 'currentTime' => $time,
  421. 'expectedUserType' => null,
  422. 'expectedUserId' => null,
  423. ],
  424. 'token_vigent_customer' => [
  425. 'tokenData' => [
  426. 'user_type' => UserContextInterface::USER_TYPE_CUSTOMER,
  427. 'user_id' => 1234,
  428. 'created_at' => date('Y-m-d H:i:s', $time - 400),
  429. ],
  430. 'tokenTtl' => 1,
  431. 'currentTime' => $time,
  432. 'expectedUserType' => UserContextInterface::USER_TYPE_CUSTOMER,
  433. 'expectedUserId' => 1234,
  434. ],
  435. 'token_expired_integration' => [
  436. 'tokenData' => [
  437. 'user_type' => UserContextInterface::USER_TYPE_INTEGRATION,
  438. 'user_id' => 1234,
  439. 'created_at' => date('Y-m-d H:i:s', $time - 3600 - 400),
  440. ],
  441. 'tokenTtl' => 1,
  442. 'currentTime' => $time,
  443. 'expectedUserType' => UserContextInterface::USER_TYPE_INTEGRATION,
  444. 'expectedUserId' => 1234,
  445. ],
  446. 'token_vigent_integration' => [
  447. 'tokenData' => [
  448. 'user_type' => UserContextInterface::USER_TYPE_INTEGRATION,
  449. 'user_id' => 1234,
  450. 'created_at' => date('Y-m-d H:i:s', $time - 400),
  451. ],
  452. 'tokenTtl' => 1,
  453. 'currentTime' => $time,
  454. 'expectedUserType' => UserContextInterface::USER_TYPE_INTEGRATION,
  455. 'expectedUserId' => 1234,
  456. ],
  457. 'token_expired_guest' => [
  458. 'tokenData' => [
  459. 'user_type' => UserContextInterface::USER_TYPE_GUEST,
  460. 'user_id' => 1234,
  461. 'created_at' => date('Y-m-d H:i:s', $time - 3600 - 400),
  462. ],
  463. 'tokenTtl' => 1,
  464. 'currentTime' => $time,
  465. 'expectedUserType' => null,
  466. 'expectedUserId' => null,
  467. ],
  468. 'token_vigent_guest' => [
  469. 'tokenData' => [
  470. 'user_type' => UserContextInterface::USER_TYPE_GUEST,
  471. 'user_id' => 1234,
  472. 'created_at' => date('Y-m-d H:i:s', $time - 400),
  473. ],
  474. 'tokenTtl' => 1,
  475. 'currentTime' => $time,
  476. 'expectedUserType' => null,
  477. 'expectedUserId' => null,
  478. ],
  479. ];
  480. }
  481. }