Skip to content

Commit

Permalink
test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
mrFlick72 committed Jul 28, 2024
1 parent e86fb22 commit 20464a7
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.vauthenticator.server.mfa.api

import com.vauthenticator.server.account.repository.AccountRepository
import com.vauthenticator.server.extentions.clientAppId
import com.vauthenticator.server.mask.SensitiveEmailMasker
import com.vauthenticator.server.mfa.domain.EmailMfaDevice
Expand All @@ -12,8 +11,10 @@ import com.vauthenticator.server.oauth2.clientapp.Scope
import com.vauthenticator.server.oauth2.clientapp.Scopes
import com.vauthenticator.server.role.PermissionValidator
import jakarta.servlet.http.HttpSession
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.http.ResponseEntity.ok
import org.springframework.http.ResponseEntity.status
import org.springframework.security.core.Authentication
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken
import org.springframework.web.bind.annotation.GetMapping
Expand All @@ -26,7 +27,6 @@ class MfaEnrolmentAssociationEndPoint(
private val sensitiveEmailMasker: SensitiveEmailMasker,
private val mfaAccountMethodsRepository: MfaAccountMethodsRepository,
private val mfaMethodsEnrollment: MfaMethodsEnrollment,
private val accountRepository: AccountRepository,
private val mfaMethodsEnrolmentAssociation: MfaMethodsEnrollmentAssociation,
private val permissionValidator: PermissionValidator
) {
Expand Down Expand Up @@ -56,7 +56,7 @@ class MfaEnrolmentAssociationEndPoint(
authentication: JwtAuthenticationToken,
httpSession: HttpSession,
@RequestBody enrolling: MfaEnrollmentRequest
): ResponseEntity<String> {
): ResponseEntity<MfaEnrollmentResponse> {
permissionValidator.validate(authentication, httpSession, Scopes.from(Scope.MFA_ENROLLMENT))
val ticketId = mfaMethodsEnrollment.enroll(
authentication.name,
Expand All @@ -65,17 +65,18 @@ class MfaEnrolmentAssociationEndPoint(
authentication.clientAppId(),
true
)
return ok(ticketId.content)
return status(HttpStatus.CREATED).body(MfaEnrollmentResponse(ticketId.content))
}

@PostMapping("/api/mfa/associate")
fun associateMfaEnrollment(
httpSession: HttpSession,
authentication: JwtAuthenticationToken,
@RequestBody associationRequest: MfaEnrollmentAssociationRequest,
) {
): ResponseEntity<Unit> {
permissionValidator.validate(authentication, httpSession, Scopes.from(Scope.MFA_ENROLLMENT))
mfaMethodsEnrolmentAssociation.associate(associationRequest.ticket, associationRequest.code)
return ResponseEntity.noContent().build()
}

}
Expand All @@ -85,6 +86,9 @@ data class MfaEnrollmentRequest(
val mfaMethod: MfaMethod,
)

data class MfaEnrollmentResponse(
val ticket: String
)

data class MfaEnrollmentAssociationRequest(
val ticket: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,33 @@ package com.vauthenticator.server.mfa.api

import com.fasterxml.jackson.databind.ObjectMapper
import com.vauthenticator.server.account.repository.AccountRepository
import com.vauthenticator.server.clientapp.A_CLIENT_APP_ID
import com.vauthenticator.server.mask.SensitiveEmailMasker
import com.vauthenticator.server.mfa.domain.EmailMfaDevice
import com.vauthenticator.server.mfa.domain.MfaMethod.EMAIL_MFA_METHOD
import com.vauthenticator.server.mfa.domain.MfaMethodsEnrollment
import com.vauthenticator.server.mfa.domain.MfaMethodsEnrollmentAssociation
import com.vauthenticator.server.mfa.repository.MfaAccountMethodsRepository
import com.vauthenticator.server.oauth2.clientapp.ClientAppId
import com.vauthenticator.server.oauth2.clientapp.Scope
import com.vauthenticator.server.oauth2.clientapp.Scopes
import com.vauthenticator.server.role.PermissionValidator
import com.vauthenticator.server.support.AccountTestFixture
import com.vauthenticator.server.support.MfaFixture.accountMfaAssociatedMfaMethods
import com.vauthenticator.server.support.SecurityFixture.principalFor
import com.vauthenticator.server.ticket.TicketId
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import io.mockk.just
import io.mockk.runs
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.http.MediaType
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.content
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import org.springframework.test.web.servlet.setup.MockMvcBuilders
Expand Down Expand Up @@ -56,7 +65,6 @@ class MfaEnrolmentAssociationEndPointTest {
sensitiveEmailMasker,
mfaAccountMethodsRepository,
mfaMethodsEnrollment,
accountRepository,
mfaMethodsEnrolmentAssociation,
permissionValidator
)
Expand Down Expand Up @@ -87,4 +95,67 @@ class MfaEnrolmentAssociationEndPointTest {
)
)
}

@Test
fun `when a new mfa channel is enrolled`() {
val account = AccountTestFixture.anAccount()
val email = account.email

val authentication = principalFor(
clientAppId = A_CLIENT_APP_ID,
email = email,
authorities = listOf("USER"),
scopes = listOf(Scope.MFA_ENROLLMENT.content)
)
every { permissionValidator.validate(authentication, any(), Scopes.from(Scope.MFA_ENROLLMENT)) } just runs
every {
mfaMethodsEnrollment.enroll(
account.email,
EMAIL_MFA_METHOD,
account.email,
ClientAppId(A_CLIENT_APP_ID),
true
)
} returns TicketId("A_TICKET")

mokMvc.perform(
post("/api/mfa/enrollment")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(MfaEnrollmentRequest(account.email, EMAIL_MFA_METHOD)))
.principal(authentication)
)
.andExpect(status().isCreated)
.andExpect(
content().json(
objectMapper.writeValueAsString(
MfaEnrollmentResponse("A_TICKET")
)
)
)

}


@Test
fun `when a new enrolled mfa is associated`() {
val account = AccountTestFixture.anAccount()
val email = account.email

val authentication = principalFor(
clientAppId = A_CLIENT_APP_ID,
email = email,
authorities = listOf("USER"),
scopes = listOf(Scope.MFA_ENROLLMENT.content)
)
every { permissionValidator.validate(authentication, any(), Scopes.from(Scope.MFA_ENROLLMENT)) } just runs
every { mfaMethodsEnrolmentAssociation.associate("A_TICKET", "A_CODE") } just runs

mokMvc.perform(
post("/api/mfa/associate")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(MfaEnrollmentAssociationRequest("A_TICKET", "A_CODE")))
.principal(authentication)
)
.andExpect(status().isNoContent)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class PermissionValidatorTest {

val principal = SecurityFixture.principalFor(
clientAppId = clientAppId.content,
mail = EMAIL,
email = EMAIL,
scopes = scopesValues
)
uut.validate(principal = principal, session = session, scopes = scopes)
Expand All @@ -80,7 +80,7 @@ class PermissionValidatorTest {

val principal = SecurityFixture.principalFor(
clientAppId = clientAppId.content,
mail = EMAIL,
email = EMAIL,
scopes = emptyList()
)
assertThrows(InsufficientClientApplicationScopeException::class.java) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ object SecurityFixture {

fun principalFor(
clientAppId: String,
mail: String,
email: String,
authorities: List<String> = emptyList(),
scopes: List<String> = emptyList()
) =
signedJWTFor(clientAppId, mail, scopes).let { signedJWT ->
signedJWTFor(clientAppId, email, scopes).let { signedJWT ->
JwtAuthenticationToken(
Jwt(
simpleJwtFor(clientAppId),
Expand All @@ -68,7 +68,7 @@ object SecurityFixture {
signedJWT.payload.toJSONObject()
),
authorities.map(::SimpleGrantedAuthority),
mail
email
)
}

Expand Down

0 comments on commit 20464a7

Please sign in to comment.