diff --git a/misk/src/test/kotlin/misk/web/actions/AuthenticationTest.kt b/misk/src/test/kotlin/misk/web/actions/AuthenticationTest.kt index aedacac1a78..7ce9fc32b76 100644 --- a/misk/src/test/kotlin/misk/web/actions/AuthenticationTest.kt +++ b/misk/src/test/kotlin/misk/web/actions/AuthenticationTest.kt @@ -22,6 +22,7 @@ import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.ValueSource import jakarta.inject.Inject import misk.security.authz.AccessInterceptor +import misk.web.toResponseBody import wisp.logging.LogCollector import kotlin.test.assertFailsWith @@ -273,6 +274,34 @@ class AuthenticationTest { ) } + @Test + fun `stacking @Authenticated with other access annotations is an error`() { + val unauthService = MiskCaller(service = "test") + assertThat( + executeRequest( + path = "/auth-and-custom-capability", + service = unauthService.service + ) + ).isEqualTo("unauthorized") + + val authService = MiskCaller(service = "dingo") + assertThat( + executeRequest( + path = "/auth-and-custom-capability", + service = authService.service + ) + ).isEqualTo("$authService authorized with custom capability") + + val caller = MiskCaller(user = "bob", capabilities = setOf("admin")) + assertThat( + executeRequest( + path = "/auth-and-custom-capability", + user = caller.user, + capabilities = caller.capabilities.first() + ) + ).isEqualTo("$caller authorized with custom capability") + } + /** Executes a request and returns the response body as a string. */ private fun executeRequest( path: String = "/", diff --git a/misk/src/test/kotlin/misk/web/actions/TestWebActionModule.kt b/misk/src/test/kotlin/misk/web/actions/TestWebActionModule.kt index 9a937eef68c..9e0c13d101e 100644 --- a/misk/src/test/kotlin/misk/web/actions/TestWebActionModule.kt +++ b/misk/src/test/kotlin/misk/web/actions/TestWebActionModule.kt @@ -45,10 +45,10 @@ class TestWebActionModule : KAbstractModule() { install(WebActionModule.create()) install(WebActionModule.create()) install(WebActionModule.create()) - install(WebActionModule.create()) install(WebActionModule.create()) install(WebActionModule.create()) install(WebActionModule.create()) + install(WebActionModule.create()) multibind().toInstance( AccessAnnotationEntry(services = listOf("payments")) @@ -167,6 +167,16 @@ class EmptyAuthenticatedWithCustomAnnototationAccessAction @Inject constructor() fun get() = "${scopedCaller.get()} authorized with CustomCapabilityAccess".toResponseBody() } +class AuthenticatedServiceWithCustomAnnotations @Inject constructor() : WebAction { + @Inject + lateinit var scopedCaller: ActionScoped + + @Get("/auth-and-custom-capability") + @Authenticated(services = ["dingo"]) + @CustomCapabilityAccess + fun get() = "${scopedCaller.get()} authorized with custom capability".toResponseBody() +} + class AllowAnyServiceAccessAction @Inject constructor() : WebAction { @Inject lateinit var scopedCaller: ActionScoped