test #383

Merged
klaus merged 7 commits from test into main 2026-01-28 15:40:26 +00:00
18 changed files with 73 additions and 53 deletions
Showing only changes of commit f778f68f1f - Show all commits

View File

@@ -126,7 +126,7 @@ class AdminMemberService(
GetAdminMemberListResponseItem( GetAdminMemberListResponseItem(
id = it.id!!, id = it.id!!,
email = it.email, email = it.email ?: "",
nickname = it.nickname, nickname = it.nickname,
profileUrl = if (it.profileImage != null) { profileUrl = if (it.profileImage != null) {
"$cloudFrontHost/${it.profileImage}" "$cloudFrontHost/${it.profileImage}"
@@ -160,6 +160,7 @@ class AdminMemberService(
val member = repository.findByIdAndActive(memberId = request.memberId) val member = repository.findByIdAndActive(memberId = request.memberId)
?: throw SodaException(messageKey = "admin.member.reset_password_invalid") ?: throw SodaException(messageKey = "admin.member.reset_password_invalid")
member.password = passwordEncoder.encode(member.email.split("@")[0]) val email = member.email ?: throw SodaException(message = "이메일이 없는 계정은 비밀번호 재설정이 불가능합니다.")
member.password = passwordEncoder.encode(email.split("@")[0])
} }
} }

View File

@@ -5,7 +5,6 @@ import kr.co.vividnext.sodalive.common.ApiResponse
import kr.co.vividnext.sodalive.common.SodaException import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.member.Member import kr.co.vividnext.sodalive.member.Member
import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.security.core.userdetails.User
import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMapping
@@ -29,6 +28,12 @@ class ChargeTempController(private val service: ChargeTempService) {
@PostMapping("/verify") @PostMapping("/verify")
fun verify( fun verify(
@RequestBody request: VerifyRequest, @RequestBody request: VerifyRequest,
@AuthenticationPrincipal user: User @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = ApiResponse.ok(service.verify(user, request)) ) = run {
if (member == null) {
throw SodaException(messageKey = "common.error.bad_credentials")
}
ApiResponse.ok(service.verify(member, request))
}
} }

View File

@@ -15,10 +15,8 @@ import kr.co.vividnext.sodalive.extensions.moneyFormat
import kr.co.vividnext.sodalive.i18n.LangContext import kr.co.vividnext.sodalive.i18n.LangContext
import kr.co.vividnext.sodalive.i18n.SodaMessageSource import kr.co.vividnext.sodalive.i18n.SodaMessageSource
import kr.co.vividnext.sodalive.member.Member import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.MemberRepository
import org.springframework.beans.factory.annotation.Value import org.springframework.beans.factory.annotation.Value
import org.springframework.data.repository.findByIdOrNull import org.springframework.data.repository.findByIdOrNull
import org.springframework.security.core.userdetails.User
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional import org.springframework.transaction.annotation.Transactional
@@ -26,7 +24,6 @@ import org.springframework.transaction.annotation.Transactional
@Transactional(readOnly = true) @Transactional(readOnly = true)
class ChargeTempService( class ChargeTempService(
private val chargeRepository: ChargeRepository, private val chargeRepository: ChargeRepository,
private val memberRepository: MemberRepository,
private val objectMapper: ObjectMapper, private val objectMapper: ObjectMapper,
private val messageSource: SodaMessageSource, private val messageSource: SodaMessageSource,
@@ -54,11 +51,9 @@ class ChargeTempService(
} }
@Transactional @Transactional
fun verify(user: User, verifyRequest: VerifyRequest) { fun verify(member: Member, verifyRequest: VerifyRequest) {
val charge = chargeRepository.findByIdOrNull(verifyRequest.orderId.toLong()) val charge = chargeRepository.findByIdOrNull(verifyRequest.orderId.toLong())
?: throw SodaException(messageKey = "can.charge.invalid_payment_info") ?: throw SodaException(messageKey = "can.charge.invalid_payment_info")
val member = memberRepository.findByEmail(user.username)
?: throw SodaException(messageKey = "common.error.bad_credentials")
if (charge.payment!!.paymentGateway == PaymentGateway.PG) { if (charge.payment!!.paymentGateway == PaymentGateway.PG) {
val bootpay = Bootpay(bootpayApplicationId, bootpayPrivateKey) val bootpay = Bootpay(bootpayApplicationId, bootpayPrivateKey)

View File

@@ -87,7 +87,7 @@ class CreatorAdminMemberService(
userId = member.id!!, userId = member.id!!,
token = jwt, token = jwt,
nickname = member.nickname, nickname = member.nickname,
email = member.email, email = member.email ?: "",
profileImage = if (member.profileImage != null) { profileImage = if (member.profileImage != null) {
"$cloudFrontHost/${member.profileImage}" "$cloudFrontHost/${member.profileImage}"
} else { } else {

View File

@@ -19,7 +19,7 @@ import javax.persistence.OneToOne
@Entity @Entity
data class Member( data class Member(
val email: String, var email: String? = null,
var password: String, var password: String,
var nickname: String, var nickname: String,
var profileImage: String? = null, var profileImage: String? = null,

View File

@@ -4,7 +4,7 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority
import org.springframework.security.core.userdetails.User import org.springframework.security.core.userdetails.User
class MemberAdapter(val member: Member) : User( class MemberAdapter(val member: Member) : User(
member.email, member.email ?: "member:${member.id}",
member.password, member.password,
listOf(SimpleGrantedAuthority("ROLE_${member.role.name}")) listOf(SimpleGrantedAuthority("ROLE_${member.role.name}"))
) )

View File

@@ -20,7 +20,7 @@ import org.springframework.stereotype.Repository
@Repository @Repository
interface MemberRepository : JpaRepository<Member, Long>, MemberQueryRepository { interface MemberRepository : JpaRepository<Member, Long>, MemberQueryRepository {
fun findByEmail(email: String): Member? fun findByEmail(email: String?): Member?
fun findByNickname(nickname: String): Member? fun findByNickname(nickname: String): Member?
fun findByGoogleId(googleId: String): Member? fun findByGoogleId(googleId: String): Member?
fun findByKakaoId(kakaoId: Long): Member? fun findByKakaoId(kakaoId: Long): Member?
@@ -51,7 +51,7 @@ interface MemberQueryRepository {
fun getMessageRecipientPushToken(messageId: Long): PushTokenInfo? fun getMessageRecipientPushToken(messageId: Long): PushTokenInfo?
fun getIndividualRecipientPushTokens(recipients: List<Long>, isAuth: Boolean?): List<PushTokenInfo> fun getIndividualRecipientPushTokens(recipients: List<Long>, isAuth: Boolean?): List<PushTokenInfo>
fun getChangeNicknamePrice(memberId: Long): GetChangeNicknamePriceResponse fun getChangeNicknamePrice(memberId: Long): GetChangeNicknamePriceResponse
fun getMemberByEmail(email: String): Member? fun getMemberByEmail(email: String?): Member?
fun getChangeNoticeRecipientPushTokens(creatorId: Long): List<PushTokenInfo> fun getChangeNoticeRecipientPushTokens(creatorId: Long): List<PushTokenInfo>
fun getPushTokenFromReservationList(roomId: Long): List<PushTokenInfo> fun getPushTokenFromReservationList(roomId: Long): List<PushTokenInfo>
@@ -363,7 +363,8 @@ class MemberQueryRepositoryImpl(
) )
} }
override fun getMemberByEmail(email: String): Member? { override fun getMemberByEmail(email: String?): Member? {
if (email == null) return null
return queryFactory return queryFactory
.selectFrom(member) .selectFrom(member)
.where(member.email.eq(email)) .where(member.email.eq(email))

View File

@@ -346,7 +346,7 @@ class MemberService(
userId = member.id!!, userId = member.id!!,
token = jwt, token = jwt,
nickname = member.nickname, nickname = member.nickname,
email = member.email, email = member.email ?: "",
profileImage = if (member.profileImage != null) { profileImage = if (member.profileImage != null) {
"$cloudFrontHost/${member.profileImage}" "$cloudFrontHost/${member.profileImage}"
} else { } else {
@@ -454,8 +454,16 @@ class MemberService(
} }
override fun loadUserByUsername(username: String): UserDetails { override fun loadUserByUsername(username: String): UserDetails {
val member = repository.findByEmail(email = username) val member = if (username.startsWith("member:")) {
?: throw UsernameNotFoundException(username) val id = username.substringAfter("member:").toLongOrNull()
if (id != null) {
repository.findByIdOrNull(id)
} else {
null
}
} else {
repository.findByEmail(email = username)
} ?: throw UsernameNotFoundException(username)
return MemberAdapter(member) return MemberAdapter(member)
} }
@@ -592,7 +600,7 @@ class MemberService(
@Transactional @Transactional
fun signOut(signOutRequest: SignOutRequest, user: User) { fun signOut(signOutRequest: SignOutRequest, user: User) {
val member = repository.findByEmail(user.username) val member = findMemberByUsername(user.username)
?: throw SodaException(messageKey = "common.error.bad_credentials") ?: throw SodaException(messageKey = "common.error.bad_credentials")
if ( if (
member.provider == MemberProvider.EMAIL && member.provider == MemberProvider.EMAIL &&
@@ -620,11 +628,7 @@ class MemberService(
@Transactional @Transactional
fun updateNickname(profileUpdateRequest: ProfileUpdateRequest, user: User) { fun updateNickname(profileUpdateRequest: ProfileUpdateRequest, user: User) {
if (profileUpdateRequest.email != user.username) { val member = findMemberByUsername(user.username)
throw SodaException(messageKey = "common.error.bad_credentials")
}
val member = repository.findByEmail(user.username)
?: throw SodaException(messageKey = "common.error.bad_credentials") ?: throw SodaException(messageKey = "common.error.bad_credentials")
if (profileUpdateRequest.nickname != null) { if (profileUpdateRequest.nickname != null) {
@@ -652,11 +656,7 @@ class MemberService(
@Transactional @Transactional
fun profileUpdate(profileUpdateRequest: ProfileUpdateRequest, user: User): ProfileResponse { fun profileUpdate(profileUpdateRequest: ProfileUpdateRequest, user: User): ProfileResponse {
if (profileUpdateRequest.email != user.username) { val member = findMemberByUsername(user.username)
throw SodaException(messageKey = "common.error.bad_credentials")
}
val member = repository.findByEmail(user.username)
?: throw SodaException(messageKey = "common.error.bad_credentials") ?: throw SodaException(messageKey = "common.error.bad_credentials")
if (profileUpdateRequest.modifyPassword != null) { if (profileUpdateRequest.modifyPassword != null) {
@@ -729,7 +729,7 @@ class MemberService(
@Transactional @Transactional
fun profileImageUpdate(multipartFile: MultipartFile, user: User): String { fun profileImageUpdate(multipartFile: MultipartFile, user: User): String {
val member = repository.findByEmail(user.username) val member = findMemberByUsername(user.username)
?: throw SodaException(messageKey = "common.error.bad_credentials") ?: throw SodaException(messageKey = "common.error.bad_credentials")
val metadata = ObjectMetadata() val metadata = ObjectMetadata()
@@ -932,7 +932,24 @@ class MemberService(
return MemberResolveResult(member = member, isNew = true) return MemberResolveResult(member = member, isNew = true)
} }
private fun checkEmail(email: String) { private fun findMemberByUsername(username: String): Member? {
return if (username.startsWith("member:")) {
val id = username.substringAfter("member:").toLongOrNull()
if (id != null) {
repository.findByIdOrNull(id)
} else {
null
}
} else {
repository.findByEmail(email = username)
}
}
private fun checkEmail(email: String?) {
if (email.isNullOrBlank()) {
return
}
val member = repository.findByEmail(email) val member = repository.findByEmail(email)
if (member != null) { if (member != null) {

View File

@@ -17,7 +17,7 @@ data class ProfileResponse(
) { ) {
constructor(member: Member, cloudFrontHost: String, container: String) : this( constructor(member: Member, cloudFrontHost: String, container: String) : this(
userId = member.id!!, userId = member.id!!,
email = member.email, email = member.email ?: "",
nickname = member.nickname, nickname = member.nickname,
gender = member.gender, gender = member.gender,
profileUrl = if (member.profileImage != null) { profileUrl = if (member.profileImage != null) {

View File

@@ -1,7 +1,7 @@
package kr.co.vividnext.sodalive.member package kr.co.vividnext.sodalive.member
data class ProfileUpdateRequest( data class ProfileUpdateRequest(
val email: String, val email: String? = null,
val password: String? = null, val password: String? = null,
val modifyPassword: String? = null, val modifyPassword: String? = null,
val nickname: String? = null, val nickname: String? = null,

View File

@@ -47,7 +47,7 @@ class GoogleAuthService(
userId = member.id!!, userId = member.id!!,
token = jwt, token = jwt,
nickname = member.nickname, nickname = member.nickname,
email = member.email, email = member.email ?: "",
profileImage = if (member.profileImage != null) { profileImage = if (member.profileImage != null) {
"$cloudFrontHost/${member.profileImage}" "$cloudFrontHost/${member.profileImage}"
} else { } else {

View File

@@ -3,7 +3,6 @@ package kr.co.vividnext.sodalive.member.social.google
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
import com.google.api.client.json.gson.GsonFactory import com.google.api.client.json.gson.GsonFactory
import kr.co.vividnext.sodalive.common.SodaException
import org.springframework.beans.factory.annotation.Value import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
@@ -27,7 +26,7 @@ class GoogleService(
if (token != null) { if (token != null) {
val payload = token.payload val payload = token.payload
val email = payload.email ?: throw SodaException(messageKey = "member.social.email_consent_required") val email = payload.email
GoogleUserInfo( GoogleUserInfo(
sub = payload.subject, sub = payload.subject,

View File

@@ -2,6 +2,6 @@ package kr.co.vividnext.sodalive.member.social.google
data class GoogleUserInfo( data class GoogleUserInfo(
val sub: String, val sub: String,
val email: String, val email: String?,
val name: String? val name: String?
) )

View File

@@ -47,7 +47,7 @@ class KakaoAuthService(
userId = member.id!!, userId = member.id!!,
token = jwt, token = jwt,
nickname = member.nickname, nickname = member.nickname,
email = member.email, email = member.email ?: "",
profileImage = if (member.profileImage != null) { profileImage = if (member.profileImage != null) {
"$cloudFrontHost/${member.profileImage}" "$cloudFrontHost/${member.profileImage}"
} else { } else {

View File

@@ -1,7 +1,6 @@
package kr.co.vividnext.sodalive.member.social.kakao package kr.co.vividnext.sodalive.member.social.kakao
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import kr.co.vividnext.sodalive.common.SodaException
import org.springframework.http.HttpEntity import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders import org.springframework.http.HttpHeaders
import org.springframework.http.HttpMethod import org.springframework.http.HttpMethod
@@ -37,7 +36,6 @@ class KakaoService(
val id = jsonNode.get("id").asLong() val id = jsonNode.get("id").asLong()
val kakaoAccount = jsonNode.get("kakao_account") val kakaoAccount = jsonNode.get("kakao_account")
val email = kakaoAccount?.get("email")?.asText() val email = kakaoAccount?.get("email")?.asText()
?: throw SodaException(messageKey = "member.social.kakao_login_failed")
val properties = jsonNode.get("properties") val properties = jsonNode.get("properties")
val nickname = properties?.get("nickname")?.asText() val nickname = properties?.get("nickname")?.asText()

View File

@@ -2,6 +2,6 @@ package kr.co.vividnext.sodalive.member.social.kakao
data class KakaoUserInfo( data class KakaoUserInfo(
val id: Long, val id: Long,
val email: String, val email: String?,
val nickname: String? val nickname: String?
) )

View File

@@ -1,9 +1,10 @@
package kr.co.vividnext.sodalive.menu package kr.co.vividnext.sodalive.menu
import kr.co.vividnext.sodalive.common.ApiResponse import kr.co.vividnext.sodalive.common.ApiResponse
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.member.Member
import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.security.core.userdetails.User
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
@@ -13,5 +14,13 @@ import org.springframework.web.bind.annotation.RestController
class MenuController(private val service: MenuService) { class MenuController(private val service: MenuService) {
@GetMapping @GetMapping
@PreAuthorize("hasAnyRole('AGENT', 'ADMIN', 'CREATOR')") @PreAuthorize("hasAnyRole('AGENT', 'ADMIN', 'CREATOR')")
fun getMenus(@AuthenticationPrincipal user: User) = ApiResponse.ok(service.getMenus(user)) fun getMenus(
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?
) = run {
if (member == null) {
throw SodaException(messageKey = "common.error.bad_credentials")
}
ApiResponse.ok(service.getMenus(member))
}
} }

View File

@@ -1,18 +1,13 @@
package kr.co.vividnext.sodalive.menu package kr.co.vividnext.sodalive.menu
import kr.co.vividnext.sodalive.common.SodaException import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.MemberRepository
import org.springframework.security.core.userdetails.User
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
@Service @Service
class MenuService( class MenuService(
private val repository: MenuRepository, private val repository: MenuRepository
private val memberRepository: MemberRepository
) { ) {
fun getMenus(user: User): List<GetMenuResponse> { fun getMenus(member: Member): List<GetMenuResponse> {
val member = memberRepository.findByEmail(user.username)
?: throw SodaException(messageKey = "common.error.bad_credentials")
return repository.getMenu(member.role) return repository.getMenu(member.role)
} }
} }