Skip to content

Commit

Permalink
OpenAPI 3.0 Support For SecurityDefinitions (#123) Fixes #124
Browse files Browse the repository at this point in the history
* fixes to openapi-3.0 support of security definitions

* fixes to openapi-3.0 support of security definitions

* updated config to show open api 3.0 security example

* minor code cleanup

* refactored

* code cleanup

* styleci fixes

* added testing tweaks for more code coverage

* styleci fixed

* styleci fixed

* skip testing for OpenApi 3

* skip tests when version swagger / open api versions are different then supported test

* fixed test for mixing settings

* styleci fix
  • Loading branch information
joseph-montanez authored and DarkaOnLine committed Mar 2, 2018
1 parent ee1de13 commit 4ad03c4
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 54 deletions.
20 changes: 19 additions & 1 deletion config/l5-swagger.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,25 @@
'read:projects' => 'read your projects',
'write:projects' => 'modify projects in your account',
]
],*/
],
*/

/* Open API 3.0 support
'passport' => [ // Unique name of security
'type' => 'oauth2', // The type of the security scheme. Valid values are "basic", "apiKey" or "oauth2".
'description' => 'Laravel passport oauth2 security.',
'in' => 'header',
'scheme' => 'https',
'flows' => [
"password" => [
"authorizationUrl" => config('app.url') . '/oauth/authorize',
"tokenUrl" => config('app.url') . '/oauth/token',
"refreshUrl" => config('app.url') . '/token/refresh',
"scopes" => []
],
],
],
*/
],

/*
Expand Down
29 changes: 2 additions & 27 deletions src/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public static function generateDocs()
$filename = $docDir.'/'.config('l5-swagger.paths.docs_json', 'api-docs.json');
$swagger->saveAs($filename);

self::appendSecurityDefinisions($filename);
$security = new SecurityDefinitions();
$security->generate($filename);
}
}

Expand All @@ -42,30 +43,4 @@ protected static function defineConstants(array $constants)
}
}
}

protected static function appendSecurityDefinisions(string $filename)
{
$securityConfig = config('l5-swagger.security', []);

if (is_array($securityConfig) && ! empty($securityConfig)) {
$documentation = collect(
json_decode(file_get_contents($filename))
);

$securityDefinitions = $documentation->has('securityDefinitions') ? collect($documentation->get('securityDefinitions')) : collect();

foreach ($securityConfig as $key => $cfg) {
$securityDefinitions->offsetSet($key, self::arrayToObject($cfg));
}

$documentation->offsetSet('securityDefinitions', $securityDefinitions);

file_put_contents($filename, $documentation->toJson());
}
}

public static function arrayToObject($array)
{
return json_decode(json_encode($array));
}
}
99 changes: 99 additions & 0 deletions src/SecurityDefinitions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?php

namespace L5Swagger;

use Illuminate\Support\Collection;

class SecurityDefinitions
{
/**
* Reads in the l5-swagger configuration and appends security settings to documentation.
*
* @param string $filename The path to the generated json documentation
*/
public function generate($filename)
{
$securityConfig = config('l5-swagger.security', []);

if (is_array($securityConfig) && ! empty($securityConfig)) {
$documentation = collect(
json_decode(file_get_contents($filename))
);

$openApi3 = version_compare(config('l5-swagger.swagger_version'), '3.0', '>=');

$documentation = $openApi3 ?
$this->generateOpenApi($documentation, $securityConfig) :
$this->generateSwaggerApi($documentation, $securityConfig);

file_put_contents($filename, $documentation->toJson());
}
}

/**
* Inject security settings for Swagger 1 & 2.
*
* @param Collection $documentation The parse json
* @param array $securityConfig The security settings from l5-swagger
*
* @return Collection
*/
public function generateSwaggerApi(Collection $documentation, array $securityConfig)
{
$securityDefinitions = collect();
if ($documentation->has('securityDefinitions')) {
$securityDefinitions = collect($documentation->get('securityDefinitions'));
}

foreach ($securityConfig as $key => $cfg) {
$securityDefinitions->offsetSet($key, self::arrayToObject($cfg));
}

$documentation->offsetSet('securityDefinitions', $securityDefinitions);

return $documentation;
}

/**
* Inject security settings for OpenApi 3.
*
* @param Collection $documentation The parse json
* @param array $securityConfig The security settings from l5-swagger
*
* @return Collection
*/
public function generateOpenApi(Collection $documentation, array $securityConfig)
{
$components = collect();
if ($documentation->has('components')) {
$components = collect($documentation->get('components'));
}

$securitySchemes = collect();
if ($components->has('securitySchemes')) {
$securitySchemes = collect($components->get('securitySchemes'));
}

foreach ($securityConfig as $key => $cfg) {
$securitySchemes->offsetSet($key, self::arrayToObject($cfg));
}

$components->offsetSet('securitySchemes', $securitySchemes);

$documentation->offsetSet('components', $components);

return $documentation;
}

/**
* Converts an array to an object.
*
* @param $array
*
* @return object
*/
public static function arrayToObject($array)
{
return json_decode(json_encode($array));
}
}
26 changes: 0 additions & 26 deletions tests/GeneratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,30 +74,4 @@ public function canSetValidatorUrl()

$this->assertTrue(file_exists($this->jsonDocsFile()));
}

/** @test */
public function canGenerateApiJsonFileWithSecurityDefinition()
{
$this->setAnnotationsPath();

$cfg = config('l5-swagger');
$security = [
'new_api_key_securitye' => [
'type' => 'apiKey',
'name' => 'api_key_name',
'in' => 'query',
],
];
$cfg['security'] = $security;
config(['l5-swagger' => $cfg]);

Generator::generateDocs();

$this->assertTrue(file_exists($this->jsonDocsFile()));

$this->get(route('l5-swagger.docs'))
->assertSee('new_api_key_securitye')
->assertJsonFragment($security)
->isOk();
}
}
68 changes: 68 additions & 0 deletions tests/SecurityDefinitionsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Tests;

use L5Swagger\Generator;

class SecurityDefinitionsTest extends TestCase
{
/** @test */
public function canGenerateApiJsonFileWithSecurityDefinition()
{
if ($this->isOpenApi()) {
$this->markTestSkipped('only for openApi 2.0');
}
$this->setAnnotationsPath();

$cfg = config('l5-swagger');
$security = [
'new_api_key_securitye' => [
'type' => 'apiKey',
'name' => 'api_key_name',
'in' => 'query',
],
];
$cfg['security'] = $security;
$cfg['swagger_version'] = '2.0';
config(['l5-swagger' => $cfg]);

tap(new Generator)->generateDocs();

$this->assertTrue(file_exists($this->jsonDocsFile()));

$this->get(route('l5-swagger.docs'))
->assertSee('new_api_key_securitye')
->assertJsonFragment($security)
->isOk();
}

/** @test */
public function canGenerateApiJsonFileWithSecurityDefinitionOpenApi3()
{
if (! $this->isOpenApi()) {
$this->markTestSkipped('only for openApi 3.0');
}
$this->setAnnotationsPath();

$cfg = config('l5-swagger');
$security = [
'new_api_key_securitye' => [
'type' => 'apiKey',
'name' => 'api_key_name',
'in' => 'query',
],
];
$cfg['security'] = $security;
$cfg['swagger_version'] = '3.0';
config(['l5-swagger' => $cfg]);

tap(new Generator)->generateDocs();

$this->assertTrue(file_exists($this->jsonDocsFile()));

$this->get(route('l5-swagger.docs'))
->assertSee('new_api_key_securitye')
->assertJsonFragment($security)
->isOk();
}
}
17 changes: 17 additions & 0 deletions tests/storage/annotations/OpenApi/Anotations.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,23 @@
* )
*/

/**
* @OAS\SecurityScheme(
* type="oauth2",
* description="Use a global client_id / client_secret and your username / password combo to obtain a token",
* name="Password Based",
* in="header",
* scheme="https",
* securityScheme="Password Based",
* @OAS\Flow(
* flow="password",
* authorizationUrl="/oauth/authorize",
* tokenUrl="/oauth/token",
* refreshUrl="/oauth/token/refresh"
* )
* )
*/

/**
* @OAS\Tag(
* name="project",
Expand Down
9 changes: 9 additions & 0 deletions tests/storage/annotations/Swagger/Anotations.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@
* )
*/

/**
* @SWG\SecurityScheme(
* securityDefinition="passport",
* type="oauth2",
* tokenUrl="/oauth/token",
* flow="password",
* scopes={}
* )
*/

/**
* @SWG\Get(
Expand Down

0 comments on commit 4ad03c4

Please sign in to comment.