Skip to content

Commit 61d3543

Browse files
committed
feat(authorization): Support checking for a principal
Add an extension function to `OrtServerPrincipal` that allows checking whether an authenticated principal exists in the current routing context. This is needed for some routes that require an authenticated user, even if no specific permissions are checked. Signed-off-by: Oliver Heger <[email protected]>
1 parent 3f70822 commit 61d3543

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

components/authorization/backend/src/main/kotlin/routes/OrtServerPrincipal.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ package org.eclipse.apoapsis.ortserver.components.authorization.routes
2121

2222
import com.auth0.jwt.interfaces.Payload
2323

24+
import io.ktor.server.auth.principal
25+
import io.ktor.server.routing.RoutingContext
26+
2427
import org.eclipse.apoapsis.ortserver.components.authorization.rights.EffectiveRole
2528

2629
/**
@@ -82,6 +85,13 @@ class OrtServerPrincipal(
8285
role = null,
8386
validationException = exception
8487
)
88+
89+
/**
90+
* Make sure that the current [RoutingContext] contains an authorized [OrtServerPrincipal] and return it.
91+
* Throw an [AuthorizationException] otherwise.
92+
*/
93+
fun RoutingContext.requirePrincipal(): OrtServerPrincipal =
94+
call.principal<OrtServerPrincipal>() ?: throw AuthorizationException()
8595
}
8696

8797
/**

components/authorization/backend/src/test/kotlin/routes/AuthorizedRoutesTest.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import org.eclipse.apoapsis.ortserver.components.authorization.rights.Organizati
6666
import org.eclipse.apoapsis.ortserver.components.authorization.rights.PermissionChecker
6767
import org.eclipse.apoapsis.ortserver.components.authorization.rights.ProductPermission
6868
import org.eclipse.apoapsis.ortserver.components.authorization.rights.RepositoryPermission
69+
import org.eclipse.apoapsis.ortserver.components.authorization.routes.OrtServerPrincipal.Companion.requirePrincipal
6970
import org.eclipse.apoapsis.ortserver.components.authorization.service.AuthorizationService
7071
import org.eclipse.apoapsis.ortserver.components.authorization.service.InvalidHierarchyIdException
7172
import org.eclipse.apoapsis.ortserver.model.CompoundHierarchyId
@@ -194,6 +195,26 @@ class AuthorizedRoutesTest : WordSpec() {
194195
}
195196
}
196197

198+
"support checks for an authenticated principal" {
199+
runAuthorizationTest(
200+
mockk(),
201+
routeBuilder = {
202+
route("test") {
203+
get(testDocs) {
204+
val principal = requirePrincipal()
205+
principal.username shouldBe USERNAME
206+
principal.effectiveRole.elementId shouldBe CompoundHierarchyId.WILDCARD
207+
208+
call.respond(HttpStatusCode.OK)
209+
}
210+
}
211+
}
212+
) { client ->
213+
val response = client.get("test")
214+
response.status shouldBe HttpStatusCode.OK
215+
}
216+
}
217+
197218
"support GET with an organization permission" {
198219
runAuthorizationTest(
199220
OrganizationPermission.WRITE_SECRETS,

components/authorization/backend/src/test/kotlin/routes/OrtServerPrincipalTest.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,14 @@ import io.kotest.assertions.throwables.shouldThrow
2525
import io.kotest.core.spec.style.WordSpec
2626
import io.kotest.matchers.shouldBe
2727

28+
import io.ktor.server.auth.principal
29+
import io.ktor.server.routing.RoutingContext
30+
2831
import io.mockk.every
2932
import io.mockk.mockk
3033

3134
import org.eclipse.apoapsis.ortserver.components.authorization.rights.EffectiveRole
35+
import org.eclipse.apoapsis.ortserver.components.authorization.routes.OrtServerPrincipal.Companion.requirePrincipal
3236

3337
class OrtServerPrincipalTest : WordSpec({
3438
"create()" should {
@@ -119,4 +123,16 @@ class OrtServerPrincipalTest : WordSpec({
119123
}
120124
}
121125
}
126+
127+
"requirePrincipal()" should {
128+
"throw an exception if no principal is present in the routing context" {
129+
val context = mockk<RoutingContext> {
130+
every { call.principal<OrtServerPrincipal>() } returns null
131+
}
132+
133+
shouldThrow<AuthorizationException> {
134+
context.requirePrincipal()
135+
}
136+
}
137+
}
122138
})

0 commit comments

Comments
 (0)