diff options
author | Jeremy Benoist <j0k3r@users.noreply.github.com> | 2015-10-06 09:19:06 +0200 |
---|---|---|
committer | Jeremy Benoist <j0k3r@users.noreply.github.com> | 2015-10-06 09:19:06 +0200 |
commit | 16dabc326311f084d671be188c7941bbb3c341c9 (patch) | |
tree | 3210a7688ea2bfa1bff5fd0422b52adf570edcdc /src/Wallabag/CoreBundle/Security/Authentication | |
parent | fdef5f460524215d806e244e5546865f4b8e01df (diff) | |
parent | 8263e71192989dc0fd28a41ac22f9c5b32eb11c4 (diff) | |
download | wallabag-16dabc326311f084d671be188c7941bbb3c341c9.tar.gz wallabag-16dabc326311f084d671be188c7941bbb3c341c9.tar.zst wallabag-16dabc326311f084d671be188c7941bbb3c341c9.zip |
Merge pull request #1436 from wallabag/v2-register
Public registration & oAuth2 \o/
Diffstat (limited to 'src/Wallabag/CoreBundle/Security/Authentication')
-rw-r--r-- | src/Wallabag/CoreBundle/Security/Authentication/Encoder/WallabagPasswordEncoder.php | 87 | ||||
-rw-r--r-- | src/Wallabag/CoreBundle/Security/Authentication/Provider/WallabagAuthenticationProvider.php | 89 |
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 | |||
3 | namespace Wallabag\CoreBundle\Security\Authentication\Encoder; | ||
4 | |||
5 | use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder; | ||
6 | use 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 | */ | ||
12 | class 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 | |||
3 | namespace Wallabag\CoreBundle\Security\Authentication\Provider; | ||
4 | |||
5 | use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface; | ||
6 | use Symfony\Component\Security\Core\User\UserProviderInterface; | ||
7 | use Symfony\Component\Security\Core\User\UserCheckerInterface; | ||
8 | use Symfony\Component\Security\Core\User\UserInterface; | ||
9 | use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; | ||
10 | use Symfony\Component\Security\Core\Exception\AuthenticationServiceException; | ||
11 | use Symfony\Component\Security\Core\Exception\BadCredentialsException; | ||
12 | use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; | ||
13 | use Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider; | ||
14 | |||
15 | class 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 | } | ||