]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #3937 from wallabag/fix/credential-subdomain
authorJérémy Benoist <j0k3r@users.noreply.github.com>
Sat, 27 Apr 2019 08:58:26 +0000 (10:58 +0200)
committerGitHub <noreply@github.com>
Sat, 27 Apr 2019 08:58:26 +0000 (10:58 +0200)
 Add ability to match many domains for credentials

17 files changed:
src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSiteCredentialData.php
src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
src/Wallabag/CoreBundle/Resources/translations/messages.th.yml
tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php

index 866f55a403d40bf8bf5b9a753006c5dec8693dba..faf29da662d0125d4f2a85eaa4d57a9e27120ca1 100644 (file)
@@ -5,19 +5,38 @@ namespace Wallabag\CoreBundle\DataFixtures\ORM;
 use Doctrine\Common\DataFixtures\AbstractFixture;
 use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
 use Doctrine\Common\Persistence\ObjectManager;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Wallabag\CoreBundle\Entity\SiteCredential;
 
-class LoadSiteCredentialData extends AbstractFixture implements OrderedFixtureInterface
+class LoadSiteCredentialData extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
 {
+    /**
+     * @var ContainerInterface
+     */
+    private $container;
+
+    public function setContainer(ContainerInterface $container = null)
+    {
+        $this->container = $container;
+    }
+
     /**
      * {@inheritdoc}
      */
     public function load(ObjectManager $manager)
     {
         $credential = new SiteCredential($this->getReference('admin-user'));
-        $credential->setHost('example.com');
-        $credential->setUsername('foo');
-        $credential->setPassword('bar');
+        $credential->setHost('.super.com');
+        $credential->setUsername($this->container->get('wallabag_core.helper.crypto_proxy')->crypt('.super'));
+        $credential->setPassword($this->container->get('wallabag_core.helper.crypto_proxy')->crypt('bar'));
+
+        $manager->persist($credential);
+
+        $credential = new SiteCredential($this->getReference('admin-user'));
+        $credential->setHost('paywall.example.com');
+        $credential->setUsername($this->container->get('wallabag_core.helper.crypto_proxy')->crypt('paywall.example'));
+        $credential->setPassword($this->container->get('wallabag_core.helper.crypto_proxy')->crypt('bar'));
 
         $manager->persist($credential);
 
index 90e00c62d9aaeff353e5f356ec6fcc4703e9d5db..c7502baccdb6a996597bc5502b8502307d42509c 100644 (file)
@@ -62,11 +62,24 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
             $host = substr($host, 4);
         }
 
-        $credentials = null;
-        if ($this->currentUser) {
-            $credentials = $this->credentialRepository->findOneByHostAndUser($host, $this->currentUser->getId());
+        if (!$this->currentUser) {
+            $this->logger->debug('Auth: no current user defined.');
+
+            return false;
+        }
+
+        $hosts = [$host];
+        // will try to see for a host without the first subdomain (fr.example.org & .example.org)
+        $split = explode('.', $host);
+
+        if (\count($split) > 1) {
+            // remove first subdomain
+            array_shift($split);
+            $hosts[] = '.' . implode('.', $split);
         }
 
+        $credentials = $this->credentialRepository->findOneByHostsAndUser($hosts, $this->currentUser->getId());
+
         if (null === $credentials) {
             $this->logger->debug('Auth: no credentials available for host.', ['host' => $host]);
 
index b2e212a41438cc32d7e3bbab212aed78382b76fd..aeadd77045a00af2a8dd104ca1461309c8c8fe08 100644 (file)
@@ -19,16 +19,16 @@ class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository
     /**
      * Retrieve one username/password for the given host and userId.
      *
-     * @param string $host
-     * @param int    $userId
+     * @param array $hosts  An array of host to look for
+     * @param int   $userId
      *
      * @return array|null
      */
-    public function findOneByHostAndUser($host, $userId)
+    public function findOneByHostsAndUser($hosts, $userId)
     {
         $res = $this->createQueryBuilder('s')
             ->select('s.username', 's.password')
-            ->where('s.host = :hostname')->setParameter('hostname', $host)
+            ->where('s.host IN (:hosts)')->setParameter('hosts', $hosts)
             ->andWhere('s.user = :userId')->setParameter('userId', $userId)
             ->setMaxResults(1)
             ->getQuery()
index 97eb874d28b54335c5e83ff9de81fb6f120e48e8..6f8425340ab61d0ef8f66bb96d94fafd436c4216 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
     #     create_new_one: Create a new credential
     # form:
     #     username_label: 'Username'
-    #     host_label: 'Host'
+    #     host_label: 'Host (subdomain.example.org, .example.org, etc.)'
     #     password_label: 'Password'
     #     save: Save
     #     delete: Delete
index 0cf3b138e92c5bd9f23e21ef691dc16a98396037..874908b9e6a35b9e37a867dbf2ea89870256d097 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
         create_new_one: 'Einen neuen Seitenzugang anlegen'
     form:
         username_label: 'Benutzername'
-        host_label: 'Host'
+        host_label: 'Host (subdomain.example.org, .example.org, etc.)'
         password_label: 'Passwort'
         save: 'Speichern'
         delete: 'Löschen'
index 6085be14006852fc0430b48dec1c97e9dad33082..598ad58da3d1e520aec36c746c9e80bab2a27e26 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
         create_new_one: Create a new credential
     form:
         username_label: 'Username'
-        host_label: 'Host'
+        host_label: 'Host (subdomain.example.org, .example.org, etc.)'
         password_label: 'Password'
         save: Save
         delete: Delete
index f2a8fb890b67bca57935aee308f648ff555fab7e..f8aa410939600d8ea29dbed1c547f157c62416ed 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
     #     create_new_one: Create a new credential
     # form:
     #     username_label: 'Username'
-    #     host_label: 'Host'
+    #     host_label: 'Host (subdomain.example.org, .example.org, etc.)'
     #     password_label: 'Password'
     #     save: Save
     #     delete: Delete
index a5cbd7ecbf0c8d62c1822dfa7d8347a7d1fff827..785e39ee956dea2e75c64a8ef23cc16525529138 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
     #     create_new_one: Create a new credential
     # form:
     #     username_label: 'Username'
-    #     host_label: 'Host'
+    #     host_label: 'Host (subdomain.example.org, .example.org, etc.)'
     #     password_label: 'Password'
     #     save: Save
     #     delete: Delete
index a36d84ae1377abce04c8418cc527b1944d4f5f4f..b2fa1c50cccc27597c4fc9e3f24977999e395e4b 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
         create_new_one: Créer un nouvel accès à un site
     form:
         username_label: 'Identifiant'
-        host_label: 'Domaine'
+        host_label: 'Domaine (subdomain.example.org, .example.org, etc.)'
         password_label: 'Mot de passe'
         save: "Sauvegarder"
         delete: "Supprimer"
index 1649c0e4fc2054539acdfb0bef12a62623d384c8..ecaa3b60dce6679709f16495a8f0297eb68d7203 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
     #     create_new_one: Create a new credential
     # form:
     #     username_label: 'Username'
-    #     host_label: 'Host'
+    #     host_label: 'Host (subdomain.example.org, .example.org, etc.)'
     #     password_label: 'Password'
     #     save: Save
     #     delete: Delete
index e2298f1f6206987c9d940d0f428aa87ea8d252c7..848c88d23f0376dc6c38fc5ea2dbda3bd2312f76 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
          create_new_one: Crear un novèl identificant
     form:
         username_label: "Nom d'utilizaire"
-        host_label: 'Òste'
+        host_label: 'Òste (subdomain.example.org, .example.org, etc.)'
         password_label: 'Senhal'
         save: 'Enregistrar'
         delete: 'Suprimir'
index a5712733bd58a1a8459776e5017888fa892522fb..a0032fe8fc5da5369bd5b4e2206832226a028515 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
         create_new_one: Stwórz nowe poświadczenie
     form:
         username_label: 'Nazwa użytkownika'
-        host_label: 'Host'
+        host_label: 'Host (subdomain.example.org, .example.org, etc.)'
         password_label: 'Hasło'
         save: Zapisz
         delete: Usuń
index 1ccf49e1b7252fe2b85f2b147bcab84bff5cb318..292fad61860f00befda4bf89f230718f1dc6b86d 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
         # create_new_one: Create a new credential
     form:
         # username_label: 'Username'
-        # host_label: 'Host'
+        # host_label: 'Host (subdomain.example.org, .example.org, etc.)'
         # password_label: 'Password'
         save: 'Salvar'
         delete: 'Apagar'
index 6c0e18e1c4af62c78c4ffc34a630ddd18e8222ab..9e8d68b3c0b3a643aa73ce042dabfad2e71ef644 100644 (file)
@@ -550,7 +550,7 @@ site_credential:
     #     create_new_one: Create a new credential
     # form:
     #     username_label: 'Username'
-    #     host_label: 'Host'
+    #     host_label: 'Host (subdomain.example.org, .example.org, etc.)'
     #     password_label: 'Password'
     #     save: Save
     #     delete: Delete
index 5524b1f124547892331afc9b5be673a59931abf6..cb3b0f23fd3657eaae8d2b061831f0c78be6ab0e 100644 (file)
@@ -548,7 +548,7 @@ site_credential:
         create_new_one: สร้างข้อมูลส่วนตัวใหม่
     form:
         username_label: 'ชื่อผู้ใช้'
-        host_label: 'โฮส'
+        host_label: 'โฮส (subdomain.example.org, .example.org, etc.)'
         password_label: 'รหัสผ่าน'
         save: บันทึก
         delete: ลบ
index 479e07000e642d1de582d3c67a51d666274bb718..2cd6aee370e96dfbb5523be7c6d1b574885b14e7 100644 (file)
@@ -166,7 +166,7 @@ class EntryControllerTest extends WallabagCoreTestCase
         $this->assertSame($this->url, $content->getUrl());
         $this->assertContains('Google', $content->getTitle());
         $this->assertSame('fr', $content->getLanguage());
-        $this->assertSame('2016-04-07 19:01:35', $content->getPublishedAt()->format('Y-m-d H:i:s'));
+        $this->assertSame('2015-03-28 11:43:19', $content->getPublishedAt()->format('Y-m-d H:i:s'));
         $this->assertArrayHasKey('x-frame-options', $content->getHeaders());
         $client->getContainer()->get('craue_config')->set('store_article_headers', 0);
     }
index 1173fc3dee8f4a858ceaba71658a7281aa243ab3..845762dc1bb38b8e2e6c79c8fa9e969f4c9568b9 100644 (file)
@@ -5,26 +5,22 @@ namespace Tests\Wallabag\CoreBundle\GuzzleSiteAuthenticator;
 use Graby\SiteConfig\SiteConfig as GrabySiteConfig;
 use Monolog\Handler\TestHandler;
 use Monolog\Logger;
-use PHPUnit\Framework\TestCase;
 use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
 use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
+use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
 use Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder;
 
-class GrabySiteConfigBuilderTest extends TestCase
+class GrabySiteConfigBuilderTest extends WallabagCoreTestCase
 {
-    /** @var \Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder */
-    protected $builder;
-
     public function testBuildConfigExists()
     {
-        /* @var \Graby\SiteConfig\ConfigBuilder|\PHPUnit_Framework_MockObject_MockObject */
         $grabyConfigBuilderMock = $this->getMockBuilder('Graby\SiteConfig\ConfigBuilder')
             ->disableOriginalConstructor()
             ->getMock();
 
         $grabySiteConfig = new GrabySiteConfig();
         $grabySiteConfig->requires_login = true;
-        $grabySiteConfig->login_uri = 'http://www.example.com/login';
+        $grabySiteConfig->login_uri = 'http://api.example.com/login';
         $grabySiteConfig->login_username_field = 'login';
         $grabySiteConfig->login_password_field = 'password';
         $grabySiteConfig->login_extra_fields = ['field=value'];
@@ -32,7 +28,7 @@ class GrabySiteConfigBuilderTest extends TestCase
 
         $grabyConfigBuilderMock
             ->method('buildForHost')
-            ->with('example.com')
+            ->with('api.example.com')
             ->will($this->returnValue($grabySiteConfig));
 
         $logger = new Logger('foo');
@@ -43,8 +39,8 @@ class GrabySiteConfigBuilderTest extends TestCase
             ->disableOriginalConstructor()
             ->getMock();
         $siteCrentialRepo->expects($this->once())
-            ->method('findOneByHostAndUser')
-            ->with('example.com', 1)
+            ->method('findOneByHostsAndUser')
+            ->with(['api.example.com', '.example.com'], 1)
             ->willReturn(['username' => 'foo', 'password' => 'bar']);
 
         $user = $this->getMockBuilder('Wallabag\UserBundle\Entity\User')
@@ -59,18 +55,18 @@ class GrabySiteConfigBuilderTest extends TestCase
         $tokenStorage = new TokenStorage();
         $tokenStorage->setToken($token);
 
-        $this->builder = new GrabySiteConfigBuilder(
+        $builder = new GrabySiteConfigBuilder(
             $grabyConfigBuilderMock,
             $tokenStorage,
             $siteCrentialRepo,
             $logger
         );
 
-        $config = $this->builder->buildForHost('www.example.com');
+        $config = $builder->buildForHost('api.example.com');
 
-        $this->assertSame('example.com', $config->getHost());
+        $this->assertSame('api.example.com', $config->getHost());
         $this->assertTrue($config->requiresLogin());
-        $this->assertSame('http://www.example.com/login', $config->getLoginUri());
+        $this->assertSame('http://api.example.com/login', $config->getLoginUri());
         $this->assertSame('login', $config->getUsernameField());
         $this->assertSame('password', $config->getPasswordField());
         $this->assertSame(['field' => 'value'], $config->getExtraFields());
@@ -85,7 +81,6 @@ class GrabySiteConfigBuilderTest extends TestCase
 
     public function testBuildConfigDoesntExist()
     {
-        /* @var \Graby\SiteConfig\ConfigBuilder|\PHPUnit_Framework_MockObject_MockObject */
         $grabyConfigBuilderMock = $this->getMockBuilder('\Graby\SiteConfig\ConfigBuilder')
             ->disableOriginalConstructor()
             ->getMock();
@@ -103,8 +98,8 @@ class GrabySiteConfigBuilderTest extends TestCase
             ->disableOriginalConstructor()
             ->getMock();
         $siteCrentialRepo->expects($this->once())
-            ->method('findOneByHostAndUser')
-            ->with('unknown.com', 1)
+            ->method('findOneByHostsAndUser')
+            ->with(['unknown.com', '.com'], 1)
             ->willReturn(null);
 
         $user = $this->getMockBuilder('Wallabag\UserBundle\Entity\User')
@@ -119,14 +114,14 @@ class GrabySiteConfigBuilderTest extends TestCase
         $tokenStorage = new TokenStorage();
         $tokenStorage->setToken($token);
 
-        $this->builder = new GrabySiteConfigBuilder(
+        $builder = new GrabySiteConfigBuilder(
             $grabyConfigBuilderMock,
             $tokenStorage,
             $siteCrentialRepo,
             $logger
         );
 
-        $config = $this->builder->buildForHost('unknown.com');
+        $config = $builder->buildForHost('unknown.com');
 
         $this->assertFalse($config);
 
@@ -134,4 +129,121 @@ class GrabySiteConfigBuilderTest extends TestCase
 
         $this->assertCount(1, $records, 'One log was recorded');
     }
+
+    public function testBuildConfigUserNotDefined()
+    {
+        $grabyConfigBuilderMock = $this->getMockBuilder('\Graby\SiteConfig\ConfigBuilder')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $grabyConfigBuilderMock
+            ->method('buildForHost')
+            ->with('unknown.com')
+            ->will($this->returnValue(new GrabySiteConfig()));
+
+        $logger = new Logger('foo');
+        $handler = new TestHandler();
+        $logger->pushHandler($handler);
+
+        $siteCrentialRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\SiteCredentialRepository')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $tokenStorage = new TokenStorage();
+
+        $builder = new GrabySiteConfigBuilder(
+            $grabyConfigBuilderMock,
+            $tokenStorage,
+            $siteCrentialRepo,
+            $logger
+        );
+
+        $config = $builder->buildForHost('unknown.com');
+
+        $this->assertFalse($config);
+    }
+
+    public function dataProviderCredentials()
+    {
+        return [
+            [
+                'host' => 'example.com',
+            ],
+            [
+                'host' => 'other.example.com',
+            ],
+            [
+                'host' => 'paywall.example.com',
+                'expectedUsername' => 'paywall.example',
+                'expectedPassword' => 'bar',
+            ],
+            [
+                'host' => 'api.super.com',
+                'expectedUsername' => '.super',
+                'expectedPassword' => 'bar',
+            ],
+            [
+                'host' => '.super.com',
+                'expectedUsername' => '.super',
+                'expectedPassword' => 'bar',
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider dataProviderCredentials
+     */
+    public function testBuildConfigWithDbAccess($host, $expectedUsername = null, $expectedPassword = null)
+    {
+        $grabyConfigBuilderMock = $this->getMockBuilder('Graby\SiteConfig\ConfigBuilder')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $grabySiteConfig = new GrabySiteConfig();
+        $grabySiteConfig->requires_login = true;
+        $grabySiteConfig->login_uri = 'http://api.example.com/login';
+        $grabySiteConfig->login_username_field = 'login';
+        $grabySiteConfig->login_password_field = 'password';
+        $grabySiteConfig->login_extra_fields = ['field=value'];
+        $grabySiteConfig->not_logged_in_xpath = '//div[@class="need-login"]';
+
+        $grabyConfigBuilderMock
+            ->method('buildForHost')
+            ->with($host)
+            ->will($this->returnValue($grabySiteConfig));
+
+        $user = $this->getMockBuilder('Wallabag\UserBundle\Entity\User')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $user->expects($this->once())
+            ->method('getId')
+            ->willReturn(1);
+
+        $token = new UsernamePasswordToken($user, 'pass', 'provider');
+
+        $tokenStorage = new TokenStorage();
+        $tokenStorage->setToken($token);
+
+        $logger = new Logger('foo');
+        $handler = new TestHandler();
+        $logger->pushHandler($handler);
+
+        $builder = new GrabySiteConfigBuilder(
+            $grabyConfigBuilderMock,
+            $tokenStorage,
+            $this->getClient()->getContainer()->get('wallabag_core.site_credential_repository'),
+            $logger
+        );
+
+        $config = $builder->buildForHost($host);
+
+        if (null === $expectedUsername && null === $expectedPassword) {
+            $this->assertFalse($config);
+
+            return;
+        }
+
+        $this->assertSame($expectedUsername, $config->getUsername());
+        $this->assertSame($expectedPassword, $config->getPassword());
+    }
 }