Merge pull request 'test' (#74) from test into main

Reviewed-on: #74
This commit is contained in:
klaus 2023-11-09 11:18:20 +00:00
commit b848d6b4e0
4 changed files with 120 additions and 43 deletions

View File

@ -19,6 +19,15 @@ class AuthController(private val service: AuthService) {
) = run {
if (member == null) throw SodaException("로그인 정보를 확인해주세요.")
ApiResponse.ok(service.verify(member, request))
val authenticateData = service.certificate(request, memberId = member.id!!)
if (service.isBlockAuth(authenticateData)) {
service.signOut(member.id!!)
throw SodaException("운영정책을 위반하여 이용을 제한합니다.")
} else {
service.authenticate(authenticateData, member.id!!)
}
ApiResponse.ok(null, null)
}
}

View File

@ -3,72 +3,94 @@ package kr.co.vividnext.sodalive.member.auth
import com.fasterxml.jackson.databind.ObjectMapper
import kr.co.bootpay.Bootpay
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.member.Member
import kr.co.vividnext.sodalive.member.MemberRepository
import kr.co.vividnext.sodalive.member.MemberService
import kr.co.vividnext.sodalive.member.SignOut
import kr.co.vividnext.sodalive.member.SignOutRepository
import org.springframework.beans.factory.annotation.Value
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.time.LocalDate
@Service
@Transactional(readOnly = true)
class AuthService(
private val repository: AuthRepository,
private val objectMapper: ObjectMapper,
private val blockAuthRepository: BlockAuthRepository,
private val memberService: MemberService,
private val memberRepository: MemberRepository,
private val signOutRepository: SignOutRepository,
@Value("\${bootpay.application-id}")
private val bootpayApplicationId: String,
@Value("\${bootpay.private-key}")
private val bootpayPrivateKey: String
) {
@Transactional
fun verify(member: Member, request: AuthVerifyRequest) {
fun certificate(request: AuthVerifyRequest, memberId: Long): AuthVerifyCertificate {
val bootpay = Bootpay(bootpayApplicationId, bootpayPrivateKey)
val authId = repository.getAuthIdByMemberId(memberId = member.id!!)
val authId = repository.getAuthIdByMemberId(memberId = memberId)
if (authId != null) throw SodaException("이미 인증된 계정입니다.")
try {
val certificateResult: AuthCertificateResult = try {
val token = bootpay.accessToken
if (token["error_code"] != null) throw SodaException("인증정보에 오류가 있습니다.\n다시 시도해 주세요.")
val res = bootpay.certificate(request.receiptId)
val certificateResult = objectMapper.convertValue(res, AuthCertificateResult::class.java)
if (
certificateResult.status == 12 &&
certificateResult.statusLocale == "본인인증완료" &&
certificateResult.receiptId == request.receiptId
) {
val certificate = certificateResult.authenticateData
val nowYear = LocalDate.now().year
val certificateYear = certificate.birth.substring(0, 4).toInt()
if (nowYear - certificateYear >= 19) {
val memberIds = repository.getActiveMemberIdsByDi(di = certificate.di)
if (memberIds.size >= 3) {
throw SodaException(
"이미 본인인증한 계정 ${memberIds.size}개 이용중입니다.\n" +
"소다라이브의 본인인증은 최대 3개의 계정만 이용할 수 있습니다."
)
}
val auth = Auth(
name = certificate.name,
birth = certificate.birth,
uniqueCi = certificate.unique,
di = certificate.di,
gender = certificate.gender
)
auth.member = member
repository.save(auth)
} else {
throw SodaException("19세 미만 인증 오류")
}
} else {
throw SodaException("인증정보에 오류가 있습니다.\n다시 시도해 주세요.")
}
objectMapper.convertValue(res, AuthCertificateResult::class.java)
} catch (e: Exception) {
throw SodaException(e.message ?: "인증정보에 오류가 있습니다.\n다시 시도해 주세요.")
}
if (
certificateResult.status == 12 &&
certificateResult.statusLocale == "본인인증완료" &&
certificateResult.receiptId == request.receiptId
) {
return certificateResult.authenticateData
} else {
throw SodaException("인증정보에 오류가 있습니다.\n다시 시도해 주세요.")
}
}
fun isBlockAuth(certificate: AuthVerifyCertificate): Boolean {
val blockAuthId = blockAuthRepository.findByUniqueCiAndDi(certificate.unique, certificate.di)
return blockAuthId != null && blockAuthId > 0
}
@Transactional
fun signOut(memberId: Long) {
val member = memberRepository.findByIdOrNull(memberId) ?: throw SodaException("로그인 정보를 확인해주세요.")
member.isActive = false
val signOut = SignOut(reason = "운영정책을 위반하여 이용을 제한합니다.")
signOut.member = member
signOutRepository.save(signOut)
memberService.logoutAll(memberId = memberId)
}
@Transactional
fun authenticate(certificate: AuthVerifyCertificate, memberId: Long) {
val memberIds = repository.getActiveMemberIdsByDi(di = certificate.di)
if (memberIds.size >= 3) {
throw SodaException(
"이미 본인인증한 계정 ${memberIds.size}개 이용중입니다.\n" +
"소다라이브의 본인인증은 최대 3개의 계정만 이용할 수 있습니다."
)
}
val member = memberRepository.findByIdOrNull(memberId) ?: throw SodaException("로그인 정보를 확인해주세요.")
val auth = Auth(
name = certificate.name,
birth = certificate.birth,
uniqueCi = certificate.unique,
di = certificate.di,
gender = certificate.gender
)
auth.member = member
repository.save(auth)
}
}

View File

@ -0,0 +1,19 @@
package kr.co.vividnext.sodalive.member.auth
import kr.co.vividnext.sodalive.common.BaseEntity
import javax.persistence.Column
import javax.persistence.Entity
@Entity
data class BlockAuth(
@Column(nullable = false)
val name: String,
@Column(nullable = false)
val birth: String,
@Column(columnDefinition = "TEXT", nullable = false)
val uniqueCi: String,
@Column(columnDefinition = "TEXT", nullable = false)
val di: String,
@Column(nullable = false)
val gender: Int
) : BaseEntity()

View File

@ -0,0 +1,27 @@
package kr.co.vividnext.sodalive.member.auth
import com.querydsl.jpa.impl.JPAQueryFactory
import kr.co.vividnext.sodalive.member.auth.QBlockAuth.blockAuth
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface BlockAuthRepository : JpaRepository<BlockAuth, Long>, BlockAuthQueryRepository
interface BlockAuthQueryRepository {
fun findByUniqueCiAndDi(uniqueCi: String, di: String): Long?
}
@Repository
class BlockAuthQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : BlockAuthQueryRepository {
override fun findByUniqueCiAndDi(uniqueCi: String, di: String): Long? {
return queryFactory
.select(blockAuth.id)
.from(blockAuth)
.where(
blockAuth.uniqueCi.eq(uniqueCi)
.and(blockAuth.di.eq(di))
)
.fetchFirst()
}
}