From 2c37852cb473ab3360e5299b048155586599d0e4 Mon Sep 17 00:00:00 2001 From: matiasperrone-exo Date: Fri, 13 Feb 2026 20:43:36 +0000 Subject: [PATCH] feat: Add OpenAPI documentation annotations for OAuth2UserApiController v1 --- .../Api/OAuth2/OAuth2UserApiController.php | 416 ++++++++++++++++++ app/Swagger/Models/BaseUserSchema.php | 26 ++ app/Swagger/Models/GroupSchema.php | 27 ++ app/Swagger/Models/UserInfoResponseSchema.php | 90 ++++ app/Swagger/Models/UserSchema.php | 64 +++ .../OAuth2UserApiControllerSchemas.php | 26 ++ .../Requests/CreateUserRequestSchema.php | 30 ++ .../UpdateUserGroupsRequestSchema.php | 36 ++ .../Requests/UpdateUserPicRequestSchema.php | 35 ++ .../Requests/UpdateUserRequestSchema.php | 29 ++ app/Swagger/Requests/UserFieldsSchema.php | 308 +++++++++++++ app/Swagger/Security/UsersOAuth2Schema.php | 32 ++ 12 files changed, 1119 insertions(+) create mode 100644 app/Swagger/Models/BaseUserSchema.php create mode 100644 app/Swagger/Models/GroupSchema.php create mode 100644 app/Swagger/Models/UserInfoResponseSchema.php create mode 100644 app/Swagger/Models/UserSchema.php create mode 100644 app/Swagger/OAuth2UserApiControllerSchemas.php create mode 100644 app/Swagger/Requests/CreateUserRequestSchema.php create mode 100644 app/Swagger/Requests/UpdateUserGroupsRequestSchema.php create mode 100644 app/Swagger/Requests/UpdateUserPicRequestSchema.php create mode 100644 app/Swagger/Requests/UpdateUserRequestSchema.php create mode 100644 app/Swagger/Requests/UserFieldsSchema.php create mode 100644 app/Swagger/Security/UsersOAuth2Schema.php diff --git a/app/Http/Controllers/Api/OAuth2/OAuth2UserApiController.php b/app/Http/Controllers/Api/OAuth2/OAuth2UserApiController.php index fd0b744f..d8fee494 100644 --- a/app/Http/Controllers/Api/OAuth2/OAuth2UserApiController.php +++ b/app/Http/Controllers/Api/OAuth2/OAuth2UserApiController.php @@ -37,8 +37,11 @@ use OAuth2\ResourceServer\IUserService; use Utils\Http\HttpContentType; use Utils\Services\ILogService; +use App\libs\OAuth2\IUserScopes; use Exception; +use OpenApi\Attributes as OA; use OpenId\Services\IUserService as IOpenIdUserService; +use Symfony\Component\HttpFoundation\Response as HttpResponse; /** * Class OAuth2UserApiController * @package App\Http\Controllers\Api\OAuth2 @@ -49,6 +52,75 @@ final class OAuth2UserApiController extends OAuth2ProtectedController use RequestProcessor; + #[OA\Get( + path: '/api/v1/users', + summary: 'Get all users', + operationId: 'getUsers', + tags: ['Users'], + security: [ + [ + 'user_oauth2' => [ + IUserScopes::ReadAll, + ] + ], + ], + parameters: [ + new OA\Parameter( + name: 'page', + description: 'Page number', + in: 'query', + required: false, + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'per_page', + description: 'Items per page (5-100)', + in: 'query', + required: false, + schema: new OA\Schema(type: 'integer') + ), + new OA\Parameter( + name: 'filter', + description: 'Filter (first_name, last_name, email, primary_email)', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'order', + description: 'Order', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string') + ), + new OA\Parameter( + name: 'expand', + description: 'Expand relations: groups', + in: 'query', + required: false, + schema: new OA\Schema(type: 'string') + ), + ], + responses: [ + new OA\Response( + response: HttpResponse::HTTP_OK, + description: 'OK', + content: new OA\JsonContent(ref: '#/components/schemas/PaginatedUserResponseSchema') + ), + new OA\Response( + response: HttpResponse::HTTP_NOT_FOUND, + description: 'Not Found' + ), + new OA\Response( + response: HttpResponse::HTTP_PRECONDITION_FAILED, + description: 'Validation Failed' + ), + new OA\Response( + response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, + description: 'Server Error' + ), + ] + )] protected function getAllSerializerType(): string { return SerializerRegistry::SerializerType_Private; @@ -139,6 +211,32 @@ public function __construct * Gets User Basic Info * @return mixed */ + #[OA\Get( + path: '/api/v1/users/me', + summary: 'Get current user basic info', + operationId: 'getCurrentUser', + tags: ['Users'], + security: [ + [ + 'user_oauth2' => [ + IUserScopes::Profile, + IUserScopes::Email, + IUserScopes::Address, + ] + ], + ], + responses: [ + new OA\Response( + response: HttpResponse::HTTP_OK, + description: 'OK', + content: new OA\JsonContent(ref: '#/components/schemas/User') + ), + new OA\Response( + response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, + description: 'Server Error' + ), + ] + )] public function me() { try { @@ -234,18 +332,194 @@ private function _update($id){ } } + #[OA\Post( + path: '/api/v1/users', + summary: 'Create a new user', + operationId: 'createUser', + tags: ['Users'], + security: [ + [ + 'user_oauth2' => [ + IUserScopes::Write, + ] + ], + ], + requestBody: new OA\RequestBody( + description: 'User data', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/CreateUserRequest') + ), + responses: [ + new OA\Response( + response: HttpResponse::HTTP_CREATED, + description: 'Created', + content: new OA\JsonContent(ref: '#/components/schemas/User') + ), + new OA\Response( + response: HttpResponse::HTTP_BAD_REQUEST, + description: 'Bad Request' + ), + new OA\Response( + response: HttpResponse::HTTP_NOT_FOUND, + description: 'Not Found' + ), + new OA\Response( + response: HttpResponse::HTTP_PRECONDITION_FAILED, + description: 'Validation Failed' + ), + new OA\Response( + response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, + description: 'Server Error' + ), + ] + )] public function create(){ return $this->_create(); } + #[OA\Put( + path: '/api/v1/users/me', + summary: 'Update current user', + operationId: 'updateCurrentUser', + tags: ['Users'], + security: [ + [ + 'user_oauth2' => [ + IUserScopes::MeWrite, + ] + ], + ], + requestBody: new OA\RequestBody( + description: 'User data to update', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/UpdateUserRequest') + ), + responses: [ + new OA\Response( + response: HttpResponse::HTTP_CREATED, + description: 'Updated', + content: new OA\JsonContent(ref: '#/components/schemas/User') + ), + new OA\Response( + response: HttpResponse::HTTP_BAD_REQUEST, + description: 'Bad Request' + ), + new OA\Response( + response: HttpResponse::HTTP_NOT_FOUND, + description: 'Not Found' + ), + new OA\Response( + response: HttpResponse::HTTP_PRECONDITION_FAILED, + description: 'Validation Failed' + ), + new OA\Response( + response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, + description: 'Server Error' + ), + ] + )] public function updateMe(){ return $this->_update($this->resource_server_context->getCurrentUserId()); } + #[OA\Put( + path: '/api/v1/users/{id}', + summary: 'Update a user by ID', + operationId: 'updateUser', + tags: ['Users'], + security: [ + [ + 'user_oauth2' => [ + IUserScopes::Write, + ] + ], + ], + parameters: [ + new OA\Parameter( + name: 'id', + description: 'User ID', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer') + ), + ], + requestBody: new OA\RequestBody( + description: 'User data to update', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/UpdateUserRequest') + ), + responses: [ + new OA\Response( + response: HttpResponse::HTTP_CREATED, + description: 'Updated', + content: new OA\JsonContent(ref: '#/components/schemas/User') + ), + new OA\Response( + response: HttpResponse::HTTP_BAD_REQUEST, + description: 'Bad Request' + ), + new OA\Response( + response: HttpResponse::HTTP_NOT_FOUND, + description: 'Not Found' + ), + new OA\Response( + response: HttpResponse::HTTP_PRECONDITION_FAILED, + description: 'Validation Failed' + ), + new OA\Response( + response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, + description: 'Server Error' + ), + ] + )] public function update($id){ return $this->_update($id); } + #[OA\Put( + path: '/api/v1/users/me/pic', + summary: 'Update current user profile picture', + operationId: 'updateCurrentUserProfilePicture', + tags: ['Users'], + security: [ + [ + 'user_oauth2' => [ + IUserScopes::MeWrite, + ] + ], + ], + requestBody: new OA\RequestBody( + description: 'Profile picture file', + required: true, + content: new OA\MediaType( + mediaType: 'multipart/form-data', + schema: new OA\Schema(ref: '#/components/schemas/UpdateUserPicRequest') + ) + ), + responses: [ + new OA\Response( + response: HttpResponse::HTTP_CREATED, + description: 'Updated', + content: new OA\JsonContent(ref: '#/components/schemas/User') + ), + new OA\Response( + response: HttpResponse::HTTP_FORBIDDEN, + description: 'Forbidden' + ), + new OA\Response( + response: HttpResponse::HTTP_NOT_FOUND, + description: 'Not Found' + ), + new OA\Response( + response: HttpResponse::HTTP_PRECONDITION_FAILED, + description: 'Validation Failed' + ), + new OA\Response( + response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, + description: 'Server Error' + ), + ] + )] public function updateMyPic(LaravelRequest $request){ try { if (!$this->resource_server_context->getCurrentUserId()) { @@ -276,6 +550,58 @@ public function updateMyPic(LaravelRequest $request){ } } + #[OA\Get( + path: '/api/v1/users/info', + summary: 'Get current user info (OpenID Connect UserInfo)', + operationId: 'getUserInfo', + tags: ['Users'], + security: [ + [ + 'user_oauth2' => [ + IUserScopes::Profile, + IUserScopes::Email, + IUserScopes::Address, + ] + ], + ], + responses: [ + new OA\Response( + response: HttpResponse::HTTP_OK, + description: 'OK', + content: new OA\JsonContent(ref: '#/components/schemas/UserInfoResponse') + ), + new OA\Response( + response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, + description: 'Server Error' + ), + ] + )] + #[OA\Post( + path: '/api/v1/users/info', + summary: 'Get current user info (OpenID Connect UserInfo)', + operationId: 'getUserInfoPost', + tags: ['Users'], + security: [ + [ + 'user_oauth2' => [ + IUserScopes::Profile, + IUserScopes::Email, + IUserScopes::Address, + ] + ], + ], + responses: [ + new OA\Response( + response: HttpResponse::HTTP_OK, + description: 'OK', + content: new OA\JsonContent(ref: '#/components/schemas/UserInfoResponse') + ), + new OA\Response( + response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, + description: 'Server Error' + ), + ] + )] public function userInfo() { try { @@ -312,6 +638,47 @@ public function userInfo() * @param $id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: '/api/v1/users/{id}', + summary: 'Get a user by ID', + operationId: 'getUserById', + tags: ['Users'], + security: [ + [ + 'user_oauth2' => [ + IUserScopes::ReadAll, + ] + ], + ], + parameters: [ + new OA\Parameter( + name: 'id', + description: 'User ID', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer') + ), + ], + responses: [ + new OA\Response( + response: HttpResponse::HTTP_OK, + description: 'OK', + content: new OA\JsonContent(ref: '#/components/schemas/User') + ), + new OA\Response( + response: HttpResponse::HTTP_NOT_FOUND, + description: 'Not Found' + ), + new OA\Response( + response: HttpResponse::HTTP_PRECONDITION_FAILED, + description: 'Validation Failed' + ), + new OA\Response( + response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, + description: 'Server Error' + ), + ] + )] public function get($id) { try { @@ -355,6 +722,55 @@ public function getV2($id) * @param $user_id * @return JsonResponse|mixed */ + #[OA\Put( + path: '/api/v1/users/{id}/groups', + summary: 'Update user group assignments (only for account type "SERVICE")', + operationId: 'updateUserGroups', + tags: ['Users'], + security: [ + [ + 'user_oauth2' => [ + IUserScopes::UserGroupWrite, + ] + ], + ], + parameters: [ + new OA\Parameter( + name: 'id', + description: 'User ID', + in: 'path', + required: true, + schema: new OA\Schema(type: 'integer') + ), + ], + requestBody: new OA\RequestBody( + description: 'Group IDs to assign', + required: true, + content: new OA\JsonContent(ref: '#/components/schemas/UpdateUserGroupsRequest') + ), + responses: [ + new OA\Response( + response: HttpResponse::HTTP_CREATED, + description: 'Updated' + ), + new OA\Response( + response: HttpResponse::HTTP_BAD_REQUEST, + description: 'Bad Request' + ), + new OA\Response( + response: HttpResponse::HTTP_NOT_FOUND, + description: 'Not Found' + ), + new OA\Response( + response: HttpResponse::HTTP_PRECONDITION_FAILED, + description: 'Validation Failed' + ), + new OA\Response( + response: HttpResponse::HTTP_INTERNAL_SERVER_ERROR, + description: 'Server Error' + ), + ] + )] public function updateUserGroups($user_id): mixed { return $this->processRequest(function() use($user_id) { diff --git a/app/Swagger/Models/BaseUserSchema.php b/app/Swagger/Models/BaseUserSchema.php new file mode 100644 index 00000000..3122e1e2 --- /dev/null +++ b/app/Swagger/Models/BaseUserSchema.php @@ -0,0 +1,26 @@ + 'Read User Profile', + IUserScopes::Email => 'Read User Email', + IUserScopes::Address => 'Read User Address', + IUserScopes::ReadAll => 'Read All Users Data', + IUserScopes::MeWrite => 'Write Current User Data', + IUserScopes::Write => 'Write Users Data', + IUserScopes::UserGroupWrite => 'Write User Group Assignments', + ], + ), + ], +) +] +class UsersOAuth2Schema +{ +}