]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #1069 from wallabag/v2-fix-return-entries
authorJeremy <j0k3r@users.noreply.github.com>
Tue, 10 Feb 2015 13:51:32 +0000 (14:51 +0100)
committerJeremy <j0k3r@users.noreply.github.com>
Tue, 10 Feb 2015 13:51:32 +0000 (14:51 +0100)
GET /api/entries returns object, no more array

app/config/config_prod.yml
app/config/security.yml
src/Wallabag/CoreBundle/Controller/EntryController.php
src/Wallabag/CoreBundle/Controller/WallabagRestController.php
src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
src/Wallabag/CoreBundle/Repository/EntryRepository.php
src/Wallabag/CoreBundle/Resources/config/services.xml [deleted file]
src/Wallabag/CoreBundle/Resources/config/services.yml [new file with mode: 0644]
src/Wallabag/CoreBundle/Security/Authentication/Provider/WsseProvider.php
src/Wallabag/CoreBundle/Security/Firewall/WsseListener.php
src/Wallabag/CoreBundle/Tests/WallabagTestCase.php

index 342837a03137f7f2d10763f5ce9003b8d9154108..c45f0fa664fc354cfef929a6567f87af5f370bfa 100644 (file)
@@ -17,6 +17,11 @@ monolog:
             type:         fingers_crossed
             action_level: error
             handler:      nested
+        wsse:
+            type: stream
+            path: %kernel.logs_dir%/%kernel.environment%.wsse.log
+            level: error
+            channels: [wsse]
         nested:
             type:  stream
             path:  "%kernel.logs_dir%/%kernel.environment%.log"
index e161c3b53b911f70f77443f51c30609fa52263ff..e06c89672aa7712552ece39759c35ec2034aa5ad 100644 (file)
@@ -16,9 +16,11 @@ security:
     # the main part of the security, where you can set up firewalls
     # for specific sections of your app
     firewalls:
-        #wsse_secured:
-        #    pattern:   /api/.*
-        #    wsse:      true
+        wsse_secured:
+            pattern:      /api/.*
+            wsse:         true
+            stateless:    true
+            anonymous:    true
         login_firewall:
             pattern:    ^/login$
             anonymous:  ~
@@ -54,6 +56,7 @@ security:
                 target: /
 
     access_control:
+        - { path: ^/api/salt, roles: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/api/doc, roles: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/, roles: ROLE_USER }
index e0697ca3ef3852af631eef32eb91813b8b7acdab..5378486ae458d5a68208368ba503db89b0c4d099 100644 (file)
@@ -6,7 +6,6 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 use Symfony\Component\HttpFoundation\Request;
 use Wallabag\CoreBundle\Entity\Entry;
-use Wallabag\CoreBundle\Repository;
 use Wallabag\CoreBundle\Service\Extractor;
 use Wallabag\CoreBundle\Helper\Url;
 
index 4784cb012992d804b4b3573018d74d5791ae94ef..27d11da5ec158c931f614186d51777a75f73fa3b 100644 (file)
@@ -12,6 +12,29 @@ use Wallabag\CoreBundle\Service\Extractor;
 
 class WallabagRestController extends Controller
 {
+    /**
+     * Retrieve salt for a giver user.
+     *
+     * @ApiDoc(
+     *       parameters={
+     *          {"name"="username", "dataType"="string", "required"=true, "description"="username"}
+     *       }
+     * )
+     * @return string
+     */
+    public function getSaltAction($username)
+    {
+        $user = $this
+            ->getDoctrine()
+            ->getRepository('WallabagCoreBundle:User')
+            ->findOneByUsername($username);
+
+        if (is_null($user)) {
+            throw $this->createNotFoundException();
+        }
+
+        return $user->getSalt();
+    }
     /**
      * Retrieve all entries. It could be filtered by many options.
      *
@@ -43,7 +66,7 @@ class WallabagRestController extends Controller
         $entries = $this
             ->getDoctrine()
             ->getRepository('WallabagCoreBundle:Entry')
-            ->findEntries(1, $isArchived, $isStarred, $isDeleted, $sort, $order);
+            ->findEntries($this->getUser()->getId(), $isArchived, $isStarred, $isDeleted, $sort, $order);
 
         if (!($entries)) {
             throw $this->createNotFoundException();
@@ -85,8 +108,7 @@ class WallabagRestController extends Controller
         $url = $request->request->get('url');
 
         $content = Extractor::extract($url);
-        $entry = new Entry();
-        $entry->setUserId(1);
+        $entry = new Entry($this->getUser());
         $entry->setUrl($url);
         $entry->setTitle($request->request->get('title') ?: $content->getTitle());
         $entry->setContent($content->getBody());
index 7cc4165efe26366186959a04e81d2221eb171688..c6ecc99e00145afaec17737fb30cb8ea9c9258c6 100644 (file)
@@ -3,7 +3,7 @@
 namespace Wallabag\CoreBundle\DependencyInjection;
 
 use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
+use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
 use Symfony\Component\HttpKernel\DependencyInjection\Extension;
 use Symfony\Component\Config\FileLocator;
 
@@ -11,8 +11,8 @@ class WallabagCoreExtension extends Extension
 {
     public function load(array $configs, ContainerBuilder $container)
     {
-        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
-        $loader->load('services.xml');
+        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
+        $loader->load('services.yml');
     }
 
     public function getAlias()
index abf01930d1d9c6dc14a7176b9963df99bf6962e6..b6f86707046f72b73b676768d1a1b2640bd97daa 100644 (file)
@@ -91,12 +91,12 @@ class EntryRepository extends EntityRepository
     /**
      * Find Entries
      *
-     * @param  int    $userId
-     * @param  bool   $isArchived
-     * @param  bool   $isStarred
-     * @param  bool   $isDeleted
-     * @param  string $sort
-     * @param  string $order
+     * @param int    $userId
+     * @param bool   $isArchived
+     * @param bool   $isStarred
+     * @param bool   $isDeleted
+     * @param string $sort
+     * @param string $order
      *
      * @return array
      */
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.xml b/src/Wallabag/CoreBundle/Resources/config/services.xml
deleted file mode 100644 (file)
index 859665c..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" ?>
-
-<container xmlns="http://symfony.com/schema/dic/services"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
-
-    <services>
-        <!-- Twig -->
-        <service id="wallabag_core.twig.wallabag" class="Wallabag\CoreBundle\Twig\Extension\WallabagExtension">
-            <tag name="twig.extension" />
-        </service>
-
-        <!-- Security -->
-        <service id="wsse.security.authentication.provider"
-                 class="Wallabag\CoreBundle\Security\Authentication\Provider\WsseProvider" public="false">
-            <argument /> <!-- User Provider -->
-            <argument>%kernel.cache_dir%/security/nonces</argument>
-        </service>
-
-        <service id="wsse.security.authentication.listener"
-                 class="Wallabag\CoreBundle\Security\Firewall\WsseListener" public="false">
-            <argument type="service" id="security.context"/>
-            <argument type="service" id="security.authentication.manager" />
-        </service>
-    </services>
-
-</container>
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
new file mode 100644 (file)
index 0000000..b066c1a
--- /dev/null
@@ -0,0 +1,15 @@
+services:
+    wallabag_core.twig.wallabag:
+        class: Wallabag\CoreBundle\Twig\Extension\WallabagExtension
+        tags:
+            - { name: twig.extension }
+    wsse.security.authentication.provider:
+        class: Wallabag\CoreBundle\Security\Authentication\Provider\WsseProvider
+        public: false
+        arguments: ['', '%kernel.cache_dir%/security/nonces']
+    wsse.security.authentication.listener:
+        class: Wallabag\CoreBundle\Security\Firewall\WsseListener
+        public: false
+        tags:
+            - { name: monolog.logger, channel: wsse }
+        arguments: ['@security.context', '@security.authentication.manager', '@logger']
index 5499f4007d411323f37c2af41e3b0a2fa77ac5ba..7e6a5dfb3960f30f78043df38a0485cddf6b1c52 100644 (file)
@@ -17,12 +17,21 @@ class WsseProvider implements AuthenticationProviderInterface
     {
         $this->userProvider = $userProvider;
         $this->cacheDir     = $cacheDir;
+
+        // If cache directory does not exist we create it
+        if (!is_dir($this->cacheDir)) {
+            mkdir($this->cacheDir, 0777, true);
+        }
     }
 
     public function authenticate(TokenInterface $token)
     {
         $user = $this->userProvider->loadUserByUsername($token->getUsername());
 
+        if (!$user) {
+            throw new AuthenticationException("Bad credentials. Did you forgot your username?");
+        }
+
         if ($user && $this->validateDigest($token->digest, $token->nonce, $token->created, $user->getPassword())) {
             $authenticatedToken = new WsseUserToken($user->getRoles());
             $authenticatedToken->setUser($user);
@@ -35,20 +44,30 @@ class WsseProvider implements AuthenticationProviderInterface
 
     protected function validateDigest($digest, $nonce, $created, $secret)
     {
-        // Expire le timestamp après 5 minutes
+        // Check created time is not in the future
+        if (strtotime($created) > time()) {
+            throw new AuthenticationException("Back to the future...");
+        }
+
+        // Expire timestamp after 5 minutes
         if (time() - strtotime($created) > 300) {
-            return false;
+            throw new AuthenticationException("Too late for this timestamp... Watch your watch.");
         }
 
-        // Valide que le nonce est unique dans les 5 minutes
+        // Validate nonce is unique within 5 minutes
         if (file_exists($this->cacheDir.'/'.$nonce) && file_get_contents($this->cacheDir.'/'.$nonce) + 300 > time()) {
             throw new NonceExpiredException('Previously used nonce detected');
         }
+
         file_put_contents($this->cacheDir.'/'.$nonce, time());
 
-        // Valide le Secret
+        // Validate Secret
         $expected = base64_encode(sha1(base64_decode($nonce).$created.$secret, true));
 
+        if ($digest !== $expected) {
+            throw new AuthenticationException("Bad credentials ! Digest is not as expected.");
+        }
+
         return $digest === $expected;
     }
 
index 4d4f2145c884ff16d2b2e5108747602aa04ee5ce..6ffdfaf0a4e482a91749ff4081822dba74ebecfb 100644 (file)
@@ -9,16 +9,19 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException;
 use Symfony\Component\Security\Core\SecurityContextInterface;
 use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
 use Wallabag\CoreBundle\Security\Authentication\Token\WsseUserToken;
+use Psr\Log\LoggerInterface;
 
 class WsseListener implements ListenerInterface
 {
     protected $securityContext;
     protected $authenticationManager;
+    protected $logger;
 
-    public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager)
+    public function __construct(SecurityContextInterface $securityContext, AuthenticationManagerInterface $authenticationManager, LoggerInterface $logger)
     {
         $this->securityContext = $securityContext;
         $this->authenticationManager = $authenticationManager;
+        $this->logger = $logger;
     }
 
     public function handle(GetResponseEvent $event)
@@ -41,17 +44,19 @@ class WsseListener implements ListenerInterface
             $authToken = $this->authenticationManager->authenticate($token);
 
             $this->securityContext->setToken($authToken);
-        } catch (AuthenticationException $failed) {
-            // ... you might log something here
 
-            // To deny the authentication clear the token. This will redirect to the login page.
-            // $this->securityContext->setToken(null);
-            // return;
+            return;
+        } catch (AuthenticationException $failed) {
+            $failedMessage = 'WSSE Login failed for '.$token->getUsername().'. Why ? '.$failed->getMessage();
+            $this->logger->err($failedMessage);
 
             // Deny authentication with a '403 Forbidden' HTTP response
             $response = new Response();
             $response->setStatusCode(403);
+            $response->setContent($failedMessage);
             $event->setResponse($response);
+
+            return;
         }
     }
 }
index 5f092318145f4cb7a817a7f85087e228777e7480..edc7d9927acffb76a211907262a8300bada81412 100644 (file)
@@ -3,8 +3,6 @@
 namespace Wallabag\CoreBundle\Tests;
 
 use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
-use Symfony\Component\BrowserKit\Cookie;
-use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
 
 class WallabagTestCase extends WebTestCase
 {