[v0.0.2] Adds Google and Github OAuth2 Authentication
Adds to the API the feature of OAuth2 Authentication via two providers: Google and Github. For that the tests were updated.
This commit is contained in:
10
pom.xml
10
pom.xml
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.1</version>
|
||||
<version>2.7.5</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.hideyoshi</groupId>
|
||||
@@ -24,7 +24,7 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
<version>2.7.3</version>
|
||||
<version>2.7.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -34,6 +34,10 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-oauth2-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session-core</artifactId>
|
||||
@@ -46,7 +50,7 @@
|
||||
<dependency>
|
||||
<groupId>com.auth0</groupId>
|
||||
<artifactId>java-jwt</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.hideyoshi.backendportfolio.base.config;
|
||||
|
||||
import antlr.actions.python.CodeLexer;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -8,12 +9,13 @@ import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class CorsConfig {
|
||||
|
||||
@Value("${com.hideyoshi.frontEndPath}")
|
||||
@Value("${com.hideyoshi.frontendPath}")
|
||||
private String FRONTEND_PATH;
|
||||
|
||||
@Value("${com.hideyoshi.frontendConnectionType}")
|
||||
@@ -32,10 +34,12 @@ public class CorsConfig {
|
||||
|
||||
CorsConfiguration configuration = new CorsConfiguration();
|
||||
configuration.setAllowedOrigins(List.of(connectionProtocol + FRONTEND_PATH));
|
||||
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
|
||||
configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token"));
|
||||
configuration.setAllowCredentials(true);
|
||||
configuration.setAllowedMethods(Collections.singletonList("*"));
|
||||
configuration.setAllowedHeaders(Collections.singletonList("*"));
|
||||
// configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
|
||||
// configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token"));
|
||||
configuration.setExposedHeaders(List.of("x-auth-token"));
|
||||
configuration.setAllowCredentials(true);
|
||||
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
source.registerCorsConfiguration("/**", configuration);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.hideyoshi.backendportfolio.base.config;
|
||||
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Role;
|
||||
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
|
||||
import com.hideyoshi.backendportfolio.base.user.repo.UserRepository;
|
||||
@@ -30,10 +31,11 @@ public class DefaultUserConfig {
|
||||
CommandLineRunner run(UserService userService, UserRepository userRepo) {
|
||||
return args -> {
|
||||
UserDTO defaultUser = UserDTO.builder()
|
||||
.fullname(ADMIN_NAME)
|
||||
.name(ADMIN_NAME)
|
||||
.email(ADMIN_EMAIL)
|
||||
.username(ADMIN_USERNAME)
|
||||
.password(ADMIN_PASSWORD)
|
||||
.provider(Provider.LOCAL)
|
||||
.roles(new ArrayList<>())
|
||||
.build();
|
||||
if (!userRepo.findByUsername(defaultUser.getUsername()).isPresent()) {
|
||||
|
||||
@@ -3,29 +3,31 @@ package com.hideyoshi.backendportfolio.base.security;
|
||||
import com.hideyoshi.backendportfolio.base.config.RestAuthenticationEntryPointConfig;
|
||||
import com.hideyoshi.backendportfolio.base.security.filter.CustomAuthenticationFilter;
|
||||
import com.hideyoshi.backendportfolio.base.security.filter.CustomAuthorizationFilter;
|
||||
import com.hideyoshi.backendportfolio.base.security.oauth.repo.OAuthRequestRepository;
|
||||
import com.hideyoshi.backendportfolio.base.security.service.AuthService;
|
||||
import com.hideyoshi.backendportfolio.util.exception.AuthenticationInvalidException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
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.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.CorsConfigurationSource;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
|
||||
import java.util.Arrays;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
@Log4j2
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@RequiredArgsConstructor
|
||||
@@ -37,6 +39,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
private final BCryptPasswordEncoder passwordEncoder;
|
||||
|
||||
private final OAuthRequestRepository oAuthRequestRepository;
|
||||
|
||||
private final RestAuthenticationEntryPointConfig restAuthenticationEntryPointConfig;
|
||||
|
||||
@Override
|
||||
@@ -48,22 +52,64 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
|
||||
http.cors().and().csrf().disable();
|
||||
|
||||
this.addSecurityToHttp(http);
|
||||
this.addOAuthSecurityToHttp(http);
|
||||
}
|
||||
|
||||
private void addSecurityToHttp(HttpSecurity http) throws Exception {
|
||||
|
||||
CustomAuthenticationFilter customAuthenticationFilter =
|
||||
new CustomAuthenticationFilter(this.authenticationManager(), this.authService, this.restAuthenticationEntryPointConfig);
|
||||
|
||||
customAuthenticationFilter.setFilterProcessesUrl("/user/login");
|
||||
|
||||
http.cors().and().csrf().disable()
|
||||
.authorizeRequests().antMatchers("/session/**").permitAll()
|
||||
.and().authorizeRequests().antMatchers("/user/signup").permitAll()
|
||||
.and().authorizeRequests().antMatchers("/user/login/refresh").permitAll()
|
||||
.and().authorizeRequests().antMatchers("/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN")
|
||||
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
|
||||
.and().addFilter(customAuthenticationFilter)
|
||||
.addFilterBefore(new CustomAuthorizationFilter(this.authService), UsernamePasswordAuthenticationFilter.class);
|
||||
http.authorizeRequests()
|
||||
.antMatchers("/session/**").permitAll()
|
||||
.and().authorizeRequests().antMatchers("/user/signup").permitAll()
|
||||
.and().authorizeRequests().antMatchers("/user/oauth/**").permitAll()
|
||||
.and().authorizeRequests().antMatchers("/user/login/**").permitAll()
|
||||
.and().authorizeRequests().antMatchers("/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN")
|
||||
|
||||
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
|
||||
.and().addFilter(customAuthenticationFilter)
|
||||
|
||||
.addFilterBefore(new CustomAuthorizationFilter(this.authService), UsernamePasswordAuthenticationFilter.class);
|
||||
|
||||
}
|
||||
|
||||
private void addOAuthSecurityToHttp(HttpSecurity http) throws Exception {
|
||||
|
||||
http.oauth2Login()
|
||||
.authorizationEndpoint()
|
||||
.authorizationRequestRepository(this.oAuthRequestRepository)
|
||||
.and().successHandler(this::successHandler)
|
||||
.and().exceptionHandling()
|
||||
.authenticationEntryPoint(this::authenticationEntryPoint);
|
||||
}
|
||||
|
||||
private void successHandler(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
Authentication authentication ) throws IOException {
|
||||
|
||||
OAuth2User oauthUser = (OAuth2User) authentication.getPrincipal();
|
||||
|
||||
this.authService.loginOAuthUser(
|
||||
request,
|
||||
response,
|
||||
oauthUser
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
private void authenticationEntryPoint(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
AuthenticationException authentication ) {
|
||||
throw new AuthenticationInvalidException(authentication.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return super.authenticationManagerBean();
|
||||
|
||||
@@ -7,6 +7,7 @@ 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 lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@@ -57,18 +58,12 @@ public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFi
|
||||
@Override
|
||||
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) throws IOException {
|
||||
|
||||
UserDTO user = (UserDTO) authentication.getPrincipal();
|
||||
Algorithm algorithm = Algorithm.HMAC256("secret".getBytes());
|
||||
this.authService.loginUser(
|
||||
request,
|
||||
response,
|
||||
(UserDTO) authentication.getPrincipal()
|
||||
);
|
||||
|
||||
HashMap<String,TokenDTO> tokens = this.authService.generateTokens(user, algorithm, request);
|
||||
|
||||
HttpSession httpSession = request.getSession();
|
||||
UserDTO authenticatedUser = user.toResponse(tokens.get("accessToken"), tokens.get("refreshToken"));
|
||||
httpSession.setAttribute("user", authenticatedUser);
|
||||
|
||||
response.setContentType(APPLICATION_JSON_VALUE);
|
||||
new ObjectMapper()
|
||||
.writeValue(response.getOutputStream(), authenticatedUser);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,24 +2,16 @@ package com.hideyoshi.backendportfolio.base.security.filter;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.hideyoshi.backendportfolio.base.security.service.AuthService;
|
||||
import com.hideyoshi.backendportfolio.util.exception.BadRequestException;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
|
||||
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
||||
@@ -38,7 +30,7 @@ public class CustomAuthorizationFilter extends OncePerRequestFilter {
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
if (request.getServletPath().equals("/user/login")) {
|
||||
if (this.isPathNotProtected(request.getServletPath())) {
|
||||
filterChain.doFilter(request, response);
|
||||
} else {
|
||||
String authorizationHeader = request.getHeader(AUTHORIZATION);
|
||||
@@ -69,4 +61,13 @@ public class CustomAuthorizationFilter extends OncePerRequestFilter {
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean isPathNotProtected(String path) {
|
||||
|
||||
List<String> notProtectedPaths = Arrays.asList(
|
||||
"/user/login"
|
||||
);
|
||||
|
||||
return notProtectedPaths.contains(path);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.hideyoshi.backendportfolio.base.security.oauth.mapper;
|
||||
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class GithubOAuthMap implements OAuthMap {
|
||||
|
||||
private OAuth2User oAuth2User;
|
||||
|
||||
@Override
|
||||
public String getPrincipal() {
|
||||
return oAuth2User.getAttribute("login");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Provider getProvider() {
|
||||
return Provider.GITHUB;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.hideyoshi.backendportfolio.base.security.oauth.mapper;
|
||||
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class GoogleOAuthMap implements OAuthMap {
|
||||
|
||||
private OAuth2User oauthUser;
|
||||
|
||||
@Override
|
||||
public String getPrincipal() {
|
||||
return this.oauthUser.getAttribute("given_name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Provider getProvider() {
|
||||
return Provider.GOOGLE;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.hideyoshi.backendportfolio.base.security.oauth.mapper;
|
||||
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
|
||||
public interface OAuthMap {
|
||||
|
||||
String getPrincipal();
|
||||
|
||||
Provider getProvider();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.hideyoshi.backendportfolio.base.security.oauth.mapper;
|
||||
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
|
||||
|
||||
public enum OAuthMapEnum {
|
||||
|
||||
GOOGLE(GoogleOAuthMap.class, Provider.GOOGLE),
|
||||
|
||||
GITHUB(GithubOAuthMap.class, Provider.GITHUB);
|
||||
|
||||
private Class oAuthMap;
|
||||
|
||||
private Provider provider;
|
||||
|
||||
private OAuthMapEnum(Class oAuthMap, Provider provider) {
|
||||
this.oAuthMap = oAuthMap;
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public Class getMap() {
|
||||
return oAuthMap;
|
||||
}
|
||||
|
||||
public Provider getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
public static OAuthMapEnum byValue(String name) {
|
||||
for (OAuthMapEnum e : values()) {
|
||||
if (e.getProvider().getName().equals(name)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Argument not valid.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package com.hideyoshi.backendportfolio.base.security.oauth.repo;
|
||||
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository;
|
||||
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Objects;
|
||||
|
||||
@Log4j2
|
||||
@Repository
|
||||
public class OAuthRequestRepository implements AuthorizationRequestRepository<OAuth2AuthorizationRequest> {
|
||||
|
||||
@Override
|
||||
public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) {
|
||||
|
||||
String state = request.getParameter("state");
|
||||
log.info(state);
|
||||
|
||||
if (Objects.nonNull(state)) {
|
||||
return removeAuthorizationRequest(request);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest, HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
String state = authorizationRequest.getState();
|
||||
log.info(state);
|
||||
|
||||
request.getSession().setAttribute(
|
||||
String.format("state_%s", state),
|
||||
authorizationRequest
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) {
|
||||
|
||||
String state = request.getParameter("state");
|
||||
|
||||
OAuth2AuthorizationRequest authorizationRequest = null;
|
||||
if (Objects.nonNull(state)) {
|
||||
authorizationRequest = this.getAuthorizationRequestFromSession(request, state);
|
||||
}
|
||||
|
||||
if (Objects.nonNull(authorizationRequest)) {
|
||||
removeAuthorizationRequestFromSession(request, state);
|
||||
return authorizationRequest;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private OAuth2AuthorizationRequest getAuthorizationRequestFromSession(HttpServletRequest request, String state) {
|
||||
return (OAuth2AuthorizationRequest) request.getSession().getAttribute(
|
||||
String.format("state_%s", state)
|
||||
);
|
||||
}
|
||||
|
||||
private void removeAuthorizationRequestFromSession(HttpServletRequest request, String state) {
|
||||
request.getSession().removeAttribute(
|
||||
String.format("state_%s", state)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,10 +4,12 @@ import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.hideyoshi.backendportfolio.base.user.model.TokenDTO;
|
||||
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public interface AuthService {
|
||||
@@ -24,4 +26,12 @@ public interface AuthService {
|
||||
|
||||
UserDTO signupUser(@Valid UserDTO user, HttpServletRequest request);
|
||||
|
||||
UserDTO generateUserWithTokens(UserDTO user, HttpServletRequest request);
|
||||
|
||||
UserDTO processOAuthPostLogin(@Valid UserDTO user, HttpServletRequest request);
|
||||
|
||||
void loginUser(HttpServletRequest request, HttpServletResponse response, @Valid UserDTO user) throws IOException;
|
||||
|
||||
void loginOAuthUser(HttpServletRequest request, HttpServletResponse response, OAuth2User user) throws IOException;
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,11 @@ import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.hideyoshi.backendportfolio.base.security.oauth.mapper.OAuthMap;
|
||||
import com.hideyoshi.backendportfolio.base.security.oauth.mapper.OAuthMapEnum;
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Role;
|
||||
import com.hideyoshi.backendportfolio.base.user.model.TokenDTO;
|
||||
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
|
||||
import com.hideyoshi.backendportfolio.base.user.service.UserService;
|
||||
@@ -16,6 +21,7 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
|
||||
@@ -23,10 +29,12 @@ import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Arrays.stream;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
|
||||
@Log4j2
|
||||
@Service
|
||||
@@ -66,6 +74,7 @@ public class AuthServiceImpl implements AuthService {
|
||||
.sign(algorithm);
|
||||
|
||||
return new TokenDTO(accessToken, expirationDate);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -160,16 +169,93 @@ public class AuthServiceImpl implements AuthService {
|
||||
@Override
|
||||
public UserDTO signupUser(@Valid UserDTO user, HttpServletRequest request) {
|
||||
|
||||
user.setProvider(Provider.LOCAL);
|
||||
|
||||
return this.generateUserWithTokens(
|
||||
this.userService.saveUser(user),
|
||||
request
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDTO generateUserWithTokens(UserDTO user, HttpServletRequest request) {
|
||||
|
||||
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET.getBytes());
|
||||
|
||||
UserDTO userSaved = this.userService.saveUser(user);
|
||||
HashMap<String, TokenDTO> tokens = this.generateTokens(userSaved, algorithm, request);
|
||||
HashMap<String, TokenDTO> tokens = this.generateTokens(user, algorithm, request);
|
||||
|
||||
HttpSession httpSession = request.getSession();
|
||||
UserDTO userAuthenticated = userSaved.toResponse(tokens.get("accessToken"), tokens.get("refreshToken"));
|
||||
UserDTO userAuthenticated = user.toResponse(tokens.get("accessToken"), tokens.get("refreshToken"));
|
||||
|
||||
httpSession.setAttribute("user", userAuthenticated);
|
||||
|
||||
return userAuthenticated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserDTO processOAuthPostLogin(@Valid UserDTO user, HttpServletRequest request) {
|
||||
|
||||
if (Objects.nonNull(user.getId())) {
|
||||
this.userService.alterUser(user.getId(), user);
|
||||
} else {
|
||||
this.userService.saveUser(user);
|
||||
}
|
||||
|
||||
return this.generateUserWithTokens(user, request);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginUser(HttpServletRequest request, HttpServletResponse response, @Valid UserDTO user) throws IOException {
|
||||
|
||||
UserDTO authenticatedUser = this.generateUserWithTokens(
|
||||
user,
|
||||
request
|
||||
);
|
||||
|
||||
response.setContentType(APPLICATION_JSON_VALUE);
|
||||
new ObjectMapper()
|
||||
.writeValue(response.getOutputStream(), authenticatedUser);
|
||||
}
|
||||
|
||||
public void loginOAuthUser(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
OAuth2User oauthUser) throws IOException {
|
||||
|
||||
String[] url = request.getRequestURL().toString().split("/");
|
||||
String clientId = url[url.length-1];
|
||||
|
||||
OAuthMap oauthMap = null;
|
||||
try {
|
||||
oauthMap = (OAuthMap) OAuthMapEnum.byValue(clientId).getMap()
|
||||
.getDeclaredConstructor(OAuth2User.class).newInstance(oauthUser);
|
||||
} catch (Exception e) {
|
||||
throw new BadRequestException("No Such Provider");
|
||||
}
|
||||
|
||||
UserDTO user = null;
|
||||
try {
|
||||
user = this.userService.getUser(oauthMap.getPrincipal());
|
||||
} catch (BadRequestException e) {
|
||||
user = UserDTO.builder()
|
||||
.name(oauthUser.getAttribute("name"))
|
||||
.username(oauthMap.getPrincipal())
|
||||
.email(oauthUser.getAttribute("email"))
|
||||
.roles(Arrays.asList(Role.USER))
|
||||
.provider(oauthMap.getProvider())
|
||||
.build();
|
||||
}
|
||||
|
||||
UserDTO authenticatedUser = this.processOAuthPostLogin(
|
||||
user,
|
||||
request
|
||||
);
|
||||
|
||||
response.setContentType(APPLICATION_JSON_VALUE);
|
||||
new ObjectMapper()
|
||||
.writeValue(response.getOutputStream(), authenticatedUser);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,15 +10,19 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.log4j.Log4j2;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.security.Provider;
|
||||
import java.util.List;
|
||||
|
||||
@Log4j2
|
||||
@@ -49,34 +53,6 @@ public class UserController {
|
||||
return ResponseEntity.created(uri).body(this.authService.signupUser(user, request));
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
@UserResourceGuard(accessType = UserResourceGuardEnum.SAME_USER)
|
||||
public ResponseEntity<Void> deleteUser(@PathVariable("id") Long id) {
|
||||
this.userService.deleteUser(id);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
//
|
||||
// @PostMapping("/alter/{id}")
|
||||
// @UserResourceGuard(accessType = UserResourceGuardEnum.SAME_USER)
|
||||
// public ResponseEntity<Void> alterUser(@PathVariable("id") Long id, @RequestBody @Valid UserDTO user) {
|
||||
// this.userService.alterUser(id, user);
|
||||
// return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
// }
|
||||
//
|
||||
// @PostMapping("/alter/{id}/role/add")
|
||||
// @UserResourceGuard(accessType = UserResourceGuardEnum.SAME_USER)
|
||||
// public ResponseEntity<?> addRoleToUser(@PathVariable("id") Long id, @RequestBody RoleToUserDTO filter) {
|
||||
// userService.addRoleToUser(id, filter.getRoleName());
|
||||
// return ResponseEntity.ok().build();
|
||||
// }
|
||||
//
|
||||
// @PostMapping("/alter/{id}/role/delete")
|
||||
// @UserResourceGuard(accessType = UserResourceGuardEnum.SAME_USER)
|
||||
// public ResponseEntity<?> deleteRoleToUser(@PathVariable("id") Long id, @RequestBody RoleToUserDTO filter) {
|
||||
// userService.removeRoleFromUser(id, filter.getRoleName());
|
||||
// return ResponseEntity.ok().build();
|
||||
// }
|
||||
|
||||
@PostMapping("/login/refresh")
|
||||
@UserResourceGuard(accessType = UserResourceGuardEnum.OPEN)
|
||||
public ResponseEntity<UserDTO> refreshAccessToken(
|
||||
@@ -86,4 +62,18 @@ public class UserController {
|
||||
return ResponseEntity.ok(this.authService.refreshAccessToken(refreshToken.getToken(), request, response));
|
||||
}
|
||||
|
||||
@GetMapping("/login/callback")
|
||||
@UserResourceGuard(accessType = UserResourceGuardEnum.OPEN)
|
||||
public void oauthCallback(HttpServletResponse response) throws IOException {
|
||||
log.info("Teste");
|
||||
response.sendRedirect("http://localhost:4200");
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
@UserResourceGuard(accessType = UserResourceGuardEnum.SAME_USER)
|
||||
public ResponseEntity<Void> deleteUser(@PathVariable("id") Long id) {
|
||||
this.userService.deleteUser(id);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,10 @@ public enum Provider {
|
||||
|
||||
GOOGLE("google"),
|
||||
|
||||
GITHUB("github"),
|
||||
|
||||
LOCAL("local");
|
||||
|
||||
private String name;
|
||||
|
||||
Provider(String name) {
|
||||
@@ -15,4 +18,13 @@ public enum Provider {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static Provider byValue(String name) {
|
||||
for (Provider p : values()) {
|
||||
if (p.getName().equals(name)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Argument not valid.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,10 +25,10 @@ public class User {
|
||||
private Long id;
|
||||
|
||||
@Column(
|
||||
name = "full_name",
|
||||
name = "name",
|
||||
nullable = false
|
||||
)
|
||||
private String fullname;
|
||||
private String name;
|
||||
|
||||
@Column(
|
||||
name = "email",
|
||||
@@ -52,6 +52,12 @@ public class User {
|
||||
)
|
||||
private String password;
|
||||
|
||||
@Column(
|
||||
name = "provider",
|
||||
nullable = false
|
||||
)
|
||||
private String provider;
|
||||
|
||||
@Column(
|
||||
name = "roles",
|
||||
nullable = false
|
||||
|
||||
@@ -36,7 +36,7 @@ public class UserDTO implements UserDetails {
|
||||
private Long id;
|
||||
|
||||
@NotEmpty
|
||||
private String fullname;
|
||||
private String name;
|
||||
|
||||
@NotEmpty
|
||||
@ValidEmail
|
||||
@@ -59,104 +59,82 @@ public class UserDTO implements UserDetails {
|
||||
|
||||
private Provider provider;
|
||||
|
||||
public UserDTO(
|
||||
String fullname,
|
||||
String email,
|
||||
String username,
|
||||
String password
|
||||
) {
|
||||
this.fullname = fullname;
|
||||
this.email = email;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.roles = List.of(Role.USER);
|
||||
}
|
||||
|
||||
public UserDTO(
|
||||
String fullname,
|
||||
String email,
|
||||
String username,
|
||||
String password,
|
||||
List<Role> roles
|
||||
) {
|
||||
this.fullname = fullname;
|
||||
this.email = email;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.roles = roles;
|
||||
}
|
||||
|
||||
public UserDTO(User entity) {
|
||||
this.id = entity.getId();
|
||||
this.fullname = entity.getFullname();
|
||||
this.name = entity.getName();
|
||||
this.email = entity.getEmail();
|
||||
this.username = entity.getUsername();
|
||||
this.password = entity.getPassword();
|
||||
this.provider = Provider.byValue(entity.getProvider());
|
||||
this.roles = entity.getRoles();
|
||||
}
|
||||
|
||||
public User toEntity() {
|
||||
return new User(
|
||||
this.id,
|
||||
this.fullname,
|
||||
this.name,
|
||||
this.email,
|
||||
this.username,
|
||||
this.password,
|
||||
this.provider.getName(),
|
||||
Objects.nonNull(this.roles) ? this.roles.stream()
|
||||
.map(role -> role.getDescription())
|
||||
.collect(Collectors.joining("&")) : Role.USER.getDescription()
|
||||
);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return this.roles.stream()
|
||||
return this.getRoles().stream()
|
||||
.map(role -> new SimpleGrantedAuthority(role.getDescription()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public boolean isAccountNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public boolean isAccountNonLocked() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public boolean isCredentialsNonExpired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public boolean isEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public UserDTO toResponse() {
|
||||
return UserDTO.builder()
|
||||
.fullname(this.fullname)
|
||||
.name(this.name)
|
||||
.email(this.email)
|
||||
.username(this.username)
|
||||
.provider(this.provider)
|
||||
.build();
|
||||
}
|
||||
|
||||
public UserDTO toResponse(TokenDTO accessToken, TokenDTO refreshToken) {
|
||||
return UserDTO.builder()
|
||||
.id(this.id)
|
||||
.fullname(this.fullname)
|
||||
.name(this.name)
|
||||
.email(this.email)
|
||||
.username(this.username)
|
||||
.provider(this.provider)
|
||||
.roles(this.roles)
|
||||
.accessToken(accessToken)
|
||||
.refreshToken(refreshToken)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,9 +34,13 @@ public class UserServiceImpl implements UserService {
|
||||
throw new BadRequestException(String.format("User %s already exists. Try another UserName.", userOnDB.getUsername()));
|
||||
});
|
||||
|
||||
log.info(String.format("Saving to the database user of name: %s", user.getFullname()));
|
||||
log.info(String.format("Saving to the database user of name: %s", user.getName()));
|
||||
|
||||
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
||||
if (Objects.nonNull(user.getPassword())) {
|
||||
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
||||
} else {
|
||||
user.setPassword("");
|
||||
}
|
||||
UserDTO userSaved = new UserDTO(userRepo.save(user.toEntity()));
|
||||
|
||||
if (!userSaved.getRoles().contains(Role.USER)) {
|
||||
@@ -81,10 +85,10 @@ public class UserServiceImpl implements UserService {
|
||||
log.info(String.format("Adding to user %s the role %s",
|
||||
userOnDB.getUsername(), newAuthority.getDescription()));
|
||||
|
||||
if (roles.add(newAuthority)) {
|
||||
userOnDB.setRoles(roles);
|
||||
this.alterUser(userOnDB.getId(), userOnDB);
|
||||
}
|
||||
roles.add(newAuthority);
|
||||
userOnDB.setRoles(roles);
|
||||
|
||||
this.alterUser(userOnDB.getId(), userOnDB);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.hideyoshi.backendportfolio.util.validator.password;
|
||||
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
@@ -9,17 +10,25 @@ import java.util.regex.Pattern;
|
||||
@RequiredArgsConstructor
|
||||
public class PasswordValidator implements ConstraintValidator<ValidPassword, String> {
|
||||
|
||||
Provider provider;
|
||||
|
||||
private final String PASSWORD_PATTERN = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$";
|
||||
|
||||
@Override
|
||||
public void initialize(ValidPassword constraintAnnotation) {}
|
||||
public void initialize(ValidPassword constraintAnnotation) {
|
||||
this.provider = constraintAnnotation.provider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(String password, ConstraintValidatorContext context) {
|
||||
|
||||
return Pattern.compile(PASSWORD_PATTERN)
|
||||
.matcher(password)
|
||||
.matches();
|
||||
if (this.provider.equals(Provider.GOOGLE)) {
|
||||
return true;
|
||||
} else {
|
||||
return Pattern.compile(PASSWORD_PATTERN)
|
||||
.matcher(password)
|
||||
.matches();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.hideyoshi.backendportfolio.util.validator.password;
|
||||
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
import java.lang.annotation.Documented;
|
||||
@@ -9,13 +11,16 @@ import java.lang.annotation.Target;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
@Target({TYPE, FIELD, ANNOTATION_TYPE})
|
||||
@Retention(RUNTIME)
|
||||
@Constraint(validatedBy = PasswordValidator.class)
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Target({TYPE, FIELD, ANNOTATION_TYPE})
|
||||
@Constraint(validatedBy = PasswordValidator.class)
|
||||
public @interface ValidPassword {
|
||||
|
||||
String message() default "Invalid password";
|
||||
String message() default
|
||||
"The password must have at least: a special character, a number, a uppercase and a lowercase ";
|
||||
|
||||
Provider provider() default Provider.LOCAL;
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
com:
|
||||
hideyoshi:
|
||||
frontEndPath: ${FRONTEND_PATH}
|
||||
frontendPath: ${FRONTEND_PATH}
|
||||
frontendConnectionType: ${FRONTEND_CONNECTION_TYPE}
|
||||
tokenSecret: ${TOKEN_SECRET}
|
||||
accessTokenDuration: ${ACCESS_TOKEN_DURATION}
|
||||
@@ -17,6 +17,26 @@ server:
|
||||
|
||||
spring:
|
||||
|
||||
security:
|
||||
oauth2:
|
||||
client:
|
||||
registration:
|
||||
|
||||
google:
|
||||
clientId: ${GOOGLE_CLIENT_ID}
|
||||
clientSecret: ${GOOGLE_CLIENT_SECRET}
|
||||
redirectUri: ${GOOGLE_REDIRECT_URL}
|
||||
scope:
|
||||
- email
|
||||
- profile
|
||||
|
||||
github:
|
||||
clientId: ${GITHUB_CLIENT_ID}
|
||||
clientSecret: ${GITHUB_CLIENT_SECRET}
|
||||
redirectUri: ${GITHUB_REDIRECT_URL}
|
||||
scope:
|
||||
- user
|
||||
|
||||
datasource:
|
||||
url: jdbc:${DATABASE_URL}
|
||||
username: ${DATABASE_USERNAME}
|
||||
|
||||
@@ -8,4 +8,14 @@ databaseChangeLog:
|
||||
encoding: utf8
|
||||
path: sqls/db-table-model-client.sql
|
||||
relativeToChangelogFile: true
|
||||
dbms: postgresql
|
||||
dbms: postgresql
|
||||
|
||||
- changeSet:
|
||||
id: adds-user-provider
|
||||
author: vitor.h.n.batista@gmail.com
|
||||
changes:
|
||||
- sqlFile:
|
||||
encoding: utf8
|
||||
path: sqls/adds-user-provider.sql
|
||||
relativeToChangelogFile: true
|
||||
dbms: postgresql
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
alter table if exists auth."user"
|
||||
rename column "full_name" to "name";
|
||||
|
||||
ALTER TABLE IF EXISTS auth.user
|
||||
ADD COLUMN IF NOT EXISTS provider VARCHAR
|
||||
CHECK ( provider IN ('google', 'github', 'local') ) DEFAULT 'local' NOT NULL;
|
||||
|
||||
ALTER TABLE auth."user"
|
||||
DROP CONSTRAINT IF EXISTS client_email_unique;
|
||||
|
||||
ALTER TABLE auth."user"
|
||||
DROP CONSTRAINT IF EXISTS user_email_provider_unique;
|
||||
ALTER TABLE auth."user"
|
||||
ADD CONSTRAINT user_email_provider_unique UNIQUE (email, provider);
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.hideyoshi.backendportfolio.base.user.repo;
|
||||
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Provider;
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.Role;
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.User;
|
||||
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
|
||||
@@ -58,13 +59,14 @@ class UserRepositoryTest {
|
||||
}
|
||||
|
||||
private User createEntity() {
|
||||
return new UserDTO(
|
||||
"Clark Kent",
|
||||
"superman@gmail.com",
|
||||
"Superman",
|
||||
"password",
|
||||
List.of(Role.USER)
|
||||
).toEntity();
|
||||
return UserDTO.builder()
|
||||
.name("Clark Kent")
|
||||
.email("superman@gmail.com")
|
||||
.username("Superman")
|
||||
.password("password")
|
||||
.provider(Provider.LOCAL)
|
||||
.roles(List.of(Role.USER))
|
||||
.build().toEntity();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
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.Role;
|
||||
import com.hideyoshi.backendportfolio.base.user.entity.User;
|
||||
import com.hideyoshi.backendportfolio.base.user.model.UserDTO;
|
||||
@@ -349,15 +350,15 @@ class UserServiceImplTest {
|
||||
}
|
||||
|
||||
private UserDTO createUser() {
|
||||
UserDTO userCreated = new UserDTO(
|
||||
"Clark Kent",
|
||||
"superman@gmail.com",
|
||||
"Superman",
|
||||
"password",
|
||||
List.of(Role.USER)
|
||||
);
|
||||
userCreated.setId(1L);
|
||||
return userCreated;
|
||||
return UserDTO.builder()
|
||||
.id(1L)
|
||||
.name("Clark Kent")
|
||||
.email("superman@gmail.com")
|
||||
.username("Superman")
|
||||
.password("password")
|
||||
.provider(Provider.LOCAL)
|
||||
.roles(List.of(Role.USER))
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user