[#44] 매장 기능 도입 #45

Merged
pricelees merged 116 commits from feat/#44 into main 2025-09-20 03:15:06 +00:00
6 changed files with 12 additions and 87 deletions
Showing only changes of commit 3d9a4c650e - Show all commits

View File

@ -17,18 +17,6 @@ private val log: KLogger = KotlinLogging.logger {}
class AdminService( class AdminService(
private val adminRepository: AdminRepository, private val adminRepository: AdminRepository,
) { ) {
@Transactional(readOnly = true)
fun findContextById(id: Long): CurrentAdminContext {
log.info { "[AdminService.findById] 현재 로그인된 관리자 조회 시작: id=${id}" }
val admin: AdminEntity = findOrThrow(id)
return admin.toContext()
.also {
log.info { "[AdminService.findById] 현재 로그인된 관리자 조회 완료: id=${id}" }
}
}
@Transactional(readOnly = true) @Transactional(readOnly = true)
fun findCredentialsByAccount(account: String): AdminLoginCredentials { fun findCredentialsByAccount(account: String): AdminLoginCredentials {
log.info { "[AdminService.findCredentialsByAccount] 관리자 조회 시작: account=${account}" } log.info { "[AdminService.findCredentialsByAccount] 관리자 조회 시작: account=${account}" }

View File

@ -21,7 +21,3 @@ annotation class Public
@Target(AnnotationTarget.VALUE_PARAMETER) @Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
annotation class User annotation class User
@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
annotation class Admin

View File

@ -47,17 +47,26 @@ class AdminInterceptor(
} }
return true return true
} catch (e: Exception) { } catch (e: Exception) {
log.warn { "[AdminInterceptor] 예상치 못한 예외: message=${e.message}" } when (e) {
throw AuthException(AuthErrorCode.TEMPORARY_AUTH_ERROR) is AuthException -> { throw e }
else -> {
log.warn { "[AdminInterceptor] 예상치 못한 예외: message=${e.message}" }
throw AuthException(AuthErrorCode.TEMPORARY_AUTH_ERROR)
}
}
} }
} }
private fun validateTypeAndGet(token: String?, requiredType: AdminType): AdminType { private fun validateTypeAndGet(token: String?, requiredType: AdminType): AdminType {
val typeClaim: String? = jwtUtils.extractClaim(token, key = CLAIM_ADMIN_TYPE_KEY) val typeClaim: String? = jwtUtils.extractClaim(token, key = CLAIM_ADMIN_TYPE_KEY)
/**
* 이전의 id 추출 과정에서 토큰이 유효한지 검증했기 때문에 typeClaim null 이라는 것은
* 회원 토큰일 가능성이 . (관리자 토큰에는 CLAIM_ADMIN_TYPE_KEY 무조건 존재함)
*/
if (typeClaim == null) { if (typeClaim == null) {
log.warn { "[AdminInterceptor] 관리자 타입 조회 실패: token=${token}" } log.warn { "[AdminInterceptor] 관리자 타입 조회 실패: token=${token}" }
throw AuthException(AuthErrorCode.INVALID_TOKEN) throw AuthException(AuthErrorCode.ACCESS_DENIED)
} }
val type = try { val type = try {

View File

@ -1,49 +0,0 @@
package roomescape.auth.web.support.resolver
import io.github.oshai.kotlinlogging.KLogger
import io.github.oshai.kotlinlogging.KotlinLogging
import jakarta.servlet.http.HttpServletRequest
import org.springframework.core.MethodParameter
import org.springframework.stereotype.Component
import org.springframework.web.bind.support.WebDataBinderFactory
import org.springframework.web.context.request.NativeWebRequest
import org.springframework.web.method.support.HandlerMethodArgumentResolver
import org.springframework.web.method.support.ModelAndViewContainer
import roomescape.admin.business.AdminService
import roomescape.auth.exception.AuthErrorCode
import roomescape.auth.exception.AuthException
import roomescape.auth.infrastructure.jwt.JwtUtils
import roomescape.auth.web.support.Admin
import roomescape.auth.web.support.accessToken
private val log: KLogger = KotlinLogging.logger {}
@Component
class AdminContextResolver(
private val jwtUtils: JwtUtils,
private val adminService: AdminService,
) : HandlerMethodArgumentResolver {
override fun supportsParameter(parameter: MethodParameter): Boolean {
return parameter.hasParameterAnnotation(Admin::class.java)
}
override fun resolveArgument(
parameter: MethodParameter,
mavContainer: ModelAndViewContainer?,
webRequest: NativeWebRequest,
binderFactory: WebDataBinderFactory?
): Any? {
val request: HttpServletRequest = webRequest.nativeRequest as HttpServletRequest
val token: String? = request.accessToken()
try {
val id: Long = jwtUtils.extractSubject(token).toLong()
return adminService.findContextById(id)
} catch (e: Exception) {
log.info { "[AdminContextResolver] 회원 조회 실패. message=${e.message}" }
throw AuthException(AuthErrorCode.MEMBER_NOT_FOUND)
}
}
}

View File

@ -6,19 +6,16 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
import roomescape.auth.web.support.interceptors.AdminInterceptor import roomescape.auth.web.support.interceptors.AdminInterceptor
import roomescape.auth.web.support.interceptors.UserInterceptor import roomescape.auth.web.support.interceptors.UserInterceptor
import roomescape.auth.web.support.resolver.AdminContextResolver
import roomescape.auth.web.support.resolver.UserContextResolver import roomescape.auth.web.support.resolver.UserContextResolver
@Configuration @Configuration
class WebMvcConfig( class WebMvcConfig(
private val adminInterceptor: AdminInterceptor, private val adminInterceptor: AdminInterceptor,
private val userInterceptor: UserInterceptor, private val userInterceptor: UserInterceptor,
private val adminContextResolver: AdminContextResolver,
private val userContextResolver: UserContextResolver, private val userContextResolver: UserContextResolver,
) : WebMvcConfigurer { ) : WebMvcConfigurer {
override fun addArgumentResolvers(resolvers: MutableList<HandlerMethodArgumentResolver>) { override fun addArgumentResolvers(resolvers: MutableList<HandlerMethodArgumentResolver>) {
resolvers.add(adminContextResolver)
resolvers.add(userContextResolver) resolvers.add(userContextResolver)
} }

View File

@ -73,19 +73,3 @@ data class CurrentUserContext(
val id: Long, val id: Long,
val name: String, val name: String,
) )
data class CurrentAdminContext(
val id: Long,
val name: String,
val type: AdminType,
val storeId: Long?,
val permissionLevel: AdminPermissionLevel
)
fun AdminEntity.toContext() = CurrentAdminContext(
id = this.id,
name = this.name,
type = this.type,
storeId = this.storeId,
permissionLevel = this.permissionLevel
)