aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag')
-rw-r--r--src/Wallabag/CoreBundle/Command/InstallCommand.php2
-rw-r--r--src/Wallabag/CoreBundle/Controller/SiteCredentialController.php2
-rw-r--r--src/Wallabag/CoreBundle/DependencyInjection/Configuration.php2
-rw-r--r--src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php1
-rw-r--r--src/Wallabag/CoreBundle/Entity/SiteCredential.php3
-rw-r--r--src/Wallabag/CoreBundle/Helper/CryptoProxy.php86
-rw-r--r--src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php20
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/services.yml8
8 files changed, 121 insertions, 3 deletions
diff --git a/src/Wallabag/CoreBundle/Command/InstallCommand.php b/src/Wallabag/CoreBundle/Command/InstallCommand.php
index 0f119377..eb725a59 100644
--- a/src/Wallabag/CoreBundle/Command/InstallCommand.php
+++ b/src/Wallabag/CoreBundle/Command/InstallCommand.php
@@ -313,6 +313,8 @@ class InstallCommand extends ContainerAwareCommand
313 313
314 $this 314 $this
315 ->runCommand('doctrine:migrations:migrate', ['--no-interaction' => true]); 315 ->runCommand('doctrine:migrations:migrate', ['--no-interaction' => true]);
316
317 return $this;
316 } 318 }
317 319
318 /** 320 /**
diff --git a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
index dc8e723d..0bacafb7 100644
--- a/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
+++ b/src/Wallabag/CoreBundle/Controller/SiteCredentialController.php
@@ -45,6 +45,8 @@ class SiteCredentialController extends Controller
45 $form->handleRequest($request); 45 $form->handleRequest($request);
46 46
47 if ($form->isSubmitted() && $form->isValid()) { 47 if ($form->isSubmitted() && $form->isValid()) {
48 $credential->setPassword($this->get('wallabag_core.helper.crypto_proxy')->crypt($credential->getPassword()));
49
48 $em = $this->getDoctrine()->getManager(); 50 $em = $this->getDoctrine()->getManager();
49 $em->persist($credential); 51 $em->persist($credential);
50 $em->flush($credential); 52 $em->flush($credential);
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
index 33df92d3..a9791f6b 100644
--- a/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
+++ b/src/Wallabag/CoreBundle/DependencyInjection/Configuration.php
@@ -63,6 +63,8 @@ class Configuration implements ConfigurationInterface
63 ->end() 63 ->end()
64 ->end() 64 ->end()
65 ->end() 65 ->end()
66 ->scalarNode('encryption_key_path')
67 ->end()
66 ->end() 68 ->end()
67 ; 69 ;
68 70
diff --git a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
index b4d8a386..532ce238 100644
--- a/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
+++ b/src/Wallabag/CoreBundle/DependencyInjection/WallabagCoreExtension.php
@@ -29,6 +29,7 @@ class WallabagCoreExtension extends Extension
29 $container->setParameter('wallabag_core.fetching_error_message_title', $config['fetching_error_message_title']); 29 $container->setParameter('wallabag_core.fetching_error_message_title', $config['fetching_error_message_title']);
30 $container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']); 30 $container->setParameter('wallabag_core.api_limit_mass_actions', $config['api_limit_mass_actions']);
31 $container->setParameter('wallabag_core.default_internal_settings', $config['default_internal_settings']); 31 $container->setParameter('wallabag_core.default_internal_settings', $config['default_internal_settings']);
32 $container->setParameter('wallabag_core.site_credentials.encryption_key_path', $config['encryption_key_path']);
32 33
33 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 34 $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
34 $loader->load('services.yml'); 35 $loader->load('services.yml');
diff --git a/src/Wallabag/CoreBundle/Entity/SiteCredential.php b/src/Wallabag/CoreBundle/Entity/SiteCredential.php
index 85ee07d4..732d9506 100644
--- a/src/Wallabag/CoreBundle/Entity/SiteCredential.php
+++ b/src/Wallabag/CoreBundle/Entity/SiteCredential.php
@@ -46,8 +46,7 @@ class SiteCredential
46 * @var string 46 * @var string
47 * 47 *
48 * @Assert\NotBlank() 48 * @Assert\NotBlank()
49 * @Assert\Length(max=255) 49 * @ORM\Column(name="password", type="text")
50 * @ORM\Column(name="password", type="string", length=255)
51 */ 50 */
52 private $password; 51 private $password;
53 52
diff --git a/src/Wallabag/CoreBundle/Helper/CryptoProxy.php b/src/Wallabag/CoreBundle/Helper/CryptoProxy.php
new file mode 100644
index 00000000..d0a9b85c
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Helper/CryptoProxy.php
@@ -0,0 +1,86 @@
1<?php
2
3namespace Wallabag\CoreBundle\Helper;
4
5use Psr\Log\LoggerInterface;
6use Defuse\Crypto\Key;
7use Defuse\Crypto\Crypto;
8use Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException;
9
10/**
11 * This is a proxy to crypt and decrypt password used by SiteCredential entity.
12 * BTW, It might be re-use for sth else.
13 */
14class CryptoProxy
15{
16 private $logger;
17 private $encryptionKey;
18
19 public function __construct($encryptionKeyPath, LoggerInterface $logger)
20 {
21 $this->logger = $logger;
22
23 if (!file_exists($encryptionKeyPath)) {
24 $key = Key::createNewRandomKey();
25
26 file_put_contents($encryptionKeyPath, $key->saveToAsciiSafeString());
27 chmod($encryptionKeyPath, 0600);
28 }
29
30 $this->encryptionKey = file_get_contents($encryptionKeyPath);
31 }
32
33 /**
34 * Ensure the given value will be crypted.
35 *
36 * @param string $secretValue Secret valye to crypt
37 *
38 * @return string
39 */
40 public function crypt($secretValue)
41 {
42 $this->logger->debug('Crypto: crypting value: '.$this->mask($secretValue));
43
44 return Crypto::encrypt($secretValue, $this->loadKey());
45 }
46
47 /**
48 * Ensure the given crypted value will be decrypted.
49 *
50 * @param string $cryptedValue The value to be decrypted
51 *
52 * @return string
53 */
54 public function decrypt($cryptedValue)
55 {
56 $this->logger->debug('Crypto: decrypting value: '.$this->mask($cryptedValue));
57
58 try {
59 return Crypto::decrypt($cryptedValue, $this->loadKey());
60 } catch (WrongKeyOrModifiedCiphertextException $e) {
61 throw new \RuntimeException('Decrypt fail: '.$e->getMessage());
62 }
63 }
64
65 /**
66 * Load the private key.
67 *
68 * @return string
69 */
70 private function loadKey()
71 {
72 return Key::loadFromAsciiSafeString($this->encryptionKey);
73 }
74
75 /**
76 * Keep first and last character and put some stars in between.
77 *
78 * @param string $value Value to mask
79 *
80 * @return string
81 */
82 private function mask($value)
83 {
84 return $value[0].'*****'.$value[strlen($value) - 1];
85 }
86}
diff --git a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
index 316ecc75..6f904f0a 100644
--- a/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/SiteCredentialRepository.php
@@ -2,11 +2,20 @@
2 2
3namespace Wallabag\CoreBundle\Repository; 3namespace Wallabag\CoreBundle\Repository;
4 4
5use Wallabag\CoreBundle\Helper\CryptoProxy;
6
5/** 7/**
6 * SiteCredentialRepository. 8 * SiteCredentialRepository.
7 */ 9 */
8class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository 10class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository
9{ 11{
12 private $cryptoProxy;
13
14 public function setCrypto(CryptoProxy $cryptoProxy)
15 {
16 $this->cryptoProxy = $cryptoProxy;
17 }
18
10 /** 19 /**
11 * Retrieve one username/password for the given host and userId. 20 * Retrieve one username/password for the given host and userId.
12 * 21 *
@@ -17,12 +26,21 @@ class SiteCredentialRepository extends \Doctrine\ORM\EntityRepository
17 */ 26 */
18 public function findOneByHostAndUser($host, $userId) 27 public function findOneByHostAndUser($host, $userId)
19 { 28 {
20 return $this->createQueryBuilder('s') 29 $res = $this->createQueryBuilder('s')
21 ->select('s.username', 's.password') 30 ->select('s.username', 's.password')
22 ->where('s.host = :hostname')->setParameter('hostname', $host) 31 ->where('s.host = :hostname')->setParameter('hostname', $host)
23 ->andWhere('s.user = :userId')->setParameter('userId', $userId) 32 ->andWhere('s.user = :userId')->setParameter('userId', $userId)
24 ->setMaxResults(1) 33 ->setMaxResults(1)
25 ->getQuery() 34 ->getQuery()
26 ->getOneOrNullResult(); 35 ->getOneOrNullResult();
36
37 if (null === $res) {
38 return;
39 }
40
41 // decrypt password before returning it
42 $res['password'] = $this->cryptoProxy->decrypt($res['password']);
43
44 return $res;
27 } 45 }
28} 46}
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index 09bc77fe..e09b0f18 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -126,6 +126,8 @@ services:
126 factory: [ "@doctrine.orm.default_entity_manager", getRepository ] 126 factory: [ "@doctrine.orm.default_entity_manager", getRepository ]
127 arguments: 127 arguments:
128 - WallabagCoreBundle:SiteCredential 128 - WallabagCoreBundle:SiteCredential
129 calls:
130 - [ setCrypto, [ "@wallabag_core.helper.crypto_proxy" ] ]
129 131
130 wallabag_core.helper.entries_export: 132 wallabag_core.helper.entries_export:
131 class: Wallabag\CoreBundle\Helper\EntriesExport 133 class: Wallabag\CoreBundle\Helper\EntriesExport
@@ -208,3 +210,9 @@ services:
208 210
209 wallabag_core.entry.download_images.client: 211 wallabag_core.entry.download_images.client:
210 class: GuzzleHttp\Client 212 class: GuzzleHttp\Client
213
214 wallabag_core.helper.crypto_proxy:
215 class: Wallabag\CoreBundle\Helper\CryptoProxy
216 arguments:
217 - "%wallabag_core.site_credentials.encryption_key_path%"
218 - "@logger"