Skip to content

Commit

Permalink
Merge pull request #115 from RonasIT/97-add-custom-authentication-hea…
Browse files Browse the repository at this point in the history
…der-support

feat: add ability to select security in source key.
  • Loading branch information
DenTray committed Dec 26, 2023
2 parents e39de87 + 0c2fcae commit 581e2f2
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 33 deletions.
17 changes: 15 additions & 2 deletions config/auto-doc.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,22 @@
|--------------------------------------------------------------------------
|
| Library name, which used to secure the project.
| Available values: "jwt", "laravel", "null"
| Should have one of the key from the `security_drivers` config
*/
'security' => '',
'security_drivers' => [
'jwt' => [
'type' => 'apiKey',
'name' => 'Authorization',
'in' => 'header'
],
'laravel' => [
'type' => 'apiKey',
'name' => '__ym_uid',
'in' => 'cookie'
]
],

'defaults' => [

/*
Expand Down Expand Up @@ -171,5 +184,5 @@
'development'
],

'config_version' => '2.6'
'config_version' => '2.7'
];
51 changes: 28 additions & 23 deletions src/Services/SwaggerService.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ protected function initConfig()
if (!view()->exists("auto-doc::documentation-{$documentationViewer}")) {
throw new UnsupportedDocumentationViewerException($documentationViewer);
}

$securityDriver = Arr::get($this->config, 'security');

if ($securityDriver && !array_key_exists($securityDriver, Arr::get($this->config, 'security_drivers'))) {
throw new WrongSecurityConfigException();
}
}

protected function setDriver()
Expand Down Expand Up @@ -170,23 +176,11 @@ protected function generateSecurityDefinition(): ?array

protected function generateSecurityDefinitionObject($type): array
{
switch ($type) {
case 'jwt':
return [
'type' => 'apiKey',
'name' => 'authorization',
'in' => 'header'
];

case 'laravel':
return [
'type' => 'apiKey',
'name' => 'Cookie',
'in' => 'header'
];
default:
throw new WrongSecurityConfigException();
}
return [
'type' => $this->config['security_drivers'][$type]['type'],
'name' => $this->config['security_drivers'][$type]['name'],
'in' => $this->config['security_drivers'][$type]['in']
];
}

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

protected function requestSupportAuth(): bool
{
switch ($this->security) {
case 'jwt':
$header = $this->request->header('authorization');
$security = Arr::get($this->config, 'security');
$securityDriver = Arr::get($this->config, "security_drivers.{$security}");

switch (Arr::get($securityDriver, 'in')) {
case 'header':
// TODO Change this logic after migration on Swagger 3.0
// Swagger 2.0 does not support cookie authorization.
$securityToken = $this->request->hasHeader($securityDriver['name'])
? $this->request->header($securityDriver['name'])
: $this->request->cookie($securityDriver['name']);

break;
case 'laravel':
$header = $this->request->cookie('__ym_uid');
case 'query':
$securityToken = $this->request->query($securityDriver['name']);

break;
default:
$securityToken = null;
}

return !empty($header);
return !empty($securityToken);
}

protected function parseRequestName($request)
Expand Down
57 changes: 52 additions & 5 deletions tests/SwaggerServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,11 @@ public static function getConstructorInvalidTmpData(): array
}

#[DataProvider('getConstructorInvalidTmpData')]
public function testGetDocFileContentInvalidTmpData(string $docFilePath, string $exception, string $exceptionMessage)
{
public function testGetDocFileContentInvalidTmpData(
string $docFilePath,
string $exception,
string $exceptionMessage
) {
$this->mockDriverGetDocumentation($this->getJsonFixture($docFilePath));

$this->expectException($exception);
Expand Down Expand Up @@ -323,6 +326,10 @@ public static function getAddEmptyData(): array
'security' => 'jwt',
'savedTmpDataFixture' => 'tmp_data_request_with_empty_data_jwt',
],
[
'security' => 'query',
'savedTmpDataFixture' => 'tmp_data_request_with_empty_data_query',
],
];
}

Expand All @@ -331,6 +338,23 @@ public function testAddDataRequestWithEmptyDataLaravel(string $security, string
{
config([
'auto-doc.security' => $security,
'auto-doc.security_drivers' => [
'laravel' => [
'name' => 'laravel',
'in' => 'cookie',
'type' => 'apiKey'
],
'jwt' => [
'name' => 'Authorization',
'in' => 'header',
'type' => 'apiKey'
],
'query' => [
'name' => 'api_key',
'in' => 'query',
'type' => 'apiKey'
]
]
]);

$this->mockDriverGetEmptyAndSaveTpmData([], $this->getJsonFixture($savedTmpDataFixture));
Expand Down Expand Up @@ -439,13 +463,36 @@ public static function addDataWithSecurity(): array
'security' => 'jwt',
'requestFixture' => 'tmp_data_search_roles_request_jwt_security',
],
[
'security' => 'query',
'requestFixture' => 'tmp_data_search_roles_request_query_security',
],
];
}

#[DataProvider('addDataWithSecurity')]
public function testAddDataWithJWTSecurity(string $security, string $requestFixture)
public function testAddDataWithSecurity(string $security, string $requestFixture)
{
config(['auto-doc.security' => $security]);
config([
'auto-doc.security' => $security,
'auto-doc.security_drivers' => [
'laravel' => [
'name' => 'laravel',
'in' => 'cookie',
'type' => 'apiKey'
],
'jwt' => [
'name' => 'Authorization',
'in' => 'header',
'type' => 'apiKey'
],
'query' => [
'name' => 'api_key',
'in' => 'query',
'type' => 'apiKey'
]
]
]);

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

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

public function testAddDataWithEmptySecurity()
public function testAddDataWithInvalidSecurity()
{
config(['auto-doc.security' => 'invalid']);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"securityDefinitions": {
"jwt": {
"type": "apiKey",
"name": "authorization",
"name": "Authorization",
"in": "header"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"securityDefinitions": {
"laravel": {
"type": "apiKey",
"name": "Cookie",
"in": "header"
"name": "laravel",
"in": "cookie"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"swagger": "2.0",
"host": "localhost",
"basePath": "\/",
"schemes": [],
"paths": [],
"definitions": [],
"info": {
"description": "This is automatically collected documentation",
"version": "0.0.0",
"title": "Name of Your Application",
"termsOfService": "",
"contact": {
"email": "your@mail.com"
}
},
"securityDefinitions": {
"query": {
"type": "apiKey",
"name": "api_key",
"in": "query"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
{
"swagger": "2.0",
"host": "localhost",
"basePath": "/",
"schemes": [],
"paths": {
"/users/roles": {
"get": {
"tags": [
"users"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "query",
"name": "query",
"description": "string, required",
"type": "string",
"required": true
},
{
"in": "query",
"name": "user_id",
"description": "integer, with_to_array_rule_string_name",
"type": "integer"
},
{
"in": "query",
"name": "is_email_enabled",
"type": "string",
"description": "test_rule_without_to_string"
}
],
"responses": {
"200": {
"description": "Operation successfully done",
"schema": {
"example": [
{
"id": 1,
"name": "admin",
"users": [
{
"id": 1,
"name": "admin"
}
]
},
{
"id": 2,
"name": "client",
"users": [
{
"id": 2,
"name": "first_client"
},
{
"id": 3,
"name": "second_client"
}
]
}
],
"$ref": "#/definitions/getUsersroles200ResponseObject"
}
}
},
"security": [],
"description": "",
"summary": "test",
"deprecated": false
}
}
},
"definitions": {
"getUsersroles200ResponseObject": {
"type": "array",
"properties": {
"items": {
"allOf": [
{
"type": "array"
}
]
}
}
}
},
"info": {
"description": "This is automatically collected documentation",
"version": "0.0.0",
"title": "Name of Your Application",
"termsOfService": "",
"contact": {
"email": "your@email.com"
}
},
"securityDefinitions": {
"query": {
"type": "apiKey",
"name": "authorization",
"in": "header"
}
}
}

0 comments on commit 581e2f2

Please sign in to comment.