aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag/CoreBundle/Security/Authentication
diff options
context:
space:
mode:
Diffstat (limited to 'src/Wallabag/CoreBundle/Security/Authentication')
-rw-r--r--src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php87
-rw-r--r--src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php89
2 files changed, 0 insertions, 176 deletions
diff --git a/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php b/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php
deleted file mode 100644
index 98b4e86b..00000000
--- a/src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php
+++ /dev/null
@@ -1,87 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Security\Authentication\Encoder;
4
5use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder;
6use Symfony\Component\Security\Core\Exception\BadCredentialsException;
7
8/**
9 * This override just add en extra variable (username) to be able to salt the password
10 * the way Wallabag v1 does. It will avoid to break compatibility with Wallabag v1.
11 */
12class WallabagPasswordEncoder extends BasePasswordEncoder
13{
14 private $algorithm;
15 private $encodeHashAsBase64;
16 private $iterations;
17 private $username = null;
18
19 /**
20 * Constructor.
21 *
22 * @param string $algorithm The digest algorithm to use
23 * @param bool $encodeHashAsBase64 Whether to base64 encode the password hash
24 * @param int $iterations The number of iterations to use to stretch the password hash
25 */
26 public function __construct($algorithm = 'sha512', $encodeHashAsBase64 = true, $iterations = 5000)
27 {
28 $this->algorithm = $algorithm;
29 $this->encodeHashAsBase64 = $encodeHashAsBase64;
30 $this->iterations = $iterations;
31 }
32
33 public function setUsername($username)
34 {
35 $this->username = $username;
36 }
37
38 /**
39 * {@inheritdoc}
40 */
41 public function encodePassword($raw, $salt)
42 {
43 if ($this->isPasswordTooLong($raw)) {
44 throw new BadCredentialsException('Invalid password.');
45 }
46
47 if (!in_array($this->algorithm, hash_algos(), true)) {
48 throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
49 }
50
51 $salted = $this->mergePasswordAndSalt($raw, $salt);
52 $digest = hash($this->algorithm, $salted, true);
53
54 // "stretch" hash
55 for ($i = 1; $i < $this->iterations; ++$i) {
56 $digest = hash($this->algorithm, $digest.$salted, true);
57 }
58
59 return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
60 }
61
62 /**
63 * {@inheritdoc}
64 *
65 * We inject the username inside the salted password
66 */
67 protected function mergePasswordAndSalt($password, $salt)
68 {
69 if (null === $this->username) {
70 throw new \LogicException('We can not check the password without a username.');
71 }
72
73 if (empty($salt)) {
74 return $password;
75 }
76
77 return $password.$this->username.$salt;
78 }
79
80 /**
81 * {@inheritdoc}
82 */
83 public function isPasswordValid($encoded, $raw, $salt)
84 {
85 return !$this->isPasswordTooLong($raw) && $this->comparePasswords($encoded, $this->encodePassword($raw, $salt));
86 }
87}
diff --git a/src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php b/src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php
deleted file mode 100644
index cf3cb051..00000000
--- a/src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php
+++ /dev/null
@@ -1,89 +0,0 @@
1<?php
2
3namespace Wallabag\CoreBundle\Security\Authentication\Provider;
4
5use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
6use Symfony\Component\Security\Core\User\UserProviderInterface;
7use Symfony\Component\Security\Core\User\UserCheckerInterface;
8use Symfony\Component\Security\Core\User\UserInterface;
9use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
10use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
11use Symfony\Component\Security\Core\Exception\BadCredentialsException;
12use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
13use Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider;
14
15class WallabagAuthenticationProvider extends UserAuthenticationProvider
16{
17 private $encoderFactory;
18 private $userProvider;
19
20 /**
21 * Constructor.
22 *
23 * @param UserProviderInterface $userProvider An UserProviderInterface instance
24 * @param UserCheckerInterface $userChecker An UserCheckerInterface instance
25 * @param string $providerKey The provider key
26 * @param EncoderFactoryInterface $encoderFactory An EncoderFactoryInterface instance
27 * @param bool $hideUserNotFoundExceptions Whether to hide user not found exception or not
28 */
29 public function __construct(UserProviderInterface $userProvider, UserCheckerInterface $userChecker, $providerKey, EncoderFactoryInterface $encoderFactory, $hideUserNotFoundExceptions = true)
30 {
31 parent::__construct($userChecker, $providerKey, $hideUserNotFoundExceptions);
32
33 $this->encoderFactory = $encoderFactory;
34 $this->userProvider = $userProvider;
35 }
36
37 /**
38 * {@inheritdoc}
39 */
40 protected function checkAuthentication(UserInterface $user, UsernamePasswordToken $token)
41 {
42 $currentUser = $token->getUser();
43 if ($currentUser instanceof UserInterface) {
44 if ($currentUser->getPassword() !== $user->getPassword()) {
45 throw new BadCredentialsException('The credentials were changed from another session.');
46 }
47 } else {
48 if ('' === ($presentedPassword = $token->getCredentials())) {
49 throw new BadCredentialsException('The presented password cannot be empty.');
50 }
51
52 // give username, it's used to hash the password
53 $encoder = $this->encoderFactory->getEncoder($user);
54 $encoder->setUsername($user->getUsername());
55
56 if (!$encoder->isPasswordValid($user->getPassword(), $presentedPassword, $user->getSalt())) {
57 throw new BadCredentialsException('The presented password is invalid.');
58 }
59 }
60 }
61
62 /**
63 * {@inheritdoc}
64 */
65 protected function retrieveUser($username, UsernamePasswordToken $token)
66 {
67 $user = $token->getUser();
68 if ($user instanceof UserInterface) {
69 return $user;
70 }
71
72 try {
73 $user = $this->userProvider->loadUserByUsername($username);
74
75 if (!$user instanceof UserInterface) {
76 throw new AuthenticationServiceException('The user provider must return a UserInterface object.');
77 }
78
79 return $user;
80 } catch (UsernameNotFoundException $notFound) {
81 $notFound->setUsername($username);
82 throw $notFound;
83 } catch (\Exception $repositoryProblem) {
84 $ex = new AuthenticationServiceException($repositoryProblem->getMessage(), 0, $repositoryProblem);
85 $ex->setToken($token);
86 throw $ex;
87 }
88 }
89}