Skip to content

Commit

Permalink
fix(scopes): Allow scopes and tags without parameter names
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <[email protected]>
  • Loading branch information
nickvergessen committed Jan 12, 2024
1 parent a152105 commit 0c5e149
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 7 deletions.
18 changes: 11 additions & 7 deletions src/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ public static function cleanSchemaName(string $name): string {
return substr($name, strlen($readableAppID));
}

protected static function getScopeNameFromAttributeArgument(Arg $arg, string $routeName): ?string {
if ($arg->name->name === 'scope') {
protected static function getScopeNameFromAttributeArgument(Arg $arg, int $key, string $routeName): ?string {
if ($arg->name?->name === 'scope' || ($arg->name === null && $key === 0)) {
if ($arg->value instanceof ClassConstFetch) {
if ($arg->value->class->getLast() === self::OPENAPI_ATTRIBUTE_CLASSNAME) {
return self::getScopeNameFromConst($arg->value);
Expand Down Expand Up @@ -204,8 +204,8 @@ public static function getOpenAPIAttributeScopes(ClassMethod|Class_|Node $node,
continue;
}

foreach ($attr->args as $arg) {
$scope = self::getScopeNameFromAttributeArgument($arg, $routeName);
foreach ($attr->args as $key => $arg) {
$scope = self::getScopeNameFromAttributeArgument($arg, (int) $key, $routeName);
if ($scope !== null) {
$scopes[] = $scope;
}
Expand All @@ -231,13 +231,15 @@ public static function getOpenAPIAttributeTagsByScope(ClassMethod|Class_|Node $n

$foundTags = [];
$foundScopeName = null;
foreach ($attr->args as $arg) {
$foundScopeName = self::getScopeNameFromAttributeArgument($arg, $routeName);
foreach ($attr->args as $key => $arg) {
$foundScopeName = self::getScopeNameFromAttributeArgument($arg, (int) $key, $routeName);

if ($arg->name->name !== 'tags') {
if ($arg->name?->name !== 'tags' && ($arg->name !== null || $key !== 1)) {
continue;
}

if (!$arg->value instanceof Array_) {

continue;
}

Expand All @@ -251,6 +253,8 @@ public static function getOpenAPIAttributeTagsByScope(ClassMethod|Class_|Node $n
if (!empty($foundTags)) {
$tags[$foundScopeName ?: $defaultScope] = $foundTags;
}


}
}
}
Expand Down
2 changes: 2 additions & 0 deletions tests/appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@
['name' => 'AdminSettings#adminScopeImplicitFromAdminRequired', 'url' => '/api/{apiVersion}/default-admin', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'AdminSettings#movedToDefaultScope', 'url' => '/api/{apiVersion}/default-admin-overwritten', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'AdminSettings#movedToSettingsTag', 'url' => '/api/{apiVersion}/moved-with-tag', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'AdminSettings#movedToSettingsTagUnnamed', 'url' => '/api/{apiVersion}/moved-with-unnamed-tag', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],

['name' => 'Federation#federationByController', 'url' => '/api/{apiVersion}/controller-scope', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'Federation#movedToDefaultScope', 'url' => '/api/{apiVersion}/default-scope', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],

['name' => 'Settings#ignoreByDeprecatedAttributeOnMethod', 'url' => '/api/{apiVersion}/ignore-openapi-attribute', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'Settings#ignoreByScopeOnMethod', 'url' => '/api/{apiVersion}/ignore-method-scope', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'Settings#ignoreByUnnamedScopeOnMethod', 'url' => '/api/{apiVersion}/ignore-method-scope-unnamed', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'Settings#movedToAdminScope', 'url' => '/api/{apiVersion}/admin-scope', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'Settings#defaultAndAdminScope', 'url' => '/api/{apiVersion}/default-and-admin-scope', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
['name' => 'Settings#nestedSchemas', 'url' => '/api/{apiVersion}/nested-schemas', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
Expand Down
12 changes: 12 additions & 0 deletions tests/lib/Controller/AdminSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,16 @@ public function movedToDefaultScope(): DataResponse {
public function movedToSettingsTag(): DataResponse {
return new DataResponse();
}

/**
* Route in default scope with tags
*
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
*
* 200: Personal settings updated
*/
#[OpenAPI(OpenAPI::SCOPE_ADMINISTRATION, ['settings', 'admin-settings'])]
public function movedToSettingsTagUnnamed(): DataResponse {
return new DataResponse();
}
}
14 changes: 14 additions & 0 deletions tests/lib/Controller/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ public function ignoreByScopeOnMethod(): DataResponse {
return new DataResponse();
}

/**
* @NoAdminRequired
*
* Route is ignored because of scope on the method but without `scope: ` name
*
* @return DataResponse<Http::STATUS_OK, array<empty>, array{}>
*
* 200: OK
*/
#[OpenAPI(OpenAPI::SCOPE_IGNORE)]
public function ignoreByUnnamedScopeOnMethod(): DataResponse {
return new DataResponse();
}

/**
* @NoAdminRequired
*
Expand Down
73 changes: 73 additions & 0 deletions tests/openapi-administration.json
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,79 @@
}
}
},
"/ocs/v2.php/apps/notifications/api/{apiVersion}/moved-with-unnamed-tag": {
"post": {
"operationId": "settings-admin-settings-moved-to-settings-tag-unnamed",
"summary": "Route in default scope with tags",
"description": "This endpoint requires admin access",
"tags": [
"settings",
"admin-settings"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "apiVersion",
"in": "path",
"required": true,
"schema": {
"type": "string",
"enum": [
"v2"
],
"default": "v2"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Personal settings updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
}
},
"/ocs/v2.php/apps/notifications/api/{apiVersion}/admin-scope": {
"post": {
"operationId": "settings-moved-to-admin-scope",
Expand Down

0 comments on commit 0c5e149

Please sign in to comment.