Skip to content

Commit

Permalink
add ticket context in order to store mfa information like mfa channel…
Browse files Browse the repository at this point in the history
… and mfa method
  • Loading branch information
mrFlick72 committed Jul 22, 2024
1 parent a1964fb commit f54efd1
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ import java.util.*


fun HttpServletRequest.oauth2ClientId(): Optional<ClientAppId> {
return Optional.ofNullable((this.getParameter("client_id") as String?)).map { ClientAppId(it) }
return Optional.ofNullable(this.getParameter("client_id")).map { ClientAppId(it) }

}
17 changes: 17 additions & 0 deletions src/main/kotlin/com/vauthenticator/server/extentions/MapExt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.vauthenticator.server.extentions

import software.amazon.awssdk.services.dynamodb.model.AttributeValue
import java.util.*

fun Map<String, String>.asDynamoAttribute(): AttributeValue =
this.map { mutableMapOf(it.key to AttributeValue.builder().s(it.value).build()) }
.reduce { a, b -> a.plus(b) as MutableMap<String, AttributeValue> }
.let { AttributeValue.fromM(it) }

fun Map<String, AttributeValue>.valueAsMapFor(key: String): Map<String, String> =
Optional.ofNullable(this[key])
.map { it.m() }
.map { it.entries }
.map { it.map { mutableMapOf(it.key to it.value.s()) } }
.map { it.reduce { acc, mutableMap -> (acc + mutableMap) as MutableMap<String, String> } }
.orElseGet { mutableMapOf<String, String>() }
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import java.util.*
fun MutableMap<String, AttributeValue>.valueAsStringFor(key: String): String =
this[key]?.s()!!

fun MutableMap<String, AttributeValue>.valueAsStringFor(key: String, default : String): String =
fun MutableMap<String, AttributeValue>.valueAsStringFor(key: String, default: String): String =
Optional.ofNullable(this[key]).map { this[key]?.s()!! }.orElse(default)

fun MutableMap<String, AttributeValue>.valuesAsListOfStringFor(key: String): List<String> =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,23 @@ class MfaMethodsEnrollment(

fun enroll(
account: Account,
emailMfaMethod: MfaMethod,
mfaMethod: MfaMethod,
mfaChannel: String,
clientAppId: ClientAppId,
sendChallengeCode: Boolean = true
): TicketId {
if (sendChallengeCode) {
mfaSender.sendMfaChallenge(account.email, mfaChannel)
}
return ticketCreator.createTicketFor(account, clientAppId)
return ticketCreator.createTicketFor(
account,
clientAppId,
TicketContext(
mapOf(
"mfaChannel" to mfaChannel,
"mfaMethod" to mfaMethod.name
)
)
)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.vauthenticator.server.ticket

import com.vauthenticator.server.extentions.asDynamoAttribute
import com.vauthenticator.server.extentions.filterEmptyMetadata
import com.vauthenticator.server.extentions.valueAsLongFor
import com.vauthenticator.server.extentions.valueAsStringFor
import com.vauthenticator.server.extentions.*
import software.amazon.awssdk.services.dynamodb.DynamoDbClient
import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest
Expand All @@ -23,8 +20,9 @@ class DynamoDbTicketRepository(
mapOf(
"ticket" to ticket.ticketId.content.asDynamoAttribute(),
"ttl" to (ticket.ttl).asDynamoAttribute(),
"email" to ticket.userName.asDynamoAttribute(),
"client_application_id" to ticket.clientAppId.asDynamoAttribute()
"user_name" to ticket.userName.asDynamoAttribute(),
"client_application_id" to ticket.clientAppId.asDynamoAttribute(),
"context" to ticket.context.content.asDynamoAttribute()
)
)
.build()
Expand All @@ -45,9 +43,10 @@ class DynamoDbTicketRepository(
.map {
Ticket(
TicketId(it.valueAsStringFor("ticket")),
it.valueAsStringFor("email"),
it.valueAsStringFor("user_name"),
it.valueAsStringFor("client_application_id"),
it.valueAsLongFor("ttl")
it.valueAsLongFor("ttl"),
TicketContext(it.valueAsMapFor("context"))
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.vauthenticator.server.clientapp.A_CLIENT_APP_ID
import com.vauthenticator.server.oauth2.clientapp.ClientAppId
import com.vauthenticator.server.support.AccountTestFixture.anAccount
import com.vauthenticator.server.support.EMAIL
import com.vauthenticator.server.support.TicketFixture.ticketContext
import com.vauthenticator.server.support.TicketFixture.ticketFor
import com.vauthenticator.server.ticket.TicketCreator
import com.vauthenticator.server.ticket.TicketFeatures
Expand Down Expand Up @@ -55,7 +56,7 @@ internal class TicketIdFactoryTest {
every { ticketRepository.store(ticket) } just runs

val expected = TicketId(ticketGenerator.invoke())
val actual = underTest.createTicketFor(account, ClientAppId(A_CLIENT_APP_ID))
val actual = underTest.createTicketFor(account, ClientAppId(A_CLIENT_APP_ID), ticketContext(account.email))

assertEquals(expected, actual)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.vauthenticator.server.mfa.domain

import com.vauthenticator.server.clientapp.ClientAppFixture.aClientAppId
import com.vauthenticator.server.support.AccountTestFixture.anAccount
import com.vauthenticator.server.support.TicketFixture.ticketContext
import com.vauthenticator.server.ticket.TicketCreator
import com.vauthenticator.server.ticket.TicketId
import io.mockk.every
Expand Down Expand Up @@ -39,10 +40,13 @@ class MfaMethodsEnrollmentTest {

val ticketId = TicketId("A_TICKET")

every { ticketCreator.createTicketFor(account, clientAppId) } returns ticketId
val actual = uut.enroll(account, MfaMethod.EMAIL_MFA_METHOD,account.email, clientAppId, false)

verify { ticketCreator.createTicketFor(account, clientAppId) }
every { ticketCreator.createTicketFor(account, clientAppId, ticketContext(account.email)) } returns ticketId
val actual = uut.enroll(account, MfaMethod.EMAIL_MFA_METHOD, account.email, clientAppId, false)
verify {
ticketCreator.createTicketFor(
account, clientAppId, ticketContext(account.email)
)
}

assertEquals(ticketId, actual)
}
Expand All @@ -62,13 +66,13 @@ class MfaMethodsEnrollmentTest {

val ticketId = TicketId("A_TICKET")

every { ticketCreator.createTicketFor(account, clientAppId) } returns ticketId
every { mfaSender.sendMfaChallenge(account.email,account.email) } just runs
every { ticketCreator.createTicketFor(account, clientAppId, ticketContext(account.email)) } returns ticketId
every { mfaSender.sendMfaChallenge(account.email, account.email) } just runs

val actual = uut.enroll(account, MfaMethod.EMAIL_MFA_METHOD,account.email, clientAppId, true)
val actual = uut.enroll(account, MfaMethod.EMAIL_MFA_METHOD, account.email, clientAppId, true)

verify { ticketCreator.createTicketFor(account, clientAppId) }
verify { mfaSender.sendMfaChallenge(account.email,account.email) }
verify { ticketCreator.createTicketFor(account, clientAppId, ticketContext(account.email)) }
verify { mfaSender.sendMfaChallenge(account.email, account.email) }

assertEquals(ticketId, actual)
}
Expand Down
19 changes: 17 additions & 2 deletions src/test/kotlin/com/vauthenticator/server/support/TicketFixture.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
package com.vauthenticator.server.support

import com.vauthenticator.server.mfa.domain.MfaMethod
import com.vauthenticator.server.ticket.Ticket
import com.vauthenticator.server.ticket.TicketContext
import com.vauthenticator.server.ticket.TicketId

object TicketFixture {
fun ticketFor(verificationTicketValue: String, mail: String, clientAppId: String) =
Ticket(TicketId(verificationTicketValue), mail, clientAppId, 200)

fun ticketContext(email: String) = TicketContext(
mapOf(
"mfaChannel" to email,
"mfaMethod" to MfaMethod.EMAIL_MFA_METHOD.name
)
)

fun ticketFor(verificationTicketValue: String, email: String, clientAppId: String): Ticket {

return Ticket(
TicketId(verificationTicketValue), email, clientAppId, 200,
ticketContext(email)
)
}
}

0 comments on commit f54efd1

Please sign in to comment.