feat: add club member's gestion page

This commit is contained in:
2024-02-04 22:13:21 +01:00
parent 0c9020890a
commit 2a59c22db6
28 changed files with 935 additions and 72 deletions

View File

@@ -79,6 +79,11 @@ public class ExampleResource {
response.append("<li>scopes: ").append(this.accessToken.toString()).append("</li>");
}
if (scopes != null) {
response.append("<li>scopes: ").append(this.accessToken.getClaim("user_groups").toString()).append("</li>");
}
if (scopes != null) {
response.append("<li>getRoles: ").append(this.securityIdentity.getRoles()).append("</li>");
}

View File

@@ -18,7 +18,7 @@ public class LicenceModel {
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@ManyToOne(fetch = FetchType.EAGER)
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "membre", referencedColumnName = "id")
MembreModel membre;

View File

@@ -2,8 +2,7 @@ package fr.titionfire.ffsaf.domain.service;
import fr.titionfire.ffsaf.data.model.ClubModel;
import fr.titionfire.ffsaf.data.model.MembreModel;
import fr.titionfire.ffsaf.utils.KeycloakException;
import fr.titionfire.ffsaf.utils.RequiredAction;
import fr.titionfire.ffsaf.utils.*;
import io.quarkus.runtime.annotations.RegisterForReflection;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.unchecked.Unchecked;
@@ -21,6 +20,7 @@ import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import java.text.Normalizer;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -86,13 +86,42 @@ public class KeycloakService {
})));
}
public Uni<UserCompteState> fetchCompte(String id) {
public Uni<?> setEmail(String userId, String email) {
return vertx.getOrCreateContext().executeBlocking(() -> {
UserResource user = keycloak.realm(realm).users().get(userId);
UserRepresentation user2 = user.toRepresentation();
if (email.equals(user2.getEmail()))
return "";
user2.setEmail(email);
user2.setRequiredActions(List.of(RequiredAction.VERIFY_EMAIL.name()));
user.update(user2);
return "";
});
}
public Uni<?> setAutoRoleMembre(String id, RoleAsso role, GradeArbitrage gradeArbitrage) {
List<String> toRemove = new ArrayList<>(List.of("club_president", "club_tresorier", "club_secretaire", "asseseur", "arbitre"));
List<String> toAdd = new ArrayList<>();
switch (role) {
case PRESIDENT -> toAdd.add("club_president");
case TRESORIER -> toAdd.add("club_tresorier");
case SECRETAIRE -> toAdd.add("club_secretaire");
}
switch (gradeArbitrage) {
case ARBITRE -> toAdd.addAll(List.of("asseseur", "arbitre"));
case ASSESSEUR -> toAdd.add("asseseur");
}
toRemove.removeAll(toAdd);
return updateRole(id, toAdd, toRemove);
}
public Uni<Pair<UserResource, UserCompteState>> fetchCompte(String id) {
return vertx.getOrCreateContext().executeBlocking(() -> {
UserResource user = keycloak.realm(realm).users().get(id);
UserRepresentation user2 = user.toRepresentation();
return new UserCompteState(user2.isEnabled(), user2.getUsername(), user2.isEmailVerified(),
user.roles().realmLevel().listEffective().stream().map(RoleRepresentation::getName).toList(),
user.groups().stream().map(GroupRepresentation::getName).toList());
return new Pair<>(user, new UserCompteState(user2.isEnabled(), user2.getUsername(), user2.isEmailVerified())) ;
});
}
@@ -182,7 +211,6 @@ public class KeycloakService {
}
@RegisterForReflection
public record UserCompteState(Boolean enabled, String login, Boolean emailVerified, List<String> realmRoles,
List<String> groups) {
public record UserCompteState(Boolean enabled, String login, Boolean emailVerified) {
}
}

View File

@@ -1,17 +1,22 @@
package fr.titionfire.ffsaf.domain.service;
import fr.titionfire.ffsaf.data.model.LicenceModel;
import fr.titionfire.ffsaf.data.model.MembreModel;
import fr.titionfire.ffsaf.data.repository.CombRepository;
import fr.titionfire.ffsaf.data.repository.LicenceRepository;
import fr.titionfire.ffsaf.rest.from.LicenceForm;
import fr.titionfire.ffsaf.utils.Utils;
import io.quarkus.hibernate.reactive.panache.Panache;
import io.quarkus.hibernate.reactive.panache.common.WithSession;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.unchecked.Unchecked;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.BadRequestException;
import org.hibernate.reactive.mutiny.Mutiny;
import java.util.List;
import java.util.function.Consumer;
@WithSession
@ApplicationScoped
@@ -23,8 +28,8 @@ public class LicenceService {
@Inject
CombRepository combRepository;
public Uni<List<LicenceModel>> getLicence(long id) {
return combRepository.findById(id).chain(combRepository -> Mutiny.fetch(combRepository.getLicences()));
public Uni<List<LicenceModel>> getLicence(long id, Consumer<MembreModel> checkPerm) {
return combRepository.findById(id).invoke(checkPerm).chain(combRepository -> Mutiny.fetch(combRepository.getLicences()));
}
public Uni<LicenceModel> setLicence(long id, LicenceForm form) {
@@ -49,4 +54,33 @@ public class LicenceService {
public Uni<?> deleteLicence(long id) {
return Panache.withTransaction(() -> repository.deleteById(id));
}
public Uni<LicenceModel> askLicence(long id, LicenceForm form, Consumer<MembreModel> checkPerm) {
return combRepository.findById(id).invoke(checkPerm).chain(membreModel -> {
if (form.getId() == -1) {
return repository.find("saison = ?1", Utils.getSaison()).count().invoke(Unchecked.consumer(count -> {
if (count > 0)
throw new BadRequestException();
})).chain(__ -> combRepository.findById(id).chain(combRepository -> {
LicenceModel model = new LicenceModel();
model.setMembre(combRepository);
model.setSaison(Utils.getSaison());
model.setCertificate(form.isCertificate());
model.setValidate(false);
return Panache.withTransaction(() -> repository.persist(model));
}));
} else {
return repository.findById(form.getId()).chain(model -> {
model.setCertificate(form.isCertificate());
return Panache.withTransaction(() -> repository.persist(model));
});
}
});
}
public Uni<?> deleteAskLicence(long id, Consumer<MembreModel> checkPerm) {
return repository.findById(id)
.call(licenceModel -> Mutiny.fetch(licenceModel.getMembre()).invoke(checkPerm))
.chain(__ -> Panache.withTransaction(() -> repository.deleteById(id)));
}
}

View File

@@ -6,15 +6,21 @@ import fr.titionfire.ffsaf.data.repository.CombRepository;
import fr.titionfire.ffsaf.net2.ServerCustom;
import fr.titionfire.ffsaf.net2.data.SimpleCombModel;
import fr.titionfire.ffsaf.net2.request.SReqComb;
import fr.titionfire.ffsaf.rest.from.ClubMemberForm;
import fr.titionfire.ffsaf.rest.from.FullMemberForm;
import fr.titionfire.ffsaf.utils.GroupeUtils;
import fr.titionfire.ffsaf.utils.Pair;
import fr.titionfire.ffsaf.utils.RoleAsso;
import io.quarkus.hibernate.reactive.panache.Panache;
import io.quarkus.hibernate.reactive.panache.common.WithSession;
import io.quarkus.panache.common.Sort;
import io.quarkus.vertx.VertxContextSupport;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.unchecked.Unchecked;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.ForbiddenException;
import org.eclipse.microprofile.jwt.JsonWebToken;
import java.util.List;
@@ -46,6 +52,11 @@ public class MembreService {
return repository.listAll(Sort.ascending("fname", "lname"));
}
public Uni<List<MembreModel>> getInClub(String subject) {
return repository.find("userId = ?1", subject).firstResult()
.chain(membreModel -> repository.find("club = ?1", membreModel.getClub()).list());
}
public Uni<MembreModel> getById(long id) {
return repository.findById(id);
}
@@ -70,6 +81,46 @@ public class MembreService {
.invoke(membreModel -> SReqComb.sendIfNeed(serverCustom.clients, SimpleCombModel.fromModel(membreModel)))
.call(membreModel -> (membreModel.getUserId() != null) ?
keycloakService.setClubGroupMembre(membreModel, membreModel.getClub()) : Uni.createFrom().nullItem())
.call(membreModel -> (membreModel.getUserId() != null) ?
keycloakService.setAutoRoleMembre(membreModel.getUserId(), membreModel.getRole(),
membreModel.getGrade_arbitrage()) : Uni.createFrom().nullItem())
.call(membreModel -> (membreModel.getUserId() != null) ?
keycloakService.setEmail(membreModel.getUserId(), membreModel.getEmail()) : Uni.createFrom().nullItem())
.map(__ -> "OK");
}
public Uni<String> update(long id, ClubMemberForm membre, JsonWebToken idToken) {
return repository.findById(id)
.invoke(Unchecked.consumer(membreModel -> {
if (!GroupeUtils.isInClubGroup(membreModel.getClub().getId(), idToken))
throw new ForbiddenException();
}))
.invoke(Unchecked.consumer(membreModel -> {
RoleAsso source = RoleAsso.MEMBRE;
if (idToken.getGroups().contains("club_president")) source = RoleAsso.PRESIDENT;
else if (idToken.getGroups().contains("club_secretaire")) source = RoleAsso.SECRETAIRE;
else if (idToken.getGroups().contains("club_respo_intra")) source = RoleAsso.SECRETAIRE;
if (!membre.getRole().equals(membreModel.getRole()) && membre.getRole().level > source.level)
throw new ForbiddenException();
}))
.onItem().transformToUni(target -> {
target.setFname(membre.getFname());
target.setLname(membre.getLname());
target.setCountry(membre.getCountry());
target.setBirth_date(membre.getBirth_date());
target.setGenre(membre.getGenre());
target.setCategorie(membre.getCategorie());
target.setEmail(membre.getEmail());
if (!idToken.getSubject().equals(target.getUserId()))
target.setRole(membre.getRole());
return Panache.withTransaction(() -> repository.persist(target));
})
.invoke(membreModel -> SReqComb.sendIfNeed(serverCustom.clients, SimpleCombModel.fromModel(membreModel)))
.call(membreModel -> (membreModel.getUserId() != null) ?
keycloakService.setAutoRoleMembre(membreModel.getUserId(), membreModel.getRole(),
membreModel.getGrade_arbitrage()) : Uni.createFrom().nullItem())
.call(membreModel -> (membreModel.getUserId() != null) ?
keycloakService.setEmail(membreModel.getUserId(), membreModel.getEmail()) : Uni.createFrom().nullItem())
.map(__ -> "OK");
}
@@ -79,5 +130,4 @@ public class MembreService {
return Panache.withTransaction(() -> repository.persist(membreModel));
});
}
}

View File

@@ -2,8 +2,8 @@ package fr.titionfire.ffsaf.rest;
import fr.titionfire.ffsaf.domain.service.ClubService;
import fr.titionfire.ffsaf.net2.data.SimpleClubModel;
import io.quarkus.security.Authenticated;
import io.smallrye.mutiny.Uni;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@@ -20,7 +20,7 @@ public class ClubEndpoints {
@GET
@Path("/no_detail")
@RolesAllowed("federation_admin")
@Authenticated
@Produces(MediaType.APPLICATION_JSON)
public Uni<List<SimpleClubModel>> getAll() {
return clubService.getAll().map(clubModels -> clubModels.stream().map(SimpleClubModel::fromModel).toList());

View File

@@ -1,9 +1,14 @@
package fr.titionfire.ffsaf.rest;
import fr.titionfire.ffsaf.data.model.MembreModel;
import fr.titionfire.ffsaf.domain.service.MembreService;
import fr.titionfire.ffsaf.rest.data.SimpleMembre;
import fr.titionfire.ffsaf.rest.from.ClubMemberForm;
import fr.titionfire.ffsaf.rest.from.FullMemberForm;
import fr.titionfire.ffsaf.utils.GroupeUtils;
import fr.titionfire.ffsaf.utils.Pair;
import io.quarkus.oidc.IdToken;
import io.quarkus.security.Authenticated;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.unchecked.Unchecked;
import jakarta.annotation.security.RolesAllowed;
@@ -14,6 +19,7 @@ import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jodd.net.MimeTypes;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.jwt.JsonWebToken;
import java.io.*;
import java.net.URI;
@@ -23,7 +29,9 @@ import java.nio.file.Files;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.function.Consumer;
@Authenticated
@Path("api/member")
public class CombEndpoints {
@@ -33,6 +41,15 @@ public class CombEndpoints {
@ConfigProperty(name = "upload_dir")
String media;
@Inject
@IdToken
JsonWebToken idToken;
Consumer<MembreModel> checkPerm = Unchecked.consumer(membreModel -> {
if (!idToken.getGroups().contains("federation_admin") && !GroupeUtils.isInClubGroup(membreModel.getClub().getId(), idToken))
throw new ForbiddenException();
});
@GET
@Path("/all")
@RolesAllowed("federation_admin")
@@ -42,22 +59,62 @@ public class CombEndpoints {
}
@GET
@Path("{id}")
@RolesAllowed("federation_admin")
@Path("/club")
@RolesAllowed({"club_president", "club_secretaire", "club_respo_intra"})
@Produces(MediaType.APPLICATION_JSON)
public Uni<SimpleMembre> getById(@PathParam("id") long id) {
return membreService.getById(id).map(SimpleMembre::fromModel);
public Uni<List<SimpleMembre>> getClub() {
return membreService.getInClub(idToken.getSubject()).map(membreModels -> membreModels.stream().map(SimpleMembre::fromModel).toList());
}
@GET
@Path("{id}")
@RolesAllowed({"federation_admin", "club_president", "club_secretaire", "club_respo_intra"})
@Produces(MediaType.APPLICATION_JSON)
public Uni<SimpleMembre> getById(@PathParam("id") long id) {
return membreService.getById(id).onItem().invoke(checkPerm).map(SimpleMembre::fromModel);
}
@POST
@Path("{id}")
@RolesAllowed("federation_admin")
@RolesAllowed({"federation_admin"})
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Uni<String> setAdminMembre(@PathParam("id") long id, FullMemberForm input) {
Future<String> future = CompletableFuture.supplyAsync(() -> {
try (InputStream is = new BufferedInputStream(new ByteArrayInputStream(input.getPhoto_data()))) {
return membreService.update(id, input)
.invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
})).chain(() -> {
if (input.getPhoto_data().length > 0)
return Uni.createFrom().future(replacePhoto(id, input.getPhoto_data())).invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
}));
else
return Uni.createFrom().nullItem();
});
}
@POST
@Path("club/{id}")
@RolesAllowed({"club_president", "club_secretaire", "club_respo_intra"})
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Uni<String> setMembre(@PathParam("id") long id, ClubMemberForm input) {
return membreService.update(id, input, idToken)
.invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
})).chain(() -> {
if (input.getPhoto_data().length > 0)
return Uni.createFrom().future(replacePhoto(id, input.getPhoto_data())).invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
}));
else
return Uni.createFrom().nullItem();
});
}
private Future<String> replacePhoto(long id, byte[] input) {
return CompletableFuture.supplyAsync(() -> {
try (InputStream is = new BufferedInputStream(new ByteArrayInputStream(input))) {
String mimeType = URLConnection.guessContentTypeFromStream(is);
String[] detectedExtensions = MimeTypes.findExtensionsByMimeTypes(mimeType, false);
if (detectedExtensions.length == 0)
@@ -73,33 +130,17 @@ public class CombEndpoints {
}
String extension = "." + detectedExtensions[0];
Files.write(new File(media, "ppMembre/" + input.getId() + extension).toPath(), input.getPhoto_data());
Files.write(new File(media, "ppMembre/" + id + extension).toPath(), input);
return "OK";
} catch (IOException e) {
return e.getMessage();
}
});
if (input.getPhoto_data().length > 0) {
return membreService.update(id, input)
.invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
}))
.chain(() -> Uni.createFrom().future(future))
.invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
}));
} else {
return membreService.update(id, input)
.invoke(Unchecked.consumer(out -> {
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
}));
}
}
@GET
@Path("{id}/photo")
@RolesAllowed("federation_admin")
@RolesAllowed({"federation_admin", "club_president", "club_secretaire", "club_respo_intra"})
public Uni<Response> getPhoto(@PathParam("id") long id) throws URISyntaxException {
Future<Pair<File, byte[]>> future = CompletableFuture.supplyAsync(() -> {
FilenameFilter filter = (directory, filename) -> filename.startsWith(String.valueOf(id));
@@ -117,7 +158,7 @@ public class CombEndpoints {
URI uri = new URI("https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-chat/ava2.webp");
return Uni.createFrom().future(future)
return membreService.getById(id).onItem().invoke(checkPerm).chain(__ -> Uni.createFrom().future(future)
.map(filePair -> {
if (filePair == null)
return Response.temporaryRedirect(uri).build();
@@ -131,7 +172,7 @@ public class CombEndpoints {
resp.header(HttpHeaders.CONTENT_DISPOSITION, "inline; ");
return resp.build();
});
}));
}
}

View File

@@ -2,13 +2,16 @@ package fr.titionfire.ffsaf.rest;
import fr.titionfire.ffsaf.domain.service.KeycloakService;
import fr.titionfire.ffsaf.rest.from.MemberPermForm;
import fr.titionfire.ffsaf.utils.GroupeUtils;
import fr.titionfire.ffsaf.utils.Pair;
import io.quarkus.oidc.IdToken;
import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.core.Vertx;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.*;
import org.eclipse.microprofile.jwt.JsonWebToken;
import org.keycloak.representations.idm.GroupRepresentation;
import java.util.ArrayList;
import java.util.List;
@@ -19,11 +22,26 @@ public class CompteEndpoints {
@Inject
KeycloakService service;
@Inject
JsonWebToken accessToken;
@Inject
@IdToken
JsonWebToken idToken;
@Inject
Vertx vertx;
@GET
@Path("{id}")
@RolesAllowed("federation_admin")
public Uni<?> getCompte(@PathParam("id") String id) {
return service.fetchCompte(id);
@RolesAllowed({"federation_admin", "club_president", "club_secretaire", "club_respo_intra"})
public Uni<KeycloakService.UserCompteState> getCompte(@PathParam("id") String id) {
return service.fetchCompte(id).call(pair -> vertx.getOrCreateContext().executeBlocking(() -> {
if (!idToken.getGroups().contains("federation_admin") && !pair.getKey().groups().stream().map(GroupRepresentation::getPath)
.anyMatch(s -> s.startsWith("/club/") && GroupeUtils.contains(s, accessToken)))
throw new ForbiddenException();
return pair;
})).map(Pair::getValue);
}
@PUT

View File

@@ -1,15 +1,21 @@
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.from.LicenceForm;
import fr.titionfire.ffsaf.utils.GroupeUtils;
import io.quarkus.oidc.IdToken;
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 org.eclipse.microprofile.jwt.JsonWebToken;
import java.util.List;
import java.util.function.Consumer;
@Path("api/licence")
public class LicenceEndpoints {
@@ -17,12 +23,21 @@ public class LicenceEndpoints {
@Inject
LicenceService licenceService;
@Inject
@IdToken
JsonWebToken idToken;
Consumer<MembreModel> checkPerm = Unchecked.consumer(membreModel -> {
if (!idToken.getGroups().contains("federation_admin") && !GroupeUtils.isInClubGroup(membreModel.getClub().getId(), idToken))
throw new ForbiddenException();
});
@GET
@Path("{id}")
@RolesAllowed("federation_admin")
@RolesAllowed({"federation_admin", "club_president", "club_secretaire", "club_respo_intra"})
@Produces(MediaType.APPLICATION_JSON)
public Uni<List<SimpleLicence>> getLicence(@PathParam("id") long id) {
return licenceService.getLicence(id).map(licenceModels -> licenceModels.stream().map(SimpleLicence::fromModel).toList());
return licenceService.getLicence(id, checkPerm).map(licenceModels -> licenceModels.stream().map(SimpleLicence::fromModel).toList());
}
@POST
@@ -41,4 +56,21 @@ public class LicenceEndpoints {
public Uni<?> deleteLicence(@PathParam("id") long id) {
return licenceService.deleteLicence(id);
}
@POST
@Path("club/{id}")
@RolesAllowed({"club_president", "club_secretaire", "club_respo_intra"})
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Uni<SimpleLicence> askLicence(@PathParam("id") long id, LicenceForm form) {
return licenceService.askLicence(id, form, checkPerm).map(SimpleLicence::fromModel);
}
@DELETE
@Path("club/{id}")
@RolesAllowed({"club_president", "club_secretaire", "club_respo_intra"})
@Produces(MediaType.TEXT_PLAIN)
public Uni<?> deleteAskLicence(@PathParam("id") long id) {
return licenceService.deleteAskLicence(id, checkPerm);
}
}

View File

@@ -6,6 +6,8 @@ import lombok.Builder;
import lombok.Data;
import org.eclipse.microprofile.jwt.JsonWebToken;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Data
@@ -19,7 +21,7 @@ public class UserInfo {
String email;
boolean emailVerified;
long expiration;
Set<String> groups;
List<String> groups;
Set<String> roles;
public static UserInfo makeUserInfo(JsonWebToken accessToken, SecurityIdentity securityIdentity) {
@@ -31,7 +33,13 @@ public class UserInfo {
builder.email(accessToken.getClaim("email"));
builder.emailVerified(accessToken.getClaim("email_verified"));
builder.expiration(accessToken.getExpirationTime());
builder.groups(accessToken.getGroups());
List<String> groups = new ArrayList<>();
if (accessToken.getClaim("user_groups") instanceof Iterable<?>) {
for (Object str : (Iterable<?>) accessToken.getClaim("user_groups")) {
groups.add(str.toString().substring(1, str.toString().length() - 1));
}
}
builder.groups(groups);
builder.roles(securityIdentity.getRoles());
return builder.build();
}

View File

@@ -0,0 +1,61 @@
package fr.titionfire.ffsaf.rest.from;
import fr.titionfire.ffsaf.utils.Categorie;
import fr.titionfire.ffsaf.utils.Genre;
import fr.titionfire.ffsaf.utils.RoleAsso;
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.core.MediaType;
import lombok.Getter;
import org.jboss.resteasy.reactive.PartType;
import java.util.Date;
@Getter
public class ClubMemberForm {
@FormParam("id")
private String id = null;
@FormParam("lname")
private String lname = null;
@FormParam("fname")
private String fname = null;
@FormParam("categorie")
private Categorie categorie = null;
@FormParam("genre")
private Genre genre;
@FormParam("country")
private String country;
@FormParam("birth_date")
private Date birth_date;
@FormParam("email")
private String email;
@FormParam("role")
private RoleAsso role;
@FormParam("photo_data")
@PartType(MediaType.APPLICATION_OCTET_STREAM)
private byte[] photo_data = new byte[0];
@Override
public String toString() {
return "ClubMemberForm{" +
"id='" + id + '\'' +
", lname='" + lname + '\'' +
", fname='" + fname + '\'' +
", categorie=" + categorie +
", genre=" + genre +
", country='" + country + '\'' +
", birth_date=" + birth_date +
", email='" + email + '\'' +
", role=" + role +
", url_photo=" + photo_data.length +
'}';
}
}

View File

@@ -0,0 +1,25 @@
package fr.titionfire.ffsaf.utils;
import org.eclipse.microprofile.jwt.JsonWebToken;
public class GroupeUtils {
public static boolean isInClubGroup(long id, JsonWebToken accessToken) {
if (accessToken.getClaim("user_groups") instanceof Iterable<?>) {
for (Object str : (Iterable<?>) accessToken.getClaim("user_groups")) {
if (str.toString().substring(1, str.toString().length() - 1).startsWith("/club/" + id + "-"))
return true;
}
}
return false;
}
public static boolean contains(String string, JsonWebToken accessToken) {
if (accessToken.getClaim("user_groups") instanceof Iterable<?>) {
for (Object str : (Iterable<?>) accessToken.getClaim("user_groups")) {
if (str.toString().substring(1, str.toString().length() - 1).contains(string))
return true;
}
}
return false;
}
}

View File

@@ -4,19 +4,17 @@ import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection
public enum RoleAsso {
MEMBRE("Membre"),
PRESIDENT("Président"),
TRESORIER("Trésorier"),
SECRETAIRE("Secrétaire");
MEMBRE("Membre", 0),
PRESIDENT("Président", 3),
TRESORIER("Trésorier", 1),
SECRETAIRE("Secrétaire", 2);
public String name;
public final String name;
public final int level;
RoleAsso(String name) {
this.name = name;
}
public void setName(String name) {
RoleAsso(String name, int level) {
this.name = name;
this.level = level;
}
@Override

View File

@@ -0,0 +1,22 @@
package fr.titionfire.ffsaf.utils;
import java.util.Calendar;
import java.util.Date;
public class Utils {
public static int getSaison() {
return getSaison(new Date());
}
public static int getSaison(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
if (calendar.get(Calendar.MONTH) >= Calendar.SEPTEMBER) {
return calendar.get(Calendar.YEAR);
} else {
return calendar.get(Calendar.YEAR) - 1;
}
}
}