AuthenticationService   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 10
dl 0
loc 130
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 2
A authenticate() 0 39 4
A setServer() 0 5 1
A getServer() 0 4 1
A createServer() 0 17 1
A addMissingServerVariables() 0 16 4
1
<?php
2
3
namespace AdvancedLearning\Oauth2Server\Services;
4
5
6
use AdvancedLearning\Oauth2Server\Exceptions\AuthenticationException;
7
use AdvancedLearning\Oauth2Server\Repositories\AccessTokenRepository;
8
use GuzzleHttp\Psr7\Response;
9
use League\OAuth2\Server\Exception\OAuthServerException;
10
use League\OAuth2\Server\ResourceServer;
11
use Robbie\Psr7\HttpRequestAdapter;
12
use Robbie\Psr7\HttpResponseAdapter;
13
use SilverStripe\Control\Director;
14
use SilverStripe\Control\HTTPRequest;
15
use SilverStripe\Core\Environment;
16
17
class AuthenticationService implements Authenticator
18
{
19
    protected $server;
20
21
    /**
22
     * AuthenticationService constructor.
23
     *
24
     * @param ResourceServer|null $server Optional resource server.
25
     */
26
    public function __construct(ResourceServer $server = null)
27
    {
28
        $this->server = $server ?: $this->createServer();
29
    }
30
31
    /**
32
     * Authenticate the request. Adds oauth fields as headers on the request.
33
     *
34
     * @param HTTPRequest $request The SilverStripe request object to be authenticated.
35
     *
36
     * @return HTTPRequest
37
     * @throws AuthenticationException
38
     */
39
    public function authenticate(HTTPRequest $request): HTTPRequest
40
    {
41
        $requestAdapter = new HttpRequestAdapter();
42
        $responseAdapter = new HttpResponseAdapter();
43
44
        // missing vars (cli)
45
        $this->addMissingServerVariables($requestAdapter);
46
47
        $server = $this->getServer();
48
        $psrRequest = $requestAdapter->toPsr7($request);
49
        $psrResponse = new Response();
50
51
        try {
52
            $psrRequest = $server->validateAuthenticatedRequest($psrRequest);
53
        } catch (OAuthServerException $exception) {
54
            // convert to authentication exception
55
            throw new AuthenticationException(
56
                $exception->getMessage(),
57
                $exception->getCode(),
58
                $responseAdapter->fromPsr7($exception->generateHttpResponse($psrResponse))
0 ignored issues
show
Bug introduced by Conrad
It seems like $responseAdapter->fromPs...Response($psrResponse)) targeting Robbie\Psr7\HttpResponseAdapter::fromPsr7() can also be of type object<SilverStripe\Control\HTTPRequest>; however, AdvancedLearning\Oauth2S...xception::__construct() does only seem to accept object<SilverStripe\Control\HTTPResponse>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
59
            );
60
        } catch (\Exception $exception) {
61
            // convert to authentication exception
62
            throw new AuthenticationException(
63
                $exception->getMessage(),
64
                $exception->getCode(),
65
                $responseAdapter->fromPsr7(
0 ignored issues
show
Bug introduced by Conrad
It seems like $responseAdapter->fromPs...Response($psrResponse)) targeting Robbie\Psr7\HttpResponseAdapter::fromPsr7() can also be of type object<SilverStripe\Control\HTTPRequest>; however, AdvancedLearning\Oauth2S...xception::__construct() does only seem to accept object<SilverStripe\Control\HTTPResponse>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
66
                    (new OAuthServerException($exception->getMessage(), 0, 'unknown_error', 500))
67
                        ->generateHttpResponse($psrResponse)
68
                )
69
            );
70
        }
71
        // add the request attributes as custom auth headers
72
        foreach ($psrRequest->getAttributes() as $attribute => $value) {
73
            $request->addHeader($attribute, $value);
74
        }
75
76
        return $request;
77
    }
78
79
    /**
80
     * Override the default ResourceServer.
81
     *
82
     * @param ResourceServer $v The new ResourceServer to use.
83
     *
84
     * @return $this
85
     */
86
    public function setServer(ResourceServer $v): Authenticator
87
    {
88
        $this->server = $v;
89
        return $this;
90
    }
91
92
    /**
93
     * Get the ResourceServer.
94
     *
95
     * @return ResourceServer
96
     */
97
    public function getServer(): ResourceServer
98
    {
99
        return $this->server;
100
    }
101
102
    /**
103
     * Create a default ResourceServer. Used if one isn't provided.
104
     *
105
     * @return ResourceServer
106
     */
107
    protected function createServer(): ResourceServer
108
    {
109
        // Init our repositories
110
        $accessTokenRepository = new AccessTokenRepository(); // instance of AccessTokenRepositoryInterface
111
112
        // Path to authorization server's public key
113
        $publicKeyPath = Environment::getEnv('OAUTH_PUBLIC_KEY_PATH');
114
115
        // Relative paths to the web root
116
        $publicKeyPath = str_replace('{BASE_DIR}', Director::baseFolder(), $publicKeyPath);
117
118
        // Setup the authorization server
119
        return new ResourceServer(
120
            $accessTokenRepository,
121
            $publicKeyPath
122
        );
123
    }
124
125
    /**
126
     * Cli is missing some $_SERVER variables.
127
     *
128
     * @param HttpRequestAdapter $adapter
129
     */
130
    protected function addMissingServerVariables(HttpRequestAdapter $adapter)
131
    {
132
        $vars = $adapter->getServerVars() ?: [];
133
        $defaults = [
134
            'SERVER_PORT' => 80,
135
            'HTTP_HOST' => Environment::getEnv('SS_BASE_URL')
136
        ];
137
138
        foreach ($defaults as $key => $value) {
139
            if (empty($vars[$key])) {
140
                $vars[$key] = $value;
141
            }
142
        }
143
144
        $adapter->setServerVars($vars);
145
    }
146
}
147