Skip to content

Commit 5a60e17

Browse files
committed
role packages refactor
key store dynamo implementation test with contract test technique
1 parent d669e09 commit 5a60e17

File tree

14 files changed

+230
-162
lines changed

14 files changed

+230
-162
lines changed

src/main/kotlin/com/vauthenticator/server/config/PermissionConfig.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import com.vauthenticator.server.cache.RedisCacheOperation
66
import com.vauthenticator.server.oauth2.clientapp.domain.ClientApplicationRepository
77
import com.vauthenticator.server.role.PermissionValidator
88
import com.vauthenticator.server.role.RoleCacheContentConverter
9-
import com.vauthenticator.server.role.repository.CachedRoleRepository
10-
import com.vauthenticator.server.role.repository.dynamodb.DynamoDbRoleRepository
11-
import com.vauthenticator.server.role.repository.jdbc.JdbcRoleRepository
9+
import com.vauthenticator.server.role.adapter.CachedRoleRepository
10+
import com.vauthenticator.server.role.adapter.dynamodb.DynamoDbRoleRepository
11+
import com.vauthenticator.server.role.adapter.jdbc.JdbcRoleRepository
1212
import org.springframework.beans.factory.annotation.Value
1313
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
1414
import org.springframework.context.annotation.Bean
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.vauthenticator.server.keys.adapter.jdbc
2+
3+
import com.vauthenticator.server.keys.domain.*
4+
import org.slf4j.LoggerFactory
5+
import java.time.Duration
6+
7+
class JdbcKeyStorage : KeyStorage {
8+
9+
private val logger = LoggerFactory.getLogger(JdbcKeyStorage::class.java)
10+
11+
override fun store(
12+
masterKid: MasterKid,
13+
kid: Kid,
14+
dataKey: DataKey,
15+
keyType: KeyType,
16+
keyPurpose: KeyPurpose
17+
) {
18+
TODO()
19+
}
20+
21+
override fun signatureKeys(): Keys {
22+
TODO()
23+
}
24+
25+
override fun findOne(kid: Kid, keyPurpose: KeyPurpose): Key {
26+
TODO()
27+
}
28+
29+
override fun justDeleteKey(kid: Kid, keyPurpose: KeyPurpose) {
30+
TODO()
31+
}
32+
33+
override fun keyDeleteJodPlannedFor(kid: Kid, ttl: Duration, keyPurpose: KeyPurpose) {
34+
TODO()
35+
}
36+
37+
}

src/main/kotlin/com/vauthenticator/server/role/repository/CachedRoleRepository.kt renamed to src/main/kotlin/com/vauthenticator/server/role/adapter/CachedRoleRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.vauthenticator.server.role.repository
1+
package com.vauthenticator.server.role.adapter
22

33
import com.vauthenticator.server.cache.CacheContentConverter
44
import com.vauthenticator.server.cache.CacheOperation

src/main/kotlin/com/vauthenticator/server/role/repository/dynamodb/DynamoDbRoleRepository.kt renamed to src/main/kotlin/com/vauthenticator/server/role/adapter/dynamodb/DynamoDbRoleRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.vauthenticator.server.role.repository.dynamodb
1+
package com.vauthenticator.server.role.adapter.dynamodb
22

33
import com.vauthenticator.server.role.DynamoDbRoleMapper
44
import com.vauthenticator.server.role.ProtectedRoleFromDeletionException

src/main/kotlin/com/vauthenticator/server/role/repository/jdbc/JdbcRoleRepository.kt renamed to src/main/kotlin/com/vauthenticator/server/role/adapter/jdbc/JdbcRoleRepository.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.vauthenticator.server.role.repository.jdbc
1+
package com.vauthenticator.server.role.adapter.jdbc
22

33
import com.vauthenticator.server.role.ProtectedRoleFromDeletionException
44
import com.vauthenticator.server.role.Role

src/test/kotlin/com/vauthenticator/server/account/repository/dynamodb/DynamoDbAbstractAccountRepositoryTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import com.vauthenticator.server.account.repository.AbstractAccountRepositoryTes
44
import com.vauthenticator.server.account.repository.AccountRepository
55
import com.vauthenticator.server.role.RoleRepository
66
import com.vauthenticator.server.role.protectedRoleNames
7-
import com.vauthenticator.server.role.repository.dynamodb.DynamoDbRoleRepository
7+
import com.vauthenticator.server.role.adapter.dynamodb.DynamoDbRoleRepository
88
import com.vauthenticator.server.support.DynamoDbUtils.dynamoAccountTableName
99
import com.vauthenticator.server.support.DynamoDbUtils.dynamoDbClient
1010
import com.vauthenticator.server.support.DynamoDbUtils.dynamoRoleTableName

src/test/kotlin/com/vauthenticator/server/account/repository/jdbc/JdbcAccountRepositoryTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import com.vauthenticator.server.account.repository.AbstractAccountRepositoryTes
44
import com.vauthenticator.server.account.repository.AccountRepository
55
import com.vauthenticator.server.role.RoleRepository
66
import com.vauthenticator.server.role.protectedRoleNames
7-
import com.vauthenticator.server.role.repository.jdbc.JdbcRoleRepository
7+
import com.vauthenticator.server.role.adapter.jdbc.JdbcRoleRepository
88
import com.vauthenticator.server.support.JdbcUtils.jdbcTemplate
99
import com.vauthenticator.server.support.JdbcUtils.resetDb
1010

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package com.vauthenticator.server.keys.adapter
2+
3+
import com.vauthenticator.server.extentions.encoder
4+
import com.vauthenticator.server.extentions.valueAsStringFor
5+
import com.vauthenticator.server.keys.domain.KeyPurpose.MFA
6+
import com.vauthenticator.server.keys.domain.KeyPurpose.SIGNATURE
7+
import com.vauthenticator.server.keys.domain.KeyStorage
8+
import com.vauthenticator.server.keys.domain.KeyType.ASYMMETRIC
9+
import com.vauthenticator.server.keys.domain.KeyType.SYMMETRIC
10+
import com.vauthenticator.server.keys.domain.Keys
11+
import com.vauthenticator.server.keys.domain.Kid
12+
import com.vauthenticator.server.support.DynamoDbUtils.dynamoMfaKeysTableName
13+
import com.vauthenticator.server.support.DynamoDbUtils.dynamoSignatureKeysTableName
14+
import com.vauthenticator.server.support.KeysUtils.aKeyFor
15+
import com.vauthenticator.server.support.KeysUtils.aKid
16+
import com.vauthenticator.server.support.KeysUtils.aMasterKey
17+
import com.vauthenticator.server.support.KeysUtils.aSignatureDataKey
18+
import com.vauthenticator.server.support.KeysUtils.aSimmetricDataKey
19+
import com.vauthenticator.server.support.KeysUtils.anotherKid
20+
import org.junit.jupiter.api.Assertions.assertEquals
21+
import org.junit.jupiter.api.BeforeEach
22+
import org.junit.jupiter.api.Test
23+
import software.amazon.awssdk.services.dynamodb.model.AttributeValue
24+
import java.time.Duration
25+
import java.time.Instant
26+
import kotlin.test.assertNotNull
27+
28+
abstract class AbstractKeyStorageTest {
29+
30+
private val masterKid = aMasterKey
31+
private val now = Instant.now()
32+
33+
private lateinit var uut: KeyStorage
34+
35+
abstract fun initKeyStorage(): KeyStorage
36+
abstract fun resetDatabase()
37+
abstract fun getActual(kid: Kid, tableName: String): MutableMap<String, AttributeValue>
38+
39+
40+
@BeforeEach
41+
fun setUp() {
42+
resetDatabase()
43+
uut = initKeyStorage()
44+
}
45+
46+
@Test
47+
fun `when store a new data key pair`() {
48+
uut.store(masterKid, aKid, aSignatureDataKey, ASYMMETRIC, SIGNATURE)
49+
50+
val actual = getActual(aKid, dynamoSignatureKeysTableName)
51+
assertEquals(aKid.content(), actual.valueAsStringFor("key_id"))
52+
assertEquals(masterKid.content(), actual.valueAsStringFor("master_key_id"))
53+
assertEquals(
54+
encoder.encode(aSignatureDataKey.encryptedPrivateKey)
55+
.decodeToString(), actual.valueAsStringFor("encrypted_private_key")
56+
)
57+
assertEquals(
58+
encoder.encode(aSignatureDataKey.publicKey.get()).decodeToString(),
59+
actual.valueAsStringFor("public_key")
60+
)
61+
}
62+
63+
@Test
64+
fun `when store a new data key for mfa`() {
65+
uut.store(masterKid, aKid, aSimmetricDataKey, SYMMETRIC, MFA)
66+
67+
val actual = getActual(aKid, dynamoMfaKeysTableName)
68+
assertEquals(aKid.content(), actual.valueAsStringFor("key_id"))
69+
assertEquals(masterKid.content(), actual.valueAsStringFor("master_key_id"))
70+
assertEquals(
71+
encoder.encode(aSimmetricDataKey.encryptedPrivateKey)
72+
.decodeToString(), actual.valueAsStringFor("encrypted_private_key")
73+
)
74+
}
75+
76+
@Test
77+
fun `when find an mfa key`() {
78+
uut.store(masterKid, aKid, aSimmetricDataKey, SYMMETRIC, MFA)
79+
val actual = uut.findOne(aKid, MFA)
80+
val excpected = aKeyFor(masterKid.content(), aKid.content(), SYMMETRIC, MFA)
81+
assertEquals(excpected, actual)
82+
}
83+
84+
@Test
85+
fun `when find an signature key`() {
86+
uut.store(masterKid, aKid, aSignatureDataKey, ASYMMETRIC, SIGNATURE)
87+
val actual = uut.findOne(aKid, SIGNATURE)
88+
val excpected = aKeyFor(masterKid.content(), aKid.content(), ASYMMETRIC, SIGNATURE)
89+
assertEquals(excpected, actual)
90+
}
91+
92+
@Test
93+
fun `when find all signature keys`() {
94+
uut.store(masterKid, aKid, aSignatureDataKey, ASYMMETRIC, SIGNATURE)
95+
uut.store(masterKid, anotherKid, aSignatureDataKey, ASYMMETRIC, SIGNATURE)
96+
val actual = uut.signatureKeys()
97+
val excpected = Keys(
98+
listOf(
99+
aKeyFor(masterKid.content(), aKid.content(), ASYMMETRIC, SIGNATURE),
100+
aKeyFor(masterKid.content(), anotherKid.content(), ASYMMETRIC, SIGNATURE)
101+
)
102+
)
103+
assertEquals(excpected, actual)
104+
}
105+
106+
@Test
107+
fun `when a signature key is deleted`() {
108+
uut.store(masterKid, aKid, aSignatureDataKey, ASYMMETRIC, SIGNATURE)
109+
val storedKey = uut.findOne(aKid, SIGNATURE)
110+
assertNotNull(storedKey)
111+
112+
uut.justDeleteKey(aKid, SIGNATURE)
113+
val actual = getActual(aKid, dynamoSignatureKeysTableName)
114+
assertEquals(emptyMap<String, AttributeValue>(), actual)
115+
}
116+
117+
@Test
118+
fun `when a signature key planned to be deleted`() {
119+
uut.store(masterKid, aKid, aSignatureDataKey, ASYMMETRIC, SIGNATURE)
120+
val storedKey = uut.findOne(aKid, SIGNATURE)
121+
assertNotNull(storedKey)
122+
123+
val ttl = Duration.ofSeconds(1)
124+
uut.keyDeleteJodPlannedFor(aKid, ttl, SIGNATURE)
125+
126+
val actual = getActual(aKid, dynamoSignatureKeysTableName)
127+
val expectedTTl = now.epochSecond + 1
128+
assertEquals(false, (actual["enabled"] as AttributeValue).bool())
129+
assertEquals(expectedTTl, (actual["key_expiration_date_timestamp"] as AttributeValue).n().toLong())
130+
}
131+
132+
@Test
133+
fun `when a signature key deletion planning is ignored`() {
134+
uut.store(masterKid, aKid, aSignatureDataKey, ASYMMETRIC, SIGNATURE)
135+
val storedKey = uut.findOne(aKid, SIGNATURE)
136+
assertNotNull(storedKey)
137+
138+
uut.keyDeleteJodPlannedFor(aKid, Duration.ofSeconds(1), SIGNATURE)
139+
140+
val actual = getActual(aKid, dynamoSignatureKeysTableName)
141+
val expectedTTl = now.epochSecond + 1
142+
assertEquals(false, (actual["enabled"] as AttributeValue).bool())
143+
assertEquals(expectedTTl, (actual["key_expiration_date_timestamp"] as AttributeValue).n().toLong())
144+
145+
uut.keyDeleteJodPlannedFor(aKid, Duration.ofSeconds(10), SIGNATURE)
146+
147+
val actualAfterReplanning = getActual(aKid, dynamoSignatureKeysTableName)
148+
val expectedTTlAfterReplanning = now.epochSecond + 1
149+
assertEquals(false, (actualAfterReplanning["enabled"] as AttributeValue).bool())
150+
assertEquals(expectedTTlAfterReplanning, (actualAfterReplanning["key_expiration_date_timestamp"] as AttributeValue).n().toLong())
151+
}
152+
153+
}

0 commit comments

Comments
 (0)