This repository has been archived by the owner on Nov 21, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [#28] security 적용 (SecurityConfig.kt) , api mock 생성 * [#28] 가입 인증코드 기능구현 * [#28] 가입기능 구현 * [#28] authCode 복합키로 설정 - 복합키 미지원 확인 spring-projects/spring-data-relational#574 * [#28] spring security에서 swagger관련 제외 * [#28] 이벤트 통일 , exception 응답 설정, 트랜잭션 커밋안되는 이슈 수정 * [#28] 이전 상태 체크 추가 * Update user-api/src/main/kotlin/com/sns/user/core/config/SwaggerTag.kt Co-authored-by: Chanhyeong Cho <chu7825@gmail.com> * PR반영, 논의내용 반영 - response는 json으로 - crudRepository 활용 - controller에 함께 aggregator 위치. (1:1 매칭) * 코드정리, test fail 수정 Co-authored-by: Chanhyeong Cho <chu7825@gmail.com>
- Loading branch information
1 parent
6219617
commit 7b42fcb
Showing
42 changed files
with
978 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
submodules/commons/src/main/kotlin/com/sns/commons/utils/Booleans.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.sns.commons.utils | ||
|
||
inline fun Boolean?.ifTrue(block: Boolean.() -> Unit): Boolean? { | ||
if (this == true) { | ||
block() | ||
} | ||
return this | ||
} | ||
|
||
inline fun Boolean?.ifFalse(block: Boolean.() -> Unit): Boolean? { | ||
if (this == true) { | ||
block() | ||
} | ||
return this | ||
} |
35 changes: 35 additions & 0 deletions
35
...api/src/main/kotlin/com/sns/user/component/authcode/application/AuthCodeCommandService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.sns.user.component.authcode.application | ||
|
||
import com.sns.commons.utils.ifTrue | ||
import com.sns.user.component.authcode.domain.AuthCode | ||
import com.sns.user.component.authcode.domain.AuthCodeKey | ||
import com.sns.user.component.authcode.domain.Purpose | ||
import com.sns.user.component.authcode.repositories.AuthCodeRepository | ||
import com.sns.user.component.user.domains.User | ||
import com.sns.user.core.infrastructures.mail.MailService | ||
import org.springframework.stereotype.Service | ||
import org.springframework.transaction.annotation.Transactional | ||
|
||
@Service | ||
class AuthCodeCommandService( | ||
val authCodeRepository: AuthCodeRepository, | ||
val mailService: MailService, | ||
) { | ||
|
||
@Transactional | ||
fun create(user: User): AuthCode { | ||
val authCode = AuthCode.createSignUp(user.id) | ||
authCodeRepository.save(authCode) | ||
|
||
mailService.sendSignUpAuthCodeMail(authCode.code, user.infoEmailAddress) | ||
return authCode | ||
} | ||
|
||
@Transactional | ||
fun verify(userId: String, purpose: Purpose, code: String): Boolean { | ||
val authCodeKey = AuthCodeKey(purpose, userId) | ||
val authCode: AuthCode? = authCodeRepository.findByAuthCodeKey(authCodeKey) | ||
return authCode?.isCorrect(userId, code, purpose) | ||
.ifTrue { authCodeRepository.delete(authCodeKey) } ?: false | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
user-api/src/main/kotlin/com/sns/user/component/authcode/domain/AuthCode.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.sns.user.component.authcode.domain | ||
|
||
import kotlin.random.Random | ||
import java.sql.ResultSet | ||
import java.time.Instant | ||
import javax.validation.constraints.NotBlank | ||
import org.springframework.jdbc.core.RowMapper | ||
|
||
data class AuthCode( | ||
@NotBlank | ||
val purpose: Purpose, | ||
@NotBlank | ||
val userId: String, | ||
@NotBlank | ||
val code: String = (1..CODE_LENGTH) | ||
.map { Random.nextInt(0, charPool.size) } | ||
.map(charPool::get) | ||
.joinToString(""), | ||
val createdAt: Instant = Instant.MIN | ||
) { | ||
|
||
fun isCorrect(userId: String, code: String, purpose: Purpose): Boolean = | ||
(this.userId == userId) and (this.code == code) and (this.purpose == purpose) | ||
|
||
companion object { | ||
private const val CODE_LENGTH = 10; | ||
private val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9') | ||
fun createSignUp(userId: String) = AuthCode(purpose = Purpose.SIGN_UP, userId = userId) | ||
val MAPPER: RowMapper<AuthCode> = AuthCodeRowMapper() | ||
} | ||
} | ||
|
||
data class AuthCodeKey( | ||
@NotBlank | ||
val purpose: Purpose, | ||
@NotBlank | ||
val userId: String, | ||
) { | ||
fun toMap(): MutableMap<String, Any> = mutableMapOf( | ||
"userId" to userId, | ||
"purpose" to purpose.name, | ||
) | ||
} | ||
|
||
// purpose enum 매핑이 안되서 수동으로 작성함. 확인필요. | ||
class AuthCodeRowMapper : RowMapper<AuthCode> { | ||
override fun mapRow(rs: ResultSet, rowNum: Int): AuthCode? { | ||
return AuthCode( | ||
purpose = Purpose.valueOf(rs.getString("purpose")), | ||
userId = rs.getString("user_id"), | ||
code = rs.getString("code"), | ||
createdAt = Instant.ofEpochMilli(rs.getTimestamp("created_at").time), | ||
) | ||
} | ||
} | ||
|
||
enum class Purpose { | ||
SIGN_UP | ||
} |
10 changes: 10 additions & 0 deletions
10
user-api/src/main/kotlin/com/sns/user/component/authcode/repositories/AuthCodeRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.sns.user.component.authcode.repositories | ||
|
||
import com.sns.user.component.authcode.domain.AuthCode | ||
import com.sns.user.component.authcode.domain.AuthCodeKey | ||
|
||
interface AuthCodeRepository { | ||
fun save(authCode: AuthCode): AuthCode | ||
fun findByAuthCodeKey(authCodeKey: AuthCodeKey): AuthCode? | ||
fun delete(authCodeKey: AuthCodeKey) | ||
} |
51 changes: 51 additions & 0 deletions
51
...src/main/kotlin/com/sns/user/component/authcode/repositories/DefaultAuthCodeRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.sns.user.component.authcode.repositories | ||
|
||
import com.sns.user.component.authcode.domain.AuthCode | ||
import com.sns.user.component.authcode.domain.AuthCodeKey | ||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate | ||
import org.springframework.stereotype.Repository | ||
import org.springframework.transaction.annotation.Transactional | ||
|
||
@Repository | ||
class DefaultAuthCodeRepository( | ||
val jdbcTemplate: NamedParameterJdbcTemplate, | ||
) : AuthCodeRepository { | ||
|
||
override fun findByAuthCodeKey(authCodeKey: AuthCodeKey): AuthCode? = jdbcTemplate.queryForObject( | ||
""" | ||
SELECT user_id,`code`,created_at,purpose | ||
FROM auth_code | ||
WHERE user_id = :userId AND purpose = :purpose | ||
LIMIT 1 | ||
""".trimIndent(), | ||
authCodeKey.toMap(), AuthCode.MAPPER, | ||
) | ||
|
||
@Transactional | ||
override fun save(authCode: AuthCode): AuthCode { | ||
jdbcTemplate.update( | ||
""" | ||
REPLACE INTO auth_code (user_id, `code`, created_at, purpose) | ||
VALUES (:userId, :code, NOW(), :purpose) | ||
""".trimIndent(), | ||
mutableMapOf( | ||
"userId" to authCode.userId, | ||
"purpose" to authCode.purpose.name, | ||
"code" to authCode.code, | ||
), | ||
) | ||
return authCode | ||
} | ||
|
||
@Transactional | ||
override fun delete(authCodeKey: AuthCodeKey) { | ||
jdbcTemplate.update( | ||
""" | ||
DELETE FROM auth_code | ||
WHERE user_id = :userId AND purpose = :purpose | ||
LIMIT 1 | ||
""".trimIndent(), | ||
authCodeKey.toMap(), | ||
) | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
user-api/src/main/kotlin/com/sns/user/component/user/application/UserCommandService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.sns.user.component.user.application | ||
|
||
import com.sns.commons.service.EventPublisher | ||
import com.sns.user.component.user.domains.User | ||
import com.sns.user.component.user.repositories.UserRepository | ||
import com.sns.user.core.exceptions.AlreadyExistException | ||
import com.sns.user.core.exceptions.NoAuthorityException | ||
import org.springframework.data.repository.findByIdOrNull | ||
import org.springframework.security.crypto.password.PasswordEncoder | ||
import org.springframework.stereotype.Service | ||
import org.springframework.transaction.annotation.Transactional | ||
|
||
@Service | ||
class UserCommandService( | ||
private val userRepository: UserRepository, | ||
private val passwordEncoder: PasswordEncoder, | ||
private val eventPublisher: EventPublisher | ||
) { | ||
|
||
@Transactional | ||
fun create(name: String, password: String, email: String): User { | ||
userRepository.findById(email).ifPresent { throw AlreadyExistException() } | ||
|
||
val user = User.create(email, passwordEncoder.encode(password), name, email) { | ||
eventPublisher.publish(it) | ||
} | ||
userRepository.save(user) | ||
return user | ||
} | ||
|
||
@Transactional | ||
fun activate(userId: String) { | ||
val user = userRepository.findByIdOrNull(userId) ?: throw NoAuthorityException() | ||
|
||
user.activate() { | ||
eventPublisher.publish(it) | ||
} | ||
userRepository.save(user) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
user-api/src/main/kotlin/com/sns/user/component/user/events/UserStatusChangedEvent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.sns.user.component.user.events | ||
|
||
import com.sns.commons.DomainEvent | ||
import com.sns.user.component.user.domains.User | ||
import com.sns.user.core.config.IntegrationConfig | ||
|
||
class UserStatusChangedEvent(val user: User) : DomainEvent { | ||
override val eventId: String | ||
get() = "$channel-$user.id-${System.currentTimeMillis()}" | ||
|
||
override val channel = IntegrationConfig.Channels.USER_STATUS | ||
} |
18 changes: 18 additions & 0 deletions
18
user-api/src/main/kotlin/com/sns/user/component/user/listeners/UserStatusListener.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.sns.user.component.user.listeners | ||
|
||
import com.sns.commons.annotation.CustomEventListener | ||
import com.sns.user.component.authcode.application.AuthCodeCommandService | ||
import com.sns.user.component.user.events.UserStatusChangedEvent | ||
|
||
@CustomEventListener | ||
class UserStatusListener(val authCodeCommandService: AuthCodeCommandService) { | ||
// 인증 전, 기초 가입만 마친 상태 | ||
fun onCreated(createdEvent: UserStatusChangedEvent) { | ||
val user = createdEvent.user | ||
authCodeCommandService.create(user) | ||
} | ||
|
||
fun onActivated(activatedEvent: UserStatusChangedEvent) { | ||
// TODO 타임라인생성, 프로필생성,, | ||
} | ||
} |
4 changes: 3 additions & 1 deletion
4
user-api/src/main/kotlin/com/sns/user/component/user/repositories/DefaultUserRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,11 @@ | ||
package com.sns.user.component.user.repositories | ||
|
||
import org.springframework.jdbc.core.JdbcTemplate | ||
import org.springframework.stereotype.Repository | ||
|
||
@Repository | ||
class DefaultUserRepository( | ||
userCrudRepository: UserCrudRepository | ||
userCrudRepository: UserCrudRepository, | ||
private val jdbcTemplate: JdbcTemplate | ||
) : UserRepository, | ||
UserCrudRepository by userCrudRepository |
5 changes: 4 additions & 1 deletion
5
user-api/src/main/kotlin/com/sns/user/component/user/repositories/UserCrudRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
package com.sns.user.component.user.repositories | ||
|
||
import com.sns.user.component.user.domains.User | ||
import java.util.* | ||
import org.springframework.data.repository.CrudRepository | ||
import org.springframework.stereotype.Repository | ||
|
||
@Repository | ||
interface UserCrudRepository : CrudRepository<User, String> | ||
interface UserCrudRepository : CrudRepository<User, String> { | ||
fun findByInfoEmailAddress(email: String): Optional<User> | ||
} |
5 changes: 4 additions & 1 deletion
5
user-api/src/main/kotlin/com/sns/user/component/user/repositories/UserRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,11 @@ | ||
package com.sns.user.component.user.repositories | ||
|
||
import com.sns.user.component.user.domains.User | ||
import java.util.* | ||
import org.springframework.data.repository.CrudRepository | ||
import org.springframework.data.repository.NoRepositoryBean | ||
|
||
@NoRepositoryBean | ||
interface UserRepository : CrudRepository<User, String> | ||
interface UserRepository : CrudRepository<User, String> { | ||
fun findByInfoEmailAddress(email: String): Optional<User> | ||
} |
Oops, something went wrong.