]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #2637 from wallabag/mruminski-patch-1
authorJeremy Benoist <j0k3r@users.noreply.github.com>
Tue, 22 Nov 2016 19:02:00 +0000 (20:02 +0100)
committerGitHub <noreply@github.com>
Tue, 22 Nov 2016 19:02:00 +0000 (20:02 +0100)
Update messages.pl.yml

28 files changed:
app/AppKernel.php
app/DoctrineMigrations/Version20161122144743.php [new file with mode: 0644]
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.da.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.de.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.en.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.es.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fa.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.fr.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.it.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.oc.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pl.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.pt.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.ro.yml
app/Resources/CraueConfigBundle/translations/CraueConfigBundle.tr.yml
app/config/parameters.yml.dist
composer.json
docs/de/developer/paywall.rst [new file with mode: 0644]
docs/de/index.rst
docs/en/developer/paywall.rst [new file with mode: 0644]
docs/en/index.rst
docs/fr/developer/paywall.rst [new file with mode: 0644]
docs/fr/index.rst
src/Wallabag/CoreBundle/Command/InstallCommand.php
src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSettingData.php
src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Helper/HttpClientFactory.php [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/config/services.yml
tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php [new file with mode: 0644]

index 81b83ef9d40472322dec346edaa4c67cc50b2bb3..c8382d5f6c27991f2034dfcb93e1c030b30e35cc 100644 (file)
@@ -31,6 +31,7 @@ class AppKernel extends Kernel
             new Craue\ConfigBundle\CraueConfigBundle(),
             new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(),
             new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
+            new BD\GuzzleSiteAuthenticatorBundle\BDGuzzleSiteAuthenticatorBundle(),
 
             // wallabag bundles
             new Wallabag\CoreBundle\WallabagCoreBundle(),
diff --git a/app/DoctrineMigrations/Version20161122144743.php b/app/DoctrineMigrations/Version20161122144743.php
new file mode 100644 (file)
index 0000000..ec80c48
--- /dev/null
@@ -0,0 +1,45 @@
+<?php
+
+namespace Application\Migrations;
+
+use Doctrine\DBAL\Migrations\AbstractMigration;
+use Doctrine\DBAL\Schema\Schema;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Add the restricted_access internal setting for articles with paywall
+ */
+class Version20161122144743 extends AbstractMigration implements ContainerAwareInterface
+{
+    /**
+     * @var ContainerInterface
+     */
+    private $container;
+
+    public function setContainer(ContainerInterface $container = null)
+    {
+        $this->container = $container;
+    }
+
+    private function getTable($tableName)
+    {
+        return $this->container->getParameter('database_table_prefix') . $tableName;
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function up(Schema $schema)
+    {
+        $this->addSql("INSERT INTO ".$this->getTable('craue_config_setting')." (name, value, section) VALUES ('restricted_access', 0, 'entry')");
+    }
+
+    /**
+     * @param Schema $schema
+     */
+    public function down(Schema $schema)
+    {
+        $this->addSql("DELETE FROM ".$this->getTable('craue_config_setting')." WHERE name = 'restricted_access';");
+    }
+}
index fac3b4f876fa380943f8fb5a073af9765061b025..c65463dba3269ffdf574482b8f44230fabd83c10 100644 (file)
@@ -32,3 +32,4 @@ demo_mode_enabled: "Aktiver demo-indstilling? (anvendes kun til wallabags offent
 demo_mode_username: "Demobruger"
 # share_public: Allow public url for entries
 # download_images_enabled: Download images locally
+# restricted_access: Enable authentication for websites with paywall
index d382733c53315829aa46bcacbde50453b25e5aa4..bc378147b2242ddd3d0addf1fcc3b0a031d73f2b 100644 (file)
@@ -32,3 +32,4 @@ demo_mode_enabled: "Test-Modus aktivieren? (nur für die öffentliche wallabag-D
 demo_mode_username: "Test-Benutzer"
 share_public: Erlaube eine öffentliche URL für Einträge
 # download_images_enabled: Download images locally
+# restricted_access: Enable authentication for websites with paywall
index 23de7a434a06a89b1d00f1976633615433095090..52cb8e202c716768b4bdfab62057f1d4d9836453 100644 (file)
@@ -32,3 +32,4 @@ demo_mode_enabled: "Enable demo mode ? (only used for the wallabag public demo)"
 demo_mode_username: "Demo user"
 share_public: Allow public url for entries
 download_images_enabled: Download images locally
+restricted_access: Enable authentication for websites with paywall
index ff1dd04ff6abbd704cfe134725aac85f9caaf444..dbec0e81853d8b5f70add3fed4c770ab9e571dbe 100644 (file)
@@ -32,3 +32,4 @@ demo_mode_enabled: "Activar modo demo (sólo usado para la demo de wallabag)"
 demo_mode_username: "Nombre de usuario demo"
 # share_public: Allow public url for entries
 # download_images_enabled: Download images locally
+# restricted_access: Enable authentication for websites with paywall
index 4e712fdde5d6ae0a4a4c974bd52f09b5955ac578..7a341e0b71d6c532f5aa665f5c3f6c893307c014 100644 (file)
@@ -32,3 +32,4 @@ modify_settings: "اعمال"
 # demo_mode_username: "Demo user"
 # share_public: Allow public url for entries
 # download_images_enabled: Download images locally
+# restricted_access: Enable authentication for websites with paywall
index cae4c662dd382eca296cdab154dba7c71ff52cfd..f5c886d6ecf9b07b06f85292ba39bcaa30cd057d 100644 (file)
@@ -32,3 +32,4 @@ demo_mode_enabled: "Activer le mode démo ? (utiliser uniquement pour la démo p
 demo_mode_username: "Utilisateur de la démo"
 share_public: Autoriser une URL publique pour les articles
 download_images_enabled: Télécharger les images en local
+restricted_access: Activer l'authentification pour les articles derrière un paywall
index f94f834f6693455e8e0cd0468e3f71deae05a5d9..88a1b4f6f601e6a3d31723c702ce17f1467b4c76 100644 (file)
@@ -32,3 +32,4 @@ demo_mode_enabled: "Abilita modalità demo ? (usato solo per la demo pubblica di
 demo_mode_username: "Utente Demo"
 # share_public: Allow public url for entries
 # download_images_enabled: Download images locally
+# restricted_access: Enable authentication for websites with paywall
index de60a194856d58194881f859680357be8450cae2..00deeade078a203b5a8e006545ef4d05b8e425f3 100644 (file)
@@ -32,3 +32,4 @@ demo_mode_enabled: "Activar lo mode demostracion ? (utilizar solament per la dem
 demo_mode_username: "Utilizaire de la demostracion"
 # share_public: Allow public url for entries
 # download_images_enabled: Download images locally
+# restricted_access: Enable authentication for websites with paywall
index 1157974516287d2614b69f7f15bb488e4831cb29..744031e8ec9c6431fad812414149f4d864deee17 100644 (file)
@@ -32,3 +32,4 @@ demo_mode_enabled: "Włacz tryb demo? (używany wyłącznie dla publicznej demon
 demo_mode_username: "Użytkownik Demonstracyjny"
 share_public: Zezwalaj na publiczny adres url dla wpisow
 # download_images_enabled: Download images locally
+# restricted_access: Enable authentication for websites with paywall
index 74ae5a44f3af6a07d615e126ffe811d72f3439eb..1edde87ac7f126bb1f1d29dc027be23f224a8e6b 100644 (file)
@@ -32,3 +32,4 @@ demo_mode_enabled: "Habilitar modo demo? (somente usado para o demo público do
 demo_mode_username: "Usuário demo"
 # share_public: Allow public url for entries
 # download_images_enabled: Download images locally
+# restricted_access: Enable authentication for websites with paywall
index 5095dfa00417331be346bded4bb2ad34a7c4e61e..f0c935d3fd65a24758886a42016456323b24f4cf 100644 (file)
@@ -32,3 +32,4 @@ modify_settings: "aplică"
 # demo_mode_username: "Demo user"
 # share_public: Allow public url for entries
 # download_images_enabled: Download images locally
+# restricted_access: Enable authentication for websites with paywall
index cd42e595d4524b8f6e86caf894065f66e1de8869..eb40fc5ed16d7d4ec983023e8179ffaac5f46d12 100644 (file)
@@ -32,3 +32,4 @@
 # demo_mode_username: "Demo user"
 # share_public: Allow public url for entries
 # download_images_enabled: Download images locally
+# restricted_access: Enable authentication for websites with paywall
index f821f2a85c8e6513e5256a947737e0d219327c07..a4dc0bdea5df1f654275f713436a7cf209af4613 100644 (file)
@@ -56,3 +56,6 @@ parameters:
     redis_port: 6379
     redis_path: null
     redis_password: null
+
+    # sites credentials
+    sites_credentials: {}
index 1548d6ec60db32bfcd912380e426f4e51d844326..e2aeb424cf59aa2d71322a443f9499abe9adc618 100644 (file)
@@ -83,7 +83,8 @@
         "predis/predis": "^1.0",
         "javibravo/simpleue": "^1.0",
         "symfony/dom-crawler": "^3.1",
-        "friendsofsymfony/jsrouting-bundle": "^1.6"
+        "friendsofsymfony/jsrouting-bundle": "^1.6",
+        "bdunogier/guzzle-site-authenticator": "^1.0@beta"
     },
     "require-dev": {
         "doctrine/doctrine-fixtures-bundle": "~2.2",
diff --git a/docs/de/developer/paywall.rst b/docs/de/developer/paywall.rst
new file mode 100644 (file)
index 0000000..365027b
--- /dev/null
@@ -0,0 +1,56 @@
+Articles behind a paywall
+=========================
+
+wallabag can fetch articles from websites which use a paywall system.
+
+Enable paywall authentication
+-----------------------------
+
+In internal settings, in the **Article** section, enable authentication for websites with paywall (with the value 1).
+
+Configure credentials in wallabag
+---------------------------------
+
+Edit your ``app/config/parameters.yml`` file to edit credentials for each website with paywall. Here is an example for some french websites:
+
+.. code:: yaml
+
+    sites_credentials:
+        mediapart.fr: {username: "myMediapartLogin", password: "mypassword"}
+        arretsurimages.net: {username: "myASILogin", password: "mypassword"}
+
+.. note::
+
+    These credentials will be shared between each user of your wallabag instance.
+
+Parsing configuration files
+---------------------------
+
+.. note::
+
+    Read `this part of the documentation <http://doc.wallabag.org/en/master/user/errors_during_fetching.html>`_ to understand the configuration files.
+
+Each parsing configuration file needs to be improved by adding ``requires_login``, ``login_uri``,
+``login_username_field``, ``login_password_field`` and ``not_logged_in_xpath``.
+
+Be careful, the login form must be in the page content when wallabag loads it. It's impossible for wallabag to be authenticated
+on a website where the login form is loaded after the page (by ajax for example).
+
+``login_uri`` is the action URL of the form (``action`` attribute in the form).
+``login_username_field`` is the ``name`` attribute of the login field.
+``login_password_field`` is the ``name`` attribute of the password field.
+
+For example:
+
+.. code::
+
+    title://div[@id="titrage-contenu"]/h1[@class="title"]
+    body: //div[@class="contenu-html"]/div[@class="page-pane"]
+
+    requires_login: yes
+
+    login_uri: http://www.arretsurimages.net/forum/login.php
+    login_username_field: username
+    login_password_field: password
+
+    not_logged_in_xpath: //body[@class="not-logged-in"]
index c1ce7d4b4b7b315eaac2801e16de1cf8ae3d561c..1c3e4873bbd46cc01d1acef258bb40ae229b9d17 100644 (file)
@@ -46,6 +46,7 @@ Die Dokumentation ist in anderen Sprachen verfügbar :
 
    developer/api
    developer/docker
+   developer/paywall
    developer/documentation
    developer/translate
    developer/asynchronous
diff --git a/docs/en/developer/paywall.rst b/docs/en/developer/paywall.rst
new file mode 100644 (file)
index 0000000..365027b
--- /dev/null
@@ -0,0 +1,56 @@
+Articles behind a paywall
+=========================
+
+wallabag can fetch articles from websites which use a paywall system.
+
+Enable paywall authentication
+-----------------------------
+
+In internal settings, in the **Article** section, enable authentication for websites with paywall (with the value 1).
+
+Configure credentials in wallabag
+---------------------------------
+
+Edit your ``app/config/parameters.yml`` file to edit credentials for each website with paywall. Here is an example for some french websites:
+
+.. code:: yaml
+
+    sites_credentials:
+        mediapart.fr: {username: "myMediapartLogin", password: "mypassword"}
+        arretsurimages.net: {username: "myASILogin", password: "mypassword"}
+
+.. note::
+
+    These credentials will be shared between each user of your wallabag instance.
+
+Parsing configuration files
+---------------------------
+
+.. note::
+
+    Read `this part of the documentation <http://doc.wallabag.org/en/master/user/errors_during_fetching.html>`_ to understand the configuration files.
+
+Each parsing configuration file needs to be improved by adding ``requires_login``, ``login_uri``,
+``login_username_field``, ``login_password_field`` and ``not_logged_in_xpath``.
+
+Be careful, the login form must be in the page content when wallabag loads it. It's impossible for wallabag to be authenticated
+on a website where the login form is loaded after the page (by ajax for example).
+
+``login_uri`` is the action URL of the form (``action`` attribute in the form).
+``login_username_field`` is the ``name`` attribute of the login field.
+``login_password_field`` is the ``name`` attribute of the password field.
+
+For example:
+
+.. code::
+
+    title://div[@id="titrage-contenu"]/h1[@class="title"]
+    body: //div[@class="contenu-html"]/div[@class="page-pane"]
+
+    requires_login: yes
+
+    login_uri: http://www.arretsurimages.net/forum/login.php
+    login_username_field: username
+    login_password_field: password
+
+    not_logged_in_xpath: //body[@class="not-logged-in"]
index 54a1eef8829b676e5e368b3966632936cb0ad88b..2e20aee628aca03a592f18c9c94a9a9a89c353a4 100644 (file)
@@ -46,6 +46,7 @@ The documentation is available in other languages:
 
    developer/api
    developer/docker
+   developer/paywall
    developer/documentation
    developer/translate
    developer/asynchronous
diff --git a/docs/fr/developer/paywall.rst b/docs/fr/developer/paywall.rst
new file mode 100644 (file)
index 0000000..c1c410b
--- /dev/null
@@ -0,0 +1,56 @@
+Articles derrière un paywall
+============================
+
+wallabag peut récupérer le contenu des articles des sites qui utilisent un système de paiement.
+
+Activer l'authentification pour les paywall
+-------------------------------------------
+
+Dans les paramètres internes, section **Article**, activez l'authentification pour les articles derrière un paywall (avec la valeur 1).
+
+Configurer les accès dans wallabag
+----------------------------------
+
+Éditez le fichier ``app/config/parameters.yml`` pour modifier les accès aux sites avec paywall. Voici un exemple pour certains sites :
+
+.. code:: yaml
+
+    sites_credentials:
+        mediapart.fr: {username: "myMediapartLogin", password: "mypassword"}
+        arretsurimages.net: {username: "myASILogin", password: "mypassword"}
+
+.. note::
+
+    Ces accès seront partagés entre chaque utilisateur de votre instance wallabag.
+
+Fichiers de configuration pour parser les articles
+--------------------------------------------------
+
+.. note::
+
+    Lisez `cette documentation <http://doc.wallabag.org/fr/master/user/errors_during_fetching.html>`_ pour en savoir plus sur ces fichiers de configuration.
+
+Chaque fichier de configuration doit être enrichi en ajoutant ``requires_login``, ``login_uri``,
+``login_username_field``, ``login_password_field`` et ``not_logged_in_xpath``.
+
+Attention, le formulaire de connexion doit se trouver dans le contenu de la page lors du chargement de celle-ci.
+Il sera impossible pour wallabag de se connecter à un site dont le formulaire de connexion est chargé après coup (en ajax par exemple).
+
+``login_uri`` correspond à l'URL à laquelle le formulaire est soumis (attribut ``action`` du formulaire).
+``login_username_field`` correspond à l'attribut ``name`` du champ de l'identifiant.
+``login_password_field`` correspond à l'attribut ``name`` du champ du mot de passe.
+
+Par exemple :
+
+.. code::
+
+    title://div[@id="titrage-contenu"]/h1[@class="title"]
+    body: //div[@class="contenu-html"]/div[@class="page-pane"]
+
+    requires_login: yes
+
+    login_uri: http://www.arretsurimages.net/forum/login.php
+    login_username_field: username
+    login_password_field: password
+
+    not_logged_in_xpath: //body[@class="not-logged-in"]
index 8a4c600a964830d33e409e8803e94080a1f666d8..e3f14b048dd69d15473ba320c256ae362e200807 100644 (file)
@@ -47,6 +47,7 @@ La documentation est disponible dans d'autres langues :
 
    developer/api
    developer/docker
+   developer/paywall
    developer/documentation
    developer/translate
    developer/asynchronous
index e95c3a7b226b76cd2e87b7d1ef66a7b20eaee878..f0738b9172a8f5cbda8bea7bb8be553dd2d54fd4 100644 (file)
@@ -432,6 +432,11 @@ class InstallCommand extends ContainerAwareCommand
                 'value' => '0',
                 'section' => 'misc',
             ],
+            [
+                'name' => 'restricted_access',
+                'value' => '0',
+                'section' => 'entry',
+            ],
         ];
 
         foreach ($settings as $setting) {
index 1f74891a836aea752ed3eb9ea28ac4a3bc65344f..a723656e250470e98384dc46954bf81e047564a9 100644 (file)
@@ -155,6 +155,11 @@ class LoadSettingData extends AbstractFixture implements OrderedFixtureInterface
                 'value' => '0',
                 'section' => 'misc',
             ],
+            [
+                'name' => 'restricted_access',
+                'value' => '0',
+                'section' => 'entry',
+            ],
         ];
 
         foreach ($settings as $setting) {
diff --git a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
new file mode 100644 (file)
index 0000000..6d4129e
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+namespace Wallabag\CoreBundle\GuzzleSiteAuthenticator;
+
+use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfig;
+use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfigBuilder;
+use Graby\SiteConfig\ConfigBuilder;
+use OutOfRangeException;
+
+class GrabySiteConfigBuilder implements SiteConfigBuilder
+{
+    /**
+     * @var \Graby\SiteConfig\ConfigBuilder
+     */
+    private $grabyConfigBuilder;
+    /**
+     * @var array
+     */
+    private $credentials;
+
+    /**
+     * GrabySiteConfigBuilder constructor.
+     *
+     * @param \Graby\SiteConfig\ConfigBuilder $grabyConfigBuilder
+     * @param array                           $credentials
+     */
+    public function __construct(ConfigBuilder $grabyConfigBuilder, array $credentials = [])
+    {
+        $this->grabyConfigBuilder = $grabyConfigBuilder;
+        $this->credentials = $credentials;
+    }
+
+    /**
+     * Builds the SiteConfig for a host.
+     *
+     * @param string $host The "www." prefix is ignored
+     *
+     * @return SiteConfig
+     *
+     * @throws OutOfRangeException If there is no config for $host
+     */
+    public function buildForHost($host)
+    {
+        // required by credentials below
+        $host = strtolower($host);
+        if (substr($host, 0, 4) == 'www.') {
+            $host = substr($host, 4);
+        }
+
+        $config = $this->grabyConfigBuilder->buildForHost($host);
+        $parameters = [
+            'host' => $host,
+            'requiresLogin' => $config->requires_login ?: false,
+            'loginUri' => $config->login_uri ?: null,
+            'usernameField' => $config->login_username_field ?: null,
+            'passwordField' => $config->login_password_field ?: null,
+            'extraFields' => is_array($config->login_extra_fields) ? $config->login_extra_fields : [],
+            'notLoggedInXpath' => $config->not_logged_in_xpath ?: null,
+        ];
+
+        if (isset($this->credentials[$host])) {
+            $parameters['username'] = $this->credentials[$host]['username'];
+            $parameters['password'] = $this->credentials[$host]['password'];
+        }
+
+        return new SiteConfig($parameters);
+    }
+}
diff --git a/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php b/src/Wallabag/CoreBundle/Helper/HttpClientFactory.php
new file mode 100644 (file)
index 0000000..8891887
--- /dev/null
@@ -0,0 +1,54 @@
+<?php
+
+namespace Wallabag\CoreBundle\Helper;
+
+use Graby\Ring\Client\SafeCurlHandler;
+use GuzzleHttp\Client;
+use GuzzleHttp\Cookie\CookieJar;
+use GuzzleHttp\Event\SubscriberInterface;
+
+/**
+ * Builds and configures the Guzzle HTTP client.
+ */
+class HttpClientFactory
+{
+    /** @var \GuzzleHttp\Event\SubscriberInterface */
+    private $authenticatorSubscriber;
+
+    /** @var \GuzzleHttp\Cookie\CookieJar */
+    private $cookieJar;
+
+    private $restrictedAccess;
+
+    /**
+     * HttpClientFactory constructor.
+     *
+     * @param \GuzzleHttp\Event\SubscriberInterface $authenticatorSubscriber
+     * @param \GuzzleHttp\Cookie\CookieJar          $cookieJar
+     * @param string                                $restrictedAccess        this param is a kind of boolean. Values: 0 or 1
+     */
+    public function __construct(SubscriberInterface $authenticatorSubscriber, CookieJar $cookieJar, $restrictedAccess)
+    {
+        $this->authenticatorSubscriber = $authenticatorSubscriber;
+        $this->cookieJar = $cookieJar;
+        $this->restrictedAccess = $restrictedAccess;
+    }
+
+    /**
+     * @return \GuzzleHttp\Client|null
+     */
+    public function buildHttpClient()
+    {
+        if (0 === (int) $this->restrictedAccess) {
+            return null;
+        }
+
+        // we clear the cookie to avoid websites who use cookies for analytics
+        $this->cookieJar->clear();
+        // need to set the (shared) cookie jar
+        $client = new Client(['handler' => new SafeCurlHandler(), 'defaults' => ['cookies' => $this->cookieJar]]);
+        $client->getEmitter()->attach($this->authenticatorSubscriber);
+
+        return $client;
+    }
+}
index 0280bc182a754e58835f04ccdea6a4e5bf4a83df..bcf0c9cab338748831df21ba5f2164b9ae385ca5 100644 (file)
@@ -41,11 +41,44 @@ services:
         arguments:
             -
                 error_message: '%wallabag_core.fetching_error_message%'
+            - "@wallabag_core.guzzle.http_client"
+            - "@wallabag_core.graby.config_builder"
         calls:
             - [ setLogger, [ "@logger" ] ]
         tags:
             - { name: monolog.logger, channel: graby }
 
+    wallabag_core.graby.config_builder:
+        class: Graby\SiteConfig\ConfigBuilder
+        arguments:
+            - {}
+            - "@logger"
+
+    wallabag_core.guzzle.http_client:
+        class: GuzzleHttp\ClientInterface
+        factory: ["@wallabag_core.guzzle.http_client_factory", buildHttpClient]
+
+    wallabag_core.guzzle_authenticator.config_builder:
+        class: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder
+        arguments:
+            - "@wallabag_core.graby.config_builder"
+            - "%sites_credentials%"
+
+    # service alias override
+    bd_guzzle_site_authenticator.site_config_builder:
+        alias: wallabag_core.guzzle_authenticator.config_builder
+
+    wallabag_core.guzzle.http_client_factory:
+        class: Wallabag\CoreBundle\Helper\HttpClientFactory
+        arguments:
+            - "@bd_guzzle_site_authenticator.authenticator_subscriber"
+            - "@wallabag_core.guzzle.cookie_jar"
+            - '@=service(''craue_config'').get(''restricted_access'')'
+
+    wallabag_core.guzzle.cookie_jar:
+        class: GuzzleHttp\Cookie\FileCookieJar
+        arguments: ["%kernel.cache_dir%/cookiejar.json"]
+
     wallabag_core.content_proxy:
         class: Wallabag\CoreBundle\Helper\ContentProxy
         arguments:
diff --git a/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php b/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php
new file mode 100644 (file)
index 0000000..aee6725
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+
+namespace Tests\Wallabag\CoreBundle\GuzzleSiteAuthenticator;
+
+use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfig;
+use Graby\SiteConfig\SiteConfig as GrabySiteConfig;
+use PHPUnit_Framework_TestCase;
+use Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder;
+
+class GrabySiteConfigBuilderTest extends PHPUnit_Framework_TestCase
+{
+    /** @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://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('example.com')
+            ->will($this->returnValue($grabySiteConfig));
+
+        $this->builder = new GrabySiteConfigBuilder(
+            $grabyConfigBuilderMock,
+            ['example.com' => ['username' => 'foo', 'password' => 'bar']]
+        );
+
+        $config = $this->builder->buildForHost('example.com');
+
+        self::assertEquals(
+            new SiteConfig([
+                'host' => 'example.com',
+                'requiresLogin' => true,
+                'loginUri' => 'http://example.com/login',
+                'usernameField' => 'login',
+                'passwordField' => 'password',
+                'extraFields' => ['field' => 'value'],
+                'notLoggedInXpath' => '//div[@class="need-login"]',
+                'username' => 'foo',
+                'password' => 'bar',
+            ]),
+            $config
+        );
+    }
+
+    public function testBuildConfigDoesntExist()
+    {
+        /* @var \Graby\SiteConfig\ConfigBuilder|\PHPUnit_Framework_MockObject_MockObject */
+        $grabyConfigBuilderMock = $this->getMockBuilder('\Graby\SiteConfig\ConfigBuilder')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $grabyConfigBuilderMock
+            ->method('buildForHost')
+            ->with('unknown.com')
+            ->will($this->returnValue(new GrabySiteConfig()));
+
+        $this->builder = new GrabySiteConfigBuilder($grabyConfigBuilderMock, []);
+
+        $config = $this->builder->buildForHost('unknown.com');
+
+        self::assertEquals(
+            new SiteConfig([
+                'host' => 'unknown.com',
+                'requiresLogin' => false,
+                'username' => null,
+                'password' => null,
+                'extraFields' => [],
+            ]),
+            $config
+        );
+    }
+}