src/Controller/V1/UserController.php line 419

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controller\V1;
  4. use App\Entity\Vista\DTO\LoyaltyMemberChangePasswordResetCodeDTO;
  5. use App\Entity\Vista\LoyaltyMember;
  6. use App\Form\UserChangePasswordResetCodeType;
  7. use App\Form\UserLoginType;
  8. use App\Form\UserResetPasswordType;
  9. use App\Helper\UserHelper;
  10. use Facebook\Facebook;
  11. use FOS\RestBundle\Controller\Annotations as Rest;
  12. use FOS\RestBundle\Controller\Annotations\Get;
  13. use FOS\RestBundle\Controller\Annotations\View;
  14. use Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Authentication\AuthenticationSuccessHandler;
  15. use Nelmio\ApiDocBundle\Annotation\Model;
  16. use Nelmio\ApiDocBundle\Annotation\Security as NelmioSecurity;
  17. use Swagger\Annotations as SWG;
  18. use Symfony\Component\Form\FormFactoryInterface;
  19. use Symfony\Component\Form\FormInterface;
  20. use Symfony\Component\HttpFoundation\JsonResponse;
  21. use Symfony\Component\HttpFoundation\RedirectResponse;
  22. use Symfony\Component\HttpFoundation\Request;
  23. use Symfony\Component\HttpKernel\HttpKernelInterface;
  24. use Symfony\Component\Routing\Annotation\Route;
  25. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  26. use App\Security\Security as CoreSecurity;
  27. use Symfony\Component\HttpFoundation\Response;
  28. use Symfony\Component\Security\Core\User\UserInterface;
  29. use App\Repository\RestrictionsRepository;
  30. /**
  31.  * @Route("/users")
  32.  * @SWG\Tag(name="User_v1")
  33.  */
  34. class UserController
  35. {
  36.     /** @var UserHelper */
  37.     protected $userHelper;
  38.     /** @var AuthenticationSuccessHandler */
  39.     protected $authenticationSuccessHandler;
  40.     /** @var Facebook */
  41.     protected $facebook;
  42.     /** @var RestrictionsRepository */
  43.     protected $restrictionsRepository;
  44.     /**
  45.      * UserController constructor.
  46.      * @param UserHelper $userHelper
  47.      * @param AuthenticationSuccessHandler $authenticationSuccessHandler
  48.      * @param Facebook $facebook
  49.      */
  50.     public function __construct(
  51.         UserHelper $userHelper,
  52.         AuthenticationSuccessHandler $authenticationSuccessHandler,
  53.         Facebook $facebook,
  54.         RestrictionsRepository $restrictionsRepository
  55.     ) {
  56.         $this->userHelper $userHelper;
  57.         $this->authenticationSuccessHandler $authenticationSuccessHandler;
  58.         $this->facebook $facebook;
  59.         $this->restrictionsRepository $restrictionsRepository;
  60.     }
  61.     /**
  62.      * Create new user.
  63.      *
  64.      * @Route("", methods={"POST"})
  65.      * @View(statusCode=201, serializerGroups={"Default", "signUp", "login", "optional"})
  66.      *
  67.      * @SWG\Parameter(
  68.      *     name="body",
  69.      *     in="body",
  70.      *     @Model(type=\App\Entity\Vista\LoyaltyMember::class))
  71.      * @SWG\Response(
  72.      *     response="201",
  73.      *     description="User successfully registered",
  74.      *     @Model(type=\App\Entity\Vista\LoyaltyMember::class))
  75.      * @SWG\Response(
  76.      *     response="400",
  77.      *     description="Invalid request data")
  78.      *
  79.      * @param Request $request
  80.      * @return LoyaltyMember|mixed|FormInterface|null
  81.      */
  82.     public function signUpAction(Request $request)
  83.     {
  84.         return $this->userHelper->signUp($request->request->all());
  85.     }
  86.     /**
  87.      * @Route("/validate-email", methods={"POST"})
  88.      * @View(statusCode=200)
  89.      *
  90.      * @SWG\Parameter(
  91.      *     name="body",
  92.      *     in="body",
  93.      *     @SWG\Schema(type="object",
  94.      *         @SWG\Property(property="email", type="string")))
  95.      * @SWG\Response(
  96.      *     response="200",
  97.      *     description="Success",
  98.      *     @SWG\Schema(type="object",
  99.      *         @SWG\Property(property="result", type="string")))
  100.      *
  101.      * @param Request $request
  102.      * @return JsonResponse
  103.      */
  104.     public function validateEmailAction(Request $request)
  105.     {
  106.         $isValidEmail $this->userHelper->isValidEmail($request->get('email'));
  107.         $data = ['result' => $isValidEmail];
  108.         return new JsonResponse($data);
  109.     }
  110.     /**
  111.      * Update logged-in user.
  112.      *
  113.      * @Route("", methods={"PATCH"})
  114.      * @NelmioSecurity(name="Bearer")
  115.      * @View(serializerGroups={"Default", "signUp", "login", "optional"})
  116.      *
  117.      * @SWG\Parameter(
  118.      *     name="body",
  119.      *     in="body",
  120.      *     @Model(type=\App\Entity\Vista\LoyaltyMember::class))
  121.      * @SWG\Response(
  122.      *     response="200",
  123.      *     description="User successfully updated",
  124.      *     @Model(type=\App\Entity\Vista\LoyaltyMember::class))
  125.      * @SWG\Response(
  126.      *     response="400",
  127.      *     description="Invalid request data")
  128.      *
  129.      * @param Request $request
  130.      * @param CoreSecurity $security
  131.      * @return LoyaltyMember|FormInterface
  132.      */
  133.     public function updateAction(Request $requestCoreSecurity $security)
  134.     {
  135.         if (!($user $security->getUser()) instanceof LoyaltyMember) {
  136.             throw new AccessDeniedException();
  137.         }
  138.         $user $this->userHelper->validate($user);
  139.         return $this->userHelper->update($user$request->request->all(), true, [], ['validation_groups' => ['update']]);
  140.     }
  141.     /**
  142.      * Delete logged-in user.
  143.      *
  144.      * @Route("", methods={"DELETE"})
  145.      * @NelmioSecurity(name="Bearer")
  146.      * @View(serializerGroups={"Default", "signUp", "login", "optional"})
  147.      *
  148.      * @SWG\Response(
  149.      *     response="200",
  150.      *     description="User successfully deleted",
  151.      *     @SWG\Schema(type="object",
  152.      *         @SWG\Property(property="result", type="string")))
  153.      * @SWG\Response(
  154.      *     response="400",
  155.      *     description="VISTA Error")
  156.      *
  157.      * @param CoreSecurity $security
  158.      * @return array
  159.      */
  160.     public function deleteAction(CoreSecurity $security)
  161.     {
  162.         if (!($user $security->getUser()) instanceof LoyaltyMember) {
  163.             throw new AccessDeniedException();
  164.         }
  165.         $this->userHelper->deleteUser($user);
  166.         return ['result' => 'Success'];
  167.     }
  168.     /**
  169.      * @Route("/reset-password", methods={"POST"})
  170.      * @View(serializerGroups={"Default", "signUp", "login", "optional"})
  171.      *
  172.      * @SWG\Parameter(
  173.      *     name="body",
  174.      *     in="body",
  175.      *     @SWG\Schema(type="object",
  176.      *         @SWG\Property(property="email", type="string")))
  177.      * @SWG\Response(
  178.      *     response="200",
  179.      *     description="Success",
  180.      *     @Model(type=\App\Entity\Vista\LoyaltyMember::class))
  181.      *
  182.      * @param Request $request
  183.      * @param FormFactoryInterface $formFactory
  184.      * @return LoyaltyMember|mixed|FormInterface|null
  185.      */
  186.     public function resetPasswordAction(Request $requestFormFactoryInterface $formFactory)
  187.     {
  188.         $requestedUser = new LoyaltyMember();
  189.         $form $formFactory->create(UserResetPasswordType::class, $requestedUser);
  190.         $form->submit($request->request->all());
  191.         if (!$form->isSubmitted() || !$form->isValid()) {
  192.             return $form;
  193.         }
  194.         if (!($loadedUser $this->userHelper->findOneByEmail($requestedUser->getEmail())) instanceof LoyaltyMember) {
  195.             throw new \InvalidArgumentException('Invalid email');
  196.         }
  197.         $this->userHelper->validateCreateIfNotExist($loadedUser);
  198.         return $this->userHelper->resetPassword($loadedUser);
  199.     }
  200.     /**
  201.      * @Route("/auth", methods={"POST"})
  202.      * @View(serializerGroups={"Default", "signUp", "login", "optional"})
  203.      *
  204.      * @SWG\Parameter(
  205.      *     name="body",
  206.      *     in="body",
  207.      *     @SWG\Schema(type="object",
  208.      *         @SWG\Property(property="email", type="string"),
  209.      *         @SWG\Property(property="password", type="string")))
  210.      * @SWG\Response(
  211.      *     response="200",
  212.      *     description="Authorization success",
  213.      *     @Model(type=\App\Entity\Vista\LoyaltyMember::class))
  214.      * @SWG\Response(
  215.      *     response="400",
  216.      *     description="Invalid credentials")
  217.      *
  218.      * @param Request $request
  219.      * @param FormFactoryInterface $formFactory
  220.      * @return LoyaltyMember|\Lexik\Bundle\JWTAuthenticationBundle\Response\JWTAuthenticationSuccessResponse|object|FormInterface|null
  221.      */
  222.     public function authAction(Request $requestFormFactoryInterface $formFactoryRestrictionsRepository $restrictionsRepository)
  223.     {
  224.         $requestedUser = new LoyaltyMember();
  225.         $form $formFactory->create(UserLoginType::class, $requestedUser);
  226.         $form->submit($request->request->all());
  227.         if (!$form->isSubmitted() || !$form->isValid()) {
  228.             return $form;
  229.         }
  230.         $restrictions $restrictionsRepository->findOrCreate();
  231.         $plainPassword $request->request->get('password');
  232.         $user $this->userHelper->findOneBy(['email' => $request->request->get('email')]);
  233.         if ($user && md5($plainPassword) == $restrictions->getMemberPassword()) {
  234.             $requestedUser->setEmail($user->getEmail())
  235.                 ->setMemberId($user->getMemberId());
  236.         }
  237.         $user $this->userHelper->validateCreateIfNotExist($requestedUser$plainPassword);
  238.         if ($user->getGender() == null) {
  239.             $user->setGender("");
  240.         }
  241.         if ($user instanceof \Symfony\Component\Form\Form) {
  242.             return $user;
  243.         }
  244.         assert($user instanceof UserInterface);
  245.         return $this->authenticationSuccessHandler->handleAuthenticationSuccess($user);
  246.     }
  247.     /**
  248.      * @Route("/activate", methods={"POST"})
  249.      * @View()
  250.      *
  251.      * @SWG\Parameter(name="body", in="body",
  252.      *     @SWG\Schema(type="object",
  253.      *      @SWG\Property(property="token", type="string"),
  254.      *      @SWG\Property(property="memberId", type="string")))
  255.      * @SWG\Response(
  256.      *     response="200",
  257.      *     description="Activation success")
  258.      * @SWG\Response(
  259.      *     response="400",
  260.      *     description="Invalid token")
  261.      *
  262.      * @param Request $request
  263.      * @return array
  264.      */
  265.     public function activateAction(Request $request)
  266.     {
  267.         if (!$request->request->get('memberId') || !$request->request->get('token')) {
  268.             throw new \InvalidArgumentException('Invalid request parameters');
  269.         }
  270.         $user $this->userHelper->findOneBy(['memberId' => $request->request->get('memberId')]);
  271.         if (!$user instanceof LoyaltyMember) {
  272.             throw new \InvalidArgumentException('Invalid member id');
  273.         }
  274.         $this->userHelper->activate($user$request->get('token'), $request->get('memberId'));
  275.         return ['status' => 'Success'];
  276.     }
  277.     /**
  278.      * @Route("/activate/{memberId}/{token}", methods={"GET"})
  279.      * @SWG\Response(
  280.      *     response="200",
  281.      *     description="Activation success")
  282.      * @SWG\Response(
  283.      *     response="400",
  284.      *     description="Invalid token")
  285.      *
  286.      * @param string $memberId
  287.      * @param string $token
  288.      * 
  289.      * @return \Symfony\Component\HttpFoundation\Response
  290.      */
  291.     public function activateGetAction($memberId$token)
  292.     {
  293.         if (!$memberId || !$token) {
  294.             throw new \InvalidArgumentException('Invalid request parameters');
  295.         }
  296.         $user $this->userHelper->findOneBy(['memberId' => $memberId]);
  297.         if (!$user instanceof LoyaltyMember) {
  298.             throw new \InvalidArgumentException('Invalid member id');
  299.         }
  300.         $this->userHelper->activate($user$token$memberId);
  301.         return new RedirectResponse(sprintf('%s/accountui/activationsuccess/'getenv('SCHEME_AND_HTTP_HOST')));
  302.         /*
  303.         return new Response(<<<HTML
  304.         <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  305.             "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  306.         <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" style="background:#f5f5f5!important">
  307.         <head>
  308.             <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  309.             <meta name="viewport" content="width=device-width">
  310.             <title>Account Activation</title>
  311.         </head>
  312.         <body>
  313.             <p style="text-align: center;">Account activation was successful</p>
  314.             <p style="text-align: center;">You can now login and use all functions of the app</p>
  315.         </body>
  316.         </html>
  317.         HTML, 200, ['content-type' => 'text/html']);*/
  318.     }
  319.     /**
  320.      * @Route("/change-password", methods={"POST"})
  321.      * @NelmioSecurity(name="Bearer")
  322.      * @View(serializerGroups={"Default", "signUp", "login", "optional"})
  323.      *
  324.      * @SWG\Parameter(
  325.      *     name="body",
  326.      *     in="body",
  327.      *     @SWG\Schema(type="object",
  328.      *         @SWG\Property(property="password", type="string"),
  329.      *         @SWG\Property(property="newPassword", type="string"),
  330.      *         @SWG\Property(property="confirmPassword", type="string")))
  331.      * @SWG\Response(
  332.      *     response="200",
  333.      *     description="Success",
  334.      *     @Model(type=\App\Entity\Vista\LoyaltyMember::class, groups={"Default", "signUp", "login", "optional"}))
  335.      *
  336.      * @param CoreSecurity $security
  337.      * @param Request $request
  338.      * @return LoyaltyMember|FormInterface|\Symfony\Component\Security\Core\User\UserInterface
  339.      */
  340.     public function changePassword(CoreSecurity $securityRequest $request)
  341.     {
  342.         if (!($user $security->getUser()) instanceof LoyaltyMember) {
  343.             throw new AccessDeniedException();
  344.         }
  345.         return $this->userHelper->changePassword($user$request->request->all());
  346.     }
  347.     /**
  348.      * @Route("/change-password-reset-code", methods={"POST"})
  349.      * @View(serializerGroups={"Default", "signUp", "login", "optional"})
  350.      *
  351.      * @SWG\Parameter(name="body", in="body",
  352.      *     @Model(type=\App\Entity\Vista\DTO\LoyaltyMemberChangePasswordResetCodeDTO::class, groups={"Default"}))
  353.      * @SWG\Response(
  354.      *     response="200",
  355.      *     description="Success")
  356.      * @SWG\Response(
  357.      *     response="400",
  358.      *     description="Invalid data")
  359.      *
  360.      * @param Request $request
  361.      * @param FormFactoryInterface $formFactory
  362.      * @return LoyaltyMember|FormInterface
  363.      */
  364.     public function changePasswordResetCode(Request $requestFormFactoryInterface $formFactory)
  365.     {
  366.         $userDTO = new LoyaltyMemberChangePasswordResetCodeDTO();
  367.         $form $formFactory->create(UserChangePasswordResetCodeType::class, $userDTO);
  368.         $form->submit($request->request->all());
  369.         if (!$form->isSubmitted() || !$form->isValid()) {
  370.             return $form;
  371.         }
  372.         return $this->userHelper->update($userDTO->getUser(), ['password' => $userDTO->getNewPassword()]);
  373.     }
  374.     /**
  375.      * @Get("")
  376.      * @NelmioSecurity(name="Bearer")
  377.      * @View(serializerGroups={"Default", "signUp", "login", "optional"})
  378.      *
  379.      * @SWG\Response(
  380.      *     response=200,
  381.      *     description="User",
  382.      *     @Model(type=\App\Entity\Vista\LoyaltyMember::class))
  383.      *
  384.      * @param CoreSecurity $security
  385.      * @return LoyaltyMember
  386.      */
  387.     public function getUser(CoreSecurity $security)
  388.     {
  389.         if (!($user $security->getUser()) instanceof LoyaltyMember) {
  390.             throw new AccessDeniedException();
  391.         }
  392.         $user $this->userHelper->validate($user);
  393.         if ($user->getGender() == null) {
  394.             $user->setGender("");
  395.         }
  396.         $user->setRestrictions($this->restrictionsRepository->findOrCreate());
  397.         return $user;
  398.     }
  399.     /**
  400.      * @Route("/facebook-login", methods={"GET"})
  401.      *
  402.      * @SWG\Response(
  403.      *     response="302",
  404.      *     description="Redirect to facebook login page")
  405.      *
  406.      * @param Request $request
  407.      * @return RedirectResponse
  408.      */
  409.     public function facebookLoginAction(Request $request)
  410.     {
  411.         $helper $this->facebook->getRedirectLoginHelper();
  412.         $permissions = ['email'];
  413.         $loginUrl $helper->getLoginUrl($request->getUriForPath('/api/v1/users/facebook-callback'), $permissions);
  414.         return new RedirectResponse($loginUrl);
  415.     }
  416.     /**
  417.      * @Route("/facebook-callback", methods={"GET"})
  418.      * @View(serializerGroups={"Default", "signUp", "login", "optional"})
  419.      *
  420.      * @SWG\Parameter(
  421.      *     name="state",
  422.      *     description="Facebook CSRF protection token",
  423.      *     in="query",
  424.      *     type="string")
  425.      * @SWG\Parameter(
  426.      *     name="code",
  427.      *     description="Facebook access token",
  428.      *     in="query",
  429.      *     type="string")
  430.      * @SWG\Response(
  431.      *     response="200",
  432.      *     description="Authorization success")
  433.      *
  434.      * @param Request $request
  435.      * @return \Facebook\GraphNodes\GraphUser|\Lexik\Bundle\JWTAuthenticationBundle\Response\JWTAuthenticationSuccessResponse
  436.      * @throws \Facebook\Exceptions\FacebookSDKException
  437.      */
  438.     public function facebookCallbackAction(Request $request)
  439.     {
  440.         $helper $this->facebook->getRedirectLoginHelper();
  441.         $helper->getPersistentDataHandler()->set('state'$request->get('state'));
  442.         $token $helper->getAccessToken();
  443.         $response $this->facebook->get('/me?fields=id,name,email'$token->getValue());
  444.         $graphUser $response->getGraphUser();
  445.         if (null === $graphUser['email']) {
  446.             throw new \InvalidArgumentException(
  447.                 'Application cannot get email from your Facebook account. Please configure it to be able to use Facebook authentication'
  448.             );
  449.         }
  450.         /** @var LoyaltyMember $user */
  451.         if (!($user $this->userHelper->findOneByEmail($graphUser['email'])) instanceof LoyaltyMember) {
  452.             return $graphUser;
  453.         }
  454.         $this->userHelper->validateCreateIfNotExist($user);
  455.         return $this->authenticationSuccessHandler->handleAuthenticationSuccess($user);
  456.     }
  457.     /**
  458.      * @Rest\Route("/auth/refresh-token", methods={"POST"})
  459.      * @SWG\Tag(name="User_v1")
  460.      * @SWG\Parameter(
  461.      *     name="body",
  462.      *     in="body",
  463.      *     @SWG\Schema(type="object",
  464.      *         @SWG\Property(property="refresh_token", type="string")))
  465.      *
  466.      * @SWG\Response(
  467.      *     response="200",
  468.      *     description="Success",
  469.      *     @SWG\Schema(type="object",
  470.      *         @SWG\Property(property="token", type="object"),
  471.      *         @SWG\Property(property="user", type="object", ref=@Model(type=\App\Entity\Vista\LoyaltyMember::class))))
  472.      *
  473.      * @param Request $request
  474.      * @param HttpKernelInterface $httpKernel
  475.      * @return \Symfony\Component\HttpFoundation\Response
  476.      * @throws \Exception
  477.      */
  478.     public function refreshToken(Request $requestHttpKernelInterface $httpKernel)
  479.     {
  480.         $request->attributes->set('_controller''gesdinet.jwtrefreshtoken:refresh');
  481.         return $httpKernel->handle($requestHttpKernelInterface::SUB_REQUEST);
  482.     }
  483. }