From 78b6a257aded381d61a26244570a2ae8cb93d8cb Mon Sep 17 00:00:00 2001 From: hong-sile Date: Thu, 25 Jan 2024 22:13:05 +0900 Subject: [PATCH] =?UTF-8?q?chore:=20=EC=BD=94=EB=93=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=9E=84=EC=8B=9C=20?= =?UTF-8?q?=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #904 --- .../login/application/LoginService.java | 32 ++++++++++++++++++- .../dto/GithubProfileResponse.java | 10 +++++- .../com/emmsale/login/utils/GithubClient.java | 16 +++++++++- .../application/MemberQueryService.java | 11 +++++++ .../login/application/LoginServiceTest.java | 24 ++++++++++++++ .../application/MemberQueryServiceTest.java | 22 +++++++++++++ 6 files changed, 112 insertions(+), 3 deletions(-) diff --git a/backend/emm-sale/src/main/java/com/emmsale/login/application/LoginService.java b/backend/emm-sale/src/main/java/com/emmsale/login/application/LoginService.java index 5714c8c71..a27df661f 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/login/application/LoginService.java +++ b/backend/emm-sale/src/main/java/com/emmsale/login/application/LoginService.java @@ -3,26 +3,36 @@ import com.emmsale.login.application.dto.GithubProfileResponse; import com.emmsale.login.application.dto.MemberQueryResponse; import com.emmsale.login.application.dto.TokenResponse; +import com.emmsale.login.domain.OAuthProfileResponse; +import com.emmsale.login.domain.OAuthProviderComposite; +import com.emmsale.login.domain.OAuthProviderType; import com.emmsale.login.utils.GithubClient; import com.emmsale.login.utils.JwtTokenProvider; import com.emmsale.member.application.MemberQueryService; +import com.emmsale.member.domain.MemberRepository; import org.springframework.stereotype.Service; @Service public class LoginService { + private final OAuthProviderComposite oAuthProviderComposite; private final GithubClient githubClient; private final JwtTokenProvider tokenProvider; private final MemberQueryService memberQueryService; + private final MemberRepository memberRepository; public LoginService( + final OAuthProviderComposite oAuthProviderComposite, final GithubClient githubClient, final JwtTokenProvider tokenProvider, - final MemberQueryService memberQueryService + final MemberQueryService memberQueryService, + final MemberRepository memberRepository ) { + this.oAuthProviderComposite = oAuthProviderComposite; this.githubClient = githubClient; this.tokenProvider = tokenProvider; this.memberQueryService = memberQueryService; + this.memberRepository = memberRepository; } public TokenResponse createTokenByGithub(final String code) { @@ -43,4 +53,24 @@ public TokenResponse createTokenByGithub(final String code) { accessToken ); } + + public TokenResponse createToken(final String code, final String oauthTypeName) { + final OAuthProviderType oAuthProviderType = OAuthProviderType.from(oauthTypeName); + final OAuthProfileResponse profile = oAuthProviderComposite + .getProfileResponse(code, oAuthProviderType); + + final MemberQueryResponse memberQueryResponse = memberQueryService.findOrCreateMemberByOAuthProfileAndType( + profile, oAuthProviderType + ); + + final String accessToken = tokenProvider.createToken( + String.valueOf(memberQueryResponse.getMemberId()) + ); + + return new TokenResponse( + memberQueryResponse.getMemberId(), + memberQueryResponse.isOnboarded(), + accessToken + ); + } } diff --git a/backend/emm-sale/src/main/java/com/emmsale/login/application/dto/GithubProfileResponse.java b/backend/emm-sale/src/main/java/com/emmsale/login/application/dto/GithubProfileResponse.java index 061c26917..ee69a728f 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/login/application/dto/GithubProfileResponse.java +++ b/backend/emm-sale/src/main/java/com/emmsale/login/application/dto/GithubProfileResponse.java @@ -1,5 +1,6 @@ package com.emmsale.login.application.dto; +import com.emmsale.login.domain.OAuthProfileResponse; import com.emmsale.member.domain.Member; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AccessLevel; @@ -10,7 +11,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Getter -public class GithubProfileResponse { +public class GithubProfileResponse implements OAuthProfileResponse { @JsonProperty("id") private String githubId; @@ -21,10 +22,17 @@ public class GithubProfileResponse { @JsonProperty("avatar_url") private String imageUrl; + //TODO : 추후 삭제 public Long getGithubId() { return Long.valueOf(githubId); } + @Override + public Long getId() { + return Long.valueOf(githubId); + } + + @Override public Member toMember() { return new Member( getGithubId(), diff --git a/backend/emm-sale/src/main/java/com/emmsale/login/utils/GithubClient.java b/backend/emm-sale/src/main/java/com/emmsale/login/utils/GithubClient.java index 62e194124..2a2c23acf 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/login/utils/GithubClient.java +++ b/backend/emm-sale/src/main/java/com/emmsale/login/utils/GithubClient.java @@ -3,6 +3,9 @@ import com.emmsale.login.application.dto.GithubAccessTokenRequest; import com.emmsale.login.application.dto.GithubAccessTokenResponse; import com.emmsale.login.application.dto.GithubProfileResponse; +import com.emmsale.login.domain.OAuthClient; +import com.emmsale.login.domain.OAuthProfileResponse; +import com.emmsale.login.domain.OAuthProviderType; import com.emmsale.login.exception.LoginException; import com.emmsale.login.exception.LoginExceptionType; import lombok.RequiredArgsConstructor; @@ -17,7 +20,7 @@ @Component @RequiredArgsConstructor -public class GithubClient { +public class GithubClient implements OAuthClient { @Value("${github.client.id}") private String clientId; @@ -89,4 +92,15 @@ private void throwIfNotFoundAccessToken(final String accessToken) { throw new LoginException(LoginExceptionType.NOT_FOUND_GITHUB_ACCESS_TOKEN); } } + + @Override + public OAuthProfileResponse getOAuthProfileResponse(final String code) { + final String accessTokenFromGithub = getAccessTokenFromGithub(code); + return getGithubProfileResponse(accessTokenFromGithub); + } + + @Override + public OAuthProviderType supportServer() { + return OAuthProviderType.GITHUB; + } } diff --git a/backend/emm-sale/src/main/java/com/emmsale/member/application/MemberQueryService.java b/backend/emm-sale/src/main/java/com/emmsale/member/application/MemberQueryService.java index 6cf8410a3..230bf87a6 100644 --- a/backend/emm-sale/src/main/java/com/emmsale/member/application/MemberQueryService.java +++ b/backend/emm-sale/src/main/java/com/emmsale/member/application/MemberQueryService.java @@ -4,6 +4,8 @@ import com.emmsale.login.application.dto.GithubProfileResponse; import com.emmsale.login.application.dto.MemberQueryResponse; +import com.emmsale.login.domain.OAuthProfileResponse; +import com.emmsale.login.domain.OAuthProviderType; import com.emmsale.member.application.dto.MemberDetailResponse; import com.emmsale.member.domain.Member; import com.emmsale.member.domain.MemberActivity; @@ -38,6 +40,15 @@ public MemberQueryResponse findOrCreateMember( return new MemberQueryResponse(member.getId(), member.isOnboarded()); } + @Transactional + public MemberQueryResponse findOrCreateMemberByOAuthProfileAndType( + final OAuthProfileResponse profile, final OAuthProviderType type + ) { + final Member member = memberRepository.findByOauthIdAndOauthProviderType(profile.getId(), type) + .orElseGet(() -> memberRepository.save(profile.toMember())); + return new MemberQueryResponse(member.getId(), member.isOnboarded()); + } + public MemberDetailResponse findProfile(final Long memberId) { final Member member = memberRepository.getByIdOrElseThrow(memberId); final List memberActivities = memberActivityRepository.findAllByMember(member); diff --git a/backend/emm-sale/src/test/java/com/emmsale/login/application/LoginServiceTest.java b/backend/emm-sale/src/test/java/com/emmsale/login/application/LoginServiceTest.java index fed14e512..ab81e1fac 100644 --- a/backend/emm-sale/src/test/java/com/emmsale/login/application/LoginServiceTest.java +++ b/backend/emm-sale/src/test/java/com/emmsale/login/application/LoginServiceTest.java @@ -94,4 +94,28 @@ void getAccessTokenFromGithubWithInvalidCode() { () -> assertEquals(actualExceptionType.errorMessage(), expectExceptionType.errorMessage()) ); } + + @Test + @DisplayName("OAuth type과 auth code를 받아서, 실제 member의 JWT를 생성해준다.") + void createToken() { + // given + final String memberId = "1"; + final String validCode = "valid_code"; + final String validAccessToken = "valid_access_token"; + final String oauthType = "github"; + final GithubProfileResponse githubProfile + = new GithubProfileResponse(memberId, "name", "username", "imageUrl"); + + final String expectAccessToken = "expect_access_token"; + final TokenResponse expectTokenResponse = new TokenResponse(1L, false, expectAccessToken); + + given(githubClient.getAccessTokenFromGithub(validCode)).willReturn(validAccessToken); + given(githubClient.getGithubProfileFromGithub(validAccessToken)).willReturn(githubProfile); + + // when + final TokenResponse actualToken = loginService.createToken(validCode, oauthType); + + // then + assertEquals(expectTokenResponse.getMemberId(), actualToken.getMemberId()); + } } diff --git a/backend/emm-sale/src/test/java/com/emmsale/member/application/MemberQueryServiceTest.java b/backend/emm-sale/src/test/java/com/emmsale/member/application/MemberQueryServiceTest.java index de995f6c0..45607bfb0 100644 --- a/backend/emm-sale/src/test/java/com/emmsale/member/application/MemberQueryServiceTest.java +++ b/backend/emm-sale/src/test/java/com/emmsale/member/application/MemberQueryServiceTest.java @@ -6,6 +6,8 @@ import com.emmsale.helper.ServiceIntegrationTestHelper; import com.emmsale.login.application.dto.GithubProfileResponse; import com.emmsale.login.application.dto.MemberQueryResponse; +import com.emmsale.login.domain.OAuthProfileResponse; +import com.emmsale.login.domain.OAuthProviderType; import com.emmsale.member.application.dto.MemberActivityResponse; import com.emmsale.member.application.dto.MemberDetailResponse; import com.emmsale.member.exception.MemberException; @@ -107,4 +109,24 @@ void findProfile_fail() { .hasMessage(MemberExceptionType.NOT_FOUND_MEMBER.errorMessage()); } } + + @Test + @DisplayName("OAuthProfile과 OAuthProviderType로 member를 조회한다.") + void findProfileByOAuthProfileAndType() { + //given + final OAuthProviderType providerType = OAuthProviderType.GITHUB; + final OAuthProfileResponse profile = new GithubProfileResponse("1", "name", + "username", "https://imageUrl.com"); + + final MemberQueryResponse expectResponse = new MemberQueryResponse(1L, false); + + //when + final MemberQueryResponse actualResponse = memberQueryService + .findOrCreateMemberByOAuthProfileAndType(profile, providerType); + + //then + assertThat(expectResponse) + .usingRecursiveComparison() + .isEqualTo(actualResponse); + } }