src/Controller/Login/SecurityController.php line 171

Open in your IDE?
  1. <?php
  2. namespace Orioly\Controller\Login;
  3. use Doctrine\ORM\ORMException;
  4. use JMS\Serializer\SerializationContext;
  5. use Nelmio\ApiDocBundle\Annotation\Operation;
  6. use Orioly\Constants\Settings\OriolySettingsBundleConstants;
  7. use Orioly\Entity\Login\User;
  8. use Orioly\Entity\Login\UserToken;
  9. use Orioly\Entity\Onboarding\AccountOnboardingOptions;
  10. use Orioly\Entity\Onboarding\OnboardingStats;
  11. use Orioly\Event\Login\UserEvent;
  12. use Orioly\Exception\Services\FunctionalityNotAvailableException;
  13. use Orioly\Form\Login\SecurityLoginFormType;
  14. use Orioly\Services\Response\JsonResponse;
  15. use Swagger\Annotations as SWG;
  16. use Symfony\Component\HttpFoundation\Request;
  17. use Symfony\Component\HttpFoundation\Response;
  18. use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
  19. use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
  20. use Symfony\Component\Security\Core\User\UserInterface;
  21. class SecurityController extends LoginBaseController
  22. {
  23.     /**
  24.      * Login
  25.      *
  26.      * @Operation(
  27.      *     tags={"Login"},
  28.      *     consumes={"application/json"},
  29.      *     produces={"application/json"},
  30.      *     @SWG\Parameter(
  31.      *     name="credentials",
  32.      *     in="body",
  33.      *     type="json",
  34.      *     description="User Credentials",
  35.      *     required=true,
  36.      *     @SWG\Schema(
  37.      *     type="object",
  38.      *     @SWG\Property(property="username", type="string"),
  39.      *     @SWG\Property(property="password", type="string")
  40.      * )
  41.      * ),
  42.      *     @SWG\Response(
  43.      *         response="200",
  44.      *         description="Returned when successful"
  45.      *     )
  46.      * )
  47.      *
  48.      * @param Request $request
  49.      * @return JsonResponse
  50.      * @throws \Exception
  51.      */
  52.     public function loginAction(Request $request)
  53.     {
  54.         $form $this->createForm(SecurityLoginFormType::class);
  55.         $form->submit($this->decodeJsonContent($request));
  56.         if ($form->isValid()) {
  57.             $user $this->getUserManager()->findUserByUsernameOrEmail($form->getData()->getUsername());
  58.             if ($user->hasLastLogin()) {
  59.                 $this->checkAndUpdateOnboardingOption($user);
  60.             }
  61.             $this->loginUser($user$request);
  62.             if ($request->attributes->has('_mobile') && !$this->isGranted('CAN_USE_MOBILE_APPLICATION')) {
  63.                 throw new FunctionalityNotAvailableException();
  64.             } else {
  65.                 $response $this->createResponse(
  66.                     $this->serializeObject(
  67.                         $user,
  68.                         SerializationContext::create()->setGroups(['login_successful'])
  69.                     )
  70.                 );
  71.             }
  72.         } else {
  73.             $response $this->createResponse(
  74.                 $this->serializeObject($form),
  75.                 Response::HTTP_BAD_REQUEST
  76.             );
  77.         }
  78.         return $response;
  79.     }
  80.     /**
  81.      * @param User|UserInterface $user
  82.      * @param Request $request
  83.      * @throws \Exception
  84.      */
  85.     private function loginUser(User $userRequest $request)
  86.     {
  87.         $userManager $this->getUserManager();
  88.         $createHashFromAccessingObject =
  89.             base64_encode(json_encode(
  90.                 [
  91.                     $request->headers->get('User-Agent'),
  92.                     $request->getClientIp(),
  93.                 ]
  94.             ));
  95.         $user->setTokenFromAccessingObject($createHashFromAccessingObject);
  96.         $user->setLastLogin(new \DateTime());
  97.         $userManager->updateUser($user);
  98.         $loginManager $this->getSecurityLoginManager();
  99.         $loginManager->logInUser(
  100.             $user
  101.         );
  102.         $this->get('event_dispatcher')->dispatch(new UserEvent($user$request), OriolySettingsBundleConstants::SECURITY_IMPLICIT_LOGIN);
  103.     }
  104.     /**
  105.      * @param Request $request
  106.      * @return JsonResponse
  107.      * @throws ORMException
  108.      */
  109.     public function logoutAction(Request $request)
  110.     {
  111.         try {
  112.             $token $request->headers->get(
  113.                 $this->getParameter('api_key')
  114.             );
  115.             $user $this->findUserByToken($token);
  116.             if (is_null($user)) {
  117.                 throw new NotAcceptableHttpException();
  118.             }
  119.             $currentTokenList = ($user->getTokens()->filter(
  120.                 function (UserToken $userToken) use ($token) {
  121.                     return $userToken->getApiKey() == $token;
  122.                 })
  123.             );
  124.             $currentToken $currentTokenList->first();
  125.             $user->getTokens()->removeElement($currentToken);
  126.             $this->getEntityManager()->remove($currentToken);
  127.             $this->getUserManager()->updateUser($user);
  128.             $security $this->getSecurityContext();
  129.             $token = new AnonymousToken($this->getParameter('secret'), new User());
  130.             $security->setToken($token);
  131.             $this->getSession()->invalidate();
  132.             $statusCode Response::HTTP_OK;
  133.         } catch (NotAcceptableHttpException $exception) {
  134.             $statusCode Response::HTTP_NOT_ACCEPTABLE;
  135.         }
  136.         return $this->createResponse(''$statusCode);
  137.     }
  138.     /**
  139.      * @param string $token
  140.      * @return User
  141.      * @throws \Doctrine\ORM\NonUniqueResultException
  142.      */
  143.     private function findUserByToken($token)
  144.     {
  145.         return $this->getUserTokenRepository()->getUserFromToken($token);
  146.     }
  147.     /**
  148.      * @return JsonResponse
  149.      */
  150.     public function retrieveInfoAction()
  151.     {
  152.         return $this->createResponse(
  153.             $this->serializeObject(
  154.                 $this->getUser(),
  155.                 SerializationContext::create()->setGroups(['login_successful'])
  156.             ),
  157.             Response::HTTP_OK
  158.         );
  159.     }
  160.     /**
  161.      * @param UserInterface $user
  162.      * @throws ORMException
  163.      */
  164.     private function checkAndUpdateOnboardingOption(UserInterface $user): void
  165.     {
  166.         $entityManager $this->getEntityManager();
  167.         $optionName OnboardingStats::OPTION_FIRST_VISIT_TO_DASHBOARD;
  168.         $account $user->getAccount();
  169.         $option $entityManager->getRepository(AccountOnboardingOptions::class)->findOneBy(
  170.             [
  171.                 'optionName' => $optionName,
  172.                 'userAccount' => $account->getId()
  173.             ]
  174.         );
  175.         if (!$option) {
  176.             $entityManager->persist(
  177.                 (new AccountOnboardingOptions())
  178.                     ->setOptionName($optionName)
  179.                     ->setValue('Y')
  180.                     ->setUserAccount($account)
  181.             );
  182.         }
  183.     }
  184. }