diff --git a/CHANGELOG.md b/CHANGELOG.md index adba85c..e9bb833 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +## [0.13.0] - 2017-11-03 +- Added api required endpoint access exceptions +- Upgrade Swagger to OpenAPI 3.0 specification ## [0.12.0] - 2017-08-17 ### Changed @@ -77,7 +80,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## 0.1.0 - 2015-10-24 First official release working with the new [dreamfactory](https://github.com/dreamfactorysoftware/dreamfactory) project. -[Unreleased]: https://github.com/dreamfactorysoftware/df-oauth/compare/0.12.0...HEAD +[Unreleased]: https://github.com/dreamfactorysoftware/df-oauth/compare/0.13.0...HEAD +[0.13.0]: https://github.com/dreamfactorysoftware/df-oauth/compare/0.12.0...0.13.0 [0.12.0]: https://github.com/dreamfactorysoftware/df-oauth/compare/0.11.0...0.12.0 [0.11.0]: https://github.com/dreamfactorysoftware/df-oauth/compare/0.10.0...0.11.0 [0.10.0]: https://github.com/dreamfactorysoftware/df-oauth/compare/0.9.0...0.10.0 diff --git a/composer.json b/composer.json index 86e3a55..ad746b0 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "wiki": "https://wiki.dreamfactory.com" }, "require": { - "dreamfactory/df-core": "~0.12.0", + "dreamfactory/df-core": "~0.13.0", "laravel/socialite": "~2.0", "socialiteproviders/microsoft-live": "^2.0", "socialiteproviders/twitter": "^2.0" @@ -38,7 +38,7 @@ }, "extra": { "branch-alias": { - "dev-develop": "0.12.x-dev" + "dev-develop": "0.13.x-dev" } } } diff --git a/src/Resources/SSO.php b/src/Resources/SSO.php index 65aa710..cc1d093 100644 --- a/src/Resources/SSO.php +++ b/src/Resources/SSO.php @@ -32,79 +32,79 @@ protected function handlePOST() } /** {@inheritdoc} */ - public static function getApiDocInfo($service, array $resource = []) + protected function getApiDocPaths() { - $base = parent::getApiDocInfo($service, $resource); - $serviceName = strtolower($service); - $class = trim(strrchr(static::class, '\\'), '\\'); - $resourceName = strtolower(array_get($resource, 'name', $class)); - $path = '/' . $serviceName . '/' . $resourceName; - unset($base['paths'][$path]['get']); - $base['paths'][$path]['post'] = [ - 'tags' => [$serviceName], - 'summary' => 'performSSO() - Single Sign On', - 'operationId' => 'performSSO', - 'consumes' => ['application/json', 'application/xml'], - 'produces' => ['application/json', 'application/xml'], - 'description' => 'Performs Single Sign On using OAuth 2.0 access token', - 'parameters' => [ - [ - 'name' => 'body', - 'description' => 'Content - OAuth token response', - 'schema' => [ - 'type' => 'object', - 'required' => ['access_token', 'token_type'], - 'properties' => [ - 'access_token' => [ - 'type' => 'string', - 'description' => 'The access token issued by the authorization server.' - ], - 'token_type' => [ - 'type' => 'string', - 'description' => 'The type of the token. Typically Bearer.' - ], - 'expires_in' => [ - 'type' => 'integer', - 'description' => 'The lifetime in seconds of the access token.' - ], - 'refresh_token' => [ - 'type' => 'string', - 'description' => 'The refresh token, which can be used to obtain new access tokens.' - ], - 'scope' => [ - 'type' => 'string', - 'description' => 'OPTIONAL, if identical to the scope requested by the client; otherwise, REQUIRED.' + $resourceName = strtolower($this->name); + $path = '/' . $resourceName; + $service = $this->getServiceName(); + $capitalized = camelize($service); + + $base = [ + $path => [ + 'post' => [ + 'summary' => 'Single Sign On', + 'description' => 'Performs Single Sign On using OAuth 2.0 access token', + 'operationId' => 'perform' . $capitalized . 'SSO', + 'requestBody' => [ + 'description' => 'Content - OAuth token response', + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + 'required' => ['access_token', 'token_type'], + 'properties' => [ + 'access_token' => [ + 'type' => 'string', + 'description' => 'The access token issued by the authorization server.' + ], + 'token_type' => [ + 'type' => 'string', + 'description' => 'The type of the token. Typically Bearer.' + ], + 'expires_in' => [ + 'type' => 'integer', + 'description' => 'The lifetime in seconds of the access token.' + ], + 'refresh_token' => [ + 'type' => 'string', + 'description' => 'The refresh token, which can be used to obtain new access tokens.' + ], + 'scope' => [ + 'type' => 'string', + 'description' => 'OPTIONAL, if identical to the scope requested by the client; otherwise, REQUIRED.' + ], + ], + ], ], - ] + ], + 'required' => true + ], + 'responses' => [ + '200' => [ + 'description' => 'Successful login', + 'content' => [ + 'application/json' => [ + 'schema' => [ + 'type' => 'object', + 'properties' => [ + 'session_token' => ['type' => 'string'], + 'session_id' => ['type' => 'string'], + 'id' => ['type' => 'integer'], + 'name' => ['type' => 'string'], + 'first_name' => ['type' => 'string'], + 'last_name' => ['type' => 'string'], + 'email' => ['type' => 'string'], + 'is_sys_admin' => ['type' => 'string'], + 'last_login_date' => ['type' => 'string'], + 'host' => ['type' => 'string'], + 'oauth_token' => ['type' => 'string'], + ] + ] + ] + ] + ], ], - 'in' => 'body', - 'required' => true - ] - ], - 'responses' => [ - '200' => [ - 'description' => 'Successful login', - 'schema' => [ - 'type' => 'object', - 'properties' => [ - 'session_token' => ['type' => 'string'], - 'session_id' => ['type' => 'string'], - 'id' => ['type' => 'integer'], - 'name' => ['type' => 'string'], - 'first_name' => ['type' => 'string'], - 'last_name' => ['type' => 'string'], - 'email' => ['type' => 'string'], - 'is_sys_admin' => ['type' => 'string'], - 'last_login_date' => ['type' => 'string'], - 'host' => ['type' => 'string'], - 'oauth_token' => ['type' => 'string'], - ] - ] ], - 'default' => [ - 'description' => 'Error', - 'schema' => ['$ref' => '#/definitions/Error'] - ] ], ]; diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index f322a38..5229461 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -1,4 +1,5 @@ app->resolving('df.service', function (ServiceManager $df) { $df->addType( new ServiceType([ - 'name' => 'oauth_facebook', - 'label' => 'Facebook OAuth', - 'description' => 'OAuth service for supporting Facebook authentication and API access.', - 'group' => ServiceTypeGroups::OAUTH, - 'config_handler' => OAuthConfig::class, - 'factory' => function ($config) { + 'name' => 'oauth_facebook', + 'label' => 'Facebook OAuth', + 'description' => 'OAuth service for supporting Facebook authentication and API access.', + 'group' => ServiceTypeGroups::OAUTH, + 'config_handler' => OAuthConfig::class, + 'factory' => function ($config) { return new Facebook($config); }, + 'access_exceptions' => [ + [ + 'verb_mask' => 2, + 'resource' => 'sso', + ], + ], ]) ); $df->addType( new ServiceType([ - 'name' => 'oauth_twitter', - 'label' => 'Twitter OAuth', - 'description' => 'OAuth service for supporting Twitter authentication and API access.', - 'group' => ServiceTypeGroups::OAUTH, - 'config_handler' => OAuthConfig::class, - 'factory' => function ($config) { + 'name' => 'oauth_twitter', + 'label' => 'Twitter OAuth', + 'description' => 'OAuth service for supporting Twitter authentication and API access.', + 'group' => ServiceTypeGroups::OAUTH, + 'config_handler' => OAuthConfig::class, + 'factory' => function ($config) { return new Twitter($config); }, + 'access_exceptions' => [ + [ + 'verb_mask' => 2, + 'resource' => 'sso', + ], + ], ]) ); $df->addType( new ServiceType([ - 'name' => 'oauth_github', - 'label' => 'GitHub OAuth', - 'description' => 'OAuth service for supporting GitHub authentication and API access.', - 'group' => ServiceTypeGroups::OAUTH, - 'config_handler' => OAuthConfig::class, - 'factory' => function ($config) { + 'name' => 'oauth_github', + 'label' => 'GitHub OAuth', + 'description' => 'OAuth service for supporting GitHub authentication and API access.', + 'group' => ServiceTypeGroups::OAUTH, + 'config_handler' => OAuthConfig::class, + 'factory' => function ($config) { return new Github($config); }, + 'access_exceptions' => [ + [ + 'verb_mask' => 2, + 'resource' => 'sso', + ], + ], ]) ); $df->addType( new ServiceType([ - 'name' => 'oauth_google', - 'label' => 'Google OAuth', - 'description' => 'OAuth service for supporting Google authentication and API access.', - 'group' => ServiceTypeGroups::OAUTH, - 'config_handler' => OAuthConfig::class, - 'factory' => function ($config) { + 'name' => 'oauth_google', + 'label' => 'Google OAuth', + 'description' => 'OAuth service for supporting Google authentication and API access.', + 'group' => ServiceTypeGroups::OAUTH, + 'config_handler' => OAuthConfig::class, + 'factory' => function ($config) { return new Google($config); }, + 'access_exceptions' => [ + [ + 'verb_mask' => 2, + 'resource' => 'sso', + ], + ], ]) ); $df->addType( new ServiceType([ - 'name' => 'oauth_linkedin', - 'label' => 'LinkedIn OAuth', - 'description' => 'OAuth service for supporting LinkedIn authentication and API access.', - 'group' => ServiceTypeGroups::OAUTH, - 'config_handler' => OAuthConfig::class, - 'factory' => function ($config) { + 'name' => 'oauth_linkedin', + 'label' => 'LinkedIn OAuth', + 'description' => 'OAuth service for supporting LinkedIn authentication and API access.', + 'group' => ServiceTypeGroups::OAUTH, + 'config_handler' => OAuthConfig::class, + 'factory' => function ($config) { return new LinkedIn($config); }, + 'access_exceptions' => [ + [ + 'verb_mask' => 2, + 'resource' => 'sso', + ], + ], ]) ); $df->addType( new ServiceType([ - 'name' => 'oauth_microsoft-live', - 'label' => 'Microsoft Live OAuth', - 'description' => 'OAuth service for supporting Microsoft Live authentication and API access.', - 'group' => ServiceTypeGroups::OAUTH, - 'config_handler' => OAuthConfig::class, - 'factory' => function ($config) { + 'name' => 'oauth_microsoft-live', + 'label' => 'Microsoft Live OAuth', + 'description' => 'OAuth service for supporting Microsoft Live authentication and API access.', + 'group' => ServiceTypeGroups::OAUTH, + 'config_handler' => OAuthConfig::class, + 'factory' => function ($config) { return new MicrosoftLive($config); }, + 'access_exceptions' => [ + [ + 'verb_mask' => 2, + 'resource' => 'sso', + ], + ], ]) ); $df->addType( new ServiceType([ - 'name' => 'oauth_bitbucket', - 'label' => 'Bitbucket OAuth', - 'description' => 'OAuth 1.0 service for supporting Bitbucket authentication and API access.', - 'group' => ServiceTypeGroups::OAUTH, - 'config_handler' => OAuthConfig::class, - 'factory' => function ($config) { + 'name' => 'oauth_bitbucket', + 'label' => 'Bitbucket OAuth', + 'description' => 'OAuth 1.0 service for supporting Bitbucket authentication and API access.', + 'group' => ServiceTypeGroups::OAUTH, + 'config_handler' => OAuthConfig::class, + 'factory' => function ($config) { return new Bitbucket($config); }, + 'access_exceptions' => [ + [ + 'verb_mask' => 2, + 'resource' => 'sso', + ], + ], ]) ); }); diff --git a/src/Services/BaseOAuthService.php b/src/Services/BaseOAuthService.php index d9af470..04343e6 100644 --- a/src/Services/BaseOAuthService.php +++ b/src/Services/BaseOAuthService.php @@ -251,37 +251,4 @@ protected function getOAuthResponse() { return OAuthTokenMap::whereServiceId($this->id)->whereUserId(Session::getCurrentUserId())->value('response'); } - - /** @inheritdoc */ - public static function getApiDocInfo($service) - { - $base = parent::getApiDocInfo($service); - - $apis = []; - $models = []; - foreach (static::$resources as $resourceInfo) { - $resourceClass = array_get($resourceInfo, 'class_name'); - - if (!class_exists($resourceClass)) { - throw new InternalServerErrorException('Service configuration class name lookup failed for resource ' . - $resourceClass); - } - - $resourceName = array_get($resourceInfo, static::RESOURCE_IDENTIFIER); - if (Session::checkForAnyServicePermissions($service->name, $resourceName)) { - $results = $resourceClass::getApiDocInfo($service->name, $resourceInfo); - if (isset($results, $results['paths'])) { - $apis = array_merge($apis, $results['paths']); - } - if (isset($results, $results['definitions'])) { - $models = array_merge($models, $results['definitions']); - } - } - } - - $base['paths'] = array_merge($base['paths'], $apis); - $base['definitions'] = array_merge($base['definitions'], $models); - - return $base; - } } \ No newline at end of file