Skip to content

Commit

Permalink
repackaging
Browse files Browse the repository at this point in the history
key repository jdbc test
  • Loading branch information
mrFlick72 committed Oct 24, 2024
1 parent 4e90dd3 commit b03824b
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 78 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.vauthenticator.server.communication.adapter.email
package com.vauthenticator.server.communication.adapter.javamail

import com.vauthenticator.document.repository.DocumentRepository
import com.vauthenticator.document.repository.DocumentType
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.vauthenticator.server.communication.adapter.sms
package com.vauthenticator.server.communication.adapter.sns

import com.vauthenticator.server.account.Account
import com.vauthenticator.server.communication.domain.MessageContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.vauthenticator.server.account.emailverification.VerifyEMailChallenge
import com.vauthenticator.server.account.repository.AccountRepository
import com.vauthenticator.server.communication.NoReplyEMailConfiguration
import com.vauthenticator.server.communication.adapter.JinJavaTemplateResolver
import com.vauthenticator.server.communication.adapter.email.JavaEMailSenderService
import com.vauthenticator.server.communication.adapter.javamail.JavaEMailSenderService
import com.vauthenticator.server.communication.domain.EMailSenderService
import com.vauthenticator.server.communication.domain.EMailType
import com.vauthenticator.server.communication.domain.SimpleEMailMessageFactory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.vauthenticator.document.repository.DocumentRepository
import com.vauthenticator.server.account.repository.AccountRepository
import com.vauthenticator.server.communication.NoReplyEMailConfiguration
import com.vauthenticator.server.communication.adapter.JinJavaTemplateResolver
import com.vauthenticator.server.communication.adapter.email.JavaEMailSenderService
import com.vauthenticator.server.communication.adapter.javamail.JavaEMailSenderService
import com.vauthenticator.server.communication.domain.EMailSenderService
import com.vauthenticator.server.communication.domain.EMailType
import com.vauthenticator.server.communication.domain.SimpleEMailMessageFactory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.vauthenticator.server.account.welcome.SayWelcome
import com.vauthenticator.server.account.welcome.SendWelcomeMailUponSignUpEventConsumer
import com.vauthenticator.server.communication.NoReplyEMailConfiguration
import com.vauthenticator.server.communication.adapter.JinJavaTemplateResolver
import com.vauthenticator.server.communication.adapter.email.JavaEMailSenderService
import com.vauthenticator.server.communication.adapter.javamail.JavaEMailSenderService
import com.vauthenticator.server.communication.domain.EMailSenderService
import com.vauthenticator.server.communication.domain.EMailType
import com.vauthenticator.server.communication.domain.SimpleEMailMessageFactory
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package com.vauthenticator.server.keys.adapter.jdbc

import com.vauthenticator.server.extentions.expirationTimeStampInSecondFromNow
import com.vauthenticator.server.keys.domain.*
import org.slf4j.LoggerFactory
import org.springframework.jdbc.core.JdbcTemplate
import java.sql.ResultSet
import java.time.Clock
import java.time.Duration

class JdbcKeyStorage(private val jdbcTemplate: JdbcTemplate) : KeyStorage {
class JdbcKeyStorage(
private val jdbcTemplate: JdbcTemplate,
private val clock: Clock,
) : KeyStorage {

private val logger = LoggerFactory.getLogger(JdbcKeyStorage::class.java)

Expand All @@ -18,59 +24,66 @@ class JdbcKeyStorage(private val jdbcTemplate: JdbcTemplate) : KeyStorage {
) {
jdbcTemplate.update(
"""
INSERT INTO KEY (
key_id
INSERT INTO KEYS(
key_id,
master_key_id,
key_purpose,
key_type,
encrypted_private_key,
public_key,
enabled,
key_expiration_date_timestamp
) VALUES (?,?,?,?,?,?,?,?)
) VALUES (?,?,?,?,?,?,?,?)
""".trimIndent(),
kid.content(),
masterKid.content(),
keyPurpose.name,
keyType.name,
dataKey.encryptedPrivateKeyAsString(),
dataKey.publicKeyAsString(),
keyPurpose.name,
true,
Duration.ofSeconds(0).toSeconds()
)
}

override fun signatureKeys(): Keys {
TODO()
}
override fun signatureKeys(): Keys = Keys(
jdbcTemplate.query(
"SELECT * FROM KEYS WHERE key_purpose = ?;", { rs, _ -> keyFrom(rs) },
KeyPurpose.SIGNATURE.name
)
)


override fun findOne(kid: Kid, keyPurpose: KeyPurpose): Key {
return jdbcTemplate.query(
"""
SELECT * FROM KEY WHERE key_id = ? AND key_purpose = ?;
""".trimIndent(), { rs, _ ->
Key(
kid = Kid(rs.getString("key_id")),
masterKid = MasterKid(rs.getString("master_key_id")),
keyPurpose = KeyPurpose.valueOf(rs.getString("key_purpose")),
enabled = rs.getBoolean("enabled"),
type = KeyType.valueOf(rs.getString("key_type")),
expirationDateTimestamp = rs.getLong("key_expiration_date_timestamp"),
dataKey = DataKey.from(
rs.getString("encrypted_private_key"),
rs.getString("public_key"),
)
)
},
return jdbcTemplate.query(
"SELECT * FROM KEYS WHERE key_id = ? AND key_purpose = ?;", { rs, _ -> keyFrom(rs) },
kid.content(), keyPurpose.name
).first()
}

private fun keyFrom(rs: ResultSet) = Key(
kid = Kid(rs.getString("key_id")),
masterKid = MasterKid(rs.getString("master_key_id")),
keyPurpose = KeyPurpose.valueOf(rs.getString("key_purpose")),
enabled = rs.getBoolean("enabled"),
type = KeyType.valueOf(rs.getString("key_type")),
expirationDateTimestamp = rs.getLong("key_expiration_date_timestamp"),
dataKey = DataKey.from(
rs.getString("encrypted_private_key"),
rs.getString("public_key"),
)
)

override fun justDeleteKey(kid: Kid, keyPurpose: KeyPurpose) {
TODO()
jdbcTemplate.update(
"DELETE FROM KEYS WHERE key_id = ? AND key_purpose = ?;", kid.content(), keyPurpose.name
)
}

override fun keyDeleteJodPlannedFor(kid: Kid, ttl: Duration, keyPurpose: KeyPurpose) {
TODO()
jdbcTemplate.update("UPDATE KEYS SET key_expiration_date_timestamp=?, enabled=? WHERE key_id =? AND key_expiration_date_timestamp=0 AND key_purpose=?",
ttl.expirationTimeStampInSecondFromNow(clock), false, kid.content(), keyPurpose.name
)
}

}
4 changes: 2 additions & 2 deletions src/main/kotlin/com/vauthenticator/server/mfa/MfaConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import com.vauthenticator.document.repository.DocumentRepository
import com.vauthenticator.server.account.repository.AccountRepository
import com.vauthenticator.server.communication.NoReplyEMailConfiguration
import com.vauthenticator.server.communication.adapter.JinJavaTemplateResolver
import com.vauthenticator.server.communication.adapter.email.JavaEMailSenderService
import com.vauthenticator.server.communication.adapter.sms.SnsSmsSenderService
import com.vauthenticator.server.communication.adapter.javamail.JavaEMailSenderService
import com.vauthenticator.server.communication.adapter.sns.SnsSmsSenderService
import com.vauthenticator.server.communication.domain.*
import com.vauthenticator.server.keys.domain.KeyDecrypter
import com.vauthenticator.server.keys.domain.KeyRepository
Expand Down
9 changes: 4 additions & 5 deletions src/main/resources/data/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,19 @@ CREATE TABLE ACCOUNT_ROLE
FOREIGN KEY (role_name) REFERENCES ROLE (name) on delete cascade
);

CREATE TABLE KEY
CREATE TABLE KEYS
(
key_id varchar(255) not null primary key,
master_key_id varchar(255) not null,
key_purpose varchar(255) not null,
key_type varchar(255) not null,
encrypted_private_key text,
public_key text,
enabled not null default false,
key_expiration_date_timestamp bigint_field not null default 0,

enabled boolean not null default false,
key_expiration_date_timestamp bigint not null default 0
);

CREATE INDEX keys_key_purpose ON KEY (key_purpose);
CREATE INDEX keys_key_purpose ON KEYS (key_purpose);

CREATE TABLE CLIENT_APPLICATION
(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package com.vauthenticator.server.communication.email
package com.vauthenticator.server.communication.adapter.javamail

import com.hubspot.jinjava.Jinjava
import com.icegreen.greenmail.configuration.GreenMailConfiguration
import com.icegreen.greenmail.junit5.GreenMailExtension
import com.icegreen.greenmail.util.ServerSetupTest
import com.vauthenticator.document.repository.DocumentRepository
import com.vauthenticator.server.communication.adapter.JinJavaTemplateResolver
import com.vauthenticator.server.communication.adapter.email.JavaEMailSenderService
import com.vauthenticator.server.communication.domain.EMailSenderService
import com.vauthenticator.server.communication.domain.EMailType
import com.vauthenticator.server.communication.domain.MessageTemplateResolver
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.vauthenticator.server.communication.sms
package com.vauthenticator.server.communication.adapter.sns

import com.vauthenticator.server.account.Phone.Companion.phoneFor
import com.vauthenticator.server.communication.adapter.sms.SnsSmsSenderService
import com.vauthenticator.server.communication.domain.SmsMessage
import com.vauthenticator.server.communication.domain.SmsMessageFactory
import com.vauthenticator.server.support.AccountTestFixture.anAccount
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package com.vauthenticator.server.communication.email
package com.vauthenticator.server.communication.domain

import com.vauthenticator.server.communication.domain.EMailMessage
import com.vauthenticator.server.communication.domain.EMailType
import com.vauthenticator.server.communication.domain.SimpleEMailMessageFactory
import com.vauthenticator.server.support.AccountTestFixture.anAccount
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.vauthenticator.server.keys.adapter

import com.vauthenticator.server.extentions.encoder
import com.vauthenticator.server.extentions.valueAsStringFor
import com.vauthenticator.server.keys.adapter.dynamo.DynamoDbKeyStorage
import com.vauthenticator.server.keys.domain.KeyPurpose
import com.vauthenticator.server.keys.domain.KeyPurpose.MFA
import com.vauthenticator.server.keys.domain.KeyPurpose.SIGNATURE
Expand All @@ -11,9 +9,6 @@ import com.vauthenticator.server.keys.domain.KeyType.ASYMMETRIC
import com.vauthenticator.server.keys.domain.KeyType.SYMMETRIC
import com.vauthenticator.server.keys.domain.Keys
import com.vauthenticator.server.keys.domain.Kid
import com.vauthenticator.server.support.DynamoDbUtils.dynamoDbClient
import com.vauthenticator.server.support.DynamoDbUtils.dynamoMfaKeysTableName
import com.vauthenticator.server.support.DynamoDbUtils.dynamoSignatureKeysTableName
import com.vauthenticator.server.support.KeysUtils.aKeyFor
import com.vauthenticator.server.support.KeysUtils.aKid
import com.vauthenticator.server.support.KeysUtils.aMasterKey
Expand All @@ -23,14 +18,14 @@ import com.vauthenticator.server.support.KeysUtils.anotherKid
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import software.amazon.awssdk.services.dynamodb.model.AttributeValue
import java.time.Clock
import java.time.Duration
import java.time.Instant
import java.time.ZoneId
import kotlin.test.assertNotNull

abstract class AbstractKeyStorageTest {
abstract class
AbstractKeyStorageTest {

private val masterKid = aMasterKey
private val now = Instant.now()
Expand All @@ -39,7 +34,7 @@ abstract class AbstractKeyStorageTest {

abstract fun initKeyStorage(): KeyStorage
abstract fun resetDatabase()
abstract fun getActual(kid: Kid, keyPurpose: KeyPurpose): MutableMap<String, AttributeValue>
abstract fun getActual(kid: Kid, keyPurpose: KeyPurpose): Map<String, Any>

fun clock(): Clock = Clock.fixed(now, ZoneId.systemDefault())

Expand All @@ -54,15 +49,15 @@ abstract class AbstractKeyStorageTest {
uut.store(masterKid, aKid, aSignatureDataKey, ASYMMETRIC, SIGNATURE)

val actual = getActual(aKid, SIGNATURE)
assertEquals(aKid.content(), actual.valueAsStringFor("key_id"))
assertEquals(masterKid.content(), actual.valueAsStringFor("master_key_id"))
assertEquals(aKid.content(), actual["key_id"])
assertEquals(masterKid.content(), actual["master_key_id"])
assertEquals(
encoder.encode(aSignatureDataKey.encryptedPrivateKey)
.decodeToString(), actual.valueAsStringFor("encrypted_private_key")
.decodeToString(), actual["encrypted_private_key"]
)
assertEquals(
encoder.encode(aSignatureDataKey.publicKey.get()).decodeToString(),
actual.valueAsStringFor("public_key")
actual["public_key"]
)
}

Expand All @@ -71,11 +66,11 @@ abstract class AbstractKeyStorageTest {
uut.store(masterKid, aKid, aSimmetricDataKey, SYMMETRIC, MFA)

val actual = getActual(aKid, MFA)
assertEquals(aKid.content(), actual.valueAsStringFor("key_id"))
assertEquals(masterKid.content(), actual.valueAsStringFor("master_key_id"))
assertEquals(aKid.content(), actual["key_id"])
assertEquals(masterKid.content(), actual["master_key_id"])
assertEquals(
encoder.encode(aSimmetricDataKey.encryptedPrivateKey)
.decodeToString(), actual.valueAsStringFor("encrypted_private_key")
.decodeToString(), actual["encrypted_private_key"]
)
}

Expand Down Expand Up @@ -117,7 +112,7 @@ abstract class AbstractKeyStorageTest {

uut.justDeleteKey(aKid, SIGNATURE)
val actual = getActual(aKid, SIGNATURE)
assertEquals(emptyMap<String, AttributeValue>(), actual)
assertEquals(emptyMap<String, Any>(), actual)
}

@Test
Expand All @@ -131,8 +126,8 @@ abstract class AbstractKeyStorageTest {

val actual = getActual(aKid, SIGNATURE)
val expectedTTl = now.epochSecond + 1
assertEquals(false, (actual["enabled"] as AttributeValue).bool())
assertEquals(expectedTTl, (actual["key_expiration_date_timestamp"] as AttributeValue).n().toLong())
assertEquals(false, (actual["enabled"] as Boolean))
assertEquals(expectedTTl, (actual["key_expiration_date_timestamp"] as Long))
}

@Test
Expand All @@ -145,15 +140,15 @@ abstract class AbstractKeyStorageTest {

val actual = getActual(aKid, SIGNATURE)
val expectedTTl = now.epochSecond + 1
assertEquals(false, (actual["enabled"] as AttributeValue).bool())
assertEquals(expectedTTl, (actual["key_expiration_date_timestamp"] as AttributeValue).n().toLong())
assertEquals(false, (actual["enabled"] as Boolean))
assertEquals(expectedTTl, (actual["key_expiration_date_timestamp"] as Long))

uut.keyDeleteJodPlannedFor(aKid, Duration.ofSeconds(10), SIGNATURE)

val actualAfterReplanning = getActual(aKid, SIGNATURE)
val expectedTTlAfterReplanning = now.epochSecond + 1
assertEquals(false, (actualAfterReplanning["enabled"] as AttributeValue).bool())
assertEquals(expectedTTlAfterReplanning, (actualAfterReplanning["key_expiration_date_timestamp"] as AttributeValue).n().toLong())
assertEquals(false, (actualAfterReplanning["enabled"] as Boolean))
assertEquals(expectedTTlAfterReplanning, (actualAfterReplanning["key_expiration_date_timestamp"] as Long))
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.vauthenticator.server.keys.adapter.dynamodb

import com.vauthenticator.server.extentions.asDynamoAttribute
import com.vauthenticator.server.extentions.valueAsBoolFor
import com.vauthenticator.server.extentions.valueAsLongFor
import com.vauthenticator.server.extentions.valueAsStringFor
import com.vauthenticator.server.keys.adapter.AbstractKeyStorageTest
import com.vauthenticator.server.keys.adapter.dynamo.DynamoDbKeyStorage
import com.vauthenticator.server.keys.domain.KeyPurpose
Expand All @@ -15,6 +18,7 @@ import software.amazon.awssdk.services.dynamodb.model.GetItemRequest
import java.time.Clock
import java.time.Instant
import java.time.ZoneId
import kotlin.reflect.jvm.internal.impl.load.kotlin.JvmType

class DynamoDbKeyStorageTest : AbstractKeyStorageTest() {

Expand All @@ -29,8 +33,8 @@ class DynamoDbKeyStorageTest : AbstractKeyStorageTest() {
resetDynamoDb()
}

override fun getActual(kid: Kid, keyPurpose: KeyPurpose): MutableMap<String, AttributeValue> =
dynamoDbClient.getItem(
override fun getActual(kid: Kid, keyPurpose: KeyPurpose): Map<String, Any> {
val items = dynamoDbClient.getItem(
GetItemRequest.builder().tableName(tableNameFor(keyPurpose))
.key(
mapOf(
Expand All @@ -40,8 +44,22 @@ class DynamoDbKeyStorageTest : AbstractKeyStorageTest() {
.build()
).item()

return if(items.isNotEmpty()) {
mapOf(
"key_id" to items.valueAsStringFor("key_id"),
"master_key_id" to items.valueAsStringFor("master_key_id"),
"encrypted_private_key" to items.valueAsStringFor("encrypted_private_key"),
"public_key" to items.valueAsStringFor("public_key"),
"key_expiration_date_timestamp" to items.valueAsLongFor("key_expiration_date_timestamp"),
"enabled" to items.valueAsBoolFor("enabled"),
)
}else {
emptyMap()
}
}


private fun tableNameFor(keyPurpose: KeyPurpose) = when (keyPurpose) {
private fun tableNameFor(keyPurpose: KeyPurpose) = when (keyPurpose) {
KeyPurpose.MFA -> dynamoMfaKeysTableName
KeyPurpose.SIGNATURE -> dynamoSignatureKeysTableName
}
Expand Down
Loading

0 comments on commit b03824b

Please sign in to comment.