]>
Commit | Line | Data |
---|---|---|
c3235553 | 1 | <?php |
4346a860 | 2 | |
769e19dc | 3 | namespace Wallabag\ApiBundle\Security\Authentication\Provider; |
c3235553 NL |
4 | |
5 | use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; | |
6 | use Symfony\Component\Security\Core\User\UserProviderInterface; | |
7 | use Symfony\Component\Security\Core\Exception\AuthenticationException; | |
8 | use Symfony\Component\Security\Core\Exception\NonceExpiredException; | |
9 | use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; | |
769e19dc | 10 | use Wallabag\ApiBundle\Security\Authentication\Token\WsseUserToken; |
c3235553 NL |
11 | |
12 | class WsseProvider implements AuthenticationProviderInterface | |
13 | { | |
14 | private $userProvider; | |
15 | private $cacheDir; | |
16 | ||
17 | public function __construct(UserProviderInterface $userProvider, $cacheDir) | |
18 | { | |
19 | $this->userProvider = $userProvider; | |
8ce32af6 | 20 | $this->cacheDir = $cacheDir; |
92504e0d NL |
21 | |
22 | // If cache directory does not exist we create it | |
23 | if (!is_dir($this->cacheDir)) { | |
24 | mkdir($this->cacheDir, 0777, true); | |
25 | } | |
c3235553 NL |
26 | } |
27 | ||
28 | public function authenticate(TokenInterface $token) | |
29 | { | |
30 | $user = $this->userProvider->loadUserByUsername($token->getUsername()); | |
31 | ||
2a94b1d1 | 32 | if (!$user) { |
4346a860 | 33 | throw new AuthenticationException('Bad credentials. Did you forgot your username?'); |
2a94b1d1 NL |
34 | } |
35 | ||
c3235553 NL |
36 | if ($user && $this->validateDigest($token->digest, $token->nonce, $token->created, $user->getPassword())) { |
37 | $authenticatedToken = new WsseUserToken($user->getRoles()); | |
38 | $authenticatedToken->setUser($user); | |
39 | ||
40 | return $authenticatedToken; | |
41 | } | |
42 | ||
43 | throw new AuthenticationException('The WSSE authentication failed.'); | |
44 | } | |
45 | ||
46 | protected function validateDigest($digest, $nonce, $created, $secret) | |
47 | { | |
2a94b1d1 NL |
48 | // Check created time is not in the future |
49 | if (strtotime($created) > time()) { | |
4346a860 | 50 | throw new AuthenticationException('Back to the future...'); |
2a94b1d1 NL |
51 | } |
52 | ||
53 | // Expire timestamp after 5 minutes | |
c3235553 | 54 | if (time() - strtotime($created) > 300) { |
4346a860 | 55 | throw new AuthenticationException('Too late for this timestamp... Watch your watch.'); |
c3235553 NL |
56 | } |
57 | ||
2a94b1d1 | 58 | // Validate nonce is unique within 5 minutes |
c3235553 NL |
59 | if (file_exists($this->cacheDir.'/'.$nonce) && file_get_contents($this->cacheDir.'/'.$nonce) + 300 > time()) { |
60 | throw new NonceExpiredException('Previously used nonce detected'); | |
61 | } | |
0ac38198 | 62 | |
c3235553 NL |
63 | file_put_contents($this->cacheDir.'/'.$nonce, time()); |
64 | ||
2a94b1d1 | 65 | // Validate Secret |
c3235553 NL |
66 | $expected = base64_encode(sha1(base64_decode($nonce).$created.$secret, true)); |
67 | ||
2a94b1d1 | 68 | if ($digest !== $expected) { |
4346a860 | 69 | throw new AuthenticationException('Bad credentials ! Digest is not as expected.'); |
2a94b1d1 NL |
70 | } |
71 | ||
c3235553 NL |
72 | return $digest === $expected; |
73 | } | |
74 | ||
75 | public function supports(TokenInterface $token) | |
76 | { | |
77 | return $token instanceof WsseUserToken; | |
78 | } | |
7df80cb3 | 79 | } |