feat: better error message

This commit is contained in:
2024-07-19 14:52:05 +02:00
parent a58dcdd08e
commit 47daa459e2
35 changed files with 327 additions and 89 deletions

View File

@@ -4,6 +4,7 @@ import fr.titionfire.ffsaf.domain.service.AffiliationService;
import fr.titionfire.ffsaf.rest.data.SimpleAffiliation;
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.GroupeUtils;
@@ -42,7 +43,7 @@ public class AffiliationEndpoints {
Consumer<Long> checkPerm = Unchecked.consumer(id -> {
if (!securityIdentity.getRoles().contains("federation_admin") && !GroupeUtils.isInClubGroup(id, idToken))
throw new ForbiddenException();
throw new DForbiddenException();
});
@GET
@@ -68,7 +69,7 @@ public class AffiliationEndpoints {
public Uni<SimpleReqAffiliation> getAffRequest(@PathParam("id") long id) {
return service.getRequest(id).invoke(Unchecked.consumer(o -> {
if (o.getClub() == null && !securityIdentity.getRoles().contains("federation_admin"))
throw new ForbiddenException();
throw new DForbiddenException();
})).invoke(o -> checkPerm.accept(o.getClub()));
}
@@ -79,7 +80,7 @@ public class AffiliationEndpoints {
public Uni<?> getDelAffRequest(@PathParam("id") long id) {
return service.getRequest(id).invoke(Unchecked.consumer(o -> {
if (o.getClub() == null && !securityIdentity.getRoles().contains("federation_admin"))
throw new ForbiddenException();
throw new DForbiddenException();
})).invoke(o -> checkPerm.accept(o.getClub()))
.chain(o -> service.deleteReqAffiliation(id));
}

View File

@@ -2,6 +2,7 @@ package fr.titionfire.ffsaf.rest;
import fr.titionfire.ffsaf.rest.client.SirenService;
import fr.titionfire.ffsaf.rest.data.UniteLegaleRoot;
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
import io.smallrye.mutiny.Uni;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
@@ -20,7 +21,7 @@ public class AssoEndpoints {
return sirenService.get_unite(siren).onFailure().transform(throwable -> {
if (throwable instanceof WebApplicationException exception) {
if (exception.getResponse().getStatus() == 400)
return new BadRequestException("Not found");
return new DNotFoundException("Siret introuvable");
}
return throwable;
});

View File

@@ -7,6 +7,8 @@ import fr.titionfire.ffsaf.rest.data.DeskMember;
import fr.titionfire.ffsaf.rest.data.RenewAffData;
import fr.titionfire.ffsaf.rest.data.SimpleClub;
import fr.titionfire.ffsaf.rest.data.SimpleClubList;
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
import fr.titionfire.ffsaf.rest.exception.DInternalError;
import fr.titionfire.ffsaf.rest.from.FullClubForm;
import fr.titionfire.ffsaf.rest.from.PartClubForm;
import fr.titionfire.ffsaf.utils.Contact;
@@ -50,11 +52,11 @@ public class ClubEndpoints {
Consumer<ClubModel> checkPerm = Unchecked.consumer(clubModel -> {
if (!securityIdentity.getRoles().contains("federation_admin") && !GroupeUtils.isInClubGroup(clubModel.getId(),
idToken))
throw new ForbiddenException();
throw new DForbiddenException();
});
Consumer<Long> checkPerm2 = Unchecked.consumer(id -> {
if (!securityIdentity.getRoles().contains("federation_admin") && !GroupeUtils.isInClubGroup(id, idToken))
throw new ForbiddenException();
throw new DForbiddenException();
});
@GET
@@ -112,7 +114,8 @@ public class ClubEndpoints {
if (input.getLogo().length > 0)
return Uni.createFrom().future(Utils.replacePhoto(id, input.getLogo(), media, "ppClub"
)).invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
if (!out.equals("OK"))
throw new DInternalError("Impossible de reconnaitre le fichier: " + out);
}));
else
return Uni.createFrom().nullItem();
@@ -120,7 +123,8 @@ public class ClubEndpoints {
if (input.getStatus().length > 0)
return Uni.createFrom().future(Utils.replacePhoto(id, input.getStatus(), media, "clubStatus"
)).invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
if (!out.equals("OK"))
throw new DInternalError("Impossible de reconnaitre le fichier: " + out);
}));
else
return Uni.createFrom().nullItem();

View File

@@ -4,6 +4,8 @@ import fr.titionfire.ffsaf.data.model.MembreModel;
import fr.titionfire.ffsaf.domain.service.MembreService;
import fr.titionfire.ffsaf.rest.data.MeData;
import fr.titionfire.ffsaf.rest.data.SimpleMembre;
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
import fr.titionfire.ffsaf.rest.exception.DInternalError;
import fr.titionfire.ffsaf.rest.from.ClubMemberForm;
import fr.titionfire.ffsaf.rest.from.FullMemberForm;
import fr.titionfire.ffsaf.utils.GroupeUtils;
@@ -46,7 +48,7 @@ public class CombEndpoints {
Consumer<MembreModel> checkPerm = Unchecked.consumer(membreModel -> {
if (!securityIdentity.getRoles().contains("federation_admin") && !GroupeUtils.isInClubGroup(
membreModel.getClub().getId(), idToken))
throw new ForbiddenException();
throw new DForbiddenException();
});
@GET
@@ -110,12 +112,14 @@ public class CombEndpoints {
public Uni<String> setAdminMembre(@PathParam("id") long id, FullMemberForm input) {
return membreService.update(id, input)
.invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
if (!out.equals("OK"))
throw new DInternalError("Impossible de reconnaitre le fichier: " + out);
})).chain(() -> {
if (input.getPhoto_data().length > 0)
return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre"
)).invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
if (!out.equals("OK"))
throw new DInternalError("Impossible de reconnaitre le fichier: " + out);
}));
else
return Uni.createFrom().nullItem();
@@ -160,7 +164,8 @@ public class CombEndpoints {
if (input.getPhoto_data().length > 0)
return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre"
)).invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
if (!out.equals("OK"))
throw new DInternalError("Impossible de reconnaitre le fichier: " + out);
}));
else
return Uni.createFrom().nullItem();

View File

@@ -1,6 +1,7 @@
package fr.titionfire.ffsaf.rest;
import fr.titionfire.ffsaf.domain.service.KeycloakService;
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
import fr.titionfire.ffsaf.rest.from.MemberPermForm;
import fr.titionfire.ffsaf.utils.GroupeUtils;
import fr.titionfire.ffsaf.utils.Pair;
@@ -38,7 +39,7 @@ public class CompteEndpoints {
return service.fetchCompte(id).call(pair -> vertx.getOrCreateContext().executeBlocking(() -> {
if (!securityIdentity.getRoles().contains("federation_admin") && pair.getKey().groups().stream().map(GroupRepresentation::getPath)
.noneMatch(s -> s.startsWith("/club/") && GroupeUtils.contains(s, accessToken)))
throw new ForbiddenException();
throw new DForbiddenException();
return pair;
})).map(Pair::getValue);
}

View File

@@ -3,6 +3,7 @@ package fr.titionfire.ffsaf.rest;
import fr.titionfire.ffsaf.data.model.MembreModel;
import fr.titionfire.ffsaf.domain.service.LicenceService;
import fr.titionfire.ffsaf.rest.data.SimpleLicence;
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
import fr.titionfire.ffsaf.rest.from.LicenceForm;
import fr.titionfire.ffsaf.utils.GroupeUtils;
import io.quarkus.oidc.IdToken;
@@ -33,7 +34,7 @@ public class LicenceEndpoints {
Consumer<MembreModel> checkPerm = Unchecked.consumer(membreModel -> {
if (!securityIdentity.getRoles().contains("federation_admin") && !GroupeUtils.isInClubGroup(membreModel.getClub().getId(), idToken))
throw new ForbiddenException();
throw new DForbiddenException();
});
@GET

View File

@@ -0,0 +1,14 @@
package fr.titionfire.ffsaf.rest.exception;
import jakarta.ws.rs.core.Response;
import java.io.Serial;
public class DBadRequestException extends DetailException {
@Serial
private static final long serialVersionUID = 7518556311032332135L;
public DBadRequestException(String message) {
super(Response.Status.BAD_REQUEST, message);
}
}

View File

@@ -0,0 +1,18 @@
package fr.titionfire.ffsaf.rest.exception;
import jakarta.ws.rs.core.Response;
import java.io.Serial;
public class DForbiddenException extends DetailException {
@Serial
private static final long serialVersionUID = 8408920537659758038L;
public DForbiddenException() {
this("Accès a la ressource interdite");
}
public DForbiddenException(String message) {
super(Response.Status.FORBIDDEN, message);
}
}

View File

@@ -0,0 +1,15 @@
package fr.titionfire.ffsaf.rest.exception;
import jakarta.ws.rs.core.Response;
import java.io.Serial;
public class DInternalError extends DetailException {
@Serial
private static final long serialVersionUID = -3635595157694180842L;
public DInternalError(String message) {
super(Response.Status.INTERNAL_SERVER_ERROR, message);
}
}

View File

@@ -0,0 +1,15 @@
package fr.titionfire.ffsaf.rest.exception;
import jakarta.ws.rs.core.Response;
import java.io.Serial;
public class DNotFoundException extends DetailException{
@Serial
private static final long serialVersionUID = -5193524134675732376L;
public DNotFoundException(String message) {
super(Response.Status.NOT_FOUND, message);
}
}

View File

@@ -0,0 +1,20 @@
package fr.titionfire.ffsaf.rest.exception;
import jakarta.ws.rs.core.Response;
import lombok.Getter;
import java.io.Serial;
@Getter
public class DetailException extends Exception {
@Serial
private static final long serialVersionUID = 5349921926328753676L;
private final Response.Status status;
public DetailException(Response.Status status, String message) {
super(message);
this.status = status;
}
}

View File

@@ -0,0 +1,19 @@
package fr.titionfire.ffsaf.rest.exception;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class DetailExceptionMapper implements ExceptionMapper<DetailException> {
@Override
public Response toResponse(DetailException e) {
return Response.status(e.getStatus())
.entity(e.getMessage())
.type(MediaType.TEXT_PLAIN_TYPE)
.build();
}
}

View File

@@ -0,0 +1,20 @@
package fr.titionfire.ffsaf.rest.exception;
import fr.titionfire.ffsaf.utils.KeycloakException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
@Provider
public class KeycloakExceptionMapper implements ExceptionMapper<KeycloakException> {
@Override
public Response toResponse(KeycloakException e) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity("Erreur du gestionnaire d'identité: " + e.getMessage())
.type(MediaType.TEXT_PLAIN_TYPE)
.build();
}
}