Compare commits

...

1 Commits

Author SHA1 Message Date
dongHyo
acbaf0232b feat: 권한변경 API 구현 2022-07-12 14:51:24 +09:00
9 changed files with 134 additions and 5 deletions

View File

@@ -17,6 +17,7 @@ public enum ErrorCode {
MISMATCH_PASSWORD(BAD_REQUEST, "비밀번호가 일치하지 않습니다."),
TOKEN_TYPE(BAD_REQUEST, "토큰 타입이 올바르지 않습니다."),
UNAVAILABLE_REFRESH_TOKEN(BAD_REQUEST, "사용할 수 없는 토큰 입니다."),
UNABLE_CHANGE_GRADE(BAD_REQUEST, "동일한 등급으로 변경할 수 없습니다."),
/* 403 FORBIDDEN : 접근 권한 제한 */
VALID_USER_ID(FORBIDDEN, "해당 정보에 접근 권한이 존재하지 않습니다."),
@@ -50,6 +51,10 @@ public enum ErrorCode {
throw new TicketingException(UNAVAILABLE_REFRESH_TOKEN);
}
public static TicketingException throwUnableChangeGrade() {
throw new TicketingException(UNABLE_CHANGE_GRADE);
}
/* 403 FORBIDDEN : 접근 권한 제한 */
public static TicketingException throwValidUserId() {
throw new TicketingException(VALID_USER_ID);

View File

@@ -0,0 +1,17 @@
package com.ticketing.server.user.application;
import com.ticketing.server.user.domain.UserGrade;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class UserChangeGradeResponse {
private String email;
private UserGrade beforeGrade;
private UserGrade afterGrade;
}

View File

@@ -1,6 +1,10 @@
package com.ticketing.server.user.application;
import static com.ticketing.server.user.domain.UserGrade.ROLES.ADMIN;
import static com.ticketing.server.user.domain.UserGrade.ROLES.USER;
import com.ticketing.server.user.application.request.SignUpRequest;
import com.ticketing.server.user.application.request.UserChangeGradeRequest;
import com.ticketing.server.user.application.request.UserChangePasswordRequest;
import com.ticketing.server.user.application.request.UserDeleteRequest;
import com.ticketing.server.user.application.response.PaymentsResponse;
@@ -8,8 +12,8 @@ import com.ticketing.server.user.application.response.SignUpResponse;
import com.ticketing.server.user.application.response.UserChangePasswordResponse;
import com.ticketing.server.user.application.response.UserDeleteResponse;
import com.ticketing.server.user.application.response.UserDetailResponse;
import com.ticketing.server.user.domain.ChangeGradeDTO;
import com.ticketing.server.user.domain.User;
import com.ticketing.server.user.domain.UserGrade;
import com.ticketing.server.user.service.dto.UserDetailDTO;
import com.ticketing.server.user.service.interfaces.UserApisService;
import com.ticketing.server.user.service.interfaces.UserService;
@@ -47,21 +51,21 @@ public class UserController {
}
@GetMapping("/details")
@Secured(UserGrade.ROLES.USER)
@Secured(USER)
public ResponseEntity<UserDetailResponse> details(@AuthenticationPrincipal UserDetails userRequest) {
UserDetailDTO userDetail = userService.findDetailByEmail(userRequest.getUsername());
return ResponseEntity.status(HttpStatus.OK).body(userDetail.toResponse());
}
@DeleteMapping
@Secured(UserGrade.ROLES.USER)
@Secured(USER)
public ResponseEntity<UserDeleteResponse> deleteUser(@RequestBody @Valid UserDeleteRequest request) {
User user = userService.delete(request.toDeleteUserDto(passwordEncoder));
return ResponseEntity.status(HttpStatus.OK).body(UserDeleteResponse.from(user));
}
@PutMapping("/password")
@Secured(UserGrade.ROLES.USER)
@Secured(USER)
public ResponseEntity<UserChangePasswordResponse> changePassword(
@AuthenticationPrincipal UserDetails userRequest,
@RequestBody @Valid UserChangePasswordRequest request) {
@@ -69,8 +73,15 @@ public class UserController {
return ResponseEntity.status(HttpStatus.OK).body(UserChangePasswordResponse.from(user));
}
@PostMapping("/grade")
@Secured(ADMIN)
public ResponseEntity<UserChangeGradeResponse> changeGrade(@RequestBody @Valid UserChangeGradeRequest request) {
ChangeGradeDTO changeGradeDto = userService.changeGrade(request.getEmail(), request.getAfterGrade());
return ResponseEntity.status(HttpStatus.OK).body(changeGradeDto.toResponse());
}
@GetMapping("/payments")
@Secured(UserGrade.ROLES.USER)
@Secured(USER)
public ResponseEntity<PaymentsResponse> getPayments(@AuthenticationPrincipal UserDetails userRequest) {
PaymentsResponse paymentDetails = userApisService.findPaymentsByEmail(userRequest.getUsername());
return ResponseEntity.status(HttpStatus.OK).body(paymentDetails);

View File

@@ -0,0 +1,19 @@
package com.ticketing.server.user.application.request;
import com.ticketing.server.user.domain.UserGrade;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import lombok.Getter;
@Getter
public class UserChangeGradeRequest {
@NotEmpty(message = "{validation.not.empty.email}")
@Email(message = "{validation.email}")
private String email;
@NotNull(message = "{validation.not.null.grade}")
private UserGrade afterGrade;
}

View File

@@ -0,0 +1,19 @@
package com.ticketing.server.user.domain;
import com.ticketing.server.user.application.UserChangeGradeResponse;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class ChangeGradeDTO {
private final String email;
private final UserGrade beforeGrade;
private final UserGrade afterGrade;
public UserChangeGradeResponse toResponse() {
return new UserChangeGradeResponse(email, beforeGrade, afterGrade);
}
}

View File

@@ -93,4 +93,14 @@ public class User extends AbstractEntity {
}
}
public ChangeGradeDTO changeGrade(UserGrade afterGrade) {
if (grade.equals(afterGrade)) {
throw ErrorCode.throwUnableChangeGrade();
}
final UserGrade beforeGrade = this.grade;
this.grade = afterGrade;
return new ChangeGradeDTO(email, beforeGrade, afterGrade);
}
}

View File

@@ -1,8 +1,10 @@
package com.ticketing.server.user.service;
import com.ticketing.server.global.exception.ErrorCode;
import com.ticketing.server.user.domain.ChangeGradeDTO;
import com.ticketing.server.user.domain.SequenceGenerator;
import com.ticketing.server.user.domain.User;
import com.ticketing.server.user.domain.UserGrade;
import com.ticketing.server.user.domain.repository.UserRepository;
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
import com.ticketing.server.user.service.dto.DeleteUserDTO;
@@ -53,6 +55,13 @@ public class UserServiceImpl implements UserService {
return user.changePassword(changePasswordDto);
}
@Override
@Transactional
public ChangeGradeDTO changeGrade(@NotNull String email, @NotNull UserGrade grade) {
User user = findNotDeletedUserByEmail(email);
return user.changeGrade(grade);
}
@Override
public UserDetailDTO findDetailByEmail(@NotNull String email) {
User user = userRepository.findByEmail(email)

View File

@@ -1,12 +1,15 @@
package com.ticketing.server.user.service.interfaces;
import com.ticketing.server.user.domain.ChangeGradeDTO;
import com.ticketing.server.user.domain.User;
import com.ticketing.server.user.domain.UserGrade;
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
import com.ticketing.server.user.service.dto.DeleteUserDTO;
import com.ticketing.server.user.service.dto.SignUpDTO;
import com.ticketing.server.user.service.dto.UserDetailDTO;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.springframework.transaction.annotation.Transactional;
public interface UserService {
@@ -16,6 +19,9 @@ public interface UserService {
User changePassword(@Valid ChangePasswordDTO changePasswordDto);
@Transactional
ChangeGradeDTO changeGrade(@NotNull String email, @NotNull UserGrade grade);
UserDetailDTO findDetailByEmail(@NotNull String email);
User findNotDeletedUserByEmail(@NotNull String email);

View File

@@ -2,7 +2,9 @@ package com.ticketing.server.user.domain;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertAll;
import com.ticketing.server.global.exception.ErrorCode;
import com.ticketing.server.global.exception.TicketingException;
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
import com.ticketing.server.user.service.dto.DeleteUserDTO;
@@ -33,6 +35,37 @@ public class UserTest {
users = provideCorrectUsers().collect(Collectors.toMap(User::getEmail, user -> user));
}
@Test
@DisplayName("동일한 권한으로 변경 시 예외처리")
void changeGradeFail() {
// given
User user = users.get("ticketing1@gmail.com");
// when
// then
assertThatThrownBy(() -> user.changeGrade(UserGrade.USER))
.isInstanceOf(TicketingException.class)
.extracting("errorCode")
.isEqualTo(ErrorCode.UNABLE_CHANGE_GRADE);
}
@Test
@DisplayName("권한 변경 성공")
void changeGradeSuccess() {
// given
User user = users.get("ticketing1@gmail.com");
// when
ChangeGradeDTO changeGradeDto = user.changeGrade(UserGrade.ADMIN);
// then
assertAll(
() -> assertThat(changeGradeDto.getEmail()).isEqualTo("ticketing1@gmail.com"),
() -> assertThat(changeGradeDto.getBeforeGrade()).isEqualTo(UserGrade.USER),
() -> assertThat(changeGradeDto.getAfterGrade()).isEqualTo(UserGrade.ADMIN)
);
}
@ParameterizedTest
@MethodSource("provideDifferentPasswordDeleteUsers")
@DisplayName("입력된 패스워드가 다를 경우")