Merge pull request #38 from HideyoshiNakazone/implements-health-check-api

Implements Health Checker API and Formats Code
This commit is contained in:
2024-02-16 01:12:46 -03:00
committed by GitHub
42 changed files with 155 additions and 152 deletions

View File

@@ -9,13 +9,13 @@ import org.springframework.security.crypto.password.PasswordEncoder;
@SpringBootApplication @SpringBootApplication
public class BackendPortfolioApplication { public class BackendPortfolioApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(BackendPortfolioApplication.class, args); SpringApplication.run(BackendPortfolioApplication.class, args);
} }
@Bean @Bean
PasswordEncoder passwordEncoder() { PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); return new BCryptPasswordEncoder();
} }
} }

View File

@@ -1,6 +1,5 @@
package com.hideyoshi.backendportfolio.base.config; package com.hideyoshi.backendportfolio.base.config;
import antlr.actions.python.CodeLexer;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;

View File

@@ -31,13 +31,13 @@ public class DefaultUserConfig {
CommandLineRunner run(UserService userService, UserRepository userRepo) { CommandLineRunner run(UserService userService, UserRepository userRepo) {
return args -> { return args -> {
UserDTO defaultUser = UserDTO.builder() UserDTO defaultUser = UserDTO.builder()
.name(ADMIN_NAME) .name(ADMIN_NAME)
.email(ADMIN_EMAIL) .email(ADMIN_EMAIL)
.username(ADMIN_USERNAME) .username(ADMIN_USERNAME)
.password(ADMIN_PASSWORD) .password(ADMIN_PASSWORD)
.provider(Provider.LOCAL) .provider(Provider.LOCAL)
.roles(new ArrayList<>()) .roles(new ArrayList<>())
.build(); .build();
if (!userRepo.findByUsername(defaultUser.getUsername()).isPresent()) { if (!userRepo.findByUsername(defaultUser.getUsername()).isPresent()) {
defaultUser = userService.saveUser(defaultUser); defaultUser = userService.saveUser(defaultUser);

View File

@@ -1,7 +1,6 @@
package com.hideyoshi.backendportfolio.base.config; package com.hideyoshi.backendportfolio.base.config;
import com.hideyoshi.backendportfolio.util.exception.AuthenticationInvalidException; import com.hideyoshi.backendportfolio.util.exception.AuthenticationInvalidException;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
@@ -15,7 +14,7 @@ import javax.servlet.http.HttpServletResponse;
@Log4j2 @Log4j2
@Component("restAuthenticationEntryPoint") @Component("restAuthenticationEntryPoint")
public class RestAuthenticationEntryPointConfig implements AuthenticationEntryPoint{ public class RestAuthenticationEntryPointConfig implements AuthenticationEntryPoint {
@Autowired @Autowired
@Qualifier("handlerExceptionResolver") @Qualifier("handlerExceptionResolver")

View File

@@ -8,10 +8,8 @@ import com.hideyoshi.backendportfolio.base.security.service.AuthService;
import com.hideyoshi.backendportfolio.util.exception.AuthenticationInvalidException; import com.hideyoshi.backendportfolio.util.exception.AuthenticationInvalidException;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -24,7 +22,6 @@ import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.ForwardedHeaderFilter;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@@ -69,31 +66,31 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
customAuthenticationFilter.setFilterProcessesUrl("/user/login"); customAuthenticationFilter.setFilterProcessesUrl("/user/login");
http.authorizeRequests() http.authorizeRequests()
.antMatchers("/session/**").permitAll() .antMatchers("/session/**").permitAll()
.and().authorizeRequests().antMatchers("/user/signup").permitAll() .and().authorizeRequests().antMatchers("/user/signup").permitAll()
.and().authorizeRequests().antMatchers("/user/oauth/**").permitAll() .and().authorizeRequests().antMatchers("/user/oauth/**").permitAll()
.and().authorizeRequests().antMatchers("/user/login/**").permitAll() .and().authorizeRequests().antMatchers("/user/login/**").permitAll()
.and().authorizeRequests().antMatchers("/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN") .and().authorizeRequests().antMatchers("/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN")
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED) .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.and().addFilter(customAuthenticationFilter) .and().addFilter(customAuthenticationFilter)
.addFilterBefore(new CustomAuthorizationFilter(this.authService), UsernamePasswordAuthenticationFilter.class); .addFilterBefore(new CustomAuthorizationFilter(this.authService), UsernamePasswordAuthenticationFilter.class);
} }
private void addOAuthSecurityToHttp(HttpSecurity http) throws Exception { private void addOAuthSecurityToHttp(HttpSecurity http) throws Exception {
http.oauth2Login() http.oauth2Login()
.authorizationEndpoint() .authorizationEndpoint()
.authorizationRequestRepository(this.oAuthRequestRepository) .authorizationRequestRepository(this.oAuthRequestRepository)
.and().successHandler(this::successHandler) .and().successHandler(this::successHandler)
.failureHandler(this::failureHandler); .failureHandler(this::failureHandler);
} }
private void successHandler(HttpServletRequest request, private void successHandler(HttpServletRequest request,
HttpServletResponse response, HttpServletResponse response,
Authentication authentication ) throws IOException { Authentication authentication) throws IOException {
OAuth2User oauthUser = (OAuth2User) authentication.getPrincipal(); OAuth2User oauthUser = (OAuth2User) authentication.getPrincipal();

View File

@@ -1,13 +1,9 @@
package com.hideyoshi.backendportfolio.base.security.filter; package com.hideyoshi.backendportfolio.base.security.filter;
import com.auth0.jwt.algorithms.Algorithm;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hideyoshi.backendportfolio.base.config.RestAuthenticationEntryPointConfig; import com.hideyoshi.backendportfolio.base.config.RestAuthenticationEntryPointConfig;
import com.hideyoshi.backendportfolio.base.security.service.AuthService; import com.hideyoshi.backendportfolio.base.security.service.AuthService;
import com.hideyoshi.backendportfolio.base.user.model.TokenDTO;
import com.hideyoshi.backendportfolio.base.user.model.UserDTO; import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
@@ -17,11 +13,7 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
@Log4j2 @Log4j2
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter { public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

View File

@@ -19,7 +19,13 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
public class CustomAuthorizationFilter extends OncePerRequestFilter { public class CustomAuthorizationFilter extends OncePerRequestFilter {
public static String AUTHORIZATION_TYPE_STRING = "Bearer "; private static final List<String> notProtectedPaths = Arrays.asList(
"/user/login",
"/user/signup",
"/user/login/refresh"
);
private static final String AUTHORIZATION_TYPE_STRING = "Bearer ";
private final AuthService authService; private final AuthService authService;
@@ -62,11 +68,6 @@ public class CustomAuthorizationFilter extends OncePerRequestFilter {
} }
private Boolean isPathNotProtected(String path) { private Boolean isPathNotProtected(String path) {
List<String> notProtectedPaths = Arrays.asList(
"/user/login"
);
return notProtectedPaths.contains(path); return notProtectedPaths.contains(path);
} }

View File

@@ -7,7 +7,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class ConfigInterceptor implements WebMvcConfigurer { public class ConfigInterceptor implements WebMvcConfigurer {
private final UserResourceAccessInterceptor userResourceAccessInterceptor; private final UserResourceAccessInterceptor userResourceAccessInterceptor;

View File

@@ -29,7 +29,7 @@ public class UserResourceAccessInterceptor implements HandlerInterceptor {
return true; return true;
} }
final UserResourceGuard annotation = ((HandlerMethod)handler) final UserResourceGuard annotation = ((HandlerMethod) handler)
.getMethodAnnotation(UserResourceGuard.class); .getMethodAnnotation(UserResourceGuard.class);
if (Objects.nonNull(annotation)) { if (Objects.nonNull(annotation)) {

View File

@@ -10,7 +10,6 @@ import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;

View File

@@ -2,7 +2,6 @@ package com.hideyoshi.backendportfolio.base.security.oauth.mapper;
import com.hideyoshi.backendportfolio.base.user.entity.Provider; import com.hideyoshi.backendportfolio.base.user.entity.Provider;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User;
@AllArgsConstructor @AllArgsConstructor

View File

@@ -2,7 +2,6 @@ package com.hideyoshi.backendportfolio.base.security.oauth.mapper;
import com.hideyoshi.backendportfolio.base.user.entity.Provider; import com.hideyoshi.backendportfolio.base.user.entity.Provider;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.security.oauth2.core.user.OAuth2User; import org.springframework.security.oauth2.core.user.OAuth2User;
@AllArgsConstructor @AllArgsConstructor

View File

@@ -1,7 +1,6 @@
package com.hideyoshi.backendportfolio.base.security.oauth.mapper; package com.hideyoshi.backendportfolio.base.security.oauth.mapper;
import com.hideyoshi.backendportfolio.base.user.entity.Provider; import com.hideyoshi.backendportfolio.base.user.entity.Provider;
import org.springframework.security.oauth2.core.user.OAuth2User;
public interface OAuthMap { public interface OAuthMap {

View File

@@ -19,10 +19,6 @@ public enum OAuthMapper {
this.provider = provider; this.provider = provider;
} }
public Class getMap() {
return oAuthMap;
}
public static OAuthMapper byValue(String name) { public static OAuthMapper byValue(String name) {
for (OAuthMapper e : values()) { for (OAuthMapper e : values()) {
if (e.getProvider().getName().equals(name)) { if (e.getProvider().getName().equals(name)) {
@@ -32,4 +28,8 @@ public enum OAuthMapper {
throw new IllegalArgumentException("Argument not valid."); throw new IllegalArgumentException("Argument not valid.");
} }
public Class getMap() {
return oAuthMap;
}
} }

View File

@@ -29,8 +29,8 @@ public class OAuthRequestRepository implements AuthorizationRequestRepository<OA
String state = authorizationRequest.getState(); String state = authorizationRequest.getState();
request.getSession().setAttribute( request.getSession().setAttribute(
String.format("state_%s", state), String.format("state_%s", state),
authorizationRequest authorizationRequest
); );
} }

View File

@@ -19,7 +19,7 @@ public interface AuthService {
TokenDTO generateRefreshToken(@Valid UserDTO user, Algorithm algorithm, HttpServletRequest request); TokenDTO generateRefreshToken(@Valid UserDTO user, Algorithm algorithm, HttpServletRequest request);
HashMap<String,TokenDTO> generateTokens(@Valid UserDTO user, Algorithm algorithm, HttpServletRequest request); HashMap<String, TokenDTO> generateTokens(@Valid UserDTO user, Algorithm algorithm, HttpServletRequest request);
UsernamePasswordAuthenticationToken verifyAccessToken(String authorizationHeader); UsernamePasswordAuthenticationToken verifyAccessToken(String authorizationHeader);

View File

@@ -45,21 +45,15 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
public class AuthServiceImpl implements AuthService { public class AuthServiceImpl implements AuthService {
private static final String AUTHORIZATION_TYPE_STRING = "Bearer ";
private final UserService userService;
private final StorageService storageService;
@Value("${com.hideyoshi.tokenSecret}") @Value("${com.hideyoshi.tokenSecret}")
private String TOKEN_SECRET; private String TOKEN_SECRET;
@Value("${com.hideyoshi.accessTokenDuration}") @Value("${com.hideyoshi.accessTokenDuration}")
private Integer ACCESS_TOKEN_DURATION; private Integer ACCESS_TOKEN_DURATION;
@Value("${com.hideyoshi.refreshTokenDuration}") @Value("${com.hideyoshi.refreshTokenDuration}")
private Integer REFRESH_TOKEN_DURATION; private Integer REFRESH_TOKEN_DURATION;
private static final String AUTHORIZATION_TYPE_STRING = "Bearer ";
private final UserService userService;
private final StorageService storageService;
@Autowired @Autowired
@Qualifier("handlerExceptionResolver") @Qualifier("handlerExceptionResolver")
private HandlerExceptionResolver resolver; private HandlerExceptionResolver resolver;

View File

@@ -2,12 +2,14 @@ package com.hideyoshi.backendportfolio.base.session.api;
import com.hideyoshi.backendportfolio.base.security.model.AuthDTO; import com.hideyoshi.backendportfolio.base.security.model.AuthDTO;
import com.hideyoshi.backendportfolio.base.session.service.SessionManagerService; import com.hideyoshi.backendportfolio.base.session.service.SessionManagerService;
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
@@ -24,7 +26,7 @@ public class SessionController {
return ResponseEntity.ok(this.sessionManagerService.validateSession(session)); return ResponseEntity.ok(this.sessionManagerService.validateSession(session));
} }
@DeleteMapping(path="/destroy") @DeleteMapping(path = "/destroy")
public ResponseEntity<Void> destroyCurrentSession(HttpSession session) { public ResponseEntity<Void> destroyCurrentSession(HttpSession session) {
this.sessionManagerService.destroySession(session); this.sessionManagerService.destroySession(session);
return new ResponseEntity<>(HttpStatus.NO_CONTENT); return new ResponseEntity<>(HttpStatus.NO_CONTENT);

View File

@@ -1,7 +1,6 @@
package com.hideyoshi.backendportfolio.base.session.service; package com.hideyoshi.backendportfolio.base.session.service;
import com.hideyoshi.backendportfolio.base.security.model.AuthDTO; import com.hideyoshi.backendportfolio.base.security.model.AuthDTO;
import com.hideyoshi.backendportfolio.base.user.service.UserService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;

View File

@@ -14,10 +14,6 @@ public enum Provider {
this.name = name; this.name = name;
} }
public String getName() {
return name;
}
public static Provider byValue(String name) { public static Provider byValue(String name) {
for (Provider p : values()) { for (Provider p : values()) {
if (p.getName().equals(name)) { if (p.getName().equals(name)) {
@@ -27,4 +23,8 @@ public enum Provider {
throw new IllegalArgumentException("Argument not valid."); throw new IllegalArgumentException("Argument not valid.");
} }
public String getName() {
return name;
}
} }

View File

@@ -13,10 +13,6 @@ public enum Role {
this.description = description; this.description = description;
} }
public String getDescription() {
return this.description;
}
public static Role byValue(String description) { public static Role byValue(String description) {
for (Role r : values()) { for (Role r : values()) {
if (r.getDescription().equals(description)) { if (r.getDescription().equals(description)) {
@@ -26,4 +22,8 @@ public enum Role {
throw new IllegalArgumentException("Argument not valid."); throw new IllegalArgumentException("Argument not valid.");
} }
public String getDescription() {
return this.description;
}
} }

View File

@@ -25,30 +25,30 @@ public class User {
private Long id; private Long id;
@Column( @Column(
name = "name", name = "name",
nullable = false nullable = false
) )
private String name; private String name;
@Column( @Column(
name = "email", name = "email",
unique = true, unique = true,
nullable = false nullable = false
) )
private String email; private String email;
@Column( @Column(
name = "username", name = "username",
unique = true, unique = true,
nullable = false nullable = false
) )
private String username; private String username;
@Column( @Column(
name = "password", name = "password",
nullable = false nullable = false
) )
private String password; private String password;
@@ -59,17 +59,11 @@ public class User {
private String provider; private String provider;
@Column( @Column(
name = "roles", name = "roles",
nullable = false nullable = false
) )
private String roles; private String roles;
public void setRoles(List<Role> roles) {
this.roles = roles.stream()
.map(role -> role.getDescription())
.collect(Collectors.joining("&"));
}
public List<Role> getRoles() { public List<Role> getRoles() {
List<Role> roles = new ArrayList<>(); List<Role> roles = new ArrayList<>();
if (Objects.nonNull(this.roles) && !this.roles.isEmpty()) { if (Objects.nonNull(this.roles) && !this.roles.isEmpty()) {
@@ -80,4 +74,10 @@ public class User {
return roles; return roles;
} }
public void setRoles(List<Role> roles) {
this.roles = roles.stream()
.map(role -> role.getDescription())
.collect(Collectors.joining("&"));
}
} }

View File

@@ -3,7 +3,9 @@ package com.hideyoshi.backendportfolio.base.user.model;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.*; import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
@@ -19,7 +21,7 @@ public class TokenDTO implements Serializable {
@NotNull(message = "Invalid AccessToken. Please Authenticate first.") @NotNull(message = "Invalid AccessToken. Please Authenticate first.")
private String token; private String token;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date expirationDate; private Date expirationDate;
} }

View File

@@ -50,7 +50,7 @@ public class UserDTO implements UserDetails {
@ValidPassword @ValidPassword
private String password; private String password;
@Size(min=1) @Size(min = 1)
private List<Role> roles; private List<Role> roles;
private String profilePictureUrl; private String profilePictureUrl;

View File

@@ -9,5 +9,6 @@ import java.util.Optional;
@Repository @Repository
public interface UserRepository extends JpaRepository<User, Long> { public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username); Optional<User> findByUsername(String username);
Optional<User> findByEmail(String email); Optional<User> findByEmail(String email);
} }

View File

@@ -31,7 +31,7 @@ public class UserServiceImpl implements UserService {
@Override @Override
public UserDTO saveUser(@Valid UserDTO user) { public UserDTO saveUser(@Valid UserDTO user) {
this.userRepo.findByUsername(user.getUsername()).ifPresent( userOnDB -> { this.userRepo.findByUsername(user.getUsername()).ifPresent(userOnDB -> {
throw new BadRequestException(String.format("User %s already exists. Try another UserName.", userOnDB.getUsername())); throw new BadRequestException(String.format("User %s already exists. Try another UserName.", userOnDB.getUsername()));
}); });
@@ -48,7 +48,7 @@ public class UserServiceImpl implements UserService {
@Override @Override
public void alterUser(Long id, @Valid UserDTO user) { public void alterUser(Long id, @Valid UserDTO user) {
this.userRepo.findById(id).ifPresentOrElse( userOnDB -> { this.userRepo.findById(id).ifPresentOrElse(userOnDB -> {
User userToSave = user.toEntity(); User userToSave = user.toEntity();
userToSave.setId(userOnDB.getId()); userToSave.setId(userOnDB.getId());
userRepo.save(userToSave); userRepo.save(userToSave);
@@ -60,7 +60,7 @@ public class UserServiceImpl implements UserService {
@Override @Override
public void deleteUser(Long id) { public void deleteUser(Long id) {
this.userRepo.findById(id).ifPresentOrElse( userOnDB -> { this.userRepo.findById(id).ifPresentOrElse(userOnDB -> {
this.userRepo.delete(userOnDB); this.userRepo.delete(userOnDB);
}, () -> { }, () -> {
throw new BadRequestException("User doesn't exist."); throw new BadRequestException("User doesn't exist.");
@@ -124,8 +124,8 @@ public class UserServiceImpl implements UserService {
log.info(String.format("Fetching user: %s", username)); log.info(String.format("Fetching user: %s", username));
return new UserDTO( return new UserDTO(
userRepo.findByUsername(username) userRepo.findByUsername(username)
.orElseThrow(() -> new BadRequestException("User Not Found. Please create an Account.")) .orElseThrow(() -> new BadRequestException("User Not Found. Please create an Account."))
); );
} }

View File

@@ -0,0 +1,21 @@
package com.hideyoshi.backendportfolio.healthChecker.api;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Log4j2
@Controller
@RestController
@RequestMapping("/health")
public class HealthCheckerController {
@RequestMapping
public ResponseEntity<String> healthCheck() {
log.info("Health check requested");
return ResponseEntity.ok("Health check successful!");
}
}

View File

@@ -19,7 +19,7 @@ public enum FileTypeEnum {
} }
public static FileTypeEnum fromValue(String value) { public static FileTypeEnum fromValue(String value) {
for (FileTypeEnum e: FileTypeEnum.values()) { for (FileTypeEnum e : FileTypeEnum.values()) {
if (e.getFileExtension().equals(value)) { if (e.getFileExtension().equals(value)) {
return e; return e;
} }

View File

@@ -2,7 +2,9 @@ package com.hideyoshi.backendportfolio.microservice.storageService.model;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*; import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter @Getter
@NoArgsConstructor @NoArgsConstructor

View File

@@ -2,7 +2,9 @@ package com.hideyoshi.backendportfolio.microservice.storageService.model;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*; import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Getter @Getter
@NoArgsConstructor @NoArgsConstructor

View File

@@ -1,7 +1,6 @@
package com.hideyoshi.backendportfolio.microservice.storageService.service; package com.hideyoshi.backendportfolio.microservice.storageService.service;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.hideyoshi.backendportfolio.microservice.storageService.config.StorageServiceConfig; import com.hideyoshi.backendportfolio.microservice.storageService.config.StorageServiceConfig;
import com.hideyoshi.backendportfolio.microservice.storageService.enums.FileTypeEnum; import com.hideyoshi.backendportfolio.microservice.storageService.enums.FileTypeEnum;
@@ -10,8 +9,8 @@ import com.hideyoshi.backendportfolio.microservice.storageService.model.StorageS
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder; import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;

View File

@@ -2,7 +2,7 @@ package com.hideyoshi.backendportfolio.util.exception;
import java.time.LocalDateTime; import java.time.LocalDateTime;
public class AuthenticationInvalidExceptionDetails extends ExceptionDetails{ public class AuthenticationInvalidExceptionDetails extends ExceptionDetails {
public AuthenticationInvalidExceptionDetails( public AuthenticationInvalidExceptionDetails(
String title, String title,

View File

@@ -4,7 +4,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseStatus(HttpStatus.BAD_REQUEST)
public class BadRequestException extends RuntimeException{ public class BadRequestException extends RuntimeException {
public BadRequestException(String message) { public BadRequestException(String message) {
super(message); super(message);
} }

View File

@@ -2,8 +2,8 @@ package com.hideyoshi.backendportfolio.util.guard;
import java.lang.annotation.*; import java.lang.annotation.*;
@Target( ElementType.METHOD ) @Target(ElementType.METHOD)
@Retention( RetentionPolicy.RUNTIME ) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface UserResourceGuard { public @interface UserResourceGuard {

View File

@@ -61,11 +61,6 @@ public enum UserResourceGuardEnum {
this.accessType = accessType; this.accessType = accessType;
} }
public abstract Boolean hasAccess(
UserService userService,
ObjectMapper objectMapper,
HttpServletRequest request);
public static UserResourceGuardEnum byValue(String accessType) { public static UserResourceGuardEnum byValue(String accessType) {
for (UserResourceGuardEnum o : values()) { for (UserResourceGuardEnum o : values()) {
if (o.getAccessType().equals(accessType)) { if (o.getAccessType().equals(accessType)) {
@@ -106,4 +101,9 @@ public enum UserResourceGuardEnum {
return true; return true;
} }
public abstract Boolean hasAccess(
UserService userService,
ObjectMapper objectMapper,
HttpServletRequest request);
} }

View File

@@ -18,7 +18,7 @@ public class EmailValidator implements ConstraintValidator<ValidEmail, String> {
} }
@Override @Override
public boolean isValid(String email, ConstraintValidatorContext context){ public boolean isValid(String email, ConstraintValidatorContext context) {
return (validateEmail(email)); return (validateEmail(email));
} }

View File

@@ -1,7 +1,5 @@
package com.hideyoshi.backendportfolio.util.validator.email.valid; package com.hideyoshi.backendportfolio.util.validator.email.valid;
import com.hideyoshi.backendportfolio.util.validator.email.valid.EmailValidator;
import javax.validation.Constraint; import javax.validation.Constraint;
import javax.validation.Payload; import javax.validation.Payload;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;

View File

@@ -10,9 +10,8 @@ import java.util.regex.Pattern;
@RequiredArgsConstructor @RequiredArgsConstructor
public class PasswordValidator implements ConstraintValidator<ValidPassword, String> { public class PasswordValidator implements ConstraintValidator<ValidPassword, String> {
Provider provider;
private final String PASSWORD_PATTERN = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"; private final String PASSWORD_PATTERN = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$";
Provider provider;
@Override @Override
public void initialize(ValidPassword constraintAnnotation) { public void initialize(ValidPassword constraintAnnotation) {

View File

@@ -2,13 +2,12 @@ package com.hideyoshi.backendportfolio;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.context.SpringBootTest;
@DataJpaTest @DataJpaTest
class BackendPortfolioApplicationTests { class BackendPortfolioApplicationTests {
@Test @Test
void contextLoads() { void contextLoads() {
} }
} }

View File

@@ -38,7 +38,7 @@ class UserRepositoryTest {
} }
@Test @Test
void canFindsUserByUsername() { void canFindsUserByUsername() {
// Given // Given
User userSaved = this.entityManager.persist(this.createEntity()); User userSaved = this.entityManager.persist(this.createEntity());
this.underTest.findAll(); this.underTest.findAll();

View File

@@ -1,6 +1,5 @@
package com.hideyoshi.backendportfolio.base.user.service; package com.hideyoshi.backendportfolio.base.user.service;
import com.hideyoshi.backendportfolio.base.security.service.AuthService;
import com.hideyoshi.backendportfolio.base.user.entity.Provider; import com.hideyoshi.backendportfolio.base.user.entity.Provider;
import com.hideyoshi.backendportfolio.base.user.entity.Role; import com.hideyoshi.backendportfolio.base.user.entity.Role;
import com.hideyoshi.backendportfolio.base.user.entity.User; import com.hideyoshi.backendportfolio.base.user.entity.User;
@@ -10,7 +9,10 @@ import com.hideyoshi.backendportfolio.util.exception.BadRequestException;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.*; import org.mockito.ArgumentCaptor;
import org.mockito.ArgumentMatchers;
import org.mockito.BDDMockito;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
@@ -24,12 +26,11 @@ import java.util.Optional;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@DataJpaTest @DataJpaTest
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
@DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
class UserServiceImplTest { class UserServiceImplTest {
private UserServiceImpl underTest; private UserServiceImpl underTest;
@@ -70,25 +71,25 @@ class UserServiceImplTest {
@Test @Test
void canSaveOAuthUser() { void canSaveOAuthUser() {
BDDMockito.when(userRepository.findByUsername(ArgumentMatchers.any(String.class))) BDDMockito.when(userRepository.findByUsername(ArgumentMatchers.any(String.class)))
.thenReturn(Optional.ofNullable(null)); .thenReturn(Optional.ofNullable(null));
BDDMockito.when(userRepository.save(ArgumentMatchers.any(User.class))) BDDMockito.when(userRepository.save(ArgumentMatchers.any(User.class)))
.thenReturn(createOAuthUser().toEntity()); .thenReturn(createOAuthUser().toEntity());
// Given // Given
UserDTO user = this.createOAuthUser(); UserDTO user = this.createOAuthUser();
// When // When
UserDTO userSaved = this.underTest.saveUser(user); UserDTO userSaved = this.underTest.saveUser(user);
//Then //Then
ArgumentCaptor<User> userArgumentCaptor = ArgumentCaptor.forClass(User.class); ArgumentCaptor<User> userArgumentCaptor = ArgumentCaptor.forClass(User.class);
verify(userRepository).save(userArgumentCaptor.capture()); verify(userRepository).save(userArgumentCaptor.capture());
assertThat(userArgumentCaptor.getValue()).isEqualTo(user.toEntity()); assertThat(userArgumentCaptor.getValue()).isEqualTo(user.toEntity());
assertThat(userArgumentCaptor.getValue().getPassword()).isEmpty(); assertThat(userArgumentCaptor.getValue().getPassword()).isEmpty();
assertThat(userSaved).isInstanceOf(UserDTO.class); assertThat(userSaved).isInstanceOf(UserDTO.class);
} }
@Test @Test
@@ -181,7 +182,7 @@ class UserServiceImplTest {
// Given // Given
UserDTO userSaved = this.underTest.getUser(user.getUsername()); UserDTO userSaved = this.underTest.getUser(user.getUsername());
if (!Objects.nonNull(userSaved)) { if (!Objects.nonNull(userSaved)) {
userSaved = this.underTest.saveUser(user); userSaved = this.underTest.saveUser(user);
} }
// When // When
this.underTest.addRoleToUser(userSaved.getId(), Role.USER.getDescription()); this.underTest.addRoleToUser(userSaved.getId(), Role.USER.getDescription());

View File

@@ -17,7 +17,7 @@ import java.io.IOException;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
@DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class StorageServiceTest { public class StorageServiceTest {
private StorageService storageService; private StorageService storageService;