package fr.titionfire.ffsaf.rest; import fr.titionfire.ffsaf.domain.service.AffiliationService; import fr.titionfire.ffsaf.rest.data.SimpleReqAffiliation; import fr.titionfire.ffsaf.rest.data.SimpleReqAffiliationResume; import fr.titionfire.ffsaf.rest.exception.DForbiddenException; import fr.titionfire.ffsaf.rest.from.AffiliationRequestForm; import fr.titionfire.ffsaf.rest.from.AffiliationRequestSaveForm; import fr.titionfire.ffsaf.utils.SecurityCtx; import fr.titionfire.ffsaf.utils.Utils; import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.unchecked.Unchecked; import jakarta.annotation.security.RolesAllowed; import jakarta.inject.Inject; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; import java.net.URISyntaxException; import java.util.List; import java.util.function.Consumer; @Path("api/affiliation/request") public class AffiliationRequestEndpoints { @Inject AffiliationService service; @Inject SecurityCtx securityCtx; @ConfigProperty(name = "upload_dir") String media; Consumer checkPerm = Unchecked.consumer(id -> { if (!securityCtx.roleHas("federation_admin") && !securityCtx.isInClubGroup(id)) throw new DForbiddenException(); }); @GET @Path("") @RolesAllowed({"federation_admin"}) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Renvoie toutes les demandes d'affiliation", description = "Cette méthode renvoie toutes les " + "demandes d'affiliation sous forme de résumés.") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Réussite"), @APIResponse(responseCode = "403", description = "Accès refusé") }) public Uni> getAllAffRequest() { return service.getAllReq().map(o -> o.stream().map(SimpleReqAffiliationResume::fromModel).toList()); } @POST @Path("") @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.MULTIPART_FORM_DATA) @Operation(summary = "Enregistre une nouvelle demande d'affiliation", description = "Cette méthode enregistre une " + "nouvelle demande d'affiliation à partir des données soumises dans le formulaire. Ne nécessite pas d'authentification.") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Réussite"), @APIResponse(responseCode = "400", description = "Données invalides"), @APIResponse(responseCode = "403", description = "Accès refusé") }) public Uni saveAffRequest(AffiliationRequestForm form) { return service.save(form); } @GET @Path("/{id}") @RolesAllowed({"federation_admin", "club_president", "club_secretaire", "club_respo_intra"}) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Renvoie une demande d'affiliation", description = "Cette méthode renvoie une demande d'affiliation " + "pour l'identifiant spécifié.") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Réussite"), @APIResponse(responseCode = "403", description = "Accès refusé"), @APIResponse(responseCode = "404", description = "Demande d'affiliation non trouvée") }) public Uni getAffRequest( @Parameter(description = "L'identifiant de la demande d'affiliation") @PathParam("id") long id) { return service.getRequest(id).invoke(Unchecked.consumer(o -> { if (o.getClub() == null && !securityCtx.roleHas("federation_admin")) throw new DForbiddenException(); })).invoke(o -> checkPerm.accept(o.getClub())); } @DELETE @Path("/{id}") @RolesAllowed({"federation_admin"}) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Supprime une demande d'affiliation", description = "Cette méthode supprime une demande " + "d'affiliation pour l'identifiant spécifié.") @APIResponses(value = { @APIResponse(responseCode = "204", description = "Réussite"), @APIResponse(responseCode = "403", description = "Accès refusé"), @APIResponse(responseCode = "404", description = "Demande d'affiliation non trouvée") }) public Uni getDelAffRequest( @Parameter(description = "L'identifiant de la demande d'affiliation") @PathParam("id") long id) { return service.getRequest(id).invoke(Unchecked.consumer(o -> { if (o.getClub() == null && !securityCtx.roleHas("federation_admin")) throw new DForbiddenException(); })).invoke(o -> checkPerm.accept(o.getClub())) .chain(o -> service.deleteReqAffiliation(id)); } @PUT @Path("/save") @RolesAllowed({"federation_admin"}) @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.MULTIPART_FORM_DATA) @Operation(summary = "Enregistre une demande d'affiliation en tant qu'admin", description = "Cette méthode " + "enregistre une demande d'affiliation en tant qu'admin à partir des données soumises dans le formulaire.") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Réussite"), @APIResponse(responseCode = "400", description = "Données invalides"), @APIResponse(responseCode = "403", description = "Accès refusé") }) public Uni saveAdminAffRequest(AffiliationRequestSaveForm form) { return service.saveAdmin(form); } @PUT @Path("/edit") @RolesAllowed({"club_president", "club_secretaire", "club_respo_intra"}) @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.MULTIPART_FORM_DATA) @Operation(summary = "Modifie une demande d'affiliation", description = "Cette méthode modifie une demande " + "d'affiliation à partir des données soumises dans le formulaire.") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Réussite"), @APIResponse(responseCode = "400", description = "Données invalides"), @APIResponse(responseCode = "403", description = "Accès refusé") }) public Uni saveEditAffRequest(AffiliationRequestForm form) { return service.saveEdit(form); } @PUT @Path("/apply") @RolesAllowed({"federation_admin"}) @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.MULTIPART_FORM_DATA) @Operation(summary = "Accepte une demande d'affiliation", description = "Cette méthode accepte une demande " + "d'affiliation à partir des données soumises dans le formulaire.") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Réussite"), @APIResponse(responseCode = "400", description = "Données invalides"), @APIResponse(responseCode = "403", description = "Accès refusé") }) public Uni acceptAffRequest(AffiliationRequestSaveForm form) { return service.accept(form); } @GET @Path("/{id}/logo") @RolesAllowed({"federation_admin"}) @Operation(summary = "Renvoie le logo d'une demande d'affiliation", description = "Cette méthode renvoie le logo" + " d'une demande d'affiliation pour l'identifiant spécifié.") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Réussite"), @APIResponse(responseCode = "403", description = "Accès refusé"), @APIResponse(responseCode = "404", description = "Logo non trouvé") }) public Uni getLogo( @Parameter(description = "L'identifiant de la demande d'affiliation") @PathParam("id") long id) throws URISyntaxException { return Utils.getMediaFile(id, media, "aff_request/logo", Uni.createFrom().nullItem()); } @GET @Path("/{id}/status") @RolesAllowed({"federation_admin"}) @Operation(summary = "Renvoie le statut d'une demande d'affiliation", description = "Cette méthode renvoie le statut" + " d'une demande d'affiliation pour l'identifiant spécifié.") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Réussite"), @APIResponse(responseCode = "403", description = "Accès refusé"), @APIResponse(responseCode = "404", description = "Statut non trouvé") }) public Uni getStatus( @Parameter(description = "L'identifiant de la demande d'affiliation") @PathParam("id") long id) throws URISyntaxException { return Utils.getMediaFile(id, media, "aff_request/status", "affiliation_request_" + id + ".pdf", Uni.createFrom().nullItem()); } }