Skip to content

Commit

Permalink
Merge branch 'feature/backed-issue-319' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
younghoonkwon committed Oct 28, 2021
2 parents ff01c0b + 051e635 commit 4270a0a
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 58 deletions.
7 changes: 5 additions & 2 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ subprojects {
'**/ImageType*',
// domain-cvi-oauth-service
'**/KakaoProfile*',
'**/NaverProfile*'
'**/NaverProfile*',
'**/UserInformation*',
'**/AuthRequest*',
'**/OAuthConfig*'
] + Qdomains)}))
}
finalizedBy 'jacocoTestCoverageVerification'
Expand All @@ -108,7 +111,7 @@ subprojects {
// domain-cvi
"**/Sort.java, **/Filter.java, **/ImageType.java, " +
// domain-cvi-oauth-service
"**/KakaoProfile.java, **/NaverProfile.java"
"**/KakaoProfile.java, **/NaverProfile.java, **/UserInformation.java, **/AuthRequest.java, **/OAuthConfig.java"
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion backend/domain-cvi-oauth-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jacocoTestCoverageVerification { // ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€ ์ธก์ •ํ•ญ๋ชฉ ์‹œํ–‰
limit {
counter = 'METHOD'
value = 'COVEREDRATIO'
minimum = 0.85
minimum = 1.00
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.cvi.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class OAuthConfig {

@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.cvi.exception.MappingFailureException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
Expand All @@ -20,14 +21,15 @@

@Slf4j
@Component
@RequiredArgsConstructor
public class KakaoAuthorization implements Authorization {

private static final String PROFILE_REQUEST_URL = "https://kapi.kakao.com/v2/user/me";
private static final String TOKEN_REQUEST_URL = "https://kauth.kakao.com/oauth/token";
private static final String CALLBACK_URL_SUFFIX = "/auth/kakao/callback";

private final RestTemplate restTemplate = new RestTemplate();
private final ObjectMapper objectMapper = new ObjectMapper();
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;

@Override
public UserInformation requestProfile(String code, String state, String requestOrigin) {
Expand Down Expand Up @@ -93,10 +95,10 @@ public HttpEntity<MultiValueMap<String, String>> createProfileRequest(OAuthToken
@Override
public ResponseEntity<String> sendRequest(HttpEntity<MultiValueMap<String, String>> request, String url) {
return restTemplate.exchange(
url,
HttpMethod.POST,
request,
String.class
url,
HttpMethod.POST,
request,
String.class
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.cvi.exception.MappingFailureException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
Expand All @@ -21,13 +22,14 @@

@Component
@Slf4j
public class NaverAuthorization implements Authorization {
@RequiredArgsConstructor
public class NaverAuthorization implements Authorization {

private static final String PROFILE_REQUEST_URL = "https://openapi.naver.com/v1/nid/me";
private static final String TOKEN_REQUEST_URL = "https://nid.naver.com/oauth2.0/token";

private final RestTemplate restTemplate = new RestTemplate();
private final ObjectMapper objectMapper = new ObjectMapper();
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;

@Value("${security.auth.naver.client-secret}")
private String clientSecret;
Expand Down Expand Up @@ -97,10 +99,10 @@ public HttpEntity<MultiValueMap<String, String>> createProfileRequest(OAuthToken
@Override
public ResponseEntity<String> sendRequest(HttpEntity<MultiValueMap<String, String>> request, String url) {
return restTemplate.exchange(
url,
HttpMethod.POST,
request,
String.class
url,
HttpMethod.POST,
request,
String.class
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.willReturn;
import static org.mockito.Mockito.spy;

Expand All @@ -17,6 +18,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.web.client.RestTemplate;

@DisplayName("Authorization ๋งค๋‹ˆ์ € ๋„๋ฉ”์ธ ํ…Œ์ŠคํŠธ")
class AuthorizationManagerTest {
Expand All @@ -29,13 +31,14 @@ class AuthorizationManagerTest {

private Map<String, Authorization> authorizationMap = new HashMap<>();
private AuthorizationManager authorizationManager = new AuthorizationManager(authorizationMap);
private final ObjectMapper objectMapper = new ObjectMapper();
private final RestTemplate restTemplate = new RestTemplate();

private final Authorization naverAuthorization = spy(new NaverAuthorization(restTemplate, objectMapper));
private final Authorization kakaoAuthorization = spy(new KakaoAuthorization(restTemplate, objectMapper));

private NaverAuthorization naverAuthorization = spy(new NaverAuthorization());
private KakaoAuthorization kakaoAuthorization = spy(new KakaoAuthorization());

private ObjectMapper objectMapper = new ObjectMapper();
private UserInformation naverUserInfo;
private UserInformation kakaoUserInfo;

@BeforeEach
void setUp() throws JsonProcessingException {
Expand All @@ -44,9 +47,6 @@ void setUp() throws JsonProcessingException {

NaverProfile naverProfile = objectMapper.readValue(NAVER_PROFILE_RESPONSE, NaverProfile.class);
naverUserInfo = UserInformation.of(naverProfile);

KakaoProfile kakaoProfile = objectMapper.readValue(KAKAO_PROFILE_RESPONSE, KakaoProfile.class);
kakaoUserInfo = UserInformation.of(kakaoProfile);
}

@DisplayName("Naver Authorization ๋งค๋‹ˆ์ € ์œ ์ € ์ •๋ณด ์š”์ฒญ - ์„ฑ๊ณต")
Expand All @@ -60,25 +60,28 @@ void requestNaverUserInfo() {
assertThat(expected).isEqualTo(naverUserInfo);
}

@DisplayName("Kakao Authorization ๋งค๋‹ˆ์ € ์œ ์ € ์ •๋ณด ์š”์ฒญ - ์„ฑ๊ณต")
@DisplayName("Authorization ๋งค๋‹ˆ์ € ์œ ์ € ์ •๋ณด ์š”์ฒญ - ์‹คํŒจ - Provider๊ฐ€ Null์ธ ๊ฒฝ์šฐ")
@Test
void requestKakaoUserInfo() {
void requestUserInfoFailureWhenNullSocialProvider() {
//given
willReturn(kakaoUserInfo).given(kakaoAuthorization).requestProfile(SOCIAL_CODE, null, REQUEST_ORIGIN);
//when
UserInformation expected = authorizationManager.requestUserInfo(SocialProvider.KAKAO, SOCIAL_CODE, null, REQUEST_ORIGIN);
//then
assertThat(expected).isEqualTo(kakaoUserInfo);
assertThatThrownBy(() -> authorizationManager.requestUserInfo(null, SOCIAL_CODE, STATE, REQUEST_ORIGIN))
.isExactlyInstanceOf(InvalidOperationException.class)
.hasMessage("ํ•ด๋‹น OAuth ์ œ๊ณต์ž๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ์ž…๋ ฅ๊ฐ’: null");
}

@DisplayName("Authorization ๋งค๋‹ˆ์ € ์œ ์ € ์ •๋ณด ์š”์ฒญ - ์‹คํŒจ - Provider๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ - Naver")
@DisplayName("Authorization ๋งค๋‹ˆ์ € ์œ ์ € ์ •๋ณด ์š”์ฒญ - ์‹คํŒจ - Provider๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ")
@Test
void requestUserInfoFailureWhenInvalidSocialProviderNaver() {
void requestUserInfoFailureWhenInvalidSocialProvider() {
//given
//when
authorizationMap = spy(HashMap.class);
authorizationManager = new AuthorizationManager(authorizationMap);
willReturn(false).given(authorizationMap).containsKey(any());
//then
assertThatThrownBy(() -> authorizationManager.requestUserInfo(null, SOCIAL_CODE, STATE, REQUEST_ORIGIN))
.isExactlyInstanceOf(InvalidOperationException.class)
.hasMessage("ํ•ด๋‹น OAuth ์ œ๊ณต์ž๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ์ž…๋ ฅ๊ฐ’: null");
assertThatThrownBy(() -> authorizationManager.requestUserInfo(SocialProvider.KAKAO, SOCIAL_CODE, STATE, REQUEST_ORIGIN))
.isExactlyInstanceOf(InvalidOperationException.class)
.hasMessage("ํ•ด๋‹น OAuth ์ œ๊ณต์ž๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค ์ž…๋ ฅ๊ฐ’: kakaoAuthorization");
}
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
package com.cvi.parser;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.BDDMockito.willReturn;
import static org.mockito.Mockito.spy;

import com.cvi.dto.oauthtoken.KakaoOAuthToken;
import com.cvi.dto.oauthtoken.OAuthToken;
import com.cvi.dto.profile.SocialProfile;
import com.cvi.dto.profile.UserInformation;
import com.cvi.exception.MappingFailureException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.BDDMockito.willReturn;
import static org.mockito.Mockito.spy;

@DisplayName("Kakao Authorization ๋„๋ฉ”์ธ ํ…Œ์ŠคํŠธ")
class KakaoAuthorizationTest {

private static final String TOKEN_RESPONSE = "{\"token_type\":\"bearer\",\"access_token\":\"{ACCESS_TOKEN received from Social Provider}\",\"expires_in\":\"43199\",\"refresh_token\":\"{REFRESH_TOKEN received from Social Provider}\",\"refresh_token_expires_in\":\"25184000\",\"scope\":\"account_email profile\"}";
private static final String PROFILE_RESPONSE = "{\"id\":1816688137,\"connected_at\":\"2021-07-22T05:43:16Z\",\"properties\":{\"nickname\":\"๊น€์˜๋นˆ\"},\"kakao_account\":{\"profile_nickname_needs_agreement\":false,\"profile_image_needs_agreement\":false,\"profile\":{\"nickname\":\"๊น€์˜๋นˆ\",\"thumbnail_image_url\":\"http://k.kakaocdn.net/dn/dpk9l1/btqmGhA2lKL/Oz0wDuJn1YV2DIn92f6DVK/img_110x110.jpg\",\"profile_image_url\":\"http://k.kakaocdn.net/dn/dpk9l1/btqmGhA2lKL/Oz0wDuJn1YV2DIn92f6DVK/img_640x640.jpg\",\"is_default_image\":true}}}";
private static final String TOKEN_REQUEST_URL = "https://kauth.kakao.com/oauth/token";
Expand All @@ -35,22 +37,23 @@ class KakaoAuthorizationTest {
private static final String SCOPE = "account_email profile";
private static final String REQUEST_ORIGIN = "http://localhost:9000";

private KakaoAuthorization kakaoAuthorization = spy(new KakaoAuthorization());
private final RestTemplate restTemplate = spy(RestTemplate.class);
private final ObjectMapper objectMapper = new ObjectMapper();
private final Authorization kakaoAuthorization = new KakaoAuthorization(restTemplate, objectMapper);
private HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest;
private ResponseEntity<String> tokenResponse;
private ResponseEntity<String> profileResponse;
private HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest;

@BeforeEach
void beforeEach() {
kakaoTokenRequest = kakaoAuthorization.createTokenRequest(CODE, null, REQUEST_ORIGIN);
tokenResponse = ResponseEntity.ok(TOKEN_RESPONSE);
profileResponse = ResponseEntity.ok(PROFILE_RESPONSE);

kakaoProfileRequest = kakaoAuthorization.createProfileRequest(kakaoAuthorization.mapToOAuthToken(tokenResponse));
HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest = kakaoAuthorization.createProfileRequest(kakaoAuthorization.mapToOAuthToken(tokenResponse));

willReturn(tokenResponse).given(kakaoAuthorization).sendRequest(kakaoTokenRequest, TOKEN_REQUEST_URL);
willReturn(profileResponse).given(kakaoAuthorization).sendRequest(kakaoProfileRequest, PROFILE_REQUEST_URL);
willReturn(tokenResponse).given(restTemplate).exchange(TOKEN_REQUEST_URL, HttpMethod.POST, kakaoTokenRequest, String.class);
willReturn(profileResponse).given(restTemplate).exchange(PROFILE_REQUEST_URL, HttpMethod.POST, kakaoProfileRequest, String.class);
}

@DisplayName("์นด์นด์˜ค ํ”„๋กœํ•„ ์š”์ฒญ ํ…Œ์ŠคํŠธ - ์„ฑ๊ณต")
Expand Down Expand Up @@ -84,11 +87,11 @@ void requestToken() {
void requestTokenFailure() {
//given
HttpEntity<MultiValueMap<String, String>> invalidToken = kakaoAuthorization.createTokenRequest("INVALID_TOKEN", null, REQUEST_ORIGIN);
willReturn(new ResponseEntity<>("{\"ERROR\":\"ERROR\"}", HttpStatus.BAD_REQUEST)).given(kakaoAuthorization).sendRequest(invalidToken, TOKEN_REQUEST_URL);
willReturn(new ResponseEntity<>("{\"ERROR\":\"ERROR\"}", HttpStatus.BAD_REQUEST)).given(restTemplate).exchange(TOKEN_REQUEST_URL, HttpMethod.POST, invalidToken, String.class);
//when
//then
assertThatThrownBy(() -> kakaoAuthorization.requestToken("INVALID_TOKEN", null, REQUEST_ORIGIN))
.isExactlyInstanceOf(MappingFailureException.class);
.isExactlyInstanceOf(MappingFailureException.class);
}

@DisplayName("ํ† ํฐ ๋งคํ•‘ ํ…Œ์ŠคํŠธ - ์„ฑ๊ณต")
Expand All @@ -113,7 +116,7 @@ void mapToOAuthTokenFailureWhenNotValidTokenResponse() {
//when
//then
assertThatThrownBy(() -> kakaoAuthorization.mapToOAuthToken(ResponseEntity.ok("NOT_VALID_TOKEN")))
.isExactlyInstanceOf(MappingFailureException.class);
.isExactlyInstanceOf(MappingFailureException.class);
}

@DisplayName("ํ”„๋กœํ•„ ์š”์ฒญ ํ…Œ์ŠคํŠธ - ์„ฑ๊ณต")
Expand All @@ -133,11 +136,11 @@ void parseProfileFailure() {
//given
OAuthToken oAuthToken = kakaoAuthorization.mapToOAuthToken(tokenResponse);
HttpEntity<MultiValueMap<String, String>> invalidProfileRequest = kakaoAuthorization.createProfileRequest(oAuthToken);
willReturn(new ResponseEntity<>("{\"ERROR\":\"ERROR\"}", HttpStatus.BAD_REQUEST)).given(kakaoAuthorization).sendRequest(invalidProfileRequest, PROFILE_REQUEST_URL);
willReturn(new ResponseEntity<>("{\"ERROR\":\"ERROR\"}", HttpStatus.BAD_REQUEST)).given(restTemplate).exchange(PROFILE_REQUEST_URL, HttpMethod.POST, invalidProfileRequest, String.class);
//when
//then
assertThatThrownBy(() -> kakaoAuthorization.parseProfile(oAuthToken))
.isExactlyInstanceOf(MappingFailureException.class);
.isExactlyInstanceOf(MappingFailureException.class);
}

@DisplayName("ํ”„๋กœํ•„ ๋งคํ•‘ ํ…Œ์ŠคํŠธ - ์„ฑ๊ณต")
Expand All @@ -158,6 +161,15 @@ void mapToProfileFailureWhenInvalidProfileResponse() {
//when
//then
assertThatThrownBy(() -> kakaoAuthorization.mapToProfile(ResponseEntity.ok("NOT_VALID_PROFILE")))
.isExactlyInstanceOf(MappingFailureException.class);
.isExactlyInstanceOf(MappingFailureException.class);
}

@DisplayName("์™ธ๋ถ€์š”์ฒญ ํ…Œ์ŠคํŠธ - ์„ฑ๊ณต")
@Test
void sendRequest() {
//given
//when
//then
assertThat(kakaoAuthorization.sendRequest(kakaoTokenRequest, TOKEN_REQUEST_URL)).isEqualTo(tokenResponse);
}
}
Loading

0 comments on commit 4270a0a

Please sign in to comment.