diff --git a/src/Controller/HealthzController.php b/src/Controller/HealthzController.php index 3c030dc03..db420433e 100644 --- a/src/Controller/HealthzController.php +++ b/src/Controller/HealthzController.php @@ -11,7 +11,9 @@ use App\Rest\Interfaces\ResponseHandlerInterface; use App\Rest\ResponseHandler; use App\Utils\HealthzService; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -39,27 +41,34 @@ public function __construct( * * @see https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ * - * @OA\Get( - * operationId="healthz", - * responses={ - * @OA\Response( - * response=200, - * description="success", - * @OA\Schema( - * type="object", - * example={"timestamp": "2018-01-01T13:08:05+00:00"}, - * @OA\Property(property="timestamp", type="string"), - * ), - * ), - * }, - * ) - * * @throws Throwable */ #[Route( path: '/healthz', methods: [Request::METHOD_GET], )] + #[OA\Get( + operationId: 'healthz', + responses: [ + new OA\Response( + response: 200, + description: 'success', + content: new JsonContent( + properties: [ + new Property( + property: 'timestamp', + description: 'Timestamp when health check was performed', + type: 'string', + ), + ], + type: 'object', + example: [ + 'timestamp' => '2018-01-01T13:08:05+00:00', + ], + ), + ), + ], + )] public function __invoke(Request $request): Response { return $this->responseHandler->createResponse( diff --git a/src/Controller/VersionController.php b/src/Controller/VersionController.php index 70522fa46..7c2729e92 100644 --- a/src/Controller/VersionController.php +++ b/src/Controller/VersionController.php @@ -9,7 +9,9 @@ namespace App\Controller; use App\Service\Version; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -30,27 +32,34 @@ public function __construct( } /** - * Route for get API version. - * - * @OA\Get( - * operationId="version", - * responses={ - * @OA\Response( - * response=200, - * description="success", - * @OA\Schema( - * type="object", - * example={"version": "1.2.3"}, - * @OA\Property(property="version", type="string", description="Version number"), - * ), - * ), - * }, - * ) + * Route to get API version. */ #[Route( path: '/version', methods: [Request::METHOD_GET], )] + #[OA\Get( + operationId: 'version', + responses: [ + new OA\Response( + response: 200, + description: 'success', + content: new JsonContent( + properties: [ + new Property( + property: 'version', + description: 'Version number of the API in semver format', + type: 'string', + ), + ], + type: 'object', + example: [ + 'version' => '1.2.3', + ], + ), + ), + ], + )] public function __invoke(): JsonResponse { return new JsonResponse([ diff --git a/src/Controller/v1/ApiKey/ApiKeyController.php b/src/Controller/v1/ApiKey/ApiKeyController.php index d6ef42592..39f8726aa 100644 --- a/src/Controller/v1/ApiKey/ApiKeyController.php +++ b/src/Controller/v1/ApiKey/ApiKeyController.php @@ -14,7 +14,7 @@ use App\Resource\ApiKeyResource; use App\Rest\Controller; use App\Rest\Traits\Actions; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; @@ -23,8 +23,6 @@ /** * Class ApiKeyController * - * @OA\Tag(name="ApiKey Management") - * * @package App\Controller * @author TLe, Tarmo Leppänen * @@ -35,6 +33,7 @@ path: '/v1/api_key', )] #[IsGranted(AuthenticatedVoter::IS_AUTHENTICATED_FULLY)] +#[OA\Tag(name: 'ApiKey Management')] class ApiKeyController extends Controller { use Actions\Root\CountAction; diff --git a/src/Controller/v1/Auth/GetTokenController.php b/src/Controller/v1/Auth/GetTokenController.php index 494ce41df..d50011bdc 100644 --- a/src/Controller/v1/Auth/GetTokenController.php +++ b/src/Controller/v1/Auth/GetTokenController.php @@ -10,7 +10,9 @@ use App\Utils\JSON; use JsonException; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -30,45 +32,6 @@ class GetTokenController /** * Endpoint action to get user Json Web Token (JWT) for authentication. * - * @OA\RequestBody( - * request="body", - * description="Credentials object", - * required=true, - * @OA\Schema( - * example={"username": "username", "password": "password"}, - * ) - * ) - * @OA\Response( - * response=200, - * description="JSON Web Token for user", - * @OA\Schema( - * type="object", - * example={"token": "_json_web_token_"}, - * @OA\Property(property="token", type="string", description="Json Web Token"), - * ), - * ) - * @OA\Response( - * response=400, - * description="Bad Request", - * @OA\Schema( - * type="object", - * example={"code": 400, "message": "Bad Request"}, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * @OA\Response( - * response=401, - * description="Unauthorized", - * @OA\Schema( - * type="object", - * example={"code": 401, "message": "Bad credentials"}, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * @OA\Tag(name="Authentication") - * * @throws HttpException * @throws JsonException */ @@ -76,6 +39,70 @@ class GetTokenController path: '/v1/auth/get_token', methods: [Request::METHOD_POST], )] + #[OA\RequestBody( + request: 'body', + description: 'Credentials object', + required: true, + content: new JsonContent( + properties: [ + new Property(property: 'username', type: 'string'), + new Property(property: 'password', type: 'string'), + ], + type: 'object', + example: [ + 'username' => 'username', + 'password' => 'password', + ], + ), + )] + #[OA\Response( + response: 200, + description: 'JSON Web Token for user', + content: new JsonContent( + properties: [ + new Property( + property: 'token', + description: 'Json Web Token', + type: 'string', + ), + ], + type: 'object', + example: [ + 'token' => '_json_web_token_', + ], + ), + )] + #[OA\Response( + response: 400, + description: 'Bad Request', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'code' => 400, + 'message' => 'Bad Request', + ], + ), + )] + #[OA\Response( + response: 401, + description: 'Unauthorized', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'code' => 401, + 'message' => 'Bad credentials', + ], + ), + )] + #[OA\Tag(name: 'Authentication')] public function __invoke(): never { $message = sprintf( diff --git a/src/Controller/v1/Localization/LanguageController.php b/src/Controller/v1/Localization/LanguageController.php index 0ff33cbf2..7269016b1 100644 --- a/src/Controller/v1/Localization/LanguageController.php +++ b/src/Controller/v1/Localization/LanguageController.php @@ -9,7 +9,8 @@ namespace App\Controller\v1\Localization; use App\Service\Localization; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -18,12 +19,11 @@ /** * Class LanguageController * - * @OA\Tag(name="Localization") - * * @package App\Controller\v1\Localization * @author TLe, Tarmo Leppänen */ #[AsController] +#[OA\Tag(name: 'Localization')] class LanguageController { public function __construct( @@ -34,21 +34,23 @@ public function __construct( /** * Endpoint action to get supported languages. This is for use to choose * what language your frontend application can use within its translations. - * - * @OA\Response( - * response=200, - * description="List of language strings.", - * @OA\Schema( - * type="array", - * example={"en","fi"}, - * @OA\Items(type="string"), - * ), - * ) */ #[Route( path: '/v1/localization/language', methods: [Request::METHOD_GET], )] + #[OA\Response( + response: 200, + description: 'List of language strings.', + content: new JsonContent( + type: 'array', + items: new OA\Items( + type: 'string', + example: 'en', + ), + example: ['en', 'fi'], + ), + )] public function __invoke(): JsonResponse { return new JsonResponse($this->localization->getLanguages()); diff --git a/src/Controller/v1/Localization/LocaleController.php b/src/Controller/v1/Localization/LocaleController.php index 461252769..31df3ad4d 100644 --- a/src/Controller/v1/Localization/LocaleController.php +++ b/src/Controller/v1/Localization/LocaleController.php @@ -9,7 +9,8 @@ namespace App\Controller\v1\Localization; use App\Service\Localization; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -18,12 +19,11 @@ /** * Class LocaleController * - * @OA\Tag(name="Localization") - * * @package App\Controller\v1\Localization * @author TLe, Tarmo Leppänen */ #[AsController] +#[OA\Tag(name: 'Localization')] class LocaleController { public function __construct( @@ -35,21 +35,23 @@ public function __construct( * Endpoint action to get supported locales. This is for use to choose what * locale your frontend application can use within its number, time, date, * datetime, etc. formatting. - * - * @OA\Response( - * response=200, - * description="List of locale strings.", - * @OA\Schema( - * type="array", - * example={"en","fi"}, - * @OA\Items(type="string"), - * ), - * ) */ #[Route( path: '/v1/localization/locale', methods: [Request::METHOD_GET], )] + #[OA\Response( + response: 200, + description: 'List of locale strings.', + content: new JsonContent( + type: 'array', + items: new OA\Items( + type: 'string', + example: 'en', + ), + example: ['en', 'fi'], + ), + )] public function __invoke(): JsonResponse { return new JsonResponse($this->localization->getLocales()); diff --git a/src/Controller/v1/Localization/TimeZoneController.php b/src/Controller/v1/Localization/TimeZoneController.php index ae2b2b835..ef7c5f967 100644 --- a/src/Controller/v1/Localization/TimeZoneController.php +++ b/src/Controller/v1/Localization/TimeZoneController.php @@ -9,7 +9,8 @@ namespace App\Controller\v1\Localization; use App\Service\Localization; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -18,12 +19,11 @@ /** * Class TimezoneController * - * @OA\Tag(name="Localization") - * * @package App\Controller\v1\Localization * @author TLe, Tarmo Leppänen */ #[AsController] +#[OA\Tag(name: 'Localization')] class TimeZoneController { public function __construct( @@ -35,46 +35,50 @@ public function __construct( * Endpoint action to get list of supported timezones. This is for use to * choose what timezone your frontend application can use within its date, * time, datetime, etc. formatting. - * - * @OA\Response( - * response=200, - * description="List of timezone objects.", - * @OA\Schema( - * type="array", - * @OA\Items( - * type="object", - * @OA\Property( - * property="timezone", - * type="string", - * example="Europe", - * description="Africa,America,Antarctica,Arctic,Asia,Atlantic,Australia,Europe,Indian,Pacific,UTC.", - * ), - * @OA\Property( - * property="identier", - * type="string", - * example="Europe/Helsinki", - * description="Timezone identifier that you can use with other librariers.", - * ), - * @OA\Property( - * property="offset", - * type="string", - * example="GMT+2:00", - * description="GMT offset of identifier.", - * ), - * @OA\Property( - * property="value", - * type="string", - * example="Europe/Helsinki", - * description="User friendly value of identifier value eg. '_' characters are replaced by space.", - * ), - * ), - * ), - * ) */ #[Route( path: '/v1/localization/timezone', methods: [Request::METHOD_GET], )] + #[OA\Response( + response: 200, + description: 'List of timezone objects.', + content: new JsonContent( + type: 'array', + items: new OA\Items( + properties: [ + new OA\Property( + property: 'timezone', + description: 'Africa, America, Antarctica, Arctic, Asia, Atlantic, Australia, Europe, ' . + 'Indian,Pacific,UTC.', + type: 'string', + example: 'Europe', + ), + new OA\Property( + property: 'identifier', + description: 'Timezone identifier that you can use with other libraries.', + type: 'string', + example: 'Europe/Helsinki', + ), + new OA\Property( + property: 'offset', + description: 'GMT offset of identifier.', + type: 'string', + example: 'GMT+2:00', + ), + new OA\Property( + property: 'value', + description: 'User friendly value of identifier value eg. `_` characters are replaced ' . + 'by space.', + type: 'string', + example: 'Europe/Helsinki', + ), + ], + type: 'object' + ), + example: ['en', 'fi'] + ), + )] public function __invoke(): JsonResponse { return new JsonResponse($this->localization->getTimezones()); diff --git a/src/Controller/v1/Profile/GroupsController.php b/src/Controller/v1/Profile/GroupsController.php index 0ef268db8..8ffc04f45 100644 --- a/src/Controller/v1/Profile/GroupsController.php +++ b/src/Controller/v1/Profile/GroupsController.php @@ -11,7 +11,9 @@ use App\Entity\User; use App\Entity\UserGroup; use Nelmio\ApiDocBundle\Annotation\Model; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -36,62 +38,64 @@ public function __construct( /** * Endpoint action to get current user user groups. - * - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ), - * ) - * @OA\Response( - * response=200, - * description="User groups", - * @OA\Schema( - * type="array", - * @OA\Items( - * ref=@Model( - * type=\App\Entity\UserGroup::class, - * groups={"set.UserProfileGroups"}, - * ), - * ), - * ), - * ) - * @OA\Response( - * response=401, - * description="Invalid token", - * @OA\Schema( - * type="object", - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * @OA\Response( - * response=403, - * description="Access denied", - * @OA\Schema( - * type="403", - * example={ - * "Access denied": "{code: 403, message: 'Access denied'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * @OA\Tag(name="Profile") */ #[Route( path: '/v1/profile/groups', methods: [Request::METHOD_GET], )] #[IsGranted(AuthenticatedVoter::IS_AUTHENTICATED_FULLY)] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Response( + response: 200, + description: 'List of logged in user user groups', + content: new JsonContent( + type: 'array', + items: new OA\Items( + ref: new Model( + type: UserGroup::class, + groups: ['set.UserProfileGroups'], + ), + ), + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] + #[OA\Tag(name: 'Profile')] public function __invoke(User $loggedInUser): JsonResponse { return new JsonResponse( diff --git a/src/Controller/v1/Profile/IndexController.php b/src/Controller/v1/Profile/IndexController.php index 76e7c1799..242b556fd 100644 --- a/src/Controller/v1/Profile/IndexController.php +++ b/src/Controller/v1/Profile/IndexController.php @@ -13,7 +13,9 @@ use App\Utils\JSON; use JsonException; use Nelmio\ApiDocBundle\Annotation\Model; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -40,41 +42,6 @@ public function __construct( /** * Endpoint action to get current user profile data. * - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ), - * ) - * @OA\Response( - * response=200, - * description="User profile data", - * @OA\Schema( - * ref=@Model( - * type=User::class, - * groups={"set.UserProfile"}, - * ), - * ), - * ) - * @OA\Response( - * response=401, - * description="Invalid token", - * @OA\Schema( - * type="object", - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * @OA\Tag(name="Profile") - * * @throws JsonException */ #[Route( @@ -82,6 +49,56 @@ public function __construct( methods: [Request::METHOD_GET], )] #[IsGranted(AuthenticatedVoter::IS_AUTHENTICATED_FULLY)] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Response( + response: 200, + description: 'User profile data', + content: new JsonContent( + ref: new Model( + type: User::class, + groups: ['set.UserProfile'], + ), + type: 'object', + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] + #[OA\Tag(name: 'Profile')] public function __invoke(User $loggedInUser): JsonResponse { /** @var array> $output */ diff --git a/src/Controller/v1/Profile/RolesController.php b/src/Controller/v1/Profile/RolesController.php index 528cb8d84..ba320e07e 100644 --- a/src/Controller/v1/Profile/RolesController.php +++ b/src/Controller/v1/Profile/RolesController.php @@ -10,7 +10,9 @@ use App\Entity\User; use App\Security\RolesService; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -34,45 +36,60 @@ public function __construct( /** * Endpoint action to get current user roles as an array. - * - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ), - * ) - * @OA\Response( - * response=200, - * description="User roles", - * @OA\Schema( - * type="array", - * @OA\Items(type="string"), - * ), - * ) - * @OA\Response( - * response=401, - * description="Invalid token", - * @OA\Schema( - * type="object", - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * @OA\Tag(name="Profile") */ #[Route( path: '/v1/profile/roles', methods: [Request::METHOD_GET], )] #[IsGranted(AuthenticatedVoter::IS_AUTHENTICATED_FULLY)] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Response( + response: 200, + description: 'Logged in user roles', + content: new JsonContent( + type: 'array', + items: new OA\Items(type: 'string', example: 'ROLE_USER'), + example: ['ROLE_USER', 'ROLE_LOGGED'], + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] + #[OA\Tag(name: 'Profile')] public function __invoke(User $loggedInUser): JsonResponse { return new JsonResponse($this->rolesService->getInheritedRoles($loggedInUser->getRoles())); diff --git a/src/Controller/v1/Role/FindOneRoleController.php b/src/Controller/v1/Role/FindOneRoleController.php index 12a72683a..1b06a17f5 100644 --- a/src/Controller/v1/Role/FindOneRoleController.php +++ b/src/Controller/v1/Role/FindOneRoleController.php @@ -12,7 +12,7 @@ use App\Resource\RoleResource; use App\Rest\Controller; use App\Rest\Traits\Methods; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -24,12 +24,11 @@ /** * Class FindOneRoleController * - * @OA\Tag(name="Role Management") - * * @package App\Controller\v1\Role * @author TLe, Tarmo Leppänen */ #[AsController] +#[OA\Tag(name: 'Role Management')] class FindOneRoleController extends Controller { use Methods\FindOneMethod; diff --git a/src/Controller/v1/Role/InheritedRolesController.php b/src/Controller/v1/Role/InheritedRolesController.php index c7ee8426a..713d1cc95 100644 --- a/src/Controller/v1/Role/InheritedRolesController.php +++ b/src/Controller/v1/Role/InheritedRolesController.php @@ -11,7 +11,9 @@ use App\Entity\Role; use App\Enum\Role as RoleEnum; use App\Security\RolesService; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -22,12 +24,11 @@ /** * Class InheritedRolesController * - * @OA\Tag(name="Role Management") - * * @package App\Controller\v1\Role * @author TLe, Tarmo Leppänen */ #[AsController] +#[OA\Tag(name: 'Role Management')] class InheritedRolesController { public function __construct( @@ -38,40 +39,6 @@ public function __construct( /** * Endpoint action to return all inherited roles as an array for specified * Role. - * - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ), - * ) - * @OA\Response( - * response=200, - * description="Inherited roles", - * @OA\Schema( - * type="array", - * @OA\Items( - * type="string", - * ), - * ), - * ) - * @OA\Response( - * response=401, - * description="Invalid token", - * @OA\Schema( - * type="object", - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) */ #[Route( path: '/v1/role/{role}/inherited', @@ -81,6 +48,53 @@ public function __construct( methods: [Request::METHOD_GET], )] #[IsGranted(RoleEnum::ADMIN->value)] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Response( + response: 200, + description: 'Inherited roles', + content: new JsonContent( + type: 'array', + items: new OA\Items(type: 'string', example: 'ROLE_USER'), + example: ['ROLE_USER', 'ROLE_LOGGED'], + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] public function __invoke(Role $role): JsonResponse { return new JsonResponse($this->rolesService->getInheritedRoles([$role->getId()])); diff --git a/src/Controller/v1/Role/RoleController.php b/src/Controller/v1/Role/RoleController.php index 069f506fc..25b2cf38e 100644 --- a/src/Controller/v1/Role/RoleController.php +++ b/src/Controller/v1/Role/RoleController.php @@ -11,7 +11,7 @@ use App\Resource\RoleResource; use App\Rest\Controller; use App\Rest\Traits\Actions; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; @@ -20,8 +20,6 @@ /** * Class RoleController * - * @OA\Tag(name="Role Management") - * * @package App\Controller\v1\Role * @author TLe, Tarmo Leppänen * @@ -32,6 +30,7 @@ path: '/v1/role', )] #[IsGranted(AuthenticatedVoter::IS_AUTHENTICATED_FULLY)] +#[OA\Tag(name: 'Role Management')] class RoleController extends Controller { use Actions\Admin\CountAction; diff --git a/src/Controller/v1/User/AttachUserGroupController.php b/src/Controller/v1/User/AttachUserGroupController.php index b19365cc2..4ffc801fa 100644 --- a/src/Controller/v1/User/AttachUserGroupController.php +++ b/src/Controller/v1/User/AttachUserGroupController.php @@ -14,7 +14,9 @@ use App\Resource\UserGroupResource; use App\Resource\UserResource; use Nelmio\ApiDocBundle\Annotation\Model; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -44,89 +46,6 @@ public function __construct( /** * Endpoint action to attach specified user group to specified user. * - * @OA\Tag(name="User Management") - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ), - * ) - * @OA\Parameter( - * name="userId", - * in="path", - * required=true, - * description="User GUID", - * @OA\Schema( - * type="string", - * default="User GUID", - * ), - * ) - * @OA\Parameter( - * name="userGroupId", - * in="path", - * required=true, - * description="User Group GUID", - * @OA\Schema( - * type="string", - * default="User Group GUID", - * ), - * ) - * @OA\Response( - * response=200, - * description="User groups (user already belongs to this group)", - * @OA\Schema( - * type="array", - * @OA\Items( - * ref=@Model( - * type=\App\Entity\UserGroup::class, - * groups={"UserGroup", "UserGroup.role"}, - * ), - * ), - * ), - * ) - * @OA\Response( - * response=201, - * description="User groups (user added to this group)", - * @OA\Schema( - * type="array", - * @OA\Items( - * ref=@Model( - * type=\App\Entity\UserGroup::class, - * groups={"UserGroup", "UserGroup.role"}, - * ), - * ), - * ), - * ) - * @OA\Response( - * response=401, - * description="Unauthorized", - * @OA\Schema( - * type="object", - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * @OA\Response( - * response=403, - * description="Access denied", - * @OA\Schema( - * type="object", - * example={ - * "Access denied": "{code: 403, message: 'Access denied'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * * @throws Throwable */ #[Route( @@ -138,7 +57,67 @@ public function __construct( methods: [Request::METHOD_POST], )] #[IsGranted(Role::ROOT->value)] - + #[OA\Tag(name: 'User Management')] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Parameter(name: 'user', description: 'User GUID', in: 'path', required: true)] + #[OA\Parameter(name: 'userGroup', description: 'User Group GUID', in: 'path', required: true)] + #[OA\Response( + response: 200, + description: 'User groups (user already belongs to this group)', + content: new JsonContent( + type: 'array', + items: new OA\Items( + ref: new Model(type: UserGroup::class, groups: ['UserGroup', 'UserGroup.role']), + ), + ), + )] + #[OA\Response( + response: 201, + description: 'User groups (user added to this group)', + content: new JsonContent( + type: 'array', + items: new OA\Items( + ref: new Model(type: UserGroup::class, groups: ['UserGroup', 'UserGroup.role']), + ), + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] public function __invoke(User $user, UserGroup $userGroup): JsonResponse { $status = $user->getUserGroups()->contains($userGroup) ? Response::HTTP_OK : Response::HTTP_CREATED; diff --git a/src/Controller/v1/User/DeleteUserController.php b/src/Controller/v1/User/DeleteUserController.php index fb9675d9a..e9a93b39c 100644 --- a/src/Controller/v1/User/DeleteUserController.php +++ b/src/Controller/v1/User/DeleteUserController.php @@ -13,7 +13,7 @@ use App\Resource\UserResource; use App\Rest\Controller; use App\Rest\Traits\Methods; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -26,12 +26,11 @@ /** * Class DeleteUserController * - * @OA\Tag(name="User Management") - * * @package App\Controller\v1\User * @author TLe, Tarmo Leppänen */ #[AsController] +#[OA\Tag(name: 'User Management')] class DeleteUserController extends Controller { use Methods\DeleteMethod; diff --git a/src/Controller/v1/User/DetachUserGroupController.php b/src/Controller/v1/User/DetachUserGroupController.php index 957e2189b..1b7b6b8d9 100644 --- a/src/Controller/v1/User/DetachUserGroupController.php +++ b/src/Controller/v1/User/DetachUserGroupController.php @@ -14,7 +14,9 @@ use App\Resource\UserGroupResource; use App\Resource\UserResource; use Nelmio\ApiDocBundle\Annotation\Model; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -43,76 +45,6 @@ public function __construct( /** * Endpoint action to detach specified user group from specified user. * - * @OA\Tag(name="User Management") - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ), - * ) - * @OA\Parameter( - * name="userId", - * in="path", - * required=true, - * description="User GUID", - * @OA\Schema( - * type="string", - * default="User GUID", - * ), - * ) - * @OA\Parameter( - * name="userGroupId", - * in="path", - * required=true, - * description="User Group GUID", - * @OA\Schema( - * type="string", - * default="User Group GUID", - * ), - * ) - * @OA\Response( - * response=200, - * description="User groups", - * @OA\Schema( - * type="array", - * @OA\Items( - * ref=@Model( - * type=\App\Entity\UserGroup::class, - * groups={"UserGroup", "UserGroup.role"}, - * ), - * ), - * ), - * ) - * @OA\Response( - * response=401, - * description="Unauthorized", - * @OA\Schema( - * type="object", - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * @OA\Response( - * response=403, - * description="Forbidden", - * @OA\Schema( - * type="object", - * example={ - * "Access denied": "{code: 403, message: 'Access denied'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * * @throws Throwable */ #[Route( @@ -124,6 +56,57 @@ public function __construct( methods: [Request::METHOD_DELETE], )] #[IsGranted(Role::ROOT->value)] + #[OA\Tag(name: 'User Management')] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Parameter(name: 'user', description: 'User GUID', in: 'path', required: true)] + #[OA\Parameter(name: 'userGroup', description: 'User Group GUID', in: 'path', required: true)] + #[OA\Response( + response: 200, + description: 'User groups', + content: new JsonContent( + type: 'array', + items: new OA\Items( + ref: new Model(type: UserGroup::class, groups: ['UserGroup', 'UserGroup.role']), + ), + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] public function __invoke(User $user, UserGroup $userGroup): JsonResponse { $this->userResource->save($user->removeUserGroup($userGroup), false); diff --git a/src/Controller/v1/User/UserController.php b/src/Controller/v1/User/UserController.php index 9e370178f..e0360d15b 100644 --- a/src/Controller/v1/User/UserController.php +++ b/src/Controller/v1/User/UserController.php @@ -14,7 +14,7 @@ use App\Resource\UserResource; use App\Rest\Controller; use App\Rest\Traits\Actions; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; @@ -23,11 +23,8 @@ /** * Class UserController * - * @OA\Tag(name="User Management") - * * @package App\Controller\v1\User * @author TLe, Tarmo Leppänen - * * @method UserResource getResource() */ #[AsController] @@ -35,6 +32,7 @@ path: '/v1/user', )] #[IsGranted(AuthenticatedVoter::IS_AUTHENTICATED_FULLY)] +#[OA\Tag(name: 'User Management')] class UserController extends Controller { use Actions\Admin\CountAction; diff --git a/src/Controller/v1/User/UserGroupsController.php b/src/Controller/v1/User/UserGroupsController.php index 693063a15..4c071cbfd 100644 --- a/src/Controller/v1/User/UserGroupsController.php +++ b/src/Controller/v1/User/UserGroupsController.php @@ -11,7 +11,9 @@ use App\Entity\User; use App\Entity\UserGroup; use Nelmio\ApiDocBundle\Annotation\Model; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -37,56 +39,6 @@ public function __construct( /** * Endpoint action to fetch specified user user groups. - * - * @OA\Tag(name="User Management") - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ), - * ) - * @OA\Response( - * response=200, - * description="User groups", - * @OA\Schema( - * type="array", - * @OA\Items( - * ref=@Model( - * type=\App\Entity\UserGroup::class, - * groups={"UserGroup", "UserGroup.role"}, - * ), - * ), - * ), - * ) - * @OA\Response( - * response=401, - * description="Unauthorized", - * @OA\Schema( - * type="object", - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * @OA\Response( - * response=403, - * description="Access denied", - * @OA\Schema( - * type="object", - * example={ - * "Access denied": "{code: 403, message: 'Access denied'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) */ #[Route( path: '/v1/user/{user}/groups', @@ -96,6 +48,58 @@ public function __construct( methods: [Request::METHOD_GET], )] #[IsGranted(new Expression('is_granted("IS_USER_HIMSELF", object) or "ROLE_ROOT" in role_names'), 'user')] + #[OA\Tag(name: 'User Management')] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Response( + response: 200, + description: 'User groups', + content: new JsonContent( + type: 'array', + items: new OA\Items( + ref: new Model( + type: UserGroup::class, + groups: ['UserGroup', 'UserGroup.role'], + ), + ), + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] public function __invoke(User $user): JsonResponse { $groups = [ diff --git a/src/Controller/v1/User/UserRolesController.php b/src/Controller/v1/User/UserRolesController.php index 621eabdf7..260676695 100644 --- a/src/Controller/v1/User/UserRolesController.php +++ b/src/Controller/v1/User/UserRolesController.php @@ -10,7 +10,9 @@ use App\Entity\User; use App\Security\RolesService; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\ExpressionLanguage\Expression; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; @@ -35,51 +37,6 @@ public function __construct( /** * Endpoint action to fetch specified user roles. - * - * @OA\Tag(name="User Management") - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ), - * ) - * @OA\Response( - * response=200, - * description="Specified user roles", - * @OA\Schema( - * type="array", - * @OA\Items(type="string"), - * ), - * ) - * @OA\Response( - * response=401, - * description="Unauthorized", - * @OA\Schema( - * type="object", - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) - * @OA\Response( - * response=403, - * description="Access denied", - * @OA\Schema( - * type="object", - * example={ - * "Access denied": "{code: 403, message: 'Access denied'}", - * }, - * @OA\Property(property="code", type="integer", description="Error code"), - * @OA\Property(property="message", type="string", description="Error description"), - * ), - * ) */ #[Route( path: '/v1/user/{user}/roles', @@ -89,6 +46,54 @@ public function __construct( methods: [Request::METHOD_GET], )] #[IsGranted(new Expression('is_granted("IS_USER_HIMSELF", object) or "ROLE_ROOT" in role_names'), 'user')] + #[OA\Tag(name: 'User Management')] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Response( + response: 200, + description: 'Specified user roles', + content: new JsonContent( + type: 'array', + items: new OA\Items(type: 'string', example: 'ROLE_USER'), + example: ['ROLE_USER', 'ROLE_LOGGED'], + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] public function __invoke(User $user): JsonResponse { return new JsonResponse($this->rolesService->getInheritedRoles($user->getRoles())); diff --git a/src/Controller/v1/UserGroup/AttachUserController.php b/src/Controller/v1/UserGroup/AttachUserController.php index 504598375..e6e366c38 100644 --- a/src/Controller/v1/UserGroup/AttachUserController.php +++ b/src/Controller/v1/UserGroup/AttachUserController.php @@ -14,7 +14,9 @@ use App\Resource\UserGroupResource; use App\Resource\UserResource; use Nelmio\ApiDocBundle\Annotation\Model; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -43,78 +45,6 @@ public function __construct( /** * Endpoint action to attach specified user to specified user group. * - * @OA\Tag(name="UserGroup Management") - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ) - * ) - * @OA\Parameter( - * name="userGroupId", - * in="path", - * required=true, - * description="User Group GUID", - * @OA\Schema( - * type="string", - * default="User Group GUID", - * ) - * ) - * @OA\Parameter( - * name="userId", - * in="path", - * required=true, - * description="User GUID", - * @OA\Schema( - * type="string", - * default="User GUID", - * ) - * ) - * @OA\Response( - * response=200, - * description="List of user group users - specified user already exists on this group", - * @OA\Schema( - * type="array", - * @OA\Items( - * ref=@Model( - * type=\App\Entity\User::class, - * groups={"User"}, - * ), - * ), - * ), - * ) - * @OA\Response( - * response=201, - * description="List of user group users - specified user has been attached to this group", - * @OA\Schema( - * type="array", - * @OA\Items( - * ref=@Model( - * type=\App\Entity\User::class, - * groups={"User"}, - * ), - * ), - * ), - * ) - * @OA\Response( - * response=401, - * description="Invalid token", - * @OA\Schema( - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * ), - * ) - * @OA\Response( - * response=403, - * description="Access denied", - * ) - * * @throws Throwable */ #[Route( @@ -126,6 +56,67 @@ public function __construct( methods: [Request::METHOD_POST], )] #[IsGranted(Role::ROOT->value)] + #[OA\Tag(name: 'UserGroup Management')] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Parameter(name: 'userGroup', description: 'User Group GUID', in: 'path', required: true)] + #[OA\Parameter(name: 'user', description: 'User GUID', in: 'path', required: true)] + #[OA\Response( + response: 200, + description: 'List of user group users - specified user already exists on this group', + content: new JsonContent( + type: 'array', + items: new OA\Items( + ref: new Model(type: User::class, groups: ['User']), + ), + ), + )] + #[OA\Response( + response: 201, + description: 'List of user group users - specified user has been attached to this group', + content: new JsonContent( + type: 'array', + items: new OA\Items( + ref: new Model(type: User::class, groups: ['User']), + ), + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] public function __invoke(UserGroup $userGroup, User $user): JsonResponse { $status = $userGroup->getUsers()->contains($user) ? 200 : 201; diff --git a/src/Controller/v1/UserGroup/DetachUserController.php b/src/Controller/v1/UserGroup/DetachUserController.php index 531d4f069..70274c65b 100644 --- a/src/Controller/v1/UserGroup/DetachUserController.php +++ b/src/Controller/v1/UserGroup/DetachUserController.php @@ -14,7 +14,9 @@ use App\Resource\UserGroupResource; use App\Resource\UserResource; use Nelmio\ApiDocBundle\Annotation\Model; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -43,65 +45,6 @@ public function __construct( /** * Endpoint action to detach specified user from specified user group. * - * @OA\Tag(name="UserGroup Management") - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ) - * ) - * @OA\Parameter( - * name="userGroupId", - * in="path", - * required=true, - * description="User Group GUID", - * @OA\Schema( - * type="string", - * default="User Group GUID", - * ) - * ) - * @OA\Parameter( - * name="userId", - * in="path", - * required=true, - * description="User GUID", - * @OA\Schema( - * type="string", - * default="User GUID", - * ) - * ) - * @OA\Response( - * response=200, - * description="Users", - * @OA\Schema( - * type="array", - * @OA\Items( - * ref=@Model( - * type=\App\Entity\User::class, - * groups={"User"}, - * ), - * ), - * ), - * ) - * @OA\Response( - * response=401, - * description="Invalid token", - * @OA\Schema( - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * ), - * ) - * @OA\Response( - * response=403, - * description="Access denied", - * ) - * * @throws Throwable */ #[Route( @@ -113,6 +56,57 @@ public function __construct( methods: [Request::METHOD_DELETE], )] #[IsGranted(Role::ROOT->value)] + #[OA\Tag(name: 'UserGroup Management')] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Parameter(name: 'userGroup', description: 'User Group GUID', in: 'path', required: true)] + #[OA\Parameter(name: 'user', description: 'User GUID', in: 'path', required: true)] + #[OA\Response( + response: 200, + description: 'List of users in this user group', + content: new JsonContent( + type: 'array', + items: new OA\Items( + ref: new Model(type: User::class, groups: ['User']), + ), + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] public function __invoke(UserGroup $userGroup, User $user): JsonResponse { $this->userGroupResource->save($userGroup->removeUser($user), false); diff --git a/src/Controller/v1/UserGroup/UserGroupController.php b/src/Controller/v1/UserGroup/UserGroupController.php index cf1bd37d5..0c6739b0a 100644 --- a/src/Controller/v1/UserGroup/UserGroupController.php +++ b/src/Controller/v1/UserGroup/UserGroupController.php @@ -14,7 +14,7 @@ use App\Resource\UserGroupResource; use App\Rest\Controller; use App\Rest\Traits\Actions; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter; @@ -23,11 +23,8 @@ /** * Class UserGroupController * - * @OA\Tag(name="UserGroup Management") - * * @package App\Controller\v1\UserGroup * @author TLe, Tarmo Leppänen - * * @method UserGroupResource getResource() */ #[AsController] @@ -35,6 +32,7 @@ path: '/v1/user_group', )] #[IsGranted(AuthenticatedVoter::IS_AUTHENTICATED_FULLY)] +#[OA\Tag(name: 'UserGroup Management')] class UserGroupController extends Controller { use Actions\Admin\CountAction; diff --git a/src/Controller/v1/UserGroup/UsersController.php b/src/Controller/v1/UserGroup/UsersController.php index dbf92dbde..aa6cad207 100644 --- a/src/Controller/v1/UserGroup/UsersController.php +++ b/src/Controller/v1/UserGroup/UsersController.php @@ -14,7 +14,9 @@ use App\Resource\UserResource; use App\Rest\ResponseHandler; use Nelmio\ApiDocBundle\Annotation\Model; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; +use OpenApi\Attributes\JsonContent; +use OpenApi\Attributes\Property; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; @@ -41,42 +43,6 @@ public function __construct( /** * Endpoint action to list specified user group users. * - * @OA\Tag(name="UserGroup Management") - * @OA\Parameter( - * name="Authorization", - * in="header", - * required=true, - * description="Authorization header", - * @OA\Schema( - * type="string", - * default="Bearer _your_jwt_here_", - * ) - * ) - * @OA\Response( - * response=200, - * description="User group users", - * @OA\Schema( - * ref=@Model( - * type=User::class, - * groups={"User", "User.userGroups", "User.roles", "UserGroup", "UserGroup.role"}, - * ), - * ), - * ) - * @OA\Response( - * response=401, - * description="Invalid token", - * @OA\Schema( - * example={ - * "Token not found": "{code: 401, message: 'JWT Token not found'}", - * "Expired token": "{code: 401, message: 'Expired JWT Token'}", - * }, - * ), - * ) - * @OA\Response( - * response=404, - * description="User Group not found", - * ) - * * @throws Throwable */ #[Route( @@ -87,6 +53,58 @@ public function __construct( methods: [Request::METHOD_GET], )] #[IsGranted(Role::ROOT->value)] + #[OA\Tag(name: 'UserGroup Management')] + #[OA\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + description: 'Authorization header', + name: 'bearerAuth', + in: 'header', + bearerFormat: 'JWT', + scheme: 'bearer', + )] + #[OA\Response( + response: 200, + description: 'User group users', + content: new JsonContent( + type: 'array', + items: new OA\Items( + ref: new Model( + type: User::class, + groups: ['User', 'User.userGroups', 'User.roles', 'UserGroup', 'UserGroup.role'] + ), + ), + ), + )] + #[OA\Response( + response: 401, + description: 'Invalid token', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Token not found' => "{code: 401, message: 'JWT Token not found'}", + 'Expired token' => "{code: 401, message: 'Expired JWT Token'}", + ], + ), + )] + #[OA\Response( + response: 403, + description: 'Access denied', + content: new JsonContent( + properties: [ + new Property(property: 'code', type: 'integer'), + new Property(property: 'message', type: 'string'), + ], + type: 'object', + example: [ + 'Access denied' => "{code: 403, message: 'Access denied'}", + ], + ), + )] public function __invoke(Request $request, UserGroup $userGroup): Response { return $this->responseHandler diff --git a/src/Entity/ApiKey.php b/src/Entity/ApiKey.php index 41ca5e9dc..67e03667f 100644 --- a/src/Entity/ApiKey.php +++ b/src/Entity/ApiKey.php @@ -18,7 +18,7 @@ use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; use Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType; use Ramsey\Uuid\UuidInterface; use Symfony\Bridge\Doctrine\Validator\Constraints as AssertCollection; @@ -54,9 +54,6 @@ class ApiKey implements EntityInterface, UserGroupAwareInterface use Timestampable; use Uuid; - /** - * @OA\Property(type="string", format="uuid") - */ #[ORM\Id] #[ORM\Column( name: 'id', @@ -69,6 +66,7 @@ class ApiKey implements EntityInterface, UserGroupAwareInterface 'LogRequest.apiKey', ])] + #[OA\Property(type: 'string', format: 'uuid')] private UuidInterface $id; #[ORM\Column( diff --git a/src/Entity/DateDimension.php b/src/Entity/DateDimension.php index 8107d646f..c4ab62d88 100644 --- a/src/Entity/DateDimension.php +++ b/src/Entity/DateDimension.php @@ -15,7 +15,7 @@ use DateTimeZone; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; use Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType; use Ramsey\Uuid\UuidInterface; use Symfony\Component\Serializer\Annotation\Groups; @@ -45,9 +45,6 @@ class DateDimension implements EntityInterface { use Uuid; - /** - * @OA\Property(type="string", format="uuid") - */ #[ORM\Id] #[ORM\Column( name: 'id', @@ -58,6 +55,7 @@ class DateDimension implements EntityInterface 'DateDimension', 'DateDimension.id', ])] + #[OA\Property(type: 'string', format: 'uuid')] private UuidInterface $id; #[ORM\Column( diff --git a/src/Entity/Healthz.php b/src/Entity/Healthz.php index 38b57b7ee..9b7471dac 100644 --- a/src/Entity/Healthz.php +++ b/src/Entity/Healthz.php @@ -14,7 +14,7 @@ use DateTimeZone; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; use Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType; use Ramsey\Uuid\UuidInterface; use Symfony\Component\Serializer\Annotation\Groups; @@ -35,9 +35,6 @@ class Healthz implements EntityInterface { use Uuid; - /** - * @OA\Property(type="string", format="uuid") - */ #[ORM\Id] #[ORM\Column( name: 'id', @@ -48,6 +45,7 @@ class Healthz implements EntityInterface 'Healthz', 'Healthz.id', ])] + #[OA\Property(type: 'string', format: 'uuid')] private UuidInterface $id; #[ORM\Column( diff --git a/src/Entity/LogRequest.php b/src/Entity/LogRequest.php index 30d997d0c..12bf1998e 100644 --- a/src/Entity/LogRequest.php +++ b/src/Entity/LogRequest.php @@ -14,7 +14,7 @@ use App\Entity\Traits\Uuid; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; -use OpenApi\Annotations as OA; +use OpenApi\Attributes as OA; use Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType; use Ramsey\Uuid\UuidInterface; use Symfony\Component\HttpFoundation\Request; @@ -61,9 +61,6 @@ class LogRequest implements EntityInterface use LogRequestProcessRequestTrait; use Uuid; - /** - * @OA\Property(type="string", format="uuid") - */ #[ORM\Id] #[ORM\Column( name: 'id', @@ -77,6 +74,7 @@ class LogRequest implements EntityInterface 'ApiKey.logsRequest', 'User.logsRequest', ])] + #[OA\Property(type: 'string', format: 'uuid')] private UuidInterface $id; #[ORM\Column(