diff --git a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitMembersApiController.php b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitMembersApiController.php index 61d218d2d..ed1db63c2 100644 --- a/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitMembersApiController.php +++ b/app/Http/Controllers/Apis/Protected/Summit/OAuth2SummitMembersApiController.php @@ -16,10 +16,9 @@ use App\Http\Utils\EpochCellFormatter; use App\Models\Foundation\Main\IGroup; use App\ModelSerializers\SerializerUtils; -use App\Security\RSVPInvitationsScopes; +use App\Security\MemberScopes; use App\Security\SummitScopes; use App\Services\Model\ISummitRSVPService; -use Illuminate\Http\Response; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Validator; @@ -38,6 +37,8 @@ use utils\PagingInfo; use utils\PagingResponse; use OpenApi\Attributes as OA; +use Symfony\Component\HttpFoundation\Response; + /** * Class OAuth2SummitMembersApiController * @package App\Http\Controllers @@ -90,9 +91,30 @@ public function __construct * @param $member_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/members/me", + operationId: "getMyMember", + description: "Get current user member details for a summit", + tags: ["Summit Members"], + security: [['summit_members_oauth2' => [ + SummitScopes::MeRead, + MemberScopes::ReadMyMemberData, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "expand", description: "Expand relations", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "fields", description: "Fields to return", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "relations", description: "Relations to include", in: "query", schema: new OA\Schema(type: "string")), + ], + responses: [ + new OA\Response(response: Response::HTTP_OK, description: "Member details", content: new OA\JsonContent(ref: "#/components/schemas/Member")), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function getMyMember($summit_id, $member_id) { - return $this->processRequest(function () use ($summit_id, $member_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); @@ -119,9 +141,30 @@ public function getMyMember($summit_id, $member_id) * @param $member_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/members/me/favorites", + operationId: "getMemberFavoritesSummitEvents", + description: "Get current user favorite summit events", + tags: ["Summit Members"], + security: [['summit_members_oauth2' => [ + SummitScopes::MeRead, + MemberScopes::ReadMyMemberData, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "expand", description: "Expand relations", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "fields", description: "Fields to return", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "relations", description: "Relations to include", in: "query", schema: new OA\Schema(type: "string")), + ], + responses: [ + new OA\Response(response: Response::HTTP_OK, description: "List of favorite events", content: new OA\JsonContent(ref: "#/components/schemas/MemberFavoriteEventsList")), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function getMemberFavoritesSummitEvents($summit_id, $member_id) { - return $this->processRequest(function () use ($summit_id, $member_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); @@ -163,9 +206,28 @@ public function getMemberFavoritesSummitEvents($summit_id, $member_id) * @param $event_id * @return mixed */ + #[OA\Post( + path: "/api/v1/summits/{id}/members/me/favorites/{event_id}", + operationId: "addEventToMemberFavorites", + description: "Add an event to current user favorites", + tags: ["Summit Members"], + security: [['summit_members_oauth2' => [ + SummitScopes::AddMyFavorites, + MemberScopes::ReadMyMemberData, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "event_id", description: "Event ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + ], + responses: [ + new OA\Response(response: Response::HTTP_CREATED, description: "Event added to favorites"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function addEventToMemberFavorites($summit_id, $member_id, $event_id) { - return $this->processRequest(function () use ($summit_id, $member_id, $event_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); @@ -185,9 +247,27 @@ public function addEventToMemberFavorites($summit_id, $member_id, $event_id) * @param $event_id * @return mixed */ + #[OA\Delete( + path: "/api/v1/summits/{id}/members/me/favorites/{event_id}", + operationId: "removeEventFromMemberFavorites", + description: "Remove an event from current user favorites", + tags: ["Summit Members"], + security: [['summit_members_oauth2' => [ + SummitScopes::DeleteMyFavorites, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "event_id", description: "Event ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "Event removed from favorites"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function removeEventFromMemberFavorites($summit_id, $member_id, $event_id) { - return $this->processRequest(function () use ($summit_id, $member_id, $event_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); @@ -206,9 +286,30 @@ public function removeEventFromMemberFavorites($summit_id, $member_id, $event_id * @param $member_id * @return mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/members/me/schedule", + operationId: "getMemberScheduleSummitEvents", + description: "Get current user schedule events", + tags: ["Summit Members"], + security: [['summit_members_oauth2' => [ + SummitScopes::MeRead, + MemberScopes::ReadMyMemberData, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "expand", description: "Expand relations", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "fields", description: "Fields to return", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "relations", description: "Relations to include", in: "query", schema: new OA\Schema(type: "string")), + ], + responses: [ + new OA\Response(response: Response::HTTP_OK, description: "List of schedule events", content: new OA\JsonContent(ref: "#/components/schemas/MemberScheduleEventsList")), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function getMemberScheduleSummitEvents($summit_id, $member_id) { - return $this->processRequest(function () use ($summit_id, $member_id) { $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); @@ -250,6 +351,26 @@ public function getMemberScheduleSummitEvents($summit_id, $member_id) * @param $event_id * @return mixed */ + #[OA\Post( + path: "/api/v1/summits/{id}/members/me/schedule/{event_id}", + operationId: "addEventToMemberSchedule", + description: "Add an event to current user schedule", + tags: ["Summit Members"], + security: [['summit_members_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::AddMySchedule, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "event_id", description: "Event ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + ], + responses: [ + new OA\Response(response: Response::HTTP_CREATED, description: "Event added to schedule"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function addEventToMemberSchedule($summit_id, $member_id, $event_id) { return $this->processRequest(function () use ($summit_id, $member_id, $event_id) { @@ -262,7 +383,6 @@ public function addEventToMemberSchedule($summit_id, $member_id, $event_id) $this->summit_service->addEventToMemberSchedule($summit, $current_member, intval($event_id)); return $this->created(); - }); } @@ -272,10 +392,29 @@ public function addEventToMemberSchedule($summit_id, $member_id, $event_id) * @param $event_id * @return mixed */ + #[OA\Delete( + path: "/api/v1/summits/{id}/members/me/schedule/{event_id}", + operationId: "removeEventFromMemberSchedule", + description: "Remove an event from current user schedule", + tags: ["Summit Members"], + security: [['summit_members_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::DeleteMySchedule, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "event_id", description: "Event ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "Event removed from schedule"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function removeEventFromMemberSchedule($summit_id, $member_id, $event_id) { return $this->processRequest(function () use ($summit_id, $member_id, $event_id) { - $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); @@ -294,9 +433,39 @@ public function removeEventFromMemberSchedule($summit_id, $member_id, $event_id) * @param $summit_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/members", + operationId: "getAllMembersBySummit", + description: "required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators, + tags: ["Summit Members"], + x: [ + 'required-groups' => [ + IGroup::SummitAdministrators, + IGroup::SuperAdmins, + IGroup::Administrators + ] + ], + security: [['summit_members_oauth2' => [ + SummitScopes::ReadAllSummitData, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "page", description: "Page number", in: "query", schema: new OA\Schema(type: "integer", default: 1)), + new OA\Parameter(name: "per_page", description: "Items per page", in: "query", schema: new OA\Schema(type: "integer", default: 10)), + new OA\Parameter(name: "expand", description: "Expand relations", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "fields", description: "Fields to return", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "filter", description: "Filter conditions", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "order", description: "Order by", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "relations", description: "Relations to include", in: "query", schema: new OA\Schema(type: "string")), + ], + responses: [ + new OA\Response(response: Response::HTTP_OK, description: "List of members", content: new OA\JsonContent(ref: "#/components/schemas/MembersList")), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function getAllBySummit($summit_id) { - $summit = SummitFinderStrategyFactory::build($this->summit_repository, $this->resource_server_context)->find($summit_id); if (is_null($summit)) return $this->error404(); @@ -360,6 +529,39 @@ function () { * @param $summit_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Get( + path: "/api/v1/summits/{id}/members/csv", + operationId: "getAllMembersBySummitCSV", + description: "required-groups " . IGroup::SummitAdministrators . ", " . IGroup::SuperAdmins . ", " . IGroup::Administrators, + tags: ["Summit Members"], + x: [ + 'required-groups' => [ + IGroup::SummitAdministrators, + IGroup::SuperAdmins, + IGroup::Administrators + ] + ], + security: [['summit_members_oauth2' => [ + SummitScopes::ReadAllSummitData, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "page", description: "Page number", in: "query", schema: new OA\Schema(type: "integer", default: 1)), + new OA\Parameter(name: "per_page", description: "Items per page", in: "query", schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "filter", description: "Filter conditions", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "order", description: "Order by", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "expand", description: "Expand relations", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "fields", description: "Fields to return", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "relations", description: "Relations to include", in: "query", schema: new OA\Schema(type: "string")), + new OA\Parameter(name: "columns", description: "CSV columns", in: "query", schema: new OA\Schema(type: "string")), + ], + responses: [ + new OA\Response(response: Response::HTTP_OK, description: "CSV export", content: new OA\MediaType(mediaType: "text/csv")), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_PRECONDITION_FAILED, description: "Validation Error"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function getAllBySummitCSV($summit_id) { $values = Request::all(); @@ -524,12 +726,30 @@ public function getAllBySummitCSV($summit_id) use GetAndValidateJsonPayload; - /** * @param $summit_id * @param $member_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Post( + path: "/api/v1/summits/{id}/members/me/schedule/shareable-link", + operationId: "createScheduleShareableLink", + description: "Create a shareable link for member schedule", + tags: ["Summit Members"], + security: [['summit_members_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::AddMyScheduleShareable, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + ], + responses: [ + new OA\Response(response: Response::HTTP_CREATED, description: "Shareable link created", content: new OA\JsonContent(type: "object")), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function createScheduleShareableLink($summit_id, $member_id) { return $this->processRequest(function () use ($summit_id, $member_id) { @@ -556,6 +776,25 @@ public function createScheduleShareableLink($summit_id, $member_id) * @param $member_id * @return \Illuminate\Http\JsonResponse|mixed */ + #[OA\Delete( + path: "/api/v1/summits/{id}/members/me/schedule/shareable-link", + operationId: "revokeScheduleShareableLink", + description: "Revoke shareable link for member schedule", + tags: ["Summit Members"], + security: [['summit_members_oauth2' => [ + SummitScopes::WriteSummitData, + SummitScopes::DeleteMyScheduleShareable, + ]]], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + ], + responses: [ + new OA\Response(response: Response::HTTP_NO_CONTENT, description: "Shareable link revoked"), + new OA\Response(response: Response::HTTP_FORBIDDEN, description: "Forbidden"), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function revokeScheduleShareableLink($summit_id, $member_id) { return $this->processRequest(function () use ($summit_id, $member_id) { @@ -578,6 +817,21 @@ public function revokeScheduleShareableLink($summit_id, $member_id) * @param $cid * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|mixed */ + #[OA\Get( + path: "/api/public/v1/summits/{id}/members/all/schedule/ics/{cid}", + operationId: "getCalendarFeedICS", + description: "Get calendar feed in ICS format for member schedule", + tags: ["Summit Members (Public)"], + parameters: [ + new OA\Parameter(name: "id", description: "Summit ID", in: "path", required: true, schema: new OA\Schema(type: "integer")), + new OA\Parameter(name: "cid", description: "Calendar ID", in: "path", required: true, schema: new OA\Schema(type: "string")), + ], + responses: [ + new OA\Response(response: Response::HTTP_OK, description: "ICS calendar feed", content: new OA\MediaType(mediaType: "text/calendar")), + new OA\Response(response: Response::HTTP_NOT_FOUND, description: "Not found"), + new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error"), + ] + )] public function getCalendarFeedICS($summit_id, $cid) { return $this->processRequest(function () use ($summit_id, $cid) { @@ -591,5 +845,4 @@ public function getCalendarFeedICS($summit_id, $cid) ]); }); } - -} \ No newline at end of file +} diff --git a/app/Swagger/Security/SummitMembersAuthSchema.php b/app/Swagger/Security/SummitMembersAuthSchema.php new file mode 100644 index 000000000..d544e8999 --- /dev/null +++ b/app/Swagger/Security/SummitMembersAuthSchema.php @@ -0,0 +1,35 @@ + 'Read My Member Data', + MemberScopes::ReadMyMemberData => 'Read My Member Data', + SummitScopes::AddMyFavorites => 'Add Favorites to My Schedule', + SummitScopes::DeleteMyFavorites => 'Remove Favorites from My Schedule', + SummitScopes::AddMySchedule => 'Add Events to My Schedule', + SummitScopes::DeleteMySchedule => 'Remove Events from My Schedule', + SummitScopes::AddMyScheduleShareable => 'Create Shareable Links for My Schedule', + SummitScopes::DeleteMyScheduleShareable => 'Delete Shareable Links for My Schedule', + SummitScopes::WriteSummitData => 'Write Summit Data', + SummitScopes::ReadAllSummitData => 'Read All Summit Data', + SummitScopes::ReadSummitData => 'Read Summit Data', + ], + ), + ], + ) +] +class SummitMembersAuthSchema {} diff --git a/app/Swagger/SummitMembersSchemas.php b/app/Swagger/SummitMembersSchemas.php new file mode 100644 index 000000000..d9684522c --- /dev/null +++ b/app/Swagger/SummitMembersSchemas.php @@ -0,0 +1,51 @@ +