1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @author Boris Guéry <[email protected]> |
4
|
|
|
*/ |
5
|
|
|
|
6
|
|
|
namespace Bgy\OAuth2; |
7
|
|
|
|
8
|
|
|
use Bgy\OAuth2\GrantType\GrantType; |
9
|
|
|
use Bgy\OAuth2\Storage\AccessTokenStorage; |
10
|
|
|
use Bgy\OAuth2\Storage\ClientStorage; |
11
|
|
|
use Bgy\OAuth2\Storage\RefreshTokenStorage; |
12
|
|
|
|
13
|
|
|
class AuthorizationServerConfigurationBuilder |
14
|
|
|
{ |
15
|
|
|
private $defaultOptions = [ |
16
|
|
|
'client_storage' => null, |
17
|
|
|
'access_token_storage' => null, |
18
|
|
|
'refresh_token_storage' => null, |
19
|
|
|
'access_token_generator' => null, |
20
|
|
|
'always_require_a_client' => false, |
21
|
|
|
'access_token_length' => 32, |
22
|
|
|
'access_token_ttl' => 3600, |
23
|
|
|
'always_generate_a_refresh_token' => false, |
24
|
|
|
'revoke_refresh_token_when_used' => true, |
25
|
|
|
'grant_types' => [] |
26
|
|
|
]; |
27
|
|
|
|
28
|
|
|
private $options = [ |
29
|
|
|
'client_storage' => null, |
30
|
|
|
'access_token_storage' => null, |
31
|
|
|
'refresh_token_storage' => null, |
32
|
|
|
'access_token_generator' => null, |
33
|
|
|
'always_require_a_client' => false, |
34
|
|
|
'access_token_length' => 32, |
35
|
|
|
'access_token_ttl' => 3600, |
36
|
|
|
'always_generate_a_refresh_token' => false, |
37
|
|
|
'revoke_refresh_token_when_used' => true, |
38
|
|
|
'grant_types' => [] |
39
|
|
|
]; |
40
|
|
|
|
41
|
|
|
private $built = false; |
42
|
|
|
|
43
|
|
|
private $configuration; |
44
|
|
|
|
45
|
|
|
public function __construct() |
46
|
|
|
{ |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
public function setClientStorage(ClientStorage $clientStorage) |
50
|
|
|
{ |
51
|
|
|
$this->options['client_storage'] = $clientStorage; |
52
|
|
|
|
53
|
|
|
return $this; |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
public function setAccessTokenStorage(AccessTokenStorage $clientStorage) |
57
|
|
|
{ |
58
|
|
|
$this->options['access_token_storage'] = $clientStorage; |
59
|
|
|
|
60
|
|
|
return $this; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
public function setRefreshStorage(RefreshTokenStorage $clientStorage) |
64
|
|
|
{ |
65
|
|
|
$this->options['refresh_token_storage'] = $clientStorage; |
66
|
|
|
|
67
|
|
|
return $this; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
public function alwaysRequireAClient($flag) |
71
|
|
|
{ |
72
|
|
|
$this->options['always_require_a_client'] = (bool) $flag; |
73
|
|
|
|
74
|
|
|
return $this; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
public function shouldRevokeRefreshTokenWhenUsed($flag) |
78
|
|
|
{ |
79
|
|
|
$this->options['revoke_refresh_token_when_used'] = (bool) $flag; |
80
|
|
|
|
81
|
|
|
return $this; |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
public function alwaysGenerateARefreshToken($flag) |
85
|
|
|
{ |
86
|
|
|
$this->options['always_generate_a_refresh_token'] = (bool) $flag; |
87
|
|
|
|
88
|
|
|
return $this; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
public function setAccessTokenTTL($ttlInSeconds) |
92
|
|
|
{ |
93
|
|
|
$this->options['access_token_ttl'] = (int) $ttlInSeconds; |
94
|
|
|
|
95
|
|
|
return $this; |
96
|
|
|
|
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
public function setAccessTokenGenerator($accessTokenGenerator) |
100
|
|
|
{ |
101
|
|
|
$this->options['access_token_generator'] = $accessTokenGenerator; |
102
|
|
|
|
103
|
|
|
return $this; |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
public function addGrantType(GrantType $grantType, $overrideExisting = false) |
107
|
|
|
{ |
108
|
|
|
if (isset($this->options['grant_types'][$grantType->getIdentifier()]) && !$overrideExisting) { |
109
|
|
|
|
110
|
|
|
throw UnableToAddGrantType::aGrantTypeExtensionIsAlreadyRegisteredForThisIdentifier( |
111
|
|
|
$grantType->getIdentifier(), |
112
|
|
|
get_class($this->options['grant_types'][$grantType->getIdentifier()]) |
113
|
|
|
); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
$this->options['grant_types'][$grantType->getIdentifier()] = $grantType; |
117
|
|
|
|
118
|
|
|
return $this; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
public function build() |
122
|
|
|
{ |
123
|
|
|
// all options without a default value (not null) are required |
124
|
|
|
$missingOptions = array_filter($this->options, function ($value, $key) { |
125
|
|
|
return (null === $value); |
126
|
|
|
}, ARRAY_FILTER_USE_BOTH); |
127
|
|
|
|
128
|
|
|
if (count($missingOptions) > 0) { |
129
|
|
|
|
130
|
|
|
throw new \RuntimeException(sprintf( |
131
|
|
|
'You must configure the following options: %s', |
132
|
|
|
rtrim(implode(", ", array_keys($missingOptions)), ", ") |
133
|
|
|
)); |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
$this->built = true; |
137
|
|
|
|
138
|
|
|
$this->configuration = new AuthorizationServerConfiguration( |
139
|
|
|
$this->options['client_storage'], |
140
|
|
|
$this->options['access_token_storage'], |
141
|
|
|
$this->options['refresh_token_storage'], |
|
|
|
|
142
|
|
|
$this->options['grant_types'], |
143
|
|
|
$this->options['access_token_generator'], |
144
|
|
|
[ |
145
|
|
|
'always_require_a_client' => $this->options['always_require_a_client'], |
146
|
|
|
'access_token_ttl' => $this->options['access_token_ttl'], |
147
|
|
|
'access_token_length' => $this->options['access_token_length'], |
148
|
|
|
'always_generate_a_refresh_token' => $this->options['always_generate_a_refresh_token'], |
149
|
|
|
] |
150
|
|
|
); |
151
|
|
|
|
152
|
|
|
return $this; |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
public function reset() |
156
|
|
|
{ |
157
|
|
|
$this->options = $this->defaultOptions; |
158
|
|
|
|
159
|
|
|
$this->built = false; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
public function getAuthorizationServerConfiguration() |
163
|
|
|
{ |
164
|
|
|
if (!$this->built) { |
165
|
|
|
|
166
|
|
|
throw new \LogicException('You must build() the configuration before to get it.'); |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
return $this->configuration; |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.