5
5
use Illuminate \Foundation \Http \FormRequest ;
6
6
use Illuminate \Routing \Route ;
7
7
use Illuminate \Support \Str ;
8
+ use Illuminate \Support \Arr ;
8
9
use phpDocumentor \Reflection \DocBlockFactory ;
9
10
use ReflectionMethod ;
10
11
11
12
class Generator
12
13
{
14
+ const SECURITY_DEFINITION_NAME = 'OAuth2 ' ;
13
15
const OAUTH_TOKEN_PATH = '/oauth/token ' ;
14
16
const OAUTH_AUTHORIZE_PATH = '/oauth/authorize ' ;
15
17
@@ -20,18 +22,27 @@ class Generator
20
22
protected $ originalUri ;
21
23
protected $ method ;
22
24
protected $ action ;
25
+ protected $ middleware ;
26
+ protected $ docParser ;
27
+ protected $ hasSecurityDefinitions ;
23
28
24
29
public function __construct ($ config , $ routeFilter = null )
25
30
{
26
31
$ this ->config = $ config ;
27
32
$ this ->routeFilter = $ routeFilter ;
28
33
$ this ->docParser = DocBlockFactory::createInstance ();
34
+ $ this ->hasSecurityDefinitions = false ;
29
35
}
30
36
31
37
public function generate ()
32
38
{
33
39
$ this ->docs = $ this ->getBaseInfo ();
34
40
41
+ if ($ this ->config ['parseSecurity ' ] && $ this ->hasOauthRoutes ()) {
42
+ $ this ->docs ['securityDefinitions ' ] = $ this ->generateSecurityDefinitions ();
43
+ $ this ->hasSecurityDefinitions = true ;
44
+ }
45
+
35
46
foreach ($ this ->getAppRoutes () as $ route ) {
36
47
$ this ->originalUri = $ uri = $ this ->getRouteUri ($ route );
37
48
$ this ->uri = strip_optional_char ($ uri );
@@ -40,11 +51,11 @@ public function generate()
40
51
continue ;
41
52
}
42
53
43
- if ($ this ->config ['parseSecurity ' ] && $ this ->isOauthRoute ()) {
44
- $ this ->docs ['securityDefinitions ' ] = $ this ->generateSecurityDefinitions ();
45
- }
54
+ $ middleware = isset ($ route ->getAction ()['middleware ' ]) ? $ route ->getAction ()['middleware ' ] : [];
46
55
47
56
$ this ->action = $ route ->getAction ()['uses ' ];
57
+ $ this ->middleware = $ this ->formatMiddleware ($ middleware );
58
+
48
59
$ methods = $ route ->methods ();
49
60
50
61
if (!isset ($ this ->docs ['paths ' ][$ this ->uri ])) {
@@ -118,22 +129,22 @@ protected function generateSecurityDefinitions()
118
129
$ this ->validateAuthFlow ($ authFlow );
119
130
120
131
$ securityDefinition = [
121
- ' OAuth2 ' => [
132
+ self :: SECURITY_DEFINITION_NAME => [
122
133
'type ' => 'oauth2 ' ,
123
134
'flow ' => $ authFlow ,
124
135
]
125
136
];
126
137
127
138
128
139
if (in_array ($ authFlow , ['implicit ' , 'accessCode ' ])) {
129
- $ securityDefinition [' OAuth2 ' ]['authorizationUrl ' ] = $ this ->getEndpoint (self ::OAUTH_AUTHORIZE_PATH );
140
+ $ securityDefinition [self :: SECURITY_DEFINITION_NAME ]['authorizationUrl ' ] = $ this ->getEndpoint (self ::OAUTH_AUTHORIZE_PATH );
130
141
}
131
142
132
143
if (in_array ($ authFlow , ['password ' , 'application ' , 'accessCode ' ])) {
133
- $ securityDefinition [' OAuth2 ' ]['tokenUrl ' ] = $ this ->getEndpoint (self ::OAUTH_TOKEN_PATH );
144
+ $ securityDefinition [self :: SECURITY_DEFINITION_NAME ]['tokenUrl ' ] = $ this ->getEndpoint (self ::OAUTH_TOKEN_PATH );
134
145
}
135
146
136
- $ securityDefinition [' OAuth2 ' ]['scopes ' ] = $ this ->generateOauthScopes ();
147
+ $ securityDefinition [self :: SECURITY_DEFINITION_NAME ]['scopes ' ] = $ this ->generateOauthScopes ();
137
148
138
149
return $ securityDefinition ;
139
150
}
@@ -157,6 +168,10 @@ protected function generatePath()
157
168
];
158
169
159
170
$ this ->addActionParameters ();
171
+
172
+ if ($ this ->hasSecurityDefinitions ) {
173
+ $ this ->addActionScopes ();
174
+ }
160
175
}
161
176
162
177
protected function addActionParameters ()
@@ -176,6 +191,17 @@ protected function addActionParameters()
176
191
}
177
192
}
178
193
194
+ protected function addActionScopes ()
195
+ {
196
+ foreach ($ this ->middleware as $ middleware ) {
197
+ if ($ middleware ['name ' ] === 'scope ' || $ middleware ['name ' ] === 'scopes ' ) {
198
+ $ this ->docs ['paths ' ][$ this ->uri ][$ this ->method ]['security ' ] = [
199
+ self ::SECURITY_DEFINITION_NAME => $ middleware ['parameters ' ]
200
+ ];
201
+ }
202
+ }
203
+ }
204
+
179
205
protected function getFormRules ()
180
206
{
181
207
if (!is_string ($ this ->action )) {
@@ -237,9 +263,20 @@ private function isFilteredRoute()
237
263
return !preg_match ('/^ ' . preg_quote ($ this ->routeFilter , '/ ' ) . '/ ' , $ this ->uri );
238
264
}
239
265
240
- private function isOauthRoute ()
266
+ /**
267
+ * Assumes routes have been created using Passport::routes()
268
+ */
269
+ private function hasOauthRoutes ()
241
270
{
242
- return $ this ->uri === self ::OAUTH_TOKEN_PATH || $ this ->uri === self ::OAUTH_AUTHORIZE_PATH ;
271
+ foreach ($ this ->getAppRoutes () as $ route ) {
272
+ $ uri = $ this ->getRouteUri ($ route );
273
+
274
+ if ($ uri === self ::OAUTH_TOKEN_PATH || $ uri === self ::OAUTH_AUTHORIZE_PATH ) {
275
+ return true ;
276
+ }
277
+ }
278
+
279
+ return false ;
243
280
}
244
281
245
282
private function getEndpoint (string $ path )
@@ -264,4 +301,17 @@ private function validateAuthFlow(string $flow)
264
301
throw new LaravelSwaggerException ('Invalid OAuth flow passed ' );
265
302
}
266
303
}
304
+
305
+ private function formatMiddleware ($ middleware )
306
+ {
307
+ $ middleware = Arr::wrap ($ middleware );
308
+
309
+ return array_map (function ($ mw ) {
310
+ $ tokens = explode (': ' , $ mw , 2 );
311
+ $ name = $ tokens [0 ];
312
+ $ parameters = isset ($ tokens [1 ]) ? explode (', ' , $ tokens [1 ]) : [];
313
+
314
+ return compact ('name ' , 'parameters ' );
315
+ }, $ middleware );
316
+ }
267
317
}
0 commit comments