TokenUserContext.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Webapi\Model\Authorization;
  7. use Magento\Authorization\Model\UserContextInterface;
  8. use Magento\Framework\App\ObjectManager;
  9. use Magento\Integration\Model\Oauth\Token;
  10. use Magento\Integration\Model\Oauth\TokenFactory;
  11. use Magento\Integration\Api\IntegrationServiceInterface;
  12. use Magento\Framework\Webapi\Request;
  13. use Magento\Framework\Stdlib\DateTime\DateTime as Date;
  14. use Magento\Framework\Stdlib\DateTime;
  15. use Magento\Integration\Helper\Oauth\Data as OauthHelper;
  16. /**
  17. * A user context determined by tokens in a HTTP request Authorization header.
  18. */
  19. class TokenUserContext implements UserContextInterface
  20. {
  21. /**
  22. * @var Request
  23. */
  24. protected $request;
  25. /**
  26. * @var Token
  27. */
  28. protected $tokenFactory;
  29. /**
  30. * @var int
  31. */
  32. protected $userId;
  33. /**
  34. * @var string
  35. */
  36. protected $userType;
  37. /**
  38. * @var bool
  39. */
  40. protected $isRequestProcessed;
  41. /**
  42. * @var IntegrationServiceInterface
  43. */
  44. protected $integrationService;
  45. /**
  46. * @var DateTime
  47. */
  48. private $dateTime;
  49. /**
  50. * @var Date
  51. */
  52. private $date;
  53. /**
  54. * @var OauthHelper
  55. */
  56. private $oauthHelper;
  57. /**
  58. * Initialize dependencies.
  59. *
  60. * @param Request $request
  61. * @param TokenFactory $tokenFactory
  62. * @param IntegrationServiceInterface $integrationService
  63. * @param DateTime|null $dateTime
  64. * @param Date|null $date
  65. * @param OauthHelper|null $oauthHelper
  66. */
  67. public function __construct(
  68. Request $request,
  69. TokenFactory $tokenFactory,
  70. IntegrationServiceInterface $integrationService,
  71. DateTime $dateTime = null,
  72. Date $date = null,
  73. OauthHelper $oauthHelper = null
  74. ) {
  75. $this->request = $request;
  76. $this->tokenFactory = $tokenFactory;
  77. $this->integrationService = $integrationService;
  78. $this->dateTime = $dateTime ?: ObjectManager::getInstance()->get(
  79. DateTime::class
  80. );
  81. $this->date = $date ?: ObjectManager::getInstance()->get(
  82. Date::class
  83. );
  84. $this->oauthHelper = $oauthHelper ?: ObjectManager::getInstance()->get(
  85. OauthHelper::class
  86. );
  87. }
  88. /**
  89. * {@inheritdoc}
  90. */
  91. public function getUserId()
  92. {
  93. $this->processRequest();
  94. return $this->userId;
  95. }
  96. /**
  97. * {@inheritdoc}
  98. */
  99. public function getUserType()
  100. {
  101. $this->processRequest();
  102. return $this->userType;
  103. }
  104. /**
  105. * Check if token is expired.
  106. *
  107. * @param Token $token
  108. * @return bool
  109. */
  110. private function isTokenExpired(Token $token): bool
  111. {
  112. if ($token->getUserType() == UserContextInterface::USER_TYPE_ADMIN) {
  113. $tokenTtl = $this->oauthHelper->getAdminTokenLifetime();
  114. } elseif ($token->getUserType() == UserContextInterface::USER_TYPE_CUSTOMER) {
  115. $tokenTtl = $this->oauthHelper->getCustomerTokenLifetime();
  116. } else {
  117. // other user-type tokens are considered always valid
  118. return false;
  119. }
  120. if (empty($tokenTtl)) {
  121. return false;
  122. }
  123. if ($this->dateTime->strToTime($token->getCreatedAt()) < ($this->date->gmtTimestamp() - $tokenTtl * 3600)) {
  124. return true;
  125. }
  126. return false;
  127. }
  128. /**
  129. * Finds the bearer token and looks up the value.
  130. *
  131. * @return void
  132. */
  133. protected function processRequest()
  134. {
  135. if ($this->isRequestProcessed) {
  136. return;
  137. }
  138. $authorizationHeaderValue = $this->request->getHeader('Authorization');
  139. if (!$authorizationHeaderValue) {
  140. $this->isRequestProcessed = true;
  141. return;
  142. }
  143. $headerPieces = explode(" ", $authorizationHeaderValue);
  144. if (count($headerPieces) !== 2) {
  145. $this->isRequestProcessed = true;
  146. return;
  147. }
  148. $tokenType = strtolower($headerPieces[0]);
  149. if ($tokenType !== 'bearer') {
  150. $this->isRequestProcessed = true;
  151. return;
  152. }
  153. $bearerToken = $headerPieces[1];
  154. $token = $this->tokenFactory->create()->loadByToken($bearerToken);
  155. if (!$token->getId() || $token->getRevoked() || $this->isTokenExpired($token)) {
  156. $this->isRequestProcessed = true;
  157. return;
  158. }
  159. $this->setUserDataViaToken($token);
  160. $this->isRequestProcessed = true;
  161. }
  162. /**
  163. * @param Token $token
  164. * @return void
  165. */
  166. protected function setUserDataViaToken(Token $token)
  167. {
  168. $this->userType = $token->getUserType();
  169. switch ($this->userType) {
  170. case UserContextInterface::USER_TYPE_INTEGRATION:
  171. $this->userId = $this->integrationService->findByConsumerId($token->getConsumerId())->getId();
  172. $this->userType = UserContextInterface::USER_TYPE_INTEGRATION;
  173. break;
  174. case UserContextInterface::USER_TYPE_ADMIN:
  175. $this->userId = $token->getAdminId();
  176. $this->userType = UserContextInterface::USER_TYPE_ADMIN;
  177. break;
  178. case UserContextInterface::USER_TYPE_CUSTOMER:
  179. $this->userId = $token->getCustomerId();
  180. $this->userType = UserContextInterface::USER_TYPE_CUSTOMER;
  181. break;
  182. default:
  183. /* this is an unknown user type so reset the cached user type */
  184. $this->userType = null;
  185. }
  186. }
  187. }