aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJérémy Benoist <j0k3r@users.noreply.github.com>2017-06-08 17:24:49 +0200
committerGitHub <noreply@github.com>2017-06-08 17:24:49 +0200
commit3f474025d889c3eff20b481f005f4d292f1ef29d (patch)
treee74288b7df91e226b1d23a4047a3af5cc04a6484
parent2da8f071cfcc6e50be7be66c037de23f0d073bea (diff)
parenta8d3fe50df52ec486add5691a3b67fe5205a032e (diff)
downloadwallabag-3f474025d889c3eff20b481f005f4d292f1ef29d.tar.gz
wallabag-3f474025d889c3eff20b481f005f4d292f1ef29d.tar.zst
wallabag-3f474025d889c3eff20b481f005f4d292f1ef29d.zip
Merge pull request #3187 from wallabag/api-client-credentials
Create (and return) a client after creating a new user using the API
-rw-r--r--src/Wallabag/ApiBundle/Controller/UserRestController.php25
-rw-r--r--src/Wallabag/ApiBundle/Entity/Client.php23
-rw-r--r--src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig2
-rw-r--r--src/Wallabag/UserBundle/Entity/User.php38
-rw-r--r--tests/Wallabag/AnnotationBundle/Controller/AnnotationControllerTest.php4
-rw-r--r--tests/Wallabag/ApiBundle/Controller/UserRestControllerTest.php13
-rw-r--r--tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php2
7 files changed, 88 insertions, 19 deletions
diff --git a/src/Wallabag/ApiBundle/Controller/UserRestController.php b/src/Wallabag/ApiBundle/Controller/UserRestController.php
index 8f675b8d..7471f5f6 100644
--- a/src/Wallabag/ApiBundle/Controller/UserRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/UserRestController.php
@@ -9,6 +9,7 @@ use Nelmio\ApiDocBundle\Annotation\ApiDoc;
9use Symfony\Component\HttpFoundation\Request; 9use Symfony\Component\HttpFoundation\Request;
10use Symfony\Component\HttpFoundation\JsonResponse; 10use Symfony\Component\HttpFoundation\JsonResponse;
11use Wallabag\UserBundle\Entity\User; 11use Wallabag\UserBundle\Entity\User;
12use Wallabag\ApiBundle\Entity\Client;
12 13
13class UserRestController extends WallabagRestController 14class UserRestController extends WallabagRestController
14{ 15{
@@ -27,13 +28,14 @@ class UserRestController extends WallabagRestController
27 } 28 }
28 29
29 /** 30 /**
30 * Register an user. 31 * Register an user and create a client.
31 * 32 *
32 * @ApiDoc( 33 * @ApiDoc(
33 * requirements={ 34 * requirements={
34 * {"name"="username", "dataType"="string", "required"=true, "description"="The user's username"}, 35 * {"name"="username", "dataType"="string", "required"=true, "description"="The user's username"},
35 * {"name"="password", "dataType"="string", "required"=true, "description"="The user's password"}, 36 * {"name"="password", "dataType"="string", "required"=true, "description"="The user's password"},
36 * {"name"="email", "dataType"="string", "required"=true, "description"="The user's email"} 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)"}
37 * } 39 * }
38 * ) 40 * )
39 * 41 *
@@ -97,29 +99,38 @@ class UserRestController extends WallabagRestController
97 ->setStatusCode(JsonResponse::HTTP_BAD_REQUEST); 99 ->setStatusCode(JsonResponse::HTTP_BAD_REQUEST);
98 } 100 }
99 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
100 $userManager->updateUser($user); 110 $userManager->updateUser($user);
101 111
102 // dispatch a created event so the associated config will be created 112 // dispatch a created event so the associated config will be created
103 $event = new UserEvent($user, $request); 113 $event = new UserEvent($user, $request);
104 $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event); 114 $this->get('event_dispatcher')->dispatch(FOSUserEvents::USER_CREATED, $event);
105 115
106 return $this->sendUser($user, JsonResponse::HTTP_CREATED); 116 return $this->sendUser($user, 'user_api_with_client', JsonResponse::HTTP_CREATED);
107 } 117 }
108 118
109 /** 119 /**
110 * Send user response. 120 * Send user response.
111 * 121 *
112 * @param User $user 122 * @param User $user
113 * @param int $status HTTP Status code to send 123 * @param string $group Used to define with serialized group might be used
124 * @param int $status HTTP Status code to send
114 * 125 *
115 * @return JsonResponse 126 * @return JsonResponse
116 */ 127 */
117 private function sendUser(User $user, $status = JsonResponse::HTTP_OK) 128 private function sendUser(User $user, $group = 'user_api', $status = JsonResponse::HTTP_OK)
118 { 129 {
119 $json = $this->get('serializer')->serialize( 130 $json = $this->get('serializer')->serialize(
120 $user, 131 $user,
121 'json', 132 'json',
122 SerializationContext::create()->setGroups(['user_api']) 133 SerializationContext::create()->setGroups([$group])
123 ); 134 );
124 135
125 return (new JsonResponse()) 136 return (new JsonResponse())
diff --git a/src/Wallabag/ApiBundle/Entity/Client.php b/src/Wallabag/ApiBundle/Entity/Client.php
index 9ed9f980..c15fd3fa 100644
--- a/src/Wallabag/ApiBundle/Entity/Client.php
+++ b/src/Wallabag/ApiBundle/Entity/Client.php
@@ -5,6 +5,9 @@ namespace Wallabag\ApiBundle\Entity;
5use Doctrine\ORM\Mapping as ORM; 5use Doctrine\ORM\Mapping as ORM;
6use FOS\OAuthServerBundle\Entity\Client as BaseClient; 6use FOS\OAuthServerBundle\Entity\Client as BaseClient;
7use Wallabag\UserBundle\Entity\User; 7use Wallabag\UserBundle\Entity\User;
8use JMS\Serializer\Annotation\Groups;
9use JMS\Serializer\Annotation\SerializedName;
10use JMS\Serializer\Annotation\VirtualProperty;
8 11
9/** 12/**
10 * @ORM\Table("oauth2_clients") 13 * @ORM\Table("oauth2_clients")
@@ -23,6 +26,8 @@ class Client extends BaseClient
23 * @var string 26 * @var string
24 * 27 *
25 * @ORM\Column(name="name", type="text", nullable=false) 28 * @ORM\Column(name="name", type="text", nullable=false)
29 *
30 * @Groups({"user_api_with_client"})
26 */ 31 */
27 protected $name; 32 protected $name;
28 33
@@ -37,6 +42,14 @@ class Client extends BaseClient
37 protected $accessTokens; 42 protected $accessTokens;
38 43
39 /** 44 /**
45 * @var string
46 *
47 * @SerializedName("client_secret")
48 * @Groups({"user_api_with_client"})
49 */
50 protected $secret;
51
52 /**
40 * @ORM\ManyToOne(targetEntity="Wallabag\UserBundle\Entity\User", inversedBy="clients") 53 * @ORM\ManyToOne(targetEntity="Wallabag\UserBundle\Entity\User", inversedBy="clients")
41 */ 54 */
42 private $user; 55 private $user;
@@ -78,4 +91,14 @@ class Client extends BaseClient
78 { 91 {
79 return $this->user; 92 return $this->user;
80 } 93 }
94
95 /**
96 * @VirtualProperty
97 * @SerializedName("client_id")
98 * @Groups({"user_api_with_client"})
99 */
100 public function getClientId()
101 {
102 return $this->getId().'_'.$this->getRandomId();
103 }
81} 104}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig
index b3f0affb..528b055c 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Developer/index.html.twig
@@ -33,7 +33,7 @@
33 <table class="striped"> 33 <table class="striped">
34 <tr> 34 <tr>
35 <td>{{ 'developer.existing_clients.field_id'|trans }}</td> 35 <td>{{ 'developer.existing_clients.field_id'|trans }}</td>
36 <td><strong><code>{{ client.id }}_{{ client.randomId }}</code></strong></td> 36 <td><strong><code>{{ client.clientId }}</code></strong></td>
37 </tr> 37 </tr>
38 <tr> 38 <tr>
39 <td>{{ 'developer.existing_clients.field_secret'|trans }}</td> 39 <td>{{ 'developer.existing_clients.field_secret'|trans }}</td>
diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php
index ed6ce331..aba76ca7 100644
--- a/src/Wallabag/UserBundle/Entity/User.php
+++ b/src/Wallabag/UserBundle/Entity/User.php
@@ -6,6 +6,7 @@ use Doctrine\Common\Collections\ArrayCollection;
6use Doctrine\ORM\Mapping as ORM; 6use Doctrine\ORM\Mapping as ORM;
7use JMS\Serializer\Annotation\Groups; 7use JMS\Serializer\Annotation\Groups;
8use JMS\Serializer\Annotation\XmlRoot; 8use JMS\Serializer\Annotation\XmlRoot;
9use JMS\Serializer\Annotation\Accessor;
9use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface; 10use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
10use Scheb\TwoFactorBundle\Model\TrustedComputerInterface; 11use Scheb\TwoFactorBundle\Model\TrustedComputerInterface;
11use FOS\UserBundle\Model\User as BaseUser; 12use FOS\UserBundle\Model\User as BaseUser;
@@ -36,7 +37,7 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
36 * @ORM\Id 37 * @ORM\Id
37 * @ORM\GeneratedValue(strategy="AUTO") 38 * @ORM\GeneratedValue(strategy="AUTO")
38 * 39 *
39 * @Groups({"user_api"}) 40 * @Groups({"user_api", "user_api_with_client"})
40 */ 41 */
41 protected $id; 42 protected $id;
42 43
@@ -45,21 +46,21 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
45 * 46 *
46 * @ORM\Column(name="name", type="text", nullable=true) 47 * @ORM\Column(name="name", type="text", nullable=true)
47 * 48 *
48 * @Groups({"user_api"}) 49 * @Groups({"user_api", "user_api_with_client"})
49 */ 50 */
50 protected $name; 51 protected $name;
51 52
52 /** 53 /**
53 * @var string 54 * @var string
54 * 55 *
55 * @Groups({"user_api"}) 56 * @Groups({"user_api", "user_api_with_client"})
56 */ 57 */
57 protected $username; 58 protected $username;
58 59
59 /** 60 /**
60 * @var string 61 * @var string
61 * 62 *
62 * @Groups({"user_api"}) 63 * @Groups({"user_api", "user_api_with_client"})
63 */ 64 */
64 protected $email; 65 protected $email;
65 66
@@ -68,7 +69,7 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
68 * 69 *
69 * @ORM\Column(name="created_at", type="datetime") 70 * @ORM\Column(name="created_at", type="datetime")
70 * 71 *
71 * @Groups({"user_api"}) 72 * @Groups({"user_api", "user_api_with_client"})
72 */ 73 */
73 protected $createdAt; 74 protected $createdAt;
74 75
@@ -77,7 +78,7 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
77 * 78 *
78 * @ORM\Column(name="updated_at", type="datetime") 79 * @ORM\Column(name="updated_at", type="datetime")
79 * 80 *
80 * @Groups({"user_api"}) 81 * @Groups({"user_api", "user_api_with_client"})
81 */ 82 */
82 protected $updatedAt; 83 protected $updatedAt;
83 84
@@ -97,7 +98,8 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
97 private $authCode; 98 private $authCode;
98 99
99 /** 100 /**
100 * @var bool Enabled yes/no 101 * @var bool
102 *
101 * @ORM\Column(type="boolean") 103 * @ORM\Column(type="boolean")
102 */ 104 */
103 private $twoFactorAuthentication = false; 105 private $twoFactorAuthentication = false;
@@ -108,10 +110,20 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
108 private $trusted; 110 private $trusted;
109 111
110 /** 112 /**
113 * @var ArrayCollection
114 *
111 * @ORM\OneToMany(targetEntity="Wallabag\ApiBundle\Entity\Client", mappedBy="user", cascade={"remove"}) 115 * @ORM\OneToMany(targetEntity="Wallabag\ApiBundle\Entity\Client", mappedBy="user", cascade={"remove"})
112 */ 116 */
113 protected $clients; 117 protected $clients;
114 118
119 /**
120 * @see getFirstClient() below
121 *
122 * @Groups({"user_api_with_client"})
123 * @Accessor(getter="getFirstClient")
124 */
125 protected $default_client;
126
115 public function __construct() 127 public function __construct()
116 { 128 {
117 parent::__construct(); 129 parent::__construct();
@@ -288,4 +300,16 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf
288 { 300 {
289 return $this->clients; 301 return $this->clients;
290 } 302 }
303
304 /**
305 * Only used by the API when creating a new user it'll also return the first client (which was also created at the same time).
306 *
307 * @return Client
308 */
309 public function getFirstClient()
310 {
311 if (!empty($this->clients)) {
312 return $this->clients->first();
313 }
314 }
291} 315}
diff --git a/tests/Wallabag/AnnotationBundle/Controller/AnnotationControllerTest.php b/tests/Wallabag/AnnotationBundle/Controller/AnnotationControllerTest.php
index 8f87ccf3..3c94382c 100644
--- a/tests/Wallabag/AnnotationBundle/Controller/AnnotationControllerTest.php
+++ b/tests/Wallabag/AnnotationBundle/Controller/AnnotationControllerTest.php
@@ -85,7 +85,7 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase
85 'text' => 'my annotation', 85 'text' => 'my annotation',
86 'quote' => 'my quote', 86 'quote' => 'my quote',
87 'ranges' => [ 87 'ranges' => [
88 ['start' => '', 'startOffset' => 24, 'end' => '', 'endOffset' => 31] 88 ['start' => '', 'startOffset' => 24, 'end' => '', 'endOffset' => 31],
89 ], 89 ],
90 ]); 90 ]);
91 $this->client->request('POST', $prefixUrl.'/'.$entry->getId().'.json', [], [], $headers, $content); 91 $this->client->request('POST', $prefixUrl.'/'.$entry->getId().'.json', [], [], $headers, $content);
@@ -130,7 +130,7 @@ class AnnotationControllerTest extends WallabagAnnotationTestCase
130 'text' => 'my annotation', 130 'text' => 'my annotation',
131 'quote' => $longQuote, 131 'quote' => $longQuote,
132 'ranges' => [ 132 'ranges' => [
133 ['start' => '', 'startOffset' => 24, 'end' => '', 'endOffset' => 31] 133 ['start' => '', 'startOffset' => 24, 'end' => '', 'endOffset' => 31],
134 ], 134 ],
135 ]); 135 ]);
136 $this->client->request('POST', $prefixUrl.'/'.$entry->getId().'.json', [], [], $headers, $content); 136 $this->client->request('POST', $prefixUrl.'/'.$entry->getId().'.json', [], [], $headers, $content);
diff --git a/tests/Wallabag/ApiBundle/Controller/UserRestControllerTest.php b/tests/Wallabag/ApiBundle/Controller/UserRestControllerTest.php
index 5735bc58..4e65f130 100644
--- a/tests/Wallabag/ApiBundle/Controller/UserRestControllerTest.php
+++ b/tests/Wallabag/ApiBundle/Controller/UserRestControllerTest.php
@@ -61,10 +61,16 @@ class UserRestControllerTest extends WallabagApiTestCase
61 $this->assertArrayHasKey('username', $content); 61 $this->assertArrayHasKey('username', $content);
62 $this->assertArrayHasKey('created_at', $content); 62 $this->assertArrayHasKey('created_at', $content);
63 $this->assertArrayHasKey('updated_at', $content); 63 $this->assertArrayHasKey('updated_at', $content);
64 $this->assertArrayHasKey('default_client', $content);
64 65
65 $this->assertEquals('wallabag@google.com', $content['email']); 66 $this->assertEquals('wallabag@google.com', $content['email']);
66 $this->assertEquals('google', $content['username']); 67 $this->assertEquals('google', $content['username']);
67 68
69 $this->assertArrayHasKey('client_secret', $content['default_client']);
70 $this->assertArrayHasKey('client_id', $content['default_client']);
71
72 $this->assertEquals('Default client', $content['default_client']['name']);
73
68 $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type')); 74 $this->assertEquals('application/json', $this->client->getResponse()->headers->get('Content-Type'));
69 75
70 $this->client->getContainer()->get('craue_config')->set('api_user_registration', 0); 76 $this->client->getContainer()->get('craue_config')->set('api_user_registration', 0);
@@ -79,6 +85,7 @@ class UserRestControllerTest extends WallabagApiTestCase
79 'username' => 'google', 85 'username' => 'google',
80 'password' => 'googlegoogle', 86 'password' => 'googlegoogle',
81 'email' => 'wallabag@google.com', 87 'email' => 'wallabag@google.com',
88 'client_name' => 'My client name !!',
82 ]); 89 ]);
83 90
84 $this->assertEquals(201, $client->getResponse()->getStatusCode()); 91 $this->assertEquals(201, $client->getResponse()->getStatusCode());
@@ -90,10 +97,16 @@ class UserRestControllerTest extends WallabagApiTestCase
90 $this->assertArrayHasKey('username', $content); 97 $this->assertArrayHasKey('username', $content);
91 $this->assertArrayHasKey('created_at', $content); 98 $this->assertArrayHasKey('created_at', $content);
92 $this->assertArrayHasKey('updated_at', $content); 99 $this->assertArrayHasKey('updated_at', $content);
100 $this->assertArrayHasKey('default_client', $content);
93 101
94 $this->assertEquals('wallabag@google.com', $content['email']); 102 $this->assertEquals('wallabag@google.com', $content['email']);
95 $this->assertEquals('google', $content['username']); 103 $this->assertEquals('google', $content['username']);
96 104
105 $this->assertArrayHasKey('client_secret', $content['default_client']);
106 $this->assertArrayHasKey('client_id', $content['default_client']);
107
108 $this->assertEquals('My client name !!', $content['default_client']['name']);
109
97 $this->assertEquals('application/json', $client->getResponse()->headers->get('Content-Type')); 110 $this->assertEquals('application/json', $client->getResponse()->headers->get('Content-Type'));
98 111
99 $client->getContainer()->get('craue_config')->set('api_user_registration', 0); 112 $client->getContainer()->get('craue_config')->set('api_user_registration', 0);
diff --git a/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php b/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php
index 3b928d1e..c0a4acfa 100644
--- a/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php
+++ b/tests/Wallabag/CoreBundle/Command/ShowUserCommandTest.php
@@ -4,10 +4,8 @@ namespace Tests\Wallabag\CoreBundle\Command;
4 4
5use Symfony\Bundle\FrameworkBundle\Console\Application; 5use Symfony\Bundle\FrameworkBundle\Console\Application;
6use Symfony\Component\Console\Tester\CommandTester; 6use Symfony\Component\Console\Tester\CommandTester;
7use Wallabag\CoreBundle\Command\CleanDuplicatesCommand;
8use Tests\Wallabag\CoreBundle\WallabagCoreTestCase; 7use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
9use Wallabag\CoreBundle\Command\ShowUserCommand; 8use Wallabag\CoreBundle\Command\ShowUserCommand;
10use Wallabag\CoreBundle\Entity\Entry;
11use Wallabag\UserBundle\Entity\User; 9use Wallabag\UserBundle\Entity\User;
12 10
13class ShowUserCommandTest extends WallabagCoreTestCase 11class ShowUserCommandTest extends WallabagCoreTestCase