aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/ApiBundle
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag/ApiBundle')
-rw-r--r--src/Wallabag/ApiBundle/Controller/UserRestController.php119
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;
6use FOS\UserBundle\FOSUserEvents; 6use FOS\UserBundle\FOSUserEvents;
7use JMS\Serializer\SerializationContext; 7use JMS\Serializer\SerializationContext;
8use Nelmio\ApiDocBundle\Annotation\ApiDoc; 8use Nelmio\ApiDocBundle\Annotation\ApiDoc;
9use Symfony\Component\HttpFoundation\Request;
9use Symfony\Component\HttpFoundation\JsonResponse; 10use Symfony\Component\HttpFoundation\JsonResponse;
11use Wallabag\UserBundle\Entity\User;
10 12
11class UserRestController extends WallabagRestController 13class 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}