test: WithMockHttpSignatureを追加

This commit is contained in:
usbharu 2023-11-12 15:05:23 +09:00
parent 59298f77c2
commit 87d6b61b25
5 changed files with 88 additions and 15 deletions

View File

@ -18,7 +18,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders
import org.springframework.transaction.annotation.Transactional import org.springframework.transaction.annotation.Transactional
import org.springframework.web.context.WebApplicationContext import org.springframework.web.context.WebApplicationContext
import util.TestTransaction import util.TestTransaction
import util.WithHttpSignature import util.WithMockHttpSignature
@SpringBootTest(classes = [SpringApplication::class]) @SpringBootTest(classes = [SpringApplication::class])
@AutoConfigureMockMvc @AutoConfigureMockMvc
@ -49,7 +49,7 @@ class InboxTest {
} }
@Test @Test
@WithHttpSignature @WithMockHttpSignature
fun 有効なHttpSignatureでPOSTしたら202() { fun 有効なHttpSignatureでPOSTしたら202() {
mockMvc mockMvc
.post("/inbox") { .post("/inbox") {
@ -72,7 +72,7 @@ class InboxTest {
} }
@Test @Test
@WithHttpSignature @WithMockHttpSignature
fun 有効なHttpSignaturesでPOSTしたら202() { fun 有効なHttpSignaturesでPOSTしたら202() {
mockMvc mockMvc
.post("/users/hoge/inbox") { .post("/users/hoge/inbox") {

View File

@ -13,5 +13,8 @@ import java.lang.annotation.Inherited
annotation class WithHttpSignature( annotation class WithHttpSignature(
@get:AliasFor( @get:AliasFor(
annotation = WithSecurityContext::class annotation = WithSecurityContext::class
) val setupBefore: TestExecutionEvent = TestExecutionEvent.TEST_METHOD ) val setupBefore: TestExecutionEvent = TestExecutionEvent.TEST_METHOD,
val keyId: String = "https://example.com/users/test-user#pubkey",
val url: String = "https://example.com/inbox",
val method: String = "GET"
) )

View File

@ -1,34 +1,42 @@
package util package util
import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureUser import dev.usbharu.hideout.application.external.Transaction
import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureUserDetailsService
import dev.usbharu.hideout.core.query.UserQueryService
import dev.usbharu.httpsignature.common.HttpHeaders import dev.usbharu.httpsignature.common.HttpHeaders
import dev.usbharu.httpsignature.common.HttpMethod import dev.usbharu.httpsignature.common.HttpMethod
import dev.usbharu.httpsignature.common.HttpRequest import dev.usbharu.httpsignature.common.HttpRequest
import dev.usbharu.httpsignature.sign.RsaSha256HttpSignatureSigner
import dev.usbharu.httpsignature.verify.DefaultSignatureHeaderParser
import dev.usbharu.httpsignature.verify.RsaSha256HttpSignatureVerifier
import org.springframework.security.core.context.SecurityContext import org.springframework.security.core.context.SecurityContext
import org.springframework.security.core.context.SecurityContextHolder import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.test.context.support.WithSecurityContextFactory import org.springframework.security.test.context.support.WithSecurityContextFactory
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken
import java.net.URL import java.net.URL
class WithHttpSignatureSecurityContextFactory : WithSecurityContextFactory<WithHttpSignature> { class WithHttpSignatureSecurityContextFactory(
userQueryService: UserQueryService,
transaction: Transaction
) : WithSecurityContextFactory<WithHttpSignature> {
private val securityContextStrategy = SecurityContextHolder.getContextHolderStrategy() private val securityContextStrategy = SecurityContextHolder.getContextHolderStrategy()
override fun createSecurityContext(annotation: WithHttpSignature): SecurityContext { private val httpSignatureUserDetailsService: HttpSignatureUserDetailsService = HttpSignatureUserDetailsService(
val httpSignatureUser = HttpSignatureUser( userQueryService,
"user", RsaSha256HttpSignatureVerifier(DefaultSignatureHeaderParser(), RsaSha256HttpSignatureSigner()),
"example.com", transaction
12345,
true,
true,
mutableListOf()
) )
override fun createSecurityContext(annotation: WithHttpSignature): SecurityContext {
val preAuthenticatedAuthenticationToken = PreAuthenticatedAuthenticationToken( val preAuthenticatedAuthenticationToken = PreAuthenticatedAuthenticationToken(
"user", HttpRequest( annotation.keyId, HttpRequest(
URL("https://example.com/inbox"), URL("https://example.com/inbox"),
HttpHeaders(mapOf()), HttpMethod.GET HttpHeaders(mapOf()), HttpMethod.GET
) )
) )
val httpSignatureUser = httpSignatureUserDetailsService.loadUserDetails(preAuthenticatedAuthenticationToken)
preAuthenticatedAuthenticationToken.details = httpSignatureUser preAuthenticatedAuthenticationToken.details = httpSignatureUser
preAuthenticatedAuthenticationToken.isAuthenticated = true preAuthenticatedAuthenticationToken.isAuthenticated = true
val emptyContext = securityContextStrategy.createEmptyContext() val emptyContext = securityContextStrategy.createEmptyContext()

View File

@ -0,0 +1,23 @@
package util
import org.springframework.core.annotation.AliasFor
import org.springframework.security.test.context.support.TestExecutionEvent
import org.springframework.security.test.context.support.WithSecurityContext
import java.lang.annotation.Inherited
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
@Inherited
@MustBeDocumented
@WithSecurityContext(factory = WithMockHttpSignatureSecurityContextFactory::class)
annotation class WithMockHttpSignature(
@get:AliasFor(
annotation = WithSecurityContext::class
) val setupBefore: TestExecutionEvent = TestExecutionEvent.TEST_METHOD,
val username: String = "test-user",
val domain: String = "example.com",
val keyId: String = "https://example.com/users/test-user#pubkey",
val id: Long = 1234L,
val url: String = "https://example.com/inbox",
val method: String = "GET"
)

View File

@ -0,0 +1,39 @@
package util
import dev.usbharu.hideout.core.infrastructure.springframework.httpsignature.HttpSignatureUser
import dev.usbharu.httpsignature.common.HttpHeaders
import dev.usbharu.httpsignature.common.HttpMethod
import dev.usbharu.httpsignature.common.HttpRequest
import org.springframework.security.core.context.SecurityContext
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.test.context.support.WithSecurityContextFactory
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken
import java.net.URL
class WithMockHttpSignatureSecurityContextFactory :
WithSecurityContextFactory<WithMockHttpSignature> {
private val securityContextStrategy = SecurityContextHolder.getContextHolderStrategy()
override fun createSecurityContext(annotation: WithMockHttpSignature): SecurityContext {
val preAuthenticatedAuthenticationToken = PreAuthenticatedAuthenticationToken(
annotation.keyId, HttpRequest(
URL(annotation.url),
HttpHeaders(mapOf()), HttpMethod.valueOf(annotation.method.uppercase())
)
)
val httpSignatureUser = HttpSignatureUser(
annotation.username,
annotation.domain,
annotation.id,
true,
true,
mutableListOf()
)
preAuthenticatedAuthenticationToken.details = httpSignatureUser
preAuthenticatedAuthenticationToken.isAuthenticated = true
val emptyContext = securityContextStrategy.createEmptyContext()
emptyContext.authentication = preAuthenticatedAuthenticationToken
return emptyContext
}
}