From f92fcb53ca78cc8822962e676b0db117e1a08aa5 Mon Sep 17 00:00:00 2001
From: Jeremy Benoist
Date: Sun, 4 Dec 2016 13:51:58 +0100
Subject: [PATCH 1/9] Add CRUD for site credentials
---
.../Version20161204115751.php | 56 +++++
.../Controller/SiteCredentialController.php | 138 ++++++++++++
.../CoreBundle/Entity/SiteCredential.php | 197 ++++++++++++++++++
.../Form/Type/SiteCredentialType.php | 43 ++++
.../Repository/SiteCredentialRepository.php | 13 ++
.../Resources/translations/messages.da.yml | 25 +++
.../Resources/translations/messages.de.yml | 25 +++
.../Resources/translations/messages.en.yml | 25 +++
.../Resources/translations/messages.es.yml | 25 +++
.../Resources/translations/messages.fa.yml | 25 +++
.../Resources/translations/messages.fr.yml | 31 ++-
.../Resources/translations/messages.it.yml | 25 +++
.../Resources/translations/messages.oc.yml | 25 +++
.../Resources/translations/messages.pl.yml | 25 +++
.../Resources/translations/messages.pt.yml | 25 +++
.../Resources/translations/messages.ro.yml | 25 +++
.../Resources/translations/messages.tr.yml | 5 +
.../baggy/SiteCredential/edit.html.twig | 60 ++++++
.../baggy/SiteCredential/index.html.twig | 44 ++++
.../themes/baggy/SiteCredential/new.html.twig | 53 +++++
.../themes/material/Config/index.html.twig | 20 +-
.../material/SiteCredential/edit.html.twig | 60 ++++++
.../material/SiteCredential/index.html.twig | 44 ++++
.../material/SiteCredential/new.html.twig | 53 +++++
24 files changed, 1054 insertions(+), 13 deletions(-)
create mode 100644 app/DoctrineMigrations/Version20161204115751.php
create mode 100644 src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
create mode 100644 src/Wallabag/CoreBundle/Entity/SiteCredential.php
create mode 100644 src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php
create mode 100644 src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
create mode 100644 src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/edit.html.twig
create mode 100644 src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig
create mode 100644 src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig
create mode 100644 src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/edit.html.twig
create mode 100644 src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/index.html.twig
create mode 100644 src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/new.html.twig
diff --git a/app/DoctrineMigrations/Version20161204115751.php b/app/DoctrineMigrations/Version20161204115751.php
new file mode 100644
index 000000000..97635fa73
--- /dev/null
+++ b/app/DoctrineMigrations/Version20161204115751.php
@@ -0,0 +1,56 @@
+container = $container;
+ }
+
+ private function getTable($tableName)
+ {
+ return $this->container->getParameter('database_table_prefix').$tableName;
+ }
+
+ /**
+ * @param Schema $schema
+ */
+ public function up(Schema $schema)
+ {
+ $this->skipIf($schema->hasTable($this->getTable('site_credential')), 'It seems that you already played this migration.');
+
+ $table = $schema->createTable($this->getTable('site_credential'));
+ $table->addColumn('id', 'integer', ['autoincrement' => true]);
+ $table->addColumn('user_id', 'integer');
+ $table->addColumn('host', 'string', ['length' => 255]);
+ $table->addColumn('username', 'string', ['length' => 255]);
+ $table->addColumn('password', 'string', ['length' => 255]);
+ $table->addColumn('createdAt', 'datetime');
+ $table->addIndex(['user_id'], 'idx_user');
+ $table->setPrimaryKey(['id']);
+ $table->addForeignKeyConstraint($this->getTable('user'), ['user_id'], ['id'], [], 'fk_user');
+ }
+
+ /**
+ * @param Schema $schema
+ */
+ public function down(Schema $schema)
+ {
+ $schema->dropTable($this->getTable('site_credential'));
+ }
+}
diff --git a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
new file mode 100644
index 000000000..e7e438002
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
@@ -0,0 +1,138 @@
+getDoctrine()->getManager();
+
+ $credentials = $em->getRepository('WallabagCoreBundle:SiteCredential')->findAll();
+
+ return $this->render('WallabagCoreBundle:SiteCredential:index.html.twig', array(
+ 'credentials' => $credentials,
+ ));
+ }
+
+ /**
+ * Creates a new site credential entity.
+ *
+ * @Route("/site-credential/new", name="site_credential_new")
+ * @Method({"GET", "POST"})
+ */
+ public function newAction(Request $request)
+ {
+ $credential = new SiteCredential($this->getUser());
+
+ $form = $this->createForm('Wallabag\CoreBundle\Form\Type\SiteCredentialType', $credential);
+ $form->handleRequest($request);
+
+ if ($form->isSubmitted() && $form->isValid()) {
+ $em = $this->getDoctrine()->getManager();
+ $em->persist($credential);
+ $em->flush($credential);
+
+ $this->get('session')->getFlashBag()->add(
+ 'notice',
+ $this->get('translator')->trans('flashes.site_credential.notice.added', ['%host%' => $credential->getHost()])
+ );
+
+ return $this->redirectToRoute('site_credential_edit', array('id' => $credential->getId()));
+ }
+
+ return $this->render('WallabagCoreBundle:SiteCredential:new.html.twig', array(
+ 'credential' => $credential,
+ 'form' => $form->createView(),
+ ));
+ }
+
+ /**
+ * Displays a form to edit an existing site credential entity.
+ *
+ * @Route("/site-credential/{id}/edit", name="site_credential_edit")
+ * @Method({"GET", "POST"})
+ */
+ public function editAction(Request $request, SiteCredential $siteCredential)
+ {
+ $deleteForm = $this->createDeleteForm($siteCredential);
+ $editForm = $this->createForm('Wallabag\CoreBundle\Form\Type\SiteCredentialType', $siteCredential);
+ $editForm->handleRequest($request);
+
+ if ($editForm->isSubmitted() && $editForm->isValid()) {
+ $em = $this->getDoctrine()->getManager();
+ $em->persist($siteCredential);
+ $em->flush();
+
+ $this->get('session')->getFlashBag()->add(
+ 'notice',
+ $this->get('translator')->trans('flashes.site_credential.notice.updated', ['%host%' => $siteCredential->getHost()])
+ );
+
+ return $this->redirectToRoute('site_credential_edit', array('id' => $siteCredential->getId()));
+ }
+
+ return $this->render('WallabagCoreBundle:SiteCredential:edit.html.twig', array(
+ 'credential' => $siteCredential,
+ 'edit_form' => $editForm->createView(),
+ 'delete_form' => $deleteForm->createView(),
+ ));
+ }
+
+ /**
+ * Deletes a site credential entity.
+ *
+ * @Route("/site-credential/{id}", name="site_credential_delete")
+ * @Method("DELETE")
+ */
+ public function deleteAction(Request $request, SiteCredential $siteCredential)
+ {
+ $form = $this->createDeleteForm($siteCredential);
+ $form->handleRequest($request);
+
+ if ($form->isSubmitted() && $form->isValid()) {
+ $this->get('session')->getFlashBag()->add(
+ 'notice',
+ $this->get('translator')->trans('flashes.site_credential.notice.deleted', ['%host%' => $siteCredential->getHost()])
+ );
+
+ $em = $this->getDoctrine()->getManager();
+ $em->remove($siteCredential);
+ $em->flush();
+ }
+
+ return $this->redirectToRoute('site_credential_index');
+ }
+
+ /**
+ * Creates a form to delete a site credential entity.
+ *
+ * @param SiteCredential $siteCredential The site credential entity
+ *
+ * @return \Symfony\Component\Form\Form The form
+ */
+ private function createDeleteForm(SiteCredential $siteCredential)
+ {
+ return $this->createFormBuilder()
+ ->setAction($this->generateUrl('site_credential_delete', array('id' => $siteCredential->getId())))
+ ->setMethod('DELETE')
+ ->getForm()
+ ;
+ }
+}
diff --git a/src/Wallabag/CoreBundle/Entity/SiteCredential.php b/src/Wallabag/CoreBundle/Entity/SiteCredential.php
new file mode 100644
index 000000000..85ee07d4a
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Entity/SiteCredential.php
@@ -0,0 +1,197 @@
+user = $user;
+ }
+
+ /**
+ * Get id.
+ *
+ * @return int
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Set host.
+ *
+ * @param string $host
+ *
+ * @return SiteCredential
+ */
+ public function setHost($host)
+ {
+ $this->host = $host;
+
+ return $this;
+ }
+
+ /**
+ * Get host.
+ *
+ * @return string
+ */
+ public function getHost()
+ {
+ return $this->host;
+ }
+
+ /**
+ * Set username.
+ *
+ * @param string $username
+ *
+ * @return SiteCredential
+ */
+ public function setUsername($username)
+ {
+ $this->username = $username;
+
+ return $this;
+ }
+
+ /**
+ * Get username.
+ *
+ * @return string
+ */
+ public function getUsername()
+ {
+ return $this->username;
+ }
+
+ /**
+ * Set password.
+ *
+ * @param string $password
+ *
+ * @return SiteCredential
+ */
+ public function setPassword($password)
+ {
+ $this->password = $password;
+
+ return $this;
+ }
+
+ /**
+ * Get password.
+ *
+ * @return string
+ */
+ public function getPassword()
+ {
+ return $this->password;
+ }
+
+ /**
+ * Set createdAt.
+ *
+ * @param \DateTime $createdAt
+ *
+ * @return SiteCredential
+ */
+ public function setCreatedAt($createdAt)
+ {
+ $this->createdAt = $createdAt;
+
+ return $this;
+ }
+
+ /**
+ * Get createdAt.
+ *
+ * @return \DateTime
+ */
+ public function getCreatedAt()
+ {
+ return $this->createdAt;
+ }
+
+ /**
+ * @return User
+ */
+ public function getUser()
+ {
+ return $this->user;
+ }
+
+ /**
+ * @ORM\PrePersist
+ */
+ public function timestamps()
+ {
+ if (is_null($this->createdAt)) {
+ $this->createdAt = new \DateTime();
+ }
+ }
+}
diff --git a/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php b/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php
new file mode 100644
index 000000000..9db7c155d
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php
@@ -0,0 +1,43 @@
+add('host', TextType::class, [
+ 'label' => 'site_credential.form.host_label',
+ ])
+ ->add('username', TextType::class, [
+ 'label' => 'site_credential.form.username_label',
+ ])
+ ->add('password', PasswordType::class, [
+ 'label' => 'site_credential.form.password_label',
+ ])
+ ->add('save', SubmitType::class, [
+ 'label' => 'config.form.save',
+ ])
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults([
+ 'data_class' => 'Wallabag\CoreBundle\Entity\SiteCredential',
+ ]);
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'site_credential';
+ }
+}
diff --git a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
new file mode 100644
index 000000000..501b44396
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
@@ -0,0 +1,13 @@
+
+
+
+
+{% endblock %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig
new file mode 100644
index 000000000..fda60b31f
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig
@@ -0,0 +1,44 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'site_credential.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+
+
+{% endblock %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig
new file mode 100644
index 000000000..bf713902a
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig
@@ -0,0 +1,53 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'site_credential.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+
+
+{% endblock %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
index 9b0816eb5..1e10bf38a 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
@@ -66,13 +66,13 @@
-
-
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/new.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/new.html.twig
index bf713902a..3c008cdec 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/new.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/new.html.twig
@@ -42,7 +42,7 @@
{{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{{ form_rest(form) }}
-
{{ 'site_credential.form.back_to_list'|trans }}
+
{{ 'site_credential.form.back_to_list'|trans }}
From 5a9bc00726ddaf7c8798d4932d0a8b7a38422670 Mon Sep 17 00:00:00 2001
From: Jeremy Benoist
Date: Mon, 1 May 2017 22:13:17 +0200
Subject: [PATCH 3/9] Retrieve username/password from database
Inject the current user & the repo to retrieve username/password from the database
---
app/config/parameters.yml.dist | 3 --
.../GrabySiteConfigBuilder.php | 32 +++++++++++++------
.../Repository/SiteCredentialRepository.php | 18 +++++++++++
.../CoreBundle/Resources/config/services.yml | 9 +++++-
4 files changed, 49 insertions(+), 13 deletions(-)
diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist
index 914fb1efc..b3fe11c87 100644
--- a/app/config/parameters.yml.dist
+++ b/app/config/parameters.yml.dist
@@ -60,6 +60,3 @@ parameters:
redis_port: 6379
redis_path: null
redis_password: null
-
- # sites credentials
- sites_credentials: {}
diff --git a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
index 1c56fa9f4..94615687e 100644
--- a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
+++ b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
@@ -6,6 +6,8 @@ use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfig;
use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfigBuilder;
use Graby\SiteConfig\ConfigBuilder;
use Psr\Log\LoggerInterface;
+use Wallabag\CoreBundle\Repository\SiteCredentialRepository;
+use Wallabag\UserBundle\Entity\User;
class GrabySiteConfigBuilder implements SiteConfigBuilder
{
@@ -13,26 +15,36 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
* @var ConfigBuilder
*/
private $grabyConfigBuilder;
+
/**
- * @var array
+ * @var SiteCredentialRepository
*/
- private $credentials;
+ private $credentialRepository;
+
/**
* @var LoggerInterface
*/
private $logger;
+ /**
+ * @var User
+ */
+ private $currentUser;
+
+
/**
* GrabySiteConfigBuilder constructor.
*
- * @param ConfigBuilder $grabyConfigBuilder
- * @param array $credentials
+ * @param ConfigBuilder $grabyConfigBuilder
+ * @param User $currentUser
+ * @param SiteCredentialRepository $credentialRepository
* @param LoggerInterface $logger
*/
- public function __construct(ConfigBuilder $grabyConfigBuilder, array $credentials, LoggerInterface $logger)
+ public function __construct(ConfigBuilder $grabyConfigBuilder, User $currentUser, SiteCredentialRepository $credentialRepository, LoggerInterface $logger)
{
$this->grabyConfigBuilder = $grabyConfigBuilder;
- $this->credentials = $credentials;
+ $this->credentialRepository = $credentialRepository;
+ $this->currentUser = $currentUser;
$this->logger = $logger;
}
@@ -47,7 +59,9 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
$host = substr($host, 4);
}
- if (empty($this->credentials[$host])) {
+ $credentials = $this->credentialRepository->findOneByHostAndUser($host, $this->currentUser->getId());
+
+ if (null === $credentials) {
$this->logger->debug('Auth: no credentials available for host.', ['host' => $host]);
return false;
@@ -62,8 +76,8 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
'passwordField' => $config->login_password_field ?: null,
'extraFields' => $this->processExtraFields($config->login_extra_fields),
'notLoggedInXpath' => $config->not_logged_in_xpath ?: null,
- 'username' => $this->credentials[$host]['username'],
- 'password' => $this->credentials[$host]['password'],
+ 'username' => $credentials['username'],
+ 'password' => $credentials['password'],
];
$config = new SiteConfig($parameters);
diff --git a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
index 88aee6d58..316ecc750 100644
--- a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
@@ -7,4 +7,22 @@ namespace Wallabag\CoreBundle\Repository;
*/
class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository
{
+ /**
+ * Retrieve one username/password for the given host and userId.
+ *
+ * @param string $host
+ * @param int $userId
+ *
+ * @return null|array
+ */
+ public function findOneByHostAndUser($host, $userId)
+ {
+ return $this->createQueryBuilder('s')
+ ->select('s.username', 's.password')
+ ->where('s.host = :hostname')->setParameter('hostname', $host)
+ ->andWhere('s.user = :userId')->setParameter('userId', $userId)
+ ->setMaxResults(1)
+ ->getQuery()
+ ->getOneOrNullResult();
+ }
}
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index 4be795470..a59152d35 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -63,7 +63,8 @@ services:
class: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder
arguments:
- "@wallabag_core.graby.config_builder"
- - "%sites_credentials%"
+ - "@=service('security.token_storage').getToken().getUser()"
+ - "@wallabag_core.site_credential_repository"
- '@logger'
tags:
- { name: monolog.logger, channel: graby }
@@ -120,6 +121,12 @@ services:
arguments:
- WallabagCoreBundle:Tag
+ wallabag_core.site_credential_repository:
+ class: Wallabag\CoreBundle\Repository\SiteCredentialRepository
+ factory: [ "@doctrine.orm.default_entity_manager", getRepository ]
+ arguments:
+ - WallabagCoreBundle:SiteCredential
+
wallabag_core.helper.entries_export:
class: Wallabag\CoreBundle\Helper\EntriesExport
arguments:
From b8427f22f06cab58383ec3080f09715c712c65ef Mon Sep 17 00:00:00 2001
From: Jeremy Benoist
Date: Mon, 1 May 2017 22:13:35 +0200
Subject: [PATCH 4/9] Add menu access to site credentials CRUD
---
.../ORM/LoadSiteCredentialData.php | 34 +++++
.../GrabySiteConfigBuilder.php | 18 ++-
.../CoreBundle/Resources/config/services.yml | 2 +-
.../Resources/translations/messages.da.yml | 1 +
.../Resources/translations/messages.de.yml | 1 +
.../Resources/translations/messages.en.yml | 1 +
.../Resources/translations/messages.es.yml | 1 +
.../Resources/translations/messages.fa.yml | 1 +
.../Resources/translations/messages.fr.yml | 1 +
.../Resources/translations/messages.it.yml | 1 +
.../Resources/translations/messages.oc.yml | 1 +
.../Resources/translations/messages.pl.yml | 1 +
.../Resources/translations/messages.pt.yml | 1 +
.../Resources/translations/messages.ro.yml | 1 +
.../Resources/translations/messages.tr.yml | 1 +
.../baggy/SiteCredential/edit.html.twig | 2 +-
.../baggy/SiteCredential/index.html.twig | 4 +-
.../themes/baggy/SiteCredential/new.html.twig | 2 +-
.../views/themes/baggy/layout.html.twig | 3 +
.../views/themes/material/layout.html.twig | 5 +
.../SiteCredentialControllerTest.php | 140 ++++++++++++++++++
.../GrabySiteConfigBuilderTest.php | 50 ++++++-
22 files changed, 258 insertions(+), 14 deletions(-)
create mode 100644 src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSiteCredentialData.php
create mode 100644 tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php
diff --git a/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSiteCredentialData.php b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSiteCredentialData.php
new file mode 100644
index 000000000..866f55a40
--- /dev/null
+++ b/src/Wallabag/CoreBundle/DataFixtures/ORM/LoadSiteCredentialData.php
@@ -0,0 +1,34 @@
+getReference('admin-user'));
+ $credential->setHost('example.com');
+ $credential->setUsername('foo');
+ $credential->setPassword('bar');
+
+ $manager->persist($credential);
+
+ $manager->flush();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getOrder()
+ {
+ return 50;
+ }
+}
diff --git a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
index 94615687e..ae69492d4 100644
--- a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
+++ b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
@@ -7,7 +7,7 @@ use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfigBuilder;
use Graby\SiteConfig\ConfigBuilder;
use Psr\Log\LoggerInterface;
use Wallabag\CoreBundle\Repository\SiteCredentialRepository;
-use Wallabag\UserBundle\Entity\User;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
class GrabySiteConfigBuilder implements SiteConfigBuilder
{
@@ -27,7 +27,7 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
private $logger;
/**
- * @var User
+ * @var Wallabag\UserBundle\Entity\User|null
*/
private $currentUser;
@@ -36,16 +36,19 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
* GrabySiteConfigBuilder constructor.
*
* @param ConfigBuilder $grabyConfigBuilder
- * @param User $currentUser
+ * @param TokenStorage $token
* @param SiteCredentialRepository $credentialRepository
* @param LoggerInterface $logger
*/
- public function __construct(ConfigBuilder $grabyConfigBuilder, User $currentUser, SiteCredentialRepository $credentialRepository, LoggerInterface $logger)
+ public function __construct(ConfigBuilder $grabyConfigBuilder, TokenStorage $token, SiteCredentialRepository $credentialRepository, LoggerInterface $logger)
{
$this->grabyConfigBuilder = $grabyConfigBuilder;
$this->credentialRepository = $credentialRepository;
- $this->currentUser = $currentUser;
$this->logger = $logger;
+
+ if ($token->getToken()) {
+ $this->currentUser = $token->getToken()->getUser();
+ }
}
/**
@@ -59,7 +62,10 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
$host = substr($host, 4);
}
- $credentials = $this->credentialRepository->findOneByHostAndUser($host, $this->currentUser->getId());
+ $credentials = null;
+ if ($this->currentUser) {
+ $credentials = $this->credentialRepository->findOneByHostAndUser($host, $this->currentUser->getId());
+ }
if (null === $credentials) {
$this->logger->debug('Auth: no credentials available for host.', ['host' => $host]);
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index a59152d35..09bc77fe9 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -63,7 +63,7 @@ services:
class: Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder
arguments:
- "@wallabag_core.graby.config_builder"
- - "@=service('security.token_storage').getToken().getUser()"
+ - "@security.token_storage"
- "@wallabag_core.site_credential_repository"
- '@logger'
tags:
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
index ef58a16b8..3a3fb91d8 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
@@ -32,6 +32,7 @@ menu:
# save_link: 'Save a link'
back_to_unread: 'Tilbage til de ulæste artikler'
# users_management: 'Users management'
+ # site_credentials: 'Site credentials'
top:
add_new_entry: 'Tilføj ny artikel'
search: 'Søg'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
index d026a030b..85f0e1a35 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
@@ -32,6 +32,7 @@ menu:
save_link: 'Link speichern'
back_to_unread: 'Zurück zu ungelesenen Artikeln'
users_management: 'Benutzerverwaltung'
+ # site_credentials: 'Site credentials'
top:
add_new_entry: 'Neuen Artikel hinzufügen'
search: 'Suche'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
index 12feb7dd4..284fa2fb8 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
@@ -32,6 +32,7 @@ menu:
save_link: 'Save a link'
back_to_unread: 'Back to unread articles'
users_management: 'Users management'
+ site_credentials: 'Site credentials'
top:
add_new_entry: 'Add a new entry'
search: 'Search'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
index 2351d467f..33bb879c6 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
@@ -32,6 +32,7 @@ menu:
save_link: 'Guardar un enlace'
back_to_unread: 'Volver a los artículos sin leer'
users_management: 'Configuración de usuarios'
+ # site_credentials: 'Site credentials'
top:
add_new_entry: 'Añadir un nuevo artículo'
search: 'Buscar'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
index 32e1ff42a..90eb119c1 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
@@ -32,6 +32,7 @@ menu:
save_link: 'ذخیرهٔ یک پیوند'
back_to_unread: 'بازگشت به خواندهنشدهها'
# users_management: 'Users management'
+ # site_credentials: 'Site credentials'
top:
add_new_entry: 'افزودن مقالهٔ تازه'
search: 'جستجو'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
index 17eaf0150..542ddf486 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -32,6 +32,7 @@ menu:
save_link: "Sauvegarder un nouvel article"
back_to_unread: "Retour aux articles non lus"
users_management: "Gestion des utilisateurs"
+ site_credentials: 'Accès aux sites'
top:
add_new_entry: "Sauvegarder un nouvel article"
search: "Rechercher"
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
index 752085c80..5cb2a68f7 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
@@ -32,6 +32,7 @@ menu:
save_link: 'Salva collegamento'
back_to_unread: 'Torna ai contenuti non letti'
# users_management: 'Users management'
+ # site_credentials: 'Site credentials'
top:
add_new_entry: 'Aggiungi un nuovo contenuto'
search: 'Cerca'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
index 9e941de0a..bc11b2a49 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
@@ -32,6 +32,7 @@ menu:
save_link: 'Enregistrar un novèl article'
back_to_unread: 'Tornar als articles pas legits'
users_management: 'Gestion dels utilizaires'
+ # site_credentials: 'Site credentials'
top:
add_new_entry: 'Enregistrar un novèl article'
search: 'Cercar'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
index 38e051f58..033d6ac55 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
@@ -32,6 +32,7 @@ menu:
save_link: 'Zapisz link'
back_to_unread: 'Powrót do nieprzeczytanych artykułów'
users_management: 'Zarządzanie użytkownikami'
+ # site_credentials: 'Site credentials'
top:
add_new_entry: 'Dodaj nowy wpis'
search: 'Szukaj'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
index d3b245b83..c70c24961 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
@@ -32,6 +32,7 @@ menu:
save_link: 'Salvar um link'
back_to_unread: 'Voltar para os artigos não lidos'
users_management: 'Gestão de Usuários'
+ # site_credentials: 'Site credentials'
top:
add_new_entry: 'Adicionar uma nova entrada'
search: 'Pesquisa'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
index 66c724299..a5dc44f02 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
@@ -32,6 +32,7 @@ menu:
# save_link: 'Save a link'
back_to_unread: 'Înapoi la articolele necitite'
# users_management: 'Users management'
+ # site_credentials: 'Site credentials'
top:
add_new_entry: 'Introdu un nou articol'
search: 'Căutare'
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
index 34ae5b877..4d01e7f75 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
@@ -32,6 +32,7 @@ menu:
# save_link: 'Save a link'
back_to_unread: 'Okunmayan makalelere geri dön'
# users_management: 'Users management'
+ # site_credentials: 'Site credentials'
top:
add_new_entry: 'Yeni bir makale ekle'
search: 'Ara'
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/edit.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/edit.html.twig
index 8448f17ec..882be430f 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/edit.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/edit.html.twig
@@ -49,7 +49,7 @@
{{ form_end(delete_form) }}
- {{ 'site_credential.form.back_to_list'|trans }}
+ {{ 'site_credential.form.back_to_list'|trans }}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig
index fda60b31f..c128bcebd 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig
@@ -25,7 +25,7 @@
{{ credential.host }} |
{{ credential.username }} |
- {{ 'site_credential.list.edit_action'|trans }}
+ {{ 'site_credential.list.edit_action'|trans }}
|
{% endfor %}
@@ -33,7 +33,7 @@
- {{ 'site_credential.list.create_new_one'|trans }}
+ {{ 'site_credential.list.create_new_one'|trans }}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig
index bf713902a..3c008cdec 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/new.html.twig
@@ -42,7 +42,7 @@
{{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
{{ form_rest(form) }}
- {{ 'site_credential.form.back_to_list'|trans }}
+ {{ 'site_credential.form.back_to_list'|trans }}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig
index 42aeace93..17fa13bb5 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig
@@ -38,6 +38,9 @@
{{ render(controller("WallabagCoreBundle:Entry:searchForm", {'currentRoute': app.request.attributes.get('_route')})) }}
+ {% if craue_setting('restricted_access') %}
+
+ {% endif %}
{% if is_granted('ROLE_SUPER_ADMIN') %}
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
index 2dab1c186..60907e11a 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
@@ -66,6 +66,11 @@
{{ 'menu.left.config'|trans }}
+ {% if craue_setting('restricted_access') %}
+
+ {{ 'menu.left.site_credentials'|trans }}
+
+ {% endif %}
{% if is_granted('ROLE_SUPER_ADMIN') %}
{{ 'menu.left.users_management'|trans }}
diff --git a/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php b/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php
new file mode 100644
index 000000000..47bf0907a
--- /dev/null
+++ b/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php
@@ -0,0 +1,140 @@
+logInAs('admin');
+ $client = $this->getClient();
+
+ $crawler = $client->request('GET', '/site-credentials/');
+
+ $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+ $body = $crawler->filter('body')->extract(['_text'])[0];
+
+ $this->assertContains('site_credential.description', $body);
+ $this->assertContains('site_credential.list.create_new_one', $body);
+ }
+
+ public function testNewSiteCredential()
+ {
+ $this->logInAs('admin');
+ $client = $this->getClient();
+
+ $crawler = $client->request('GET', '/site-credentials/new');
+
+ $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+ $body = $crawler->filter('body')->extract(['_text'])[0];
+
+ $this->assertContains('site_credential.new_site_credential', $body);
+ $this->assertContains('site_credential.form.back_to_list', $body);
+
+ $form = $crawler->filter('button[id=site_credential_save]')->form();
+
+ $data = [
+ 'site_credential[host]' => 'google.io',
+ 'site_credential[username]' => 'sergei',
+ 'site_credential[password]' => 'microsoft',
+ ];
+
+ $client->submit($form, $data);
+
+ $this->assertEquals(302, $client->getResponse()->getStatusCode());
+
+ $crawler = $client->followRedirect();
+
+ $this->assertContains('flashes.site_credential.notice.added', $crawler->filter('body')->extract(['_text'])[0]);
+ }
+
+ /**
+ * @depends testNewSiteCredential
+ */
+ public function testEditSiteCredential()
+ {
+ $this->logInAs('admin');
+ $client = $this->getClient();
+
+ $credential = $client->getContainer()
+ ->get('doctrine.orm.entity_manager')
+ ->getRepository('WallabagCoreBundle:SiteCredential')
+ ->findOneByHost('google.io');
+
+ $crawler = $client->request('GET', '/site-credentials/'.$credential->getId().'/edit');
+
+ $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+ $body = $crawler->filter('body')->extract(['_text'])[0];
+
+ $this->assertContains('site_credential.edit_site_credential', $body);
+ $this->assertContains('site_credential.form.back_to_list', $body);
+
+ $form = $crawler->filter('button[id=site_credential_save]')->form();
+
+ $data = [
+ 'site_credential[host]' => 'google.io',
+ 'site_credential[username]' => 'larry',
+ 'site_credential[password]' => 'microsoft',
+ ];
+
+ $client->submit($form, $data);
+
+ $this->assertEquals(302, $client->getResponse()->getStatusCode());
+
+ $crawler = $client->followRedirect();
+
+ $this->assertContains('flashes.site_credential.notice.updated', $crawler->filter('body')->extract(['_text'])[0]);
+ $this->assertContains('larry', $crawler->filter('input[id=site_credential_username]')->attr('value'));
+ }
+
+ /**
+ * @depends testNewSiteCredential
+ */
+ public function testEditFromADifferentUserSiteCredential()
+ {
+ $this->logInAs('bob');
+ $client = $this->getClient();
+
+ $credential = $client->getContainer()
+ ->get('doctrine.orm.entity_manager')
+ ->getRepository('WallabagCoreBundle:SiteCredential')
+ ->findOneByHost('google.io');
+
+ $client->request('GET', '/site-credentials/'.$credential->getId().'/edit');
+
+ $this->assertEquals(403, $client->getResponse()->getStatusCode());
+ }
+
+ /**
+ * @depends testNewSiteCredential
+ */
+ public function testDeleteSiteCredential()
+ {
+ $this->logInAs('admin');
+ $client = $this->getClient();
+
+ $credential = $client->getContainer()
+ ->get('doctrine.orm.entity_manager')
+ ->getRepository('WallabagCoreBundle:SiteCredential')
+ ->findOneByHost('google.io');
+
+ $crawler = $client->request('GET', '/site-credentials/'.$credential->getId().'/edit');
+
+ $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+ $deleteForm = $crawler->filter('body')->selectButton('site_credential.form.delete')->form();
+
+ $client->submit($deleteForm, []);
+
+ $this->assertEquals(302, $client->getResponse()->getStatusCode());
+
+ $crawler = $client->followRedirect();
+
+ $this->assertContains('flashes.site_credential.notice.deleted', $crawler->filter('body')->extract(['_text'])[0]);
+ }
+}
diff --git a/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php b/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php
index 8b50bce98..980f75793 100644
--- a/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php
+++ b/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php
@@ -8,6 +8,8 @@ use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfig;
use Graby\SiteConfig\SiteConfig as GrabySiteConfig;
use PHPUnit_Framework_TestCase;
use Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder;
+use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
class GrabySiteConfigBuilderTest extends PHPUnit_Framework_TestCase
{
@@ -17,7 +19,7 @@ class GrabySiteConfigBuilderTest extends PHPUnit_Framework_TestCase
public function testBuildConfigExists()
{
/* @var \Graby\SiteConfig\ConfigBuilder|\PHPUnit_Framework_MockObject_MockObject */
- $grabyConfigBuilderMock = $this->getMockBuilder('\Graby\SiteConfig\ConfigBuilder')
+ $grabyConfigBuilderMock = $this->getMockBuilder('Graby\SiteConfig\ConfigBuilder')
->disableOriginalConstructor()
->getMock();
@@ -38,9 +40,30 @@ class GrabySiteConfigBuilderTest extends PHPUnit_Framework_TestCase
$handler = new TestHandler();
$logger->pushHandler($handler);
+ $siteCrentialRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\SiteCredentialRepository')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $siteCrentialRepo->expects($this->once())
+ ->method('findOneByHostAndUser')
+ ->with('example.com', 1)
+ ->willReturn(['username' => 'foo', 'password' => 'bar']);
+
+ $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);
+
$this->builder = new GrabySiteConfigBuilder(
$grabyConfigBuilderMock,
- ['example.com' => ['username' => 'foo', 'password' => 'bar']],
+ $tokenStorage,
+ $siteCrentialRepo,
$logger
);
@@ -82,9 +105,30 @@ class GrabySiteConfigBuilderTest extends PHPUnit_Framework_TestCase
$handler = new TestHandler();
$logger->pushHandler($handler);
+ $siteCrentialRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\SiteCredentialRepository')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $siteCrentialRepo->expects($this->once())
+ ->method('findOneByHostAndUser')
+ ->with('unknown.com', 1)
+ ->willReturn(null);
+
+ $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);
+
$this->builder = new GrabySiteConfigBuilder(
$grabyConfigBuilderMock,
- [],
+ $tokenStorage,
+ $siteCrentialRepo,
$logger
);
From fd7fde95159828960784a438c4b4da147e20ab18 Mon Sep 17 00:00:00 2001
From: Jeremy Benoist
Date: Tue, 2 May 2017 08:38:22 +0200
Subject: [PATCH 5/9] Force sequence creation for postgresql
---
...Version20161204115751.php => Version20170501115751.php} | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
rename app/DoctrineMigrations/{Version20161204115751.php => Version20170501115751.php} (86%)
diff --git a/app/DoctrineMigrations/Version20161204115751.php b/app/DoctrineMigrations/Version20170501115751.php
similarity index 86%
rename from app/DoctrineMigrations/Version20161204115751.php
rename to app/DoctrineMigrations/Version20170501115751.php
index 97635fa73..846a87b5c 100644
--- a/app/DoctrineMigrations/Version20161204115751.php
+++ b/app/DoctrineMigrations/Version20170501115751.php
@@ -10,7 +10,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Add site credential table to store username & password for some website (behind authentication or paywall)
*/
-class Version20161204115751 extends AbstractMigration implements ContainerAwareInterface
+class Version20170501115751 extends AbstractMigration implements ContainerAwareInterface
{
/**
* @var ContainerInterface
@@ -44,6 +44,11 @@ class Version20161204115751 extends AbstractMigration implements ContainerAwareI
$table->addIndex(['user_id'], 'idx_user');
$table->setPrimaryKey(['id']);
$table->addForeignKeyConstraint($this->getTable('user'), ['user_id'], ['id'], [], 'fk_user');
+
+ if ('postgresql' === $this->connection->getDatabasePlatform()->getName()) {
+ $schema->dropSequence('site_credential_id_seq');
+ $schema->createSequence('site_credential_id_seq');
+ }
}
/**
From 9de9f1e5ceed4ac7ecd27e1cb808e630a831f94b Mon Sep 17 00:00:00 2001
From: Jeremy Benoist
Date: Wed, 3 May 2017 10:23:49 +0200
Subject: [PATCH 6/9] Add a live test for restricted article
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
It is not aimed to test if we can get the full article (since we aren't using real login/password)
but mostly to test the full work (with authentication, etc.)
Do not clean fixtured to avoid SQLite to re-use id for entry tag relation 😓
---
.../Controller/SiteCredentialController.php | 4 +-
.../GrabySiteConfigBuilder.php | 5 +-
.../Controller/EntryControllerTest.php | 53 +++++++++++++++++++
.../SiteCredentialControllerTest.php | 44 +++++++--------
.../GrabySiteConfigBuilderTest.php | 6 +--
5 files changed, 81 insertions(+), 31 deletions(-)
diff --git a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
index 429f529ab..dc8e723da 100644
--- a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
+++ b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
@@ -24,9 +24,7 @@ class SiteCredentialController extends Controller
*/
public function indexAction()
{
- $em = $this->getDoctrine()->getManager();
-
- $credentials = $em->getRepository('WallabagCoreBundle:SiteCredential')->findByUser($this->getUser());
+ $credentials = $this->get('wallabag_core.site_credential_repository')->findByUser($this->getUser());
return $this->render('WallabagCoreBundle:SiteCredential:index.html.twig', array(
'credentials' => $credentials,
diff --git a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
index ae69492d4..62a3bc131 100644
--- a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
+++ b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
@@ -31,14 +31,13 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
*/
private $currentUser;
-
/**
* GrabySiteConfigBuilder constructor.
*
* @param ConfigBuilder $grabyConfigBuilder
- * @param TokenStorage $token
+ * @param TokenStorage $token
* @param SiteCredentialRepository $credentialRepository
- * @param LoggerInterface $logger
+ * @param LoggerInterface $logger
*/
public function __construct(ConfigBuilder $grabyConfigBuilder, TokenStorage $token, SiteCredentialRepository $credentialRepository, LoggerInterface $logger)
{
diff --git a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
index 8f5c372d8..104f60f17 100644
--- a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
+++ b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
@@ -5,6 +5,7 @@ namespace Tests\Wallabag\CoreBundle\Controller;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
use Wallabag\CoreBundle\Entity\Config;
use Wallabag\CoreBundle\Entity\Entry;
+use Wallabag\CoreBundle\Entity\SiteCredential;
class EntryControllerTest extends WallabagCoreTestCase
{
@@ -1321,4 +1322,56 @@ class EntryControllerTest extends WallabagCoreTestCase
$this->assertEquals($url, $content->getUrl());
$this->assertEquals($expectedLanguage, $content->getLanguage());
}
+
+ /**
+ * This test will require an internet connection.
+ */
+ public function testRestrictedArticle()
+ {
+ $url = 'http://www.monde-diplomatique.fr/2017/05/BONNET/57475';
+ $this->logInAs('admin');
+ $client = $this->getClient();
+ $em = $client->getContainer()->get('doctrine.orm.entity_manager');
+
+ // enable restricted access
+ $client->getContainer()->get('craue_config')->set('restricted_access', 1);
+
+ // create a new site_credential
+ $user = $client->getContainer()->get('security.token_storage')->getToken()->getUser();
+ $credential = new SiteCredential($user);
+ $credential->setHost('monde-diplomatique.fr');
+ $credential->setUsername('foo');
+ $credential->setPassword('bar');
+
+ $em->persist($credential);
+ $em->flush();
+
+ $crawler = $client->request('GET', '/new');
+
+ $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+ $form = $crawler->filter('form[name=entry]')->form();
+
+ $data = [
+ 'entry[url]' => $url,
+ ];
+
+ $client->submit($form, $data);
+
+ $this->assertEquals(302, $client->getResponse()->getStatusCode());
+
+ $crawler = $client->followRedirect();
+
+ $this->assertEquals(200, $client->getResponse()->getStatusCode());
+ $this->assertContains('flashes.entry.notice.entry_saved', $crawler->filter('body')->extract(['_text'])[0]);
+
+ $content = $em
+ ->getRepository('WallabagCoreBundle:Entry')
+ ->findByUrlAndUserId($url, $this->getLoggedInUserId());
+
+ $this->assertInstanceOf('Wallabag\CoreBundle\Entity\Entry', $content);
+ $this->assertSame('Crimes et réformes aux Philippines', $content->getTitle());
+
+ $client->getContainer()->get('craue_config')->set('restricted_access', 0);
+ }
}
diff --git a/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php b/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php
index 47bf0907a..7e6dafee6 100644
--- a/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php
+++ b/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php
@@ -2,7 +2,9 @@
namespace Tests\Wallabag\CoreBundle\Controller;
+use Symfony\Bundle\FrameworkBundle\Client;
use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
+use Wallabag\CoreBundle\Entity\SiteCredential;
class SiteCredentialControllerTest extends WallabagCoreTestCase
{
@@ -52,18 +54,12 @@ class SiteCredentialControllerTest extends WallabagCoreTestCase
$this->assertContains('flashes.site_credential.notice.added', $crawler->filter('body')->extract(['_text'])[0]);
}
- /**
- * @depends testNewSiteCredential
- */
public function testEditSiteCredential()
{
$this->logInAs('admin');
$client = $this->getClient();
- $credential = $client->getContainer()
- ->get('doctrine.orm.entity_manager')
- ->getRepository('WallabagCoreBundle:SiteCredential')
- ->findOneByHost('google.io');
+ $credential = $this->createSiteCredential($client);
$crawler = $client->request('GET', '/site-credentials/'.$credential->getId().'/edit');
@@ -92,36 +88,26 @@ class SiteCredentialControllerTest extends WallabagCoreTestCase
$this->assertContains('larry', $crawler->filter('input[id=site_credential_username]')->attr('value'));
}
- /**
- * @depends testNewSiteCredential
- */
public function testEditFromADifferentUserSiteCredential()
{
- $this->logInAs('bob');
+ $this->logInAs('admin');
$client = $this->getClient();
- $credential = $client->getContainer()
- ->get('doctrine.orm.entity_manager')
- ->getRepository('WallabagCoreBundle:SiteCredential')
- ->findOneByHost('google.io');
+ $credential = $this->createSiteCredential($client);
+
+ $this->logInAs('bob');
$client->request('GET', '/site-credentials/'.$credential->getId().'/edit');
$this->assertEquals(403, $client->getResponse()->getStatusCode());
}
- /**
- * @depends testNewSiteCredential
- */
public function testDeleteSiteCredential()
{
$this->logInAs('admin');
$client = $this->getClient();
- $credential = $client->getContainer()
- ->get('doctrine.orm.entity_manager')
- ->getRepository('WallabagCoreBundle:SiteCredential')
- ->findOneByHost('google.io');
+ $credential = $this->createSiteCredential($client);
$crawler = $client->request('GET', '/site-credentials/'.$credential->getId().'/edit');
@@ -137,4 +123,18 @@ class SiteCredentialControllerTest extends WallabagCoreTestCase
$this->assertContains('flashes.site_credential.notice.deleted', $crawler->filter('body')->extract(['_text'])[0]);
}
+
+ private function createSiteCredential(Client $client)
+ {
+ $credential = new SiteCredential($this->getLoggedInUser());
+ $credential->setHost('google.io');
+ $credential->setUsername('sergei');
+ $credential->setPassword('microsoft');
+
+ $em = $client->getContainer()->get('doctrine.orm.entity_manager');
+ $em->persist($credential);
+ $em->flush();
+
+ return $credential;
+ }
}
diff --git a/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php b/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php
index 980f75793..1e1e8989b 100644
--- a/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php
+++ b/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php
@@ -25,7 +25,7 @@ class GrabySiteConfigBuilderTest extends PHPUnit_Framework_TestCase
$grabySiteConfig = new GrabySiteConfig();
$grabySiteConfig->requires_login = true;
- $grabySiteConfig->login_uri = 'http://example.com/login';
+ $grabySiteConfig->login_uri = 'http://www.example.com/login';
$grabySiteConfig->login_username_field = 'login';
$grabySiteConfig->login_password_field = 'password';
$grabySiteConfig->login_extra_fields = ['field=value'];
@@ -67,13 +67,13 @@ class GrabySiteConfigBuilderTest extends PHPUnit_Framework_TestCase
$logger
);
- $config = $this->builder->buildForHost('example.com');
+ $config = $this->builder->buildForHost('www.example.com');
$this->assertEquals(
new SiteConfig([
'host' => 'example.com',
'requiresLogin' => true,
- 'loginUri' => 'http://example.com/login',
+ 'loginUri' => 'http://www.example.com/login',
'usernameField' => 'login',
'passwordField' => 'password',
'extraFields' => ['field' => 'value'],
From 906424c1b6fd884bf2081bfe6dd0b1f9651c2801 Mon Sep 17 00:00:00 2001
From: Jeremy Benoist
Date: Sun, 11 Jun 2017 23:05:19 +0200
Subject: [PATCH 7/9] Crypt site credential password
---
.gitignore | 1 +
.../Version20170501115751.php | 2 +-
app/config/wallabag.yml | 1 +
composer.json | 5 +-
.../CoreBundle/Command/InstallCommand.php | 2 +
.../Controller/SiteCredentialController.php | 2 +
.../DependencyInjection/Configuration.php | 2 +
.../WallabagCoreExtension.php | 1 +
.../CoreBundle/Entity/SiteCredential.php | 3 +-
.../CoreBundle/Helper/CryptoProxy.php | 86 +++++++++++++++++++
.../Repository/SiteCredentialRepository.php | 20 ++++-
.../CoreBundle/Resources/config/services.yml | 8 ++
.../Controller/EntryControllerTest.php | 2 +-
.../GrabySiteConfigBuilderTest.php | 3 +-
.../CoreBundle/Helper/CryptoProxyTest.php | 40 +++++++++
15 files changed, 169 insertions(+), 9 deletions(-)
create mode 100644 src/Wallabag/CoreBundle/Helper/CryptoProxy.php
create mode 100644 tests/Wallabag/CoreBundle/Helper/CryptoProxyTest.php
diff --git a/.gitignore b/.gitignore
index 709f78cf2..8fd762fa8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,3 +56,4 @@ app/Resources/build/
# Test-generated files
admin-export.json
specialexport.json
+/data/site-credentials-secret-key.txt
diff --git a/app/DoctrineMigrations/Version20170501115751.php b/app/DoctrineMigrations/Version20170501115751.php
index 846a87b5c..2597f1ffd 100644
--- a/app/DoctrineMigrations/Version20170501115751.php
+++ b/app/DoctrineMigrations/Version20170501115751.php
@@ -39,7 +39,7 @@ class Version20170501115751 extends AbstractMigration implements ContainerAwareI
$table->addColumn('user_id', 'integer');
$table->addColumn('host', 'string', ['length' => 255]);
$table->addColumn('username', 'string', ['length' => 255]);
- $table->addColumn('password', 'string', ['length' => 255]);
+ $table->addColumn('password', 'text');
$table->addColumn('createdAt', 'datetime');
$table->addIndex(['user_id'], 'idx_user');
$table->setPrimaryKey(['id']);
diff --git a/app/config/wallabag.yml b/app/config/wallabag.yml
index 51b7e4e30..b45934e4b 100644
--- a/app/config/wallabag.yml
+++ b/app/config/wallabag.yml
@@ -26,6 +26,7 @@ wallabag_core:
fetching_error_message: |
wallabag can't retrieve contents for this article. Please troubleshoot this issue.
api_limit_mass_actions: 10
+ encryption_key_path: "%kernel.root_dir%/../data/site-credentials-secret-key.txt"
default_internal_settings:
-
name: share_public
diff --git a/composer.json b/composer.json
index 0a170c168..7428f688c 100644
--- a/composer.json
+++ b/composer.json
@@ -73,7 +73,7 @@
"kphoen/rulerz-bundle": "~0.13",
"guzzlehttp/guzzle": "^5.3.1",
"doctrine/doctrine-migrations-bundle": "^1.0",
- "paragonie/random_compat": "~1.0",
+ "paragonie/random_compat": "~2.0",
"craue/config-bundle": "~2.0",
"mnapoli/piwik-twig-extension": "^1.0",
"ocramius/proxy-manager": "1.*",
@@ -83,7 +83,8 @@
"javibravo/simpleue": "^1.0",
"symfony/dom-crawler": "^3.1",
"friendsofsymfony/jsrouting-bundle": "^1.6",
- "bdunogier/guzzle-site-authenticator": "^1.0.0@dev"
+ "bdunogier/guzzle-site-authenticator": "^1.0.0@dev",
+ "defuse/php-encryption": "^2.1"
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "~2.2",
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php
index 0f119377f..eb725a59a 100644
--- a/src/Wallabag/CoreBundle/Command/InstallCommand.php
+++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php
@@ -313,6 +313,8 @@ class InstallCommand extends ContainerAwareCommand
$this
->runCommand('doctrine:migrations:migrate', ['--no-interaction' => true]);
+
+ return $this;
}
/**
diff --git a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
index dc8e723da..0bacafb79 100644
--- a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
+++ b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
@@ -45,6 +45,8 @@ class SiteCredentialController extends Controller
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
+ $credential->setPassword($this->get('wallabag_core.helper.crypto_proxy')->crypt($credential->getPassword()));
+
$em = $this->getDoctrine()->getManager();
$em->persist($credential);
$em->flush($credential);
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
index 33df92d3c..a9791f6be 100644
--- a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
+++ b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
@@ -63,6 +63,8 @@ class Configuration implements ConfigurationInterface
->end()
->end()
->end()
+ ->scalarNode('encryption_key_path')
+ ->end()
->end()
;
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
index b4d8a3866..532ce2386 100644
--- a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
+++ b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
@@ -29,6 +29,7 @@ class WallabagCoreExtension extends Extension
$container->setParameter('wallabag_core.fetching_error_message_title', $config['fetching_error_message_title']);
$container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']);
$container->setParameter('wallabag_core.default_internal_settings', $config['default_internal_settings']);
+ $container->setParameter('wallabag_core.site_credentials.encryption_key_path', $config['encryption_key_path']);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
diff --git a/src/Wallabag/CoreBundle/Entity/SiteCredential.php b/src/Wallabag/CoreBundle/Entity/SiteCredential.php
index 85ee07d4a..732d95066 100644
--- a/src/Wallabag/CoreBundle/Entity/SiteCredential.php
+++ b/src/Wallabag/CoreBundle/Entity/SiteCredential.php
@@ -46,8 +46,7 @@ class SiteCredential
* @var string
*
* @Assert\NotBlank()
- * @Assert\Length(max=255)
- * @ORM\Column(name="password", type="string", length=255)
+ * @ORM\Column(name="password", type="text")
*/
private $password;
diff --git a/src/Wallabag/CoreBundle/Helper/CryptoProxy.php b/src/Wallabag/CoreBundle/Helper/CryptoProxy.php
new file mode 100644
index 000000000..d0a9b85c8
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Helper/CryptoProxy.php
@@ -0,0 +1,86 @@
+logger = $logger;
+
+ if (!file_exists($encryptionKeyPath)) {
+ $key = Key::createNewRandomKey();
+
+ file_put_contents($encryptionKeyPath, $key->saveToAsciiSafeString());
+ chmod($encryptionKeyPath, 0600);
+ }
+
+ $this->encryptionKey = file_get_contents($encryptionKeyPath);
+ }
+
+ /**
+ * Ensure the given value will be crypted.
+ *
+ * @param string $secretValue Secret valye to crypt
+ *
+ * @return string
+ */
+ public function crypt($secretValue)
+ {
+ $this->logger->debug('Crypto: crypting value: '.$this->mask($secretValue));
+
+ return Crypto::encrypt($secretValue, $this->loadKey());
+ }
+
+ /**
+ * Ensure the given crypted value will be decrypted.
+ *
+ * @param string $cryptedValue The value to be decrypted
+ *
+ * @return string
+ */
+ public function decrypt($cryptedValue)
+ {
+ $this->logger->debug('Crypto: decrypting value: '.$this->mask($cryptedValue));
+
+ try {
+ return Crypto::decrypt($cryptedValue, $this->loadKey());
+ } catch (WrongKeyOrModifiedCiphertextException $e) {
+ throw new \RuntimeException('Decrypt fail: '.$e->getMessage());
+ }
+ }
+
+ /**
+ * Load the private key.
+ *
+ * @return string
+ */
+ private function loadKey()
+ {
+ return Key::loadFromAsciiSafeString($this->encryptionKey);
+ }
+
+ /**
+ * Keep first and last character and put some stars in between.
+ *
+ * @param string $value Value to mask
+ *
+ * @return string
+ */
+ private function mask($value)
+ {
+ return $value[0].'*****'.$value[strlen($value) - 1];
+ }
+}
diff --git a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
index 316ecc750..6f904f0ae 100644
--- a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
@@ -2,11 +2,20 @@
namespace Wallabag\CoreBundle\Repository;
+use Wallabag\CoreBundle\Helper\CryptoProxy;
+
/**
* SiteCredentialRepository.
*/
class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository
{
+ private $cryptoProxy;
+
+ public function setCrypto(CryptoProxy $cryptoProxy)
+ {
+ $this->cryptoProxy = $cryptoProxy;
+ }
+
/**
* Retrieve one username/password for the given host and userId.
*
@@ -17,12 +26,21 @@ class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository
*/
public function findOneByHostAndUser($host, $userId)
{
- return $this->createQueryBuilder('s')
+ $res = $this->createQueryBuilder('s')
->select('s.username', 's.password')
->where('s.host = :hostname')->setParameter('hostname', $host)
->andWhere('s.user = :userId')->setParameter('userId', $userId)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
+
+ if (null === $res) {
+ return;
+ }
+
+ // decrypt password before returning it
+ $res['password'] = $this->cryptoProxy->decrypt($res['password']);
+
+ return $res;
}
}
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index 09bc77fe9..e09b0f185 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -126,6 +126,8 @@ services:
factory: [ "@doctrine.orm.default_entity_manager", getRepository ]
arguments:
- WallabagCoreBundle:SiteCredential
+ calls:
+ - [ setCrypto, [ "@wallabag_core.helper.crypto_proxy" ] ]
wallabag_core.helper.entries_export:
class: Wallabag\CoreBundle\Helper\EntriesExport
@@ -208,3 +210,9 @@ services:
wallabag_core.entry.download_images.client:
class: GuzzleHttp\Client
+
+ wallabag_core.helper.crypto_proxy:
+ class: Wallabag\CoreBundle\Helper\CryptoProxy
+ arguments:
+ - "%wallabag_core.site_credentials.encryption_key_path%"
+ - "@logger"
diff --git a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
index 104f60f17..803806853 100644
--- a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
+++ b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
@@ -1341,7 +1341,7 @@ class EntryControllerTest extends WallabagCoreTestCase
$credential = new SiteCredential($user);
$credential->setHost('monde-diplomatique.fr');
$credential->setUsername('foo');
- $credential->setPassword('bar');
+ $credential->setPassword($client->getContainer()->get('wallabag_core.helper.crypto_proxy')->crypt('bar'));
$em->persist($credential);
$em->flush();
diff --git a/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php b/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php
index 1e1e8989b..b0c81e7b0 100644
--- a/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php
+++ b/tests/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilderTest.php
@@ -6,12 +6,11 @@ use Monolog\Handler\TestHandler;
use Monolog\Logger;
use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfig;
use Graby\SiteConfig\SiteConfig as GrabySiteConfig;
-use PHPUnit_Framework_TestCase;
use Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
-class GrabySiteConfigBuilderTest extends PHPUnit_Framework_TestCase
+class GrabySiteConfigBuilderTest extends \PHPUnit_Framework_TestCase
{
/** @var \Wallabag\CoreBundle\GuzzleSiteAuthenticator\GrabySiteConfigBuilder */
protected $builder;
diff --git a/tests/Wallabag/CoreBundle/Helper/CryptoProxyTest.php b/tests/Wallabag/CoreBundle/Helper/CryptoProxyTest.php
new file mode 100644
index 000000000..cede86962
--- /dev/null
+++ b/tests/Wallabag/CoreBundle/Helper/CryptoProxyTest.php
@@ -0,0 +1,40 @@
+crypt('test');
+ $decrypted = $crypto->decrypt($crypted);
+
+ $this->assertSame('test', $decrypted);
+
+ $records = $logHandler->getRecords();
+ $this->assertCount(2, $records);
+ $this->assertContains('Crypto: crypting value', $records[0]['message']);
+ $this->assertContains('Crypto: decrypting value', $records[1]['message']);
+ }
+
+ /**
+ * @expectedException RuntimeException
+ * @expectedExceptionMessage Decrypt fail
+ *
+ * @return [type] [description]
+ */
+ public function testDecryptBadValue()
+ {
+ $crypto = new CryptoProxy(sys_get_temp_dir().'/'.uniqid('', true).'.txt', new NullLogger());
+ $crypto->decrypt('badvalue');
+ }
+}
From bead8b42da4f17238dc0d5e0f90184b224ec5df7 Mon Sep 17 00:00:00 2001
From: Thomas Citharel
Date: Wed, 14 Jun 2017 15:02:34 +0200
Subject: [PATCH 8/9] Fix reviews
Encrypt username too
Redirect to list after saving credentials
Fix typos
Signed-off-by: Thomas Citharel
---
.../Version20170501115751.php | 2 +-
.../Controller/SiteCredentialController.php | 38 ++++++++++++++-----
.../CoreBundle/Entity/SiteCredential.php | 3 +-
.../Form/Type/SiteCredentialType.php | 1 +
.../GrabySiteConfigBuilder.php | 3 +-
.../CoreBundle/Helper/CryptoProxy.php | 4 +-
.../Repository/SiteCredentialRepository.php | 3 +-
.../Resources/translations/messages.fr.yml | 4 +-
.../material/SiteCredential/index.html.twig | 4 +-
.../Controller/EntryControllerTest.php | 2 +-
.../SiteCredentialControllerTest.php | 1 -
11 files changed, 43 insertions(+), 22 deletions(-)
diff --git a/app/DoctrineMigrations/Version20170501115751.php b/app/DoctrineMigrations/Version20170501115751.php
index 2597f1ffd..7f068eb84 100644
--- a/app/DoctrineMigrations/Version20170501115751.php
+++ b/app/DoctrineMigrations/Version20170501115751.php
@@ -38,7 +38,7 @@ class Version20170501115751 extends AbstractMigration implements ContainerAwareI
$table->addColumn('id', 'integer', ['autoincrement' => true]);
$table->addColumn('user_id', 'integer');
$table->addColumn('host', 'string', ['length' => 255]);
- $table->addColumn('username', 'string', ['length' => 255]);
+ $table->addColumn('username', 'text');
$table->addColumn('password', 'text');
$table->addColumn('createdAt', 'datetime');
$table->addIndex(['user_id'], 'idx_user');
diff --git a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
index 0bacafb79..98781dab0 100644
--- a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
+++ b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
@@ -26,9 +26,9 @@ class SiteCredentialController extends Controller
{
$credentials = $this->get('wallabag_core.site_credential_repository')->findByUser($this->getUser());
- return $this->render('WallabagCoreBundle:SiteCredential:index.html.twig', array(
+ return $this->render('WallabagCoreBundle:SiteCredential:index.html.twig', [
'credentials' => $credentials,
- ));
+ ]);
}
/**
@@ -36,6 +36,10 @@ class SiteCredentialController extends Controller
*
* @Route("/new", name="site_credentials_new")
* @Method({"GET", "POST"})
+ *
+ * @param Request $request
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request)
{
@@ -45,24 +49,25 @@ class SiteCredentialController extends Controller
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
+ $credential->setUsername($this->get('wallabag_core.helper.crypto_proxy')->crypt($credential->getUsername()));
$credential->setPassword($this->get('wallabag_core.helper.crypto_proxy')->crypt($credential->getPassword()));
$em = $this->getDoctrine()->getManager();
$em->persist($credential);
- $em->flush($credential);
+ $em->flush();
$this->get('session')->getFlashBag()->add(
'notice',
$this->get('translator')->trans('flashes.site_credential.notice.added', ['%host%' => $credential->getHost()])
);
- return $this->redirectToRoute('site_credentials_edit', array('id' => $credential->getId()));
+ return $this->redirectToRoute('site_credentials_index');
}
- return $this->render('WallabagCoreBundle:SiteCredential:new.html.twig', array(
+ return $this->render('WallabagCoreBundle:SiteCredential:new.html.twig', [
'credential' => $credential,
'form' => $form->createView(),
- ));
+ ]);
}
/**
@@ -70,6 +75,11 @@ class SiteCredentialController extends Controller
*
* @Route("/{id}/edit", name="site_credentials_edit")
* @Method({"GET", "POST"})
+ *
+ * @param Request $request
+ * @param SiteCredential $siteCredential
+ *
+ * @return \Symfony\Component\HttpFoundation\Response
*/
public function editAction(Request $request, SiteCredential $siteCredential)
{
@@ -80,6 +90,9 @@ class SiteCredentialController extends Controller
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
+ $siteCredential->setUsername($this->get('wallabag_core.helper.crypto_proxy')->crypt($siteCredential->getUsername()));
+ $siteCredential->setPassword($this->get('wallabag_core.helper.crypto_proxy')->crypt($siteCredential->getPassword()));
+
$em = $this->getDoctrine()->getManager();
$em->persist($siteCredential);
$em->flush();
@@ -89,14 +102,14 @@ class SiteCredentialController extends Controller
$this->get('translator')->trans('flashes.site_credential.notice.updated', ['%host%' => $siteCredential->getHost()])
);
- return $this->redirectToRoute('site_credentials_edit', array('id' => $siteCredential->getId()));
+ return $this->redirectToRoute('site_credentials_index');
}
- return $this->render('WallabagCoreBundle:SiteCredential:edit.html.twig', array(
+ return $this->render('WallabagCoreBundle:SiteCredential:edit.html.twig', [
'credential' => $siteCredential,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
- ));
+ ]);
}
/**
@@ -104,6 +117,11 @@ class SiteCredentialController extends Controller
*
* @Route("/{id}", name="site_credentials_delete")
* @Method("DELETE")
+ *
+ * @param Request $request
+ * @param SiteCredential $siteCredential
+ *
+ * @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function deleteAction(Request $request, SiteCredential $siteCredential)
{
@@ -136,7 +154,7 @@ class SiteCredentialController extends Controller
private function createDeleteForm(SiteCredential $siteCredential)
{
return $this->createFormBuilder()
- ->setAction($this->generateUrl('site_credentials_delete', array('id' => $siteCredential->getId())))
+ ->setAction($this->generateUrl('site_credentials_delete', ['id' => $siteCredential->getId()]))
->setMethod('DELETE')
->getForm()
;
diff --git a/src/Wallabag/CoreBundle/Entity/SiteCredential.php b/src/Wallabag/CoreBundle/Entity/SiteCredential.php
index 732d95066..58075e928 100644
--- a/src/Wallabag/CoreBundle/Entity/SiteCredential.php
+++ b/src/Wallabag/CoreBundle/Entity/SiteCredential.php
@@ -37,8 +37,7 @@ class SiteCredential
* @var string
*
* @Assert\NotBlank()
- * @Assert\Length(max=255)
- * @ORM\Column(name="username", type="string", length=255)
+ * @ORM\Column(name="username", type="text")
*/
private $username;
diff --git a/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php b/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php
index 9db7c155d..fd409ad2c 100644
--- a/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php
+++ b/src/Wallabag/CoreBundle/Form/Type/SiteCredentialType.php
@@ -19,6 +19,7 @@ class SiteCredentialType extends AbstractType
])
->add('username', TextType::class, [
'label' => 'site_credential.form.username_label',
+ 'data' => '',
])
->add('password', PasswordType::class, [
'label' => 'site_credential.form.password_label',
diff --git a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
index 62a3bc131..a79e6ebed 100644
--- a/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
+++ b/src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
@@ -87,7 +87,8 @@ class GrabySiteConfigBuilder implements SiteConfigBuilder
$config = new SiteConfig($parameters);
- // do not leak password in log
+ // do not leak usernames and passwords in log
+ $parameters['username'] = '**masked**';
$parameters['password'] = '**masked**';
$this->logger->debug('Auth: add parameters.', ['host' => $host, 'parameters' => $parameters]);
diff --git a/src/Wallabag/CoreBundle/Helper/CryptoProxy.php b/src/Wallabag/CoreBundle/Helper/CryptoProxy.php
index d0a9b85c8..e8b19cb9e 100644
--- a/src/Wallabag/CoreBundle/Helper/CryptoProxy.php
+++ b/src/Wallabag/CoreBundle/Helper/CryptoProxy.php
@@ -65,7 +65,7 @@ class CryptoProxy
/**
* Load the private key.
*
- * @return string
+ * @return Key
*/
private function loadKey()
{
@@ -81,6 +81,6 @@ class CryptoProxy
*/
private function mask($value)
{
- return $value[0].'*****'.$value[strlen($value) - 1];
+ return strlen($value) > 0 ? $value[0].'*****'.$value[strlen($value) - 1] : 'Empty value';
}
}
diff --git a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
index 6f904f0ae..369067612 100644
--- a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
@@ -38,7 +38,8 @@ class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository
return;
}
- // decrypt password before returning it
+ // decrypt user & password before returning them
+ $res['username'] = $this->cryptoProxy->decrypt($res['username']);
$res['password'] = $this->cryptoProxy->decrypt($res['password']);
return $res;
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
index 542ddf486..cd239b5cb 100644
--- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
+++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
@@ -515,7 +515,7 @@ user:
twofactor_label: "Double authentification"
save: "Sauvegarder"
delete: "Supprimer"
- delete_confirm: "Êtes-vous sur ?"
+ delete_confirm: "Êtes-vous sûr ?"
back_to_list: "Revenir à la liste"
search:
placeholder: "Filtrer par nom d’utilisateur ou email"
@@ -537,7 +537,7 @@ site_credential:
password_label: 'Mot de passe'
save: "Sauvegarder"
delete: "Supprimer"
- delete_confirm: "Êtes-vous sur ?"
+ delete_confirm: "Êtes-vous sûr ?"
back_to_list: "Revenir à la liste"
error:
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/index.html.twig
index c128bcebd..4d30a6925 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/index.html.twig
@@ -16,6 +16,7 @@
{{ 'site_credential.form.host_label'|trans }} |
{{ 'site_credential.form.username_label'|trans }} |
+ {{ 'site_credential.form.password_label'|trans }} |
{{ 'site_credential.list.actions'|trans }} |
@@ -23,7 +24,8 @@
{% for credential in credentials %}
{{ credential.host }} |
- {{ credential.username }} |
+ ***** |
+ ***** |
{{ 'site_credential.list.edit_action'|trans }}
|
diff --git a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
index 803806853..f17dc97b3 100644
--- a/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
+++ b/tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php
@@ -1340,7 +1340,7 @@ class EntryControllerTest extends WallabagCoreTestCase
$user = $client->getContainer()->get('security.token_storage')->getToken()->getUser();
$credential = new SiteCredential($user);
$credential->setHost('monde-diplomatique.fr');
- $credential->setUsername('foo');
+ $credential->setUsername($client->getContainer()->get('wallabag_core.helper.crypto_proxy')->crypt('foo'));
$credential->setPassword($client->getContainer()->get('wallabag_core.helper.crypto_proxy')->crypt('bar'));
$em->persist($credential);
diff --git a/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php b/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php
index 7e6dafee6..e73a9743c 100644
--- a/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php
+++ b/tests/Wallabag/CoreBundle/Controller/SiteCredentialControllerTest.php
@@ -85,7 +85,6 @@ class SiteCredentialControllerTest extends WallabagCoreTestCase
$crawler = $client->followRedirect();
$this->assertContains('flashes.site_credential.notice.updated', $crawler->filter('body')->extract(['_text'])[0]);
- $this->assertContains('larry', $crawler->filter('input[id=site_credential_username]')->attr('value'));
}
public function testEditFromADifferentUserSiteCredential()
From f44dba22fc1a566cb156d9e6eda5afc353163eda Mon Sep 17 00:00:00 2001
From: Jeremy Benoist
Date: Sun, 18 Jun 2017 15:34:59 +0200
Subject: [PATCH 9/9] Get rid of masked value in listing
---
.../views/themes/baggy/SiteCredential/index.html.twig | 2 --
.../views/themes/material/SiteCredential/index.html.twig | 4 ----
2 files changed, 6 deletions(-)
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig
index c128bcebd..324854add 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/baggy/SiteCredential/index.html.twig
@@ -15,7 +15,6 @@
{{ 'site_credential.form.host_label'|trans }} |
- {{ 'site_credential.form.username_label'|trans }} |
{{ 'site_credential.list.actions'|trans }} |
@@ -23,7 +22,6 @@
{% for credential in credentials %}
{{ credential.host }} |
- {{ credential.username }} |
{{ 'site_credential.list.edit_action'|trans }}
|
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/index.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/index.html.twig
index 4d30a6925..324854add 100644
--- a/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/index.html.twig
+++ b/src/Wallabag/CoreBundle/Resources/views/themes/material/SiteCredential/index.html.twig
@@ -15,8 +15,6 @@
{{ 'site_credential.form.host_label'|trans }} |
- {{ 'site_credential.form.username_label'|trans }} |
- {{ 'site_credential.form.password_label'|trans }} |
{{ 'site_credential.list.actions'|trans }} |
@@ -24,8 +22,6 @@
{% for credential in credentials %}
{{ credential.host }} |
- ***** |
- ***** |
{{ 'site_credential.list.edit_action'|trans }}
|