-
Notifications
You must be signed in to change notification settings - Fork 0
refactor: sprint1 hardening #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
cc5349d
811390e
7695a7a
b6317ad
f79f27a
5d99fcb
704c338
6f0370f
ab30156
bd78f62
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package com.unit.member.config | ||
|
|
||
| import org.springframework.boot.context.properties.EnableConfigurationProperties | ||
| import org.springframework.context.annotation.Configuration | ||
|
|
||
| @Configuration | ||
| @EnableConfigurationProperties(EmailEncryptionProperties::class) | ||
| class EmailEncryptionConfig |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package com.unit.member.config | ||
|
|
||
| import org.springframework.boot.context.properties.ConfigurationProperties | ||
|
|
||
| @ConfigurationProperties(prefix = "unit.security.email-encryption") | ||
| data class EmailEncryptionProperties( | ||
| val keyBase64: String, | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ import com.unit.member.repository.MemberConsentRepository | |
| import com.unit.member.repository.MemberRepository | ||
| import com.unit.member.repository.SchoolRepository | ||
| import com.unit.member.repository.UserSchoolVerificationRepository | ||
| import com.unit.member.util.EmailEncryptor | ||
| import com.unit.member.util.EmailHasher | ||
| import com.unit.platform.error.BusinessException | ||
| import org.springframework.security.crypto.password.PasswordEncoder | ||
|
|
@@ -32,10 +33,12 @@ class MemberSignupService( | |
| private val emailHasher: EmailHasher, | ||
| private val memberConsentRepository: MemberConsentRepository, | ||
| private val memberConsentProperties: MemberConsentProperties, | ||
| private val emailEncryptor: EmailEncryptor, | ||
| ) : MemberSignupUseCase { | ||
|
|
||
| override fun signup(request: MemberSignupRequest): MemberSignupResponse { | ||
| val emailHash = emailHasher.hash(request.email) | ||
| val email = request.email.trim().lowercase() | ||
| val emailHash = emailHasher.hash(email) | ||
|
Comment on lines
+40
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
μ΄λ² 컀λ°μμ νμκ°μ
μ Useful? React with πΒ / π.
Comment on lines
+40
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
νμκ°μ
μμ μ΄λ©μΌμ μλ¬Έμ μ κ·νν΄ ν΄μλ₯Ό λ§λ€κΈ° μμνμ§λ§ κΈ°μ‘΄ λ°μ΄ν°λ λΉμ κ·ν ν΄μλ₯Ό κ·Έλλ‘ κ°μ§κ³ μμ΄, κ³Όκ±°μ λλ¬Έμλ‘ κ°μ
λ μ£Όμμ λμΌν λ©μΌλ°μ€κ° μλ‘μ΄ μλ¬Έμ ν΄μλ‘ μ€λ³΅ κ°μ
λ μ μμ΅λλ€. μ΄ κ²½μ° Useful? React with πΒ / π. |
||
| val nickname = request.nickname.trim() | ||
| val schoolId = request.schoolId!! | ||
|
|
||
|
|
@@ -54,6 +57,7 @@ class MemberSignupService( | |
| val member = memberRepository.save( | ||
| Member( | ||
| emailHash = emailHash, | ||
| emailEncrypted = emailEncryptor.encrypt(email), | ||
| passwordHash = passwordEncoder.encode(request.password), | ||
| nickname = nickname, | ||
| status = MemberStatus.PENDING, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,18 +2,23 @@ package com.unit.member.service | |
|
|
||
| import com.unit.member.enums.MemberStatus | ||
| import com.unit.member.exception.MemberErrorCode | ||
| import com.unit.member.repository.MemberConsentRepository | ||
| import com.unit.member.repository.MemberRepository | ||
| import com.unit.member.withdrawal.MemberWithdrawalContext | ||
| import com.unit.member.withdrawal.MemberWithdrawalPolicy | ||
| import com.unit.platform.error.BusinessException | ||
| import org.slf4j.LoggerFactory | ||
| import org.springframework.stereotype.Service | ||
| import org.springframework.transaction.annotation.Transactional | ||
| import org.springframework.transaction.support.TransactionSynchronization | ||
| import org.springframework.transaction.support.TransactionSynchronizationManager | ||
| import java.time.LocalDateTime | ||
|
|
||
| @Service | ||
| @Transactional | ||
| class MemberWithdrawalService( | ||
| private val memberRepository: MemberRepository, | ||
| private val memberConsentRepository: MemberConsentRepository, | ||
| private val refreshTokenUseCase: RefreshTokenUseCase, | ||
| private val withdrawalPolicies: List<MemberWithdrawalPolicy>, | ||
| ) : MemberWithdrawalUseCase { | ||
|
|
@@ -33,8 +38,45 @@ class MemberWithdrawalService( | |
| withdrawalPolicies.forEach { it.validate(context) } | ||
|
|
||
| member.withdraw(now) | ||
| memberConsentRepository.findAllByMemberId(context.memberId) | ||
| .forEach { it.withdraw(now) } | ||
| refreshTokenUseCase.revokeAll(context.memberId) | ||
|
|
||
| withdrawalPolicies.forEach { it.apply(context) } | ||
| registerAfterCommit { | ||
| applyWithdrawalPoliciesAfterCommit(context) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private fun registerAfterCommit(action: () -> Unit) { | ||
| if (!TransactionSynchronizationManager.isSynchronizationActive()) { | ||
| action() | ||
| return | ||
| } | ||
|
|
||
| TransactionSynchronizationManager.registerSynchronization( | ||
| object : TransactionSynchronization { | ||
| override fun afterCommit() { | ||
| action() | ||
| } | ||
|
Comment on lines
+58
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Useful? React with πΒ / π. |
||
| }, | ||
| ) | ||
| } | ||
|
|
||
| private fun applyWithdrawalPoliciesAfterCommit(context: MemberWithdrawalContext) { | ||
| withdrawalPolicies.forEach { policy -> | ||
| try { | ||
| policy.apply(context) | ||
| } catch (e: Exception) { | ||
| log.error( | ||
| "Member withdrawal post-processing failed. memberId=${context.memberId}, policy=${policy.javaClass.name}", | ||
| e, | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| companion object { | ||
| private val log = LoggerFactory.getLogger(MemberWithdrawalService::class.java) | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
μ¬κΈ°μ μ΄λ©μΌμ
trim().lowercase()λ‘ μ κ·νν λ€ ν΄μλ₯Ό μ‘°ννλ©΄, μ΄ μ»€λ° μ΄μ μ λμλ¬Έμ κ·Έλλ‘ ν΄μ μ μ₯λ νμ(μ:User@school.ac.kr)μ λμΌ μ£Όμλ‘ λ‘κ·ΈμΈν΄λ νμ λ€λ₯Έ ν΄μκ° λμ΄INVALID_LOGIN_CREDENTIALSλ‘ μ€ν¨ν©λλ€. μ¦ λ°°ν¬ μμ λΆν° μΌλΆ κΈ°μ‘΄ κ³μ μ΄ μ¦μ λ‘κ·ΈμΈ λΆκ° μνκ° λ μ μμΌλ―λ‘, μ΅μν λ°μ΄ν° λ°±ν(backfill) μλ£ μ κΉμ§λ κΈ°μ‘΄ ν΄μ ν¬λ§·λ ν¨κ» μ‘°ννκ±°λ, λ§μ΄κ·Έλ μ΄μ μ μ νν΄ ν΄μ μΌκ΄μ±μ λ§μΆ°μΌ ν©λλ€.Useful? React with πΒ / π.