diff --git a/pom.xml b/pom.xml index b188d1d..853ed70 100644 --- a/pom.xml +++ b/pom.xml @@ -60,6 +60,10 @@ io.quarkus quarkus-security-jpa + + io.quarkus + quarkus-smallrye-openapi + io.quarkus quarkus-junit5 diff --git a/src/main/java/com/covas/Entity/UsersEntity.java b/src/main/java/com/covas/Entity/UsersEntity.java index 0d17bc8..1f1d2e9 100644 --- a/src/main/java/com/covas/Entity/UsersEntity.java +++ b/src/main/java/com/covas/Entity/UsersEntity.java @@ -1,13 +1,12 @@ package com.covas.Entity; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.UUID; -import javax.annotation.Generated; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @@ -40,10 +39,19 @@ public class UsersEntity extends PanacheEntityBase { public LocalDate birth; @ColumnDefault("false") public Boolean status; + @ColumnDefault("false") + public Boolean active_mail; @Column(nullable = false) public String password; + @Column(nullable = false) public String roles; - + @Column(nullable = false) + public LocalDateTime created_at; + @Column(nullable = false) + public LocalDateTime updated_at; + @ColumnDefault("null") + public LocalDateTime deleted_at; + public static UsersEntity findByPseudo(String pseudo){ return find("pseudo", pseudo).firstResult(); } @@ -59,6 +67,8 @@ public class UsersEntity extends PanacheEntityBase { users.status = false; users.password = Hash.encryptSHA512(password); users.roles = roles; + users.created_at = LocalDateTime.now(); + users.updated_at = LocalDateTime.now(); users.persist(); } } \ No newline at end of file diff --git a/src/main/java/com/covas/Json/UserSingle.java b/src/main/java/com/covas/Json/UserSingle.java new file mode 100644 index 0000000..22ea520 --- /dev/null +++ b/src/main/java/com/covas/Json/UserSingle.java @@ -0,0 +1,21 @@ +package com.covas.Json; + +import java.time.LocalDate; + +import io.quarkus.runtime.annotations.RegisterForReflection; + +@RegisterForReflection +public class UserSingle { + + public final String name; + public final String pseudo; + public final String firstname; + + public UserSingle(String name, String pseudo, String firstname){ + this.name = name; + this.pseudo = pseudo; + this.firstname = firstname; + + } + +} diff --git a/src/main/java/com/covas/Resources/TokenRessource.java b/src/main/java/com/covas/Resources/TokenRessource.java index 84daf33..9daf5e3 100644 --- a/src/main/java/com/covas/Resources/TokenRessource.java +++ b/src/main/java/com/covas/Resources/TokenRessource.java @@ -2,9 +2,6 @@ package com.covas.Resources; import java.nio.charset.StandardCharsets; import java.time.Duration; -import java.util.Arrays; -import java.util.HashSet; - import javax.inject.Inject; import javax.ws.rs.CookieParam; @@ -59,8 +56,8 @@ public class TokenRessource { return Response.status(Response.Status.NOT_FOUND).build(); } if (jwtCookie == null) { - if(!password.equals(users.password)){ - return Response.status(Response.Status.FORBIDDEN).build(); + if((!password.equals(users.password)) && (!users.status)) { + return Response.status(Response.Status.FORBIDDEN).build(); } // Create a JWT token signed using the 'HS256' algorithm String newJwtCookie = Jwt.issuer("https://example.com/issuer").upn(name).groups(users.roles).claim(Claims.kid, users.id.toString()).expiresIn(Duration.ofMinutes(1)).sign(); diff --git a/src/main/java/com/covas/Resources/UsersRessources.java b/src/main/java/com/covas/Resources/UsersRessources.java index 1f193fe..9392a36 100644 --- a/src/main/java/com/covas/Resources/UsersRessources.java +++ b/src/main/java/com/covas/Resources/UsersRessources.java @@ -1,48 +1,315 @@ package com.covas.Resources; +import java.nio.charset.StandardCharsets; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.UUID; import javax.annotation.security.RolesAllowed; +import javax.inject.Inject; +import javax.transaction.Transactional; +import javax.ws.rs.core.SecurityContext; +import javax.ws.rs.Consumes; +import javax.ws.rs.CookieParam; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; +import javax.ws.rs.PATCH; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import com.covas.Classes.Hash; import com.covas.Entity.UsersEntity; +import com.covas.Json.UserSingle; +import org.eclipse.microprofile.jwt.Claims; +import org.eclipse.microprofile.jwt.JsonWebToken; import org.jboss.logging.Logger; - +import org.postgresql.shaded.com.ongres.scram.common.bouncycastle.base64.Base64; @Produces(MediaType.APPLICATION_JSON) @Path("users") public class UsersRessources { private static final Logger LOGGER = Logger.getLogger(UsersRessources.class); + @Inject + JsonWebToken jwt; + + /// Function + private Boolean checkUserCookie(String userCookie, UsersEntity users) { + if ((userCookie == null) || (users == null)) { + return false; + } + String name = new String(Base64.decode(userCookie), StandardCharsets.UTF_8); + if (!name.equals(users.pseudo) && (!users.status)) { + return false; + } + return true; + } + + private Response.Status getResponseCheck(SecurityContext ctx, String userCookie, UsersEntity users) { + if (!ctx.getUserPrincipal().getName().equals(jwt.getName())) { + return Response.Status.INTERNAL_SERVER_ERROR; + } + if (!checkUserCookie(userCookie, users)) { + return Response.Status.FORBIDDEN; + } + return Response.Status.OK; + } + + /// Appel HTTP + + /// GET @GET @RolesAllowed("Admin") - public Response getUsers(){ - return Response.ok(UsersEntity.listAll()).build(); + public Response getUsers(@CookieParam("user") String userCookie, @Context SecurityContext ctx) { + UUID kid = UUID.fromString(jwt.getClaim(Claims.kid)); + UsersEntity user = UsersEntity.findById(kid); + Response.Status status = getResponseCheck(ctx, userCookie, user); + Response responseHttp = Response.status(status).build(); + if (status.equals(Response.Status.OK)) { + responseHttp = Response.ok(UsersEntity.listAll()).build(); + } + return responseHttp; } @GET @RolesAllowed("Admin") @Path("{id}") - public Response getSingleUser(@PathParam("id") String id){ - UUID uid = UUID.fromString(id); - UsersEntity users = UsersEntity.findById(uid); - if(users == null){ - return Response.status(Response.Status.NOT_FOUND).build(); + public Response getSingleUser(@PathParam("id") String id, @CookieParam("user") String userCookie, + @Context SecurityContext ctx) { + UUID kid = UUID.fromString(jwt.getClaim(Claims.kid)); + UsersEntity user = UsersEntity.findById(kid); + Response.Status status = getResponseCheck(ctx, userCookie, user); + Response responseHttp = Response.status(status).build(); + if (status.equals(Response.Status.OK)) { + UUID uid = UUID.fromString(id); + UsersEntity users = UsersEntity.findById(uid); + responseHttp = Response.status(Response.Status.NOT_FOUND).build(); + if (users != null) { + responseHttp = Response.ok(users).build(); + } + } - return Response.ok(users).build(); + return responseHttp; } @GET @RolesAllowed("User") @Path("info") - public Response getInfoUser(){ - return Response.ok().build(); + public Response getInfoUser(@Context SecurityContext ctx, @CookieParam("user") String userCookie) { + UUID kid = UUID.fromString(jwt.getClaim(Claims.kid)); + UsersEntity user = UsersEntity.findById(kid); + Response.Status status = getResponseCheck(ctx, userCookie, user); + if (status.equals(Response.Status.OK)) { + if (user == null) { + status = Response.Status.NOT_FOUND; + } + if (!checkUserCookie(userCookie, user)) { + status = Response.Status.FORBIDDEN; + } + } + Response responseHttp = Response.status(status).build(); + if (status.equals(Response.Status.OK)) { + responseHttp = Response.status(status).entity(new UserSingle(user.name, user.pseudo, user.firstName)) + .build(); + } + return responseHttp; } - + // POST + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Transactional + public Response createUser(UsersEntity users) { + Response.Status status = Response.Status.OK; + UsersEntity usersOrig = UsersEntity.findByPseudo(users.pseudo); + if (usersOrig != null) { + status = Response.Status.UNAUTHORIZED; + } else { + UsersEntity usersNew = new UsersEntity(); + usersNew.name = users.name; + usersNew.pseudo = users.pseudo; + usersNew.firstName = users.firstName; + usersNew.email = users.email; + usersNew.birth = LocalDate.of(users.birth.getYear(), users.birth.getMonth(), + users.birth.getDayOfMonth()); + usersNew.created_at = LocalDateTime.now(); + usersNew.updated_at = LocalDateTime.now(); + usersNew.password = Hash + .encryptSHA512(Base64.toBase64String(users.password.getBytes(StandardCharsets.UTF_8))); + usersNew.roles = users.roles; + usersNew.status = false; + usersNew.active_mail = false; + usersNew.persist(); + if (usersNew.isPersistent()) { + status = Response.Status.CREATED; + } else { + status = Response.Status.NO_CONTENT; + } + } + return Response.status(status).build(); + } + + + // PUT + @PUT + @Path("{pseudo}") + @RolesAllowed("Admin") + @Consumes(MediaType.APPLICATION_JSON) + @Transactional + public Response addUser(@Context SecurityContext ctx, @CookieParam("user") String userCookie, @PathParam("pseudo") String pseudo, + UsersEntity users) { + UUID kid = UUID.fromString(jwt.getClaim(Claims.kid)); + UsersEntity user = UsersEntity.findById(kid); + Response.Status status = getResponseCheck(ctx, userCookie, user); + + if (status.equals(Response.Status.OK)) { + + UsersEntity usersOrig = UsersEntity.findByPseudo(pseudo); + if (usersOrig != null) { + status = Response.Status.UNAUTHORIZED; + } else { + UsersEntity usersNew = new UsersEntity(); + usersNew.name = users.name; + usersNew.pseudo = pseudo; + usersNew.firstName = users.firstName; + usersNew.email = users.email; + usersNew.birth = LocalDate.of(users.birth.getYear(), users.birth.getMonth(), + users.birth.getDayOfMonth()); + usersNew.created_at = LocalDateTime.now(); + usersNew.updated_at = LocalDateTime.now(); + usersNew.password = Hash + .encryptSHA512(Base64.toBase64String(users.password.getBytes(StandardCharsets.UTF_8))); + usersNew.roles = users.roles; + usersNew.status = false; + usersNew.active_mail = true; + usersNew.persist(); + if (usersNew.isPersistent()) { + status = Response.Status.CREATED; + } else { + status = Response.Status.NO_CONTENT; + } + } + } + return Response.status(status).build(); + } + + // Delete + @DELETE + @RolesAllowed("User") + @Transactional + public Response changeStatus(@Context SecurityContext ctx, @CookieParam("user") String userCookie) { + UUID kid = UUID.fromString(jwt.getClaim(Claims.kid)); + UsersEntity user = UsersEntity.findById(kid); + + Response.Status status = getResponseCheck(ctx, userCookie, user); + + if (status.equals(Response.Status.OK)) { + user.status = false; + user.updated_at = LocalDateTime.now(); + user.deleted_at = LocalDateTime.now(); + user.persist(); + if (!user.isPersistent()) { + status = Response.Status.NOT_MODIFIED; + } + } + return Response.status(status).build(); + } + + @DELETE + @Path("{id}") + @RolesAllowed("Admin") + @Transactional + public Response changeStatusSingleUser(@Context SecurityContext ctx, @CookieParam("user") String userCookie, + @PathParam("id") String id) { + UUID kid = UUID.fromString(jwt.getClaim(Claims.kid)); + UsersEntity user = UsersEntity.findById(kid); + Response.Status status = getResponseCheck(ctx, userCookie, user); + if (status.equals(Response.Status.OK)) { + UsersEntity singleUser = UsersEntity.find("id", UUID.fromString(id)).firstResult(); + if (singleUser == null) { + status = Response.Status.NOT_FOUND; + } else { + singleUser.status = false; + singleUser.updated_at = LocalDateTime.now(); + singleUser.deleted_at = LocalDateTime.now(); + singleUser.persist(); + if (!singleUser.isPersistent()) { + status = Response.Status.NOT_MODIFIED; + } + } + } + return Response.status(status).build(); + } + + // PATCH + @PATCH + @RolesAllowed("Admin") + @Consumes(MediaType.APPLICATION_JSON) + @Transactional + public Response updateUserAdmin(@Context SecurityContext ctx, @CookieParam("user") String userCookie, + UsersEntity users) { + UUID kid = UUID.fromString(jwt.getClaim(Claims.kid)); + UsersEntity user = UsersEntity.findById(kid); + Response.Status status = getResponseCheck(ctx, userCookie, user); + + if (status.equals(Response.Status.OK)) { + + UsersEntity usersOrig = UsersEntity.findByPseudo(users.pseudo); + if (usersOrig == null) { + status = Response.Status.NOT_FOUND; + } else { + usersOrig.name = users.name; + usersOrig.firstName = users.firstName; + usersOrig.email = users.email; + usersOrig.birth = LocalDate.of(users.birth.getYear(), users.birth.getMonth(), + users.birth.getDayOfMonth()); + usersOrig.updated_at = LocalDateTime.now(); + usersOrig.password = Hash + .encryptSHA512(Base64.toBase64String(users.password.getBytes(StandardCharsets.UTF_8))); + usersOrig.roles = users.roles; + if(users.status){ + usersOrig.deleted_at = null; + usersOrig.status = true; + } + usersOrig.persist(); + if (!usersOrig.isPersistent()) { + status = Response.Status.NOT_MODIFIED; + } + } + } + return Response.status(status).build(); + } + + @PATCH + @RolesAllowed("User") + @Consumes(MediaType.APPLICATION_JSON) + @Transactional + public Response updateSingleUser(@Context SecurityContext ctx, @CookieParam("user") String userCookie, + UsersEntity users) { + UUID kid = UUID.fromString(jwt.getClaim(Claims.kid)); + UsersEntity user = UsersEntity.findById(kid); + Response.Status status = getResponseCheck(ctx, userCookie, user); + + if (status.equals(Response.Status.OK)) { + + user.name = users.name; + user.firstName = users.firstName; + user.email = users.email; + user.birth = LocalDate.of(users.birth.getYear(), users.birth.getMonth(), + users.birth.getDayOfMonth()); + user.updated_at = LocalDateTime.now(); + user.password = Hash.encryptSHA512(Base64.toBase64String(users.password.getBytes(StandardCharsets.UTF_8))); + user.persist(); + if (!user.isPersistent()) { + status = Response.Status.NOT_MODIFIED; + } + } + return Response.status(status).build(); + } }