From 0757ae71989aadf62325d08b24a7089fadd754ce Mon Sep 17 00:00:00 2001 From: Thibaut Valentin Date: Mon, 5 Jan 2026 14:20:22 +0100 Subject: [PATCH] feat: allow admin and club admin to get comp result --- .../ffsaf/domain/service/ResultService.java | 89 ++++++++++++++----- .../ffsaf/rest/ExternalResultEndpoints.java | 5 +- .../ffsaf/rest/ResultEndpoints.java | 9 +- 3 files changed, 73 insertions(+), 30 deletions(-) diff --git a/src/main/java/fr/titionfire/ffsaf/domain/service/ResultService.java b/src/main/java/fr/titionfire/ffsaf/domain/service/ResultService.java index 934322d..ca07ad5 100644 --- a/src/main/java/fr/titionfire/ffsaf/domain/service/ResultService.java +++ b/src/main/java/fr/titionfire/ffsaf/domain/service/ResultService.java @@ -93,12 +93,21 @@ public class ResultService { public Uni> getList(SecurityCtx securityCtx) { return membreService.getByAccountId(securityCtx.getSubject()) - .chain(m -> registerRepository.list("membre = ?1", m)) + .chain(m -> registerRepository.list( + "membre = ?1 OR (TRUE = ?2 AND membre.club = ?3)", + m, securityCtx.isClubAdmin(), m.getClub())) .onItem().transformToMulti(Multi.createFrom()::iterable) .onItem().call(r -> Mutiny.fetch(r.getCompetition())) - .onItem().transform(r -> new Object[]{r.getCompetition().getUuid(), r.getCompetition().getName(), - r.getCompetition().getDate()}) - .collect().asList(); + .onItem().transform(RegisterModel::getCompetition) + .collect().asList() + .chain(l -> compRepository.list("owner = ?1 OR ?1 IN admin", securityCtx.getSubject()) + .map(l2 -> Stream.concat(l.stream(), l2.stream()).distinct() + .map(c -> new Object[]{c.getUuid(), c.getName(), c.getDate()}).toList()) + ); + } + + public Uni> getCategoryList(String uuid, SecurityCtx securityCtx) { + return hasAccess(uuid, securityCtx).chain(__ -> getCategoryList(uuid)); } public Uni> getCategoryList(String uuid) { @@ -113,11 +122,11 @@ public class ResultService { } public Uni getCategory(String uuid, long poule, SecurityCtx securityCtx) { - return hasAccess(uuid, securityCtx).chain(r -> + return hasAccess(uuid, securityCtx).chain(membreModel -> matchRepository.list("category.compet.uuid = ?1 AND category.id = ?2", uuid, poule) .call(list -> list.isEmpty() ? Uni.createFrom().voidItem() : Mutiny.fetch(list.get(0).getCategory().getTree())) - .map(list -> getData(list, r.getMembre()))); + .map(list -> getData(list, membreModel))); } public Uni getCategory(String uuid, long poule) { @@ -242,7 +251,7 @@ public class ResultService { public Uni getAllCombArray(String uuid, SecurityCtx securityCtx) { return hasAccess(uuid, securityCtx) - .chain(r -> getAllCombArray_(uuid, r.getMembre())); + .chain(membreModel -> getAllCombArray_(uuid, membreModel)); } public Uni getAllCombArrayPublic(String uuid) { @@ -315,7 +324,16 @@ public class ResultService { }); } - public Uni> getCombList(String uuid, ResultPrivacy privacy) { + public Uni> getCombList(String uuid, SecurityCtx securityCtx) { + return hasAccess(uuid, securityCtx) + .chain(membreModel -> getCombList(uuid, ResultPrivacy.REGISTERED_ONLY)); + } + + public Uni> getCombList(String uuid) { + return getCombList(uuid, ResultPrivacy.PUBLIC); + } + + private Uni> getCombList(String uuid, ResultPrivacy privacy) { return registerRepository.list("competition.uuid = ?1 AND membre.resultPrivacy <= ?2", uuid, privacy) .map(models -> { HashMap map = new HashMap<>(); @@ -332,7 +350,16 @@ public class ResultService { ); } - public Uni getCombArrayPublic(String uuid, String combTempId, ResultPrivacy privacy) { + public Uni getCombArrayPublic(String uuid, String combTempId, SecurityCtx securityCtx) { + return hasAccess(uuid, securityCtx) + .chain(membreModel -> getCombArrayPublic(uuid, combTempId, ResultPrivacy.REGISTERED_ONLY)); + } + + public Uni getCombArrayPublic(String uuid, String combTempId) { + return getCombArrayPublic(uuid, combTempId, ResultPrivacy.PUBLIC); + } + + private Uni getCombArrayPublic(String uuid, String combTempId, ResultPrivacy privacy) { CombArrayData.CombArrayDataBuilder builder = CombArrayData.builder(); Long id = getCombTempId(combTempId); @@ -471,6 +498,10 @@ public class ResultService { } } + public Uni> getClubList(String uuid, SecurityCtx securityCtx) { + return hasAccess(uuid, securityCtx).chain(__ -> getClubList(uuid)); + } + public Uni> getClubList(String uuid) { return registerRepository.list("competition.uuid = ?1", uuid) .map(registers -> { @@ -491,7 +522,7 @@ public class ResultService { } public Uni getClubArray(String uuid, Long id, SecurityCtx securityCtx) { - return hasAccess(uuid, securityCtx).chain(cm_register -> getClubArray2(uuid, id, cm_register.getMembre())); + return hasAccess(uuid, securityCtx).chain(membreModel -> getClubArray2(uuid, id, membreModel)); } public Uni getClubArray2(String uuid, Long id, MembreModel membreModel) { @@ -620,21 +651,35 @@ public class ResultService { } } - private Uni hasAccess(String uuid, SecurityCtx securityCtx) { + private Uni hasAccess(String uuid, SecurityCtx securityCtx) { return registerRepository.find("membre.userId = ?1 AND competition.uuid = ?2", securityCtx.getSubject(), uuid) .firstResult() - .invoke(Unchecked.consumer(o -> { - if (o == null) - throw new DForbiddenException("Access denied"); - })); - } + .chain(Unchecked.function(o -> { + if (o != null) + return Uni.createFrom().item(o.getMembre()); - private Uni hasAccess(Long compId, SecurityCtx securityCtx) { - return registerRepository.find("membre.userId = ?1 AND competition.id = ?2", securityCtx.getSubject(), compId) - .firstResult() - .invoke(Unchecked.consumer(o -> { - if (o == null) - throw new DForbiddenException("Access denied"); + return membreService.getByAccountId(securityCtx.getSubject()).chain(m -> { + if (securityCtx.isClubAdmin()) { + return registerRepository.count("membre.club = ?2 AND competition.uuid = ?1", + uuid, m.getClub()).chain(c -> { + if (c > 0) return Uni.createFrom().item(m); + + return compRepository.count("uuid = ?1 AND (owner = ?2 OR ?2 IN admin)", + uuid, securityCtx.getSubject()) + .chain(c2 -> { + if (c2 > 0) return Uni.createFrom().item(m); + return Uni.createFrom().failure(new DForbiddenException("Access denied")); + }); + }); + } else { + return compRepository.count("uuid = ?1 AND (owner = ?2 OR ?2 IN admin)", uuid, + securityCtx.getSubject()) + .chain(c2 -> { + if (c2 > 0) return Uni.createFrom().item(m); + return Uni.createFrom().failure(new DForbiddenException("Access denied")); + }); + } + }); })); } } diff --git a/src/main/java/fr/titionfire/ffsaf/rest/ExternalResultEndpoints.java b/src/main/java/fr/titionfire/ffsaf/rest/ExternalResultEndpoints.java index 2febbd1..259c3bb 100644 --- a/src/main/java/fr/titionfire/ffsaf/rest/ExternalResultEndpoints.java +++ b/src/main/java/fr/titionfire/ffsaf/rest/ExternalResultEndpoints.java @@ -2,7 +2,6 @@ package fr.titionfire.ffsaf.rest; import fr.titionfire.ffsaf.domain.service.ResultService; import fr.titionfire.ffsaf.domain.service.UpdateService; -import fr.titionfire.ffsaf.utils.ResultPrivacy; import io.smallrye.mutiny.Uni; import jakarta.inject.Inject; import jakarta.ws.rs.*; @@ -47,7 +46,7 @@ public class ExternalResultEndpoints { @Path("/comb/list") @Produces(MediaType.APPLICATION_JSON) public Uni> combList() { - return resultService.getCombList(id, ResultPrivacy.PUBLIC); + return resultService.getCombList(id); } @GET @@ -56,7 +55,7 @@ public class ExternalResultEndpoints { public Uni getArray(@QueryParam("comb") String comb) { if (comb.equals("0")) return Uni.createFrom().item(""); - return resultService.getCombArrayPublic(id, comb, ResultPrivacy.PUBLIC); + return resultService.getCombArrayPublic(id, comb); } @GET diff --git a/src/main/java/fr/titionfire/ffsaf/rest/ResultEndpoints.java b/src/main/java/fr/titionfire/ffsaf/rest/ResultEndpoints.java index e1449fb..25e1a6e 100644 --- a/src/main/java/fr/titionfire/ffsaf/rest/ResultEndpoints.java +++ b/src/main/java/fr/titionfire/ffsaf/rest/ResultEndpoints.java @@ -2,7 +2,6 @@ package fr.titionfire.ffsaf.rest; import fr.titionfire.ffsaf.domain.service.ResultService; import fr.titionfire.ffsaf.rest.data.ResultCategoryData; -import fr.titionfire.ffsaf.utils.ResultPrivacy; import fr.titionfire.ffsaf.utils.SecurityCtx; import io.quarkus.security.Authenticated; import io.smallrye.mutiny.Uni; @@ -33,7 +32,7 @@ public class ResultEndpoints { @GET @Path("{uuid}/category/list") public Uni> getCategoryList(@PathParam("uuid") String uuid) { - return resultService.getCategoryList(uuid); + return resultService.getCategoryList(uuid, securityCtx); } @GET @@ -45,7 +44,7 @@ public class ResultEndpoints { @GET @Path("{uuid}/club/list") public Uni> getClubList(@PathParam("uuid") String uuid) { - return resultService.getClubList(uuid); + return resultService.getClubList(uuid, securityCtx); } @GET @@ -57,13 +56,13 @@ public class ResultEndpoints { @GET @Path("{uuid}/comb/list") public Uni> getCombList(@PathParam("uuid") String uuid) { - return resultService.getCombList(uuid, ResultPrivacy.REGISTERED_ONLY); + return resultService.getCombList(uuid, securityCtx); } @GET @Path("{uuid}/comb/{id}") public Uni getCombList(@PathParam("uuid") String uuid, @PathParam("id") String id) { - return resultService.getCombArrayPublic(uuid, id, ResultPrivacy.REGISTERED_ONLY); + return resultService.getCombArrayPublic(uuid, id, securityCtx); } @GET