aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag')
-rw-r--r--src/Wallabag/ApiBundle/Controller/WallabagRestController.php (renamed from src/Wallabag/CoreBundle/Controller/WallabagRestController.php)116
-rw-r--r--src/Wallabag/ApiBundle/DependencyInjection/Configuration.php29
-rw-r--r--src/Wallabag/ApiBundle/DependencyInjection/Security/Factory/WsseFactory.php (renamed from src/Wallabag/CoreBundle/DependencyInjection/Security/Factory/WsseFactory.php)2
-rw-r--r--src/Wallabag/ApiBundle/DependencyInjection/WallabagApiExtension.php25
-rw-r--r--src/Wallabag/ApiBundle/Resources/config/routing.yml0
-rw-r--r--src/Wallabag/ApiBundle/Resources/config/routing_rest.yml4
-rw-r--r--src/Wallabag/ApiBundle/Resources/config/services.yml12
-rw-r--r--src/Wallabag/ApiBundle/Security/Authentication/Provider/WsseProvider.php (renamed from src/Wallabag/CoreBundle/Security/Authentication/Provider/WsseProvider.php)13
-rw-r--r--src/Wallabag/ApiBundle/Security/Authentication/Token/WsseUserToken.php (renamed from src/Wallabag/CoreBundle/Security/Authentication/Token/WsseUserToken.php)3
-rw-r--r--src/Wallabag/ApiBundle/Security/Firewall/WsseListener.php (renamed from src/Wallabag/CoreBundle/Security/Firewall/WsseListener.php)4
-rw-r--r--src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php410
-rw-r--r--src/Wallabag/ApiBundle/WallabagApiBundle.php18
-rw-r--r--src/Wallabag/CoreBundle/Command/InstallCommand.php10
-rw-r--r--src/Wallabag/CoreBundle/Controller/ConfigController.php2
-rw-r--r--src/Wallabag/CoreBundle/Controller/EntryController.php16
-rw-r--r--src/Wallabag/CoreBundle/Controller/RssController.php6
-rw-r--r--src/Wallabag/CoreBundle/Controller/SecurityController.php9
-rw-r--r--src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php8
-rw-r--r--src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php6
-rw-r--r--src/Wallabag/CoreBundle/Doctrine/Mapping/PrefixedNamingStrategy.php16
-rw-r--r--src/Wallabag/CoreBundle/Entity/Config.php56
-rw-r--r--src/Wallabag/CoreBundle/Entity/Entry.php55
-rw-r--r--src/Wallabag/CoreBundle/Entity/Tag.php15
-rw-r--r--src/Wallabag/CoreBundle/Entity/User.php60
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php1
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/ConfigType.php1
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/EntryType.php1
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/ForgotPasswordType.php1
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/NewUserType.php1
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/ResetPasswordType.php1
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/RssType.php1
-rw-r--r--src/Wallabag/CoreBundle/Form/Type/UserInformationType.php1
-rwxr-xr-xsrc/Wallabag/CoreBundle/Helper/Tools.php12
-rw-r--r--src/Wallabag/CoreBundle/Repository/EntryRepository.php8
-rw-r--r--src/Wallabag/CoreBundle/Repository/UserRepository.php2
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/routing_rest.yml4
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/services.yml12
-rw-r--r--src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php3
-rw-r--r--src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php2
-rw-r--r--src/Wallabag/CoreBundle/Service/Extractor.php23
-rw-r--r--src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php4
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php6
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php4
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php10
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/SecurityControllerTest.php4
-rw-r--r--src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php214
-rw-r--r--src/Wallabag/CoreBundle/Tests/WallabagCoreTestCase.php (renamed from src/Wallabag/CoreBundle/Tests/WallabagTestCase.php)2
-rw-r--r--src/Wallabag/CoreBundle/Tools/Utils.php5
-rw-r--r--src/Wallabag/CoreBundle/Twig/Extension/WallabagExtension.php6
-rw-r--r--src/Wallabag/CoreBundle/WallabagCoreBundle.php9
50 files changed, 776 insertions, 457 deletions
diff --git a/src/Wallabag/CoreBundle/Controller/WallabagRestController.php b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php
index 14f42c48..2f5923c8 100644
--- a/src/Wallabag/CoreBundle/Controller/WallabagRestController.php
+++ b/src/Wallabag/ApiBundle/Controller/WallabagRestController.php
@@ -1,6 +1,6 @@
1<?php 1<?php
2 2
3namespace Wallabag\CoreBundle\Controller; 3namespace Wallabag\ApiBundle\Controller;
4 4
5use Nelmio\ApiDocBundle\Annotation\ApiDoc; 5use Nelmio\ApiDocBundle\Annotation\ApiDoc;
6use Symfony\Bundle\FrameworkBundle\Controller\Controller; 6use Symfony\Bundle\FrameworkBundle\Controller\Controller;
@@ -47,6 +47,7 @@ class WallabagRestController extends Controller
47 * {"name"="username", "dataType"="string", "required"=true, "description"="username"} 47 * {"name"="username", "dataType"="string", "required"=true, "description"="username"}
48 * } 48 * }
49 * ) 49 * )
50 *
50 * @return array 51 * @return array
51 */ 52 */
52 public function getSaltAction($username) 53 public function getSaltAction($username)
@@ -62,6 +63,7 @@ class WallabagRestController extends Controller
62 63
63 return array($user->getSalt() ?: null); 64 return array($user->getSalt() ?: null);
64 } 65 }
66
65 /** 67 /**
66 * Retrieve all entries. It could be filtered by many options. 68 * Retrieve all entries. It could be filtered by many options.
67 * 69 *
@@ -76,6 +78,7 @@ class WallabagRestController extends Controller
76 * {"name"="tags", "dataType"="string", "required"=false, "format"="api%2Crest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."}, 78 * {"name"="tags", "dataType"="string", "required"=false, "format"="api%2Crest", "description"="a list of tags url encoded. Will returns entries that matches ALL tags."},
77 * } 79 * }
78 * ) 80 * )
81 *
79 * @return Entry 82 * @return Entry
80 */ 83 */
81 public function getEntriesAction(Request $request) 84 public function getEntriesAction(Request $request)
@@ -86,17 +89,13 @@ class WallabagRestController extends Controller
86 $order = $request->query->get('order', 'desc'); 89 $order = $request->query->get('order', 'desc');
87 $page = (int) $request->query->get('page', 1); 90 $page = (int) $request->query->get('page', 1);
88 $perPage = (int) $request->query->get('perPage', 30); 91 $perPage = (int) $request->query->get('perPage', 30);
89 $tags = $request->query->get('tags', array()); 92 $tags = $request->query->get('tags', []);
90 93
91 $pager = $this 94 $pager = $this
92 ->getDoctrine() 95 ->getDoctrine()
93 ->getRepository('WallabagCoreBundle:Entry') 96 ->getRepository('WallabagCoreBundle:Entry')
94 ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order); 97 ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $sort, $order);
95 98
96 if (0 === $pager->getNbResults()) {
97 throw $this->createNotFoundException();
98 }
99
100 $pager->setCurrentPage($page); 99 $pager->setCurrentPage($page);
101 $pager->setMaxPerPage($perPage); 100 $pager->setMaxPerPage($perPage);
102 101
@@ -108,32 +107,31 @@ class WallabagRestController extends Controller
108 107
109 $json = $this->get('serializer')->serialize($paginatedCollection, 'json'); 108 $json = $this->get('serializer')->serialize($paginatedCollection, 'json');
110 109
111 return new Response($json, 200, array('application/json')); 110 return $this->renderJsonResponse($json);
112 } 111 }
113 112
114 /** 113 /**
115 * Retrieve a single entry 114 * Retrieve a single entry.
116 * 115 *
117 * @ApiDoc( 116 * @ApiDoc(
118 * requirements={ 117 * requirements={
119 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} 118 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
120 * } 119 * }
121 * ) 120 * )
121 *
122 * @return Entry 122 * @return Entry
123 */ 123 */
124 public function getEntryAction(Entry $entry) 124 public function getEntryAction(Entry $entry)
125 { 125 {
126 if ($entry->getUser()->getId() != $this->getUser()->getId()) { 126 $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
127 throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
128 }
129 127
130 $json = $this->get('serializer')->serialize($entry, 'json'); 128 $json = $this->get('serializer')->serialize($entry, 'json');
131 129
132 return new Response($json, 200, array('application/json')); 130 return $this->renderJsonResponse($json);
133 } 131 }
134 132
135 /** 133 /**
136 * Create an entry 134 * Create an entry.
137 * 135 *
138 * @ApiDoc( 136 * @ApiDoc(
139 * parameters={ 137 * parameters={
@@ -142,6 +140,7 @@ class WallabagRestController extends Controller
142 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."}, 140 * {"name"="tags", "dataType"="string", "required"=false, "format"="tag1,tag2,tag3", "description"="a comma-separated list of tags."},
143 * } 141 * }
144 * ) 142 * )
143 *
145 * @return Entry 144 * @return Entry
146 */ 145 */
147 public function postEntriesAction(Request $request) 146 public function postEntriesAction(Request $request)
@@ -165,11 +164,11 @@ class WallabagRestController extends Controller
165 164
166 $json = $this->get('serializer')->serialize($entry, 'json'); 165 $json = $this->get('serializer')->serialize($entry, 'json');
167 166
168 return new Response($json, 200, array('application/json')); 167 return $this->renderJsonResponse($json);
169 } 168 }
170 169
171 /** 170 /**
172 * Change several properties of an entry 171 * Change several properties of an entry.
173 * 172 *
174 * @ApiDoc( 173 * @ApiDoc(
175 * requirements={ 174 * requirements={
@@ -182,17 +181,16 @@ class WallabagRestController extends Controller
182 * {"name"="star", "dataType"="boolean", "required"=false, "format"="true or false", "description"="starred the entry."}, 181 * {"name"="star", "dataType"="boolean", "required"=false, "format"="true or false", "description"="starred the entry."},
183 * } 182 * }
184 * ) 183 * )
184 *
185 * @return Entry 185 * @return Entry
186 */ 186 */
187 public function patchEntriesAction(Entry $entry, Request $request) 187 public function patchEntriesAction(Entry $entry, Request $request)
188 { 188 {
189 if ($entry->getUser()->getId() != $this->getUser()->getId()) { 189 $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
190 throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
191 }
192 190
193 $title = $request->request->get("title"); 191 $title = $request->request->get('title');
194 $isArchived = $request->request->get("archive"); 192 $isArchived = $request->request->get('archive');
195 $isStarred = $request->request->get("star"); 193 $isStarred = $request->request->get('star');
196 194
197 if (!is_null($title)) { 195 if (!is_null($title)) {
198 $entry->setTitle($title); 196 $entry->setTitle($title);
@@ -216,24 +214,23 @@ class WallabagRestController extends Controller
216 214
217 $json = $this->get('serializer')->serialize($entry, 'json'); 215 $json = $this->get('serializer')->serialize($entry, 'json');
218 216
219 return new Response($json, 200, array('application/json')); 217 return $this->renderJsonResponse($json);
220 } 218 }
221 219
222 /** 220 /**
223 * Delete **permanently** an entry 221 * Delete **permanently** an entry.
224 * 222 *
225 * @ApiDoc( 223 * @ApiDoc(
226 * requirements={ 224 * requirements={
227 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} 225 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
228 * } 226 * }
229 * ) 227 * )
228 *
230 * @return Entry 229 * @return Entry
231 */ 230 */
232 public function deleteEntriesAction(Entry $entry) 231 public function deleteEntriesAction(Entry $entry)
233 { 232 {
234 if ($entry->getUser()->getId() != $this->getUser()->getId()) { 233 $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
235 throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
236 }
237 234
238 $em = $this->getDoctrine()->getManager(); 235 $em = $this->getDoctrine()->getManager();
239 $em->remove($entry); 236 $em->remove($entry);
@@ -241,11 +238,11 @@ class WallabagRestController extends Controller
241 238
242 $json = $this->get('serializer')->serialize($entry, 'json'); 239 $json = $this->get('serializer')->serialize($entry, 'json');
243 240
244 return new Response($json, 200, array('application/json')); 241 return $this->renderJsonResponse($json);
245 } 242 }
246 243
247 /** 244 /**
248 * Retrieve all tags for an entry 245 * Retrieve all tags for an entry.
249 * 246 *
250 * @ApiDoc( 247 * @ApiDoc(
251 * requirements={ 248 * requirements={
@@ -255,17 +252,15 @@ class WallabagRestController extends Controller
255 */ 252 */
256 public function getEntriesTagsAction(Entry $entry) 253 public function getEntriesTagsAction(Entry $entry)
257 { 254 {
258 if ($entry->getUser()->getId() != $this->getUser()->getId()) { 255 $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
259 throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
260 }
261 256
262 $json = $this->get('serializer')->serialize($entry->getTags(), 'json'); 257 $json = $this->get('serializer')->serialize($entry->getTags(), 'json');
263 258
264 return new Response($json, 200, array('application/json')); 259 return $this->renderJsonResponse($json);
265 } 260 }
266 261
267 /** 262 /**
268 * Add one or more tags to an entry 263 * Add one or more tags to an entry.
269 * 264 *
270 * @ApiDoc( 265 * @ApiDoc(
271 * requirements={ 266 * requirements={
@@ -278,9 +273,7 @@ class WallabagRestController extends Controller
278 */ 273 */
279 public function postEntriesTagsAction(Request $request, Entry $entry) 274 public function postEntriesTagsAction(Request $request, Entry $entry)
280 { 275 {
281 if ($entry->getUser()->getId() != $this->getUser()->getId()) { 276 $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
282 throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
283 }
284 277
285 $tags = $request->request->get('tags', ''); 278 $tags = $request->request->get('tags', '');
286 if (!empty($tags)) { 279 if (!empty($tags)) {
@@ -293,24 +286,22 @@ class WallabagRestController extends Controller
293 286
294 $json = $this->get('serializer')->serialize($entry, 'json'); 287 $json = $this->get('serializer')->serialize($entry, 'json');
295 288
296 return new Response($json, 200, array('application/json')); 289 return $this->renderJsonResponse($json);
297 } 290 }
298 291
299 /** 292 /**
300 * Permanently remove one tag for an entry 293 * Permanently remove one tag for an entry.
301 * 294 *
302 * @ApiDoc( 295 * @ApiDoc(
303 * requirements={ 296 * requirements={
304 * {"name"="tag", "dataType"="string", "requirement"="\w+", "description"="The tag"}, 297 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag ID"},
305 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"} 298 * {"name"="entry", "dataType"="integer", "requirement"="\w+", "description"="The entry ID"}
306 * } 299 * }
307 * ) 300 * )
308 */ 301 */
309 public function deleteEntriesTagsAction(Entry $entry, Tag $tag) 302 public function deleteEntriesTagsAction(Entry $entry, Tag $tag)
310 { 303 {
311 if ($entry->getUser()->getId() != $this->getUser()->getId()) { 304 $this->validateUserAccess($entry->getUser()->getId(), $this->getUser()->getId());
312 throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$entry->getUser()->getId().', logged user id: '.$this->getUser()->getId());
313 }
314 305
315 $entry->removeTag($tag); 306 $entry->removeTag($tag);
316 $em = $this->getDoctrine()->getManager(); 307 $em = $this->getDoctrine()->getManager();
@@ -319,11 +310,11 @@ class WallabagRestController extends Controller
319 310
320 $json = $this->get('serializer')->serialize($entry, 'json'); 311 $json = $this->get('serializer')->serialize($entry, 'json');
321 312
322 return new Response($json, 200, array('application/json')); 313 return $this->renderJsonResponse($json);
323 } 314 }
324 315
325 /** 316 /**
326 * Retrieve all tags 317 * Retrieve all tags.
327 * 318 *
328 * @ApiDoc() 319 * @ApiDoc()
329 */ 320 */
@@ -331,23 +322,21 @@ class WallabagRestController extends Controller
331 { 322 {
332 $json = $this->get('serializer')->serialize($this->getUser()->getTags(), 'json'); 323 $json = $this->get('serializer')->serialize($this->getUser()->getTags(), 'json');
333 324
334 return new Response($json, 200, array('application/json')); 325 return $this->renderJsonResponse($json);
335 } 326 }
336 327
337 /** 328 /**
338 * Permanently remove one tag from **every** entry 329 * Permanently remove one tag from **every** entry.
339 * 330 *
340 * @ApiDoc( 331 * @ApiDoc(
341 * requirements={ 332 * requirements={
342 * {"name"="tag", "dataType"="string", "requirement"="\w+", "description"="The tag"} 333 * {"name"="tag", "dataType"="integer", "requirement"="\w+", "description"="The tag"}
343 * } 334 * }
344 * ) 335 * )
345 */ 336 */
346 public function deleteTagAction(Tag $tag) 337 public function deleteTagAction(Tag $tag)
347 { 338 {
348 if ($tag->getUser()->getId() != $this->getUser()->getId()) { 339 $this->validateUserAccess($tag->getUser()->getId(), $this->getUser()->getId());
349 throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$tag->getUser()->getId().', logged user id: '.$this->getUser()->getId());
350 }
351 340
352 $em = $this->getDoctrine()->getManager(); 341 $em = $this->getDoctrine()->getManager();
353 $em->remove($tag); 342 $em->remove($tag);
@@ -355,6 +344,33 @@ class WallabagRestController extends Controller
355 344
356 $json = $this->get('serializer')->serialize($tag, 'json'); 345 $json = $this->get('serializer')->serialize($tag, 'json');
357 346
347 return $this->renderJsonResponse($json);
348 }
349
350 /**
351 * Validate that the first id is equal to the second one.
352 * If not, throw exception. It means a user try to access information from an other user.
353 *
354 * @param int $requestUserId User id from the requested source
355 * @param int $currentUserId User id from the retrieved source
356 */
357 private function validateUserAccess($requestUserId, $currentUserId)
358 {
359 if ($requestUserId != $currentUserId) {
360 throw $this->createAccessDeniedException('Access forbidden. Entry user id: '.$requestUserId.', logged user id: '.$currentUserId);
361 }
362 }
363
364 /**
365 * Send a JSON Response.
366 * We don't use the Symfony JsonRespone, because it takes an array as parameter instead of a JSON string.
367 *
368 * @param string $json
369 *
370 * @return Response
371 */
372 private function renderJsonResponse($json)
373 {
358 return new Response($json, 200, array('application/json')); 374 return new Response($json, 200, array('application/json'));
359 } 375 }
360} 376}
diff --git a/src/Wallabag/ApiBundle/DependencyInjection/Configuration.php b/src/Wallabag/ApiBundle/DependencyInjection/Configuration.php
new file mode 100644
index 00000000..cec45412
--- /dev/null
+++ b/src/Wallabag/ApiBundle/DependencyInjection/Configuration.php
@@ -0,0 +1,29 @@
1<?php
2
3namespace Wallabag\ApiBundle\DependencyInjection;
4
5use Symfony\Component\Config\Definition\Builder\TreeBuilder;
6use Symfony\Component\Config\Definition\ConfigurationInterface;
7
8/**
9 * This is the class that validates and merges configuration from your app/config files.
10 *
11 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html#cookbook-bundles-extension-config-class}
12 */
13class Configuration implements ConfigurationInterface
14{
15 /**
16 * {@inheritdoc}
17 */
18 public function getConfigTreeBuilder()
19 {
20 $treeBuilder = new TreeBuilder();
21 $rootNode = $treeBuilder->root('wallabag_api');
22
23 // Here you should define the parameters that are allowed to
24 // configure your bundle. See the documentation linked above for
25 // more information on that topic.
26
27 return $treeBuilder;
28 }
29}
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/Security/Factory/WsseFactory.php b/src/Wallabag/ApiBundle/DependencyInjection/Security/Factory/WsseFactory.php
index 0b5bdb40..402eb869 100644
--- a/src/Wallabag/CoreBundle/DependencyInjection/Security/Factory/WsseFactory.php
+++ b/src/Wallabag/ApiBundle/DependencyInjection/Security/Factory/WsseFactory.php
@@ -1,6 +1,6 @@
1<?php 1<?php
2 2
3namespace Wallabag\CoreBundle\DependencyInjection\Security\Factory; 3namespace Wallabag\ApiBundle\DependencyInjection\Security\Factory;
4 4
5use Symfony\Component\DependencyInjection\ContainerBuilder; 5use Symfony\Component\DependencyInjection\ContainerBuilder;
6use Symfony\Component\DependencyInjection\Reference; 6use Symfony\Component\DependencyInjection\Reference;
diff --git a/src/Wallabag/ApiBundle/DependencyInjection/WallabagApiExtension.php b/src/Wallabag/ApiBundle/DependencyInjection/WallabagApiExtension.php
new file mode 100644
index 00000000..c5cc204e
--- /dev/null
+++ b/src/Wallabag/ApiBundle/DependencyInjection/WallabagApiExtension.php
@@ -0,0 +1,25 @@
1<?php
2
3namespace Wallabag\ApiBundle\DependencyInjection;
4
5use Symfony\Component\DependencyInjection\ContainerBuilder;
6use Symfony\Component\Config\FileLocator;
7use Symfony\Component\HttpKernel\DependencyInjection\Extension;
8use Symfony\Component\DependencyInjection\Loader;
9
10class WallabagApiExtension extends Extension
11{
12 public function load(array $configs, ContainerBuilder $container)
13 {
14 $configuration = new Configuration();
15 $config = $this->processConfiguration($configuration, $configs);
16
17 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
18 $loader->load('services.yml');
19 }
20
21 public function getAlias()
22 {
23 return 'wallabag_api';
24 }
25}
diff --git a/src/Wallabag/ApiBundle/Resources/config/routing.yml b/src/Wallabag/ApiBundle/Resources/config/routing.yml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/Wallabag/ApiBundle/Resources/config/routing.yml
diff --git a/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
new file mode 100644
index 00000000..5f43f971
--- /dev/null
+++ b/src/Wallabag/ApiBundle/Resources/config/routing_rest.yml
@@ -0,0 +1,4 @@
1entries:
2 type: rest
3 resource: "WallabagApiBundle:WallabagRest"
4 name_prefix: api_
diff --git a/src/Wallabag/ApiBundle/Resources/config/services.yml b/src/Wallabag/ApiBundle/Resources/config/services.yml
new file mode 100644
index 00000000..6854a444
--- /dev/null
+++ b/src/Wallabag/ApiBundle/Resources/config/services.yml
@@ -0,0 +1,12 @@
1services:
2 wsse.security.authentication.provider:
3 class: Wallabag\ApiBundle\Security\Authentication\Provider\WsseProvider
4 public: false
5 arguments: ['', '%kernel.cache_dir%/security/nonces']
6
7 wsse.security.authentication.listener:
8 class: Wallabag\ApiBundle\Security\Firewall\WsseListener
9 public: false
10 tags:
11 - { name: monolog.logger, channel: wsse }
12 arguments: ['@security.context', '@security.authentication.manager', '@logger']
diff --git a/src/Wallabag/CoreBundle/Security/Authentication/Provider/WsseProvider.php b/src/Wallabag/ApiBundle/Security/Authentication/Provider/WsseProvider.php
index 7e6a5dfb..db73ae2a 100644
--- a/src/Wallabag/CoreBundle/Security/Authentication/Provider/WsseProvider.php
+++ b/src/Wallabag/ApiBundle/Security/Authentication/Provider/WsseProvider.php
@@ -1,12 +1,13 @@
1<?php 1<?php
2namespace Wallabag\CoreBundle\Security\Authentication\Provider; 2
3namespace Wallabag\ApiBundle\Security\Authentication\Provider;
3 4
4use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; 5use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface;
5use Symfony\Component\Security\Core\User\UserProviderInterface; 6use Symfony\Component\Security\Core\User\UserProviderInterface;
6use Symfony\Component\Security\Core\Exception\AuthenticationException; 7use Symfony\Component\Security\Core\Exception\AuthenticationException;
7use Symfony\Component\Security\Core\Exception\NonceExpiredException; 8use Symfony\Component\Security\Core\Exception\NonceExpiredException;
8use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; 9use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
9use Wallabag\CoreBundle\Security\Authentication\Token\WsseUserToken; 10use Wallabag\ApiBundle\Security\Authentication\Token\WsseUserToken;
10 11
11class WsseProvider implements AuthenticationProviderInterface 12class WsseProvider implements AuthenticationProviderInterface
12{ 13{
@@ -29,7 +30,7 @@ class WsseProvider implements AuthenticationProviderInterface
29 $user = $this->userProvider->loadUserByUsername($token->getUsername()); 30 $user = $this->userProvider->loadUserByUsername($token->getUsername());
30 31
31 if (!$user) { 32 if (!$user) {
32 throw new AuthenticationException("Bad credentials. Did you forgot your username?"); 33 throw new AuthenticationException('Bad credentials. Did you forgot your username?');
33 } 34 }
34 35
35 if ($user && $this->validateDigest($token->digest, $token->nonce, $token->created, $user->getPassword())) { 36 if ($user && $this->validateDigest($token->digest, $token->nonce, $token->created, $user->getPassword())) {
@@ -46,12 +47,12 @@ class WsseProvider implements AuthenticationProviderInterface
46 { 47 {
47 // Check created time is not in the future 48 // Check created time is not in the future
48 if (strtotime($created) > time()) { 49 if (strtotime($created) > time()) {
49 throw new AuthenticationException("Back to the future..."); 50 throw new AuthenticationException('Back to the future...');
50 } 51 }
51 52
52 // Expire timestamp after 5 minutes 53 // Expire timestamp after 5 minutes
53 if (time() - strtotime($created) > 300) { 54 if (time() - strtotime($created) > 300) {
54 throw new AuthenticationException("Too late for this timestamp... Watch your watch."); 55 throw new AuthenticationException('Too late for this timestamp... Watch your watch.');
55 } 56 }
56 57
57 // Validate nonce is unique within 5 minutes 58 // Validate nonce is unique within 5 minutes
@@ -65,7 +66,7 @@ class WsseProvider implements AuthenticationProviderInterface
65 $expected = base64_encode(sha1(base64_decode($nonce).$created.$secret, true)); 66 $expected = base64_encode(sha1(base64_decode($nonce).$created.$secret, true));
66 67
67 if ($digest !== $expected) { 68 if ($digest !== $expected) {
68 throw new AuthenticationException("Bad credentials ! Digest is not as expected."); 69 throw new AuthenticationException('Bad credentials ! Digest is not as expected.');
69 } 70 }
70 71
71 return $digest === $expected; 72 return $digest === $expected;
diff --git a/src/Wallabag/CoreBundle/Security/Authentication/Token/WsseUserToken.php b/src/Wallabag/ApiBundle/Security/Authentication/Token/WsseUserToken.php
index ea6fb9bf..e6d30224 100644
--- a/src/Wallabag/CoreBundle/Security/Authentication/Token/WsseUserToken.php
+++ b/src/Wallabag/ApiBundle/Security/Authentication/Token/WsseUserToken.php
@@ -1,5 +1,6 @@
1<?php 1<?php
2namespace Wallabag\CoreBundle\Security\Authentication\Token; 2
3namespace Wallabag\ApiBundle\Security\Authentication\Token;
3 4
4use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; 5use Symfony\Component\Security\Core\Authentication\Token\AbstractToken;
5 6
diff --git a/src/Wallabag/CoreBundle/Security/Firewall/WsseListener.php b/src/Wallabag/ApiBundle/Security/Firewall/WsseListener.php
index 6ffdfaf0..50587837 100644
--- a/src/Wallabag/CoreBundle/Security/Firewall/WsseListener.php
+++ b/src/Wallabag/ApiBundle/Security/Firewall/WsseListener.php
@@ -1,6 +1,6 @@
1<?php 1<?php
2 2
3namespace Wallabag\CoreBundle\Security\Firewall; 3namespace Wallabag\ApiBundle\Security\Firewall;
4 4
5use Symfony\Component\HttpFoundation\Response; 5use Symfony\Component\HttpFoundation\Response;
6use Symfony\Component\HttpKernel\Event\GetResponseEvent; 6use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -8,7 +8,7 @@ use Symfony\Component\Security\Http\Firewall\ListenerInterface;
8use Symfony\Component\Security\Core\Exception\AuthenticationException; 8use Symfony\Component\Security\Core\Exception\AuthenticationException;
9use Symfony\Component\Security\Core\SecurityContextInterface; 9use Symfony\Component\Security\Core\SecurityContextInterface;
10use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; 10use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
11use Wallabag\CoreBundle\Security\Authentication\Token\WsseUserToken; 11use Wallabag\ApiBundle\Security\Authentication\Token\WsseUserToken;
12use Psr\Log\LoggerInterface; 12use Psr\Log\LoggerInterface;
13 13
14class WsseListener implements ListenerInterface 14class WsseListener implements ListenerInterface
diff --git a/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php b/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php
new file mode 100644
index 00000000..86c8de1e
--- /dev/null
+++ b/src/Wallabag/ApiBundle/Tests/Controller/WallabagRestControllerTest.php
@@ -0,0 +1,410 @@
1<?php
2
3namespace Wallabag\ApiBundle\Tests\Controller;
4
5use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
6
7class WallabagRestControllerTest extends WebTestCase
8{
9 protected static $salt;
10
11 /**
12 * Grab the salt once and store it to be available for all tests.
13 */
14 public static function setUpBeforeClass()
15 {
16 $client = self::createClient();
17
18 $user = $client->getContainer()
19 ->get('doctrine.orm.entity_manager')
20 ->getRepository('WallabagCoreBundle:User')
21 ->findOneByUsername('admin');
22
23 self::$salt = $user->getSalt();
24 }
25
26 /**
27 * Generate HTTP headers for authenticate user on API.
28 *
29 * @param string $username
30 * @param string $password
31 *
32 * @return array
33 */
34 private function generateHeaders($username, $password)
35 {
36 $encryptedPassword = sha1($password.$username.self::$salt);
37 $nonce = substr(md5(uniqid('nonce_', true)), 0, 16);
38
39 $now = new \DateTime('now', new \DateTimeZone('UTC'));
40 $created = (string) $now->format('Y-m-d\TH:i:s\Z');
41 $digest = base64_encode(sha1(base64_decode($nonce).$created.$encryptedPassword, true));
42
43 return array(
44 'HTTP_AUTHORIZATION' => 'Authorization profile="UsernameToken"',
45 'HTTP_x-wsse' => 'X-WSSE: UsernameToken Username="'.$username.'", PasswordDigest="'.$digest.'", Nonce="'.$nonce.'", Created="'.$created.'"',
46 );
47 }
48
49 public function testGetSalt()
50 {
51 $client = $this->createClient();
52 $client->request('GET', '/api/salts/admin.json');
53
54 $user = $client->getContainer()
55 ->get('doctrine.orm.entity_manager')
56 ->getRepository('WallabagCoreBundle:User')
57 ->findOneByUsername('admin');
58
59 $this->assertEquals(200, $client->getResponse()->getStatusCode());
60
61 $content = json_decode($client->getResponse()->getContent(), true);
62
63 $this->assertArrayHasKey(0, $content);
64 $this->assertEquals($user->getSalt(), $content[0]);
65
66 $client->request('GET', '/api/salts/notfound.json');
67 $this->assertEquals(404, $client->getResponse()->getStatusCode());
68 }
69
70 public function testWithBadHeaders()
71 {
72 $client = $this->createClient();
73
74 $entry = $client->getContainer()
75 ->get('doctrine.orm.entity_manager')
76 ->getRepository('WallabagCoreBundle:Entry')
77 ->findOneByIsArchived(false);
78
79 if (!$entry) {
80 $this->markTestSkipped('No content found in db.');
81 }
82
83 $badHeaders = array(
84 'HTTP_AUTHORIZATION' => 'Authorization profile="UsernameToken"',
85 'HTTP_x-wsse' => 'X-WSSE: UsernameToken Username="admin", PasswordDigest="Wr0ngDig3st", Nonce="n0Nc3", Created="2015-01-01T13:37:00Z"',
86 );
87
88 $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $badHeaders);
89 $this->assertEquals(403, $client->getResponse()->getStatusCode());
90 }
91
92 public function testGetOneEntry()
93 {
94 $client = $this->createClient();
95 $headers = $this->generateHeaders('admin', 'mypassword');
96
97 $entry = $client->getContainer()
98 ->get('doctrine.orm.entity_manager')
99 ->getRepository('WallabagCoreBundle:Entry')
100 ->findOneBy(array('user' => 1, 'isArchived' => false));
101
102 if (!$entry) {
103 $this->markTestSkipped('No content found in db.');
104 }
105
106 $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
107
108 $this->assertEquals(200, $client->getResponse()->getStatusCode());
109
110 $content = json_decode($client->getResponse()->getContent(), true);
111
112 $this->assertEquals($entry->getTitle(), $content['title']);
113 $this->assertEquals($entry->getUrl(), $content['url']);
114 $this->assertCount(count($entry->getTags()), $content['tags']);
115
116 $this->assertTrue(
117 $client->getResponse()->headers->contains(
118 'Content-Type',
119 'application/json'
120 )
121 );
122 }
123
124 public function testGetOneEntryWrongUser()
125 {
126 $client = $this->createClient();
127 $headers = $this->generateHeaders('admin', 'mypassword');
128
129 $entry = $client->getContainer()
130 ->get('doctrine.orm.entity_manager')
131 ->getRepository('WallabagCoreBundle:Entry')
132 ->findOneBy(array('user' => 2, 'isArchived' => false));
133
134 if (!$entry) {
135 $this->markTestSkipped('No content found in db.');
136 }
137
138 $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
139
140 $this->assertEquals(403, $client->getResponse()->getStatusCode());
141 }
142
143 public function testGetEntries()
144 {
145 $client = $this->createClient();
146 $headers = $this->generateHeaders('admin', 'mypassword');
147
148 $client->request('GET', '/api/entries', array(), array(), $headers);
149
150 $this->assertEquals(200, $client->getResponse()->getStatusCode());
151
152 $content = json_decode($client->getResponse()->getContent(), true);
153
154 $this->assertGreaterThanOrEqual(1, count($content));
155 $this->assertNotEmpty($content['_embedded']['items']);
156 $this->assertGreaterThanOrEqual(1, $content['total']);
157 $this->assertEquals(1, $content['page']);
158 $this->assertGreaterThanOrEqual(1, $content['pages']);
159
160 $this->assertTrue(
161 $client->getResponse()->headers->contains(
162 'Content-Type',
163 'application/json'
164 )
165 );
166 }
167
168 public function testGetStarredEntries()
169 {
170 $client = $this->createClient();
171 $headers = $this->generateHeaders('admin', 'mypassword');
172
173 $client->request('GET', '/api/entries', array('archive' => 1), array(), $headers);
174
175 $this->assertEquals(200, $client->getResponse()->getStatusCode());
176
177 $content = json_decode($client->getResponse()->getContent(), true);
178
179 $this->assertGreaterThanOrEqual(1, count($content));
180 $this->assertNotEmpty($content['_embedded']['items']);
181 $this->assertGreaterThanOrEqual(1, $content['total']);
182 $this->assertEquals(1, $content['page']);
183 $this->assertGreaterThanOrEqual(1, $content['pages']);
184
185 $this->assertTrue(
186 $client->getResponse()->headers->contains(
187 'Content-Type',
188 'application/json'
189 )
190 );
191 }
192
193 public function testDeleteEntry()
194 {
195 $client = $this->createClient();
196 $headers = $this->generateHeaders('admin', 'mypassword');
197
198 $entry = $client->getContainer()
199 ->get('doctrine.orm.entity_manager')
200 ->getRepository('WallabagCoreBundle:Entry')
201 ->findOneByUser(1);
202
203 if (!$entry) {
204 $this->markTestSkipped('No content found in db.');
205 }
206
207 $client->request('DELETE', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
208
209 $this->assertEquals(200, $client->getResponse()->getStatusCode());
210
211 $content = json_decode($client->getResponse()->getContent(), true);
212
213 $this->assertEquals($entry->getTitle(), $content['title']);
214 $this->assertEquals($entry->getUrl(), $content['url']);
215
216 // We'll try to delete this entry again
217 $headers = $this->generateHeaders('admin', 'mypassword');
218
219 $client->request('DELETE', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
220
221 $this->assertEquals(404, $client->getResponse()->getStatusCode());
222 }
223
224 public function testPostEntry()
225 {
226 $client = $this->createClient();
227 $headers = $this->generateHeaders('admin', 'mypassword');
228
229 $client->request('POST', '/api/entries.json', array(
230 'url' => 'http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html',
231 'tags' => 'google',
232 ), array(), $headers);
233
234 $this->assertEquals(200, $client->getResponse()->getStatusCode());
235
236 $content = json_decode($client->getResponse()->getContent(), true);
237
238 $this->assertGreaterThan(0, $content['id']);
239 $this->assertEquals('http://www.lemonde.fr/pixels/article/2015/03/28/plongee-dans-l-univers-d-ingress-le-jeu-de-google-aux-frontieres-du-reel_4601155_4408996.html', $content['url']);
240 $this->assertEquals(false, $content['is_archived']);
241 $this->assertEquals(false, $content['is_starred']);
242 $this->assertCount(1, $content['tags']);
243 }
244
245 public function testPatchEntry()
246 {
247 $client = $this->createClient();
248 $headers = $this->generateHeaders('admin', 'mypassword');
249
250 $entry = $client->getContainer()
251 ->get('doctrine.orm.entity_manager')
252 ->getRepository('WallabagCoreBundle:Entry')
253 ->findOneByUser(1);
254
255 if (!$entry) {
256 $this->markTestSkipped('No content found in db.');
257 }
258
259 // hydrate the tags relations
260 $nbTags = count($entry->getTags());
261
262 $client->request('PATCH', '/api/entries/'.$entry->getId().'.json', array(
263 'title' => 'New awesome title',
264 'tags' => 'new tag '.uniqid(),
265 'star' => true,
266 'archive' => false,
267 ), array(), $headers);
268
269 $this->assertEquals(200, $client->getResponse()->getStatusCode());
270
271 $content = json_decode($client->getResponse()->getContent(), true);
272
273 $this->assertEquals($entry->getId(), $content['id']);
274 $this->assertEquals($entry->getUrl(), $content['url']);
275 $this->assertEquals('New awesome title', $content['title']);
276 $this->assertGreaterThan($nbTags, count($content['tags']));
277 }
278
279 public function testGetTagsEntry()
280 {
281 $client = $this->createClient();
282 $headers = $this->generateHeaders('admin', 'mypassword');
283
284 $entry = $client->getContainer()
285 ->get('doctrine.orm.entity_manager')
286 ->getRepository('WallabagCoreBundle:Entry')
287 ->findOneWithTags(1);
288
289 $entry = $entry[0];
290
291 if (!$entry) {
292 $this->markTestSkipped('No content found in db.');
293 }
294
295 $tags = array();
296 foreach ($entry->getTags() as $tag) {
297 $tags[] = array('id' => $tag->getId(), 'label' => $tag->getLabel());
298 }
299
300 $client->request('GET', '/api/entries/'.$entry->getId().'/tags', array(), array(), $headers);
301
302 $this->assertEquals(json_encode($tags, JSON_HEX_QUOT), $client->getResponse()->getContent());
303 }
304
305 public function testPostTagsOnEntry()
306 {
307 $client = $this->createClient();
308 $headers = $this->generateHeaders('admin', 'mypassword');
309
310 $entry = $client->getContainer()
311 ->get('doctrine.orm.entity_manager')
312 ->getRepository('WallabagCoreBundle:Entry')
313 ->findOneByUser(1);
314
315 if (!$entry) {
316 $this->markTestSkipped('No content found in db.');
317 }
318
319 $nbTags = count($entry->getTags());
320
321 $newTags = 'tag1,tag2,tag3';
322
323 $client->request('POST', '/api/entries/'.$entry->getId().'/tags', array('tags' => $newTags), array(), $headers);
324
325 $this->assertEquals(200, $client->getResponse()->getStatusCode());
326
327 $content = json_decode($client->getResponse()->getContent(), true);
328
329 $this->assertArrayHasKey('tags', $content);
330 $this->assertEquals($nbTags + 3, count($content['tags']));
331
332 $entryDB = $client->getContainer()
333 ->get('doctrine.orm.entity_manager')
334 ->getRepository('WallabagCoreBundle:Entry')
335 ->find($entry->getId());
336
337 $tagsInDB = array();
338 foreach ($entryDB->getTags()->toArray() as $tag) {
339 $tagsInDB[$tag->getId()] = $tag->getLabel();
340 }
341
342 foreach (explode(',', $newTags) as $tag) {
343 $this->assertContains($tag, $tagsInDB);
344 }
345 }
346
347 public function testDeleteOneTagEntrie()
348 {
349 $client = $this->createClient();
350 $headers = $this->generateHeaders('admin', 'mypassword');
351
352 $entry = $client->getContainer()
353 ->get('doctrine.orm.entity_manager')
354 ->getRepository('WallabagCoreBundle:Entry')
355 ->findOneByUser(1);
356
357 if (!$entry) {
358 $this->markTestSkipped('No content found in db.');
359 }
360
361 // hydrate the tags relations
362 $nbTags = count($entry->getTags());
363 $tag = $entry->getTags()[0];
364
365 $client->request('DELETE', '/api/entries/'.$entry->getId().'/tags/'.$tag->getId().'.json', array(), array(), $headers);
366
367 $this->assertEquals(200, $client->getResponse()->getStatusCode());
368
369 $content = json_decode($client->getResponse()->getContent(), true);
370
371 $this->assertArrayHasKey('tags', $content);
372 $this->assertEquals($nbTags - 1, count($content['tags']));
373 }
374
375 public function testGetUserTags()
376 {
377 $client = $this->createClient();
378 $headers = $this->generateHeaders('admin', 'mypassword');
379
380 $client->request('GET', '/api/tags.json', array(), array(), $headers);
381
382 $this->assertEquals(200, $client->getResponse()->getStatusCode());
383
384 $content = json_decode($client->getResponse()->getContent(), true);
385
386 $this->assertGreaterThan(0, $content);
387 $this->assertArrayHasKey('id', $content[0]);
388 $this->assertArrayHasKey('label', $content[0]);
389
390 return end($content);
391 }
392
393 /**
394 * @depends testGetUserTags
395 */
396 public function testDeleteUserTag($tag)
397 {
398 $client = $this->createClient();
399 $headers = $this->generateHeaders('admin', 'mypassword');
400
401 $client->request('DELETE', '/api/tags/'.$tag['id'].'.json', array(), array(), $headers);
402
403 $this->assertEquals(200, $client->getResponse()->getStatusCode());
404
405 $content = json_decode($client->getResponse()->getContent(), true);
406
407 $this->assertArrayHasKey('label', $content);
408 $this->assertEquals($tag['label'], $content['label']);
409 }
410}
diff --git a/src/Wallabag/ApiBundle/WallabagApiBundle.php b/src/Wallabag/ApiBundle/WallabagApiBundle.php
new file mode 100644
index 00000000..2484f277
--- /dev/null
+++ b/src/Wallabag/ApiBundle/WallabagApiBundle.php
@@ -0,0 +1,18 @@
1<?php
2
3namespace Wallabag\ApiBundle;
4
5use Symfony\Component\HttpKernel\Bundle\Bundle;
6use Wallabag\ApiBundle\DependencyInjection\Security\Factory\WsseFactory;
7use Symfony\Component\DependencyInjection\ContainerBuilder;
8
9class WallabagApiBundle extends Bundle
10{
11 public function build(ContainerBuilder $container)
12 {
13 parent::build($container);
14
15 $extension = $container->getExtension('security');
16 $extension->addSecurityListenerFactory(new WsseFactory());
17 }
18}
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php
index 493842f7..491c67f9 100644
--- a/src/Wallabag/CoreBundle/Command/InstallCommand.php
+++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php
@@ -225,7 +225,7 @@ class InstallCommand extends ContainerAwareCommand
225 } 225 }
226 226
227 /** 227 /**
228 * Run a command 228 * Run a command.
229 * 229 *
230 * @param string $command 230 * @param string $command
231 * @param array $parameters Parameters to this command (usually 'force' => true) 231 * @param array $parameters Parameters to this command (usually 'force' => true)
@@ -266,9 +266,9 @@ class InstallCommand extends ContainerAwareCommand
266 } 266 }
267 267
268 /** 268 /**
269 * Check if the database already exists 269 * Check if the database already exists.
270 * 270 *
271 * @return boolean 271 * @return bool
272 */ 272 */
273 private function isDatabasePresent() 273 private function isDatabasePresent()
274 { 274 {
@@ -300,9 +300,9 @@ class InstallCommand extends ContainerAwareCommand
300 300
301 /** 301 /**
302 * Check if the schema is already created. 302 * Check if the schema is already created.
303 * If we found at least oen table, it means the schema exists 303 * If we found at least oen table, it means the schema exists.
304 * 304 *
305 * @return boolean 305 * @return bool
306 */ 306 */
307 private function isSchemaPresent() 307 private function isSchemaPresent()
308 { 308 {
diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php
index 898c291f..62ef3eea 100644
--- a/src/Wallabag/CoreBundle/Controller/ConfigController.php
+++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php
@@ -133,7 +133,7 @@ class ConfigController extends Controller
133 'rss' => array( 133 'rss' => array(
134 'username' => $user->getUsername(), 134 'username' => $user->getUsername(),
135 'token' => $config->getRssToken(), 135 'token' => $config->getRssToken(),
136 ) 136 ),
137 )); 137 ));
138 } 138 }
139 139
diff --git a/src/Wallabag/CoreBundle/Controller/EntryController.php b/src/Wallabag/CoreBundle/Controller/EntryController.php
index 8a8f3cd7..7fd982c9 100644
--- a/src/Wallabag/CoreBundle/Controller/EntryController.php
+++ b/src/Wallabag/CoreBundle/Controller/EntryController.php
@@ -50,7 +50,7 @@ class EntryController extends Controller
50 } 50 }
51 51
52 /** 52 /**
53 * Shows unread entries for current user 53 * Shows unread entries for current user.
54 * 54 *
55 * @Route("/unread", name="unread") 55 * @Route("/unread", name="unread")
56 * 56 *
@@ -70,7 +70,7 @@ class EntryController extends Controller
70 } 70 }
71 71
72 /** 72 /**
73 * Shows read entries for current user 73 * Shows read entries for current user.
74 * 74 *
75 * @Route("/archive", name="archive") 75 * @Route("/archive", name="archive")
76 * 76 *
@@ -90,7 +90,7 @@ class EntryController extends Controller
90 } 90 }
91 91
92 /** 92 /**
93 * Shows starred entries for current user 93 * Shows starred entries for current user.
94 * 94 *
95 * @Route("/starred", name="starred") 95 * @Route("/starred", name="starred")
96 * 96 *
@@ -110,7 +110,7 @@ class EntryController extends Controller
110 } 110 }
111 111
112 /** 112 /**
113 * Shows entry content 113 * Shows entry content.
114 * 114 *
115 * @param Entry $entry 115 * @param Entry $entry
116 * 116 *
@@ -129,7 +129,7 @@ class EntryController extends Controller
129 } 129 }
130 130
131 /** 131 /**
132 * Changes read status for an entry 132 * Changes read status for an entry.
133 * 133 *
134 * @param Request $request 134 * @param Request $request
135 * @param Entry $entry 135 * @param Entry $entry
@@ -154,7 +154,7 @@ class EntryController extends Controller
154 } 154 }
155 155
156 /** 156 /**
157 * Changes favorite status for an entry 157 * Changes favorite status for an entry.
158 * 158 *
159 * @param Request $request 159 * @param Request $request
160 * @param Entry $entry 160 * @param Entry $entry
@@ -179,7 +179,7 @@ class EntryController extends Controller
179 } 179 }
180 180
181 /** 181 /**
182 * Deletes entry 182 * Deletes entry.
183 * 183 *
184 * @param Request $request 184 * @param Request $request
185 * @param Entry $entry 185 * @param Entry $entry
@@ -205,7 +205,7 @@ class EntryController extends Controller
205 } 205 }
206 206
207 /** 207 /**
208 * Check if the logged user can manage the given entry 208 * Check if the logged user can manage the given entry.
209 * 209 *
210 * @param Entry $entry 210 * @param Entry $entry
211 */ 211 */
diff --git a/src/Wallabag/CoreBundle/Controller/RssController.php b/src/Wallabag/CoreBundle/Controller/RssController.php
index 14f1dcb2..86754e15 100644
--- a/src/Wallabag/CoreBundle/Controller/RssController.php
+++ b/src/Wallabag/CoreBundle/Controller/RssController.php
@@ -11,7 +11,7 @@ use Wallabag\CoreBundle\Entity\Entry;
11class RssController extends Controller 11class RssController extends Controller
12{ 12{
13 /** 13 /**
14 * Shows unread entries for current user 14 * Shows unread entries for current user.
15 * 15 *
16 * @Route("/{username}/{token}/unread.xml", name="unread_rss", defaults={"_format"="xml"}) 16 * @Route("/{username}/{token}/unread.xml", name="unread_rss", defaults={"_format"="xml"})
17 * @ParamConverter("user", class="WallabagCoreBundle:User", converter="username_rsstoken_converter") 17 * @ParamConverter("user", class="WallabagCoreBundle:User", converter="username_rsstoken_converter")
@@ -35,7 +35,7 @@ class RssController extends Controller
35 } 35 }
36 36
37 /** 37 /**
38 * Shows read entries for current user 38 * Shows read entries for current user.
39 * 39 *
40 * @Route("/{username}/{token}/archive.xml", name="archive_rss") 40 * @Route("/{username}/{token}/archive.xml", name="archive_rss")
41 * @ParamConverter("user", class="WallabagCoreBundle:User", converter="username_rsstoken_converter") 41 * @ParamConverter("user", class="WallabagCoreBundle:User", converter="username_rsstoken_converter")
@@ -59,7 +59,7 @@ class RssController extends Controller
59 } 59 }
60 60
61 /** 61 /**
62 * Shows starred entries for current user 62 * Shows starred entries for current user.
63 * 63 *
64 * @Route("/{username}/{token}/starred.xml", name="starred_rss") 64 * @Route("/{username}/{token}/starred.xml", name="starred_rss")
65 * @ParamConverter("user", class="WallabagCoreBundle:User", converter="username_rsstoken_converter") 65 * @ParamConverter("user", class="WallabagCoreBundle:User", converter="username_rsstoken_converter")
diff --git a/src/Wallabag/CoreBundle/Controller/SecurityController.php b/src/Wallabag/CoreBundle/Controller/SecurityController.php
index fe511db5..a61a898b 100644
--- a/src/Wallabag/CoreBundle/Controller/SecurityController.php
+++ b/src/Wallabag/CoreBundle/Controller/SecurityController.php
@@ -30,9 +30,10 @@ class SecurityController extends Controller
30 } 30 }
31 31
32 /** 32 /**
33 * Request forgot password: show form 33 * Request forgot password: show form.
34 * 34 *
35 * @Route("/forgot-password", name="forgot_password") 35 * @Route("/forgot-password", name="forgot_password")
36 *
36 * @Method({"GET", "POST"}) 37 * @Method({"GET", "POST"})
37 */ 38 */
38 public function forgotPasswordAction(Request $request) 39 public function forgotPasswordAction(Request $request)
@@ -73,9 +74,10 @@ class SecurityController extends Controller
73 } 74 }
74 75
75 /** 76 /**
76 * Tell the user to check his email provider 77 * Tell the user to check his email provider.
77 * 78 *
78 * @Route("/forgot-password/check-email", name="forgot_password_check_email") 79 * @Route("/forgot-password/check-email", name="forgot_password_check_email")
80 *
79 * @Method({"GET"}) 81 * @Method({"GET"})
80 */ 82 */
81 public function checkEmailAction(Request $request) 83 public function checkEmailAction(Request $request)
@@ -93,9 +95,10 @@ class SecurityController extends Controller
93 } 95 }
94 96
95 /** 97 /**
96 * Reset user password 98 * Reset user password.
97 * 99 *
98 * @Route("/forgot-password/{token}", name="forgot_password_reset") 100 * @Route("/forgot-password/{token}", name="forgot_password_reset")
101 *
99 * @Method({"GET", "POST"}) 102 * @Method({"GET", "POST"})
100 */ 103 */
101 public function resetAction(Request $request, $token) 104 public function resetAction(Request $request, $token)
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php
index 54d0d6b6..547d6753 100644
--- a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php
+++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadEntryData.php
@@ -39,9 +39,9 @@ class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface
39 $entry3->setContent('This is my content /o/'); 39 $entry3->setContent('This is my content /o/');
40 40
41 $tag1 = new Tag($this->getReference('bob-user')); 41 $tag1 = new Tag($this->getReference('bob-user'));
42 $tag1->setLabel("foo"); 42 $tag1->setLabel('foo');
43 $tag2 = new Tag($this->getReference('bob-user')); 43 $tag2 = new Tag($this->getReference('bob-user'));
44 $tag2->setLabel("bar"); 44 $tag2->setLabel('bar');
45 45
46 $entry3->addTag($tag1); 46 $entry3->addTag($tag1);
47 $entry3->addTag($tag2); 47 $entry3->addTag($tag2);
@@ -56,9 +56,9 @@ class LoadEntryData extends AbstractFixture implements OrderedFixtureInterface
56 $entry4->setContent('This is my content /o/'); 56 $entry4->setContent('This is my content /o/');
57 57
58 $tag1 = new Tag($this->getReference('admin-user')); 58 $tag1 = new Tag($this->getReference('admin-user'));
59 $tag1->setLabel("foo"); 59 $tag1->setLabel('foo');
60 $tag2 = new Tag($this->getReference('admin-user')); 60 $tag2 = new Tag($this->getReference('admin-user'));
61 $tag2->setLabel("bar"); 61 $tag2->setLabel('bar');
62 62
63 $entry4->addTag($tag1); 63 $entry4->addTag($tag1);
64 $entry4->addTag($tag2); 64 $entry4->addTag($tag2);
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
index c6ecc99e..7493351b 100644
--- a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
+++ b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
@@ -3,15 +3,15 @@
3namespace Wallabag\CoreBundle\DependencyInjection; 3namespace Wallabag\CoreBundle\DependencyInjection;
4 4
5use Symfony\Component\DependencyInjection\ContainerBuilder; 5use Symfony\Component\DependencyInjection\ContainerBuilder;
6use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
7use Symfony\Component\HttpKernel\DependencyInjection\Extension;
8use Symfony\Component\Config\FileLocator; 6use Symfony\Component\Config\FileLocator;
7use Symfony\Component\HttpKernel\DependencyInjection\Extension;
8use Symfony\Component\DependencyInjection\Loader;
9 9
10class WallabagCoreExtension extends Extension 10class WallabagCoreExtension extends Extension
11{ 11{
12 public function load(array $configs, ContainerBuilder $container) 12 public function load(array $configs, ContainerBuilder $container)
13 { 13 {
14 $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 14 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
15 $loader->load('services.yml'); 15 $loader->load('services.yml');
16 } 16 }
17 17
diff --git a/src/Wallabag/CoreBundle/Doctrine/Mapping/PrefixedNamingStrategy.php b/src/Wallabag/CoreBundle/Doctrine/Mapping/PrefixedNamingStrategy.php
index 861a60ea..509348db 100644
--- a/src/Wallabag/CoreBundle/Doctrine/Mapping/PrefixedNamingStrategy.php
+++ b/src/Wallabag/CoreBundle/Doctrine/Mapping/PrefixedNamingStrategy.php
@@ -25,7 +25,7 @@ class PrefixedNamingStrategy implements NamingStrategy
25 */ 25 */
26 public function classToTableName($className) 26 public function classToTableName($className)
27 { 27 {
28 return strtolower($this->prefix . substr($className, strrpos($className, '\\') + 1)); 28 return strtolower($this->prefix.substr($className, strrpos($className, '\\') + 1));
29 } 29 }
30 30
31 /** 31 /**
@@ -49,7 +49,7 @@ class PrefixedNamingStrategy implements NamingStrategy
49 */ 49 */
50 public function joinColumnName($propertyName) 50 public function joinColumnName($propertyName)
51 { 51 {
52 return $propertyName . '_' . $this->referenceColumnName(); 52 return $propertyName.'_'.$this->referenceColumnName();
53 } 53 }
54 54
55 /** 55 /**
@@ -62,7 +62,7 @@ class PrefixedNamingStrategy implements NamingStrategy
62 // ie: not "wallabag_entry_wallabag_tag" but "wallabag_entry_tag" 62 // ie: not "wallabag_entry_wallabag_tag" but "wallabag_entry_tag"
63 $target = substr($targetEntity, strrpos($targetEntity, '\\') + 1); 63 $target = substr($targetEntity, strrpos($targetEntity, '\\') + 1);
64 64
65 return strtolower($this->classToTableName($sourceEntity) . '_' .$target); 65 return strtolower($this->classToTableName($sourceEntity).'_'.$target);
66 } 66 }
67 67
68 /** 68 /**
@@ -70,6 +70,14 @@ class PrefixedNamingStrategy implements NamingStrategy
70 */ 70 */
71 public function joinKeyColumnName($entityName, $referencedColumnName = null) 71 public function joinKeyColumnName($entityName, $referencedColumnName = null)
72 { 72 {
73 return strtolower($this->classToTableName($entityName) . '_' .($referencedColumnName ?: $this->referenceColumnName())); 73 return strtolower($this->classToTableName($entityName).'_'.($referencedColumnName ?: $this->referenceColumnName()));
74 }
75
76 /**
77 * {@inheritdoc}
78 */
79 public function embeddedFieldToColumnName($propertyName, $embeddedColumnName, $className = null, $embeddedClassName = null)
80 {
81 return $propertyName.'_'.$embeddedColumnName;
74 } 82 }
75} 83}
diff --git a/src/Wallabag/CoreBundle/Entity/Config.php b/src/Wallabag/CoreBundle/Entity/Config.php
index 62ea637e..025d94ef 100644
--- a/src/Wallabag/CoreBundle/Entity/Config.php
+++ b/src/Wallabag/CoreBundle/Entity/Config.php
@@ -6,7 +6,7 @@ use Doctrine\ORM\Mapping as ORM;
6use Symfony\Component\Validator\Constraints as Assert; 6use Symfony\Component\Validator\Constraints as Assert;
7 7
8/** 8/**
9 * Config 9 * Config.
10 * 10 *
11 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\ConfigRepository") 11 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\ConfigRepository")
12 * @ORM\Table 12 * @ORM\Table
@@ -15,7 +15,7 @@ use Symfony\Component\Validator\Constraints as Assert;
15class Config 15class Config
16{ 16{
17 /** 17 /**
18 * @var integer 18 * @var int
19 * 19 *
20 * @ORM\Column(name="id", type="integer") 20 * @ORM\Column(name="id", type="integer")
21 * @ORM\Id 21 * @ORM\Id
@@ -32,7 +32,7 @@ class Config
32 private $theme; 32 private $theme;
33 33
34 /** 34 /**
35 * @var integer 35 * @var int
36 * 36 *
37 * @Assert\NotBlank() 37 * @Assert\NotBlank()
38 * @Assert\Range( 38 * @Assert\Range(
@@ -60,7 +60,7 @@ class Config
60 private $rssToken; 60 private $rssToken;
61 61
62 /** 62 /**
63 * @var integer 63 * @var int
64 * 64 *
65 * @ORM\Column(name="rss_limit", type="integer", nullable=true) 65 * @ORM\Column(name="rss_limit", type="integer", nullable=true)
66 * @Assert\Range( 66 * @Assert\Range(
@@ -85,9 +85,9 @@ class Config
85 } 85 }
86 86
87 /** 87 /**
88 * Get id 88 * Get id.
89 * 89 *
90 * @return integer 90 * @return int
91 */ 91 */
92 public function getId() 92 public function getId()
93 { 93 {
@@ -95,9 +95,10 @@ class Config
95 } 95 }
96 96
97 /** 97 /**
98 * Set theme 98 * Set theme.
99 *
100 * @param string $theme
99 * 101 *
100 * @param string $theme
101 * @return Config 102 * @return Config
102 */ 103 */
103 public function setTheme($theme) 104 public function setTheme($theme)
@@ -108,7 +109,7 @@ class Config
108 } 109 }
109 110
110 /** 111 /**
111 * Get theme 112 * Get theme.
112 * 113 *
113 * @return string 114 * @return string
114 */ 115 */
@@ -118,9 +119,10 @@ class Config
118 } 119 }
119 120
120 /** 121 /**
121 * Set itemsPerPage 122 * Set itemsPerPage.
123 *
124 * @param int $itemsPerPage
122 * 125 *
123 * @param integer $itemsPerPage
124 * @return Config 126 * @return Config
125 */ 127 */
126 public function setItemsPerPage($itemsPerPage) 128 public function setItemsPerPage($itemsPerPage)
@@ -131,9 +133,9 @@ class Config
131 } 133 }
132 134
133 /** 135 /**
134 * Get itemsPerPage 136 * Get itemsPerPage.
135 * 137 *
136 * @return integer 138 * @return int
137 */ 139 */
138 public function getItemsPerPage() 140 public function getItemsPerPage()
139 { 141 {
@@ -141,9 +143,10 @@ class Config
141 } 143 }
142 144
143 /** 145 /**
144 * Set language 146 * Set language.
147 *
148 * @param string $language
145 * 149 *
146 * @param string $language
147 * @return Config 150 * @return Config
148 */ 151 */
149 public function setLanguage($language) 152 public function setLanguage($language)
@@ -154,7 +157,7 @@ class Config
154 } 157 }
155 158
156 /** 159 /**
157 * Get language 160 * Get language.
158 * 161 *
159 * @return string 162 * @return string
160 */ 163 */
@@ -164,9 +167,10 @@ class Config
164 } 167 }
165 168
166 /** 169 /**
167 * Set user 170 * Set user.
171 *
172 * @param \Wallabag\CoreBundle\Entity\User $user
168 * 173 *
169 * @param \Wallabag\CoreBundle\Entity\User $user
170 * @return Config 174 * @return Config
171 */ 175 */
172 public function setUser(\Wallabag\CoreBundle\Entity\User $user = null) 176 public function setUser(\Wallabag\CoreBundle\Entity\User $user = null)
@@ -177,7 +181,7 @@ class Config
177 } 181 }
178 182
179 /** 183 /**
180 * Get user 184 * Get user.
181 * 185 *
182 * @return \Wallabag\CoreBundle\Entity\User 186 * @return \Wallabag\CoreBundle\Entity\User
183 */ 187 */
@@ -187,9 +191,10 @@ class Config
187 } 191 }
188 192
189 /** 193 /**
190 * Set rssToken 194 * Set rssToken.
195 *
196 * @param string $rssToken
191 * 197 *
192 * @param string $rssToken
193 * @return Config 198 * @return Config
194 */ 199 */
195 public function setRssToken($rssToken) 200 public function setRssToken($rssToken)
@@ -200,7 +205,7 @@ class Config
200 } 205 }
201 206
202 /** 207 /**
203 * Get rssToken 208 * Get rssToken.
204 * 209 *
205 * @return string 210 * @return string
206 */ 211 */
@@ -210,9 +215,10 @@ class Config
210 } 215 }
211 216
212 /** 217 /**
213 * Set rssLimit 218 * Set rssLimit.
219 *
220 * @param string $rssLimit
214 * 221 *
215 * @param string $rssLimit
216 * @return Config 222 * @return Config
217 */ 223 */
218 public function setRssLimit($rssLimit) 224 public function setRssLimit($rssLimit)
@@ -223,7 +229,7 @@ class Config
223 } 229 }
224 230
225 /** 231 /**
226 * Get rssLimit 232 * Get rssLimit.
227 * 233 *
228 * @return string 234 * @return string
229 */ 235 */
diff --git a/src/Wallabag/CoreBundle/Entity/Entry.php b/src/Wallabag/CoreBundle/Entity/Entry.php
index 15af105d..b1998ab6 100644
--- a/src/Wallabag/CoreBundle/Entity/Entry.php
+++ b/src/Wallabag/CoreBundle/Entity/Entry.php
@@ -9,7 +9,7 @@ use Hateoas\Configuration\Annotation as Hateoas;
9use JMS\Serializer\Annotation\XmlRoot; 9use JMS\Serializer\Annotation\XmlRoot;
10 10
11/** 11/**
12 * Entry 12 * Entry.
13 * 13 *
14 * @XmlRoot("entry") 14 * @XmlRoot("entry")
15 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository") 15 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\EntryRepository")
@@ -21,7 +21,7 @@ class Entry
21{ 21{
22 /** @Serializer\XmlAttribute */ 22 /** @Serializer\XmlAttribute */
23 /** 23 /**
24 * @var integer 24 * @var int
25 * 25 *
26 * @ORM\Column(name="id", type="integer") 26 * @ORM\Column(name="id", type="integer")
27 * @ORM\Id 27 * @ORM\Id
@@ -45,14 +45,14 @@ class Entry
45 private $url; 45 private $url;
46 46
47 /** 47 /**
48 * @var boolean 48 * @var bool
49 * 49 *
50 * @ORM\Column(name="is_archived", type="boolean") 50 * @ORM\Column(name="is_archived", type="boolean")
51 */ 51 */
52 private $isArchived = false; 52 private $isArchived = false;
53 53
54 /** 54 /**
55 * @var boolean 55 * @var bool
56 * 56 *
57 * @ORM\Column(name="is_starred", type="boolean") 57 * @ORM\Column(name="is_starred", type="boolean")
58 */ 58 */
@@ -94,7 +94,7 @@ class Entry
94 private $mimetype; 94 private $mimetype;
95 95
96 /** 96 /**
97 * @var integer 97 * @var int
98 * 98 *
99 * @ORM\Column(name="reading_type", type="integer", nullable=true) 99 * @ORM\Column(name="reading_type", type="integer", nullable=true)
100 */ 100 */
@@ -108,7 +108,7 @@ class Entry
108 private $domainName; 108 private $domainName;
109 109
110 /** 110 /**
111 * @var boolean 111 * @var bool
112 * 112 *
113 * @ORM\Column(name="is_public", type="boolean", nullable=true, options={"default" = false}) 113 * @ORM\Column(name="is_public", type="boolean", nullable=true, options={"default" = false})
114 */ 114 */
@@ -135,9 +135,9 @@ class Entry
135 } 135 }
136 136
137 /** 137 /**
138 * Get id 138 * Get id.
139 * 139 *
140 * @return integer 140 * @return int
141 */ 141 */
142 public function getId() 142 public function getId()
143 { 143 {
@@ -145,9 +145,10 @@ class Entry
145 } 145 }
146 146
147 /** 147 /**
148 * Set title 148 * Set title.
149 *
150 * @param string $title
149 * 151 *
150 * @param string $title
151 * @return Entry 152 * @return Entry
152 */ 153 */
153 public function setTitle($title) 154 public function setTitle($title)
@@ -158,7 +159,7 @@ class Entry
158 } 159 }
159 160
160 /** 161 /**
161 * Get title 162 * Get title.
162 * 163 *
163 * @return string 164 * @return string
164 */ 165 */
@@ -168,9 +169,10 @@ class Entry
168 } 169 }
169 170
170 /** 171 /**
171 * Set url 172 * Set url.
173 *
174 * @param string $url
172 * 175 *
173 * @param string $url
174 * @return Entry 176 * @return Entry
175 */ 177 */
176 public function setUrl($url) 178 public function setUrl($url)
@@ -181,7 +183,7 @@ class Entry
181 } 183 }
182 184
183 /** 185 /**
184 * Get url 186 * Get url.
185 * 187 *
186 * @return string 188 * @return string
187 */ 189 */
@@ -191,9 +193,10 @@ class Entry
191 } 193 }
192 194
193 /** 195 /**
194 * Set isArchived 196 * Set isArchived.
197 *
198 * @param string $isArchived
195 * 199 *
196 * @param string $isArchived
197 * @return Entry 200 * @return Entry
198 */ 201 */
199 public function setArchived($isArchived) 202 public function setArchived($isArchived)
@@ -204,7 +207,7 @@ class Entry
204 } 207 }
205 208
206 /** 209 /**
207 * Get isArchived 210 * Get isArchived.
208 * 211 *
209 * @return string 212 * @return string
210 */ 213 */
@@ -221,9 +224,10 @@ class Entry
221 } 224 }
222 225
223 /** 226 /**
224 * Set isStarred 227 * Set isStarred.
228 *
229 * @param string $isStarred
225 * 230 *
226 * @param string $isStarred
227 * @return Entry 231 * @return Entry
228 */ 232 */
229 public function setStarred($isStarred) 233 public function setStarred($isStarred)
@@ -234,7 +238,7 @@ class Entry
234 } 238 }
235 239
236 /** 240 /**
237 * Get isStarred 241 * Get isStarred.
238 * 242 *
239 * @return string 243 * @return string
240 */ 244 */
@@ -251,9 +255,10 @@ class Entry
251 } 255 }
252 256
253 /** 257 /**
254 * Set content 258 * Set content.
259 *
260 * @param string $content
255 * 261 *
256 * @param string $content
257 * @return Entry 262 * @return Entry
258 */ 263 */
259 public function setContent($content) 264 public function setContent($content)
@@ -264,7 +269,7 @@ class Entry
264 } 269 }
265 270
266 /** 271 /**
267 * Get content 272 * Get content.
268 * 273 *
269 * @return string 274 * @return string
270 */ 275 */
@@ -375,7 +380,7 @@ class Entry
375 } 380 }
376 381
377 /** 382 /**
378 * @return boolean 383 * @return bool
379 */ 384 */
380 public function isPublic() 385 public function isPublic()
381 { 386 {
@@ -383,7 +388,7 @@ class Entry
383 } 388 }
384 389
385 /** 390 /**
386 * @param boolean $isPublic 391 * @param bool $isPublic
387 */ 392 */
388 public function setPublic($isPublic) 393 public function setPublic($isPublic)
389 { 394 {
diff --git a/src/Wallabag/CoreBundle/Entity/Tag.php b/src/Wallabag/CoreBundle/Entity/Tag.php
index 9d3c7a32..afe9e1b9 100644
--- a/src/Wallabag/CoreBundle/Entity/Tag.php
+++ b/src/Wallabag/CoreBundle/Entity/Tag.php
@@ -9,7 +9,7 @@ use JMS\Serializer\Annotation\Expose;
9use Doctrine\Common\Collections\ArrayCollection; 9use Doctrine\Common\Collections\ArrayCollection;
10 10
11/** 11/**
12 * Tag 12 * Tag.
13 * 13 *
14 * @XmlRoot("tag") 14 * @XmlRoot("tag")
15 * @ORM\Table 15 * @ORM\Table
@@ -19,7 +19,7 @@ use Doctrine\Common\Collections\ArrayCollection;
19class Tag 19class Tag
20{ 20{
21 /** 21 /**
22 * @var integer 22 * @var int
23 * 23 *
24 * @Expose 24 * @Expose
25 * @ORM\Column(name="id", type="integer") 25 * @ORM\Column(name="id", type="integer")
@@ -52,9 +52,9 @@ class Tag
52 $this->entries = new ArrayCollection(); 52 $this->entries = new ArrayCollection();
53 } 53 }
54 /** 54 /**
55 * Get id 55 * Get id.
56 * 56 *
57 * @return integer 57 * @return int
58 */ 58 */
59 public function getId() 59 public function getId()
60 { 60 {
@@ -62,9 +62,10 @@ class Tag
62 } 62 }
63 63
64 /** 64 /**
65 * Set label 65 * Set label.
66 *
67 * @param string $label
66 * 68 *
67 * @param string $label
68 * @return Tag 69 * @return Tag
69 */ 70 */
70 public function setLabel($label) 71 public function setLabel($label)
@@ -75,7 +76,7 @@ class Tag
75 } 76 }
76 77
77 /** 78 /**
78 * Get label 79 * Get label.
79 * 80 *
80 * @return string 81 * @return string
81 */ 82 */
diff --git a/src/Wallabag/CoreBundle/Entity/User.php b/src/Wallabag/CoreBundle/Entity/User.php
index ff08c8fb..00eb808a 100644
--- a/src/Wallabag/CoreBundle/Entity/User.php
+++ b/src/Wallabag/CoreBundle/Entity/User.php
@@ -12,7 +12,7 @@ use JMS\Serializer\Annotation\ExclusionPolicy;
12use JMS\Serializer\Annotation\Expose; 12use JMS\Serializer\Annotation\Expose;
13 13
14/** 14/**
15 * User 15 * User.
16 * 16 *
17 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\UserRepository") 17 * @ORM\Entity(repositoryClass="Wallabag\CoreBundle\Repository\UserRepository")
18 * @ORM\Table 18 * @ORM\Table
@@ -25,7 +25,7 @@ use JMS\Serializer\Annotation\Expose;
25class User implements AdvancedUserInterface, \Serializable 25class User implements AdvancedUserInterface, \Serializable
26{ 26{
27 /** 27 /**
28 * @var integer 28 * @var int
29 * 29 *
30 * @Expose 30 * @Expose
31 * @ORM\Column(name="id", type="integer") 31 * @ORM\Column(name="id", type="integer")
@@ -142,9 +142,9 @@ class User implements AdvancedUserInterface, \Serializable
142 } 142 }
143 143
144 /** 144 /**
145 * Get id 145 * Get id.
146 * 146 *
147 * @return integer 147 * @return int
148 */ 148 */
149 public function getId() 149 public function getId()
150 { 150 {
@@ -152,9 +152,10 @@ class User implements AdvancedUserInterface, \Serializable
152 } 152 }
153 153
154 /** 154 /**
155 * Set username 155 * Set username.
156 *
157 * @param string $username
156 * 158 *
157 * @param string $username
158 * @return User 159 * @return User
159 */ 160 */
160 public function setUsername($username) 161 public function setUsername($username)
@@ -165,7 +166,7 @@ class User implements AdvancedUserInterface, \Serializable
165 } 166 }
166 167
167 /** 168 /**
168 * Get username 169 * Get username.
169 * 170 *
170 * @return string 171 * @return string
171 */ 172 */
@@ -191,9 +192,10 @@ class User implements AdvancedUserInterface, \Serializable
191 } 192 }
192 193
193 /** 194 /**
194 * Set password 195 * Set password.
196 *
197 * @param string $password
195 * 198 *
196 * @param string $password
197 * @return User 199 * @return User
198 */ 200 */
199 public function setPassword($password) 201 public function setPassword($password)
@@ -208,7 +210,7 @@ class User implements AdvancedUserInterface, \Serializable
208 } 210 }
209 211
210 /** 212 /**
211 * Get password 213 * Get password.
212 * 214 *
213 * @return string 215 * @return string
214 */ 216 */
@@ -218,9 +220,10 @@ class User implements AdvancedUserInterface, \Serializable
218 } 220 }
219 221
220 /** 222 /**
221 * Set name 223 * Set name.
224 *
225 * @param string $name
222 * 226 *
223 * @param string $name
224 * @return User 227 * @return User
225 */ 228 */
226 public function setName($name) 229 public function setName($name)
@@ -231,7 +234,7 @@ class User implements AdvancedUserInterface, \Serializable
231 } 234 }
232 235
233 /** 236 /**
234 * Get name 237 * Get name.
235 * 238 *
236 * @return string 239 * @return string
237 */ 240 */
@@ -241,9 +244,10 @@ class User implements AdvancedUserInterface, \Serializable
241 } 244 }
242 245
243 /** 246 /**
244 * Set email 247 * Set email.
248 *
249 * @param string $email
245 * 250 *
246 * @param string $email
247 * @return User 251 * @return User
248 */ 252 */
249 public function setEmail($email) 253 public function setEmail($email)
@@ -254,7 +258,7 @@ class User implements AdvancedUserInterface, \Serializable
254 } 258 }
255 259
256 /** 260 /**
257 * Get email 261 * Get email.
258 * 262 *
259 * @return string 263 * @return string
260 */ 264 */
@@ -341,8 +345,7 @@ class User implements AdvancedUserInterface, \Serializable
341 public function unserialize($serialized) 345 public function unserialize($serialized)
342 { 346 {
343 list( 347 list(
344 $this->id, 348 $this->id) = unserialize($serialized);
345 ) = unserialize($serialized);
346 } 349 }
347 350
348 public function isEqualTo(UserInterface $user) 351 public function isEqualTo(UserInterface $user)
@@ -370,9 +373,10 @@ class User implements AdvancedUserInterface, \Serializable
370 return $this->isActive; 373 return $this->isActive;
371 } 374 }
372 /** 375 /**
373 * Set config 376 * Set config.
377 *
378 * @param \Wallabag\CoreBundle\Entity\Config $config
374 * 379 *
375 * @param \Wallabag\CoreBundle\Entity\Config $config
376 * @return User 380 * @return User
377 */ 381 */
378 public function setConfig(\Wallabag\CoreBundle\Entity\Config $config = null) 382 public function setConfig(\Wallabag\CoreBundle\Entity\Config $config = null)
@@ -383,7 +387,7 @@ class User implements AdvancedUserInterface, \Serializable
383 } 387 }
384 388
385 /** 389 /**
386 * Get config 390 * Get config.
387 * 391 *
388 * @return \Wallabag\CoreBundle\Entity\Config 392 * @return \Wallabag\CoreBundle\Entity\Config
389 */ 393 */
@@ -393,9 +397,10 @@ class User implements AdvancedUserInterface, \Serializable
393 } 397 }
394 398
395 /** 399 /**
396 * Set confirmationToken 400 * Set confirmationToken.
401 *
402 * @param string $confirmationToken
397 * 403 *
398 * @param string $confirmationToken
399 * @return User 404 * @return User
400 */ 405 */
401 public function setConfirmationToken($confirmationToken) 406 public function setConfirmationToken($confirmationToken)
@@ -406,7 +411,7 @@ class User implements AdvancedUserInterface, \Serializable
406 } 411 }
407 412
408 /** 413 /**
409 * Get confirmationToken 414 * Get confirmationToken.
410 * 415 *
411 * @return string 416 * @return string
412 */ 417 */
@@ -416,9 +421,10 @@ class User implements AdvancedUserInterface, \Serializable
416 } 421 }
417 422
418 /** 423 /**
419 * Set passwordRequestedAt 424 * Set passwordRequestedAt.
425 *
426 * @param \DateTime $passwordRequestedAt
420 * 427 *
421 * @param \DateTime $passwordRequestedAt
422 * @return User 428 * @return User
423 */ 429 */
424 public function setPasswordRequestedAt($passwordRequestedAt) 430 public function setPasswordRequestedAt($passwordRequestedAt)
@@ -429,7 +435,7 @@ class User implements AdvancedUserInterface, \Serializable
429 } 435 }
430 436
431 /** 437 /**
432 * Get passwordRequestedAt 438 * Get passwordRequestedAt.
433 * 439 *
434 * @return \DateTime 440 * @return \DateTime
435 */ 441 */
diff --git a/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php b/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php
index e141789f..b4224e3d 100644
--- a/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/ChangePasswordType.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Wallabag\CoreBundle\Form\Type; 3namespace Wallabag\CoreBundle\Form\Type;
3 4
4use Symfony\Component\Form\AbstractType; 5use Symfony\Component\Form\AbstractType;
diff --git a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php
index 0fcf020a..d5890971 100644
--- a/src/Wallabag/CoreBundle/Form/Type/ConfigType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/ConfigType.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Wallabag\CoreBundle\Form\Type; 3namespace Wallabag\CoreBundle\Form\Type;
3 4
4use Symfony\Component\Form\AbstractType; 5use Symfony\Component\Form\AbstractType;
diff --git a/src/Wallabag/CoreBundle/Form/Type/EntryType.php b/src/Wallabag/CoreBundle/Form/Type/EntryType.php
index 9a64def5..0532bf10 100644
--- a/src/Wallabag/CoreBundle/Form/Type/EntryType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/EntryType.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Wallabag\CoreBundle\Form\Type; 3namespace Wallabag\CoreBundle\Form\Type;
3 4
4use Symfony\Component\Form\AbstractType; 5use Symfony\Component\Form\AbstractType;
diff --git a/src/Wallabag/CoreBundle/Form/Type/ForgotPasswordType.php b/src/Wallabag/CoreBundle/Form/Type/ForgotPasswordType.php
index 4cc16a50..9e95eb47 100644
--- a/src/Wallabag/CoreBundle/Form/Type/ForgotPasswordType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/ForgotPasswordType.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Wallabag\CoreBundle\Form\Type; 3namespace Wallabag\CoreBundle\Form\Type;
3 4
4use Symfony\Component\Form\AbstractType; 5use Symfony\Component\Form\AbstractType;
diff --git a/src/Wallabag/CoreBundle/Form/Type/NewUserType.php b/src/Wallabag/CoreBundle/Form/Type/NewUserType.php
index b7ebe8c2..a12fff2b 100644
--- a/src/Wallabag/CoreBundle/Form/Type/NewUserType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/NewUserType.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Wallabag\CoreBundle\Form\Type; 3namespace Wallabag\CoreBundle\Form\Type;
3 4
4use Symfony\Component\Form\AbstractType; 5use Symfony\Component\Form\AbstractType;
diff --git a/src/Wallabag/CoreBundle/Form/Type/ResetPasswordType.php b/src/Wallabag/CoreBundle/Form/Type/ResetPasswordType.php
index 50ae800b..a5d683c4 100644
--- a/src/Wallabag/CoreBundle/Form/Type/ResetPasswordType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/ResetPasswordType.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Wallabag\CoreBundle\Form\Type; 3namespace Wallabag\CoreBundle\Form\Type;
3 4
4use Symfony\Component\Form\AbstractType; 5use Symfony\Component\Form\AbstractType;
diff --git a/src/Wallabag/CoreBundle/Form/Type/RssType.php b/src/Wallabag/CoreBundle/Form/Type/RssType.php
index a1ab990f..e14e84e1 100644
--- a/src/Wallabag/CoreBundle/Form/Type/RssType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/RssType.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Wallabag\CoreBundle\Form\Type; 3namespace Wallabag\CoreBundle\Form\Type;
3 4
4use Symfony\Component\Form\AbstractType; 5use Symfony\Component\Form\AbstractType;
diff --git a/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php b/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php
index 3d6df510..f0367d14 100644
--- a/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/UserInformationType.php
@@ -1,4 +1,5 @@
1<?php 1<?php
2
2namespace Wallabag\CoreBundle\Form\Type; 3namespace Wallabag\CoreBundle\Form\Type;
3 4
4use Symfony\Component\Form\AbstractType; 5use Symfony\Component\Form\AbstractType;
diff --git a/src/Wallabag/CoreBundle/Helper/Tools.php b/src/Wallabag/CoreBundle/Helper/Tools.php
index 0fd5f259..be29ab99 100755
--- a/src/Wallabag/CoreBundle/Helper/Tools.php
+++ b/src/Wallabag/CoreBundle/Helper/Tools.php
@@ -5,15 +5,16 @@ namespace Wallabag\CoreBundle\Helper;
5final class Tools 5final class Tools
6{ 6{
7 /** 7 /**
8 * Download a file (typically, for downloading pictures on web server) 8 * Download a file (typically, for downloading pictures on web server).
9 * 9 *
10 * @param $url 10 * @param $url
11 *
11 * @return bool|mixed|string 12 * @return bool|mixed|string
12 */ 13 */
13 public static function getFile($url) 14 public static function getFile($url)
14 { 15 {
15 $timeout = 15; 16 $timeout = 15;
16 $useragent = "Mozilla/5.0 (Windows NT 5.1; rv:18.0) Gecko/20100101 Firefox/18.0"; 17 $useragent = 'Mozilla/5.0 (Windows NT 5.1; rv:18.0) Gecko/20100101 Firefox/18.0';
17 18
18 if (in_array('curl', get_loaded_extensions())) { 19 if (in_array('curl', get_loaded_extensions())) {
19 # Fetch feed from URL 20 # Fetch feed from URL
@@ -32,7 +33,7 @@ final class Tools
32 33
33 # FeedBurner requires a proper USER-AGENT... 34 # FeedBurner requires a proper USER-AGENT...
34 curl_setopt($curl, CURL_HTTP_VERSION_1_1, true); 35 curl_setopt($curl, CURL_HTTP_VERSION_1_1, true);
35 curl_setopt($curl, CURLOPT_ENCODING, "gzip, deflate"); 36 curl_setopt($curl, CURLOPT_ENCODING, 'gzip, deflate');
36 curl_setopt($curl, CURLOPT_USERAGENT, $useragent); 37 curl_setopt($curl, CURLOPT_USERAGENT, $useragent);
37 38
38 $data = curl_exec($curl); 39 $data = curl_exec($curl);
@@ -45,7 +46,7 @@ final class Tools
45 array( 46 array(
46 'http' => array( 47 'http' => array(
47 'timeout' => $timeout, 48 'timeout' => $timeout,
48 'header' => "User-Agent: ".$useragent, 49 'header' => 'User-Agent: '.$useragent,
49 'follow_location' => true, 50 'follow_location' => true,
50 ), 51 ),
51 'ssl' => array( 52 'ssl' => array(
@@ -91,9 +92,10 @@ final class Tools
91 } 92 }
92 93
93 /** 94 /**
94 * Encode a URL by using a salt 95 * Encode a URL by using a salt.
95 * 96 *
96 * @param $string 97 * @param $string
98 *
97 * @return string 99 * @return string
98 */ 100 */
99 public static function encodeString($string) 101 public static function encodeString($string)
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
index a8c138a9..1335e808 100644
--- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
@@ -10,7 +10,7 @@ use Pagerfanta\Pagerfanta;
10class EntryRepository extends EntityRepository 10class EntryRepository extends EntityRepository
11{ 11{
12 /** 12 /**
13 * Retrieves unread entries for a user 13 * Retrieves unread entries for a user.
14 * 14 *
15 * @param int $userId 15 * @param int $userId
16 * @param int $firstResult 16 * @param int $firstResult
@@ -35,7 +35,7 @@ class EntryRepository extends EntityRepository
35 } 35 }
36 36
37 /** 37 /**
38 * Retrieves read entries for a user 38 * Retrieves read entries for a user.
39 * 39 *
40 * @param int $userId 40 * @param int $userId
41 * @param int $firstResult 41 * @param int $firstResult
@@ -61,7 +61,7 @@ class EntryRepository extends EntityRepository
61 } 61 }
62 62
63 /** 63 /**
64 * Retrieves starred entries for a user 64 * Retrieves starred entries for a user.
65 * 65 *
66 * @param int $userId 66 * @param int $userId
67 * @param int $firstResult 67 * @param int $firstResult
@@ -87,7 +87,7 @@ class EntryRepository extends EntityRepository
87 } 87 }
88 88
89 /** 89 /**
90 * Find Entries 90 * Find Entries.
91 * 91 *
92 * @param int $userId 92 * @param int $userId
93 * @param bool $isArchived 93 * @param bool $isArchived
diff --git a/src/Wallabag/CoreBundle/Repository/UserRepository.php b/src/Wallabag/CoreBundle/Repository/UserRepository.php
index aab3dedc..968d0b49 100644
--- a/src/Wallabag/CoreBundle/Repository/UserRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/UserRepository.php
@@ -7,7 +7,7 @@ use Doctrine\ORM\EntityRepository;
7class UserRepository extends EntityRepository 7class UserRepository extends EntityRepository
8{ 8{
9 /** 9 /**
10 * Find a user by its username and rss roken 10 * Find a user by its username and rss roken.
11 * 11 *
12 * @param string $username 12 * @param string $username
13 * @param string $rssToken 13 * @param string $rssToken
diff --git a/src/Wallabag/CoreBundle/Resources/config/routing_rest.yml b/src/Wallabag/CoreBundle/Resources/config/routing_rest.yml
deleted file mode 100644
index d3af6b72..00000000
--- a/src/Wallabag/CoreBundle/Resources/config/routing_rest.yml
+++ /dev/null
@@ -1,4 +0,0 @@
1entries:
2 type: rest
3 resource: "WallabagCoreBundle:WallabagRest"
4 name_prefix: api_
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index cea6c0df..d8bd8d52 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -4,18 +4,6 @@ services:
4 tags: 4 tags:
5 - { name: twig.extension } 5 - { name: twig.extension }
6 6
7 wsse.security.authentication.provider:
8 class: Wallabag\CoreBundle\Security\Authentication\Provider\WsseProvider
9 public: false
10 arguments: ['', '%kernel.cache_dir%/security/nonces']
11
12 wsse.security.authentication.listener:
13 class: Wallabag\CoreBundle\Security\Firewall\WsseListener
14 public: false
15 tags:
16 - { name: monolog.logger, channel: wsse }
17 arguments: ['@security.context', '@security.authentication.manager', '@logger']
18
19 wallabag_core.helper.detect_active_theme: 7 wallabag_core.helper.detect_active_theme:
20 class: Wallabag\CoreBundle\Helper\DetectActiveTheme 8 class: Wallabag\CoreBundle\Helper\DetectActiveTheme
21 arguments: 9 arguments:
diff --git a/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php b/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php
index fcfe418b..e7c81fc0 100644
--- a/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php
+++ b/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php
@@ -7,8 +7,7 @@ use Symfony\Component\Security\Core\Exception\BadCredentialsException;
7 7
8/** 8/**
9 * This override just add en extra variable (username) to be able to salt the password 9 * This override just add en extra variable (username) to be able to salt the password
10 * the way Wallabag v1 does. It will avoid to break compatibility with Wallabag v1 10 * the way Wallabag v1 does. It will avoid to break compatibility with Wallabag v1.
11 *
12 */ 11 */
13class WallabagPasswordEncoder extends BasePasswordEncoder 12class WallabagPasswordEncoder extends BasePasswordEncoder
14{ 13{
diff --git a/src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php b/src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php
index 1c7c5fae..cf3cb051 100644
--- a/src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php
+++ b/src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php
@@ -45,7 +45,7 @@ class WallabagAuthenticationProvider extends UserAuthenticationProvider
45 throw new BadCredentialsException('The credentials were changed from another session.'); 45 throw new BadCredentialsException('The credentials were changed from another session.');
46 } 46 }
47 } else { 47 } else {
48 if ("" === ($presentedPassword = $token->getCredentials())) { 48 if ('' === ($presentedPassword = $token->getCredentials())) {
49 throw new BadCredentialsException('The presented password cannot be empty.'); 49 throw new BadCredentialsException('The presented password cannot be empty.');
50 } 50 }
51 51
diff --git a/src/Wallabag/CoreBundle/Service/Extractor.php b/src/Wallabag/CoreBundle/Service/Extractor.php
index e4ec96f6..6d43a1da 100644
--- a/src/Wallabag/CoreBundle/Service/Extractor.php
+++ b/src/Wallabag/CoreBundle/Service/Extractor.php
@@ -9,7 +9,7 @@ final class Extractor
9{ 9{
10 public static function extract($url) 10 public static function extract($url)
11 { 11 {
12 $pageContent = Extractor::getPageContent(new Url(base64_encode($url))); 12 $pageContent = self::getPageContent(new Url(base64_encode($url)));
13 $title = $pageContent['rss']['channel']['item']['title'] ?: 'Untitled'; 13 $title = $pageContent['rss']['channel']['item']['title'] ?: 'Untitled';
14 $body = $pageContent['rss']['channel']['item']['description']; 14 $body = $pageContent['rss']['channel']['item']['description'];
15 15
@@ -21,9 +21,10 @@ final class Extractor
21 } 21 }
22 22
23 /** 23 /**
24 * Get the content for a given URL (by a call to FullTextFeed) 24 * Get the content for a given URL (by a call to FullTextFeed).
25 *
26 * @param Url $url
25 * 27 *
26 * @param Url $url
27 * @return mixed 28 * @return mixed
28 */ 29 */
29 public static function getPageContent(Url $url) 30 public static function getPageContent(Url $url)
@@ -49,12 +50,12 @@ final class Extractor
49 $scope = function () { 50 $scope = function () {
50 extract(func_get_arg(1)); 51 extract(func_get_arg(1));
51 $_GET = $_REQUEST = array( 52 $_GET = $_REQUEST = array(
52 "url" => $url->getUrl(), 53 'url' => $url->getUrl(),
53 "max" => 5, 54 'max' => 5,
54 "links" => "preserve", 55 'links' => 'preserve',
55 "exc" => "", 56 'exc' => '',
56 "format" => "json", 57 'format' => 'json',
57 "submit" => "Create Feed", 58 'submit' => 'Create Feed',
58 ); 59 );
59 ob_start(); 60 ob_start();
60 require func_get_arg(0); 61 require func_get_arg(0);
@@ -67,11 +68,11 @@ final class Extractor
67 // Silence $scope function to avoid 68 // Silence $scope function to avoid
68 // issues with FTRSS when error_reporting is to high 69 // issues with FTRSS when error_reporting is to high
69 // FTRSS generates PHP warnings which break output 70 // FTRSS generates PHP warnings which break output
70 $json = @$scope(__DIR__."/../../../../vendor/wallabag/Fivefilters_Libraries/makefulltextfeed.php", array("url" => $url)); 71 $json = @$scope(__DIR__.'/../../../../vendor/wallabag/Fivefilters_Libraries/makefulltextfeed.php', array('url' => $url));
71 72
72 // Clearing and restoring context 73 // Clearing and restoring context
73 foreach ($GLOBALS as $key => $value) { 74 foreach ($GLOBALS as $key => $value) {
74 if ($key != "GLOBALS" && $key != "_SESSION") { 75 if ($key != 'GLOBALS' && $key != '_SESSION') {
75 unset($GLOBALS[$key]); 76 unset($GLOBALS[$key]);
76 } 77 }
77 } 78 }
diff --git a/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php b/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php
index f689b532..7a819953 100644
--- a/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php
+++ b/src/Wallabag/CoreBundle/Tests/Command/InstallCommandTest.php
@@ -2,7 +2,7 @@
2 2
3namespace Wallabag\CoreBundle\Tests\Command; 3namespace Wallabag\CoreBundle\Tests\Command;
4 4
5use Wallabag\CoreBundle\Tests\WallabagTestCase; 5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6use Wallabag\CoreBundle\Command\InstallCommand; 6use Wallabag\CoreBundle\Command\InstallCommand;
7use Wallabag\CoreBundle\Tests\Mock\InstallCommandMock; 7use Wallabag\CoreBundle\Tests\Mock\InstallCommandMock;
8use Symfony\Bundle\FrameworkBundle\Console\Application; 8use Symfony\Bundle\FrameworkBundle\Console\Application;
@@ -12,7 +12,7 @@ use Symfony\Component\Console\Output\NullOutput;
12use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand; 12use Doctrine\Bundle\DoctrineBundle\Command\DropDatabaseDoctrineCommand;
13use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand; 13use Doctrine\Bundle\DoctrineBundle\Command\CreateDatabaseDoctrineCommand;
14 14
15class InstallCommandTest extends WallabagTestCase 15class InstallCommandTest extends WallabagCoreTestCase
16{ 16{
17 public static function tearDownAfterClass() 17 public static function tearDownAfterClass()
18 { 18 {
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php
index 5030bcbd..a0145780 100644
--- a/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php
+++ b/src/Wallabag/CoreBundle/Tests/Controller/ConfigControllerTest.php
@@ -2,9 +2,9 @@
2 2
3namespace Wallabag\CoreBundle\Tests\Controller; 3namespace Wallabag\CoreBundle\Tests\Controller;
4 4
5use Wallabag\CoreBundle\Tests\WallabagTestCase; 5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6 6
7class ConfigControllerTest extends WallabagTestCase 7class ConfigControllerTest extends WallabagCoreTestCase
8{ 8{
9 public function testLogin() 9 public function testLogin()
10 { 10 {
@@ -397,7 +397,7 @@ class ConfigControllerTest extends WallabagTestCase
397 ); 397 );
398 398
399 $this->assertEquals(200, $client->getResponse()->getStatusCode()); 399 $this->assertEquals(200, $client->getResponse()->getStatusCode());
400 $content = json_decode($client->getResponse()->getContent(), true);; 400 $content = json_decode($client->getResponse()->getContent(), true);
401 $this->assertArrayHasKey('token', $content); 401 $this->assertArrayHasKey('token', $content);
402 } 402 }
403 403
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php
index 1a0d586c..8a7fdda2 100644
--- a/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php
+++ b/src/Wallabag/CoreBundle/Tests/Controller/EntryControllerTest.php
@@ -2,10 +2,10 @@
2 2
3namespace Wallabag\CoreBundle\Tests\Controller; 3namespace Wallabag\CoreBundle\Tests\Controller;
4 4
5use Wallabag\CoreBundle\Tests\WallabagTestCase; 5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6use Doctrine\ORM\AbstractQuery; 6use Doctrine\ORM\AbstractQuery;
7 7
8class EntryControllerTest extends WallabagTestCase 8class EntryControllerTest extends WallabagCoreTestCase
9{ 9{
10 public function testLogin() 10 public function testLogin()
11 { 11 {
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php
index 8f627b4b..b7c162a7 100644
--- a/src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php
+++ b/src/Wallabag/CoreBundle/Tests/Controller/RssControllerTest.php
@@ -2,9 +2,9 @@
2 2
3namespace Wallabag\CoreBundle\Tests\Controller; 3namespace Wallabag\CoreBundle\Tests\Controller;
4 4
5use Wallabag\CoreBundle\Tests\WallabagTestCase; 5use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
6 6
7class RssControllerTest extends WallabagTestCase 7class RssControllerTest extends WallabagCoreTestCase
8{ 8{
9 public function validateDom($xml, $nb = null) 9 public function validateDom($xml, $nb = null)
10 { 10 {
@@ -36,13 +36,13 @@ class RssControllerTest extends WallabagTestCase
36 { 36 {
37 return array( 37 return array(
38 array( 38 array(
39 '/admin/YZIOAUZIAO/unread.xml' 39 '/admin/YZIOAUZIAO/unread.xml',
40 ), 40 ),
41 array( 41 array(
42 '/wallace/YZIOAUZIAO/starred.xml' 42 '/wallace/YZIOAUZIAO/starred.xml',
43 ), 43 ),
44 array( 44 array(
45 '/wallace/YZIOAUZIAO/archives.xml' 45 '/wallace/YZIOAUZIAO/archives.xml',
46 ), 46 ),
47 ); 47 );
48 } 48 }
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/SecurityControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/SecurityControllerTest.php
index 1dd05f89..e560ffdd 100644
--- a/src/Wallabag/CoreBundle/Tests/Controller/SecurityControllerTest.php
+++ b/src/Wallabag/CoreBundle/Tests/Controller/SecurityControllerTest.php
@@ -2,11 +2,11 @@
2 2
3namespace Wallabag\CoreBundle\Tests\Controller; 3namespace Wallabag\CoreBundle\Tests\Controller;
4 4
5use Wallabag\CoreBundle\Tests\WallabagTestCase;
6use Symfony\Component\Filesystem\Filesystem; 5use Symfony\Component\Filesystem\Filesystem;
7use Symfony\Component\Finder\Finder; 6use Symfony\Component\Finder\Finder;
7use Wallabag\CoreBundle\Tests\WallabagCoreTestCase;
8 8
9class SecurityControllerTest extends WallabagTestCase 9class SecurityControllerTest extends WallabagCoreTestCase
10{ 10{
11 public function testLogin() 11 public function testLogin()
12 { 12 {
diff --git a/src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php b/src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php
deleted file mode 100644
index c9907065..00000000
--- a/src/Wallabag/CoreBundle/Tests/Controller/WallabagRestControllerTest.php
+++ /dev/null
@@ -1,214 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Tests\Controller;
4
5use Wallabag\CoreBundle\Tests\WallabagTestCase;
6
7class WallabagRestControllerTest extends WallabagTestCase
8{
9 /**
10 * Generate HTTP headers for authenticate user on API
11 *
12 * @param $username
13 * @param $password
14 * @param $salt
15 *
16 * @return array
17 */
18 private function generateHeaders($username, $password, $salt)
19 {
20 $encryptedPassword = sha1($password.$username.$salt);
21 $nonce = substr(md5(uniqid('nonce_', true)), 0, 16);
22
23 $now = new \DateTime('now', new \DateTimeZone('UTC'));
24 $created = (string) $now->format('Y-m-d\TH:i:s\Z');
25 $digest = base64_encode(sha1(base64_decode($nonce).$created.$encryptedPassword, true));
26
27 return array(
28 'HTTP_AUTHORIZATION' => 'Authorization profile="UsernameToken"',
29 'HTTP_x-wsse' => 'X-WSSE: UsernameToken Username="'.$username.'", PasswordDigest="'.$digest.'", Nonce="'.$nonce.'", Created="'.$created.'"',
30 );
31 }
32
33 public function testGetSalt()
34 {
35 $client = $this->createClient();
36 $client->request('GET', '/api/salts/admin.json');
37 $this->assertEquals(200, $client->getResponse()->getStatusCode());
38 $this->assertNotEmpty(json_decode($client->getResponse()->getContent()));
39
40 $client->request('GET', '/api/salts/notfound.json');
41 $this->assertEquals(404, $client->getResponse()->getStatusCode());
42 }
43
44 public function testWithBadHeaders()
45 {
46 $client = $this->createClient();
47
48 $entry = $client->getContainer()
49 ->get('doctrine.orm.entity_manager')
50 ->getRepository('WallabagCoreBundle:Entry')
51 ->findOneByIsArchived(false);
52
53 if (!$entry) {
54 $this->markTestSkipped('No content found in db.');
55 }
56
57 $badHeaders = array(
58 'HTTP_AUTHORIZATION' => 'Authorization profile="UsernameToken"',
59 'HTTP_x-wsse' => 'X-WSSE: UsernameToken Username="admin", PasswordDigest="Wr0ngDig3st", Nonce="n0Nc3", Created="2015-01-01T13:37:00Z"',
60 );
61
62 $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $badHeaders);
63 $this->assertEquals(403, $client->getResponse()->getStatusCode());
64 }
65
66 public function testGetOneEntry()
67 {
68 $client = $this->createClient();
69 $client->request('GET', '/api/salts/admin.json');
70 $salt = json_decode($client->getResponse()->getContent());
71
72 $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
73
74 $entry = $client->getContainer()
75 ->get('doctrine.orm.entity_manager')
76 ->getRepository('WallabagCoreBundle:Entry')
77 ->findOneByIsArchived(false);
78
79 if (!$entry) {
80 $this->markTestSkipped('No content found in db.');
81 }
82
83 $client->request('GET', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
84 $this->assertContains($entry->getTitle(), $client->getResponse()->getContent());
85
86 $this->assertTrue(
87 $client->getResponse()->headers->contains(
88 'Content-Type',
89 'application/json'
90 )
91 );
92 }
93
94 public function testGetEntries()
95 {
96 $client = $this->createClient();
97 $client->request('GET', '/api/salts/admin.json');
98 $salt = json_decode($client->getResponse()->getContent());
99
100 $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
101
102 $client->request('GET', '/api/entries', array(), array(), $headers);
103
104 $this->assertEquals(200, $client->getResponse()->getStatusCode());
105
106 $this->assertGreaterThanOrEqual(1, count(json_decode($client->getResponse()->getContent())));
107
108 $this->assertContains('Google', $client->getResponse()->getContent());
109
110 $this->assertTrue(
111 $client->getResponse()->headers->contains(
112 'Content-Type',
113 'application/json'
114 )
115 );
116 }
117
118 public function testDeleteEntry()
119 {
120 $client = $this->createClient();
121 $client->request('GET', '/api/salts/admin.json');
122 $salt = json_decode($client->getResponse()->getContent());
123
124 $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
125
126 $entry = $client->getContainer()
127 ->get('doctrine.orm.entity_manager')
128 ->getRepository('WallabagCoreBundle:Entry')
129 ->findOneByUser(1);
130
131 if (!$entry) {
132 $this->markTestSkipped('No content found in db.');
133 }
134
135 $client->request('DELETE', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
136
137 $this->assertEquals(200, $client->getResponse()->getStatusCode());
138
139 // We'll try to delete this entry again
140 $client->request('GET', '/api/salts/admin.json');
141 $salt = json_decode($client->getResponse()->getContent());
142
143 $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
144
145 $client->request('DELETE', '/api/entries/'.$entry->getId().'.json', array(), array(), $headers);
146
147 $this->assertEquals(404, $client->getResponse()->getStatusCode());
148 }
149
150 public function testGetTagsEntry()
151 {
152 $client = $this->createClient();
153 $client->request('GET', '/api/salts/admin.json');
154 $salt = json_decode($client->getResponse()->getContent());
155 $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
156
157 $entry = $client->getContainer()
158 ->get('doctrine.orm.entity_manager')
159 ->getRepository('WallabagCoreBundle:Entry')
160 ->findOneWithTags(1);
161
162 $entry = $entry[0];
163
164 if (!$entry) {
165 $this->markTestSkipped('No content found in db.');
166 }
167
168 $tags = array();
169 foreach ($entry->getTags() as $tag) {
170 $tags[] = array('id' => $tag->getId(), 'label' => $tag->getLabel());
171 }
172
173 $client->request('GET', '/api/entries/'.$entry->getId().'/tags', array(), array(), $headers);
174
175 $this->assertEquals(json_encode($tags, JSON_HEX_QUOT), $client->getResponse()->getContent());
176 }
177
178 public function testPostTagsOnEntry()
179 {
180 $client = $this->createClient();
181 $client->request('GET', '/api/salts/admin.json');
182 $salt = json_decode($client->getResponse()->getContent());
183 $headers = $this->generateHeaders('admin', 'mypassword', $salt[0]);
184
185 $entry = $client->getContainer()
186 ->get('doctrine.orm.entity_manager')
187 ->getRepository('WallabagCoreBundle:Entry')
188 ->findOneByUser(1);
189
190 if (!$entry) {
191 $this->markTestSkipped('No content found in db.');
192 }
193
194 $newTags = 'tag1,tag2,tag3';
195
196 $client->request('POST', '/api/entries/'.$entry->getId().'/tags', array('tags' => $newTags), array(), $headers);
197
198 $this->assertEquals(200, $client->getResponse()->getStatusCode());
199
200 $entryDB = $client->getContainer()
201 ->get('doctrine.orm.entity_manager')
202 ->getRepository('WallabagCoreBundle:Entry')
203 ->find($entry->getId());
204
205 $tagsInDB = array();
206 foreach ($entryDB->getTags()->toArray() as $tag) {
207 $tagsInDB[$tag->getId()] = $tag->getLabel();
208 }
209
210 foreach (explode(',', $newTags) as $tag) {
211 $this->assertContains($tag, $tagsInDB);
212 }
213 }
214}
diff --git a/src/Wallabag/CoreBundle/Tests/WallabagTestCase.php b/src/Wallabag/CoreBundle/Tests/WallabagCoreTestCase.php
index 22016d8e..e5096528 100644
--- a/src/Wallabag/CoreBundle/Tests/WallabagTestCase.php
+++ b/src/Wallabag/CoreBundle/Tests/WallabagCoreTestCase.php
@@ -4,7 +4,7 @@ namespace Wallabag\CoreBundle\Tests;
4 4
5use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; 5use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
6 6
7abstract class WallabagTestCase extends WebTestCase 7abstract class WallabagCoreTestCase extends WebTestCase
8{ 8{
9 private $client = null; 9 private $client = null;
10 10
diff --git a/src/Wallabag/CoreBundle/Tools/Utils.php b/src/Wallabag/CoreBundle/Tools/Utils.php
index de97c796..7e2968e7 100644
--- a/src/Wallabag/CoreBundle/Tools/Utils.php
+++ b/src/Wallabag/CoreBundle/Tools/Utils.php
@@ -5,7 +5,7 @@ namespace Wallabag\CoreBundle\Tools;
5class Utils 5class Utils
6{ 6{
7 /** 7 /**
8 * Generate a token used for RSS 8 * Generate a token used for RSS.
9 * 9 *
10 * @return string 10 * @return string
11 */ 11 */
@@ -22,6 +22,7 @@ class Utils
22 $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20); 22 $token = substr(base64_encode(uniqid(mt_rand(), true)), 0, 20);
23 } 23 }
24 24
25 return str_replace('+', '', $token); 25 // remove character which can broken the url
26 return str_replace(array('+', '/'), '', $token);
26 } 27 }
27} 28}
diff --git a/src/Wallabag/CoreBundle/Twig/Extension/WallabagExtension.php b/src/Wallabag/CoreBundle/Twig/Extension/WallabagExtension.php
index 92406865..18388948 100644
--- a/src/Wallabag/CoreBundle/Twig/Extension/WallabagExtension.php
+++ b/src/Wallabag/CoreBundle/Twig/Extension/WallabagExtension.php
@@ -13,9 +13,10 @@ class WallabagExtension extends \Twig_Extension
13 } 13 }
14 14
15 /** 15 /**
16 * Returns the domain name for a URL 16 * Returns the domain name for a URL.
17 * 17 *
18 * @param $url 18 * @param $url
19 *
19 * @return string 20 * @return string
20 */ 21 */
21 public static function getDomainName($url) 22 public static function getDomainName($url)
@@ -24,9 +25,10 @@ class WallabagExtension extends \Twig_Extension
24 } 25 }
25 26
26 /** 27 /**
27 * For a given text, we calculate reading time for an article 28 * For a given text, we calculate reading time for an article.
28 * 29 *
29 * @param $text 30 * @param $text
31 *
30 * @return float 32 * @return float
31 */ 33 */
32 public static function getReadingTime($text) 34 public static function getReadingTime($text)
diff --git a/src/Wallabag/CoreBundle/WallabagCoreBundle.php b/src/Wallabag/CoreBundle/WallabagCoreBundle.php
index 1deab03a..f5899e39 100644
--- a/src/Wallabag/CoreBundle/WallabagCoreBundle.php
+++ b/src/Wallabag/CoreBundle/WallabagCoreBundle.php
@@ -3,16 +3,7 @@
3namespace Wallabag\CoreBundle; 3namespace Wallabag\CoreBundle;
4 4
5use Symfony\Component\HttpKernel\Bundle\Bundle; 5use Symfony\Component\HttpKernel\Bundle\Bundle;
6use Wallabag\CoreBundle\DependencyInjection\Security\Factory\WsseFactory;
7use Symfony\Component\DependencyInjection\ContainerBuilder;
8 6
9class WallabagCoreBundle extends Bundle 7class WallabagCoreBundle extends Bundle
10{ 8{
11 public function build(ContainerBuilder $container)
12 {
13 parent::build($container);
14
15 $extension = $container->getExtension('security');
16 $extension->addSecurityListenerFactory(new WsseFactory());
17 }
18} 9}