Completed
Push — master ( 3dc8a6...dcf8fe )
by Boris
12:59
created

AuthorizationServer::buildRefreshToken()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 15
rs 9.4285
cc 2
eloc 8
nc 2
nop 1
1
<?php
2
/**
3
 * @author Boris Guéry <[email protected]>
4
 */
5
6
namespace Bgy\OAuth2;
7
8
use Bgy\OAuth2\GrantType\GrantDecision;
9
use Bgy\OAuth2\GrantType\GrantError;
10
use Bgy\OAuth2\GrantType\GrantType;
11
12
class AuthorizationServer
13
{
14
    private $configuration;
15
    private $clientAuthenticator;
16
17
    public function __construct(AuthorizationServerConfiguration $configuration)
18
    {
19
        $this->configuration       = $configuration;
20
        $this->clientAuthenticator = new ClientAuthenticator(
21
            $this->configuration->getClientStorage()
22
        );
23
    }
24
25
    /**
26
     * @param TokenRequestAttempt $tokenRequestAttempt
27
     * @return FailedTokenRequestAttemptResult|SuccessfulTokenRequestAttemptResult
28
     */
29
    public function requestAccessToken(TokenRequestAttempt $tokenRequestAttempt)
30
    {
31
        if (!$this->checkGrantType($tokenRequestAttempt)) {
32
33
            return new FailedTokenRequestAttemptResult(GrantDecision::denied(GrantError::invalidGrant('Unknown grant type')));
34
        }
35
36
        if ($this->checkIfAClientIsAlwaysRequired()) {
37
38
            if (!$this->checkIfAClientIsProvided($tokenRequestAttempt)) {
39
40
                return new FailedTokenRequestAttemptResult(GrantDecision::denied(GrantError::invalidGrant('Missing client_id')));
41
            }
42
43
            if (!$this->checkIfTheProvidedClientIsValid($tokenRequestAttempt)) {
44
45
                return new FailedTokenRequestAttemptResult(GrantDecision::denied(GrantError::accessDenied('Invalid client credentials')));
46
            }
47
48
            if (!$this->checkIfClientSupportsRequestedGrantType($tokenRequestAttempt)) {
49
50
                return new FailedTokenRequestAttemptResult(
51
                    GrantDecision::denied(
52
                        GrantError::invalidGrant(
53
                            sprintf(
54
                                'This client doesn\'t support the following grant type: "%s"',
55
                                $tokenRequestAttempt->getGrantType()
56
                            )
57
                        )
58
                    )
59
                );
60
            }
61
        }
62
63
        $grantDecision = $this->getGrantTypeByIdentifier($tokenRequestAttempt->getGrantType())
64
            ->grant($tokenRequestAttempt)
65
        ;
66
67
        if ($grantDecision->equals(GrantDecision::allowed())) {
68
69
            $accessToken = $this->buildAccessToken($tokenRequestAttempt, $grantDecision);
70
            $refreshToken = $this->buildRefreshToken($accessToken);
71
72
            return new SuccessfulTokenRequestAttemptResult($grantDecision, $accessToken, $refreshToken);
73
        }
74
75
        return new FailedTokenRequestAttemptResult($grantDecision);
76
    }
77
78
    private function checkGrantType(TokenRequestAttempt $tokenRequestAttempt)
79
    {
80
        return (null !== $this->getGrantTypeByIdentifier($tokenRequestAttempt->getGrantType()));
81
    }
82
83
    private function checkIfAClientIsAlwaysRequired()
84
    {
85
86
        return $this->configuration->alwaysRequireAClient();
87
    }
88
89
    private function checkIfAClientIsProvided(TokenRequestAttempt $tokenRequestAttempt)
90
    {
91
        return (false === $tokenRequestAttempt->getInputData()->getClientId());
92
    }
93
94
    private function checkIfTheProvidedClientIsValid(TokenRequestAttempt $tokenRequestAttempt)
95
    {
96
        return $this->clientAuthenticator->isClientValid(
97
            $tokenRequestAttempt->getInputData()->getClientId(),
98
            $tokenRequestAttempt->getInputData()->getClientSecret()
99
        );
100
    }
101
102
    private function checkIfClientSupportsRequestedGrantType(TokenRequestAttempt $tokenRequestAttempt)
103
    {
104
        $client = $this->configuration->getClientStorage()
105
            ->findById($tokenRequestAttempt->getInputData()->getClientId())
106
        ;
107
108
        return in_array($tokenRequestAttempt->getGrantType(), $client->getAllowedGrantTypes());
109
    }
110
111
    private function buildAccessToken(TokenRequestAttempt $tokenRequestAttempt, GrantDecision $grantDecision)
112
    {
113
        if ($grantDecision->isDenied()) {
114
115
            throw new \LogicException('Unable to build an access token with a denied decision');
116
        }
117
118
        $token = $this->configuration->getTokenGenerator()->generate(
119
            ['length' => $this->configuration->getAccessTokenLength()]
120
        )
121
        ;
122
123
        $accessToken = new AccessToken(
124
            $token,
125
            \DateTimeImmutable::createFromFormat(
126
                'U',
127
                date('U') + $this->configuration->getAccessTokenTTL(),
128
                new \DateTimeZone('UTC')
129
            ),
130
            $tokenRequestAttempt->getInputData()->getClientId(),
131
            $grantDecision->getResourceOwnerId(),
132
            []
133
        );
134
135
        $this->configuration->getAccessTokenStorage()->save($accessToken);
136
137
        return $accessToken;
138
    }
139
140
    private function buildRefreshToken(AccessToken $accessToken)
0 ignored issues
show
Unused Code introduced by
The parameter $accessToken is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
141
    {
142
        $refreshToken = null;
143
        if ($this->configuration->alwaysGenerateARefreshToken()) {
144
            $token = $this->configuration->getTokenGenerator()->generate(
145
                ['length' => $this->configuration->getAccessTokenLength()]
146
            )
147
            ;
148
            $refreshToken = new RefreshToken($token);
149
150
            $this->configuration->getRefreshTokenStorage()->save($refreshToken);
151
        }
152
153
        return $refreshToken;
154
    }
155
156
    /**
157
     * @param $identifier
158
     * @return GrantType
159
     */
160
    private function getGrantTypeByIdentifier($identifier)
161
    {
162
        foreach ($this->configuration->getGrantTypeExtensions() as $grantTypeExtension) {
163
            if (strtolower($identifier) === strtolower($grantTypeExtension->getIdentifier())) {
164
165
                return $grantTypeExtension;
166
            }
167
        }
168
169
        return null;
170
    }
171
}
172