diff options
Diffstat (limited to 'src/Wallabag/ApiBundle')
-rw-r--r-- | src/Wallabag/ApiBundle/Controller/UserRestController.php | 119 |
1 files changed, 80 insertions, 39 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/UserRestController.php b/src/Wallabag/ApiBundle/Controller/UserRestController.php index c5ffbdf1..a1b78e3f 100644 --- a/src/Wallabag/ApiBundle/Controller/UserRestController.php +++ b/src/Wallabag/ApiBundle/Controller/UserRestController.php | |||
@@ -6,12 +6,14 @@ use FOS\UserBundle\Event\UserEvent; | |||
6 | use FOS\UserBundle\FOSUserEvents; | 6 | use FOS\UserBundle\FOSUserEvents; |
7 | use JMS\Serializer\SerializationContext; | 7 | use JMS\Serializer\SerializationContext; |
8 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | 8 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; |
9 | use Symfony\Component\HttpFoundation\Request; | ||
9 | use Symfony\Component\HttpFoundation\JsonResponse; | 10 | use Symfony\Component\HttpFoundation\JsonResponse; |
11 | use Wallabag\UserBundle\Entity\User; | ||
10 | 12 | ||
11 | class UserRestController extends WallabagRestController | 13 | class UserRestController extends WallabagRestController |
12 | { | 14 | { |
13 | /** | 15 | /** |
14 | * Retrieve user informations | 16 | * Retrieve current logged in user informations. |
15 | * | 17 | * |
16 | * @ApiDoc() | 18 | * @ApiDoc() |
17 | * | 19 | * |
@@ -21,78 +23,117 @@ class UserRestController extends WallabagRestController | |||
21 | { | 23 | { |
22 | $this->validateAuthentication(); | 24 | $this->validateAuthentication(); |
23 | 25 | ||
24 | $serializationContext = SerializationContext::create()->setGroups(['user_api']); | 26 | return $this->sendUser($this->getUser()); |
25 | $json = $this->get('serializer')->serialize($this->getUser(), 'json', $serializationContext); | ||
26 | |||
27 | return (new JsonResponse())->setJson($json); | ||
28 | } | 27 | } |
29 | 28 | ||
30 | /** | 29 | /** |
31 | * Register an user | 30 | * Register an user. |
32 | * | 31 | * |
33 | * @ApiDoc( | 32 | * @ApiDoc( |
34 | * requirements={ | 33 | * requirements={ |
35 | * {"name"="username", "dataType"="string", "required"=true, "description"="The user's username"}, | 34 | * {"name"="username", "dataType"="string", "required"=true, "description"="The user's username"}, |
36 | * {"name"="password", "dataType"="string", "required"=true, "description"="The user's password"} | 35 | * {"name"="password", "dataType"="string", "required"=true, "description"="The user's password"}, |
37 | * {"name"="email", "dataType"="string", "required"=true, "description"="The user's email"} | 36 | * {"name"="email", "dataType"="string", "required"=true, "description"="The user's email"} |
38 | * } | 37 | * } |
39 | * ) | 38 | * ) |
39 | * | ||
40 | * @todo Make this method (or the whole API) accessible only through https | ||
41 | * | ||
40 | * @return JsonResponse | 42 | * @return JsonResponse |
41 | */ | 43 | */ |
42 | // TODO : Make this method (or the whole API) accessible only through https | 44 | public function putUserAction(Request $request) |
43 | public function putUserAction($username, $password, $email) | ||
44 | { | 45 | { |
45 | if (!$this->container->getParameter('fosuser_registration')) { | 46 | if (!$this->container->getParameter('fosuser_registration')) { |
46 | $json = $this->get('serializer')->serialize(['error' => "Server doesn't allow registrations"], 'json'); | 47 | $json = $this->get('serializer')->serialize(['error' => "Server doesn't allow registrations"], 'json'); |
48 | |||
47 | return (new JsonResponse())->setJson($json)->setStatusCode(403); | 49 | return (new JsonResponse())->setJson($json)->setStatusCode(403); |
48 | } | 50 | } |
49 | 51 | ||
50 | if ($password === '') { // TODO : might be a good idea to enforce restrictions here | 52 | $userManager = $this->get('fos_user.user_manager'); |
51 | $json = $this->get('serializer')->serialize(['error' => 'Password is blank'], 'json'); | 53 | $user = $userManager->createUser(); |
52 | return (new JsonResponse())->setJson($json)->setStatusCode(400); | 54 | // enable created user by default |
53 | } | 55 | $user->setEnabled(true); |
54 | 56 | ||
57 | $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user, [ | ||
58 | 'csrf_protection' => false, | ||
59 | ]); | ||
55 | 60 | ||
56 | // TODO : Make only one call to database by using a custom repository method | 61 | // simulate form submission |
57 | if ($this->getDoctrine() | 62 | $form->submit([ |
58 | ->getRepository('WallabagUserBundle:User') | 63 | 'username' => $request->request->get('username'), |
59 | ->findOneByUserName($username)) { | 64 | 'plainPassword' => [ |
60 | $json = $this->get('serializer')->serialize(['error' => 'Username is already taken'], 'json'); | 65 | 'first' => $request->request->get('password'), |
61 | return (new JsonResponse())->setJson($json)->setStatusCode(409); | 66 | 'second' => $request->request->get('password'), |
62 | } | 67 | ], |
68 | 'email' => $request->request->get('email'), | ||
69 | ]); | ||
63 | 70 | ||
64 | if ($this->getDoctrine() | 71 | if ($form->isSubmitted() && false === $form->isValid()) { |
65 | ->getRepository('WallabagUserBundle:User') | 72 | $view = $this->view($form, 400); |
66 | ->findOneByEmail($email)) { | 73 | $view->setFormat('json'); |
67 | $json = $this->get('serializer')->serialize(['error' => 'An account with this email already exists'], 'json'); | ||
68 | return (new JsonResponse())->setJson($json)->setStatusCode(409); | ||
69 | } | ||
70 | 74 | ||
71 | $em = $this->get('doctrine.orm.entity_manager'); | 75 | // handle errors in a more beautiful way than the default view |
76 | $data = json_decode($this->handleView($view)->getContent(), true)['children']; | ||
77 | $errors = []; | ||
72 | 78 | ||
73 | $userManager = $this->get('fos_user.user_manager'); | 79 | if (isset($data['username']['errors'])) { |
74 | $user = $userManager->createUser(); | 80 | $errors['username'] = $this->translateErrors($data['username']['errors']); |
81 | } | ||
75 | 82 | ||
76 | $user->setUsername($username); | 83 | if (isset($data['email']['errors'])) { |
84 | $errors['email'] = $this->translateErrors($data['email']['errors']); | ||
85 | } | ||
77 | 86 | ||
78 | $user->setPlainPassword($password); | 87 | if (isset($data['plainPassword']['children']['first']['errors'])) { |
88 | $errors['password'] = $this->translateErrors($data['plainPassword']['children']['first']['errors']); | ||
89 | } | ||
79 | 90 | ||
80 | $user->setEmail($email); | 91 | $json = $this->get('serializer')->serialize(['error' => $errors], 'json'); |
81 | 92 | ||
82 | $user->setEnabled(true); | 93 | return (new JsonResponse())->setJson($json)->setStatusCode(400); |
83 | $user->addRole('ROLE_USER'); | 94 | } |
84 | 95 | ||
85 | $em->persist($user); | 96 | $userManager->updateUser($user); |
86 | 97 | ||
87 | // dispatch a created event so the associated config will be created | 98 | // dispatch a created event so the associated config will be created |
88 | $event = new UserEvent($user); | 99 | $event = new UserEvent($user, $request); |
89 | $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event); | 100 | $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event); |
90 | 101 | ||
91 | $serializationContext = SerializationContext::create()->setGroups(['user_api']); | 102 | return $this->sendUser($user); |
92 | $json = $this->get('serializer')->serialize($user, 'json', $serializationContext); | 103 | } |
93 | 104 | ||
94 | return (new JsonResponse())->setJson($json); | 105 | /** |
106 | * Send user response. | ||
107 | * | ||
108 | * @param User $user | ||
109 | * | ||
110 | * @return JsonResponse | ||
111 | */ | ||
112 | private function sendUser(User $user) | ||
113 | { | ||
114 | $json = $this->get('serializer')->serialize( | ||
115 | $user, | ||
116 | 'json', | ||
117 | SerializationContext::create()->setGroups(['user_api']) | ||
118 | ); | ||
95 | 119 | ||
120 | return (new JsonResponse())->setJson($json); | ||
96 | } | 121 | } |
97 | 122 | ||
123 | /** | ||
124 | * Translate errors message. | ||
125 | * | ||
126 | * @param array $errors | ||
127 | * | ||
128 | * @return array | ||
129 | */ | ||
130 | private function translateErrors($errors) | ||
131 | { | ||
132 | $translatedErrors = []; | ||
133 | foreach ($errors as $error) { | ||
134 | $translatedErrors[] = $this->get('translator')->trans($error); | ||
135 | } | ||
136 | |||
137 | return $translatedErrors; | ||
138 | } | ||
98 | } | 139 | } |