Skip to content

Commit

Permalink
Merge pull request #20 from quotly-eu/feature/rest-endpoints
Browse files Browse the repository at this point in the history
#4: Smaller changes for the user restendpoint
  • Loading branch information
dotnomi authored Nov 7, 2024
2 parents 9b0cb9d + e175cfd commit 4ca4f25
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 14 deletions.
17 changes: 17 additions & 0 deletions src/main/java/eu/quotly/converter/UserEntityConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package eu.quotly.converter;

import eu.quotly.dto.UserDto;
import eu.quotly.entity.UserEntity;
import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class UserEntityConverter {
public UserDto toUserDto(UserEntity userEntity) {
return new UserDto(
userEntity.getDiscordId(),
userEntity.getDisplayName(),
userEntity.getEmailAddress(),
userEntity.getCreationTime()
);
}
}
5 changes: 4 additions & 1 deletion src/main/java/eu/quotly/entity/UserEntity.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package eu.quotly.entity;

import eu.quotly.Constants;
import eu.quotly.entity.listener.UserEntityListener;
import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
Expand All @@ -27,6 +29,7 @@
@NoArgsConstructor
@Table(name = "users", schema = "quotly")
@EqualsAndHashCode(callSuper = true)
@EntityListeners(UserEntityListener.class)
public class UserEntity extends PanacheEntityBase {
@Id
@Column(name = "user_id", nullable = false, updatable = false)
Expand All @@ -38,7 +41,7 @@ public class UserEntity extends PanacheEntityBase {
private String discordId;

@Column(name = "email_address", length = Constants.DB_LARGE_STRING_LENGTH)
private String emailAddress; // TODO: Email Address encryption
private String emailAddress;

@Column(name = "display_name", length = Constants.DB_EXTRA_SMALL_STRING_LENGTH)
private String displayName;
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/eu/quotly/entity/listener/UserEntityListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package eu.quotly.entity.listener;

import eu.quotly.config.QuotlyConfig;
import eu.quotly.entity.UserEntity;
import eu.quotly.service.EmailEncryptionService;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.persistence.PostLoad;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ApplicationScoped
public class UserEntityListener {
private static final Logger LOGGER = LoggerFactory.getLogger(UserEntityListener.class);

@Inject
EmailEncryptionService emailEncryptionService;

@Inject
QuotlyConfig quotlyConfig;

@PrePersist
@PreUpdate
public void encryptSensitiveData(UserEntity user) {
if (quotlyConfig.isEmailEncryptionEnabled()) {
String emailAddress = user.getEmailAddress();
try {
user.setEmailAddress(emailEncryptionService.getEncryptedEmailAddress(user));
} catch (Exception exception) {
LOGGER.error("Unable to encrypt email address from user {}", user.getDisplayName(), exception);
user.setEmailAddress(emailAddress);
}
}
}

@PostLoad
public void decryptSensitiveData(UserEntity user) {
String emailAddress = user.getEmailAddress();
try {
user.setEmailAddress(emailEncryptionService.getDecryptedEmailAddress(user));
} catch (Exception exception) {
LOGGER.error("Unable to decrypt email address from user {}", user.getDisplayName(), exception);
user.setEmailAddress(emailAddress);
}
}
}
5 changes: 4 additions & 1 deletion src/main/java/eu/quotly/resource/UserResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;

@Path("/v1/users")
@Produces(MediaType.APPLICATION_JSON)
Expand All @@ -22,14 +23,16 @@ public Response getUsers(
@QueryParam("start") String startTime,
@QueryParam("end") String endTime,
@QueryParam("search") @DefaultValue("") String searchQuery,
@QueryParam("page") @DefaultValue("0") Integer pageIndex,
@QueryParam("page") @DefaultValue("1") Integer pageIndex,
@QueryParam("limit") @DefaultValue("10") Integer pageSize
) {
return userService.getAllUsers(startTime, endTime, searchQuery, pageIndex, pageSize);
}

@GET
@Path("/{discordId}")
@APIResponse(responseCode = "200", description = "User found")
@APIResponse(responseCode = "404", description = "User not found")
public Response getUser(@PathParam("discordId") String discordId) {
return userService.getUserByDiscordId(discordId);
}
Expand Down
28 changes: 16 additions & 12 deletions src/main/java/eu/quotly/service/UserService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package eu.quotly.service;

import eu.quotly.config.ErrorCode;
import eu.quotly.converter.UserEntityConverter;
import eu.quotly.dto.UserDto;
import eu.quotly.entity.UserEntity;
import eu.quotly.repository.UserRepository;
Expand All @@ -12,6 +13,7 @@

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@ApplicationScoped
Expand All @@ -20,6 +22,7 @@ public class UserService {

@Inject UserRepository userRepository;
@Inject ResponseService responseService;
@Inject UserEntityConverter userEntityConverter;

public Response getAllUsers(
String startTime,
Expand All @@ -28,7 +31,7 @@ public Response getAllUsers(
Integer pageIndex,
Integer pageSize
) {
if (pageIndex < 0 || pageSize < 1) {
if (pageIndex < 1 || pageSize < 1) {
return responseService.createErrorResponse(Response.Status.BAD_REQUEST, ErrorCode.INVALID_PAGE_INDEX_OR_SIZE);
}

Expand Down Expand Up @@ -57,29 +60,30 @@ public Response getAllUsers(
List<UserEntity> users;
if (searchQuery == null || searchQuery.isBlank()) {
users = userRepository.filterByCreationTimeOrByDisplayName(
startDateTime, endDateTime, "", pageIndex, pageSize);
startDateTime, endDateTime, "", pageIndex - 1, pageSize);
} else {
users = userRepository.filterByCreationTimeOrByDisplayName(
startDateTime, endDateTime, searchQuery, pageIndex, pageSize);
startDateTime, endDateTime, searchQuery, pageIndex - 1, pageSize);
}

List<UserDto> responseUsers = new ArrayList<>();
users.forEach(userEntity -> {
userEntity.setEmailAddress(null);
responseUsers.add(userEntityConverter.toUserDto(userEntity));
});

LOGGER.info("Found {} users between {} and {} that starts with {}",
users.size(), startDateTime, endDateTime, searchQuery);
return responseService.createResponse(Response.Status.OK, users);
responseUsers.size(), startDateTime, endDateTime, searchQuery);
return responseService.createResponse(Response.Status.OK, responseUsers);
}

public Response getUserByDiscordId(String discordId) {
UserEntity foundUser = userRepository.findByDiscordId(discordId);
if (foundUser == null) {
return responseService.createErrorResponse(Response.Status.NOT_FOUND, ErrorCode.USER_NOT_FOUND);
}

return responseService.createResponse(Response.Status.OK, new UserDto(
foundUser.getDiscordId(),
foundUser.getDisplayName(),
foundUser.getEmailAddress(),
foundUser.getCreationTime()
));
foundUser.setEmailAddress(null);
return responseService.createResponse(Response.Status.OK, userEntityConverter.toUserDto(foundUser));
}

public Response getAllUserReactions(String discordId) {
Expand Down

0 comments on commit 4ca4f25

Please sign in to comment.