From 6d5afb757bcc84c6c7ee6826f8d51b567a29cf6f Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 13:17:12 +0900 Subject: [PATCH 01/35] refact: move naver response dto to naver package --- .../api/dto/response/auth/{ => naver}/NaverInfoResponse.kt | 2 +- .../api/dto/response/auth/{ => naver}/NaverTokenResponse.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/{ => naver}/NaverInfoResponse.kt (73%) rename src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/{ => naver}/NaverTokenResponse.kt (69%) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/NaverInfoResponse.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverInfoResponse.kt similarity index 73% rename from src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/NaverInfoResponse.kt rename to src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverInfoResponse.kt index e1ab281..046a540 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/NaverInfoResponse.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverInfoResponse.kt @@ -1,4 +1,4 @@ -package com.dobby.backend.presentation.api.dto.response.auth +package com.dobby.backend.presentation.api.dto.response.auth.naver import com.fasterxml.jackson.annotation.JsonProperty diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/NaverTokenResponse.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverTokenResponse.kt similarity index 69% rename from src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/NaverTokenResponse.kt rename to src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverTokenResponse.kt index 873f164..58b86b0 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/NaverTokenResponse.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverTokenResponse.kt @@ -1,4 +1,4 @@ -package com.dobby.backend.presentation.api.dto.response.auth +package com.dobby.backend.presentation.api.dto.response.auth.naver import com.fasterxml.jackson.annotation.JsonProperty From 66773f230395cacceb34189e84fa4e63c9db150d Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 13:17:44 +0900 Subject: [PATCH 02/35] feat: add NaverAuthGateway for DIP --- .../domain/gateway/NaverAuthGateway.kt | 8 ++++ .../gateway/NaverAuthGatewayImpl.kt | 37 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/main/kotlin/com/dobby/backend/domain/gateway/NaverAuthGateway.kt create mode 100644 src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt diff --git a/src/main/kotlin/com/dobby/backend/domain/gateway/NaverAuthGateway.kt b/src/main/kotlin/com/dobby/backend/domain/gateway/NaverAuthGateway.kt new file mode 100644 index 0000000..8b96dff --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/domain/gateway/NaverAuthGateway.kt @@ -0,0 +1,8 @@ +package com.dobby.backend.domain.gateway + +import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverInfoResponse + +interface NaverAuthGateway { + fun getAccessToken(authorizationCode: String, state: String): String? + fun getUserInfo(accessToken: String): NaverInfoResponse? +} diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt new file mode 100644 index 0000000..d917fea --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt @@ -0,0 +1,37 @@ +package com.dobby.backend.infrastructure.gateway + +import com.dobby.backend.domain.gateway.NaverAuthGateway +import com.dobby.backend.infrastructure.config.properties.NaverAuthProperties +import com.dobby.backend.infrastructure.feign.naver.NaverAuthFeignClient +import com.dobby.backend.infrastructure.feign.naver.NaverUserInfoFeignClient +import com.dobby.backend.presentation.api.dto.request.auth.NaverTokenRequest +import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverInfoResponse +import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverTokenResponse +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.stereotype.Component + +@Component +@EnableConfigurationProperties(NaverAuthProperties::class) +class NaverAuthGatewayImpl( + private val naverAuthProperties: NaverAuthProperties, + private val naverAuthFeignClient: NaverAuthFeignClient, + private val naverUserInfoFeignClient: NaverUserInfoFeignClient +) : NaverAuthGateway { + + override fun getAccessToken(authorizationCode: String, state: String): String? { + val naverTokenRequest = NaverTokenRequest( + grantType = "authorization_code", + clientId = naverAuthProperties.clientId, + clientSecret = naverAuthProperties.clientSecret, + code = authorizationCode, + state = state + ) + + val tokenResponse: NaverTokenResponse = naverAuthFeignClient.getAccessToken(naverTokenRequest) + return tokenResponse.accessToken + } + + override fun getUserInfo(accessToken: String): NaverInfoResponse? { + return naverUserInfoFeignClient.getUserInfo("Bearer $accessToken") + } +} From 5d1ee0136cd60e4830d065ae9d768577b93c4a8f Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 13:18:41 +0900 Subject: [PATCH 03/35] refact: rename OAuthService to AuthService --- .../application/service/OauthService.kt | 22 ------------------- ...OauthServiceTest.kt => AuthServiceTest.kt} | 10 ++++++--- 2 files changed, 7 insertions(+), 25 deletions(-) delete mode 100644 src/main/kotlin/com/dobby/backend/application/service/OauthService.kt rename src/test/kotlin/com/dobby/backend/application/service/{OauthServiceTest.kt => AuthServiceTest.kt} (78%) diff --git a/src/main/kotlin/com/dobby/backend/application/service/OauthService.kt b/src/main/kotlin/com/dobby/backend/application/service/OauthService.kt deleted file mode 100644 index f69c569..0000000 --- a/src/main/kotlin/com/dobby/backend/application/service/OauthService.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.dobby.backend.application.service - -import com.dobby.backend.application.usecase.FetchGoogleUserInfoUseCase -import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase -import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleOauthLoginRequest -import com.dobby.backend.presentation.api.dto.request.auth.NaverOauthLoginRequest -import com.dobby.backend.presentation.api.dto.response.auth.OauthLoginResponse -import org.springframework.stereotype.Service - -@Service -class OauthService( - private val fetchGoogleUserInfoUseCase: FetchGoogleUserInfoUseCase, - private val fetchNaverUserInfoUseCase: FetchNaverUserInfoUseCase, -) { - fun getGoogleUserInfo(oauthLoginRequest: GoogleOauthLoginRequest): OauthLoginResponse { - return fetchGoogleUserInfoUseCase.execute(oauthLoginRequest) - } - - fun getNaverUserInfo(oauthLoginRequest: NaverOauthLoginRequest): OauthLoginResponse { - return fetchNaverUserInfoUseCase.execute(oauthLoginRequest) - } -} diff --git a/src/test/kotlin/com/dobby/backend/application/service/OauthServiceTest.kt b/src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt similarity index 78% rename from src/test/kotlin/com/dobby/backend/application/service/OauthServiceTest.kt rename to src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt index b2b94d8..e31df31 100644 --- a/src/test/kotlin/com/dobby/backend/application/service/OauthServiceTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt @@ -1,6 +1,8 @@ -import com.dobby.backend.application.service.OauthService +import com.dobby.backend.application.service.AuthService import com.dobby.backend.application.usecase.FetchGoogleUserInfoUseCase import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase +import com.dobby.backend.application.usecase.GenerateTestToken +import com.dobby.backend.application.usecase.GenerateTokenWithRefreshToken import com.dobby.backend.infrastructure.database.entity.enum.ProviderType import com.dobby.backend.infrastructure.database.entity.enum.RoleType import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleOauthLoginRequest @@ -13,11 +15,13 @@ import io.mockk.mockk import org.springframework.test.context.ActiveProfiles @ActiveProfiles("test") -class OauthServiceTest : BehaviorSpec({ +class AuthServiceTest : BehaviorSpec({ val fetchGoogleUserInfoUseCase = mockk() val fetchNaverUserInfoUseCase = mockk() + val generateTokenWithRefreshToken = mockk() + val generateTestToken = mockk() - val oauthService = OauthService(fetchGoogleUserInfoUseCase, fetchNaverUserInfoUseCase) + val oauthService = AuthService(fetchGoogleUserInfoUseCase, fetchNaverUserInfoUseCase, generateTokenWithRefreshToken, generateTestToken) given("Google OAuth 요청이 들어왔을 때") { val oauthLoginRequest = GoogleOauthLoginRequest(authorizationCode = "valid-auth-code") From c8a1ecc0b04857025c6024614e09220c7eab67ca Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 13:19:42 +0900 Subject: [PATCH 04/35] refact: add generate token's logic to AuthService --- .../dobby/backend/application/usecase/GenerateTestToken.kt | 5 ++++- .../application/usecase/GenerateTokenWithRefreshToken.kt | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestToken.kt b/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestToken.kt index edf943e..5ef7b86 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestToken.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestToken.kt @@ -2,6 +2,7 @@ package com.dobby.backend.application.usecase import com.dobby.backend.domain.gateway.MemberGateway import com.dobby.backend.domain.gateway.TokenGateway +import com.dobby.backend.domain.model.Member class GenerateTestToken( private val tokenGateway: TokenGateway, @@ -14,6 +15,7 @@ class GenerateTestToken( data class Output( val accessToken: String, val refreshToken: String, + val member: Member ) override fun execute(input: Input): Output { @@ -21,7 +23,8 @@ class GenerateTestToken( val member = memberGateway.getById(memberId) return Output( accessToken = tokenGateway.generateAccessToken(member), - refreshToken = tokenGateway.generateRefreshToken(member) + refreshToken = tokenGateway.generateRefreshToken(member), + member = member ) } } diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshToken.kt b/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshToken.kt index e401aaf..84415ce 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshToken.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshToken.kt @@ -2,6 +2,7 @@ package com.dobby.backend.application.usecase import com.dobby.backend.domain.gateway.MemberGateway import com.dobby.backend.domain.gateway.TokenGateway +import com.dobby.backend.domain.model.Member class GenerateTokenWithRefreshToken( private val tokenGateway: TokenGateway, @@ -14,7 +15,7 @@ class GenerateTokenWithRefreshToken( data class Output( val accessToken: String, val refreshToken: String, - val memberId: Long + val member: Member ) override fun execute(input: Input): Output { @@ -23,7 +24,7 @@ class GenerateTokenWithRefreshToken( return Output( accessToken = tokenGateway.generateAccessToken(member), refreshToken = tokenGateway.generateRefreshToken(member), - memberId = memberId + member = member ) } } From decb6db2c3f947ca9cd012f089fbd222644f0da8 Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 13:20:21 +0900 Subject: [PATCH 05/35] refact: move naver response to naver package --- .../backend/infrastructure/feign/naver/NaverAuthFeignClient.kt | 2 +- .../infrastructure/feign/naver/NaverUserInfoFeignClient.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverAuthFeignClient.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverAuthFeignClient.kt index ecd49d1..08c14d5 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverAuthFeignClient.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverAuthFeignClient.kt @@ -1,7 +1,7 @@ package com.dobby.backend.infrastructure.feign.naver import com.dobby.backend.presentation.api.dto.request.auth.NaverTokenRequest -import com.dobby.backend.presentation.api.dto.response.auth.NaverTokenResponse +import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverTokenResponse import org.springframework.cloud.openfeign.FeignClient import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverUserInfoFeignClient.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverUserInfoFeignClient.kt index b209656..d0950f9 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverUserInfoFeignClient.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverUserInfoFeignClient.kt @@ -1,6 +1,6 @@ package com.dobby.backend.infrastructure.feign.naver -import com.dobby.backend.presentation.api.dto.response.auth.NaverInfoResponse +import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverInfoResponse import org.springframework.cloud.openfeign.FeignClient import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestHeader From 4cd937df7627441564f52de2c82b99fd229808f8 Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 13:20:53 +0900 Subject: [PATCH 06/35] refact: refactor naver login logic for clean architecture --- .../usecase/FetchNaverUserInfoUseCase.kt | 97 ++++++++++--------- 1 file changed, 53 insertions(+), 44 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt index 3158135..8ce457b 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt @@ -1,65 +1,74 @@ package com.dobby.backend.application.usecase -import com.dobby.backend.application.mapper.OauthUserMapper import com.dobby.backend.domain.exception.SignInMemberException -import com.dobby.backend.infrastructure.config.properties.NaverAuthProperties +import com.dobby.backend.domain.gateway.NaverAuthGateway import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.infrastructure.database.entity.enum.ProviderType +import com.dobby.backend.infrastructure.database.entity.enum.RoleType import com.dobby.backend.infrastructure.database.repository.MemberRepository -import com.dobby.backend.infrastructure.feign.naver.NaverAuthFeignClient -import com.dobby.backend.infrastructure.feign.naver.NaverUserInfoFeignClient import com.dobby.backend.infrastructure.token.JwtTokenProvider -import com.dobby.backend.presentation.api.dto.request.auth.NaverOauthLoginRequest -import com.dobby.backend.presentation.api.dto.request.auth.NaverTokenRequest -import com.dobby.backend.presentation.api.dto.response.auth.NaverTokenResponse -import com.dobby.backend.presentation.api.dto.response.auth.OauthLoginResponse import com.dobby.backend.util.AuthenticationUtils +import java.lang.Exception class FetchNaverUserInfoUseCase( - private val naverAuthFeignClient: NaverAuthFeignClient, - private val naverUserInfoFeginClient: NaverUserInfoFeignClient, + private val naverAuthGateway: NaverAuthGateway, private val jwtTokenProvider: JwtTokenProvider, - private val naverAuthProperties: NaverAuthProperties, private val memberRepository: MemberRepository -) : UseCase { +) : UseCase { - override fun execute(input: NaverOauthLoginRequest): OauthLoginResponse { - try { - val naverTokenRequest = NaverTokenRequest( - grantType = "authorization_code", - clientId = naverAuthProperties.clientId, - clientSecret = naverAuthProperties.clientSecret, - code = input.authorizationCode, - state = input.state - ) + data class Input( + val authorizationCode: String, + val state: String + ) - val oauthRes = fetchAccessToken(naverTokenRequest) - val oauthToken = oauthRes.accessToken + data class Output( + val isRegistered: Boolean, + val accessToken: String, + val refreshToken: String, + val memberId: Long?, + val oauthEmail: String, + val oauthName: String, + val role: RoleType?, + val provider: ProviderType + ) - val userInfo = naverUserInfoFeginClient.getUserInfo("Bearer $oauthToken") - val email = userInfo.email - val regMember = memberRepository.findByOauthEmailAndStatus(email, MemberStatus.ACTIVE) - ?: throw SignInMemberException() + override fun execute(input: Input): Output { + try { + val oauthToken = naverAuthGateway.getAccessToken(input.authorizationCode, input.state) + val userInfo = oauthToken?.let { naverAuthGateway.getUserInfo(it) } + val email = userInfo?.email + val member = email?.let { memberRepository.findByOauthEmailAndStatus(it, MemberStatus.ACTIVE) } - val regMemberAuthentication = AuthenticationUtils.createAuthentication(regMember) - val jwtAccessToken = jwtTokenProvider.generateAccessToken(regMemberAuthentication) - val jwtRefreshToken = jwtTokenProvider.generateRefreshToken(regMemberAuthentication) + return if (member != null) { + val memberAuthentication = AuthenticationUtils.createAuthentication(member) + val jwtAccessToken = jwtTokenProvider.generateAccessToken(memberAuthentication) + val jwtRefreshToken = jwtTokenProvider.generateRefreshToken(memberAuthentication) - return OauthUserMapper.toDto( - isRegistered = true, - accessToken = jwtAccessToken, - refreshToken = jwtRefreshToken, - oauthEmail = regMember.oauthEmail, - oauthName = regMember.name ?: throw SignInMemberException(), - role = regMember.role ?: throw SignInMemberException(), - provider = ProviderType.NAVER - ) - } catch (e: SignInMemberException) { + Output( + isRegistered = true, + accessToken = jwtAccessToken, + refreshToken = jwtRefreshToken, + memberId = member.id, + oauthEmail = member.oauthEmail, + oauthName = member.name ?: throw SignInMemberException(), + role = member.role ?: throw SignInMemberException(), + provider = ProviderType.NAVER + ) + } else { + // 등록된 멤버가 없으면 isRegistered = false, memberId = null + Output( + isRegistered = false, + accessToken = "", + refreshToken = "", + memberId = null, + oauthEmail = email ?: "", + oauthName = "", + role = null, + provider = ProviderType.NAVER + ) + } + } catch (e: Exception) { throw SignInMemberException() } } - - private fun fetchAccessToken(naverTokenRequest: NaverTokenRequest): NaverTokenResponse { - return naverAuthFeignClient.getAccessToken(naverTokenRequest) - } } From 599c5155875ee1ce9304ec59282568995a820ee3 Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 13:21:26 +0900 Subject: [PATCH 07/35] refact: refactor AuthController/Service for clean architecture --- .../application/service/AuthService.kt | 63 ++++++++++++++++ .../api/controller/AuthController.kt | 74 +++++++++---------- 2 files changed, 97 insertions(+), 40 deletions(-) create mode 100644 src/main/kotlin/com/dobby/backend/application/service/AuthService.kt diff --git a/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt new file mode 100644 index 0000000..6380268 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt @@ -0,0 +1,63 @@ +package com.dobby.backend.application.service + +import com.dobby.backend.application.usecase.* +import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleOauthLoginRequest +import com.dobby.backend.presentation.api.dto.response.auth.OauthLoginResponse +import org.springframework.stereotype.Service + +@Service +class AuthService( + private val fetchGoogleUserInfoUseCase: FetchGoogleUserInfoUseCase, + private val fetchNaverUserInfoUseCase: FetchNaverUserInfoUseCase, + private val generateTokenWithRefreshToken: GenerateTokenWithRefreshToken, + private val generateTestToken: GenerateTestToken, +) { + fun getGoogleUserInfo(oauthLoginRequest: GoogleOauthLoginRequest): OauthLoginResponse { + return fetchGoogleUserInfoUseCase.execute(oauthLoginRequest) + } + + fun getNaverUserInfo(authorizationCode: String, state: String): FetchNaverUserInfoUseCase.Output { + val result = fetchNaverUserInfoUseCase.execute( + FetchNaverUserInfoUseCase.Input( + authorizationCode = authorizationCode, + state = state + ) + ) + return FetchNaverUserInfoUseCase.Output( + isRegistered = result.isRegistered, + accessToken = result.accessToken, + refreshToken = result.refreshToken, + memberId = result.memberId, + oauthEmail = result.oauthEmail, + oauthName = result.oauthName, + role = result.role, + provider = result.provider, + ) + } + + fun forceToken(memberId: Long): GenerateTestToken.Output { + val result = generateTestToken.execute( + GenerateTestToken.Input( + memberId = memberId + ) + ) + return GenerateTestToken.Output( + accessToken = result.accessToken, + refreshToken = result.refreshToken, + member = result.member + ) + } + + fun signInWithRefreshToken(refreshToken: String): GenerateTokenWithRefreshToken.Output { + val result = generateTokenWithRefreshToken.execute( + GenerateTokenWithRefreshToken.Input( + refreshToken = refreshToken, + ) + ) + return GenerateTokenWithRefreshToken.Output( + accessToken = result.accessToken, + refreshToken = result.refreshToken, + member = result.member + ) + } +} diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt b/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt index 745b138..2cdae40 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt @@ -1,10 +1,7 @@ package com.dobby.backend.presentation.api.controller -import com.dobby.backend.application.service.OauthService -import com.dobby.backend.application.usecase.GenerateTestToken +import com.dobby.backend.application.service.AuthService import com.dobby.backend.presentation.api.dto.response.auth.OauthLoginResponse -import com.dobby.backend.application.usecase.GenerateTokenWithRefreshToken -import com.dobby.backend.application.usecase.GetMemberById import com.dobby.backend.infrastructure.database.entity.enum.RoleType import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleOauthLoginRequest import com.dobby.backend.presentation.api.dto.request.auth.MemberRefreshTokenRequest @@ -20,42 +17,49 @@ import org.springframework.web.bind.annotation.* @RestController @RequestMapping("/v1/auth") class AuthController( - private val generateTestToken: GenerateTestToken, - private val generateTokenWithRefreshToken: GenerateTokenWithRefreshToken, - private val getMemberById: GetMemberById, - private val oauthService: OauthService, + private val authService: AuthService ) { - @Operation(summary = "테스트용 토큰 강제 발급", description = "memberId로 테스트용 토큰을 발급합니다") - @PostMapping("/force-token") - fun forceToken( - @RequestParam memberId: Long - ): TestMemberSignInResponse { - val result = generateTestToken.execute( - GenerateTestToken.Input(memberId) - ) - - return TestMemberSignInResponse( - accessToken = result.accessToken, - refreshToken = result.refreshToken - ) - } @PostMapping("/login/google") @Operation(summary = "Google OAuth 로그인 API", description = "Google OAuth 로그인 후 인증 정보를 반환합니다") fun signInWithGoogle( @RequestParam role : RoleType, - @RequestBody @Valid oauthLoginRequest: GoogleOauthLoginRequest + @RequestBody @Valid request: GoogleOauthLoginRequest ): OauthLoginResponse { - return oauthService.getGoogleUserInfo(oauthLoginRequest) + return authService.getGoogleUserInfo(request) } @PostMapping("/login/naver") @Operation(summary = "Naver OAuth 로그인 API", description = "Naver OAuth 로그인 후 인증 정보를 반환합니다") fun signInWithNaver( @RequestParam role : RoleType, - @RequestBody @Valid oauthLoginRequest: NaverOauthLoginRequest + @RequestBody @Valid request: NaverOauthLoginRequest ): OauthLoginResponse { - return oauthService.getNaverUserInfo(oauthLoginRequest) + val result = authService.getNaverUserInfo(request.authorizationCode, request.state) + return OauthLoginResponse( + isRegistered = result.isRegistered, + accessToken = result.accessToken, + refreshToken = result.refreshToken, + memberInfo = MemberResponse( + memberId = null, + name = result.oauthName, + oauthEmail = result.oauthEmail, + role = result.role, + provider = result.provider, + ) + ) + } + + @Operation(summary = "테스트용 토큰 강제 발급", description = "memberId로 테스트용 토큰을 발급합니다") + @PostMapping("/force-token") + fun forceToken( + @RequestParam memberId: Long + ): TestMemberSignInResponse { + val result = authService.forceToken(memberId) + return TestMemberSignInResponse( + accessToken = result.accessToken, + refreshToken = result.refreshToken + ) } @Operation(summary = "토큰 갱신 요청", description = "리프레시 토큰으로 기존 토큰을 갱신합니다") @@ -63,22 +67,12 @@ class AuthController( fun signInWithRefreshToken( @RequestBody @Valid request: MemberRefreshTokenRequest, ): OauthLoginResponse { - val tokens = generateTokenWithRefreshToken.execute( - GenerateTokenWithRefreshToken.Input( - refreshToken = request.refreshToken, - ) - ) - val member = getMemberById.execute( - GetMemberById.Input( - memberId = tokens.memberId, - ) - ) - + val result = authService.signInWithRefreshToken(request.refreshToken) return OauthLoginResponse( isRegistered = false, - accessToken = tokens.accessToken, - refreshToken = tokens.refreshToken, - memberInfo = MemberResponse.fromDomain(member) + accessToken = result.accessToken, + refreshToken = result.refreshToken, + memberInfo = MemberResponse.fromDomain(result.member) ) } } From 48662c2a21969f7ff944cfe308b0d6ebf3e117c6 Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 13:34:43 +0900 Subject: [PATCH 08/35] refact: add findByOauthEmailAndStatus repository's method to MemberGateway --- .../usecase/FetchNaverUserInfoUseCase.kt | 13 +++++++------ .../dobby/backend/domain/gateway/MemberGateway.kt | 2 ++ .../infrastructure/gateway/MemberGatewayImpl.kt | 7 +++++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt index 8ce457b..72e4ab5 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt @@ -1,7 +1,9 @@ package com.dobby.backend.application.usecase import com.dobby.backend.domain.exception.SignInMemberException +import com.dobby.backend.domain.gateway.MemberGateway import com.dobby.backend.domain.gateway.NaverAuthGateway +import com.dobby.backend.domain.gateway.TokenGateway import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.infrastructure.database.entity.enum.ProviderType import com.dobby.backend.infrastructure.database.entity.enum.RoleType @@ -12,8 +14,8 @@ import java.lang.Exception class FetchNaverUserInfoUseCase( private val naverAuthGateway: NaverAuthGateway, - private val jwtTokenProvider: JwtTokenProvider, - private val memberRepository: MemberRepository + private val memberGateway: MemberGateway, + private val jwtTokenGateway: TokenGateway ) : UseCase { data class Input( @@ -37,12 +39,11 @@ class FetchNaverUserInfoUseCase( val oauthToken = naverAuthGateway.getAccessToken(input.authorizationCode, input.state) val userInfo = oauthToken?.let { naverAuthGateway.getUserInfo(it) } val email = userInfo?.email - val member = email?.let { memberRepository.findByOauthEmailAndStatus(it, MemberStatus.ACTIVE) } + val member = email?.let { memberGateway.findByOauthEmailAndStatus(it, MemberStatus.ACTIVE) } return if (member != null) { - val memberAuthentication = AuthenticationUtils.createAuthentication(member) - val jwtAccessToken = jwtTokenProvider.generateAccessToken(memberAuthentication) - val jwtRefreshToken = jwtTokenProvider.generateRefreshToken(memberAuthentication) + val jwtAccessToken = jwtTokenGateway.generateAccessToken(member) + val jwtRefreshToken = jwtTokenGateway.generateRefreshToken(member) Output( isRegistered = true, diff --git a/src/main/kotlin/com/dobby/backend/domain/gateway/MemberGateway.kt b/src/main/kotlin/com/dobby/backend/domain/gateway/MemberGateway.kt index f26c2ec..65a3038 100644 --- a/src/main/kotlin/com/dobby/backend/domain/gateway/MemberGateway.kt +++ b/src/main/kotlin/com/dobby/backend/domain/gateway/MemberGateway.kt @@ -1,7 +1,9 @@ package com.dobby.backend.domain.gateway import com.dobby.backend.domain.model.Member +import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus interface MemberGateway { fun getById(memberId: Long): Member + fun findByOauthEmailAndStatus(email: String, status: MemberStatus): Member? } diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/MemberGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/MemberGatewayImpl.kt index 6425242..d79b3ac 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/MemberGatewayImpl.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/MemberGatewayImpl.kt @@ -3,6 +3,7 @@ package com.dobby.backend.infrastructure.gateway import com.dobby.backend.domain.gateway.MemberGateway import com.dobby.backend.domain.model.Member import com.dobby.backend.infrastructure.database.entity.MemberEntity +import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.infrastructure.database.repository.MemberRepository import org.springframework.stereotype.Component @@ -15,4 +16,10 @@ class MemberGatewayImpl( .getReferenceById(memberId) .let(MemberEntity::toDomain) } + + override fun findByOauthEmailAndStatus(email: String, status: MemberStatus): Member? { + return memberRepository + .findByOauthEmailAndStatus(email, status) + ?.let(MemberEntity::toDomain) + } } From 0b1dcc20d6124448b0583b6d30ea50dc4961100e Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 13:35:05 +0900 Subject: [PATCH 09/35] refact: rename memberId to id in Member --- .../com/dobby/backend/domain/model/Member.kt | 7 +- .../database/entity/MemberEntity.kt | 4 +- .../gateway/TokenGatewayImpl.kt | 4 +- .../api/dto/response/MemberResponse.kt | 2 +- .../usecase/FetchNaverUserInfoTest.kt | 72 ++++++++++--------- .../usecase/GenerateTestTokenTest.kt | 5 +- .../GenerateTokenWithRefreshTokenTest.kt | 6 +- .../token/JwtTokenProviderTest.kt | 10 +-- 8 files changed, 56 insertions(+), 54 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/domain/model/Member.kt b/src/main/kotlin/com/dobby/backend/domain/model/Member.kt index 60cee40..2f53f6d 100644 --- a/src/main/kotlin/com/dobby/backend/domain/model/Member.kt +++ b/src/main/kotlin/com/dobby/backend/domain/model/Member.kt @@ -3,10 +3,9 @@ package com.dobby.backend.domain.model import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.infrastructure.database.entity.enum.ProviderType import com.dobby.backend.infrastructure.database.entity.enum.RoleType -import java.time.LocalDate data class Member( - val memberId: Long, + val id: Long, val name: String?, val oauthEmail: String, val contactEmail: String?, @@ -17,7 +16,7 @@ data class Member( companion object { fun newMember( - memberId: Long, + id: Long, name: String, oauthEmail: String, contactEmail: String, @@ -25,7 +24,7 @@ data class Member( status: MemberStatus, role: RoleType, ) = Member( - memberId = memberId, + id = id, name = name, oauthEmail = oauthEmail, contactEmail = contactEmail, diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/MemberEntity.kt b/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/MemberEntity.kt index 77a0381..997cffe 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/MemberEntity.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/MemberEntity.kt @@ -39,7 +39,7 @@ class MemberEntity( ) : AuditingEntity() { fun toDomain() = Member( - memberId = id, + id = id, name = name, oauthEmail = oauthEmail, contactEmail = contactEmail, @@ -51,7 +51,7 @@ class MemberEntity( companion object { fun fromDomain(member: Member) = with(member) { MemberEntity( - id = memberId, + id = id, oauthEmail = oauthEmail, provider = provider, status = status, diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/TokenGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/TokenGatewayImpl.kt index b3d80ba..d6f18fe 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/TokenGatewayImpl.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/TokenGatewayImpl.kt @@ -14,7 +14,7 @@ class TokenGatewayImpl( override fun generateAccessToken(member: Member): String { val authorities = listOf(SimpleGrantedAuthority(member.role?.roleName)) val authentication = UsernamePasswordAuthenticationToken( - member.memberId, + member.id, null, authorities ) @@ -23,7 +23,7 @@ class TokenGatewayImpl( override fun generateRefreshToken(member: Member): String { val authentication = UsernamePasswordAuthenticationToken( - member.memberId, + member.id, null ) return tokenProvider.generateRefreshToken(authentication) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/MemberResponse.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/MemberResponse.kt index ddc623a..c83a55c 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/MemberResponse.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/MemberResponse.kt @@ -26,7 +26,7 @@ data class MemberResponse( companion object { fun fromDomain(member: Member): MemberResponse = with(member) { MemberResponse( - memberId = memberId, + memberId = id, oauthEmail = oauthEmail, provider = provider, role = role, diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoTest.kt index 0d0d469..1c4fb49 100644 --- a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoTest.kt @@ -1,42 +1,32 @@ import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase -import com.dobby.backend.infrastructure.config.properties.NaverAuthProperties -import com.dobby.backend.infrastructure.database.entity.MemberEntity +import com.dobby.backend.domain.gateway.MemberGateway +import com.dobby.backend.domain.gateway.NaverAuthGateway +import com.dobby.backend.domain.gateway.TokenGateway +import com.dobby.backend.domain.model.Member import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.infrastructure.database.entity.enum.ProviderType import com.dobby.backend.infrastructure.database.entity.enum.RoleType -import com.dobby.backend.infrastructure.database.repository.MemberRepository -import com.dobby.backend.infrastructure.feign.naver.NaverAuthFeignClient -import com.dobby.backend.infrastructure.feign.naver.NaverUserInfoFeignClient -import com.dobby.backend.infrastructure.token.JwtTokenProvider -import com.dobby.backend.presentation.api.dto.request.auth.NaverOauthLoginRequest -import com.dobby.backend.presentation.api.dto.response.auth.OauthLoginResponse -import com.dobby.backend.presentation.api.dto.response.auth.NaverTokenResponse import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe import io.mockk.every import io.mockk.mockk import org.springframework.test.context.ActiveProfiles -import java.time.LocalDate @ActiveProfiles("test") class FetchNaverUserInfoUseCaseTest : BehaviorSpec({ - val naverAuthFeignClient = mockk() - val naverUserInfoFeginClient = mockk() - val jwtTokenProvider = mockk() - val naverAuthProperties = mockk() - val memberRepository = mockk() + val naverAuthGateway = mockk() + val memberGateway = mockk() + val tokenGateway = mockk() val fetchNaverUserInfoUseCase = FetchNaverUserInfoUseCase( - naverAuthFeignClient, - naverUserInfoFeginClient, - jwtTokenProvider, - naverAuthProperties, - memberRepository + naverAuthGateway, + memberGateway, + tokenGateway ) given("Naver OAuth 요청이 들어왔을 때") { - val oauthLoginRequest = NaverOauthLoginRequest(authorizationCode = "valid-auth-code", state = "valid-state") - val mockMember = MemberEntity( + val input = FetchNaverUserInfoUseCase.Input(authorizationCode = "valid-auth-code", state = "valid-state") + val mockMember = Member( id = 1L, oauthEmail = "test@example.com", name = "Test User", @@ -46,27 +36,41 @@ class FetchNaverUserInfoUseCaseTest : BehaviorSpec({ provider = ProviderType.NAVER ) - every { naverAuthProperties.clientId } returns "mock-client-id" - every { naverAuthProperties.clientSecret } returns "mock-client-secret" - every { naverAuthProperties.redirectUri } returns "http://localhost/callback" - every { naverAuthFeignClient.getAccessToken(any()) } returns NaverTokenResponse("mock-access-token") - every { naverUserInfoFeginClient.getUserInfo("Bearer mock-access-token") } returns mockk { + val mockEmptyMember = null + every { naverAuthGateway.getAccessToken(any(), any()) } returns "mock-access-token" + every { naverAuthGateway.getUserInfo("mock-access-token") } returns mockk { every { email } returns "test@example.com" every { name } returns "Test User" } - every { memberRepository.findByOauthEmailAndStatus("test@example.com", MemberStatus.ACTIVE) } returns mockMember - every { jwtTokenProvider.generateAccessToken(any()) } returns "mock-jwt-access-token" - every { jwtTokenProvider.generateRefreshToken(any()) } returns "mock-jwt-refresh-token" - `when`("정상적으로 모든 데이터가 주어지면") { - val result: OauthLoginResponse = fetchNaverUserInfoUseCase.execute(oauthLoginRequest) + every { tokenGateway.generateAccessToken(any()) } returns "mock-jwt-access-token" + every { tokenGateway.generateRefreshToken(any()) } returns "mock-jwt-refresh-token" + + // 테스트 1: 등록된 멤버가 있을 경우 + every { memberGateway.findByOauthEmailAndStatus("test@example.com", MemberStatus.ACTIVE) } returns mockMember + + `when`("정상적으로 등록된 유저가 있는 경우") { + val result: FetchNaverUserInfoUseCase.Output = fetchNaverUserInfoUseCase.execute(input) then("유저 정보를 포함한 OauthLoginResponse를 반환해야 한다") { result.isRegistered shouldBe true result.accessToken shouldBe "mock-jwt-access-token" result.refreshToken shouldBe "mock-jwt-refresh-token" - result.memberInfo.oauthEmail shouldBe "test@example.com" - result.memberInfo.name shouldBe "Test User" + result.memberId shouldBe 1L + result.oauthEmail shouldBe "test@example.com" + } + } + + // 테스트 2: 등록된 멤버가 없는 경우 + every { memberGateway.findByOauthEmailAndStatus("test@example.com", MemberStatus.ACTIVE) } returns mockEmptyMember + + `when`("등록되지 않은 유저가 있는 경우") { + val result: FetchNaverUserInfoUseCase.Output = fetchNaverUserInfoUseCase.execute(input) + + then("isRegistered는 false, memberId는 null이어야 한다") { + result.isRegistered shouldBe false + result.memberId shouldBe null + result.oauthEmail shouldBe "test@example.com" } } } diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenTest.kt index 134cac4..50dfbcd 100644 --- a/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenTest.kt @@ -10,7 +10,6 @@ import com.dobby.backend.infrastructure.database.entity.enum.RoleType import io.kotest.matchers.shouldBe import io.mockk.every import io.mockk.mockk -import java.time.LocalDate class GenerateTestTokenTest: BehaviorSpec({ val tokenGateway = mockk() @@ -18,7 +17,7 @@ class GenerateTestTokenTest: BehaviorSpec({ val generateTestToken = GenerateTestToken(tokenGateway, memberGateway) given("memberId가 주어졌을 때") { - val member = Member(memberId = 1, oauthEmail = "dlawotn3@naver.com", contactEmail = "dlawotn3@naver.com", + val member = Member(id = 1, oauthEmail = "dlawotn3@naver.com", contactEmail = "dlawotn3@naver.com", provider = ProviderType.NAVER, role = RoleType.PARTICIPANT, name = "dobby", status = MemberStatus.ACTIVE) val accessToken = "testAccessToken" @@ -29,7 +28,7 @@ class GenerateTestTokenTest: BehaviorSpec({ every { memberGateway.getById(1) } returns member `when`("execute가 호출되면") { - val input = GenerateTestToken.Input(member.memberId) + val input = GenerateTestToken.Input(member.id) val result = generateTestToken.execute(input) then("생성된 accessToken과 refreshToken이 반환되어야 한다") { diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenTest.kt index 4b5039e..1963cd3 100644 --- a/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenTest.kt @@ -19,13 +19,13 @@ class GenerateTokenWithRefreshTokenTest : BehaviorSpec({ given("유효한 리프레시 토큰이 주어졌을 때") { val validRefreshToken = "validRefreshToken" - val member = Member(memberId = 1, oauthEmail = "dlawotn3@naver.com", contactEmail = "dlawotn3@naver.com", + val member = Member(id = 1, oauthEmail = "dlawotn3@naver.com", contactEmail = "dlawotn3@naver.com", provider = ProviderType.NAVER, role = RoleType.PARTICIPANT, name = "dobby", status = MemberStatus.ACTIVE) val accessToken = "newAccessToken" val newRefreshToken = "newRefreshToken" - every { tokenGateway.extractMemberIdFromRefreshToken(validRefreshToken) } returns member.memberId.toString() + every { tokenGateway.extractMemberIdFromRefreshToken(validRefreshToken) } returns member.id.toString() every { tokenGateway.generateAccessToken(member) } returns accessToken every { tokenGateway.generateRefreshToken(member) } returns newRefreshToken every { memberGateway.getById(1) } returns member @@ -37,7 +37,7 @@ class GenerateTokenWithRefreshTokenTest : BehaviorSpec({ then("accessToken과 refreshToken이 생성되고, memberId가 포함된다") { result.accessToken shouldBe accessToken result.refreshToken shouldBe newRefreshToken - result.memberId shouldBe member.memberId + result.member.id shouldBe member.id } } } diff --git a/src/test/kotlin/com/dobby/backend/infrastructure/token/JwtTokenProviderTest.kt b/src/test/kotlin/com/dobby/backend/infrastructure/token/JwtTokenProviderTest.kt index a36b394..0a97e5c 100644 --- a/src/test/kotlin/com/dobby/backend/infrastructure/token/JwtTokenProviderTest.kt +++ b/src/test/kotlin/com/dobby/backend/infrastructure/token/JwtTokenProviderTest.kt @@ -24,11 +24,11 @@ class JwtTokenProviderTest : BehaviorSpec() { init { given("회원 정보가 주어지고") { - val member = Member(memberId = 1, oauthEmail = "dlawotn3@naver.com", contactEmail = "dlawotn3@naver.com", + val member = Member(id = 1, oauthEmail = "dlawotn3@naver.com", contactEmail = "dlawotn3@naver.com", provider = ProviderType.NAVER, role = RoleType.PARTICIPANT, name = "dobby", status = MemberStatus.ACTIVE) val authorities = listOf(SimpleGrantedAuthority(member.role?.name ?: "PARTICIPANT")) - val authentication = UsernamePasswordAuthenticationToken(member.memberId, null, authorities) + val authentication = UsernamePasswordAuthenticationToken(member.id, null, authorities) `when`("해당 인증 정보로 JWT 토큰을 생성하면") { val jwtToken = jwtTokenProvider.generateAccessToken(authentication) @@ -40,11 +40,11 @@ class JwtTokenProviderTest : BehaviorSpec() { } given("유효한 JWT 토큰이 주어지고") { - val member = Member(memberId = 1, oauthEmail = "dlawotn3@naver.com", contactEmail = "dlawotn3@naver.com", + val member = Member(id = 1, oauthEmail = "dlawotn3@naver.com", contactEmail = "dlawotn3@naver.com", provider = ProviderType.NAVER, role = RoleType.PARTICIPANT, name = "dobby", status = MemberStatus.ACTIVE) val authorities = listOf(SimpleGrantedAuthority(member.role?.name ?: "PARTICIPANT")) - val authentication = UsernamePasswordAuthenticationToken(member.memberId, null, authorities) + val authentication = UsernamePasswordAuthenticationToken(member.id, null, authorities) val validToken = jwtTokenProvider.generateAccessToken(authentication) `when`("해당 토큰을 파싱하면") { @@ -54,7 +54,7 @@ class JwtTokenProviderTest : BehaviorSpec() { then("파싱된 멤버의 ID는 원래 멤버의 ID와 같아야 한다") { extractedMemberId shouldNotBe null - extractedMemberId shouldBe member.memberId.toString() + extractedMemberId shouldBe member.id.toString() } then("파싱된 권한(role)은 원래 멤버의 역할과 같아야 한다") { From d25de54041151bb665f7e73afe6aba80abdf1f60 Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 13:52:22 +0900 Subject: [PATCH 10/35] refact: change email's api response for unification --- .../presentation/api/controller/EmailController.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/controller/EmailController.kt b/src/main/kotlin/com/dobby/backend/presentation/api/controller/EmailController.kt index 8666b91..e08b5fa 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/controller/EmailController.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/controller/EmailController.kt @@ -26,8 +26,8 @@ class EmailController( description = "연구자 회원가입 시, 학교 메일 인증 코드를 전송하는 API입니다." ) fun sendCode(@RequestBody @Valid emailSendRequest: EmailSendRequest) - : ApiResponse { - return ApiResponse.onSuccess(emailService.sendEmail(emailSendRequest)) + : EmailSendResponse { + return emailService.sendEmail(emailSendRequest) } @PostMapping("/verify") @@ -36,8 +36,8 @@ class EmailController( description = "연구자 회원가입 시, 코드를 인증하는 API입니다." ) fun verifyCode(@RequestBody @Valid emailVerificationRequest: EmailVerificationRequest) - : ApiResponse { - return ApiResponse.onSuccess(emailService.verifyCode(emailVerificationRequest)) + : EmailVerificationResponse { + return emailService.verifyCode(emailVerificationRequest) } } From dd3703195efbd2ca1115d17fde2d5c51814ae6a4 Mon Sep 17 00:00:00 2001 From: jisu Date: Wed, 8 Jan 2025 15:16:24 +0900 Subject: [PATCH 11/35] refact: change not null to nullable in OauthLoginResponse --- .../application/usecase/FetchNaverUserInfoUseCase.kt | 8 ++++---- .../api/dto/response/auth/OauthLoginResponse.kt | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt index 72e4ab5..50cc2ef 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt @@ -25,8 +25,8 @@ class FetchNaverUserInfoUseCase( data class Output( val isRegistered: Boolean, - val accessToken: String, - val refreshToken: String, + val accessToken: String?, + val refreshToken: String?, val memberId: Long?, val oauthEmail: String, val oauthName: String, @@ -59,8 +59,8 @@ class FetchNaverUserInfoUseCase( // 등록된 멤버가 없으면 isRegistered = false, memberId = null Output( isRegistered = false, - accessToken = "", - refreshToken = "", + accessToken = null, + refreshToken = null, memberId = null, oauthEmail = email ?: "", oauthName = "", diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/OauthLoginResponse.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/OauthLoginResponse.kt index 731037f..3c26209 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/OauthLoginResponse.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/OauthLoginResponse.kt @@ -10,11 +10,11 @@ data class OauthLoginResponse( @Schema(description = "OAuth 로그인 시, 이미 등록된 유저인지", example = "true") val isRegistered: Boolean, - @Schema(description = "Access Token") - val accessToken: String, + @Schema(description = "가입된 회원이라면 발급된 Access Token") + val accessToken: String?, - @Schema(description = "Refresh Token") - val refreshToken: String, + @Schema(description = "가입된 회원이라면 발급된 Refresh Token") + val refreshToken: String?, @Schema(description = "사용자 정보") val memberInfo: MemberResponse From 2ad8edd9a09c2bc7ea580b887a13fe6e9b3cbbd7 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 10:15:49 +0900 Subject: [PATCH 12/35] feat: add UseCase to UseCase class --- .../application/service/AuthService.kt | 20 +++++++++---------- ...stToken.kt => GenerateTestTokenUseCase.kt} | 4 ++-- ...> GenerateTokenWithRefreshTokenUseCase.kt} | 4 ++-- ...tMemberById.kt => GetMemberByIdUseCase.kt} | 4 ++-- .../application/service/AuthServiceTest.kt | 10 +++++----- ...t.kt => FetchGoogleUserInfoUseCaseTest.kt} | 0 ...st.kt => FetchNaverUserInfoUseCaseTest.kt} | 0 ...est.kt => GenerateTestTokenUseCaseTest.kt} | 8 ++++---- ...nerateTokenWithRefreshTokenUseCaseTest.kt} | 12 +++++------ 9 files changed, 31 insertions(+), 31 deletions(-) rename src/main/kotlin/com/dobby/backend/application/usecase/{GenerateTestToken.kt => GenerateTestTokenUseCase.kt} (88%) rename src/main/kotlin/com/dobby/backend/application/usecase/{GenerateTokenWithRefreshToken.kt => GenerateTokenWithRefreshTokenUseCase.kt} (85%) rename src/main/kotlin/com/dobby/backend/application/usecase/{GetMemberById.kt => GetMemberByIdUseCase.kt} (82%) rename src/test/kotlin/com/dobby/backend/application/usecase/{FetchGoogleUserInfoTest.kt => FetchGoogleUserInfoUseCaseTest.kt} (100%) rename src/test/kotlin/com/dobby/backend/application/usecase/{FetchNaverUserInfoTest.kt => FetchNaverUserInfoUseCaseTest.kt} (100%) rename src/test/kotlin/com/dobby/backend/application/usecase/{GenerateTestTokenTest.kt => GenerateTestTokenUseCaseTest.kt} (84%) rename src/test/kotlin/com/dobby/backend/application/usecase/{GenerateTokenWithRefreshTokenTest.kt => GenerateTokenWithRefreshTokenUseCaseTest.kt} (81%) diff --git a/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt index 6380268..f9b1b26 100644 --- a/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt +++ b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt @@ -9,8 +9,8 @@ import org.springframework.stereotype.Service class AuthService( private val fetchGoogleUserInfoUseCase: FetchGoogleUserInfoUseCase, private val fetchNaverUserInfoUseCase: FetchNaverUserInfoUseCase, - private val generateTokenWithRefreshToken: GenerateTokenWithRefreshToken, - private val generateTestToken: GenerateTestToken, + private val generateTokenWithRefreshTokenUseCase: GenerateTokenWithRefreshTokenUseCase, + private val generateTestTokenUseCase: GenerateTestTokenUseCase, ) { fun getGoogleUserInfo(oauthLoginRequest: GoogleOauthLoginRequest): OauthLoginResponse { return fetchGoogleUserInfoUseCase.execute(oauthLoginRequest) @@ -35,26 +35,26 @@ class AuthService( ) } - fun forceToken(memberId: Long): GenerateTestToken.Output { - val result = generateTestToken.execute( - GenerateTestToken.Input( + fun forceToken(memberId: Long): GenerateTestTokenUseCase.Output { + val result = generateTestTokenUseCase.execute( + GenerateTestTokenUseCase.Input( memberId = memberId ) ) - return GenerateTestToken.Output( + return GenerateTestTokenUseCase.Output( accessToken = result.accessToken, refreshToken = result.refreshToken, member = result.member ) } - fun signInWithRefreshToken(refreshToken: String): GenerateTokenWithRefreshToken.Output { - val result = generateTokenWithRefreshToken.execute( - GenerateTokenWithRefreshToken.Input( + fun signInWithRefreshToken(refreshToken: String): GenerateTokenWithRefreshTokenUseCase.Output { + val result = generateTokenWithRefreshTokenUseCase.execute( + GenerateTokenWithRefreshTokenUseCase.Input( refreshToken = refreshToken, ) ) - return GenerateTokenWithRefreshToken.Output( + return GenerateTokenWithRefreshTokenUseCase.Output( accessToken = result.accessToken, refreshToken = result.refreshToken, member = result.member diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestToken.kt b/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenUseCase.kt similarity index 88% rename from src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestToken.kt rename to src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenUseCase.kt index 19952d4..479010a 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestToken.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenUseCase.kt @@ -4,10 +4,10 @@ import com.dobby.backend.domain.gateway.MemberGateway import com.dobby.backend.domain.gateway.TokenGateway import com.dobby.backend.domain.model.member.Member -class GenerateTestToken( +class GenerateTestTokenUseCase( private val tokenGateway: TokenGateway, private val memberGateway: MemberGateway, -) : UseCase { +) : UseCase { data class Input( val memberId: Long ) diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshToken.kt b/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenUseCase.kt similarity index 85% rename from src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshToken.kt rename to src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenUseCase.kt index 8c881e1..7cffd9a 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshToken.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenUseCase.kt @@ -4,10 +4,10 @@ import com.dobby.backend.domain.gateway.MemberGateway import com.dobby.backend.domain.gateway.TokenGateway import com.dobby.backend.domain.model.member.Member -class GenerateTokenWithRefreshToken( +class GenerateTokenWithRefreshTokenUseCase( private val tokenGateway: TokenGateway, private val memberGateway: MemberGateway, -) : UseCase { +) : UseCase { data class Input( val refreshToken: String, ) diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/GetMemberById.kt b/src/main/kotlin/com/dobby/backend/application/usecase/GetMemberByIdUseCase.kt similarity index 82% rename from src/main/kotlin/com/dobby/backend/application/usecase/GetMemberById.kt rename to src/main/kotlin/com/dobby/backend/application/usecase/GetMemberByIdUseCase.kt index 50c373a..41e53db 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/GetMemberById.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/GetMemberByIdUseCase.kt @@ -3,9 +3,9 @@ package com.dobby.backend.application.usecase import com.dobby.backend.domain.gateway.MemberGateway import com.dobby.backend.domain.model.member.Member -class GetMemberById( +class GetMemberByIdUseCase( private val memberGateway: MemberGateway, -) : UseCase { +) : UseCase { data class Input( val memberId: Long, ) diff --git a/src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt b/src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt index e31df31..da6064f 100644 --- a/src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt @@ -1,8 +1,8 @@ import com.dobby.backend.application.service.AuthService import com.dobby.backend.application.usecase.FetchGoogleUserInfoUseCase import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase -import com.dobby.backend.application.usecase.GenerateTestToken -import com.dobby.backend.application.usecase.GenerateTokenWithRefreshToken +import com.dobby.backend.application.usecase.GenerateTestTokenUseCase +import com.dobby.backend.application.usecase.GenerateTokenWithRefreshTokenUseCase import com.dobby.backend.infrastructure.database.entity.enum.ProviderType import com.dobby.backend.infrastructure.database.entity.enum.RoleType import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleOauthLoginRequest @@ -18,10 +18,10 @@ import org.springframework.test.context.ActiveProfiles class AuthServiceTest : BehaviorSpec({ val fetchGoogleUserInfoUseCase = mockk() val fetchNaverUserInfoUseCase = mockk() - val generateTokenWithRefreshToken = mockk() - val generateTestToken = mockk() + val generateTokenWithRefreshTokenUseCase = mockk() + val generateTestTokenUseCase = mockk() - val oauthService = AuthService(fetchGoogleUserInfoUseCase, fetchNaverUserInfoUseCase, generateTokenWithRefreshToken, generateTestToken) + val oauthService = AuthService(fetchGoogleUserInfoUseCase, fetchNaverUserInfoUseCase, generateTokenWithRefreshTokenUseCase, generateTestTokenUseCase) given("Google OAuth 요청이 들어왔을 때") { val oauthLoginRequest = GoogleOauthLoginRequest(authorizationCode = "valid-auth-code") diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt similarity index 100% rename from src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoTest.kt rename to src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt similarity index 100% rename from src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoTest.kt rename to src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenUseCaseTest.kt similarity index 84% rename from src/test/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenTest.kt rename to src/test/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenUseCaseTest.kt index 437a6e9..22a7422 100644 --- a/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenUseCaseTest.kt @@ -11,10 +11,10 @@ import io.kotest.matchers.shouldBe import io.mockk.every import io.mockk.mockk -class GenerateTestTokenTest: BehaviorSpec({ +class GenerateTestTokenUseCaseTest: BehaviorSpec({ val tokenGateway = mockk() val memberGateway = mockk() - val generateTestToken = GenerateTestToken(tokenGateway, memberGateway) + val generateTestTokenUseCase = GenerateTestTokenUseCase(tokenGateway, memberGateway) given("memberId가 주어졌을 때") { val member = Member(id = 1, oauthEmail = "dlawotn3@naver.com", contactEmail = "dlawotn3@naver.com", @@ -28,8 +28,8 @@ class GenerateTestTokenTest: BehaviorSpec({ every { memberGateway.getById(1) } returns member `when`("execute가 호출되면") { - val input = GenerateTestToken.Input(member.id) - val result = generateTestToken.execute(input) + val input = GenerateTestTokenUseCase.Input(member.id) + val result = generateTestTokenUseCase.execute(input) then("생성된 accessToken과 refreshToken이 반환되어야 한다") { result.accessToken shouldBe accessToken diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenUseCaseTest.kt similarity index 81% rename from src/test/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenTest.kt rename to src/test/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenUseCaseTest.kt index 04baad5..f000d20 100644 --- a/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenUseCaseTest.kt @@ -11,10 +11,10 @@ import io.kotest.matchers.shouldBe import io.mockk.every import io.mockk.mockk -class GenerateTokenWithRefreshTokenTest : BehaviorSpec({ +class GenerateTokenWithRefreshTokenUseCaseTest : BehaviorSpec({ val tokenGateway = mockk() val memberGateway = mockk() - val generateTokenWithRefreshToken = GenerateTokenWithRefreshToken(tokenGateway, memberGateway) + val generateTokenWithRefreshTokenUseCase = GenerateTokenWithRefreshTokenUseCase(tokenGateway, memberGateway) given("유효한 리프레시 토큰이 주어졌을 때") { val validRefreshToken = "validRefreshToken" @@ -30,8 +30,8 @@ class GenerateTokenWithRefreshTokenTest : BehaviorSpec({ every { memberGateway.getById(1) } returns member `when`("execute가 호출되면") { - val input = GenerateTokenWithRefreshToken.Input(refreshToken = validRefreshToken) - val result = generateTokenWithRefreshToken.execute(input) + val input = GenerateTokenWithRefreshTokenUseCase.Input(refreshToken = validRefreshToken) + val result = generateTokenWithRefreshTokenUseCase.execute(input) then("accessToken과 refreshToken이 생성되고, memberId가 포함된다") { result.accessToken shouldBe accessToken @@ -47,10 +47,10 @@ class GenerateTokenWithRefreshTokenTest : BehaviorSpec({ every { tokenGateway.extractMemberIdFromRefreshToken(invalidRefreshToken) } throws IllegalArgumentException("Invalid refresh token") `when`("execute가 호출되면") { - val input = GenerateTokenWithRefreshToken.Input(refreshToken = invalidRefreshToken) + val input = GenerateTokenWithRefreshTokenUseCase.Input(refreshToken = invalidRefreshToken) then("예외가 발생한다") { - val exception = runCatching { generateTokenWithRefreshToken.execute(input) }.exceptionOrNull() + val exception = runCatching { generateTokenWithRefreshTokenUseCase.execute(input) }.exceptionOrNull() exception shouldBe IllegalArgumentException("Invalid refresh token") } } From f607eb123ac0f11eecd1cb3fa4ae13c9b2d28f50 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 10:51:59 +0900 Subject: [PATCH 13/35] refact: delete unused file --- .../com/dobby/backend/config/ApplicationConfig.kt | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt diff --git a/src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt b/src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt deleted file mode 100644 index baf7dc0..0000000 --- a/src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.dobby.backend.config - -import com.dobby.backend.infrastructure.config.properties.S3Properties -import com.dobby.backend.infrastructure.config.properties.TokenProperties -import org.springframework.boot.context.properties.EnableConfigurationProperties -import org.springframework.context.annotation.Configuration - -@Configuration -@EnableConfigurationProperties(TokenProperties::class, S3Properties::class) -class ApplicationConfig { -} From b5e663c60db41b5dfc4b556b079898b618881cff Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 10:52:14 +0900 Subject: [PATCH 14/35] feat: add GoogleAuthGateway for clean-architecture --- .../domain/gateway/feign/GoogleAuthGateway.kt | 9 +++++ .../gateway/GoogleAuthGatewayImpl.kt | 35 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/main/kotlin/com/dobby/backend/domain/gateway/feign/GoogleAuthGateway.kt create mode 100644 src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt diff --git a/src/main/kotlin/com/dobby/backend/domain/gateway/feign/GoogleAuthGateway.kt b/src/main/kotlin/com/dobby/backend/domain/gateway/feign/GoogleAuthGateway.kt new file mode 100644 index 0000000..c251e64 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/domain/gateway/feign/GoogleAuthGateway.kt @@ -0,0 +1,9 @@ +package com.dobby.backend.domain.gateway.feign; + +import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleInfoResponse; +import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleTokenResponse + +interface GoogleAuthGateway { + fun getAccessToken(code: String): GoogleTokenResponse + fun getUserInfo(token: String): GoogleInfoResponse +} diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt new file mode 100644 index 0000000..62fbc16 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt @@ -0,0 +1,35 @@ +package com.dobby.backend.infrastructure.gateway + +import com.dobby.backend.domain.gateway.feign.GoogleAuthGateway +import com.dobby.backend.infrastructure.config.properties.GoogleAuthProperties +import com.dobby.backend.infrastructure.feign.google.GoogleAuthFeignClient +import com.dobby.backend.infrastructure.feign.google.GoogleUserInfoFeginClient +import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleTokenRequest +import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleInfoResponse +import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleTokenResponse +import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.stereotype.Component + +@Component +@EnableConfigurationProperties(GoogleAuthProperties::class) +class GoogleAuthGatewayImpl( + private val googleAuthProperties: GoogleAuthProperties, + private val googleAuthFeignClient: GoogleAuthFeignClient, + private val googleUserInfoFeignClient: GoogleUserInfoFeginClient +): GoogleAuthGateway { + + override fun getAccessToken(code: String): GoogleTokenResponse { + val googleTokenRequest = GoogleTokenRequest( + code = code, + clientId = googleAuthProperties.clientId, + clientSecret = googleAuthProperties.clientSecret, + redirectUri = googleAuthProperties.redirectUri + ) + + return googleAuthFeignClient.getAccessToken(googleTokenRequest) + } + + override fun getUserInfo(token: String): GoogleInfoResponse { + return googleUserInfoFeignClient.getUserInfo(token) + } +} From 12497207e02ffa06cb1b7636565c19d6ba53f957 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 10:52:48 +0900 Subject: [PATCH 15/35] refact: move NaverAuthGateway to feign package --- .../backend/application/usecase/FetchNaverUserInfoUseCase.kt | 5 +---- .../backend/domain/gateway/{ => feign}/NaverAuthGateway.kt | 2 +- .../backend/infrastructure/gateway/NaverAuthGatewayImpl.kt | 4 ++-- .../application/usecase/FetchNaverUserInfoUseCaseTest.kt | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) rename src/main/kotlin/com/dobby/backend/domain/gateway/{ => feign}/NaverAuthGateway.kt (84%) diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt index 50cc2ef..9f2223f 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt @@ -2,14 +2,11 @@ package com.dobby.backend.application.usecase import com.dobby.backend.domain.exception.SignInMemberException import com.dobby.backend.domain.gateway.MemberGateway -import com.dobby.backend.domain.gateway.NaverAuthGateway +import com.dobby.backend.domain.gateway.feign.NaverAuthGateway import com.dobby.backend.domain.gateway.TokenGateway import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.infrastructure.database.entity.enum.ProviderType import com.dobby.backend.infrastructure.database.entity.enum.RoleType -import com.dobby.backend.infrastructure.database.repository.MemberRepository -import com.dobby.backend.infrastructure.token.JwtTokenProvider -import com.dobby.backend.util.AuthenticationUtils import java.lang.Exception class FetchNaverUserInfoUseCase( diff --git a/src/main/kotlin/com/dobby/backend/domain/gateway/NaverAuthGateway.kt b/src/main/kotlin/com/dobby/backend/domain/gateway/feign/NaverAuthGateway.kt similarity index 84% rename from src/main/kotlin/com/dobby/backend/domain/gateway/NaverAuthGateway.kt rename to src/main/kotlin/com/dobby/backend/domain/gateway/feign/NaverAuthGateway.kt index 8b96dff..fc31905 100644 --- a/src/main/kotlin/com/dobby/backend/domain/gateway/NaverAuthGateway.kt +++ b/src/main/kotlin/com/dobby/backend/domain/gateway/feign/NaverAuthGateway.kt @@ -1,4 +1,4 @@ -package com.dobby.backend.domain.gateway +package com.dobby.backend.domain.gateway.feign import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverInfoResponse diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt index d917fea..0a62068 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt @@ -1,6 +1,6 @@ package com.dobby.backend.infrastructure.gateway -import com.dobby.backend.domain.gateway.NaverAuthGateway +import com.dobby.backend.domain.gateway.feign.NaverAuthGateway import com.dobby.backend.infrastructure.config.properties.NaverAuthProperties import com.dobby.backend.infrastructure.feign.naver.NaverAuthFeignClient import com.dobby.backend.infrastructure.feign.naver.NaverUserInfoFeignClient @@ -16,7 +16,7 @@ class NaverAuthGatewayImpl( private val naverAuthProperties: NaverAuthProperties, private val naverAuthFeignClient: NaverAuthFeignClient, private val naverUserInfoFeignClient: NaverUserInfoFeignClient -) : NaverAuthGateway { +): NaverAuthGateway { override fun getAccessToken(authorizationCode: String, state: String): String? { val naverTokenRequest = NaverTokenRequest( diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt index b20a1e0..05ae9b5 100644 --- a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt @@ -1,6 +1,6 @@ import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase import com.dobby.backend.domain.gateway.MemberGateway -import com.dobby.backend.domain.gateway.NaverAuthGateway +import com.dobby.backend.domain.gateway.feign.NaverAuthGateway import com.dobby.backend.domain.gateway.TokenGateway import com.dobby.backend.domain.model.member.Member import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus From 42579a9e441e6eb03edd773605cb058dd3bd12d3 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 11:42:47 +0900 Subject: [PATCH 16/35] test: add FetchGoogleUserInfoUseCase test --- .../application/service/AuthServiceTest.kt | 50 ------------- .../usecase/FetchGoogleUserInfoUseCaseTest.kt | 74 ++++++++++--------- 2 files changed, 41 insertions(+), 83 deletions(-) delete mode 100644 src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt diff --git a/src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt b/src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt deleted file mode 100644 index da6064f..0000000 --- a/src/test/kotlin/com/dobby/backend/application/service/AuthServiceTest.kt +++ /dev/null @@ -1,50 +0,0 @@ -import com.dobby.backend.application.service.AuthService -import com.dobby.backend.application.usecase.FetchGoogleUserInfoUseCase -import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase -import com.dobby.backend.application.usecase.GenerateTestTokenUseCase -import com.dobby.backend.application.usecase.GenerateTokenWithRefreshTokenUseCase -import com.dobby.backend.infrastructure.database.entity.enum.ProviderType -import com.dobby.backend.infrastructure.database.entity.enum.RoleType -import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleOauthLoginRequest -import com.dobby.backend.presentation.api.dto.response.MemberResponse -import com.dobby.backend.presentation.api.dto.response.auth.OauthLoginResponse -import io.kotest.core.spec.style.BehaviorSpec -import io.kotest.matchers.shouldBe -import io.mockk.every -import io.mockk.mockk -import org.springframework.test.context.ActiveProfiles - -@ActiveProfiles("test") -class AuthServiceTest : BehaviorSpec({ - val fetchGoogleUserInfoUseCase = mockk() - val fetchNaverUserInfoUseCase = mockk() - val generateTokenWithRefreshTokenUseCase = mockk() - val generateTestTokenUseCase = mockk() - - val oauthService = AuthService(fetchGoogleUserInfoUseCase, fetchNaverUserInfoUseCase, generateTokenWithRefreshTokenUseCase, generateTestTokenUseCase) - - given("Google OAuth 요청이 들어왔을 때") { - val oauthLoginRequest = GoogleOauthLoginRequest(authorizationCode = "valid-auth-code") - val expectedResponse = OauthLoginResponse( - isRegistered = true, - accessToken = "mock-access-token", - refreshToken = "mock-refresh-token", - memberInfo = MemberResponse( - memberId = 1L, - oauthEmail = "test@example.com", - name = "Test User", - role = RoleType.PARTICIPANT, - provider = ProviderType.GOOGLE - ) - ) - - `when`("FetchGoogleUserInfoUseCase가 올바른 응답을 반환하면") { - every { fetchGoogleUserInfoUseCase.execute(oauthLoginRequest) } returns expectedResponse - - then("OauthService는 동일한 응답을 반환해야 한다") { - val result = oauthService.getGoogleUserInfo(oauthLoginRequest) - result shouldBe expectedResponse - } - } - } -}) diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt index e1b1a9a..ab8602c 100644 --- a/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt @@ -1,14 +1,11 @@ import com.dobby.backend.application.usecase.FetchGoogleUserInfoUseCase -import com.dobby.backend.infrastructure.config.properties.GoogleAuthProperties -import com.dobby.backend.infrastructure.database.entity.member.MemberEntity +import com.dobby.backend.domain.gateway.MemberGateway +import com.dobby.backend.domain.gateway.TokenGateway +import com.dobby.backend.domain.gateway.feign.GoogleAuthGateway +import com.dobby.backend.domain.model.member.Member import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.infrastructure.database.entity.enum.ProviderType import com.dobby.backend.infrastructure.database.entity.enum.RoleType -import com.dobby.backend.infrastructure.database.repository.MemberRepository -import com.dobby.backend.infrastructure.feign.google.GoogleAuthFeignClient -import com.dobby.backend.infrastructure.feign.google.GoogleUserInfoFeginClient -import com.dobby.backend.infrastructure.token.JwtTokenProvider -import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleOauthLoginRequest import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleTokenResponse import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe @@ -18,53 +15,64 @@ import org.springframework.test.context.ActiveProfiles @ActiveProfiles("test") class FetchGoogleUserInfoUseCaseTest : BehaviorSpec({ - val googleAuthFeignClient = mockk() - val googleUserInfoFeginClient = mockk() - val jwtTokenProvider = mockk() - val googleAuthProperties = mockk() - val memberRepository = mockk() + val googleAuthGateway = mockk() + val memberGateway = mockk() + val tokenGateway = mockk() val fetchGoogleUserInfoUseCase = FetchGoogleUserInfoUseCase( - googleAuthFeignClient, - googleUserInfoFeginClient, - jwtTokenProvider, - googleAuthProperties, - memberRepository + googleAuthGateway, + memberGateway, + tokenGateway ) given("Google OAuth 요청이 들어왔을 때") { - val oauthLoginRequest = GoogleOauthLoginRequest(authorizationCode = "valid-auth-code") - val mockMember = MemberEntity( + val input = FetchGoogleUserInfoUseCase.Input(authorizationCode = "valid-auth-code") + val mockMember = Member( id = 1L, oauthEmail = "test@example.com", - provider = ProviderType.GOOGLE, + name = "Test User", status = MemberStatus.ACTIVE, role = RoleType.PARTICIPANT, contactEmail = "contact@example.com", - name = "Test User" + provider = ProviderType.GOOGLE ) - every { googleAuthProperties.clientId } returns "mock-client-id" - every { googleAuthProperties.clientSecret } returns "mock-client-secret" - every { googleAuthProperties.redirectUri } returns "http://localhost/callback" - every { googleAuthFeignClient.getAccessToken(any()) } returns GoogleTokenResponse("mock-access-token") - every { googleUserInfoFeginClient.getUserInfo(any()) } returns mockk { + val mockEmptyMember = null + val mockGoogleTokenResponse = GoogleTokenResponse("mock-access-token") + every { googleAuthGateway.getAccessToken(any()) } returns mockGoogleTokenResponse + every { googleAuthGateway.getUserInfo("mock-access-token") } returns mockk { every { email } returns "test@example.com" every { name } returns "Test User" } - every { memberRepository.findByOauthEmailAndStatus("test@example.com", MemberStatus.ACTIVE) } returns mockMember - every { jwtTokenProvider.generateAccessToken(any()) } returns "mock-jwt-access-token" - every { jwtTokenProvider.generateRefreshToken(any()) } returns "mock-jwt-refresh-token" - `when`("정상적으로 모든 데이터가 주어지면") { - val result = fetchGoogleUserInfoUseCase.execute(oauthLoginRequest) + every { tokenGateway.generateAccessToken(any()) } returns "mock-jwt-access-token" + every { tokenGateway.generateRefreshToken(any()) } returns "mock-jwt-refresh-token" + + // 테스트 1: 등록된 멤버가 있는 경우 + every { memberGateway.findByOauthEmailAndStatus("test@example.com", MemberStatus.ACTIVE) } returns mockMember + + `when`("정상적으로 등록된 유저가 있는 경우") { + val result: FetchGoogleUserInfoUseCase.Output = fetchGoogleUserInfoUseCase.execute(input) then("유저 정보를 포함한 OauthLoginResponse를 반환해야 한다") { result.isRegistered shouldBe true result.accessToken shouldBe "mock-jwt-access-token" result.refreshToken shouldBe "mock-jwt-refresh-token" - result.memberInfo.oauthEmail shouldBe "test@example.com" - result.memberInfo.name shouldBe "Test User" + result.memberId shouldBe 1L + result.oauthEmail shouldBe "test@example.com" + } + } + + // 테스트 2: 등록된 멤버가 없는 경우 + every { memberGateway.findByOauthEmailAndStatus("test@example.com", MemberStatus.ACTIVE) } returns mockEmptyMember + + `when`("등록되지 않은 유저가 있는 경우") { + val result: FetchGoogleUserInfoUseCase.Output = fetchGoogleUserInfoUseCase.execute(input) + + then("isRegistered는 false, memberId는 null이어야 한다") { + result.isRegistered shouldBe false + result.memberId shouldBe null + result.oauthEmail shouldBe "test@example.com" } } } From c404b40021948ea77861c5ced03de2f79183ecb8 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 11:43:04 +0900 Subject: [PATCH 17/35] refact: refactor FetchGoogleUserInfoUseCase logic --- .../usecase/FetchGoogleUserInfoUseCase.kt | 90 ++++++++++--------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt index abbaaae..f687a60 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt @@ -1,64 +1,66 @@ package com.dobby.backend.application.usecase -import com.dobby.backend.application.mapper.OauthUserMapper import com.dobby.backend.domain.exception.SignInMemberException -import com.dobby.backend.infrastructure.config.properties.GoogleAuthProperties +import com.dobby.backend.domain.gateway.MemberGateway +import com.dobby.backend.domain.gateway.TokenGateway +import com.dobby.backend.domain.gateway.feign.GoogleAuthGateway import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.infrastructure.database.entity.enum.ProviderType -import com.dobby.backend.infrastructure.database.repository.MemberRepository -import com.dobby.backend.infrastructure.feign.google.GoogleAuthFeignClient -import com.dobby.backend.infrastructure.feign.google.GoogleUserInfoFeginClient -import com.dobby.backend.infrastructure.token.JwtTokenProvider -import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleTokenRequest -import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleOauthLoginRequest -import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleTokenResponse -import com.dobby.backend.presentation.api.dto.response.auth.OauthLoginResponse -import com.dobby.backend.util.AuthenticationUtils +import com.dobby.backend.infrastructure.database.entity.enum.RoleType class FetchGoogleUserInfoUseCase( - private val googleAuthFeignClient: GoogleAuthFeignClient, - private val googleUserInfoFeginClient: GoogleUserInfoFeginClient, - private val jwtTokenProvider: JwtTokenProvider, - private val googleAuthProperties: GoogleAuthProperties, - private val memberRepository: MemberRepository -) : UseCase { + private val googleAuthGateway: GoogleAuthGateway, + private val memberGateway: MemberGateway, + private val jwtTokenGateway: TokenGateway +) : UseCase { - override fun execute(input: GoogleOauthLoginRequest): OauthLoginResponse { - try { - val googleTokenRequest = GoogleTokenRequest( - code = input.authorizationCode, - clientId = googleAuthProperties.clientId, - clientSecret = googleAuthProperties.clientSecret, - redirectUri = googleAuthProperties.redirectUri - ) + data class Input( + val authorizationCode: String + ) - val oauthRes = fetchAccessToken(googleTokenRequest) - val oauthToken = oauthRes.accessToken + data class Output( + val isRegistered: Boolean, + val accessToken: String?, + val refreshToken: String?, + val memberId: Long?, + val oauthEmail: String, + val oauthName: String?, + val role: RoleType?, + val provider: ProviderType + ) - val userInfo = googleUserInfoFeginClient.getUserInfo("Bearer $oauthToken") - val email = userInfo.email - val regMember = memberRepository.findByOauthEmailAndStatus(email, MemberStatus.ACTIVE) - ?: throw SignInMemberException() + override fun execute(input: Input): Output { + val oauthToken = googleAuthGateway.getAccessToken(input.authorizationCode).accessToken + val userInfo = googleAuthGateway.getUserInfo(oauthToken) + val email = userInfo.email + val member = email.let { memberGateway.findByOauthEmailAndStatus(it, MemberStatus.ACTIVE) } - val regMemberAuthentication = AuthenticationUtils.createAuthentication(regMember) - val jwtAccessToken = jwtTokenProvider.generateAccessToken(regMemberAuthentication) - val jwtRefreshToken = jwtTokenProvider.generateRefreshToken(regMemberAuthentication) + return if (member != null) { + val jwtAccessToken = jwtTokenGateway.generateAccessToken(member) + val jwtRefreshToken = jwtTokenGateway.generateRefreshToken(member) - return OauthUserMapper.toDto( + Output( isRegistered = true, accessToken = jwtAccessToken, refreshToken = jwtRefreshToken, - oauthEmail = regMember.oauthEmail, - oauthName = regMember.name ?: throw SignInMemberException(), - role = regMember.role ?: throw SignInMemberException(), + memberId = member.id, + oauthEmail = member.oauthEmail, + oauthName = member.name ?: throw SignInMemberException(), + role = member.role ?: throw SignInMemberException(), + provider = ProviderType.GOOGLE + ) + } else { + // 등록된 멤버가 없으면 isRegistered = false, memberId = null + Output( + isRegistered = false, + accessToken = null, + refreshToken = null, + memberId = null, + oauthEmail = email, + oauthName = null, + role = null, provider = ProviderType.GOOGLE ) - } catch (e: SignInMemberException) { - throw SignInMemberException() } } - - private fun fetchAccessToken(googleTokenRequest: GoogleTokenRequest): GoogleTokenResponse { - return googleAuthFeignClient.getAccessToken(googleTokenRequest) - } } From 097aff56d1a3f77fccd6a0ad757e460ecddaebd5 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 11:44:12 +0900 Subject: [PATCH 18/35] refact: refactor signInWithGoogle Controller due to changed logic --- .../application/service/AuthService.kt | 22 ++++++++++----- .../usecase/FetchNaverUserInfoUseCase.kt | 2 +- .../com/dobby/backend/config/AppConfig.kt | 27 +++++++++++++++++++ .../gateway/GoogleAuthGatewayImpl.kt | 4 +-- .../api/controller/AuthController.kt | 16 +++++++++-- 5 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 src/main/kotlin/com/dobby/backend/config/AppConfig.kt diff --git a/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt index f9b1b26..a562487 100644 --- a/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt +++ b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt @@ -1,19 +1,29 @@ package com.dobby.backend.application.service import com.dobby.backend.application.usecase.* -import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleOauthLoginRequest -import com.dobby.backend.presentation.api.dto.response.auth.OauthLoginResponse -import org.springframework.stereotype.Service -@Service class AuthService( private val fetchGoogleUserInfoUseCase: FetchGoogleUserInfoUseCase, private val fetchNaverUserInfoUseCase: FetchNaverUserInfoUseCase, private val generateTokenWithRefreshTokenUseCase: GenerateTokenWithRefreshTokenUseCase, private val generateTestTokenUseCase: GenerateTestTokenUseCase, ) { - fun getGoogleUserInfo(oauthLoginRequest: GoogleOauthLoginRequest): OauthLoginResponse { - return fetchGoogleUserInfoUseCase.execute(oauthLoginRequest) + fun getGoogleUserInfo(authorizationCode: String): FetchGoogleUserInfoUseCase.Output { + val result = fetchGoogleUserInfoUseCase.execute( + FetchGoogleUserInfoUseCase.Input( + authorizationCode = authorizationCode + ) + ) + return FetchGoogleUserInfoUseCase.Output( + isRegistered = result.isRegistered, + accessToken = result.accessToken, + refreshToken = result.refreshToken, + memberId = result.memberId, + oauthEmail = result.oauthEmail, + oauthName = result.oauthName, + role = result.role, + provider = result.provider, + ) } fun getNaverUserInfo(authorizationCode: String, state: String): FetchNaverUserInfoUseCase.Output { diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt index 9f2223f..7b1a154 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt @@ -26,7 +26,7 @@ class FetchNaverUserInfoUseCase( val refreshToken: String?, val memberId: Long?, val oauthEmail: String, - val oauthName: String, + val oauthName: String?, val role: RoleType?, val provider: ProviderType ) diff --git a/src/main/kotlin/com/dobby/backend/config/AppConfig.kt b/src/main/kotlin/com/dobby/backend/config/AppConfig.kt new file mode 100644 index 0000000..c2c2678 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/config/AppConfig.kt @@ -0,0 +1,27 @@ +package com.dobby.backend.config + +import com.dobby.backend.application.service.AuthService +import com.dobby.backend.application.usecase.FetchGoogleUserInfoUseCase +import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase +import com.dobby.backend.application.usecase.GenerateTestTokenUseCase +import com.dobby.backend.application.usecase.GenerateTokenWithRefreshTokenUseCase +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +@Configuration +class AppConfig { + @Bean + fun authService( + fetchGoogleUserInfoUseCase: FetchGoogleUserInfoUseCase, + fetchNaverUserInfoUseCase: FetchNaverUserInfoUseCase, + generateTokenWithRefreshTokenUseCase: GenerateTokenWithRefreshTokenUseCase, + generateTestTokenUseCase: GenerateTestTokenUseCase + ): AuthService { + return AuthService( + fetchGoogleUserInfoUseCase, + fetchNaverUserInfoUseCase, + generateTokenWithRefreshTokenUseCase, + generateTestTokenUseCase + ) + } +} diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt index 62fbc16..3a01d45 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt @@ -29,7 +29,7 @@ class GoogleAuthGatewayImpl( return googleAuthFeignClient.getAccessToken(googleTokenRequest) } - override fun getUserInfo(token: String): GoogleInfoResponse { - return googleUserInfoFeignClient.getUserInfo(token) + override fun getUserInfo(accessToken: String): GoogleInfoResponse { + return googleUserInfoFeignClient.getUserInfo("Bearer $accessToken") } } diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt b/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt index 2cdae40..ca1b71a 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt @@ -26,7 +26,19 @@ class AuthController( @RequestParam role : RoleType, @RequestBody @Valid request: GoogleOauthLoginRequest ): OauthLoginResponse { - return authService.getGoogleUserInfo(request) + val result = authService.getGoogleUserInfo(request.authorizationCode) + return OauthLoginResponse( + isRegistered = result.isRegistered, + accessToken = result.accessToken, + refreshToken = result.refreshToken, + memberInfo = MemberResponse( + memberId = result.memberId, + name = result.oauthName, + oauthEmail = result.oauthEmail, + role = result.role, + provider = result.provider, + ) + ) } @PostMapping("/login/naver") @@ -41,7 +53,7 @@ class AuthController( accessToken = result.accessToken, refreshToken = result.refreshToken, memberInfo = MemberResponse( - memberId = null, + memberId = result.memberId, name = result.oauthName, oauthEmail = result.oauthEmail, role = result.role, From 01722ed8313cd9e159cc09e9cb7d3fa2fd3c3833 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 11:44:42 +0900 Subject: [PATCH 19/35] style: rename variables for clarity --- .../dobby/backend/domain/gateway/feign/GoogleAuthGateway.kt | 2 +- .../infrastructure/feign/naver/NaverUserInfoFeignClient.kt | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/domain/gateway/feign/GoogleAuthGateway.kt b/src/main/kotlin/com/dobby/backend/domain/gateway/feign/GoogleAuthGateway.kt index c251e64..c2b4bdb 100644 --- a/src/main/kotlin/com/dobby/backend/domain/gateway/feign/GoogleAuthGateway.kt +++ b/src/main/kotlin/com/dobby/backend/domain/gateway/feign/GoogleAuthGateway.kt @@ -5,5 +5,5 @@ import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleTokenRe interface GoogleAuthGateway { fun getAccessToken(code: String): GoogleTokenResponse - fun getUserInfo(token: String): GoogleInfoResponse + fun getUserInfo(accessToken: String): GoogleInfoResponse } diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverUserInfoFeignClient.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverUserInfoFeignClient.kt index d0950f9..5fca404 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverUserInfoFeignClient.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverUserInfoFeignClient.kt @@ -11,5 +11,7 @@ import org.springframework.web.bind.annotation.RequestHeader ) interface NaverUserInfoFeignClient { @PostMapping - fun getUserInfo(@RequestHeader("Authorization") accessToken: String): NaverInfoResponse + fun getUserInfo( + @RequestHeader("Authorization") accessToken: String + ): NaverInfoResponse } From 63c5c48d3b10afa1f0c5385849b83d057c0e95ce Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 11:57:35 +0900 Subject: [PATCH 20/35] refact: refactor FetchNaverUserInfoUseCase logic --- .../application/mapper/OauthUserMapper.kt | 32 --------- .../usecase/FetchGoogleUserInfoUseCase.kt | 5 +- .../usecase/FetchNaverUserInfoUseCase.kt | 67 +++++++++---------- .../domain/gateway/feign/NaverAuthGateway.kt | 3 +- .../gateway/NaverAuthGatewayImpl.kt | 5 +- .../application/mapper/OauthUserMapperTest.kt | 47 ------------- .../usecase/FetchNaverUserInfoUseCaseTest.kt | 4 +- 7 files changed, 40 insertions(+), 123 deletions(-) delete mode 100644 src/main/kotlin/com/dobby/backend/application/mapper/OauthUserMapper.kt delete mode 100644 src/test/kotlin/com/dobby/backend/application/mapper/OauthUserMapperTest.kt diff --git a/src/main/kotlin/com/dobby/backend/application/mapper/OauthUserMapper.kt b/src/main/kotlin/com/dobby/backend/application/mapper/OauthUserMapper.kt deleted file mode 100644 index 15abb13..0000000 --- a/src/main/kotlin/com/dobby/backend/application/mapper/OauthUserMapper.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.dobby.backend.application.mapper - -import com.dobby.backend.infrastructure.database.entity.enum.ProviderType -import com.dobby.backend.infrastructure.database.entity.enum.RoleType -import com.dobby.backend.presentation.api.dto.response.MemberResponse -import com.dobby.backend.presentation.api.dto.response.auth.OauthLoginResponse - -object OauthUserMapper { - fun toDto( - isRegistered: Boolean, - accessToken: String, - refreshToken: String, - oauthEmail: String, - oauthName: String, - role: RoleType, - provider: ProviderType, - memberId: Long? = null - ): OauthLoginResponse { - return OauthLoginResponse( - isRegistered = isRegistered, - accessToken = accessToken, - refreshToken = refreshToken, - memberInfo = MemberResponse( - memberId = memberId, - oauthEmail = oauthEmail, - name = oauthName, - role = role, - provider = provider - ) - ) - } -} diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt index f687a60..c742611 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt @@ -1,6 +1,5 @@ package com.dobby.backend.application.usecase -import com.dobby.backend.domain.exception.SignInMemberException import com.dobby.backend.domain.gateway.MemberGateway import com.dobby.backend.domain.gateway.TokenGateway import com.dobby.backend.domain.gateway.feign.GoogleAuthGateway @@ -45,8 +44,8 @@ class FetchGoogleUserInfoUseCase( refreshToken = jwtRefreshToken, memberId = member.id, oauthEmail = member.oauthEmail, - oauthName = member.name ?: throw SignInMemberException(), - role = member.role ?: throw SignInMemberException(), + oauthName = member.name, + role = member.role, provider = ProviderType.GOOGLE ) } else { diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt index 7b1a154..a734635 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt @@ -1,13 +1,11 @@ package com.dobby.backend.application.usecase -import com.dobby.backend.domain.exception.SignInMemberException import com.dobby.backend.domain.gateway.MemberGateway import com.dobby.backend.domain.gateway.feign.NaverAuthGateway import com.dobby.backend.domain.gateway.TokenGateway import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.infrastructure.database.entity.enum.ProviderType import com.dobby.backend.infrastructure.database.entity.enum.RoleType -import java.lang.Exception class FetchNaverUserInfoUseCase( private val naverAuthGateway: NaverAuthGateway, @@ -20,53 +18,50 @@ class FetchNaverUserInfoUseCase( val state: String ) + // TODO: 테스트 후, oauthEmail not null 처리 data class Output( val isRegistered: Boolean, val accessToken: String?, val refreshToken: String?, val memberId: Long?, - val oauthEmail: String, + val oauthEmail: String?, val oauthName: String?, val role: RoleType?, val provider: ProviderType ) override fun execute(input: Input): Output { - try { - val oauthToken = naverAuthGateway.getAccessToken(input.authorizationCode, input.state) - val userInfo = oauthToken?.let { naverAuthGateway.getUserInfo(it) } - val email = userInfo?.email - val member = email?.let { memberGateway.findByOauthEmailAndStatus(it, MemberStatus.ACTIVE) } + val oauthToken = naverAuthGateway.getAccessToken(input.authorizationCode, input.state).accessToken + val userInfo = oauthToken?.let { naverAuthGateway.getUserInfo(it) } + val email = userInfo?.email + val member = email?.let { memberGateway.findByOauthEmailAndStatus(it, MemberStatus.ACTIVE) } - return if (member != null) { - val jwtAccessToken = jwtTokenGateway.generateAccessToken(member) - val jwtRefreshToken = jwtTokenGateway.generateRefreshToken(member) + return if (member != null) { + val jwtAccessToken = jwtTokenGateway.generateAccessToken(member) + val jwtRefreshToken = jwtTokenGateway.generateRefreshToken(member) - Output( - isRegistered = true, - accessToken = jwtAccessToken, - refreshToken = jwtRefreshToken, - memberId = member.id, - oauthEmail = member.oauthEmail, - oauthName = member.name ?: throw SignInMemberException(), - role = member.role ?: throw SignInMemberException(), - provider = ProviderType.NAVER - ) - } else { - // 등록된 멤버가 없으면 isRegistered = false, memberId = null - Output( - isRegistered = false, - accessToken = null, - refreshToken = null, - memberId = null, - oauthEmail = email ?: "", - oauthName = "", - role = null, - provider = ProviderType.NAVER - ) - } - } catch (e: Exception) { - throw SignInMemberException() + Output( + isRegistered = true, + accessToken = jwtAccessToken, + refreshToken = jwtRefreshToken, + memberId = member.id, + oauthEmail = member.oauthEmail, + oauthName = member.name, + role = member.role, + provider = ProviderType.NAVER + ) + } else { + // 등록된 멤버가 없으면 isRegistered = false, memberId = null + Output( + isRegistered = false, + accessToken = null, + refreshToken = null, + memberId = null, + oauthEmail = email, + oauthName = null, + role = null, + provider = ProviderType.NAVER + ) } } } diff --git a/src/main/kotlin/com/dobby/backend/domain/gateway/feign/NaverAuthGateway.kt b/src/main/kotlin/com/dobby/backend/domain/gateway/feign/NaverAuthGateway.kt index fc31905..11cefd0 100644 --- a/src/main/kotlin/com/dobby/backend/domain/gateway/feign/NaverAuthGateway.kt +++ b/src/main/kotlin/com/dobby/backend/domain/gateway/feign/NaverAuthGateway.kt @@ -1,8 +1,9 @@ package com.dobby.backend.domain.gateway.feign import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverInfoResponse +import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverTokenResponse interface NaverAuthGateway { - fun getAccessToken(authorizationCode: String, state: String): String? + fun getAccessToken(authorizationCode: String, state: String): NaverTokenResponse fun getUserInfo(accessToken: String): NaverInfoResponse? } diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt index 0a62068..e356236 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt @@ -18,7 +18,7 @@ class NaverAuthGatewayImpl( private val naverUserInfoFeignClient: NaverUserInfoFeignClient ): NaverAuthGateway { - override fun getAccessToken(authorizationCode: String, state: String): String? { + override fun getAccessToken(authorizationCode: String, state: String): NaverTokenResponse { val naverTokenRequest = NaverTokenRequest( grantType = "authorization_code", clientId = naverAuthProperties.clientId, @@ -27,8 +27,7 @@ class NaverAuthGatewayImpl( state = state ) - val tokenResponse: NaverTokenResponse = naverAuthFeignClient.getAccessToken(naverTokenRequest) - return tokenResponse.accessToken + return naverAuthFeignClient.getAccessToken(naverTokenRequest) } override fun getUserInfo(accessToken: String): NaverInfoResponse? { diff --git a/src/test/kotlin/com/dobby/backend/application/mapper/OauthUserMapperTest.kt b/src/test/kotlin/com/dobby/backend/application/mapper/OauthUserMapperTest.kt deleted file mode 100644 index 4d81da4..0000000 --- a/src/test/kotlin/com/dobby/backend/application/mapper/OauthUserMapperTest.kt +++ /dev/null @@ -1,47 +0,0 @@ -package com.dobby.backend.application.mapper - -import com.dobby.backend.infrastructure.database.entity.enum.ProviderType -import com.dobby.backend.infrastructure.database.entity.enum.RoleType -import io.kotest.core.spec.style.BehaviorSpec -import io.kotest.matchers.shouldBe -import org.springframework.test.context.ActiveProfiles - -@ActiveProfiles("test") -class OauthUserMapperTest : BehaviorSpec({ - given("OauthUserMapper가 호출될 때") { - val isRegistered = true - val accessToken = "mock-access-token" - val refreshToken = "mock-refresh-token" - val oauthEmail = "test@example.com" - val oauthName = "Test User" - val role = RoleType.PARTICIPANT - val provider = ProviderType.GOOGLE - val memberId = 1L - - `when`("toDto 메서드가 호출되면") { - val result = OauthUserMapper.toDto( - isRegistered = isRegistered, - accessToken = accessToken, - refreshToken = refreshToken, - oauthEmail = oauthEmail, - oauthName = oauthName, - role = role, - provider = provider, - memberId = memberId - ) - - then("올바른 OauthLoginResponse가 반환되어야 한다") { - result.isRegistered shouldBe isRegistered - result.accessToken shouldBe accessToken - result.refreshToken shouldBe refreshToken - - val memberInfo = result.memberInfo - memberInfo.memberId shouldBe memberId - memberInfo.oauthEmail shouldBe oauthEmail - memberInfo.name shouldBe oauthName - memberInfo.role shouldBe role - memberInfo.provider shouldBe provider - } - } - } -}) diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt index 05ae9b5..ea9b0f2 100644 --- a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt @@ -6,6 +6,7 @@ import com.dobby.backend.domain.model.member.Member import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.infrastructure.database.entity.enum.ProviderType import com.dobby.backend.infrastructure.database.entity.enum.RoleType +import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverTokenResponse import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe import io.mockk.every @@ -37,7 +38,8 @@ class FetchNaverUserInfoUseCaseTest : BehaviorSpec({ ) val mockEmptyMember = null - every { naverAuthGateway.getAccessToken(any(), any()) } returns "mock-access-token" + val mockNaverTokenResponse = NaverTokenResponse("mock-access-token") + every { naverAuthGateway.getAccessToken(any(), any()) } returns mockNaverTokenResponse every { naverAuthGateway.getUserInfo("mock-access-token") } returns mockk { every { email } returns "test@example.com" every { name } returns "Test User" From 8a2766603286e8033ceccd3b9438a965d14bd987 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 18:31:27 +0900 Subject: [PATCH 21/35] feat: add EnableConfigurationProperties for OAuth --- .../backend/config/{AppConfig.kt => ApplicationConfig.kt} | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) rename src/main/kotlin/com/dobby/backend/config/{AppConfig.kt => ApplicationConfig.kt} (65%) diff --git a/src/main/kotlin/com/dobby/backend/config/AppConfig.kt b/src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt similarity index 65% rename from src/main/kotlin/com/dobby/backend/config/AppConfig.kt rename to src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt index c2c2678..e899e7b 100644 --- a/src/main/kotlin/com/dobby/backend/config/AppConfig.kt +++ b/src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt @@ -5,11 +5,17 @@ import com.dobby.backend.application.usecase.FetchGoogleUserInfoUseCase import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase import com.dobby.backend.application.usecase.GenerateTestTokenUseCase import com.dobby.backend.application.usecase.GenerateTokenWithRefreshTokenUseCase +import com.dobby.backend.infrastructure.config.properties.GoogleAuthProperties +import com.dobby.backend.infrastructure.config.properties.NaverAuthProperties +import com.dobby.backend.infrastructure.config.properties.S3Properties +import com.dobby.backend.infrastructure.config.properties.TokenProperties +import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @Configuration -class AppConfig { +@EnableConfigurationProperties(TokenProperties::class, S3Properties::class, GoogleAuthProperties::class, NaverAuthProperties::class) +class ApplicationConfig { @Bean fun authService( fetchGoogleUserInfoUseCase: FetchGoogleUserInfoUseCase, From a2aa734f50aa52f2129c13c0a9ea8a9c913a35e6 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 18:32:38 +0900 Subject: [PATCH 22/35] fix: fix GoogleAuthFeignClient logic --- .../feign/google/GoogleAuthFeignClient.kt | 14 +++++++++----- .../feign/google/GoogleUserInfoFeginClient.kt | 10 ++++++---- .../gateway/GoogleAuthGatewayImpl.kt | 11 ++++------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleAuthFeignClient.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleAuthFeignClient.kt index d7bd791..7649336 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleAuthFeignClient.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleAuthFeignClient.kt @@ -1,17 +1,21 @@ package com.dobby.backend.infrastructure.feign.google -import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleTokenRequest import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleTokenResponse import org.springframework.cloud.openfeign.FeignClient import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestParam @FeignClient( name = "google-auth-feign-client", - url = "https://oauth2.googleapis.com", + url = "https://oauth2.googleapis.com/token", ) interface GoogleAuthFeignClient { - @PostMapping("/token") - fun getAccessToken(@RequestBody googleTokenRequest: GoogleTokenRequest + @PostMapping + fun getAccessToken( + @RequestParam(name = "code") code: String, + @RequestParam(name = "client_id") clientId: String, + @RequestParam(name = "client_secret") clientSecret: String, + @RequestParam(name = "redirect_uri") redirectUri: String, + @RequestParam(name = "grant_type") grantType: String = "authorization_code", ): GoogleTokenResponse } diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleUserInfoFeginClient.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleUserInfoFeginClient.kt index 05d6dba..b7591f2 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleUserInfoFeginClient.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleUserInfoFeginClient.kt @@ -3,13 +3,15 @@ package com.dobby.backend.infrastructure.feign.google import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleInfoResponse import org.springframework.cloud.openfeign.FeignClient import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestHeader @FeignClient( - name= "google-userinfo-feign-client", + name = "google-userinfo-feign-client", url = "https://www.googleapis.com" ) interface GoogleUserInfoFeginClient { - @GetMapping("/oauth2/v3/userinfo?access_token={OAUTH_TOKEN}") - fun getUserInfo(@PathVariable("OAUTH_TOKEN")token: String): GoogleInfoResponse + @GetMapping("/oauth2/v3/userinfo") + fun getUserInfo( + @RequestHeader("Authorization") token: String + ): GoogleInfoResponse } diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt index 3a01d45..f3dcaea 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt @@ -4,7 +4,6 @@ import com.dobby.backend.domain.gateway.feign.GoogleAuthGateway import com.dobby.backend.infrastructure.config.properties.GoogleAuthProperties import com.dobby.backend.infrastructure.feign.google.GoogleAuthFeignClient import com.dobby.backend.infrastructure.feign.google.GoogleUserInfoFeginClient -import com.dobby.backend.presentation.api.dto.request.auth.google.GoogleTokenRequest import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleInfoResponse import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleTokenResponse import org.springframework.boot.context.properties.EnableConfigurationProperties @@ -19,14 +18,12 @@ class GoogleAuthGatewayImpl( ): GoogleAuthGateway { override fun getAccessToken(code: String): GoogleTokenResponse { - val googleTokenRequest = GoogleTokenRequest( - code = code, + return googleAuthFeignClient.getAccessToken( clientId = googleAuthProperties.clientId, - clientSecret = googleAuthProperties.clientSecret, - redirectUri = googleAuthProperties.redirectUri + redirectUri = googleAuthProperties.redirectUri, + code = code, + clientSecret = googleAuthProperties.clientSecret ) - - return googleAuthFeignClient.getAccessToken(googleTokenRequest) } override fun getUserInfo(accessToken: String): GoogleInfoResponse { From c68f93215ccd4b3c8b2bd41343c829ccc1bfca03 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 18:33:38 +0900 Subject: [PATCH 23/35] feat: add ContentLengthRequestInterceptor due to feign-client's error --- .../config/ContentLengthRequestInterceptor.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/kotlin/com/dobby/backend/config/ContentLengthRequestInterceptor.kt diff --git a/src/main/kotlin/com/dobby/backend/config/ContentLengthRequestInterceptor.kt b/src/main/kotlin/com/dobby/backend/config/ContentLengthRequestInterceptor.kt new file mode 100644 index 0000000..9a0da13 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/config/ContentLengthRequestInterceptor.kt @@ -0,0 +1,21 @@ +package com.dobby.backend.config + +import feign.RequestInterceptor +import feign.RequestTemplate +import org.springframework.stereotype.Component + + +@Component +class ContentLengthRequestInterceptor : RequestInterceptor { + override fun apply(requestTemplate: RequestTemplate) { + val length = if (requestTemplate.body() != null) requestTemplate.body().size else 0 + if (length == 0 && requestTemplate.method() == "POST") { + requestTemplate.body("gradmeet") + requestTemplate.header(CONTENT_LENGTH_HEADER, "hello".toByteArray().size.toString()) + } + } + + companion object { + private const val CONTENT_LENGTH_HEADER = "Content-Length" + } +} From db853a755f552946de9bc10cd0add552601d8c38 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:04:44 +0900 Subject: [PATCH 24/35] refact: refactor google auth and naver auth logic --- .../com/dobby/backend/application/service/AuthService.kt | 4 ++-- .../application/usecase/FetchGoogleUserInfoUseCase.kt | 6 +++--- .../application/usecase/FetchNaverUserInfoUseCase.kt | 6 +++--- .../com/dobby/backend/domain/exception/OauthException.kt | 1 - .../com/dobby/backend/infrastructure/config/S3Config.kt | 2 -- .../config/properties/GoogleAuthProperties.kt | 3 ++- .../config/properties/NaverAuthProperties.kt | 2 +- .../infrastructure/feign/naver/NaverAuthFeignClient.kt | 9 ++++++--- .../infrastructure/gateway/GoogleAuthGatewayImpl.kt | 5 ++--- .../presentation/api/controller/AuthController.kt | 4 ++-- .../api/dto/response/auth/google/GoogleInfoResponse.kt | 5 +---- 11 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt index a562487..58a34ba 100644 --- a/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt +++ b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt @@ -19,8 +19,8 @@ class AuthService( accessToken = result.accessToken, refreshToken = result.refreshToken, memberId = result.memberId, + name = result.name, oauthEmail = result.oauthEmail, - oauthName = result.oauthName, role = result.role, provider = result.provider, ) @@ -38,8 +38,8 @@ class AuthService( accessToken = result.accessToken, refreshToken = result.refreshToken, memberId = result.memberId, + name = result.name, oauthEmail = result.oauthEmail, - oauthName = result.oauthName, role = result.role, provider = result.provider, ) diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt index c742611..caa9530 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt @@ -22,8 +22,8 @@ class FetchGoogleUserInfoUseCase( val accessToken: String?, val refreshToken: String?, val memberId: Long?, + val name: String?, val oauthEmail: String, - val oauthName: String?, val role: RoleType?, val provider: ProviderType ) @@ -43,8 +43,8 @@ class FetchGoogleUserInfoUseCase( accessToken = jwtAccessToken, refreshToken = jwtRefreshToken, memberId = member.id, + name = member.name, oauthEmail = member.oauthEmail, - oauthName = member.name, role = member.role, provider = ProviderType.GOOGLE ) @@ -55,8 +55,8 @@ class FetchGoogleUserInfoUseCase( accessToken = null, refreshToken = null, memberId = null, + name = null, oauthEmail = email, - oauthName = null, role = null, provider = ProviderType.GOOGLE ) diff --git a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt index a734635..881ee9d 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCase.kt @@ -24,8 +24,8 @@ class FetchNaverUserInfoUseCase( val accessToken: String?, val refreshToken: String?, val memberId: Long?, + val name: String?, val oauthEmail: String?, - val oauthName: String?, val role: RoleType?, val provider: ProviderType ) @@ -45,8 +45,8 @@ class FetchNaverUserInfoUseCase( accessToken = jwtAccessToken, refreshToken = jwtRefreshToken, memberId = member.id, + name = member.name, oauthEmail = member.oauthEmail, - oauthName = member.name, role = member.role, provider = ProviderType.NAVER ) @@ -57,8 +57,8 @@ class FetchNaverUserInfoUseCase( accessToken = null, refreshToken = null, memberId = null, + name = null, oauthEmail = email, - oauthName = null, role = null, provider = ProviderType.NAVER ) diff --git a/src/main/kotlin/com/dobby/backend/domain/exception/OauthException.kt b/src/main/kotlin/com/dobby/backend/domain/exception/OauthException.kt index e7cf03d..c78bc28 100644 --- a/src/main/kotlin/com/dobby/backend/domain/exception/OauthException.kt +++ b/src/main/kotlin/com/dobby/backend/domain/exception/OauthException.kt @@ -7,5 +7,4 @@ class OAuth2AuthenticationException: OauthException(ErrorCode.OAUTH_USER_NOT_FOU class OAuth2ProviderMissingException: OauthException(ErrorCode.OAUTH_PROVIDER_MISSING) class OAuth2ProviderNotSupportedException: OauthException(ErrorCode.OAUTH_PROVIDER_NOT_FOUND) class OAuth2EmailNotFoundException : OauthException(ErrorCode.OAUTH_EMAIL_NOT_FOUND) -class OAuth2NameNotFoundException : OauthException(ErrorCode.OAUTH_NAME_NOT_FOUND) diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/config/S3Config.kt b/src/main/kotlin/com/dobby/backend/infrastructure/config/S3Config.kt index 1126045..a1d8be8 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/config/S3Config.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/config/S3Config.kt @@ -7,12 +7,10 @@ import com.amazonaws.services.s3.AmazonS3ClientBuilder import com.dobby.backend.infrastructure.config.properties.S3Properties import lombok.RequiredArgsConstructor import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @Configuration -@EnableConfigurationProperties(S3Properties::class) @RequiredArgsConstructor class S3Config { diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/config/properties/GoogleAuthProperties.kt b/src/main/kotlin/com/dobby/backend/infrastructure/config/properties/GoogleAuthProperties.kt index e2f7437..b0645e9 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/config/properties/GoogleAuthProperties.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/config/properties/GoogleAuthProperties.kt @@ -4,8 +4,9 @@ import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.stereotype.Component @Component -@ConfigurationProperties(prefix = "spring.security.oauth.client.registration.google") +@ConfigurationProperties(prefix = "spring.security.oauth2.client.registration.google") data class GoogleAuthProperties ( + val grantType: String = "authorization_code", var clientId: String = "", var clientSecret: String= "", var redirectUri : String = "" diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/config/properties/NaverAuthProperties.kt b/src/main/kotlin/com/dobby/backend/infrastructure/config/properties/NaverAuthProperties.kt index ed583c5..9b7b47b 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/config/properties/NaverAuthProperties.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/config/properties/NaverAuthProperties.kt @@ -4,7 +4,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties import org.springframework.stereotype.Component @Component -@ConfigurationProperties(prefix = "spring.security.oauth.client.registration.naver") +@ConfigurationProperties(prefix = "spring.security.oauth2.client.registration.naver") data class NaverAuthProperties ( var clientId: String = "", var clientSecret: String= "", diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverAuthFeignClient.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverAuthFeignClient.kt index 08c14d5..0b77c4b 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverAuthFeignClient.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverAuthFeignClient.kt @@ -1,10 +1,9 @@ package com.dobby.backend.infrastructure.feign.naver -import com.dobby.backend.presentation.api.dto.request.auth.NaverTokenRequest import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverTokenResponse import org.springframework.cloud.openfeign.FeignClient import org.springframework.web.bind.annotation.PostMapping -import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestParam @FeignClient( name = "naver-auth-feign-client", @@ -13,6 +12,10 @@ import org.springframework.web.bind.annotation.RequestBody interface NaverAuthFeignClient { @PostMapping fun getAccessToken( - @RequestBody naverTokenRequest: NaverTokenRequest + @RequestParam(name = "code") code: String, + @RequestParam(name = "client_id") clientId: String, + @RequestParam(name = "client_secret") clientSecret: String, + @RequestParam(name = "state") state: String, + @RequestParam(name = "grant_type") grantType: String, ): NaverTokenResponse } diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt index f3dcaea..40b8356 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt @@ -6,11 +6,9 @@ import com.dobby.backend.infrastructure.feign.google.GoogleAuthFeignClient import com.dobby.backend.infrastructure.feign.google.GoogleUserInfoFeginClient import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleInfoResponse import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleTokenResponse -import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.stereotype.Component @Component -@EnableConfigurationProperties(GoogleAuthProperties::class) class GoogleAuthGatewayImpl( private val googleAuthProperties: GoogleAuthProperties, private val googleAuthFeignClient: GoogleAuthFeignClient, @@ -22,7 +20,8 @@ class GoogleAuthGatewayImpl( clientId = googleAuthProperties.clientId, redirectUri = googleAuthProperties.redirectUri, code = code, - clientSecret = googleAuthProperties.clientSecret + clientSecret = googleAuthProperties.clientSecret, + grantType = googleAuthProperties.grantType ) } diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt b/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt index ca1b71a..a43670d 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/controller/AuthController.kt @@ -33,7 +33,7 @@ class AuthController( refreshToken = result.refreshToken, memberInfo = MemberResponse( memberId = result.memberId, - name = result.oauthName, + name = result.name, oauthEmail = result.oauthEmail, role = result.role, provider = result.provider, @@ -54,7 +54,7 @@ class AuthController( refreshToken = result.refreshToken, memberInfo = MemberResponse( memberId = result.memberId, - name = result.oauthName, + name = result.name, oauthEmail = result.oauthEmail, role = result.role, provider = result.provider, diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/google/GoogleInfoResponse.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/google/GoogleInfoResponse.kt index 46652cd..f9f8c06 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/google/GoogleInfoResponse.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/google/GoogleInfoResponse.kt @@ -4,8 +4,5 @@ import com.fasterxml.jackson.annotation.JsonProperty data class GoogleInfoResponse( @JsonProperty("email") - val email: String, - - @JsonProperty("name") - val name : String + val email: String ) From 0c8e2bc153e0b1a2fd878d202700826ead6c280e Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:05:07 +0900 Subject: [PATCH 25/35] refact: delete unused annotation --- .../com/dobby/backend/infrastructure/token/JwtTokenProvider.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/token/JwtTokenProvider.kt b/src/main/kotlin/com/dobby/backend/infrastructure/token/JwtTokenProvider.kt index e8d87ce..b13182e 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/token/JwtTokenProvider.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/token/JwtTokenProvider.kt @@ -5,7 +5,6 @@ import com.dobby.backend.infrastructure.config.properties.TokenProperties import io.jsonwebtoken.ExpiredJwtException import io.jsonwebtoken.JwtException import io.jsonwebtoken.Jwts -import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.security.authentication.UsernamePasswordAuthenticationToken import org.springframework.security.core.Authentication import org.springframework.security.core.authority.SimpleGrantedAuthority @@ -15,7 +14,6 @@ import javax.crypto.SecretKey import javax.crypto.spec.SecretKeySpec @Component -@EnableConfigurationProperties(TokenProperties::class) class JwtTokenProvider( private val tokenProperties: TokenProperties ) { From 0b5ee7824351a86dbeabf4cf3347bf8cc84621bb Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:05:25 +0900 Subject: [PATCH 26/35] refact: change return value --- .../infrastructure/gateway/NaverAuthGatewayImpl.kt | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt index e356236..8324676 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt @@ -4,14 +4,11 @@ import com.dobby.backend.domain.gateway.feign.NaverAuthGateway import com.dobby.backend.infrastructure.config.properties.NaverAuthProperties import com.dobby.backend.infrastructure.feign.naver.NaverAuthFeignClient import com.dobby.backend.infrastructure.feign.naver.NaverUserInfoFeignClient -import com.dobby.backend.presentation.api.dto.request.auth.NaverTokenRequest import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverInfoResponse import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverTokenResponse -import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.stereotype.Component @Component -@EnableConfigurationProperties(NaverAuthProperties::class) class NaverAuthGatewayImpl( private val naverAuthProperties: NaverAuthProperties, private val naverAuthFeignClient: NaverAuthFeignClient, @@ -19,15 +16,13 @@ class NaverAuthGatewayImpl( ): NaverAuthGateway { override fun getAccessToken(authorizationCode: String, state: String): NaverTokenResponse { - val naverTokenRequest = NaverTokenRequest( - grantType = "authorization_code", + return naverAuthFeignClient.getAccessToken( + code = authorizationCode, clientId = naverAuthProperties.clientId, clientSecret = naverAuthProperties.clientSecret, - code = authorizationCode, - state = state + state = state, + grantType = "authorization_code" ) - - return naverAuthFeignClient.getAccessToken(naverTokenRequest) } override fun getUserInfo(accessToken: String): NaverInfoResponse? { From d7ad5b5f6f23c633d823a5d28eec82503b6a31a9 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:05:36 +0900 Subject: [PATCH 27/35] style: add blank --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index b0d21fa..7b85856 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -46,7 +46,7 @@ dependencies { implementation("org.mariadb.jdbc:mariadb-java-client:2.7.3") implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0") implementation("org.springframework.cloud:spring-cloud-starter-openfeign") - implementation ("io.awspring.cloud:spring-cloud-starter-aws:2.4.4") + implementation("io.awspring.cloud:spring-cloud-starter-aws:2.4.4") implementation("com.github.in-seo:univcert:master-SNAPSHOT") { exclude(group = "org.hamcrest", module= "harmcest-core") } From 4b2a36e046d68c83a9c122dcccd38cb887d05681 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:12:40 +0900 Subject: [PATCH 28/35] refactor: move class file or code --- .../kotlin/com/dobby/backend/DobbyBackendApplication.kt | 6 ++++++ .../ContentLengthRequestInterceptor.kt | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) rename src/main/kotlin/com/dobby/backend/{config => infrastructure}/ContentLengthRequestInterceptor.kt (79%) diff --git a/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt b/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt index 4d21b68..d482a43 100644 --- a/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt +++ b/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt @@ -1,9 +1,14 @@ package com.dobby.backend import com.dobby.backend.application.usecase.UseCase +import com.dobby.backend.infrastructure.config.properties.GoogleAuthProperties +import com.dobby.backend.infrastructure.config.properties.NaverAuthProperties +import com.dobby.backend.infrastructure.config.properties.S3Properties +import com.dobby.backend.infrastructure.config.properties.TokenProperties import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication import org.springframework.boot.context.properties.ConfigurationPropertiesScan +import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.cloud.openfeign.EnableFeignClients import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.FilterType @@ -17,6 +22,7 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing ) @SpringBootApplication @ConfigurationPropertiesScan +@EnableConfigurationProperties(TokenProperties::class, S3Properties::class, GoogleAuthProperties::class, NaverAuthProperties::class) @EnableFeignClients @EnableJpaAuditing class DobbyBackendApplication diff --git a/src/main/kotlin/com/dobby/backend/config/ContentLengthRequestInterceptor.kt b/src/main/kotlin/com/dobby/backend/infrastructure/ContentLengthRequestInterceptor.kt similarity index 79% rename from src/main/kotlin/com/dobby/backend/config/ContentLengthRequestInterceptor.kt rename to src/main/kotlin/com/dobby/backend/infrastructure/ContentLengthRequestInterceptor.kt index 9a0da13..d1e20ba 100644 --- a/src/main/kotlin/com/dobby/backend/config/ContentLengthRequestInterceptor.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/ContentLengthRequestInterceptor.kt @@ -1,4 +1,4 @@ -package com.dobby.backend.config +package com.dobby.backend.infrastructure import feign.RequestInterceptor import feign.RequestTemplate @@ -11,7 +11,7 @@ class ContentLengthRequestInterceptor : RequestInterceptor { val length = if (requestTemplate.body() != null) requestTemplate.body().size else 0 if (length == 0 && requestTemplate.method() == "POST") { requestTemplate.body("gradmeet") - requestTemplate.header(CONTENT_LENGTH_HEADER, "hello".toByteArray().size.toString()) + requestTemplate.header(CONTENT_LENGTH_HEADER, "gradmeet".toByteArray().size.toString()) } } From 2a1eea0b664a835cf12f6adfd282aecc8f58be03 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:12:50 +0900 Subject: [PATCH 29/35] refactor: delete unused file --- .../dobby/backend/config/ApplicationConfig.kt | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt diff --git a/src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt b/src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt deleted file mode 100644 index e899e7b..0000000 --- a/src/main/kotlin/com/dobby/backend/config/ApplicationConfig.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.dobby.backend.config - -import com.dobby.backend.application.service.AuthService -import com.dobby.backend.application.usecase.FetchGoogleUserInfoUseCase -import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase -import com.dobby.backend.application.usecase.GenerateTestTokenUseCase -import com.dobby.backend.application.usecase.GenerateTokenWithRefreshTokenUseCase -import com.dobby.backend.infrastructure.config.properties.GoogleAuthProperties -import com.dobby.backend.infrastructure.config.properties.NaverAuthProperties -import com.dobby.backend.infrastructure.config.properties.S3Properties -import com.dobby.backend.infrastructure.config.properties.TokenProperties -import org.springframework.boot.context.properties.EnableConfigurationProperties -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -@Configuration -@EnableConfigurationProperties(TokenProperties::class, S3Properties::class, GoogleAuthProperties::class, NaverAuthProperties::class) -class ApplicationConfig { - @Bean - fun authService( - fetchGoogleUserInfoUseCase: FetchGoogleUserInfoUseCase, - fetchNaverUserInfoUseCase: FetchNaverUserInfoUseCase, - generateTokenWithRefreshTokenUseCase: GenerateTokenWithRefreshTokenUseCase, - generateTestTokenUseCase: GenerateTestTokenUseCase - ): AuthService { - return AuthService( - fetchGoogleUserInfoUseCase, - fetchNaverUserInfoUseCase, - generateTokenWithRefreshTokenUseCase, - generateTestTokenUseCase - ) - } -} From 9740ee596a461bd0abb5c9537608c96ec353454a Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:13:27 +0900 Subject: [PATCH 30/35] feat: add Service annotation --- .../kotlin/com/dobby/backend/application/service/AuthService.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt index 58a34ba..c6419a5 100644 --- a/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt +++ b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt @@ -1,7 +1,9 @@ package com.dobby.backend.application.service import com.dobby.backend.application.usecase.* +import org.springframework.stereotype.Service +@Service class AuthService( private val fetchGoogleUserInfoUseCase: FetchGoogleUserInfoUseCase, private val fetchNaverUserInfoUseCase: FetchNaverUserInfoUseCase, From 20e12ee94f26ac53829bca72b1ba75564774816d Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:15:23 +0900 Subject: [PATCH 31/35] test: delete unused name field in response --- .../api/dto/response/auth/naver/NaverInfoResponse.kt | 5 +---- .../application/usecase/FetchGoogleUserInfoUseCaseTest.kt | 1 - .../application/usecase/FetchNaverUserInfoUseCaseTest.kt | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverInfoResponse.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverInfoResponse.kt index 046a540..4543972 100644 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverInfoResponse.kt +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverInfoResponse.kt @@ -4,8 +4,5 @@ import com.fasterxml.jackson.annotation.JsonProperty data class NaverInfoResponse( @JsonProperty("email") - val email: String, - - @JsonProperty("name") - val name: String + val email: String ) diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt index ab8602c..f154b3e 100644 --- a/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt @@ -42,7 +42,6 @@ class FetchGoogleUserInfoUseCaseTest : BehaviorSpec({ every { googleAuthGateway.getAccessToken(any()) } returns mockGoogleTokenResponse every { googleAuthGateway.getUserInfo("mock-access-token") } returns mockk { every { email } returns "test@example.com" - every { name } returns "Test User" } every { tokenGateway.generateAccessToken(any()) } returns "mock-jwt-access-token" diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt index ea9b0f2..45561fc 100644 --- a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt +++ b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt @@ -42,7 +42,6 @@ class FetchNaverUserInfoUseCaseTest : BehaviorSpec({ every { naverAuthGateway.getAccessToken(any(), any()) } returns mockNaverTokenResponse every { naverAuthGateway.getUserInfo("mock-access-token") } returns mockk { every { email } returns "test@example.com" - every { name } returns "Test User" } every { tokenGateway.generateAccessToken(any()) } returns "mock-jwt-access-token" From 3db0edb3c0e309509a16074b7888fce858aa0563 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:46:46 +0900 Subject: [PATCH 32/35] refact: delete unused annotation --- src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt b/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt index d482a43..6f63a03 100644 --- a/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt +++ b/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt @@ -22,7 +22,6 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing ) @SpringBootApplication @ConfigurationPropertiesScan -@EnableConfigurationProperties(TokenProperties::class, S3Properties::class, GoogleAuthProperties::class, NaverAuthProperties::class) @EnableFeignClients @EnableJpaAuditing class DobbyBackendApplication From d162589544e4b9dfaa78d3dc02dcc6500fbeb663 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:47:32 +0900 Subject: [PATCH 33/35] refact: delete unused import --- src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt b/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt index 6f63a03..4d21b68 100644 --- a/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt +++ b/src/main/kotlin/com/dobby/backend/DobbyBackendApplication.kt @@ -1,14 +1,9 @@ package com.dobby.backend import com.dobby.backend.application.usecase.UseCase -import com.dobby.backend.infrastructure.config.properties.GoogleAuthProperties -import com.dobby.backend.infrastructure.config.properties.NaverAuthProperties -import com.dobby.backend.infrastructure.config.properties.S3Properties -import com.dobby.backend.infrastructure.config.properties.TokenProperties import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication import org.springframework.boot.context.properties.ConfigurationPropertiesScan -import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.cloud.openfeign.EnableFeignClients import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.FilterType From 1f7bf309e567aca640158ba9dd106c7d1b56ca4a Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 20:50:08 +0900 Subject: [PATCH 34/35] refact: move feign interceptor to feign package --- .../{ => feign}/ContentLengthRequestInterceptor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/kotlin/com/dobby/backend/infrastructure/{ => feign}/ContentLengthRequestInterceptor.kt (93%) diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/ContentLengthRequestInterceptor.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/ContentLengthRequestInterceptor.kt similarity index 93% rename from src/main/kotlin/com/dobby/backend/infrastructure/ContentLengthRequestInterceptor.kt rename to src/main/kotlin/com/dobby/backend/infrastructure/feign/ContentLengthRequestInterceptor.kt index d1e20ba..b541ade 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/ContentLengthRequestInterceptor.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/feign/ContentLengthRequestInterceptor.kt @@ -1,4 +1,4 @@ -package com.dobby.backend.infrastructure +package com.dobby.backend.infrastructure.feign import feign.RequestInterceptor import feign.RequestTemplate From 0e2623e06e8a6cb55f74da7508f205c7249c56a8 Mon Sep 17 00:00:00 2001 From: jisu Date: Thu, 9 Jan 2025 21:05:33 +0900 Subject: [PATCH 35/35] refact: delete unused code --- .../infrastructure/feign/google/GoogleAuthFeignClient.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleAuthFeignClient.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleAuthFeignClient.kt index 7649336..045bec9 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleAuthFeignClient.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/feign/google/GoogleAuthFeignClient.kt @@ -16,6 +16,6 @@ interface GoogleAuthFeignClient { @RequestParam(name = "client_id") clientId: String, @RequestParam(name = "client_secret") clientSecret: String, @RequestParam(name = "redirect_uri") redirectUri: String, - @RequestParam(name = "grant_type") grantType: String = "authorization_code", + @RequestParam(name = "grant_type") grantType: String, ): GoogleTokenResponse }