Authentication.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. /**
  3. * Refer to LICENSE.txt distributed with the Temando Shipping module for notice of license
  4. */
  5. namespace Temando\Shipping\Rest;
  6. use Magento\Framework\Exception\AuthenticationException;
  7. use Magento\Framework\Exception\InputException;
  8. use Magento\Framework\Session\SessionManagerInterface;
  9. use Magento\Framework\Stdlib\DateTime\DateTime;
  10. use Temando\Shipping\Rest\Adapter\AuthenticationApiInterface;
  11. use Temando\Shipping\Rest\Exception\AdapterException;
  12. use Temando\Shipping\Rest\Request\AuthRequestInterfaceFactory;
  13. use Temando\Shipping\Webservice\Config\WsConfigInterface;
  14. /**
  15. * Temando REST API Authentication
  16. *
  17. * @package Temando\Shipping\Rest
  18. * @author Christoph Aßmann <christoph.assmann@netresearch.de>
  19. * @author Sebastian Ertner <sebastian.ertner@netresearch.de>
  20. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  21. * @link http://www.temando.com/
  22. */
  23. class Authentication implements AuthenticationInterface
  24. {
  25. /**
  26. * @var SessionManagerInterface
  27. */
  28. private $session;
  29. /**
  30. * @var WsConfigInterface
  31. */
  32. private $config;
  33. /**
  34. * @var AuthenticationApiInterface
  35. */
  36. private $apiAdapter;
  37. /**
  38. * @var AuthRequestInterfaceFactory
  39. */
  40. private $authRequestFactory;
  41. /**
  42. * @var DateTime
  43. */
  44. private $datetime;
  45. /**
  46. * Authentication constructor.
  47. *
  48. * @param SessionManagerInterface $session
  49. * @param WsConfigInterface $config
  50. * @param AuthenticationApiInterface $apiAdapter
  51. * @param AuthRequestInterfaceFactory $authRequestFactory
  52. * @param DateTime $datetime
  53. */
  54. public function __construct(
  55. SessionManagerInterface $session,
  56. WsConfigInterface $config,
  57. AuthenticationApiInterface $apiAdapter,
  58. AuthRequestInterfaceFactory $authRequestFactory,
  59. DateTime $datetime
  60. ) {
  61. $this->apiAdapter = $apiAdapter;
  62. $this->config = $config;
  63. $this->authRequestFactory = $authRequestFactory;
  64. $this->session = $session;
  65. $this->datetime = $datetime;
  66. }
  67. /**
  68. * Check if Session Token is invalid
  69. *
  70. * @return bool
  71. */
  72. private function isSessionTokenExpired()
  73. {
  74. $sessionTokenExpiry = strtotime($this->getSessionTokenExpiry());
  75. $currentTime = $this->datetime->timestamp();
  76. $threshold = 1200; //20min in s
  77. return (($sessionTokenExpiry - $threshold ) < $currentTime);
  78. }
  79. /**
  80. * Save Temando API token to admin session.
  81. *
  82. * @param string $sessionToken
  83. * @param string $sessionTokenExpiry
  84. * @return void
  85. */
  86. private function setSession($sessionToken, $sessionTokenExpiry)
  87. {
  88. $this->session->setData(self::DATA_KEY_SESSION_TOKEN, $sessionToken);
  89. $this->session->setData(self::DATA_KEY_SESSION_TOKEN_EXPIRY, $sessionTokenExpiry);
  90. }
  91. /**
  92. * Remove Temando API token from admin session.
  93. *
  94. * @return void
  95. */
  96. private function unsetSession()
  97. {
  98. $this->session->unsetData(self::DATA_KEY_SESSION_TOKEN);
  99. $this->session->unsetData(self::DATA_KEY_SESSION_TOKEN_EXPIRY);
  100. }
  101. /**
  102. * Refresh bearer token.
  103. * For future use, bearer tokens do currently not expire.
  104. *
  105. * @param string $username
  106. * @param string $password
  107. * @return void
  108. * @throws AuthenticationException
  109. * @throws InputException
  110. */
  111. public function authenticate($username, $password)
  112. {
  113. if (!$username) {
  114. throw InputException::requiredField('username');
  115. }
  116. if (!$password) {
  117. throw InputException::requiredField('password');
  118. }
  119. try {
  120. $requestType = $this->authRequestFactory->create([
  121. 'scope' => self::AUTH_SCOPE_ADMIN,
  122. 'username' => $username,
  123. 'password' => $password,
  124. ]);
  125. $this->apiAdapter->startSession($requestType);
  126. } catch (AdapterException $e) {
  127. $msg = 'API connection could not be established. Please check your credentials (%1).';
  128. throw new AuthenticationException(__($msg, $e->getMessage()), $e);
  129. }
  130. }
  131. /**
  132. * Refresh session token if expired.
  133. *
  134. * @param string $accountId
  135. * @param string $bearerToken
  136. * @return void
  137. * @throws AuthenticationException
  138. * @throws InputException
  139. */
  140. public function connect($accountId, $bearerToken)
  141. {
  142. if (!$this->isSessionTokenExpired()) {
  143. return;
  144. }
  145. if (!$accountId) {
  146. throw InputException::requiredField('accountId');
  147. }
  148. if (!$bearerToken) {
  149. throw InputException::requiredField('bearerToken');
  150. }
  151. try {
  152. $requestType = $this->authRequestFactory->create([
  153. 'scope' => self::AUTH_SCOPE_ADMIN,
  154. 'accountId' => $accountId,
  155. 'bearerToken' => $bearerToken,
  156. ]);
  157. $session = $this->apiAdapter->startSession($requestType);
  158. } catch (AdapterException $e) {
  159. $msg = 'API connection could not be established. Please check your credentials (%1).';
  160. throw new AuthenticationException(__($msg, $e->getMessage()), $e);
  161. }
  162. // save session info in admin/customer session
  163. $this->setSession(
  164. $session->getAttributes()->getSessionToken(),
  165. $session->getAttributes()->getExpiry()
  166. );
  167. // save merchant's api endpoint in config
  168. if ($session->getAttributes()->getApiUrl()) {
  169. $this->config->saveApiEndpoint($session->getAttributes()->getApiUrl());
  170. } else {
  171. $this->config->saveApiEndpoint($this->config->getSessionEndpoint());
  172. }
  173. }
  174. /**
  175. * Delete session token.
  176. *
  177. * @return void
  178. */
  179. public function disconnect()
  180. {
  181. $this->apiAdapter->endSession();
  182. $this->unsetSession();
  183. }
  184. /**
  185. * Force refresh session token.
  186. *
  187. * @param string $accountId
  188. * @param string $bearerToken
  189. * @return void
  190. * @throws AuthenticationException
  191. * @throws InputException
  192. */
  193. public function reconnect($accountId, $bearerToken)
  194. {
  195. $this->disconnect();
  196. $this->connect($accountId, $bearerToken);
  197. }
  198. /**
  199. * Read Temando Session Token.
  200. *
  201. * @return string
  202. */
  203. public function getSessionToken()
  204. {
  205. return $this->session->getData(self::DATA_KEY_SESSION_TOKEN);
  206. }
  207. /**
  208. * Read Temando Session Token Expiry Date Time.
  209. *
  210. * @return string
  211. */
  212. public function getSessionTokenExpiry()
  213. {
  214. return $this->session->getData(self::DATA_KEY_SESSION_TOKEN_EXPIRY);
  215. }
  216. }