From 5ee7594fcc07eea606185fc2c7663eec35b4b3b6 Mon Sep 17 00:00:00 2001 From: Gescof Date: Wed, 26 Jul 2023 13:01:12 +0200 Subject: [PATCH] refactor to comply with JDK 17 code standards --- .../alibou/security/SecurityApplication.java | 7 +- .../security/auth/AuthenticationService.java | 11 ++-- .../config/JwtAuthenticationFilter.java | 13 ++-- .../alibou/security/config/LogoutService.java | 8 ++- .../config/SecurityConfiguration.java | 17 +---- .../java/com/alibou/security/token/Token.java | 65 ++++++++++++------- .../security/token/TokenRepository.java | 2 +- .../com/alibou/security/user/Permission.java | 2 +- .../java/com/alibou/security/user/Role.java | 2 +- .../java/com/alibou/security/user/User.java | 57 +++++++++++----- 10 files changed, 105 insertions(+), 79 deletions(-) diff --git a/src/main/java/com/alibou/security/SecurityApplication.java b/src/main/java/com/alibou/security/SecurityApplication.java index c782820..d071957 100644 --- a/src/main/java/com/alibou/security/SecurityApplication.java +++ b/src/main/java/com/alibou/security/SecurityApplication.java @@ -2,7 +2,7 @@ import com.alibou.security.auth.AuthenticationService; import com.alibou.security.auth.RegisterRequest; -import com.alibou.security.user.Role; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -11,6 +11,7 @@ import static com.alibou.security.user.Role.ADMIN; import static com.alibou.security.user.Role.MANAGER; +@Slf4j @SpringBootApplication public class SecurityApplication { @@ -30,7 +31,7 @@ public CommandLineRunner commandLineRunner( .password("password") .role(ADMIN) .build(); - System.out.println("Admin token: " + service.register(admin).getAccessToken()); + log.debug("Admin token: " + service.register(admin).getAccessToken()); var manager = RegisterRequest.builder() .firstname("Admin") @@ -39,7 +40,7 @@ public CommandLineRunner commandLineRunner( .password("password") .role(MANAGER) .build(); - System.out.println("Manager token: " + service.register(manager).getAccessToken()); + log.debug("Manager token: " + service.register(manager).getAccessToken()); }; } diff --git a/src/main/java/com/alibou/security/auth/AuthenticationService.java b/src/main/java/com/alibou/security/auth/AuthenticationService.java index 53193a7..9a9fc82 100644 --- a/src/main/java/com/alibou/security/auth/AuthenticationService.java +++ b/src/main/java/com/alibou/security/auth/AuthenticationService.java @@ -4,7 +4,6 @@ import com.alibou.security.token.Token; import com.alibou.security.token.TokenRepository; import com.alibou.security.token.TokenType; -import com.alibou.security.user.Role; import com.alibou.security.user.User; import com.alibou.security.user.UserRepository; import com.fasterxml.jackson.databind.ObjectMapper; @@ -14,13 +13,11 @@ import org.springframework.http.HttpHeaders; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Service; import java.io.IOException; +import java.util.Objects; @Service @RequiredArgsConstructor @@ -71,7 +68,7 @@ public AuthenticationResponse authenticate(AuthenticationRequest request) { private void saveUserToken(User user, String jwtToken) { var token = Token.builder() .user(user) - .token(jwtToken) + .tokenCode(jwtToken) .tokenType(TokenType.BEARER) .expired(false) .revoked(false) @@ -97,12 +94,12 @@ public void refreshToken( final String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION); final String refreshToken; final String userEmail; - if (authHeader == null ||!authHeader.startsWith("Bearer ")) { + if (Objects.isNull(authHeader) ||!authHeader.startsWith("Bearer ")) { return; } refreshToken = authHeader.substring(7); userEmail = jwtService.extractUsername(refreshToken); - if (userEmail != null) { + if (Objects.nonNull(userEmail)) { var user = this.repository.findByEmail(userEmail) .orElseThrow(); if (jwtService.isTokenValid(refreshToken, user)) { diff --git a/src/main/java/com/alibou/security/config/JwtAuthenticationFilter.java b/src/main/java/com/alibou/security/config/JwtAuthenticationFilter.java index d6e55d1..211cb7b 100644 --- a/src/main/java/com/alibou/security/config/JwtAuthenticationFilter.java +++ b/src/main/java/com/alibou/security/config/JwtAuthenticationFilter.java @@ -6,12 +6,9 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; -import java.beans.Transient; import java.io.IOException; -import java.security.Security; +import java.util.Objects; -import jakarta.transaction.TransactionScoped; -import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.lang.NonNull; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -43,18 +40,18 @@ protected void doFilterInternal( final String authHeader = request.getHeader("Authorization"); final String jwt; final String userEmail; - if (authHeader == null ||!authHeader.startsWith("Bearer ")) { + if (Objects.isNull(authHeader) || !authHeader.startsWith("Bearer ")) { filterChain.doFilter(request, response); return; } jwt = authHeader.substring(7); userEmail = jwtService.extractUsername(jwt); - if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) { + if (Objects.nonNull(userEmail) && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) { UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail); - var isTokenValid = tokenRepository.findByToken(jwt) + var isTokenValid = tokenRepository.findByTokenCode(jwt) .map(t -> !t.isExpired() && !t.isRevoked()) .orElse(false); - if (jwtService.isTokenValid(jwt, userDetails) && isTokenValid) { + if (jwtService.isTokenValid(jwt, userDetails) && Boolean.TRUE.equals(isTokenValid)) { UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken( userDetails, null, diff --git a/src/main/java/com/alibou/security/config/LogoutService.java b/src/main/java/com/alibou/security/config/LogoutService.java index 0784565..d97e5f3 100644 --- a/src/main/java/com/alibou/security/config/LogoutService.java +++ b/src/main/java/com/alibou/security/config/LogoutService.java @@ -9,6 +9,8 @@ import org.springframework.security.web.authentication.logout.LogoutHandler; import org.springframework.stereotype.Service; +import java.util.Objects; + @Service @RequiredArgsConstructor public class LogoutService implements LogoutHandler { @@ -23,13 +25,13 @@ public void logout( ) { final String authHeader = request.getHeader("Authorization"); final String jwt; - if (authHeader == null ||!authHeader.startsWith("Bearer ")) { + if (Objects.isNull(authHeader) || !authHeader.startsWith("Bearer ")) { return; } jwt = authHeader.substring(7); - var storedToken = tokenRepository.findByToken(jwt) + var storedToken = tokenRepository.findByTokenCode(jwt) .orElse(null); - if (storedToken != null) { + if (Objects.nonNull(storedToken)) { storedToken.setExpired(true); storedToken.setRevoked(true); tokenRepository.save(storedToken); diff --git a/src/main/java/com/alibou/security/config/SecurityConfiguration.java b/src/main/java/com/alibou/security/config/SecurityConfiguration.java index 9d899a2..b3c300a 100644 --- a/src/main/java/com/alibou/security/config/SecurityConfiguration.java +++ b/src/main/java/com/alibou/security/config/SecurityConfiguration.java @@ -1,12 +1,9 @@ package com.alibou.security.config; -import jakarta.servlet.Filter; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationProvider; -import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -16,20 +13,10 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.logout.LogoutHandler; -import static com.alibou.security.user.Permission.ADMIN_CREATE; -import static com.alibou.security.user.Permission.ADMIN_DELETE; -import static com.alibou.security.user.Permission.ADMIN_READ; -import static com.alibou.security.user.Permission.ADMIN_UPDATE; -import static com.alibou.security.user.Permission.MANAGER_CREATE; -import static com.alibou.security.user.Permission.MANAGER_DELETE; -import static com.alibou.security.user.Permission.MANAGER_READ; -import static com.alibou.security.user.Permission.MANAGER_UPDATE; +import static com.alibou.security.user.Permission.*; import static com.alibou.security.user.Role.ADMIN; import static com.alibou.security.user.Role.MANAGER; -import static org.springframework.http.HttpMethod.DELETE; -import static org.springframework.http.HttpMethod.GET; -import static org.springframework.http.HttpMethod.POST; -import static org.springframework.http.HttpMethod.PUT; +import static org.springframework.http.HttpMethod.*; @Configuration @EnableWebSecurity diff --git a/src/main/java/com/alibou/security/token/Token.java b/src/main/java/com/alibou/security/token/Token.java index 71f3571..8dae953 100644 --- a/src/main/java/com/alibou/security/token/Token.java +++ b/src/main/java/com/alibou/security/token/Token.java @@ -1,42 +1,63 @@ package com.alibou.security.token; import com.alibou.security.user.User; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.FetchType; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; -import jakarta.persistence.ManyToOne; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Data -@Builder -@NoArgsConstructor +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.proxy.HibernateProxy; + +import java.util.Objects; + +@Getter +@Setter +@ToString +@RequiredArgsConstructor @AllArgsConstructor +@Builder @Entity +@Table(name = "token") public class Token { @Id @GeneratedValue - public Integer id; + private Integer id; @Column(unique = true) - public String token; + private String tokenCode; @Enumerated(EnumType.STRING) - public TokenType tokenType = TokenType.BEARER; + private TokenType tokenType = TokenType.BEARER; - public boolean revoked; + private boolean revoked; - public boolean expired; + private boolean expired; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") + @ToString.Exclude public User user; + + @Override + public final boolean equals(Object o) { + if (Objects.isNull(o)) { + return false; + } + if (this == o) { + return true; + } + Class oEffectiveClass = o instanceof HibernateProxy hibernateProxy ? + hibernateProxy.getHibernateLazyInitializer().getPersistentClass() : o.getClass(); + Class thisEffectiveClass = this instanceof HibernateProxy hibernateProxy ? + hibernateProxy.getHibernateLazyInitializer().getPersistentClass() : this.getClass(); + if (thisEffectiveClass != oEffectiveClass) { + return false; + } + Token token = (Token) o; + return Objects.nonNull(getId()) && Objects.equals(getId(), token.getId()); + } + + @Override + public final int hashCode() { + return this instanceof HibernateProxy hibernateProxy ? + hibernateProxy.getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode(); + } } diff --git a/src/main/java/com/alibou/security/token/TokenRepository.java b/src/main/java/com/alibou/security/token/TokenRepository.java index 48235d8..6df1e7a 100644 --- a/src/main/java/com/alibou/security/token/TokenRepository.java +++ b/src/main/java/com/alibou/security/token/TokenRepository.java @@ -14,5 +14,5 @@ public interface TokenRepository extends JpaRepository { """) List findAllValidTokenByUser(Integer id); - Optional findByToken(String token); + Optional findByTokenCode(String token); } diff --git a/src/main/java/com/alibou/security/user/Permission.java b/src/main/java/com/alibou/security/user/Permission.java index 16ae8b4..18edaff 100644 --- a/src/main/java/com/alibou/security/user/Permission.java +++ b/src/main/java/com/alibou/security/user/Permission.java @@ -18,5 +18,5 @@ public enum Permission { ; @Getter - private final String permission; + private final String permissionStr; } diff --git a/src/main/java/com/alibou/security/user/Role.java b/src/main/java/com/alibou/security/user/Role.java index 0ff9bd1..4e85c29 100644 --- a/src/main/java/com/alibou/security/user/Role.java +++ b/src/main/java/com/alibou/security/user/Role.java @@ -51,7 +51,7 @@ public enum Role { public List getAuthorities() { var authorities = getPermissions() .stream() - .map(permission -> new SimpleGrantedAuthority(permission.getPermission())) + .map(permission -> new SimpleGrantedAuthority(permission.getPermissionStr())) .collect(Collectors.toList()); authorities.add(new SimpleGrantedAuthority("ROLE_" + this.name())); return authorities; diff --git a/src/main/java/com/alibou/security/user/User.java b/src/main/java/com/alibou/security/user/User.java index bc4e086..0300963 100644 --- a/src/main/java/com/alibou/security/user/User.java +++ b/src/main/java/com/alibou/security/user/User.java @@ -1,27 +1,22 @@ package com.alibou.security.user; import com.alibou.security.token.Token; -import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.Id; -import jakarta.persistence.OneToMany; -import jakarta.persistence.Table; -import java.util.Collection; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; +import jakarta.persistence.*; +import lombok.*; +import org.hibernate.proxy.HibernateProxy; import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; -@Data -@Builder -@NoArgsConstructor +import java.util.Collection; +import java.util.List; +import java.util.Objects; + +@Getter +@Setter +@ToString +@RequiredArgsConstructor @AllArgsConstructor +@Builder @Entity @Table(name = "_user") public class User implements UserDetails { @@ -38,7 +33,8 @@ public class User implements UserDetails { private Role role; @OneToMany(mappedBy = "user") - private List tokens; + @ToString.Exclude + private transient List tokens; @Override public Collection getAuthorities() { @@ -74,4 +70,29 @@ public boolean isCredentialsNonExpired() { public boolean isEnabled() { return true; } + + @Override + public final boolean equals(Object o) { + if (Objects.isNull(o)) { + return false; + } + if (this == o) { + return true; + } + Class oEffectiveClass = o instanceof HibernateProxy hibernateProxy ? + hibernateProxy.getHibernateLazyInitializer().getPersistentClass() : o.getClass(); + Class thisEffectiveClass = this instanceof HibernateProxy hibernateProxy ? + hibernateProxy.getHibernateLazyInitializer().getPersistentClass() : this.getClass(); + if (thisEffectiveClass != oEffectiveClass) { + return false; + } + User user = (User) o; + return Objects.nonNull(getId()) && Objects.equals(getId(), user.getId()); + } + + @Override + public final int hashCode() { + return this instanceof HibernateProxy hibernateProxy ? + hibernateProxy.getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode(); + } }