Completed
Push — master ( bbfd46...3bfc89 )
by Mathieu
01:50
created

OAuth2AuthenticationListener::handle()   B

Complexity

Conditions 3
Paths 5

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 26
rs 8.8571
cc 3
eloc 17
nc 5
nop 1
1
<?php
2
3
namespace TH\OAuth2;
4
5
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
6
use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface;
7
use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
8
use Symfony\Component\Security\Core\Exception\AuthenticationException;
9
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
10
use OAuth2\Server;
11
use OAuth2\HttpFoundationBridge\Request as BridgeRequest;
12
use OAuth2\HttpFoundationBridge\Response as BridgeResponse;
13
use Psr\Log\LoggerInterface;
14
15
class OAuth2AuthenticationListener
16
{
17
    private $oauth2Server;
18
    private $tokenStorage;
19
    private $authenticationManager;
20
    private $providerKey;
21
    private $authenticationEntryPoint;
22
    private $logger;
23
    private $ignoreFailure;
24
25
    public function __construct(
26
        Server $oauth2Server,
27
        TokenStorageInterface $tokenStorage,
28
        AuthenticationManagerInterface $authenticationManager,
29
        $providerKey,
30
        AuthenticationEntryPointInterface $authenticationEntryPoint,
31
        LoggerInterface $logger
32
    ) {
33
        $this->oauth2Server = $oauth2Server;
34
35
        if (empty($providerKey)) {
36
            throw new \InvalidArgumentException('$providerKey must not be empty.');
37
        }
38
39
        $this->tokenStorage = $tokenStorage;
40
        $this->authenticationManager = $authenticationManager;
41
        $this->providerKey = $providerKey;
42
        $this->authenticationEntryPoint = $authenticationEntryPoint;
43
        $this->logger = $logger;
44
        $this->ignoreFailure = false;
45
    }
46
47
    /**
48
     * Handles basic authentication.
49
     *
50
     * @param GetResponseEvent $event A GetResponseEvent instance
51
     */
52
    public function handle(GetResponseEvent $event)
53
    {
54
        $request = BridgeRequest::createFromRequest($event->getRequest());
55
        $response = new BridgeResponse;
56
57
        if (!$this->oauth2Server->verifyResourceRequest($request, $response)) {
58
            return;
59
        }
60
61
        try {
62
            $token = $this->oauth2Server->getAccessTokenData($request);
63
            $token = $this->authenticationManager->authenticate(
64
                new OAuth2Token(
65
                    $token['client_id'],
66
                    $token['user_id'],
67
                    $token['access_token'],
68
                    $this->providerKey,
69
                    [],
70
                    explode(" ", $token['scope'])
71
                )
72
            );
73
            $this->tokenStorage->setToken($token);
74
        } catch (AuthenticationException $failed) {
75
            $this->handleAuthenticationError($event, $request, $failed);
76
        }
77
    }
78
79
    private function handleAuthenticationError(
80
        GetResponseEvent $event,
81
        BridgeRequest $request,
82
        AuthenticationException $failed
83
    ) {
84
        $token = $this->tokenStorage->getToken();
85
        if ($token instanceof OAuth2Token) {
86
            $this->tokenStorage->setToken(null);
87
        }
88
89
        $this->logger->info(sprintf('Authentication request failed : %s', $failed->getMessage()));
90
91
        if ($this->ignoreFailure) {
92
            return;
93
        }
94
95
        $event->setResponse($this->authenticationEntryPoint->start($request, $failed));
96
    }
97
}
98