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") } 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/service/AuthService.kt b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt new file mode 100644 index 0000000..c6419a5 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/application/service/AuthService.kt @@ -0,0 +1,75 @@ +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, + private val generateTokenWithRefreshTokenUseCase: GenerateTokenWithRefreshTokenUseCase, + private val generateTestTokenUseCase: GenerateTestTokenUseCase, +) { + 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, + name = result.name, + oauthEmail = result.oauthEmail, + role = result.role, + provider = result.provider, + ) + } + + 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, + name = result.name, + oauthEmail = result.oauthEmail, + role = result.role, + provider = result.provider, + ) + } + + fun forceToken(memberId: Long): GenerateTestTokenUseCase.Output { + val result = generateTestTokenUseCase.execute( + GenerateTestTokenUseCase.Input( + memberId = memberId + ) + ) + return GenerateTestTokenUseCase.Output( + accessToken = result.accessToken, + refreshToken = result.refreshToken, + member = result.member + ) + } + + fun signInWithRefreshToken(refreshToken: String): GenerateTokenWithRefreshTokenUseCase.Output { + val result = generateTokenWithRefreshTokenUseCase.execute( + GenerateTokenWithRefreshTokenUseCase.Input( + refreshToken = refreshToken, + ) + ) + return GenerateTokenWithRefreshTokenUseCase.Output( + accessToken = result.accessToken, + refreshToken = result.refreshToken, + member = result.member + ) + } +} 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/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt b/src/main/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCase.kt index abbaaae..caa9530 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,65 @@ 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 name: String?, + val oauthEmail: 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, + name = member.name, + oauthEmail = member.oauthEmail, + role = member.role, + provider = ProviderType.GOOGLE + ) + } else { + // 등록된 멤버가 없으면 isRegistered = false, memberId = null + Output( + isRegistered = false, + accessToken = null, + refreshToken = null, + memberId = null, + name = null, + oauthEmail = email, + role = null, provider = ProviderType.GOOGLE ) - } catch (e: SignInMemberException) { - throw SignInMemberException() } } - - private fun fetchAccessToken(googleTokenRequest: GoogleTokenRequest): GoogleTokenResponse { - return googleAuthFeignClient.getAccessToken(googleTokenRequest) - } } 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..881ee9d 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,67 @@ 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.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.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 com.dobby.backend.infrastructure.database.entity.enum.RoleType class FetchNaverUserInfoUseCase( - private val naverAuthFeignClient: NaverAuthFeignClient, - private val naverUserInfoFeginClient: NaverUserInfoFeignClient, - private val jwtTokenProvider: JwtTokenProvider, - private val naverAuthProperties: NaverAuthProperties, - private val memberRepository: MemberRepository -) : UseCase { + private val naverAuthGateway: NaverAuthGateway, + private val memberGateway: MemberGateway, + private val jwtTokenGateway: TokenGateway +) : 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 + // TODO: 테스트 후, oauthEmail not null 처리 + data class Output( + val isRegistered: Boolean, + val accessToken: String?, + val refreshToken: String?, + val memberId: Long?, + val name: String?, + val oauthEmail: 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 { + 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) } - 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, + name = member.name, + oauthEmail = member.oauthEmail, + role = member.role, + provider = ProviderType.NAVER + ) + } else { + // 등록된 멤버가 없으면 isRegistered = false, memberId = null + Output( + isRegistered = false, + accessToken = null, + refreshToken = null, + memberId = null, + name = null, + oauthEmail = email, + role = null, provider = ProviderType.NAVER ) - } catch (e: SignInMemberException) { - throw SignInMemberException() } } - - private fun fetchAccessToken(naverTokenRequest: NaverTokenRequest): NaverTokenResponse { - return naverAuthFeignClient.getAccessToken(naverTokenRequest) - } } 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 76% 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 edf943e..479010a 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestToken.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTestTokenUseCase.kt @@ -2,11 +2,12 @@ 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.Member -class GenerateTestToken( +class GenerateTestTokenUseCase( private val tokenGateway: TokenGateway, private val memberGateway: MemberGateway, -) : UseCase { +) : UseCase { data class Input( val memberId: Long ) @@ -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/GenerateTokenWithRefreshTokenUseCase.kt similarity index 75% 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 e401aaf..7cffd9a 100644 --- a/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshToken.kt +++ b/src/main/kotlin/com/dobby/backend/application/usecase/GenerateTokenWithRefreshTokenUseCase.kt @@ -2,11 +2,12 @@ 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.Member -class GenerateTokenWithRefreshToken( +class GenerateTokenWithRefreshTokenUseCase( private val tokenGateway: TokenGateway, private val memberGateway: MemberGateway, -) : UseCase { +) : UseCase { data class Input( val refreshToken: String, ) @@ -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 ) } } 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/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 { -} 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/domain/gateway/MemberGateway.kt b/src/main/kotlin/com/dobby/backend/domain/gateway/MemberGateway.kt index 20cecc8..f78712f 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.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/domain/gateway/feign/GoogleAuthGateway.kt b/src/main/kotlin/com/dobby/backend/domain/gateway/feign/GoogleAuthGateway.kt new file mode 100644 index 0000000..c2b4bdb --- /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(accessToken: String): GoogleInfoResponse +} 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 new file mode 100644 index 0000000..11cefd0 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/domain/gateway/feign/NaverAuthGateway.kt @@ -0,0 +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): NaverTokenResponse + fun getUserInfo(accessToken: String): NaverInfoResponse? +} diff --git a/src/main/kotlin/com/dobby/backend/domain/model/member/Member.kt b/src/main/kotlin/com/dobby/backend/domain/model/member/Member.kt index 220ef6f..d7d7a9e 100644 --- a/src/main/kotlin/com/dobby/backend/domain/model/member/Member.kt +++ b/src/main/kotlin/com/dobby/backend/domain/model/member/Member.kt @@ -5,7 +5,7 @@ import com.dobby.backend.infrastructure.database.entity.enum.ProviderType import com.dobby.backend.infrastructure.database.entity.enum.RoleType data class Member( - val memberId: Long, + val id: Long, val name: String?, val oauthEmail: String, val contactEmail: String?, @@ -16,7 +16,7 @@ data class Member( companion object { fun newMember( - memberId: Long, + id: Long, name: String, oauthEmail: String, contactEmail: String, @@ -24,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/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/database/entity/member/MemberEntity.kt b/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/member/MemberEntity.kt index e1b0e11..fefca5c 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/member/MemberEntity.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/database/entity/member/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/feign/ContentLengthRequestInterceptor.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/ContentLengthRequestInterceptor.kt new file mode 100644 index 0000000..b541ade --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/infrastructure/feign/ContentLengthRequestInterceptor.kt @@ -0,0 +1,21 @@ +package com.dobby.backend.infrastructure.feign + +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, "gradmeet".toByteArray().size.toString()) + } + } + + companion object { + private const val CONTENT_LENGTH_HEADER = "Content-Length" + } +} 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..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 @@ -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, ): 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/feign/naver/NaverAuthFeignClient.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverAuthFeignClient.kt index ecd49d1..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.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 +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/feign/naver/NaverUserInfoFeignClient.kt b/src/main/kotlin/com/dobby/backend/infrastructure/feign/naver/NaverUserInfoFeignClient.kt index b209656..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 @@ -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 @@ -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 } 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..40b8356 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/GoogleAuthGatewayImpl.kt @@ -0,0 +1,31 @@ +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.response.auth.google.GoogleInfoResponse +import com.dobby.backend.presentation.api.dto.response.auth.google.GoogleTokenResponse +import org.springframework.stereotype.Component + +@Component +class GoogleAuthGatewayImpl( + private val googleAuthProperties: GoogleAuthProperties, + private val googleAuthFeignClient: GoogleAuthFeignClient, + private val googleUserInfoFeignClient: GoogleUserInfoFeginClient +): GoogleAuthGateway { + + override fun getAccessToken(code: String): GoogleTokenResponse { + return googleAuthFeignClient.getAccessToken( + clientId = googleAuthProperties.clientId, + redirectUri = googleAuthProperties.redirectUri, + code = code, + clientSecret = googleAuthProperties.clientSecret, + grantType = googleAuthProperties.grantType + ) + } + + override fun getUserInfo(accessToken: String): GoogleInfoResponse { + return googleUserInfoFeignClient.getUserInfo("Bearer $accessToken") + } +} 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 b7765a7..e936ae1 100644 --- a/src/main/kotlin/com/dobby/backend/infrastructure/gateway/MemberGatewayImpl.kt +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/MemberGatewayImpl.kt @@ -1,6 +1,7 @@ package com.dobby.backend.infrastructure.gateway import com.dobby.backend.domain.gateway.MemberGateway +import com.dobby.backend.infrastructure.database.entity.enum.MemberStatus import com.dobby.backend.domain.model.member.Member import com.dobby.backend.infrastructure.database.entity.member.MemberEntity import com.dobby.backend.infrastructure.database.repository.MemberRepository @@ -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) + } } 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..8324676 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/infrastructure/gateway/NaverAuthGatewayImpl.kt @@ -0,0 +1,31 @@ +package com.dobby.backend.infrastructure.gateway + +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.response.auth.naver.NaverInfoResponse +import com.dobby.backend.presentation.api.dto.response.auth.naver.NaverTokenResponse +import org.springframework.stereotype.Component + +@Component +class NaverAuthGatewayImpl( + private val naverAuthProperties: NaverAuthProperties, + private val naverAuthFeignClient: NaverAuthFeignClient, + private val naverUserInfoFeignClient: NaverUserInfoFeignClient +): NaverAuthGateway { + + override fun getAccessToken(authorizationCode: String, state: String): NaverTokenResponse { + return naverAuthFeignClient.getAccessToken( + code = authorizationCode, + clientId = naverAuthProperties.clientId, + clientSecret = naverAuthProperties.clientSecret, + state = state, + grantType = "authorization_code" + ) + } + + override fun getUserInfo(accessToken: String): NaverInfoResponse? { + return naverUserInfoFeignClient.getUserInfo("Bearer $accessToken") + } +} 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 b4b6165..2eb352e 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/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 ) { 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..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 @@ -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,61 @@ 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) + val result = authService.getGoogleUserInfo(request.authorizationCode) + return OauthLoginResponse( + isRegistered = result.isRegistered, + accessToken = result.accessToken, + refreshToken = result.refreshToken, + memberInfo = MemberResponse( + memberId = result.memberId, + name = result.name, + oauthEmail = result.oauthEmail, + role = result.role, + provider = result.provider, + ) + ) } @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 = result.memberId, + name = result.name, + 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 +79,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) ) } } 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) } } 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 1d32611..1129366 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/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/NaverInfoResponse.kt b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/NaverInfoResponse.kt deleted file mode 100644 index e1ab281..0000000 --- a/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/NaverInfoResponse.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.dobby.backend.presentation.api.dto.response.auth - -import com.fasterxml.jackson.annotation.JsonProperty - -data class NaverInfoResponse( - @JsonProperty("email") - val email: String, - - @JsonProperty("name") - val name: String -) 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 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 ) 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 new file mode 100644 index 0000000..4543972 --- /dev/null +++ b/src/main/kotlin/com/dobby/backend/presentation/api/dto/response/auth/naver/NaverInfoResponse.kt @@ -0,0 +1,8 @@ +package com.dobby.backend.presentation.api.dto.response.auth.naver + +import com.fasterxml.jackson.annotation.JsonProperty + +data class NaverInfoResponse( + @JsonProperty("email") + val email: String +) 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 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/service/OauthServiceTest.kt b/src/test/kotlin/com/dobby/backend/application/service/OauthServiceTest.kt deleted file mode 100644 index b2b94d8..0000000 --- a/src/test/kotlin/com/dobby/backend/application/service/OauthServiceTest.kt +++ /dev/null @@ -1,46 +0,0 @@ -import com.dobby.backend.application.service.OauthService -import com.dobby.backend.application.usecase.FetchGoogleUserInfoUseCase -import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase -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 OauthServiceTest : BehaviorSpec({ - val fetchGoogleUserInfoUseCase = mockk() - val fetchNaverUserInfoUseCase = mockk() - - val oauthService = OauthService(fetchGoogleUserInfoUseCase, fetchNaverUserInfoUseCase) - - 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/FetchGoogleUserInfoTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoTest.kt deleted file mode 100644 index e1b1a9a..0000000 --- a/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoTest.kt +++ /dev/null @@ -1,71 +0,0 @@ -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.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 -import io.mockk.every -import io.mockk.mockk -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 fetchGoogleUserInfoUseCase = FetchGoogleUserInfoUseCase( - googleAuthFeignClient, - googleUserInfoFeginClient, - jwtTokenProvider, - googleAuthProperties, - memberRepository - ) - - given("Google OAuth 요청이 들어왔을 때") { - val oauthLoginRequest = GoogleOauthLoginRequest(authorizationCode = "valid-auth-code") - val mockMember = MemberEntity( - id = 1L, - oauthEmail = "test@example.com", - provider = ProviderType.GOOGLE, - status = MemberStatus.ACTIVE, - role = RoleType.PARTICIPANT, - contactEmail = "contact@example.com", - name = "Test User" - ) - - 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 { - 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) - - 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" - } - } - } -}) diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt new file mode 100644 index 0000000..f154b3e --- /dev/null +++ b/src/test/kotlin/com/dobby/backend/application/usecase/FetchGoogleUserInfoUseCaseTest.kt @@ -0,0 +1,78 @@ +import com.dobby.backend.application.usecase.FetchGoogleUserInfoUseCase +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.presentation.api.dto.response.auth.google.GoogleTokenResponse +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 FetchGoogleUserInfoUseCaseTest : BehaviorSpec({ + val googleAuthGateway = mockk() + val memberGateway = mockk() + val tokenGateway = mockk() + + val fetchGoogleUserInfoUseCase = FetchGoogleUserInfoUseCase( + googleAuthGateway, + memberGateway, + tokenGateway + ) + + given("Google OAuth 요청이 들어왔을 때") { + val input = FetchGoogleUserInfoUseCase.Input(authorizationCode = "valid-auth-code") + val mockMember = Member( + id = 1L, + oauthEmail = "test@example.com", + name = "Test User", + status = MemberStatus.ACTIVE, + role = RoleType.PARTICIPANT, + contactEmail = "contact@example.com", + provider = ProviderType.GOOGLE + ) + + 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 { 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.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" + } + } + } +}) diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoTest.kt deleted file mode 100644 index 18fd41c..0000000 --- a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoTest.kt +++ /dev/null @@ -1,73 +0,0 @@ -import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase -import com.dobby.backend.infrastructure.config.properties.NaverAuthProperties -import com.dobby.backend.infrastructure.database.entity.member.MemberEntity -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 fetchNaverUserInfoUseCase = FetchNaverUserInfoUseCase( - naverAuthFeignClient, - naverUserInfoFeginClient, - jwtTokenProvider, - naverAuthProperties, - memberRepository - ) - - given("Naver OAuth 요청이 들어왔을 때") { - val oauthLoginRequest = NaverOauthLoginRequest(authorizationCode = "valid-auth-code", state = "valid-state") - val mockMember = MemberEntity( - id = 1L, - oauthEmail = "test@example.com", - name = "Test User", - status = MemberStatus.ACTIVE, - role = RoleType.PARTICIPANT, - contactEmail = "contact@example.com", - 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 { - 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) - - 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" - } - } - } -}) diff --git a/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt new file mode 100644 index 0000000..45561fc --- /dev/null +++ b/src/test/kotlin/com/dobby/backend/application/usecase/FetchNaverUserInfoUseCaseTest.kt @@ -0,0 +1,78 @@ +import com.dobby.backend.application.usecase.FetchNaverUserInfoUseCase +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.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 +import io.mockk.mockk +import org.springframework.test.context.ActiveProfiles + +@ActiveProfiles("test") +class FetchNaverUserInfoUseCaseTest : BehaviorSpec({ + val naverAuthGateway = mockk() + val memberGateway = mockk() + val tokenGateway = mockk() + + val fetchNaverUserInfoUseCase = FetchNaverUserInfoUseCase( + naverAuthGateway, + memberGateway, + tokenGateway + ) + + given("Naver OAuth 요청이 들어왔을 때") { + val input = FetchNaverUserInfoUseCase.Input(authorizationCode = "valid-auth-code", state = "valid-state") + val mockMember = Member( + id = 1L, + oauthEmail = "test@example.com", + name = "Test User", + status = MemberStatus.ACTIVE, + role = RoleType.PARTICIPANT, + contactEmail = "contact@example.com", + provider = ProviderType.NAVER + ) + + val mockEmptyMember = null + 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 { 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.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/GenerateTestTokenUseCaseTest.kt similarity index 78% 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 1fbba8e..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,13 +11,13 @@ 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(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" @@ -28,8 +28,8 @@ class GenerateTestTokenTest: BehaviorSpec({ every { memberGateway.getById(1) } returns member `when`("execute가 호출되면") { - val input = GenerateTestToken.Input(member.memberId) - 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 74% 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 841327c..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,32 +11,32 @@ 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" - 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 `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 result.refreshToken shouldBe newRefreshToken - result.memberId shouldBe member.memberId + result.member.id shouldBe member.id } } } @@ -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") } } 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 6cbc6cc..9222f31 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)은 원래 멤버의 역할과 같아야 한다") {