Skip to content

Commit 581e2f2

Browse files
authored
Merge pull request #115 from RonasIT/97-add-custom-authentication-header-support
feat: add ability to select security in source key.
2 parents e39de87 + 0c2fcae commit 581e2f2

File tree

7 files changed

+232
-33
lines changed

7 files changed

+232
-33
lines changed

config/auto-doc.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,22 @@
7373
|--------------------------------------------------------------------------
7474
|
7575
| Library name, which used to secure the project.
76-
| Available values: "jwt", "laravel", "null"
76+
| Should have one of the key from the `security_drivers` config
7777
*/
7878
'security' => '',
79+
'security_drivers' => [
80+
'jwt' => [
81+
'type' => 'apiKey',
82+
'name' => 'Authorization',
83+
'in' => 'header'
84+
],
85+
'laravel' => [
86+
'type' => 'apiKey',
87+
'name' => '__ym_uid',
88+
'in' => 'cookie'
89+
]
90+
],
91+
7992
'defaults' => [
8093

8194
/*
@@ -171,5 +184,5 @@
171184
'development'
172185
],
173186

174-
'config_version' => '2.6'
187+
'config_version' => '2.7'
175188
];

src/Services/SwaggerService.php

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ protected function initConfig()
105105
if (!view()->exists("auto-doc::documentation-{$documentationViewer}")) {
106106
throw new UnsupportedDocumentationViewerException($documentationViewer);
107107
}
108+
109+
$securityDriver = Arr::get($this->config, 'security');
110+
111+
if ($securityDriver && !array_key_exists($securityDriver, Arr::get($this->config, 'security_drivers'))) {
112+
throw new WrongSecurityConfigException();
113+
}
108114
}
109115

110116
protected function setDriver()
@@ -170,23 +176,11 @@ protected function generateSecurityDefinition(): ?array
170176

171177
protected function generateSecurityDefinitionObject($type): array
172178
{
173-
switch ($type) {
174-
case 'jwt':
175-
return [
176-
'type' => 'apiKey',
177-
'name' => 'authorization',
178-
'in' => 'header'
179-
];
180-
181-
case 'laravel':
182-
return [
183-
'type' => 'apiKey',
184-
'name' => 'Cookie',
185-
'in' => 'header'
186-
];
187-
default:
188-
throw new WrongSecurityConfigException();
189-
}
179+
return [
180+
'type' => $this->config['security_drivers'][$type]['type'],
181+
'name' => $this->config['security_drivers'][$type]['name'],
182+
'in' => $this->config['security_drivers'][$type]['in']
183+
];
190184
}
191185

192186
public function addData(Request $request, $response)
@@ -701,16 +695,27 @@ protected function getSummary($request, array $annotations)
701695

702696
protected function requestSupportAuth(): bool
703697
{
704-
switch ($this->security) {
705-
case 'jwt':
706-
$header = $this->request->header('authorization');
698+
$security = Arr::get($this->config, 'security');
699+
$securityDriver = Arr::get($this->config, "security_drivers.{$security}");
700+
701+
switch (Arr::get($securityDriver, 'in')) {
702+
case 'header':
703+
// TODO Change this logic after migration on Swagger 3.0
704+
// Swagger 2.0 does not support cookie authorization.
705+
$securityToken = $this->request->hasHeader($securityDriver['name'])
706+
? $this->request->header($securityDriver['name'])
707+
: $this->request->cookie($securityDriver['name']);
708+
707709
break;
708-
case 'laravel':
709-
$header = $this->request->cookie('__ym_uid');
710+
case 'query':
711+
$securityToken = $this->request->query($securityDriver['name']);
712+
710713
break;
714+
default:
715+
$securityToken = null;
711716
}
712717

713-
return !empty($header);
718+
return !empty($securityToken);
714719
}
715720

716721
protected function parseRequestName($request)

tests/SwaggerServiceTest.php

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,11 @@ public static function getConstructorInvalidTmpData(): array
293293
}
294294

295295
#[DataProvider('getConstructorInvalidTmpData')]
296-
public function testGetDocFileContentInvalidTmpData(string $docFilePath, string $exception, string $exceptionMessage)
297-
{
296+
public function testGetDocFileContentInvalidTmpData(
297+
string $docFilePath,
298+
string $exception,
299+
string $exceptionMessage
300+
) {
298301
$this->mockDriverGetDocumentation($this->getJsonFixture($docFilePath));
299302

300303
$this->expectException($exception);
@@ -323,6 +326,10 @@ public static function getAddEmptyData(): array
323326
'security' => 'jwt',
324327
'savedTmpDataFixture' => 'tmp_data_request_with_empty_data_jwt',
325328
],
329+
[
330+
'security' => 'query',
331+
'savedTmpDataFixture' => 'tmp_data_request_with_empty_data_query',
332+
],
326333
];
327334
}
328335

@@ -331,6 +338,23 @@ public function testAddDataRequestWithEmptyDataLaravel(string $security, string
331338
{
332339
config([
333340
'auto-doc.security' => $security,
341+
'auto-doc.security_drivers' => [
342+
'laravel' => [
343+
'name' => 'laravel',
344+
'in' => 'cookie',
345+
'type' => 'apiKey'
346+
],
347+
'jwt' => [
348+
'name' => 'Authorization',
349+
'in' => 'header',
350+
'type' => 'apiKey'
351+
],
352+
'query' => [
353+
'name' => 'api_key',
354+
'in' => 'query',
355+
'type' => 'apiKey'
356+
]
357+
]
334358
]);
335359

336360
$this->mockDriverGetEmptyAndSaveTpmData([], $this->getJsonFixture($savedTmpDataFixture));
@@ -439,13 +463,36 @@ public static function addDataWithSecurity(): array
439463
'security' => 'jwt',
440464
'requestFixture' => 'tmp_data_search_roles_request_jwt_security',
441465
],
466+
[
467+
'security' => 'query',
468+
'requestFixture' => 'tmp_data_search_roles_request_query_security',
469+
],
442470
];
443471
}
444472

445473
#[DataProvider('addDataWithSecurity')]
446-
public function testAddDataWithJWTSecurity(string $security, string $requestFixture)
474+
public function testAddDataWithSecurity(string $security, string $requestFixture)
447475
{
448-
config(['auto-doc.security' => $security]);
476+
config([
477+
'auto-doc.security' => $security,
478+
'auto-doc.security_drivers' => [
479+
'laravel' => [
480+
'name' => 'laravel',
481+
'in' => 'cookie',
482+
'type' => 'apiKey'
483+
],
484+
'jwt' => [
485+
'name' => 'Authorization',
486+
'in' => 'header',
487+
'type' => 'apiKey'
488+
],
489+
'query' => [
490+
'name' => 'api_key',
491+
'in' => 'query',
492+
'type' => 'apiKey'
493+
]
494+
]
495+
]);
449496

450497
$this->mockDriverGetEmptyAndSaveTpmData($this->getJsonFixture($requestFixture));
451498

@@ -458,7 +505,7 @@ public function testAddDataWithJWTSecurity(string $security, string $requestFixt
458505
$service->addData($request, $response);
459506
}
460507

461-
public function testAddDataWithEmptySecurity()
508+
public function testAddDataWithInvalidSecurity()
462509
{
463510
config(['auto-doc.security' => 'invalid']);
464511

tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_jwt.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
"securityDefinitions": {
1818
"jwt": {
1919
"type": "apiKey",
20-
"name": "authorization",
20+
"name": "Authorization",
2121
"in": "header"
2222
}
2323
}

tests/fixtures/SwaggerServiceTest/tmp_data_request_with_empty_data_laravel.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
"securityDefinitions": {
1818
"laravel": {
1919
"type": "apiKey",
20-
"name": "Cookie",
21-
"in": "header"
20+
"name": "laravel",
21+
"in": "cookie"
2222
}
2323
}
2424
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"swagger": "2.0",
3+
"host": "localhost",
4+
"basePath": "\/",
5+
"schemes": [],
6+
"paths": [],
7+
"definitions": [],
8+
"info": {
9+
"description": "This is automatically collected documentation",
10+
"version": "0.0.0",
11+
"title": "Name of Your Application",
12+
"termsOfService": "",
13+
"contact": {
14+
"email": "your@mail.com"
15+
}
16+
},
17+
"securityDefinitions": {
18+
"query": {
19+
"type": "apiKey",
20+
"name": "api_key",
21+
"in": "query"
22+
}
23+
}
24+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{
2+
"swagger": "2.0",
3+
"host": "localhost",
4+
"basePath": "/",
5+
"schemes": [],
6+
"paths": {
7+
"/users/roles": {
8+
"get": {
9+
"tags": [
10+
"users"
11+
],
12+
"consumes": [
13+
"application/json"
14+
],
15+
"produces": [
16+
"application/json"
17+
],
18+
"parameters": [
19+
{
20+
"in": "query",
21+
"name": "query",
22+
"description": "string, required",
23+
"type": "string",
24+
"required": true
25+
},
26+
{
27+
"in": "query",
28+
"name": "user_id",
29+
"description": "integer, with_to_array_rule_string_name",
30+
"type": "integer"
31+
},
32+
{
33+
"in": "query",
34+
"name": "is_email_enabled",
35+
"type": "string",
36+
"description": "test_rule_without_to_string"
37+
}
38+
],
39+
"responses": {
40+
"200": {
41+
"description": "Operation successfully done",
42+
"schema": {
43+
"example": [
44+
{
45+
"id": 1,
46+
"name": "admin",
47+
"users": [
48+
{
49+
"id": 1,
50+
"name": "admin"
51+
}
52+
]
53+
},
54+
{
55+
"id": 2,
56+
"name": "client",
57+
"users": [
58+
{
59+
"id": 2,
60+
"name": "first_client"
61+
},
62+
{
63+
"id": 3,
64+
"name": "second_client"
65+
}
66+
]
67+
}
68+
],
69+
"$ref": "#/definitions/getUsersroles200ResponseObject"
70+
}
71+
}
72+
},
73+
"security": [],
74+
"description": "",
75+
"summary": "test",
76+
"deprecated": false
77+
}
78+
}
79+
},
80+
"definitions": {
81+
"getUsersroles200ResponseObject": {
82+
"type": "array",
83+
"properties": {
84+
"items": {
85+
"allOf": [
86+
{
87+
"type": "array"
88+
}
89+
]
90+
}
91+
}
92+
}
93+
},
94+
"info": {
95+
"description": "This is automatically collected documentation",
96+
"version": "0.0.0",
97+
"title": "Name of Your Application",
98+
"termsOfService": "",
99+
"contact": {
100+
"email": "your@email.com"
101+
}
102+
},
103+
"securityDefinitions": {
104+
"query": {
105+
"type": "apiKey",
106+
"name": "authorization",
107+
"in": "header"
108+
}
109+
}
110+
}

0 commit comments

Comments
 (0)