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

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