X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=src%2FWallabag%2FApiBundle%2FController%2FUserRestController.php;h=6f47cff0dd85a8ddb759ef906c27f146ceffc01a;hb=f808b01692a835673f328d7221ba8c212caa9b61;hp=c5ffbdf1f7ce3d218386b712a7c49dd8de3b31b3;hpb=2251045901875aa815dee43ec467fb1af8d416d0;p=github%2Fwallabag%2Fwallabag.git diff --git a/src/Wallabag/ApiBundle/Controller/UserRestController.php b/src/Wallabag/ApiBundle/Controller/UserRestController.php index c5ffbdf1..6f47cff0 100644 --- a/src/Wallabag/ApiBundle/Controller/UserRestController.php +++ b/src/Wallabag/ApiBundle/Controller/UserRestController.php @@ -7,11 +7,14 @@ use FOS\UserBundle\FOSUserEvents; use JMS\Serializer\SerializationContext; use Nelmio\ApiDocBundle\Annotation\ApiDoc; use Symfony\Component\HttpFoundation\JsonResponse; +use Symfony\Component\HttpFoundation\Request; +use Wallabag\ApiBundle\Entity\Client; +use Wallabag\UserBundle\Entity\User; class UserRestController extends WallabagRestController { /** - * Retrieve user informations + * Retrieve current logged in user informations. * * @ApiDoc() * @@ -21,78 +24,134 @@ class UserRestController extends WallabagRestController { $this->validateAuthentication(); - $serializationContext = SerializationContext::create()->setGroups(['user_api']); - $json = $this->get('serializer')->serialize($this->getUser(), 'json', $serializationContext); - - return (new JsonResponse())->setJson($json); + return $this->sendUser($this->getUser()); } /** - * Register an user + * Register an user and create a client. * * @ApiDoc( * requirements={ * {"name"="username", "dataType"="string", "required"=true, "description"="The user's username"}, - * {"name"="password", "dataType"="string", "required"=true, "description"="The user's password"} - * {"name"="email", "dataType"="string", "required"=true, "description"="The user's email"} + * {"name"="password", "dataType"="string", "required"=true, "description"="The user's password"}, + * {"name"="email", "dataType"="string", "required"=true, "description"="The user's email"}, + * {"name"="client_name", "dataType"="string", "required"=true, "description"="The client name (to be used by your app)"} * } * ) + * + * @todo Make this method (or the whole API) accessible only through https + * * @return JsonResponse */ - // TODO : Make this method (or the whole API) accessible only through https - public function putUserAction($username, $password, $email) + public function putUserAction(Request $request) { - if (!$this->container->getParameter('fosuser_registration')) { + if (!$this->getParameter('fosuser_registration') || !$this->get('craue_config')->get('api_user_registration')) { $json = $this->get('serializer')->serialize(['error' => "Server doesn't allow registrations"], 'json'); - return (new JsonResponse())->setJson($json)->setStatusCode(403); - } - - if ($password === '') { // TODO : might be a good idea to enforce restrictions here - $json = $this->get('serializer')->serialize(['error' => 'Password is blank'], 'json'); - return (new JsonResponse())->setJson($json)->setStatusCode(400); - } - - // TODO : Make only one call to database by using a custom repository method - if ($this->getDoctrine() - ->getRepository('WallabagUserBundle:User') - ->findOneByUserName($username)) { - $json = $this->get('serializer')->serialize(['error' => 'Username is already taken'], 'json'); - return (new JsonResponse())->setJson($json)->setStatusCode(409); + return (new JsonResponse()) + ->setJson($json) + ->setStatusCode(JsonResponse::HTTP_FORBIDDEN); } - if ($this->getDoctrine() - ->getRepository('WallabagUserBundle:User') - ->findOneByEmail($email)) { - $json = $this->get('serializer')->serialize(['error' => 'An account with this email already exists'], 'json'); - return (new JsonResponse())->setJson($json)->setStatusCode(409); - } - - $em = $this->get('doctrine.orm.entity_manager'); - $userManager = $this->get('fos_user.user_manager'); $user = $userManager->createUser(); + // user will be disabled BY DEFAULT to avoid spamming account to be enabled + $user->setEnabled(false); + + $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user, [ + 'csrf_protection' => false, + ]); + + // simulate form submission + $form->submit([ + 'username' => $request->request->get('username'), + 'plainPassword' => [ + 'first' => $request->request->get('password'), + 'second' => $request->request->get('password'), + ], + 'email' => $request->request->get('email'), + ]); + + if ($form->isSubmitted() && false === $form->isValid()) { + $view = $this->view($form, 400); + $view->setFormat('json'); + + // handle errors in a more beautiful way than the default view + $data = json_decode($this->handleView($view)->getContent(), true)['children']; + $errors = []; + + if (isset($data['username']['errors'])) { + $errors['username'] = $this->translateErrors($data['username']['errors']); + } + + if (isset($data['email']['errors'])) { + $errors['email'] = $this->translateErrors($data['email']['errors']); + } + + if (isset($data['plainPassword']['children']['first']['errors'])) { + $errors['password'] = $this->translateErrors($data['plainPassword']['children']['first']['errors']); + } + + $json = $this->get('serializer')->serialize(['error' => $errors], 'json'); + + return (new JsonResponse()) + ->setJson($json) + ->setStatusCode(JsonResponse::HTTP_BAD_REQUEST); + } - $user->setUsername($username); - - $user->setPlainPassword($password); + // create a default client + $client = new Client($user); + $client->setName($request->request->get('client_name', 'Default client')); - $user->setEmail($email); + $this->getDoctrine()->getManager()->persist($client); - $user->setEnabled(true); - $user->addRole('ROLE_USER'); + $user->addClient($client); - $em->persist($user); + $userManager->updateUser($user); // dispatch a created event so the associated config will be created - $event = new UserEvent($user); + $event = new UserEvent($user, $request); $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event); - $serializationContext = SerializationContext::create()->setGroups(['user_api']); - $json = $this->get('serializer')->serialize($user, 'json', $serializationContext); - - return (new JsonResponse())->setJson($json); + return $this->sendUser($user, 'user_api_with_client', JsonResponse::HTTP_CREATED); + } + /** + * Send user response. + * + * @param User $user + * @param string $group Used to define with serialized group might be used + * @param int $status HTTP Status code to send + * + * @return JsonResponse + */ + private function sendUser(User $user, $group = 'user_api', $status = JsonResponse::HTTP_OK) + { + $json = $this->get('serializer')->serialize( + $user, + 'json', + SerializationContext::create()->setGroups([$group]) + ); + + return (new JsonResponse()) + ->setJson($json) + ->setStatusCode($status); } + /** + * Translate errors message. + * + * @param array $errors + * + * @return array + */ + private function translateErrors($errors) + { + $translatedErrors = []; + foreach ($errors as $error) { + $translatedErrors[] = $this->get('translator')->trans($error); + } + + return $translatedErrors; + } }