Skip to content

Commit 866b48f

Browse files
committed
feat(authorization): Add authorized routes with paths
Add overloaded versions for the authorized routing functions that support a path. This variant is used by some endpoints. Signed-off-by: Oliver Heger <[email protected]>
1 parent 61d3543 commit 866b48f

File tree

2 files changed

+169
-1
lines changed

2 files changed

+169
-1
lines changed

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

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
* License-Filename: LICENSE
1818
*/
1919

20+
@file:Suppress("TooManyFunctions")
21+
2022
package org.eclipse.apoapsis.ortserver.components.authorization.routes
2123

2224
import com.auth0.jwt.interfaces.Payload
@@ -77,14 +79,37 @@ fun Route.get(
7779
): Route = documentedAuthorized(checker, body) { get(builder, it) }
7880

7981
/**
80-
* Create a new [Route] for HTTP POST requests that performs an automatic authorization check using the given [checker].
82+
* Create a new [Route] for HTTP GET requests with the given [path] that performs an automatic authorization check
83+
* using the given [checker].
84+
*/
85+
fun Route.get(
86+
path: String,
87+
builder: RouteConfig.() -> Unit,
88+
checker: AuthorizationChecker,
89+
body: suspend RoutingContext.() -> Unit
90+
): Route = documentedAuthorized(checker, body) { get(path, builder, it) }
91+
92+
/**
93+
* Create a new [Route] for HTTP POST requests that performs an automatic authorization check using the given
94+
* [checker].
8195
*/
8296
fun Route.post(
8397
builder: RouteConfig.() -> Unit,
8498
checker: AuthorizationChecker,
8599
body: suspend RoutingContext.() -> Unit
86100
): Route = documentedAuthorized(checker, body) { post(builder, it) }
87101

102+
/**
103+
* Create a new [Route] for HTTP POST requests with the given [path] that performs an automatic authorization check
104+
* using the given [checker].
105+
*/
106+
fun Route.post(
107+
path: String,
108+
builder: RouteConfig.() -> Unit,
109+
checker: AuthorizationChecker,
110+
body: suspend RoutingContext.() -> Unit
111+
): Route = documentedAuthorized(checker, body) { post(path, builder, it) }
112+
88113
/**
89114
* Create a new [Route] for HTTP PATCH requests that performs an automatic authorization check using the given
90115
* [checker].
@@ -95,6 +120,17 @@ fun Route.patch(
95120
body: suspend RoutingContext.() -> Unit
96121
): Route = documentedAuthorized(checker, body) { patch(builder, it) }
97122

123+
/**
124+
* Create a new [Route] for HTTP PATCH requests with the given [path] that performs an automatic authorization check
125+
* using the given [checker].
126+
*/
127+
fun Route.patch(
128+
path: String,
129+
builder: RouteConfig.() -> Unit,
130+
checker: AuthorizationChecker,
131+
body: suspend RoutingContext.() -> Unit
132+
): Route = documentedAuthorized(checker, body) { patch(path, builder, it) }
133+
98134
/**
99135
* Create a new [Route] for HTTP PUT requests that performs an automatic authorization check using the given
100136
* [checker].
@@ -105,6 +141,17 @@ fun Route.put(
105141
body: suspend RoutingContext.() -> Unit
106142
): Route = documentedAuthorized(checker, body) { put(builder, it) }
107143

144+
/**
145+
* Create a new [Route] for HTTP PUT requests with the given [path] that performs an automatic authorization check
146+
* using the given [checker].
147+
*/
148+
fun Route.put(
149+
path: String,
150+
builder: RouteConfig.() -> Unit,
151+
checker: AuthorizationChecker,
152+
body: suspend RoutingContext.() -> Unit
153+
): Route = documentedAuthorized(checker, body) { put(path, builder, it) }
154+
108155
/**
109156
* Create a new [Route] for HTTP DELETE requests that performs an automatic authorization check using the given
110157
* [checker].
@@ -115,6 +162,17 @@ fun Route.delete(
115162
body: suspend RoutingContext.() -> Unit
116163
): Route = documentedAuthorized(checker, body) { delete(builder, it) }
117164

165+
/**
166+
* Create a new [Route] for HTTP DELETE requests with the given [path] that performs an automatic authorization check
167+
* using the given [checker].
168+
*/
169+
fun Route.delete(
170+
path: String,
171+
builder: RouteConfig.() -> Unit,
172+
checker: AuthorizationChecker,
173+
body: suspend RoutingContext.() -> Unit
174+
): Route = documentedAuthorized(checker, body) { delete(path, builder, it) }
175+
118176
/**
119177
* Generic function to create a new [Route] that performs an automatic authorization check using the given [checker].
120178
* The content of the route is defined by the given original [body] and the [build] function.

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

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,116 @@ class AuthorizedRoutesTest : WordSpec() {
385385
}
386386
}
387387
}
388+
389+
"support GET with a path" {
390+
runAuthorizationTest(
391+
OrganizationPermission.WRITE_SECRETS,
392+
routeBuilder = {
393+
get(
394+
"test/{organizationId}",
395+
testDocs,
396+
requirePermission(OrganizationPermission.WRITE_SECRETS)
397+
) {
398+
call.principal<OrtServerPrincipal>().shouldNotBeNull {
399+
username shouldBe USERNAME
400+
}
401+
402+
call.respond(HttpStatusCode.OK)
403+
}
404+
}
405+
) { client ->
406+
val response = client.get("test/$ID_PARAMETER")
407+
response.status shouldBe HttpStatusCode.OK
408+
}
409+
}
410+
411+
"support POST with a path" {
412+
runAuthorizationTest(
413+
OrganizationPermission.MANAGE_GROUPS,
414+
routeBuilder = {
415+
post(
416+
"test/{organizationId}",
417+
testDocs,
418+
requirePermission(OrganizationPermission.MANAGE_GROUPS)
419+
) {
420+
call.principal<OrtServerPrincipal>().shouldNotBeNull {
421+
username shouldBe USERNAME
422+
}
423+
424+
call.respond(HttpStatusCode.OK)
425+
}
426+
}
427+
) { client ->
428+
val response = client.post("test/$ID_PARAMETER")
429+
response.status shouldBe HttpStatusCode.OK
430+
}
431+
}
432+
433+
"support PATCH with a path" {
434+
runAuthorizationTest(
435+
OrganizationPermission.CREATE_PRODUCT,
436+
routeBuilder = {
437+
patch(
438+
"test/{organizationId}",
439+
testDocs,
440+
requirePermission(OrganizationPermission.CREATE_PRODUCT)
441+
) {
442+
call.principal<OrtServerPrincipal>().shouldNotBeNull {
443+
username shouldBe USERNAME
444+
}
445+
446+
call.respond(HttpStatusCode.OK)
447+
}
448+
}
449+
) { client ->
450+
val response = client.patch("test/$ID_PARAMETER")
451+
response.status shouldBe HttpStatusCode.OK
452+
}
453+
}
454+
455+
"support PUT with a path" {
456+
runAuthorizationTest(
457+
OrganizationPermission.READ_PRODUCTS,
458+
routeBuilder = {
459+
put(
460+
"test/{organizationId}",
461+
testDocs,
462+
requirePermission(OrganizationPermission.READ_PRODUCTS)
463+
) {
464+
call.principal<OrtServerPrincipal>().shouldNotBeNull {
465+
username shouldBe USERNAME
466+
}
467+
468+
call.respond(HttpStatusCode.OK)
469+
}
470+
}
471+
) { client ->
472+
val response = client.put("test/$ID_PARAMETER")
473+
response.status shouldBe HttpStatusCode.OK
474+
}
475+
}
476+
477+
"support DELETE with a path" {
478+
runAuthorizationTest(
479+
OrganizationPermission.WRITE,
480+
routeBuilder = {
481+
delete(
482+
"test/{organizationId}",
483+
testDocs,
484+
requirePermission(OrganizationPermission.WRITE)
485+
) {
486+
call.principal<OrtServerPrincipal>().shouldNotBeNull {
487+
username shouldBe USERNAME
488+
}
489+
490+
call.respond(HttpStatusCode.OK)
491+
}
492+
}
493+
) { client ->
494+
val response = client.delete("test/$ID_PARAMETER")
495+
response.status shouldBe HttpStatusCode.OK
496+
}
497+
}
388498
}
389499

390500
"failed authorization checks" should {

0 commit comments

Comments
 (0)