Compare commits
4 Commits
feature/fi
...
feature/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f85f06555 | ||
|
|
f037f4f46f | ||
|
|
9ddfc24d2f | ||
|
|
8d9a86df64 |
@@ -0,0 +1,56 @@
|
|||||||
|
package com.ticketing.server.global.security;
|
||||||
|
|
||||||
|
import com.ticketing.server.user.domain.UserGrade;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.access.AccessDecisionManager;
|
||||||
|
import org.springframework.security.access.AccessDecisionVoter;
|
||||||
|
import org.springframework.security.access.annotation.Jsr250Voter;
|
||||||
|
import org.springframework.security.access.expression.method.ExpressionBasedPreInvocationAdvice;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
|
||||||
|
import org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter;
|
||||||
|
import org.springframework.security.access.vote.AffirmativeBased;
|
||||||
|
import org.springframework.security.access.vote.AuthenticatedVoter;
|
||||||
|
import org.springframework.security.access.vote.RoleHierarchyVoter;
|
||||||
|
import org.springframework.security.access.vote.RoleVoter;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
|
||||||
|
|
||||||
|
@EnableGlobalMethodSecurity(
|
||||||
|
securedEnabled = true,
|
||||||
|
jsr250Enabled = true,
|
||||||
|
prePostEnabled = true
|
||||||
|
)
|
||||||
|
@Configuration
|
||||||
|
public class RoleConfig extends GlobalMethodSecurityConfiguration {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AccessDecisionManager accessDecisionManager() {
|
||||||
|
List<AccessDecisionVoter<?>> decisionVoters = new ArrayList<>();
|
||||||
|
ExpressionBasedPreInvocationAdvice expressionAdvice = new ExpressionBasedPreInvocationAdvice();
|
||||||
|
expressionAdvice.setExpressionHandler(getExpressionHandler());
|
||||||
|
decisionVoters.add(new PreInvocationAuthorizationAdviceVoter(expressionAdvice));
|
||||||
|
decisionVoters.add(new Jsr250Voter());
|
||||||
|
|
||||||
|
decisionVoters.add(new RoleVoter());
|
||||||
|
decisionVoters.add(roleHierarchyVoter());
|
||||||
|
decisionVoters.add(new AuthenticatedVoter());
|
||||||
|
return new AffirmativeBased(decisionVoters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RoleHierarchyVoter roleHierarchyVoter() {
|
||||||
|
return new RoleHierarchyVoter(roleHierarchy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RoleHierarchy roleHierarchy() {
|
||||||
|
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
|
||||||
|
roleHierarchy.setHierarchy(UserGrade.getRoleHierarchy());
|
||||||
|
return roleHierarchy;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,9 +8,7 @@ import lombok.RequiredArgsConstructor;
|
|||||||
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.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
@@ -19,7 +17,6 @@ import org.springframework.security.crypto.password.PasswordEncoder;
|
|||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@EnableGlobalMethodSecurity(securedEnabled = true)
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@@ -53,9 +50,9 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
|
|
||||||
.and()
|
.and()
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.antMatchers(HttpMethod.POST, "/api/user/login").permitAll()
|
.antMatchers(HttpMethod.POST, "/api/auth/token").permitAll()
|
||||||
.antMatchers(HttpMethod.POST, "/api/user/refresh").permitAll()
|
.antMatchers(HttpMethod.POST, "/api/auth/refresh").permitAll()
|
||||||
.antMatchers(HttpMethod.POST, "/api/user").permitAll()
|
.antMatchers(HttpMethod.POST, "/api/users").permitAll()
|
||||||
.antMatchers("/api/movies/**").permitAll()
|
.antMatchers("/api/movies/**").permitAll()
|
||||||
.antMatchers("/l7check").permitAll()
|
.antMatchers("/l7check").permitAll()
|
||||||
.antMatchers("/actuator/**").permitAll()
|
.antMatchers("/actuator/**").permitAll()
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package com.ticketing.server.global.validator.constraints;
|
||||||
|
|
||||||
|
import com.ticketing.server.global.validator.constraintvalidators.FieldsValueNotMatchValidator;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
import javax.validation.Constraint;
|
||||||
|
import javax.validation.Payload;
|
||||||
|
|
||||||
|
@Constraint(validatedBy = FieldsValueNotMatchValidator.class)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface FieldsValueNotMatch {
|
||||||
|
|
||||||
|
String message();
|
||||||
|
|
||||||
|
String field();
|
||||||
|
|
||||||
|
String fieldMatch();
|
||||||
|
|
||||||
|
Class<?>[] groups() default {};
|
||||||
|
|
||||||
|
Class<? extends Payload>[] payload() default {};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.ticketing.server.global.validator.constraintvalidators;
|
||||||
|
|
||||||
|
import com.ticketing.server.global.validator.constraints.FieldsValueNotMatch;
|
||||||
|
import javax.validation.ConstraintValidator;
|
||||||
|
import javax.validation.ConstraintValidatorContext;
|
||||||
|
import org.springframework.beans.BeanWrapperImpl;
|
||||||
|
|
||||||
|
public class FieldsValueNotMatchValidator implements ConstraintValidator<FieldsValueNotMatch, Object> {
|
||||||
|
|
||||||
|
private String field;
|
||||||
|
private String fieldMatch;
|
||||||
|
|
||||||
|
public void initialize(FieldsValueNotMatch constraintAnnotation) {
|
||||||
|
this.field = constraintAnnotation.field();
|
||||||
|
this.fieldMatch = constraintAnnotation.fieldMatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid(Object value, ConstraintValidatorContext context) {
|
||||||
|
Object fieldValue = new BeanWrapperImpl(value).getPropertyValue(field);
|
||||||
|
Object fieldMatchValue = new BeanWrapperImpl(value).getPropertyValue(fieldMatch);
|
||||||
|
|
||||||
|
if (fieldValue != null) {
|
||||||
|
return !fieldValue.equals(fieldMatchValue);
|
||||||
|
} else {
|
||||||
|
return fieldMatchValue != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.ticketing.server.user.application;
|
||||||
|
|
||||||
|
import com.ticketing.server.user.application.request.LoginRequest;
|
||||||
|
import com.ticketing.server.user.application.response.TokenDto;
|
||||||
|
import com.ticketing.server.user.service.interfaces.AuthenticationService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/api/auth")
|
||||||
|
@Slf4j
|
||||||
|
public class AuthController {
|
||||||
|
|
||||||
|
private final AuthenticationService authenticationService;
|
||||||
|
|
||||||
|
@PostMapping("/token")
|
||||||
|
public ResponseEntity<TokenDto> login(@RequestBody LoginRequest loginRequest) {
|
||||||
|
TokenDto tokenDto = authenticationService.generateTokenDto(loginRequest.toAuthentication());
|
||||||
|
|
||||||
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
|
.headers(getHttpHeaders())
|
||||||
|
.body(tokenDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/refresh")
|
||||||
|
public ResponseEntity<TokenDto> refreshToken(@RequestParam("refreshToken") String refreshToken) {
|
||||||
|
TokenDto tokenDto = authenticationService.reissueTokenDto(refreshToken);
|
||||||
|
|
||||||
|
return ResponseEntity.status(HttpStatus.OK)
|
||||||
|
.headers(getHttpHeaders())
|
||||||
|
.body(tokenDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpHeaders getHttpHeaders() {
|
||||||
|
HttpHeaders httpHeaders = new HttpHeaders();
|
||||||
|
httpHeaders.set(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
|
||||||
|
httpHeaders.set(HttpHeaders.PRAGMA, "no-store");
|
||||||
|
httpHeaders.set(HttpHeaders.EXPIRES, "0");
|
||||||
|
|
||||||
|
return httpHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,19 +1,15 @@
|
|||||||
package com.ticketing.server.user.application;
|
package com.ticketing.server.user.application;
|
||||||
|
|
||||||
import com.ticketing.server.global.security.jwt.JwtProperties;
|
|
||||||
import com.ticketing.server.user.application.request.LoginRequest;
|
|
||||||
import com.ticketing.server.user.application.request.SignUpRequest;
|
import com.ticketing.server.user.application.request.SignUpRequest;
|
||||||
|
import com.ticketing.server.user.application.request.UserChangePasswordRequest;
|
||||||
import com.ticketing.server.user.application.request.UserDeleteRequest;
|
import com.ticketing.server.user.application.request.UserDeleteRequest;
|
||||||
import com.ticketing.server.user.application.request.UserModifyPasswordRequest;
|
|
||||||
import com.ticketing.server.user.application.response.SignUpResponse;
|
import com.ticketing.server.user.application.response.SignUpResponse;
|
||||||
import com.ticketing.server.user.application.response.TokenDto;
|
|
||||||
import com.ticketing.server.user.application.response.UserChangePasswordResponse;
|
import com.ticketing.server.user.application.response.UserChangePasswordResponse;
|
||||||
import com.ticketing.server.user.application.response.UserDeleteResponse;
|
import com.ticketing.server.user.application.response.UserDeleteResponse;
|
||||||
import com.ticketing.server.user.application.response.UserDetailResponse;
|
import com.ticketing.server.user.application.response.UserDetailResponse;
|
||||||
import com.ticketing.server.user.domain.User;
|
import com.ticketing.server.user.domain.User;
|
||||||
|
import com.ticketing.server.user.domain.UserGrade;
|
||||||
import com.ticketing.server.user.service.UserServiceImpl;
|
import com.ticketing.server.user.service.UserServiceImpl;
|
||||||
import com.ticketing.server.user.service.interfaces.AuthenticationService;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -29,19 +25,16 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@RequestMapping("/api/user")
|
@RequestMapping("/api/users")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class UserController {
|
public class UserController {
|
||||||
|
|
||||||
private final UserServiceImpl userService;
|
private final UserServiceImpl userService;
|
||||||
private final AuthenticationService authenticationService;
|
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
private final JwtProperties jwtProperties;
|
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ResponseEntity<SignUpResponse> register(@RequestBody @Valid SignUpRequest request) {
|
public ResponseEntity<SignUpResponse> register(@RequestBody @Valid SignUpRequest request) {
|
||||||
@@ -49,48 +42,27 @@ public class UserController {
|
|||||||
return ResponseEntity.status(HttpStatus.CREATED).body(SignUpResponse.from(user));
|
return ResponseEntity.status(HttpStatus.CREATED).body(SignUpResponse.from(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/info")
|
@GetMapping("/details")
|
||||||
@Secured("ROLE_GUEST")
|
@Secured("ROLE_GUEST")
|
||||||
public ResponseEntity<UserDetailResponse> myInfo(@AuthenticationPrincipal UserDetails userRequest) {
|
public ResponseEntity<UserDetailResponse> details(@AuthenticationPrincipal UserDetails userRequest) {
|
||||||
User user = userService.findByEmail(userRequest.getUsername());
|
User user = userService.findByEmail(userRequest.getUsername());
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(UserDetailResponse.from(user));
|
return ResponseEntity.status(HttpStatus.OK).body(UserDetailResponse.from(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
@Secured("ROLE_GUEST")
|
@Secured(UserGrade.ROLES.GUEST)
|
||||||
public ResponseEntity<UserDeleteResponse> deleteUser(@RequestBody @Valid UserDeleteRequest request) {
|
public ResponseEntity<UserDeleteResponse> deleteUser(@RequestBody @Valid UserDeleteRequest request) {
|
||||||
User user = userService.delete(request.toDeleteUserDto(passwordEncoder));
|
User user = userService.delete(request.toDeleteUserDto(passwordEncoder));
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(UserDeleteResponse.from(user));
|
return ResponseEntity.status(HttpStatus.OK).body(UserDeleteResponse.from(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/password")
|
@PutMapping("/password")
|
||||||
@Secured("ROLE_GUEST")
|
@Secured(UserGrade.ROLES.GUEST)
|
||||||
public ResponseEntity<UserChangePasswordResponse> changePassword(@RequestBody @Valid UserModifyPasswordRequest request) {
|
public ResponseEntity<UserChangePasswordResponse> changePassword(
|
||||||
if (request.oldEqualNew()) {
|
@AuthenticationPrincipal UserDetails userRequest,
|
||||||
log.error("기존 패스워드와 동일한 패스워드로 변경할 수 없습니다.");
|
@RequestBody @Valid UserChangePasswordRequest request) {
|
||||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
|
User user = userService.changePassword(request.toChangePasswordDto(userRequest.getUsername(), passwordEncoder));
|
||||||
}
|
|
||||||
|
|
||||||
User user = userService.changePassword(request.toChangePasswordDto(passwordEncoder));
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(UserChangePasswordResponse.from(user));
|
return ResponseEntity.status(HttpStatus.OK).body(UserChangePasswordResponse.from(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/login")
|
|
||||||
public ResponseEntity<TokenDto> login(@RequestBody LoginRequest loginRequest, HttpServletResponse response) {
|
|
||||||
TokenDto tokenDto = authenticationService.login(loginRequest.toAuthentication());
|
|
||||||
|
|
||||||
response.setHeader("Cache-Control", "no-store");
|
|
||||||
response.setHeader("Pragma", "no-store");
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(tokenDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/refresh")
|
|
||||||
public ResponseEntity<TokenDto> refreshToken(@RequestParam("refreshToken") String refreshToken, HttpServletResponse response) {
|
|
||||||
TokenDto tokenDto = authenticationService.reissueAccessToken(refreshToken);
|
|
||||||
|
|
||||||
response.setHeader(jwtProperties.getAccessHeader(), tokenDto.getAccessToken());
|
|
||||||
response.setHeader(jwtProperties.getRefreshHeader(), tokenDto.getRefreshToken());
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).body(tokenDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.ticketing.server.user.application.request;
|
package com.ticketing.server.user.application.request;
|
||||||
|
|
||||||
|
import com.ticketing.server.global.validator.constraints.FieldsValueNotMatch;
|
||||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||||
import javax.validation.constraints.Email;
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
import javax.validation.constraints.NotEmpty;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@@ -11,11 +11,12 @@ import org.springframework.security.crypto.password.PasswordEncoder;
|
|||||||
@Getter
|
@Getter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class UserModifyPasswordRequest {
|
@FieldsValueNotMatch(
|
||||||
|
field = "oldPassword",
|
||||||
@NotEmpty(message = "{validation.not.empty.email}")
|
fieldMatch = "newPassword",
|
||||||
@Email(message = "{validation.email}")
|
message = "{validation.password.not.change}"
|
||||||
private String email;
|
)
|
||||||
|
public class UserChangePasswordRequest {
|
||||||
|
|
||||||
@NotEmpty(message = "{validation.not.empty.oldpassword}")
|
@NotEmpty(message = "{validation.not.empty.oldpassword}")
|
||||||
private String oldPassword;
|
private String oldPassword;
|
||||||
@@ -23,12 +24,8 @@ public class UserModifyPasswordRequest {
|
|||||||
@NotEmpty(message = "{validation.not.empty.newpassword}")
|
@NotEmpty(message = "{validation.not.empty.newpassword}")
|
||||||
private String newPassword;
|
private String newPassword;
|
||||||
|
|
||||||
public ChangePasswordDTO toChangePasswordDto(PasswordEncoder passwordEncoder) {
|
public ChangePasswordDTO toChangePasswordDto(String email, PasswordEncoder passwordEncoder) {
|
||||||
return new ChangePasswordDTO(email, oldPassword, newPassword, passwordEncoder);
|
return new ChangePasswordDTO(email, oldPassword, newPassword, passwordEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean oldEqualNew() {
|
|
||||||
return oldPassword.equals(newPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -23,14 +23,6 @@ import lombok.NoArgsConstructor;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class User extends AbstractEntity {
|
public class User extends AbstractEntity {
|
||||||
|
|
||||||
public User(String name, String email, String password, UserGrade grade, String phone) {
|
|
||||||
this.name = name;
|
|
||||||
this.email = email;
|
|
||||||
this.password = password;
|
|
||||||
this.grade = grade;
|
|
||||||
this.phone = phone;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Column(name = "name")
|
@Column(name = "name")
|
||||||
@NotEmpty(message = "{validation.not.empty.name}")
|
@NotEmpty(message = "{validation.not.empty.name}")
|
||||||
private String name;
|
private String name;
|
||||||
@@ -58,6 +50,14 @@ public class User extends AbstractEntity {
|
|||||||
|
|
||||||
private LocalDateTime deletedAt;
|
private LocalDateTime deletedAt;
|
||||||
|
|
||||||
|
public User(String name, String email, String password, UserGrade grade, String phone) {
|
||||||
|
this.name = name;
|
||||||
|
this.email = email;
|
||||||
|
this.password = password;
|
||||||
|
this.grade = grade;
|
||||||
|
this.phone = phone;
|
||||||
|
}
|
||||||
|
|
||||||
public User delete(DeleteUserDTO deleteUser) {
|
public User delete(DeleteUserDTO deleteUser) {
|
||||||
if (isDeleted) {
|
if (isDeleted) {
|
||||||
throw new AlreadyDeletedException("이미 탈퇴된 회원 입니다.");
|
throw new AlreadyDeletedException("이미 탈퇴된 회원 입니다.");
|
||||||
|
|||||||
@@ -1,5 +1,38 @@
|
|||||||
package com.ticketing.server.user.domain;
|
package com.ticketing.server.user.domain;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
public enum UserGrade {
|
public enum UserGrade {
|
||||||
GUEST, STAFF
|
ADMIN(ROLES.ADMIN, null),
|
||||||
|
STAFF(ROLES.STAFF, ROLES.ADMIN),
|
||||||
|
GUEST(ROLES.GUEST, ROLES.STAFF);
|
||||||
|
|
||||||
|
private final String roleName;
|
||||||
|
private final String parentName;
|
||||||
|
|
||||||
|
public static class ROLES {
|
||||||
|
|
||||||
|
public static final String ADMIN = "ROLE_ADMIN";
|
||||||
|
public static final String STAFF = "ROLE_STAFF";
|
||||||
|
public static final String GUEST = "ROLE_GUEST";
|
||||||
|
|
||||||
|
private ROLES() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getRoleHierarchy() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
for (UserGrade grade : UserGrade.values()) {
|
||||||
|
if (grade.parentName != null) {
|
||||||
|
sb.append(grade.parentName);
|
||||||
|
sb.append(" > ");
|
||||||
|
sb.append(grade.roleName);
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public TokenDto login(UsernamePasswordAuthenticationToken authenticationToken) {
|
public TokenDto generateTokenDto(UsernamePasswordAuthenticationToken authenticationToken) {
|
||||||
// 회원인증
|
// 회원인증
|
||||||
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
|
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public TokenDto reissueAccessToken(String bearerRefreshToken) {
|
public TokenDto reissueTokenDto(String bearerRefreshToken) {
|
||||||
String refreshToken = resolveToken(bearerRefreshToken);
|
String refreshToken = resolveToken(bearerRefreshToken);
|
||||||
|
|
||||||
// 토큰 검증
|
// 토큰 검증
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.ticketing.server.global.security.service;
|
package com.ticketing.server.user.service;
|
||||||
|
|
||||||
import com.ticketing.server.user.domain.User;
|
import com.ticketing.server.user.domain.User;
|
||||||
import com.ticketing.server.user.domain.repository.UserRepository;
|
import com.ticketing.server.user.domain.repository.UserRepository;
|
||||||
@@ -5,8 +5,8 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio
|
|||||||
|
|
||||||
public interface AuthenticationService {
|
public interface AuthenticationService {
|
||||||
|
|
||||||
TokenDto login(UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken);
|
TokenDto generateTokenDto(UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken);
|
||||||
|
|
||||||
TokenDto reissueAccessToken(String bearerRefreshToken);
|
TokenDto reissueTokenDto(String bearerRefreshToken);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ validation.not.empty.grade="\uC0AC\uC6A9\uC790 \uB4F1\uAE09\uC740 \uD544\uC218 \
|
|||||||
validation.not.empty.phone="\uD734\uB300\uBC88\uD638\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.phone="\uD734\uB300\uBC88\uD638\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||||
validation.email="\uC774\uBA54\uC77C\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
validation.email="\uC774\uBA54\uC77C\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
||||||
validation.phone="\uD734\uB300\uBC88\uD638\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
validation.phone="\uD734\uB300\uBC88\uD638\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
||||||
|
validation.password.not.change="\uB3D9\uC77C\uD55C \uD328\uC2A4\uC6CC\uB4DC\uB85C \uBCC0\uACBD\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ validation.not.empty.grade="user grade is required."
|
|||||||
validation.not.empty.phone="phone is required."
|
validation.not.empty.phone="phone is required."
|
||||||
validation.email="email is not valid."
|
validation.email="email is not valid."
|
||||||
validation.phone="phone is not valid."
|
validation.phone="phone is not valid."
|
||||||
|
validation.password.not.change="password not change."
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ validation.not.empty.grade="\uC0AC\uC6A9\uC790 \uB4F1\uAE09\uC740 \uD544\uC218 \
|
|||||||
validation.not.empty.phone="\uD734\uB300\uBC88\uD638\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.phone="\uD734\uB300\uBC88\uD638\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||||
validation.email="\uC774\uBA54\uC77C\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
validation.email="\uC774\uBA54\uC77C\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
||||||
validation.phone="\uD734\uB300\uBC88\uD638\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
validation.phone="\uD734\uB300\uBC88\uD638\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
||||||
|
validation.password.not.change="\uB3D9\uC77C\uD55C \uD328\uC2A4\uC6CC\uB4DC\uB85C \uBCC0\uACBD\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
||||||
|
|||||||
@@ -27,7 +27,10 @@ import org.springframework.web.context.WebApplicationContext;
|
|||||||
|
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
@Transactional
|
@Transactional
|
||||||
class UserControllerTest {
|
class AuthControllerTest {
|
||||||
|
|
||||||
|
private static final String LOGIN_URL = "/api/auth/token";
|
||||||
|
private static final String REGISTER_URL = "/api/users";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
WebApplicationContext context;
|
WebApplicationContext context;
|
||||||
@@ -53,7 +56,7 @@ class UserControllerTest {
|
|||||||
LoginRequest request = new LoginRequest("ticketing@gmail.com", "qwe123");
|
LoginRequest request = new LoginRequest("ticketing@gmail.com", "qwe123");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
ResultActions actions = mvc.perform(post("/api/user/login")
|
ResultActions actions = mvc.perform(post(LOGIN_URL)
|
||||||
.content(asJsonString(request))
|
.content(asJsonString(request))
|
||||||
.contentType(MediaType.APPLICATION_JSON));
|
.contentType(MediaType.APPLICATION_JSON));
|
||||||
|
|
||||||
@@ -69,7 +72,7 @@ class UserControllerTest {
|
|||||||
LoginRequest request = new LoginRequest("ticketing@gmail.com", "qwe1234");
|
LoginRequest request = new LoginRequest("ticketing@gmail.com", "qwe1234");
|
||||||
|
|
||||||
// when
|
// when
|
||||||
ResultActions actions = mvc.perform(post("/api/user/login")
|
ResultActions actions = mvc.perform(post(LOGIN_URL)
|
||||||
.content(asJsonString(request))
|
.content(asJsonString(request))
|
||||||
.contentType(MediaType.APPLICATION_JSON));
|
.contentType(MediaType.APPLICATION_JSON));
|
||||||
|
|
||||||
@@ -91,7 +94,7 @@ class UserControllerTest {
|
|||||||
|
|
||||||
SignUpRequest signUpRequest = new SignUpRequest("ticketing", "ticketing@gmail.com", "qwe123", "010-2240-7920");
|
SignUpRequest signUpRequest = new SignUpRequest("ticketing", "ticketing@gmail.com", "qwe123", "010-2240-7920");
|
||||||
|
|
||||||
mvc.perform(post("/api/user")
|
mvc.perform(post(REGISTER_URL)
|
||||||
.content(asJsonString(signUpRequest))
|
.content(asJsonString(signUpRequest))
|
||||||
.contentType(MediaType.APPLICATION_JSON));
|
.contentType(MediaType.APPLICATION_JSON));
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,7 @@ class AuthenticationServiceImplTest {
|
|||||||
when(jwtProperties.hasTokenStartsWith(refreshToken)).thenReturn(true);
|
when(jwtProperties.hasTokenStartsWith(refreshToken)).thenReturn(true);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
TokenDto tokenDto = authenticationService.reissueAccessToken(refreshToken);
|
TokenDto tokenDto = authenticationService.reissueTokenDto(refreshToken);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertAll(
|
assertAll(
|
||||||
|
|||||||
Reference in New Issue
Block a user