Skip to content

Commit

Permalink
[NAYB-155] refactor: auth 패키지 리팩토링
Browse files Browse the repository at this point in the history
[NAYB-155] refactor: auth 패키지 리팩토링
  • Loading branch information
hseong3243 authored Sep 20, 2023
2 parents dcbc3ff + ddf1685 commit ea6e3d0
Show file tree
Hide file tree
Showing 27 changed files with 237 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.prgrms.nabmart.domain.delivery.Rider;
import com.prgrms.nabmart.domain.delivery.exception.NotFoundDeliveryException;
import com.prgrms.nabmart.domain.delivery.exception.NotFoundRiderException;
import com.prgrms.nabmart.domain.delivery.exception.UnauthorizedDeliveryException;
import com.prgrms.nabmart.domain.delivery.repository.DeliveryRepository;
import com.prgrms.nabmart.domain.delivery.repository.RiderRepository;
import com.prgrms.nabmart.domain.delivery.service.request.AcceptDeliveryCommand;
Expand All @@ -18,7 +19,6 @@
import com.prgrms.nabmart.domain.user.User;
import com.prgrms.nabmart.domain.user.exception.NotFoundUserException;
import com.prgrms.nabmart.domain.user.repository.UserRepository;
import com.prgrms.nabmart.global.auth.exception.AuthorizationException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
Expand All @@ -42,7 +42,7 @@ public FindDeliveryDetailResponse findDelivery(FindDeliveryCommand findDeliveryC

private void checkAuthority(final Delivery delivery, final User user) {
if (!delivery.isOwnByUser(user)) {
throw new AuthorizationException("권한이 없습니다.");
throw new UnauthorizedDeliveryException("권한이 없습니다.");
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.prgrms.nabmart.domain.item.exception;

public class UnauthorizedLikeItemException extends ItemException {

public UnauthorizedLikeItemException(final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.prgrms.nabmart.domain.item.exception.DuplicateLikeItemException;
import com.prgrms.nabmart.domain.item.exception.NotFoundItemException;
import com.prgrms.nabmart.domain.item.exception.NotFoundLikeItemException;
import com.prgrms.nabmart.domain.item.exception.UnauthorizedLikeItemException;
import com.prgrms.nabmart.domain.item.repository.ItemRepository;
import com.prgrms.nabmart.domain.item.repository.LikeItemRepository;
import com.prgrms.nabmart.domain.item.service.request.DeleteLikeItemCommand;
Expand All @@ -14,7 +15,6 @@
import com.prgrms.nabmart.domain.user.User;
import com.prgrms.nabmart.domain.user.exception.NotFoundUserException;
import com.prgrms.nabmart.domain.user.repository.UserRepository;
import com.prgrms.nabmart.global.auth.exception.AuthorizationException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -42,7 +42,7 @@ public Long registerLikeItem(RegisterLikeItemCommand registerLikeItemCommand) {
public void deleteLikeItem(DeleteLikeItemCommand deleteLikeItemCommand) {
LikeItem likeItem = findLikeItemByLikeItemId(deleteLikeItemCommand);
if (!likeItem.isSameUser(deleteLikeItemCommand.userId())) {
throw new AuthorizationException("권한이 없습니다.");
throw new UnauthorizedLikeItemException("권한이 없습니다.");
}
likeItemRepository.delete(likeItem);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.prgrms.nabmart.global.auth.controller;

import com.prgrms.nabmart.global.auth.exception.AuthException;
import com.prgrms.nabmart.global.auth.exception.DuplicateUsernameException;
import com.prgrms.nabmart.global.auth.exception.InvalidJwtException;
import com.prgrms.nabmart.global.auth.exception.OAuthUnlinkFailureException;
import com.prgrms.nabmart.global.auth.exception.UnAuthenticationException;
import com.prgrms.nabmart.global.util.ErrorTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class AuthControllerAdvice {

@ExceptionHandler(AuthException.class)
public ResponseEntity<ErrorTemplate> authExHandle(AuthException ex) {
return ResponseEntity.badRequest()
.body(ErrorTemplate.of(ex.getMessage()));
}

@ExceptionHandler({OAuthUnlinkFailureException.class, UnAuthenticationException.class,
InvalidJwtException.class})
public ResponseEntity<ErrorTemplate> authenticationFailExHandle(AuthException ex) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
.body(ErrorTemplate.of(ex.getMessage()));
}

@ExceptionHandler(DuplicateUsernameException.class)
public ResponseEntity<ErrorTemplate> duplicateUsernameExHandle(AuthException ex) {
return ResponseEntity.status(HttpStatus.CONFLICT)
.body(ErrorTemplate.of(ex.getMessage()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import com.prgrms.nabmart.global.auth.controller.request.SignupRiderRequest;
import com.prgrms.nabmart.global.auth.service.request.SignupRiderCommand;
import com.prgrms.nabmart.global.auth.controller.request.RiderLoginRequest;
import com.prgrms.nabmart.global.auth.controller.request.LoginRiderRequest;
import com.prgrms.nabmart.global.auth.service.RiderAuthenticationService;
import com.prgrms.nabmart.global.auth.service.request.RiderLoginCommand;
import com.prgrms.nabmart.global.auth.service.request.LoginRiderCommand;
import com.prgrms.nabmart.global.auth.service.response.RiderLoginResponse;
import jakarta.validation.Valid;
import java.net.URI;
Expand Down Expand Up @@ -37,11 +37,11 @@ public ResponseEntity<Void> signupRider(@RequestBody @Valid SignupRiderRequest s

@PostMapping("/riders/login")
public ResponseEntity<RiderLoginResponse> riderLogin(
@RequestBody @Valid RiderLoginRequest riderLoginRequest) {
RiderLoginCommand riderLoginCommand
= RiderLoginCommand.of(riderLoginRequest.username(), riderLoginRequest.password());
@RequestBody @Valid LoginRiderRequest loginRiderRequest) {
LoginRiderCommand loginRiderCommand
= LoginRiderCommand.of(loginRiderRequest.username(), loginRiderRequest.password());
RiderLoginResponse riderLoginResponse
= riderAuthenticationService.riderLogin(riderLoginCommand);
= riderAuthenticationService.loginRider(loginRiderCommand);
return ResponseEntity.ok(riderLoginResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;

public record RiderLoginRequest(
public record LoginRiderRequest(
@NotNull(message = "사용자 이름은 필수 입니다.")
@Pattern(regexp = "^(?=.*[a-z])[a-z0-9]{6,20}$",
message = "사용자 이름은 영어 소문자 또는 영어 소문자와 숫자 6자 이상, 20자 이하로 구성 되어야 합니다.")
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ public Claims validateToken(final String accessToken) {
log.info("SignatureVerificationException: 토큰의 서명이 유효하지 않습니다.");
} catch (TokenExpiredException ex) {
log.info("TokenExpiredException: 토큰이 만료되었습니다.");
} catch (MissingClaimException ex) {
log.info("MissingClaimException: 유효값이 클레임이 포함되어 있지 않습니다.");
} catch (JWTVerificationException ex) {
log.info("JWTVerificationException: 유효하지 않은 토큰입니다.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.prgrms.nabmart.global.auth.oauth.handler;
package com.prgrms.nabmart.global.auth.oauth;

import com.prgrms.nabmart.global.auth.exception.InvalidProviderException;
import com.prgrms.nabmart.global.auth.oauth.client.KakaoMessageProvider;
Expand All @@ -20,21 +20,8 @@
@Getter
@RequiredArgsConstructor
public enum OAuthProvider {
KAKAO("kakao", attributes -> {
Map<String, String> properties = (Map<String, String>) attributes.get("properties");
String oAuthUserId = String.valueOf(attributes.get("id"));
String nickname = properties.get("nickname");
Map<String, Object> kakaoAccount = (Map<String, Object>) attributes.get("kakao_account");
String email = String.valueOf(kakaoAccount.get("email"));
return new OAuthUserInfo(oAuthUserId, nickname, email);
}, new KakaoMessageProvider()),
NAVER("naver", attributes -> {
Map<String, String> response = (Map<String, String>) attributes.get("response");
String oAuthUserId = response.get("id");
String nickname = response.get("nickname");
String email = response.get("email");
return new OAuthUserInfo(oAuthUserId, nickname, email);
}, new NaverMessageProvider());
KAKAO("kakao", OAuthProvider::extractKakaoUserInfo, new KakaoMessageProvider()),
NAVER("naver", OAuthProvider::extractNaverUserInfo, new NaverMessageProvider());

private static final Map<String, OAuthProvider> PROVIDERS =
Collections.unmodifiableMap(Stream.of(values())
Expand All @@ -44,6 +31,23 @@ public enum OAuthProvider {
private final Function<Map<String, Object>, OAuthUserInfo> extractUserInfo;
private final OAuthHttpMessageProvider oAuthHttpMessageProvider;

private static OAuthUserInfo extractNaverUserInfo(Map<String, Object> attributes) {
Map<String, String> response = (Map<String, String>) attributes.get("response");
String oAuthUserId = response.get("id");
String nickname = response.get("nickname");
String email = response.get("email");
return new OAuthUserInfo(oAuthUserId, nickname, email);
}

private static OAuthUserInfo extractKakaoUserInfo(Map<String, Object> attributes) {
Map<String, String> properties = (Map<String, String>) attributes.get("properties");
String oAuthUserId = String.valueOf(attributes.get("id"));
String nickname = properties.get("nickname");
Map<String, Object> kakaoAccount = (Map<String, Object>) attributes.get("kakao_account");
String email = String.valueOf(kakaoAccount.get("email"));
return new OAuthUserInfo(oAuthUserId, nickname, email);
}

public static OAuthProvider getOAuthProvider(final String provider) {
OAuthProvider oAuthProvider = PROVIDERS.get(provider);
return Optional.ofNullable(oAuthProvider)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.prgrms.nabmart.global.auth.oauth.client;

import static com.prgrms.nabmart.global.auth.oauth.constant.OAuthConstant.*;
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
import static org.springframework.http.HttpHeaders.CONTENT_TYPE;

import com.prgrms.nabmart.domain.user.service.response.FindUserDetailResponse;
import com.prgrms.nabmart.global.auth.exception.OAuthUnlinkFailureException;
import com.prgrms.nabmart.global.auth.oauth.dto.OAuthHttpMessage;
Expand All @@ -8,7 +12,6 @@
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
Expand All @@ -19,32 +22,17 @@
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

@RequiredArgsConstructor
public class KakaoMessageProvider implements OAuthHttpMessageProvider {

private static final String UNLINK_URI = "https://kapi.kakao.com/v1/user/unlink";
private static final String ACCESS_TOKEN_REFRESH_URI = "https://kauth.kakao.com/oauth/token";
private static final String CONTENT_TYPE = "Content-Type";
private static final String AUTHORIZATION = "Authorization";
private static final String TARGET_ID_TYPE = "target_id_type";
private static final String USER_ID = "user_id";
private static final String TARGET_ID = "target_id";
private static final String ID = "id";
private static final String APPLICATION_X_WWW_FORM_URLENCODED_CHARSET_UTF_8
= "application/x-www-form-urlencoded;charset=utf-8";
private static final String GRANT_TYPE = "grant_type";
private static final String REFRESH_TOKEN = "refresh_token";
private static final String CLIENT_ID = "client_id";
private static final String CLIENT_SECRET = "client_secret";
private static final String ACCESS_TOKEN = "access_token";
private static final String EXPIRES_IN = "expires_in";

@Override
public OAuthHttpMessage createUserUnlinkRequest(
public OAuthHttpMessage createUnlinkUserRequest(
final FindUserDetailResponse userDetailResponse,
final OAuth2AuthorizedClient authorizedClient) {
String accessToken = getAccessToken(authorizedClient);
HttpEntity<MultiValueMap<String, String>> unlinkHttpMeesage = createUnlinkOAuthUserMessage(
HttpEntity<MultiValueMap<String, String>> unlinkHttpMeesage = createUnlinkUserMessage(
userDetailResponse, accessToken);
return new OAuthHttpMessage(UNLINK_URI, unlinkHttpMeesage, new HashMap<>());
}
Expand All @@ -53,11 +41,12 @@ private String getAccessToken(final OAuth2AuthorizedClient authorizedClient) {
return authorizedClient.getAccessToken().getTokenValue();
}

private HttpEntity<MultiValueMap<String, String>> createUnlinkOAuthUserMessage(
private HttpEntity<MultiValueMap<String, String>> createUnlinkUserMessage(
final FindUserDetailResponse userDetailResponse,
final String accessToken) {
HttpHeaders headers = createHeader(accessToken);
MultiValueMap<String, String> multiValueMap = createUnlinkMessageBody(userDetailResponse);
MultiValueMap<String, String> multiValueMap
= createUnlinkUserMessageBody(userDetailResponse);
return new HttpEntity<>(multiValueMap, headers);
}

Expand All @@ -68,7 +57,7 @@ private HttpHeaders createHeader(final String accessToken) {
return headers;
}

private MultiValueMap<String, String> createUnlinkMessageBody(
private MultiValueMap<String, String> createUnlinkUserMessageBody(
final FindUserDetailResponse userDetailResponse) {
MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>();
multiValueMap.add(TARGET_ID_TYPE, USER_ID);
Expand All @@ -77,13 +66,14 @@ private MultiValueMap<String, String> createUnlinkMessageBody(
}

@Override
public void checkSuccessUnlinkRequest(Map<String, Object> unlinkResponse) {
public void verifySuccessUnlinkUserRequest(Map<String, Object> unlinkResponse) {
Optional.ofNullable(unlinkResponse.get(ID))
.orElseThrow(() -> new OAuthUnlinkFailureException("소셜 로그인 연동 해제가 실패하였습니다."));
}

@Override
public OAuthHttpMessage createRefreshAccessTokenRequest(OAuth2AuthorizedClient authorizedClient) {
public OAuthHttpMessage createRefreshAccessTokenRequest(
OAuth2AuthorizedClient authorizedClient) {
return new OAuthHttpMessage(
ACCESS_TOKEN_REFRESH_URI,
createRefreshAccessTokenMessage(authorizedClient),
Expand Down
Loading

0 comments on commit ea6e3d0

Please sign in to comment.