vendor/uvdesk/api-bundle/Security/Guards/APIGuard.php line 39

Open in your IDE?
  1. <?php
  2. namespace Webkul\UVDesk\ApiBundle\Security\Guards;
  3. use Doctrine\ORM\Tools\Setup;
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\HttpFoundation\Response;
  7. use Symfony\Component\HttpFoundation\RequestStack;
  8. use Symfony\Component\HttpFoundation\JsonResponse;
  9. use Symfony\Bundle\SecurityBundle\Security\FirewallMap;
  10. use Symfony\Component\Security\Core\User\UserInterface;
  11. use Webkul\UVDesk\ApiBundle\Entity\ApiAccessCredential;
  12. use Symfony\Component\DependencyInjection\ContainerInterface;
  13. use Symfony\Component\Security\Core\User\UserProviderInterface;
  14. use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
  15. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  16. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  17. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  18. class APIGuard extends AbstractGuardAuthenticator
  19. {
  20. /**
  21. * [API-*] API Exception Codes
  22. */
  23. const API_UNAUTHORIZED = 'API-001';
  24. const API_NOT_AUTHENTICATED = 'API-002';
  25. const API_INSUFFICIENT_PARAMS = 'API-003';
  26. /**
  27. * [CC-*] Campus Connect Exception Codes
  28. */
  29. const USER_NOT_FOUND = 'CC-001';
  30. const INVALID_CREDNETIALS = 'CC-002';
  31. const UNEXPECTED_ERROR = 'CC-005';
  32. public function __construct(FirewallMap $firewall, ContainerInterface $container, EntityManagerInterface $entityManager, UserPasswordEncoderInterface $encoder)
  33. {
  34. $this->firewall = $firewall;
  35. $this->container = $container;
  36. $this->entityManager = $entityManager;
  37. $this->encoder = $encoder;
  38. }
  39. /**
  40. * Check whether this guard is applicable for the current request.
  41. */
  42. public function supports(Request $request)
  43. {
  44. return 'OPTIONS' != $request->getRealMethod() && 'uvdesk_api' === $this->firewall->getFirewallConfig($request)->getName();
  45. }
  46. /**
  47. * Retrieve and prepare credentials from the request.
  48. */
  49. public function getCredentials(Request $request)
  50. {
  51. $accessToken = null;
  52. $authorization = $request->headers->get('Authorization');
  53. if (!empty($authorization) && strpos(strtolower($authorization), 'basic') === 0) {
  54. $accessToken = substr($authorization, 6);
  55. } else if (!empty($authorization) && strpos(strtolower($authorization), 'bearer') === 0) {
  56. $accessToken = substr($authorization, 7);
  57. }
  58. if (!empty($accessToken)) {
  59. try {
  60. if (in_array($request->attributes->get('_route'), ['uvdesk_api_bundle_sessions_api_v1.0_login_session'])) {
  61. list($email, $password) = explode(':', base64_decode($accessToken));
  62. return [
  63. 'email' => $email,
  64. 'password' => $password,
  65. ];
  66. } else {
  67. $user = $this->entityManager->getRepository(ApiAccessCredential::class)->getUserEmailByAccessToken($accessToken);
  68. return [
  69. 'email' => $user['email'],
  70. 'accessToken' => $accessToken,
  71. ];
  72. }
  73. } catch (\Exception $e) {
  74. throw new AuthenticationException("An unexpected error occurred while authenticating credentials: {$e->getMessage()}");
  75. }
  76. }
  77. return [];
  78. }
  79. /**
  80. * Retrieve the current user on behalf of which the request is being performed.
  81. */
  82. public function getUser($credentials, UserProviderInterface $provider)
  83. {
  84. return !empty($credentials['email']) ? $provider->loadUserByUsername($credentials['email']) : null;
  85. }
  86. /**
  87. * Process the provided credentials and check whether the current request is properly authenticated.
  88. */
  89. public function checkCredentials($credentials, UserInterface $user)
  90. {
  91. if (!empty($credentials['password'])) {
  92. return $this->encoder->isPasswordValid($user, $credentials['password']);
  93. }
  94. if (!empty($credentials['accessToken'])) {
  95. $accessCredentials = $this->entityManager->getRepository(ApiAccessCredential::class)->findOneBy([
  96. 'user' => $user,
  97. 'token' => $credentials['accessToken'],
  98. ]);
  99. if (!empty($accessCredentials) && true == $accessCredentials->getIsEnabled() && false == $accessCredentials->getIsExpired()) {
  100. return true;
  101. }
  102. }
  103. return false;
  104. }
  105. /**
  106. * Disable support for the "remember me" functionality.
  107. */
  108. public function supportsRememberMe()
  109. {
  110. return false;
  111. }
  112. public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
  113. {
  114. return null;
  115. }
  116. public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
  117. {
  118. switch ($exception->getMessageKey()) {
  119. case 'Username could not be found.':
  120. $data = [
  121. 'status' => false,
  122. 'message' => 'No such user found',
  123. 'error_code' => self::USER_NOT_FOUND,
  124. ];
  125. break;
  126. case 'Invalid Credentials.':
  127. $data = [
  128. 'status' => false,
  129. 'message' => 'Invalid credentials provided.',
  130. 'error_code' => self::INVALID_CREDNETIALS,
  131. ];
  132. break;
  133. default:
  134. $data = [
  135. 'status' => false,
  136. 'message' => strtr($exception->getMessageKey(), $exception->getMessageData()),
  137. 'error_code' => self::UNEXPECTED_ERROR,
  138. ];
  139. break;
  140. }
  141. return new JsonResponse($data, Response::HTTP_FORBIDDEN);
  142. }
  143. public function start(Request $request, AuthenticationException $authException = null)
  144. {
  145. $data = [
  146. 'status' => false,
  147. 'message' => 'Authentication Required',
  148. 'error_code' => self::API_NOT_AUTHENTICATED,
  149. ];
  150. return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
  151. }
  152. }