Skip to content
This repository was archived by the owner on Nov 21, 2023. It is now read-only.

Commit 5a5fc81

Browse files
committed
[#28] authCode 복합키로 설정
- 복합키 미지원 확인 spring-projects/spring-data-relational#574
1 parent 4456124 commit 5a5fc81

File tree

10 files changed

+46
-41
lines changed

10 files changed

+46
-41
lines changed

user-api/src/main/kotlin/com/sns/user/component/authcode/application/AuthCodeCommand.kt user-api/src/main/kotlin/com/sns/user/component/authcode/application/AuthCodeCommandService.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import org.springframework.data.repository.findByIdOrNull
1010
import org.springframework.stereotype.Service
1111

1212
@Service
13-
class AuthCodeCommand(
13+
class AuthCodeCommandService(
1414
val authCodeRepository: AuthCodeRepository,
1515
val mailService: MailService,
1616
val userRepository: DefaultUserRepository,

user-api/src/main/kotlin/com/sns/user/component/authcode/domain/AuthCode.kt

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import org.springframework.jdbc.core.RowMapper
1010

1111
data class AuthCode(
1212
@Id
13-
val id: Int? = null,
14-
// TODO 복합키 구현가능한지 확인.
1513
@NotBlank
1614
val purpose: Purpose,
15+
@Id
1716
@NotBlank
1817
val userId: String,
1918
@NotBlank
@@ -40,7 +39,6 @@ data class AuthCode(
4039
class AuthCodeRowMapper : RowMapper<AuthCode> {
4140
override fun mapRow(rs: ResultSet, rowNum: Int): AuthCode? {
4241
return AuthCode(
43-
id = rs.getInt("id"),
4442
purpose = Purpose.valueOf(rs.getString("purpose")),
4543
userId = rs.getString("user_id"),
4644
code = rs.getString("code"),

user-api/src/main/kotlin/com/sns/user/component/authcode/repositories/AuthCodeCrudRepository.kt

-9
This file was deleted.

user-api/src/main/kotlin/com/sns/user/component/authcode/repositories/AuthCodeRepository.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package com.sns.user.component.authcode.repositories
22

33
import com.sns.user.component.authcode.domain.AuthCode
44
import com.sns.user.component.authcode.domain.Purpose
5-
import org.springframework.data.repository.CrudRepository
65
import org.springframework.data.repository.NoRepositoryBean
76

87
@NoRepositoryBean
9-
interface AuthCodeRepository : CrudRepository<AuthCode, Int> {
8+
interface AuthCodeRepository {
9+
fun save(authCode: AuthCode): AuthCode
1010
fun findByUserIdAndPurpose(userId: String, purpose: Purpose): AuthCode?
1111
}

user-api/src/main/kotlin/com/sns/user/component/authcode/repositories/DefaultAuthCodeRepository.kt

+26-10
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,40 @@ package com.sns.user.component.authcode.repositories
22

33
import com.sns.user.component.authcode.domain.AuthCode
44
import com.sns.user.component.authcode.domain.Purpose
5-
import org.springframework.data.repository.CrudRepository
6-
import org.springframework.jdbc.core.JdbcTemplate
5+
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate
76
import org.springframework.stereotype.Repository
87

98
@Repository
109
class DefaultAuthCodeRepository(
11-
val jdbcTemplate: JdbcTemplate,
12-
val authCodeCrudRepository: AuthCodeCrudRepository
13-
) : AuthCodeRepository, CrudRepository<AuthCode, Int> by authCodeCrudRepository {
10+
val jdbcTemplate: NamedParameterJdbcTemplate,
11+
) : AuthCodeRepository {
1412

1513
override fun findByUserIdAndPurpose(userId: String, purpose: Purpose): AuthCode? = jdbcTemplate.queryForObject(
1614
"""
17-
SELECT id,user_id,`code`,created_at,purpose
18-
FROM auth_code
19-
WHERE user_id = ? AND purpose = ?
20-
ORDER BY id DESC
15+
SELECT user_id,`code`,created_at,purpose
16+
FROM auth_code
17+
WHERE user_id = :userId AND purpose = :purpose
2118
LIMIT 1
2219
""".trimIndent(),
23-
AuthCode.MAPPER, userId, purpose.name,
20+
mutableMapOf(
21+
"userId" to userId,
22+
"purpose" to purpose.name,
23+
),
24+
AuthCode.MAPPER,
2425
)
26+
27+
override fun save(authCode: AuthCode): AuthCode {
28+
jdbcTemplate.update(
29+
"""
30+
REPLACE INTO auth_code (user_id, `code`, created_at, purpose)
31+
VALUES (:userId, :code, NOW(), :purpose)
32+
""".trimIndent(),
33+
mutableMapOf(
34+
"userId" to authCode.userId,
35+
"purpose" to authCode.purpose.name,
36+
"code" to authCode.code,
37+
),
38+
)
39+
return authCode
40+
}
2541
}

user-api/src/main/kotlin/com/sns/user/component/user/listeners/UserStatusListener.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
package com.sns.user.component.user.listeners
22

33
import com.sns.commons.annotation.CustomEventListener
4-
import com.sns.user.component.authcode.application.AuthCodeCommand
4+
import com.sns.user.component.authcode.application.AuthCodeCommandService
55
import com.sns.user.component.user.events.UserActivatedEvent
66
import com.sns.user.component.user.events.UserCreatedEvent
77

88
@CustomEventListener
9-
class UserStatusListener(val authCodeCommand: AuthCodeCommand) {
9+
class UserStatusListener(val authCodeCommandService: AuthCodeCommandService) {
1010
// 인증 전, 기초 가입만 마친 상태
1111
fun onCreated(createdEvent: UserCreatedEvent) {
1212
val user = createdEvent.user
13-
authCodeCommand.create(user.id)
13+
authCodeCommandService.create(user.id)
1414
}
1515

1616
fun onActivated(activatedEvent: UserActivatedEvent) {

user-api/src/main/kotlin/com/sns/user/endpoints/user/SignUpController.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.sns.user.endpoints.user
22

33
import com.sns.commons.utils.ifTrue
4-
import com.sns.user.component.authcode.application.AuthCodeCommand
4+
import com.sns.user.component.authcode.application.AuthCodeCommandService
55
import com.sns.user.component.authcode.domain.Purpose
66
import com.sns.user.component.user.application.UserCommandService
77
import com.sns.user.component.user.application.UserQueryService
@@ -29,7 +29,7 @@ import org.springframework.web.bind.annotation.RestController
2929
@Tag(name = SwaggerTag.SIGN_UP)
3030
@RequestMapping("/api")
3131
class SignUpController(
32-
val authCodeCommand: AuthCodeCommand,
32+
val authCodeCommandService: AuthCodeCommandService,
3333
val userQueryService: UserQueryService,
3434
val userCommandService: UserCommandService
3535
) {
@@ -56,7 +56,7 @@ class SignUpController(
5656
@ResponseStatus(HttpStatus.CREATED)
5757
@PutMapping("/v1/sign-up/verifications/auth-code/ids/{userId}")
5858
fun createAuthenticationCode(@PathVariable userId: String) {
59-
authCodeCommand.create(userId)
59+
authCodeCommandService.create(userId)
6060
}
6161

6262
@ApiResponse(
@@ -66,7 +66,7 @@ class SignUpController(
6666
@ResponseStatus(HttpStatus.OK)
6767
@PostMapping("/v1/sign-up/verifications/auth-code/ids/{userId}")
6868
fun verifyAuthenticationCode(@PathVariable userId: String, @RequestBody code: String): ResponseEntity<Boolean> {
69-
return authCodeCommand.verify(userId, Purpose.SIGN_UP, code)
69+
return authCodeCommandService.verify(userId, Purpose.SIGN_UP, code)
7070
.ifTrue { userCommandService.activate(userId) }
7171
.let {
7272
ResponseEntity.ok(it)

user-api/src/test/kotlin/com/sns/user/component/authcode/application/AuthCodeCommandMockTest.kt user-api/src/test/kotlin/com/sns/user/component/authcode/application/AuthCodeCommandServiceMockTest.kt

+6-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import org.junit.jupiter.api.DisplayName
1717
import org.junit.jupiter.api.Test
1818
import org.springframework.data.repository.findByIdOrNull
1919

20-
class AuthCodeCommandMockTest() {
20+
class AuthCodeCommandServiceMockTest() {
2121
@MockK
2222
private lateinit var authCodeRepository: AuthCodeRepository
2323

@@ -28,7 +28,7 @@ class AuthCodeCommandMockTest() {
2828
private lateinit var userRepository: DefaultUserRepository
2929

3030
@InjectMockKs
31-
private lateinit var authCodeCommand: AuthCodeCommand
31+
private lateinit var authCodeCommandService: AuthCodeCommandService
3232

3333
@BeforeEach
3434
internal fun setUp() {
@@ -40,7 +40,7 @@ class AuthCodeCommandMockTest() {
4040

4141
@Test
4242
fun create() {
43-
val authCode = authCodeCommand.create("id")
43+
val authCode = authCodeCommandService.create("id")
4444

4545
verify { authCodeRepository.save(eq(authCode)) }
4646
verify { mailService.sendSignUpAuthCodeMail(any(), any()) }
@@ -51,7 +51,7 @@ class AuthCodeCommandMockTest() {
5151
fun verify_null() {
5252
every { authCodeRepository.findByUserIdAndPurpose(ofType(String::class), ofType(Purpose::class)) } returns null
5353

54-
authCodeCommand.verify("userId", Purpose.SIGN_UP, "123") isEqualTo false
54+
authCodeCommandService.verify("userId", Purpose.SIGN_UP, "123") isEqualTo false
5555
}
5656

5757
@DisplayName("정상 케이스인 경우, 인증에 성공해야한다.")
@@ -60,7 +60,7 @@ class AuthCodeCommandMockTest() {
6060
val authCode = AuthCode.createSignUp("userId")
6161
every { authCodeRepository.findByUserIdAndPurpose(ofType(String::class), ofType(Purpose::class)) } returns authCode
6262

63-
authCodeCommand.verify("userId", Purpose.SIGN_UP, authCode.code) isEqualTo true
63+
authCodeCommandService.verify("userId", Purpose.SIGN_UP, authCode.code) isEqualTo true
6464
}
6565

6666
@DisplayName("인증 코드가 다른 경우, 인증에 실패해야한다.")
@@ -69,6 +69,6 @@ class AuthCodeCommandMockTest() {
6969
val authCode = AuthCode.createSignUp("userId")
7070
every { authCodeRepository.findByUserIdAndPurpose(ofType(String::class), ofType(Purpose::class)) } returns authCode
7171

72-
authCodeCommand.verify("userId", Purpose.SIGN_UP, "different") isEqualTo false
72+
authCodeCommandService.verify("userId", Purpose.SIGN_UP, "different") isEqualTo false
7373
}
7474
}

user-api/src/test/resources/application.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ spring:
1010
active: test
1111
datasource:
1212
driver-class-name: org.h2.Driver
13-
url: jdbc:h2:mem:testdb
13+
url: jdbc:h2:mem:testdb;MODE=MYSQL
1414
username: root
1515
password: test
1616
sql:

user-api/src/test/resources/db/users/schema.sql

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ CREATE TABLE IF NOT EXISTS `user`
1212

1313
CREATE TABLE IF NOT EXISTS `auth_code`
1414
(
15-
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'user.id',
1615
user_id VARCHAR(50) NOT NULL COMMENT 'user.id',
1716
purpose VARCHAR(50) NOT NULL COMMENT '사용 목적',
1817
code VARCHAR(50) NOT NULL COMMENT '인증 코드',
19-
created_at DATETIME NOT NULL COMMENT '생성 시각'
18+
created_at DATETIME NOT NULL COMMENT '생성 시각',
19+
PRIMARY KEY (`user_id`, purpose)
2020
);

0 commit comments

Comments
 (0)