Remove user-related interfaces and replace with entities. Also some casting clean up.

This commit is contained in:
Jesse Brault 2026-01-14 16:59:01 -06:00
parent 7230c7887d
commit 3e08436abd
23 changed files with 158 additions and 279 deletions

View File

@ -1,7 +1,7 @@
package app.mealsmadeeasy.api.recipe;
import app.mealsmadeeasy.api.IntegrationTestsExtension;
import app.mealsmadeeasy.api.user.UserEntity;
import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -26,9 +26,9 @@ public class RecipeRepositoryTests {
@Autowired
private UserRepository userRepository;
private UserEntity seedUser() {
private User seedUser() {
final String uuid = UUID.randomUUID().toString();
final UserEntity draft = UserEntity.getDefaultDraft();
final User draft = User.getDefaultDraft();
draft.setUsername(uuid);
draft.setEmail(uuid + "@test.com");
draft.setPassword("test");
@ -74,8 +74,8 @@ public class RecipeRepositoryTests {
recipe.setRawText("Hello, World!");
final Recipe saved = this.recipeRepository.save(recipe);
final UserEntity viewer = this.seedUser();
final Set<UserEntity> viewers = new HashSet<>(recipe.getViewers());
final User viewer = this.seedUser();
final Set<User> viewers = new HashSet<>(recipe.getViewers());
viewers.add(viewer);
saved.setViewers(viewers);
@ -95,7 +95,7 @@ public class RecipeRepositoryTests {
recipe.setRawText("Hello, World!");
this.recipeRepository.save(recipe);
final UserEntity viewer = this.seedUser();
final User viewer = this.seedUser();
final List<Recipe> viewable = this.recipeRepository.findAllByViewersContaining(viewer);
assertThat(viewable.size()).isEqualTo(0);
}

View File

@ -8,7 +8,6 @@ import app.mealsmadeeasy.api.recipe.star.RecipeStar;
import app.mealsmadeeasy.api.recipe.star.RecipeStarService;
import app.mealsmadeeasy.api.recipe.view.RecipeInfoView;
import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserEntity;
import app.mealsmadeeasy.api.user.UserRepository;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Test;
@ -45,9 +44,9 @@ public class RecipeServiceTests {
@Autowired
private UserRepository userRepository;
private UserEntity seedUser() {
private User seedUser() {
final String uuid = UUID.randomUUID().toString();
final UserEntity draft = UserEntity.getDefaultDraft();
final User draft = User.getDefaultDraft();
draft.setUsername(uuid);
draft.setEmail(uuid + "@test.com");
draft.setPassword("test");

View File

@ -3,7 +3,7 @@ package app.mealsmadeeasy.api.recipe.star;
import app.mealsmadeeasy.api.IntegrationTestsExtension;
import app.mealsmadeeasy.api.recipe.Recipe;
import app.mealsmadeeasy.api.recipe.RecipeRepository;
import app.mealsmadeeasy.api.user.UserEntity;
import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ -29,8 +29,8 @@ public class RecipeStarRepositoryTests {
@Autowired
private UserRepository userRepository;
private UserEntity seedUser() {
final UserEntity draft = UserEntity.getDefaultDraft();
private User seedUser() {
final User draft = User.getDefaultDraft();
final String uuid = UUID.randomUUID().toString();
draft.setUsername(uuid);
draft.setEmail(uuid + "@test.com");
@ -38,7 +38,7 @@ public class RecipeStarRepositoryTests {
return this.userRepository.save(draft);
}
private Recipe getTestRecipe(UserEntity owner) {
private Recipe getTestRecipe(User owner) {
final Recipe recipeDraft = new Recipe();
recipeDraft.setCreated(OffsetDateTime.now());
recipeDraft.setSlug(UUID.randomUUID().toString());
@ -50,7 +50,7 @@ public class RecipeStarRepositoryTests {
@Test
public void returnsTrueIfStarer() {
final UserEntity owner = this.seedUser();
final User owner = this.seedUser();
final Recipe recipe = this.getTestRecipe(owner);
final RecipeStar starDraft = new RecipeStar();
@ -72,7 +72,7 @@ public class RecipeStarRepositoryTests {
@Test
public void returnsFalseIfNotStarer() {
final UserEntity owner = this.seedUser();
final User owner = this.seedUser();
final Recipe recipe = this.getTestRecipe(owner);
assertThat(
this.recipeStarRepository.isStarer(

View File

@ -1,7 +1,7 @@
package app.mealsmadeeasy.api.auth;
import app.mealsmadeeasy.api.jwt.JwtService;
import app.mealsmadeeasy.api.user.UserEntity;
import app.mealsmadeeasy.api.user.User;
import jakarta.transaction.Transactional;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Value;
@ -36,7 +36,7 @@ public class AuthServiceImpl implements AuthService {
this.refreshTokenLifetime = refreshTokenLifetime;
}
private RefreshToken createRefreshToken(UserEntity principal) {
private RefreshToken createRefreshToken(User principal) {
final RefreshTokenEntity refreshTokenDraft = new RefreshTokenEntity();
refreshTokenDraft.setToken(UUID.randomUUID());
refreshTokenDraft.setIssued(OffsetDateTime.now());
@ -51,7 +51,7 @@ public class AuthServiceImpl implements AuthService {
final Authentication authentication = this.authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(username, password)
);
final UserEntity principal = (UserEntity) authentication.getPrincipal();
final User principal = (User) authentication.getPrincipal();
return new LoginDetails(
username,
this.jwtService.generateAccessToken(username),
@ -87,7 +87,7 @@ public class AuthServiceImpl implements AuthService {
throw new LoginException(LoginExceptionReason.EXPIRED_REFRESH_TOKEN, "Refresh token is expired.");
}
final UserEntity principal = old.getOwner();
final User principal = old.getOwner();
old.setDeleted(true);
this.refreshTokenRepository.save(old);

View File

@ -1,6 +1,6 @@
package app.mealsmadeeasy.api.auth;
import app.mealsmadeeasy.api.user.UserEntity;
import app.mealsmadeeasy.api.user.User;
import jakarta.persistence.*;
import java.time.OffsetDateTime;
@ -23,7 +23,7 @@ public class RefreshTokenEntity implements RefreshToken {
@ManyToOne(optional = false)
@JoinColumn(name = "owner_id", nullable = false)
private UserEntity owner;
private User owner;
@Column(nullable = false)
private Boolean deleted = false;
@ -67,11 +67,11 @@ public class RefreshTokenEntity implements RefreshToken {
this.revoked = revoked;
}
public UserEntity getOwner() {
public User getOwner() {
return this.owner;
}
public void setOwner(UserEntity owner) {
public void setOwner(User owner) {
this.owner = owner;
}

View File

@ -1,7 +1,6 @@
package app.mealsmadeeasy.api.image;
import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserEntity;
import jakarta.persistence.*;
import org.jetbrains.annotations.Nullable;
@ -42,7 +41,7 @@ public class S3ImageEntity implements Image {
@ManyToOne(optional = false)
@JoinColumn(name = "owner_id", nullable = false)
private UserEntity owner;
private User owner;
@Column(nullable = false)
private Boolean isPublic = false;
@ -53,7 +52,7 @@ public class S3ImageEntity implements Image {
joinColumns = @JoinColumn(name = "image_id"),
inverseJoinColumns = @JoinColumn(name = "viewer_id")
)
private Set<UserEntity> viewers = new HashSet<>();
private Set<User> viewers = new HashSet<>();
@Override
public Integer getId() {
@ -149,7 +148,7 @@ public class S3ImageEntity implements Image {
return this.owner;
}
public void setOwner(UserEntity owner) {
public void setOwner(User owner) {
this.owner = owner;
}
@ -167,11 +166,11 @@ public class S3ImageEntity implements Image {
return Set.copyOf(this.viewers);
}
public Set<UserEntity> getViewerEntities() {
public Set<User> getViewerEntities() {
return this.viewers;
}
public void setViewers(Set<UserEntity> viewers) {
public void setViewers(Set<User> viewers) {
this.viewers = viewers;
}

View File

@ -1,6 +1,6 @@
package app.mealsmadeeasy.api.image;
import app.mealsmadeeasy.api.user.UserEntity;
import app.mealsmadeeasy.api.user.User;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
@ -14,8 +14,8 @@ public interface S3ImageRepository extends JpaRepository<S3ImageEntity, Long> {
@EntityGraph(attributePaths = { "viewers" })
S3ImageEntity getByIdWithViewers(long id);
List<S3ImageEntity> findAllByOwner(UserEntity owner);
Optional<S3ImageEntity> findByOwnerAndUserFilename(UserEntity owner, String filename);
List<S3ImageEntity> findAllByOwner(User owner);
Optional<S3ImageEntity> findByOwnerAndUserFilename(User owner, String filename);
@Query("SELECT image from Image image WHERE image.owner.username = ?1 AND image.userFilename = ?2")
Optional<S3ImageEntity> findByOwnerUsernameAndFilename(String username, String filename);

View File

@ -5,7 +5,6 @@ import app.mealsmadeeasy.api.image.spec.ImageUpdateInfoSpec;
import app.mealsmadeeasy.api.image.view.ImageView;
import app.mealsmadeeasy.api.s3.S3Manager;
import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserEntity;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PostAuthorize;
@ -95,9 +94,9 @@ public class S3ImageService implements ImageService {
}
final @Nullable Set<User> viewersToAdd = spec.getViewersToAdd();
if (viewersToAdd != null) {
final Set<UserEntity> viewers = new HashSet<>(entity.getViewerEntities());
final Set<User> viewers = new HashSet<>(entity.getViewerEntities());
for (final User viewerToAdd : spec.getViewersToAdd()) {
viewers.add((UserEntity) viewerToAdd);
viewers.add((User) viewerToAdd);
}
entity.setViewers(viewers);
didTransfer = true;
@ -154,7 +153,7 @@ public class S3ImageService implements ImageService {
inputStream.close();
final S3ImageEntity draft = new S3ImageEntity();
draft.setOwner((UserEntity) owner);
draft.setOwner((User) owner);
draft.setUserFilename(userFilename);
draft.setMimeType(mimeType);
draft.setObjectName(objectName);
@ -175,7 +174,7 @@ public class S3ImageService implements ImageService {
@Override
@PostAuthorize("@imageSecurity.isViewableBy(returnObject, #viewer)")
public Image getByOwnerAndFilename(User owner, String filename, User viewer) throws ImageException {
return this.imageRepository.findByOwnerAndUserFilename((UserEntity) owner, filename)
return this.imageRepository.findByOwnerAndUserFilename((User) owner, filename)
.orElseThrow(() -> new ImageException(
ImageException.Type.IMAGE_NOT_FOUND,
"No such image for owner " + owner + " with filename " + filename
@ -201,7 +200,7 @@ public class S3ImageService implements ImageService {
@Override
public List<Image> getImagesOwnedBy(User user) {
return new ArrayList<>(this.imageRepository.findAllByOwner((UserEntity) user));
return new ArrayList<>(this.imageRepository.findAllByOwner((User) user));
}
@Override
@ -216,9 +215,9 @@ public class S3ImageService implements ImageService {
} else {
final @Nullable Set<User> viewersToRemove = updateSpec.getViewersToRemove();
if (viewersToRemove != null) {
final Set<UserEntity> currentViewers = new HashSet<>(entity.getViewerEntities());
final Set<User> currentViewers = new HashSet<>(entity.getViewerEntities());
for (final User toRemove : updateSpec.getViewersToRemove()) {
currentViewers.remove((UserEntity) toRemove);
currentViewers.remove((User) toRemove);
}
entity.setViewers(currentViewers);
didUpdate = true;

View File

@ -3,7 +3,7 @@ package app.mealsmadeeasy.api.recipe;
import app.mealsmadeeasy.api.image.S3ImageEntity;
import app.mealsmadeeasy.api.recipe.comment.RecipeComment;
import app.mealsmadeeasy.api.recipe.star.RecipeStar;
import app.mealsmadeeasy.api.user.UserEntity;
import app.mealsmadeeasy.api.user.User;
import jakarta.persistence.*;
import lombok.Data;
import org.jetbrains.annotations.Nullable;
@ -53,7 +53,7 @@ public final class Recipe {
@ManyToOne(optional = false)
@JoinColumn(name = "owner_id", nullable = false)
private UserEntity owner;
private User owner;
@OneToMany
@JoinColumn(name = "recipe_id")
@ -71,7 +71,7 @@ public final class Recipe {
joinColumns = @JoinColumn(name = "recipe_id"),
inverseJoinColumns = @JoinColumn(name = "viewer_id")
)
private Set<UserEntity> viewers = new HashSet<>();
private Set<User> viewers = new HashSet<>();
@ManyToOne
@JoinColumn(name = "main_image_id")

View File

@ -1,6 +1,6 @@
package app.mealsmadeeasy.api.recipe;
import app.mealsmadeeasy.api.user.UserEntity;
import app.mealsmadeeasy.api.user.User;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.EntityGraph;
@ -14,15 +14,15 @@ public interface RecipeRepository extends JpaRepository<Recipe, Long> {
List<Recipe> findAllByIsPublicIsTrue();
List<Recipe> findAllByViewersContaining(UserEntity viewer);
List<Recipe> findAllByViewersContaining(User viewer);
List<Recipe> findAllByOwner(UserEntity owner);
List<Recipe> findAllByOwner(User owner);
@Query("SELECT r from Recipe r WHERE r.owner.username = ?1 AND r.slug = ?2")
Optional<Recipe> findByOwnerUsernameAndSlug(String ownerUsername, String slug);
@Query("SELECT r FROM Recipe r WHERE size(r.stars) >= ?1 AND (r.isPublic OR ?2 MEMBER OF r.viewers)")
List<Recipe> findAllViewableByStarsGreaterThanEqual(long stars, UserEntity viewer);
List<Recipe> findAllViewableByStarsGreaterThanEqual(long stars, User viewer);
@Query("SELECT r FROM Recipe r WHERE r.id = ?1")
@EntityGraph(attributePaths = { "viewers" })
@ -39,7 +39,7 @@ public interface RecipeRepository extends JpaRepository<Recipe, Long> {
int getViewerCount(long recipeId);
@Query("SELECT r FROM Recipe r WHERE r.isPublic OR r.owner = ?1 OR ?1 MEMBER OF r.viewers")
Slice<Recipe> findAllViewableBy(UserEntity viewer, Pageable pageable);
Slice<Recipe> findAllViewableBy(User viewer, Pageable pageable);
List<Recipe> findAllByEmbeddingIsNull();

View File

@ -13,7 +13,6 @@ import app.mealsmadeeasy.api.recipe.star.RecipeStarRepository;
import app.mealsmadeeasy.api.recipe.view.FullRecipeView;
import app.mealsmadeeasy.api.recipe.view.RecipeInfoView;
import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserEntity;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
@ -60,7 +59,7 @@ public class RecipeServiceImpl implements RecipeService {
}
final Recipe draft = new Recipe();
draft.setCreated(OffsetDateTime.now());
draft.setOwner((UserEntity) owner);
draft.setOwner((User) owner);
draft.setSlug(spec.getSlug());
draft.setTitle(spec.getTitle());
draft.setRawText(spec.getRawText());
@ -172,7 +171,7 @@ public class RecipeServiceImpl implements RecipeService {
@Override
public Slice<RecipeInfoView> getInfoViewsViewableBy(Pageable pageable, @Nullable User viewer) {
return this.recipeRepository.findAllViewableBy((UserEntity) viewer, pageable).map(recipe ->
return this.recipeRepository.findAllViewableBy((User) viewer, pageable).map(recipe ->
this.getInfoView(recipe, viewer)
);
}
@ -180,7 +179,7 @@ public class RecipeServiceImpl implements RecipeService {
@Override
public List<Recipe> getByMinimumStars(long minimumStars, User viewer) {
return List.copyOf(
this.recipeRepository.findAllViewableByStarsGreaterThanEqual(minimumStars, (UserEntity) viewer)
this.recipeRepository.findAllViewableByStarsGreaterThanEqual(minimumStars, (User) viewer)
);
}
@ -191,12 +190,12 @@ public class RecipeServiceImpl implements RecipeService {
@Override
public List<Recipe> getRecipesViewableBy(User viewer) {
return List.copyOf(this.recipeRepository.findAllByViewersContaining((UserEntity) viewer));
return List.copyOf(this.recipeRepository.findAllByViewersContaining((User) viewer));
}
@Override
public List<Recipe> getRecipesOwnedBy(User owner) {
return List.copyOf(this.recipeRepository.findAllByOwner((UserEntity) owner));
return List.copyOf(this.recipeRepository.findAllByOwner((User) owner));
}
@Override
@ -254,8 +253,8 @@ public class RecipeServiceImpl implements RecipeService {
final Recipe entity = this.recipeRepository.findByIdWithViewers(id).orElseThrow(() -> new RecipeException(
RecipeException.Type.INVALID_ID, "No such Recipe with id: " + id
));
final Set<UserEntity> viewers = new HashSet<>(entity.getViewers());
viewers.add((UserEntity) viewer);
final Set<User> viewers = new HashSet<>(entity.getViewers());
viewers.add((User) viewer);
entity.setViewers(viewers);
return this.recipeRepository.save(entity);
}
@ -264,8 +263,8 @@ public class RecipeServiceImpl implements RecipeService {
@PreAuthorize("@recipeSecurity.isOwner(#id, #modifier)")
public Recipe removeViewer(long id, User modifier, User viewer) throws RecipeException {
final Recipe entity = this.findRecipeEntity(id);
final Set<UserEntity> viewers = new HashSet<>(entity.getViewers());
viewers.remove((UserEntity) viewer);
final Set<User> viewers = new HashSet<>(entity.getViewers());
viewers.remove((User) viewer);
entity.setViewers(viewers);
return this.recipeRepository.save(entity);
}

View File

@ -1,7 +1,7 @@
package app.mealsmadeeasy.api.recipe.comment;
import app.mealsmadeeasy.api.recipe.Recipe;
import app.mealsmadeeasy.api.user.UserEntity;
import app.mealsmadeeasy.api.user.User;
import jakarta.persistence.*;
import lombok.Data;
@ -31,7 +31,7 @@ public final class RecipeComment {
@ManyToOne
@JoinColumn(name = "owner_id", nullable = false, updatable = false)
private UserEntity owner;
private User owner;
@ManyToOne
@JoinColumn(name = "recipe_id", nullable = false, updatable = false)

View File

@ -5,7 +5,6 @@ import app.mealsmadeeasy.api.recipe.Recipe;
import app.mealsmadeeasy.api.recipe.RecipeException;
import app.mealsmadeeasy.api.recipe.RecipeRepository;
import app.mealsmadeeasy.api.user.User;
import app.mealsmadeeasy.api.user.UserEntity;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.security.access.prepost.PostAuthorize;
@ -46,7 +45,7 @@ public class RecipeCommentServiceImpl implements RecipeCommentService {
draft.setCreated(OffsetDateTime.now());
draft.setRawText(body.getText());
draft.setCachedRenderedText(this.markdownService.renderAndCleanMarkdown(body.getText()));
draft.setOwner((UserEntity) commenter);
draft.setOwner((User) commenter);
final Recipe recipe = this.recipeRepository.findByOwnerUsernameAndSlug(recipeUsername, recipeSlug)
.orElseThrow(() -> new RecipeException(
RecipeException.Type.INVALID_USERNAME_OR_SLUG,

View File

@ -1,10 +1,13 @@
package app.mealsmadeeasy.api.user;
import jakarta.persistence.*;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
@Entity(name = "UserGrantedAuthority")
@Table(name = "user_granted_authority")
public final class UserGrantedAuthorityEntity implements UserGrantedAuthority {
@Data
public final class GrantedAuthorityEntity implements GrantedAuthority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ -15,11 +18,6 @@ public final class UserGrantedAuthorityEntity implements UserGrantedAuthority {
@ManyToOne
@JoinColumn(name = "user_id")
private UserEntity userEntity;
@Override
public String getAuthority() {
return this.authority;
}
private User user;
}

View File

@ -0,0 +1,5 @@
package app.mealsmadeeasy.api.user;
import org.springframework.data.jpa.repository.JpaRepository;
public interface GrantedAuthorityEntityRepository extends JpaRepository<GrantedAuthorityEntity, Long> {}

View File

@ -1,18 +1,92 @@
package app.mealsmadeeasy.api.user;
import jakarta.persistence.*;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public interface User extends UserDetails {
@Entity(name = "User")
@Table(name = "\"user\"")
@Data
public final class User implements UserDetails {
Integer getId();
public static User getDefaultDraft() {
final var user = new User();
user.setEnabled(true);
user.setExpired(false);
user.setLocked(false);
user.setCredentialsExpired(false);
return user;
}
String getEmail();
void setEmail(String email);
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false)
private Integer id;
void addAuthority(UserGrantedAuthority userGrantedAuthority);
void addAuthorities(Set<? extends UserGrantedAuthority> userGrantedAuthorities);
void removeAuthority(UserGrantedAuthority userGrantedAuthority);
@Column(unique = true, nullable = false)
private String username;
@Column(unique = true, nullable = false)
private String email;
@Column(nullable = false)
private String password;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "user")
private final Set<GrantedAuthorityEntity> authorities = new HashSet<>();
@Column(nullable = false)
private Boolean enabled;
@Column(nullable = false)
private Boolean expired;
@Column(nullable = false)
private Boolean locked;
@Column(nullable = false)
private Boolean credentialsExpired;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
public void addAuthority(GrantedAuthorityEntity userGrantedAuthority) {
this.authorities.add(userGrantedAuthority);
}
public void addAuthorities(Set<? extends GrantedAuthorityEntity> userGrantedAuthorities) {
userGrantedAuthorities.forEach(this::addAuthority);
}
public void removeAuthority(GrantedAuthorityEntity userGrantedAuthority) {
this.authorities.remove(userGrantedAuthority);
}
@Override
public boolean isAccountNonExpired() {
return !this.expired;
}
@Override
public boolean isAccountNonLocked() {
return !this.locked;
}
@Override
public boolean isCredentialsNonExpired() {
return !this.credentialsExpired;
}
@Override
public boolean isEnabled() {
return this.enabled;
}
}

View File

@ -1,183 +0,0 @@
package app.mealsmadeeasy.api.user;
import jakarta.persistence.*;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@Entity(name = "User")
@Table(name = "\"user\"")
public final class UserEntity implements User {
public static UserEntity getDefaultDraft() {
final var user = new UserEntity();
user.setEnabled(true);
user.setExpired(false);
user.setLocked(false);
user.setCredentialsExpired(false);
return user;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(nullable = false)
private Integer id;
@Column(unique = true, nullable = false)
private String username;
@Column(unique = true, nullable = false)
private String email;
@Column(nullable = false)
private String password;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "userEntity")
private final Set<UserGrantedAuthorityEntity> authorities = new HashSet<>();
@Column(nullable = false)
private Boolean enabled;
@Column(nullable = false)
private Boolean expired;
@Column(nullable = false)
private Boolean locked;
@Column(nullable = false)
private Boolean credentialsExpired;
@Override
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String getEmail() {
return this.email;
}
@Override
public void setEmail(String email) {
this.email = email;
}
@Override
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public void addAuthority(UserGrantedAuthority userGrantedAuthority) {
this.authorities.add((UserGrantedAuthorityEntity) userGrantedAuthority);
}
@Override
public void addAuthorities(Set<? extends UserGrantedAuthority> userGrantedAuthorities) {
userGrantedAuthorities.forEach(this::addAuthority);
}
@Override
public void removeAuthority(UserGrantedAuthority userGrantedAuthority) {
this.authorities.remove((UserGrantedAuthorityEntity) userGrantedAuthority);
}
@Override
public boolean isAccountNonExpired() {
return !this.expired;
}
public void setExpired(Boolean expired) {
this.expired = expired;
}
@Override
public boolean isAccountNonLocked() {
return !this.locked;
}
public void setLocked(Boolean locked) {
this.locked = locked;
}
@Override
public boolean isCredentialsNonExpired() {
return !this.credentialsExpired;
}
public void setCredentialsExpired(Boolean credentialsExpired) {
this.credentialsExpired = credentialsExpired;
}
@Override
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
@Override
public int hashCode() {
return Objects.hash(
this.id,
this.username,
this.email,
this.password,
this.authorities,
this.enabled,
this.expired,
this.locked,
this.credentialsExpired
);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof User o) {
return Objects.equals(this.id, o.getId())
&& Objects.equals(this.username, o.getUsername())
&& Objects.equals(this.password, o.getPassword())
&& Objects.equals(this.authorities, o.getAuthorities())
&& Objects.equals(this.enabled, o.isEnabled())
&& Objects.equals(this.expired, !o.isAccountNonExpired())
&& Objects.equals(this.locked, !o.isAccountNonLocked())
&& Objects.equals(this.credentialsExpired, !o.isCredentialsNonExpired());
} else {
return false;
}
}
@Override
public String toString() {
return "UserEntity(" + this.id + ", " + this.username + ", " + this.email + ")";
}
}

View File

@ -1,5 +0,0 @@
package app.mealsmadeeasy.api.user;
import org.springframework.security.core.GrantedAuthority;
public interface UserGrantedAuthority extends GrantedAuthority {}

View File

@ -1,5 +0,0 @@
package app.mealsmadeeasy.api.user;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserGrantedAuthorityRepository extends JpaRepository<UserGrantedAuthorityEntity, Long> {}

View File

@ -4,9 +4,9 @@ import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UserRepository extends JpaRepository<UserEntity, Long> {
Optional<UserEntity> findByUsername(String username);
UserEntity getByUsername(String username);
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
User getByUsername(String username);
boolean existsByUsername(String username);
boolean existsByEmail(String email);
void deleteByUsername(String username);

View File

@ -4,7 +4,7 @@ import java.util.Set;
public interface UserService {
User createUser(String username, String email, String rawPassword, Set<UserGrantedAuthority> authorities)
User createUser(String username, String email, String rawPassword, Set<GrantedAuthorityEntity> authorities)
throws UserCreateException;
default User createUser(String username, String email, String rawPassword) throws UserCreateException {

View File

@ -21,7 +21,7 @@ public final class UserServiceImpl implements UserService {
String username,
String email,
String rawPassword,
Set<UserGrantedAuthority> authorities
Set<GrantedAuthorityEntity> authorities
) throws UserCreateException {
if (this.userRepository.existsByUsername(username)) {
throw new UserCreateException(
@ -32,7 +32,7 @@ public final class UserServiceImpl implements UserService {
if (this.userRepository.existsByEmail(email)) {
throw new UserCreateException(UserCreateException.Type.EMAIL_TAKEN, "Email " + email + " is taken.");
}
final UserEntity draft = UserEntity.getDefaultDraft();
final User draft = User.getDefaultDraft();
draft.setUsername(username);
draft.setEmail(email);
draft.setPassword(this.passwordEncoder.encode(rawPassword));
@ -47,12 +47,12 @@ public final class UserServiceImpl implements UserService {
@Override
public User updateUser(User user) {
return this.userRepository.save((UserEntity) user);
return this.userRepository.save((User) user);
}
@Override
public void deleteUser(User user) {
this.userRepository.delete((UserEntity) user);
this.userRepository.delete((User) user);
}
@Override

View File

@ -17,8 +17,8 @@ public class ContainsRecipeStarsMatcher extends ContainsItemsMatcher<RecipeStar,
super(
List.of(allExpected),
o -> o instanceof RecipeStar,
recipeStar -> ((RecipeStar) recipeStar).getId(),
recipeStar -> ((RecipeStar) recipeStar).getId(),
RecipeStar::getId,
RecipeStar::getId,
(id0, id1) -> Objects.equals(id0.getRecipeId(), id1.getRecipeId())
&& Objects.equals(id0.getOwnerId(), id1.getOwnerId())
);