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 (
  100. ! empty($accessCredentials)
  101. && true == $accessCredentials->getIsEnabled()
  102. && false == $accessCredentials->getIsExpired()
  103. ) {
  104. return true;
  105. }
  106. }
  107. return false;
  108. }
  109. /**
  110. * Disable support for the "remember me" functionality.
  111. */
  112. public function supportsRememberMe()
  113. {
  114. return false;
  115. }
  116. public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
  117. {
  118. return null;
  119. }
  120. public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
  121. {
  122. switch ($exception->getMessageKey()) {
  123. case 'Username could not be found.':
  124. $data = [
  125. 'status' => false,
  126. 'message' => 'No such user found',
  127. 'error_code' => self::USER_NOT_FOUND,
  128. ];
  129. break;
  130. case 'Invalid Credentials.':
  131. $data = [
  132. 'status' => false,
  133. 'message' => 'Invalid credentials provided.',
  134. 'error_code' => self::INVALID_CREDNETIALS,
  135. ];
  136. break;
  137. case 'An authentication exception occurred.':
  138. if ($request->attributes->get('_route') == 'uvdesk_api_bundle_sessions_api_v1.0_logout_session'){
  139. $data = [
  140. 'status' => false,
  141. 'message' => 'This Session token has been already expired successfully.',
  142. 'error_code' => self::INVALID_CREDNETIALS,
  143. ];
  144. return new JsonResponse($data, Response::HTTP_FORBIDDEN);
  145. }
  146. $data = [
  147. 'status' => false,
  148. 'message' => 'This api is disabled from admin end, please check once again.',
  149. 'error_code' => self::INVALID_CREDNETIALS,
  150. ];
  151. break;
  152. default:
  153. $data = [
  154. 'status' => false,
  155. 'message' => strtr($exception->getMessageKey(), $exception->getMessageData()),
  156. 'error_code' => self::UNEXPECTED_ERROR,
  157. ];
  158. break;
  159. }
  160. return new JsonResponse($data, Response::HTTP_FORBIDDEN);
  161. }
  162. public function start(Request $request, AuthenticationException $authException = null)
  163. {
  164. $data = [
  165. 'status' => false,
  166. 'message' => 'Authentication Required',
  167. 'error_code' => self::API_NOT_AUTHENTICATED,
  168. ];
  169. return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
  170. }
  171. }