diff options
Diffstat (limited to 'src/Wallabag/ApiBundle/Controller/UserRestController.php')
-rw-r--r-- | src/Wallabag/ApiBundle/Controller/UserRestController.php | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/UserRestController.php b/src/Wallabag/ApiBundle/Controller/UserRestController.php new file mode 100644 index 00000000..a1378fc5 --- /dev/null +++ b/src/Wallabag/ApiBundle/Controller/UserRestController.php | |||
@@ -0,0 +1,157 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\ApiBundle\Controller; | ||
4 | |||
5 | use FOS\UserBundle\Event\UserEvent; | ||
6 | use FOS\UserBundle\FOSUserEvents; | ||
7 | use JMS\Serializer\SerializationContext; | ||
8 | use Nelmio\ApiDocBundle\Annotation\ApiDoc; | ||
9 | use Symfony\Component\HttpFoundation\JsonResponse; | ||
10 | use Symfony\Component\HttpFoundation\Request; | ||
11 | use Wallabag\ApiBundle\Entity\Client; | ||
12 | use Wallabag\UserBundle\Entity\User; | ||
13 | |||
14 | class UserRestController extends WallabagRestController | ||
15 | { | ||
16 | /** | ||
17 | * Retrieve current logged in user informations. | ||
18 | * | ||
19 | * @ApiDoc() | ||
20 | * | ||
21 | * @return JsonResponse | ||
22 | */ | ||
23 | public function getUserAction() | ||
24 | { | ||
25 | $this->validateAuthentication(); | ||
26 | |||
27 | return $this->sendUser($this->getUser()); | ||
28 | } | ||
29 | |||
30 | /** | ||
31 | * Register an user and create a client. | ||
32 | * | ||
33 | * @ApiDoc( | ||
34 | * requirements={ | ||
35 | * {"name"="username", "dataType"="string", "required"=true, "description"="The user's username"}, | ||
36 | * {"name"="password", "dataType"="string", "required"=true, "description"="The user's password"}, | ||
37 | * {"name"="email", "dataType"="string", "required"=true, "description"="The user's email"}, | ||
38 | * {"name"="client_name", "dataType"="string", "required"=true, "description"="The client name (to be used by your app)"} | ||
39 | * } | ||
40 | * ) | ||
41 | * | ||
42 | * @todo Make this method (or the whole API) accessible only through https | ||
43 | * | ||
44 | * @return JsonResponse | ||
45 | */ | ||
46 | public function putUserAction(Request $request) | ||
47 | { | ||
48 | if (!$this->getParameter('fosuser_registration') || !$this->get('craue_config')->get('api_user_registration')) { | ||
49 | $json = $this->get('jms_serializer')->serialize(['error' => "Server doesn't allow registrations"], 'json'); | ||
50 | |||
51 | return (new JsonResponse()) | ||
52 | ->setJson($json) | ||
53 | ->setStatusCode(JsonResponse::HTTP_FORBIDDEN); | ||
54 | } | ||
55 | |||
56 | $userManager = $this->get('fos_user.user_manager'); | ||
57 | $user = $userManager->createUser(); | ||
58 | // user will be disabled BY DEFAULT to avoid spamming account to be enabled | ||
59 | $user->setEnabled(false); | ||
60 | |||
61 | $form = $this->createForm('Wallabag\UserBundle\Form\NewUserType', $user, [ | ||
62 | 'csrf_protection' => false, | ||
63 | ]); | ||
64 | |||
65 | // simulate form submission | ||
66 | $form->submit([ | ||
67 | 'username' => $request->request->get('username'), | ||
68 | 'plainPassword' => [ | ||
69 | 'first' => $request->request->get('password'), | ||
70 | 'second' => $request->request->get('password'), | ||
71 | ], | ||
72 | 'email' => $request->request->get('email'), | ||
73 | ]); | ||
74 | |||
75 | if ($form->isSubmitted() && false === $form->isValid()) { | ||
76 | $view = $this->view($form, 400); | ||
77 | $view->setFormat('json'); | ||
78 | |||
79 | // handle errors in a more beautiful way than the default view | ||
80 | $data = json_decode($this->handleView($view)->getContent(), true)['children']; | ||
81 | $errors = []; | ||
82 | |||
83 | if (isset($data['username']['errors'])) { | ||
84 | $errors['username'] = $this->translateErrors($data['username']['errors']); | ||
85 | } | ||
86 | |||
87 | if (isset($data['email']['errors'])) { | ||
88 | $errors['email'] = $this->translateErrors($data['email']['errors']); | ||
89 | } | ||
90 | |||
91 | if (isset($data['plainPassword']['children']['first']['errors'])) { | ||
92 | $errors['password'] = $this->translateErrors($data['plainPassword']['children']['first']['errors']); | ||
93 | } | ||
94 | |||
95 | $json = $this->get('jms_serializer')->serialize(['error' => $errors], 'json'); | ||
96 | |||
97 | return (new JsonResponse()) | ||
98 | ->setJson($json) | ||
99 | ->setStatusCode(JsonResponse::HTTP_BAD_REQUEST); | ||
100 | } | ||
101 | |||
102 | // create a default client | ||
103 | $client = new Client($user); | ||
104 | $client->setName($request->request->get('client_name', 'Default client')); | ||
105 | |||
106 | $this->getDoctrine()->getManager()->persist($client); | ||
107 | |||
108 | $user->addClient($client); | ||
109 | |||
110 | $userManager->updateUser($user); | ||
111 | |||
112 | // dispatch a created event so the associated config will be created | ||
113 | $event = new UserEvent($user, $request); | ||
114 | $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event); | ||
115 | |||
116 | return $this->sendUser($user, 'user_api_with_client', JsonResponse::HTTP_CREATED); | ||
117 | } | ||
118 | |||
119 | /** | ||
120 | * Send user response. | ||
121 | * | ||
122 | * @param User $user | ||
123 | * @param string $group Used to define with serialized group might be used | ||
124 | * @param int $status HTTP Status code to send | ||
125 | * | ||
126 | * @return JsonResponse | ||
127 | */ | ||
128 | private function sendUser(User $user, $group = 'user_api', $status = JsonResponse::HTTP_OK) | ||
129 | { | ||
130 | $json = $this->get('jms_serializer')->serialize( | ||
131 | $user, | ||
132 | 'json', | ||
133 | SerializationContext::create()->setGroups([$group]) | ||
134 | ); | ||
135 | |||
136 | return (new JsonResponse()) | ||
137 | ->setJson($json) | ||
138 | ->setStatusCode($status); | ||
139 | } | ||
140 | |||
141 | /** | ||
142 | * Translate errors message. | ||
143 | * | ||
144 | * @param array $errors | ||
145 | * | ||
146 | * @return array | ||
147 | */ | ||
148 | private function translateErrors($errors) | ||
149 | { | ||
150 | $translatedErrors = []; | ||
151 | foreach ($errors as $error) { | ||
152 | $translatedErrors[] = $this->get('translator')->trans($error); | ||
153 | } | ||
154 | |||
155 | return $translatedErrors; | ||
156 | } | ||
157 | } | ||