Skip to content

Commit

Permalink
[feat #42] 구글 탈퇴 구현 (#47)
Browse files Browse the repository at this point in the history
* feat : Security White List 수정

* feat : 구글 프로퍼티 정의

* feat : 구글 탈퇴 구현

* refactor : 컨텐츠테스트 코드 의존객체 추가

* refactor : httpStatus enum 활용으로 수정
  • Loading branch information
dlswns2480 authored Jul 30, 2024
1 parent 9a36f28 commit 1354ade
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SecurityConfig(
) {
companion object {
private val WHITE_LIST = arrayOf(
"/api/v1/auth/**",
"/api/v1/auth/signin",
"/swagger-ui/index.html#/",
"/swagger",
"/swagger-ui.html",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.pokit.auth.common.dto

import com.fasterxml.jackson.annotation.JsonProperty

data class GoogleTokenResponse(
@JsonProperty("access_token")
val accessToken: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.pokit.auth.common.property

import org.springframework.boot.context.properties.ConfigurationProperties

@ConfigurationProperties(prefix = "google")
class GoogleProperty(
val clientId: String,
val clientSecret: String
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.pokit.auth.common.support

import com.pokit.auth.common.config.OpenFeignConfig
import com.pokit.auth.common.dto.GoogleTokenResponse
import com.pokit.auth.common.dto.GoogleUserResponse
import feign.Response
import org.springframework.cloud.openfeign.FeignClient
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestParam

@FeignClient(
Expand All @@ -14,4 +17,15 @@ import org.springframework.web.bind.annotation.RequestParam
interface GoogleFeignClient {
@GetMapping("/tokeninfo")
fun getUserInfo(@RequestParam("id_token") idToken: String): GoogleUserResponse

@PostMapping("/token")
fun getToken(
@RequestParam("code") authorizationCode: String,
@RequestParam("client_id") clientId: String,
@RequestParam("client_secret") clientSecret: String,
@RequestParam("grant_type") grantType: String
): GoogleTokenResponse?

@PostMapping("/revoke")
fun revoke(@RequestParam("token") accessToken: String): Response
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.pokit.common.exception.ClientValidationException
import com.pokit.token.exception.AuthErrorCode
import com.pokit.token.model.AuthPlatform
import com.pokit.user.dto.UserInfo
import org.apache.http.HttpStatus
import org.springframework.stereotype.Component

@Component
Expand Down Expand Up @@ -64,7 +65,7 @@ class AppleApiAdapter(
"access_token"
)
val response = appleFeignClient.revoke(request)
if (response.status() != 200) {
if (response.status() != HttpStatus.SC_OK) {
throw ClientValidationException(AuthErrorCode.FAILED_TO_REVOKE)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package com.pokit.auth.impl

import com.pokit.auth.common.property.GoogleProperty
import com.pokit.auth.common.support.GoogleFeignClient
import com.pokit.auth.port.out.GoogleApiClient
import com.pokit.common.exception.ClientValidationException
import com.pokit.token.exception.AuthErrorCode
import com.pokit.token.model.AuthPlatform
import com.pokit.user.dto.UserInfo
import io.github.oshai.kotlinlogging.KotlinLogging
import org.apache.http.HttpStatus
import org.springframework.stereotype.Component

@Component
class GoogleApiAdapter(
private val googleFeignClient: GoogleFeignClient
private val googleFeignClient: GoogleFeignClient,
private val googleProperty: GoogleProperty
) : GoogleApiClient {
override fun getUserInfo(idToken: String): UserInfo {
val response = googleFeignClient.getUserInfo(idToken)
Expand All @@ -19,4 +23,19 @@ class GoogleApiAdapter(
authPlatform = AuthPlatform.GOOGLE
)
}

override fun revoke(authorizationCode: String) {
val tokenResponse = googleFeignClient.getToken(
authorizationCode,
googleProperty.clientId,
googleProperty.clientSecret,
"authorization_code"
) ?: throw ClientValidationException(AuthErrorCode.INVALID_AUTHORIZATION_CODE)

val revokeResponse = googleFeignClient.revoke(tokenResponse.accessToken)

if (revokeResponse.status() != HttpStatus.SC_OK) {
throw ClientValidationException(AuthErrorCode.FAILED_TO_REVOKE)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ import com.pokit.user.dto.UserInfo

interface GoogleApiClient {
fun getUserInfo(idToken: String): UserInfo

fun revoke(authorizationCode: String)
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class AuthService(
}

when (request.authPlatform) {
AuthPlatform.GOOGLE -> TODO("구글 탈퇴 구현")
AuthPlatform.GOOGLE -> googleApiClient.revoke(request.authorizationCode)
AuthPlatform.APPLE -> appleApiClient.revoke(request.authorizationCode)
}
contentPort.deleteByUserId(user.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.pokit.common.exception.NotFoundCustomException
import com.pokit.content.ContentFixture
import com.pokit.content.dto.toDomain
import com.pokit.content.port.out.ContentPort
import com.pokit.log.port.out.UserLogPort
import com.pokit.user.UserFixture
import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.BehaviorSpec
Expand All @@ -19,7 +20,8 @@ class ContentServiceTest : BehaviorSpec({
val contentPort = mockk<ContentPort>()
val bookmarkPort = mockk<BookmarkPort>()
val categoryPort = mockk<CategoryPort>()
val contentService = ContentService(contentPort, bookmarkPort, categoryPort)
val userLogPort = mockk<UserLogPort>()
val contentService = ContentService(contentPort, bookmarkPort, categoryPort, userLogPort)

Given("컨텐츠에 대해 즐겨찾기 할 때") {
val user = UserFixture.getUser()
Expand Down

0 comments on commit 1354ade

Please sign in to comment.