Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package ch.epfl.bluebrain.nexus.delta.routes

import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.model.headers.OAuth2BearerToken
import akka.http.scaladsl.server.Route
import cats.effect.IO
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.JsonLdContext.keywords
Expand All @@ -19,7 +18,7 @@ import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.*
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{Identity, Label}
import ch.epfl.bluebrain.nexus.delta.sourcing.query.RefreshStrategy
import io.circe.Json
import io.circe.syntax.EncoderOps
import io.circe.syntax.KeyOps

import scala.concurrent.duration.*

Expand All @@ -44,9 +43,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
def selfAcls(address: AclAddress) = userAcl(address) ++ groupAcl(address)
def allAcls(address: AclAddress) = userAcl(address) ++ groupAcl(address) ++ group2Acl(address)

private val asUser = addCredentials(OAuth2BearerToken("uuid"))
implicit val caller: Caller = Caller(user, Set(user, group))
val subject: Subject = caller.subject

val myOrg = Organization(Label.unsafe("myorg"))
val myOrg2 = Organization(Label.unsafe("myorg2"))
Expand All @@ -57,8 +54,8 @@ class AclsRoutesSpec extends BaseRouteSpec {

def aclEntryJson(identity: Identity, permissions: Set[Permission]): Json =
Json.obj(
"identity" -> identity.asJson,
"permissions" -> Json.fromValues(permissions.toSeq.map(_.toString).sorted.map(Json.fromString))
"identity" := identity,
"permissions" := permissions.toSeq.map(_.toString).sorted
)

def aclAddressJson(address: AclAddress): Json =
Expand Down Expand Up @@ -107,7 +104,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
"fail to create acls without permissions" in {
forAll(paths) { case (path, address) =>
val json = aclJson(userAcl(address)).removeKeys("_path")
Put(s"/v1/acls$path", json.toEntity) ~> asUser ~> routes ~> check {
Put(s"/v1/acls$path", json.toEntity) ~> as(user) ~> routes ~> check {
response.shouldBeForbidden
}
}
Expand All @@ -118,7 +115,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
acls.replace(userAcl(AclAddress.Root), 0).accepted
val replace = aclJson(userAcl(AclAddress.Root)).removeKeys("_path")
forAll(paths.drop(1)) { case (path, address) =>
Put(s"/v1/acls$path", replace.toEntity) ~> asUser ~> routes ~> check {
Put(s"/v1/acls$path", replace.toEntity) ~> as(user) ~> routes ~> check {
response.asJson shouldEqual aclMetadata(address, createdBy = user, updatedBy = user)
status shouldEqual StatusCodes.Created
}
Expand All @@ -128,7 +125,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
"append ACL" in {
val patch = aclJson(groupAcl(Root)).removeKeys("_path") deepMerge Json.obj("@type" -> Json.fromString("Append"))
forAll(paths) { case (path, address) =>
Patch(s"/v1/acls$path?rev=1", patch.toEntity) ~> asUser ~> routes ~> check {
Patch(s"/v1/acls$path?rev=1", patch.toEntity) ~> as(user) ~> routes ~> check {
response.asJson shouldEqual aclMetadata(address, rev = 2, createdBy = user, updatedBy = user)
status shouldEqual StatusCodes.OK
}
Expand All @@ -139,7 +136,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
val patch = aclJson(group2Acl(Root)).removeKeys("_path") deepMerge
Json.obj("@type" -> Json.fromString("Append"))
forAll(paths) { case (path, address) =>
Patch(s"/v1/acls$path?rev=2", patch.toEntity) ~> asUser ~> routes ~> check {
Patch(s"/v1/acls$path?rev=2", patch.toEntity) ~> as(user) ~> routes ~> check {
response.asJson shouldEqual aclMetadata(address, rev = 3, createdBy = user, updatedBy = user)
status shouldEqual StatusCodes.OK
}
Expand All @@ -148,7 +145,7 @@ class AclsRoutesSpec extends BaseRouteSpec {

"get ACL self = true" in {
forAll(paths) { case (path, address) =>
Get(s"/v1/acls$path") ~> asUser ~> routes ~> check {
Get(s"/v1/acls$path") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual expectedResponse(1L, Seq((selfAcls(address), 3)))
status shouldEqual StatusCodes.OK
}
Expand All @@ -157,7 +154,7 @@ class AclsRoutesSpec extends BaseRouteSpec {

"get ACL self = false" in {
forAll(paths) { case (path, address) =>
Get(s"/v1/acls$path?self=false") ~> asUser ~> routes ~> check {
Get(s"/v1/acls$path?self=false") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual expectedResponse(1L, Seq((allAcls(address), 3)))
status shouldEqual StatusCodes.OK
}
Expand All @@ -166,7 +163,7 @@ class AclsRoutesSpec extends BaseRouteSpec {

"get ACL self = true and rev = 1" in {
forAll(paths) { case (path, address) =>
Get(s"/v1/acls$path?rev=1") ~> asUser ~> routes ~> check {
Get(s"/v1/acls$path?rev=1") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual expectedResponse(1L, Seq((userAcl(address), 1)))
status shouldEqual StatusCodes.OK
}
Expand All @@ -177,14 +174,14 @@ class AclsRoutesSpec extends BaseRouteSpec {
acls.append(userAcl(myOrg2), 0).accepted
acls.append(groupAcl(myOrg2), 1).accepted
acls.append(group2Acl(myOrg2), 2).accepted
Get(s"/v1/acls/*") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/*") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual expectedResponse(2L, Seq((selfAcls(myOrg), 3), (selfAcls(myOrg2), 3)))
status shouldEqual StatusCodes.OK
}
}

"get ACL self = false with org path containing *" in {
Get(s"/v1/acls/*?self=false") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/*?self=false") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual expectedResponse(2L, Seq((allAcls(myOrg), 3), (allAcls(myOrg2), 3)))
status shouldEqual StatusCodes.OK
}
Expand All @@ -195,15 +192,15 @@ class AclsRoutesSpec extends BaseRouteSpec {
acls.append(groupAcl(myOrgMyProj2), 1).accepted
acls.append(group2Acl(myOrgMyProj2), 2).accepted
acls.append(group2Acl(myOrg3), 0).accepted
Get(s"/v1/acls/myorg/*") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/myorg/*") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual
expectedResponse(2L, Seq((selfAcls(myOrgMyProj), 3), (selfAcls(myOrgMyProj2), 3)))
status shouldEqual StatusCodes.OK
}
}

"get ACL self = false with project path containing *" in {
Get(s"/v1/acls/myorg/*?self=false") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/myorg/*?self=false") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual
expectedResponse(2L, Seq((allAcls(myOrgMyProj), 3), (allAcls(myOrgMyProj2), 3)))
status shouldEqual StatusCodes.OK
Expand All @@ -214,7 +211,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
acls.append(userAcl(myOrg2MyProj2), 0).accepted
acls.append(groupAcl(myOrg2MyProj2), 1).accepted
acls.append(group2Acl(myOrg2MyProj2), 2).accepted
Get(s"/v1/acls/*/*") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/*/*") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual
expectedResponse(
3L,
Expand All @@ -225,7 +222,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
}

"get ACL self = false with org and project path containing *" in {
Get(s"/v1/acls/*/*?self=false") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/*/*?self=false") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual
expectedResponse(
3L,
Expand All @@ -236,7 +233,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
}

"get ACL self = true with project path containing * with ancestors" in {
Get(s"/v1/acls/myorg/*?ancestors=true") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/myorg/*?ancestors=true") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual
expectedResponse(
4L,
Expand All @@ -247,7 +244,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
}

"get ACL self = false with project path containing * with ancestors" in {
Get(s"/v1/acls/myorg/*?ancestors=true&self=false") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/myorg/*?ancestors=true&self=false") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual
expectedResponse(
4L,
Expand All @@ -258,7 +255,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
}

"get ACL self = true with org path containing * with ancestors" in {
Get(s"/v1/acls/*?ancestors=true") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/*?ancestors=true") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual expectedResponse(
3L,
Seq((selfAcls(Root), 3), (selfAcls(myOrg), 3), (selfAcls(myOrg2), 3))
Expand All @@ -268,7 +265,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
}

"get ACL self = false with org path containing * with ancestors" in {
Get(s"/v1/acls/*?ancestors=true&self=false") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/*?ancestors=true&self=false") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual expectedResponse(
4L,
Seq((allAcls(Root), 3), (allAcls(myOrg), 3), (allAcls(myOrg2), 3), (group2Acl(myOrg3), 1))
Expand All @@ -278,7 +275,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
}

"get ACL self = true with org and project path containing * with ancestors" in {
Get(s"/v1/acls/*/*?ancestors=true") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/*/*?ancestors=true") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual expectedResponse(
6L,
Seq(
Expand All @@ -295,7 +292,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
}

"get ACL self = false with org and project path containing * with ancestors" in {
Get(s"/v1/acls/*/*?ancestors=true&self=false") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/*/*?ancestors=true&self=false") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual expectedResponse(
7L,
Seq(
Expand All @@ -313,14 +310,14 @@ class AclsRoutesSpec extends BaseRouteSpec {
}

"get ACL self = false and rev = 2 when response is an empty ACL" in {
Get(s"/v1/acls/myorg/myproj1?rev=2&self=false") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/myorg/myproj1?rev=2&self=false") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual expectedResponse(0L, Seq.empty)
status shouldEqual StatusCodes.OK
}
}

"get ACL self = true and ancestors = true" in {
Get(s"/v1/acls/myorg/myproj?ancestors=true") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/myorg/myproj?ancestors=true") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual
expectedResponse(3, Seq((selfAcls(Root), 3), (selfAcls(myOrg), 3), (selfAcls(myOrgMyProj), 3)))
status shouldEqual StatusCodes.OK
Expand All @@ -331,7 +328,7 @@ class AclsRoutesSpec extends BaseRouteSpec {
val patch = aclJson(userAclRead(Root)).removeKeys("_path") deepMerge
Json.obj("@type" -> Json.fromString("Subtract"))
forAll(paths) { case (path, address) =>
Patch(s"/v1/acls$path?rev=3", patch.toEntity) ~> asUser ~> routes ~> check {
Patch(s"/v1/acls$path?rev=3", patch.toEntity) ~> as(user) ~> routes ~> check {
response.asJson shouldEqual aclMetadata(address, rev = 4, createdBy = user, updatedBy = user)
status shouldEqual StatusCodes.OK
}
Expand All @@ -340,22 +337,22 @@ class AclsRoutesSpec extends BaseRouteSpec {

"delete ACL" in {
forAll(paths) { case (path, address) =>
Delete(s"/v1/acls$path?rev=4") ~> asUser ~> routes ~> check {
Delete(s"/v1/acls$path?rev=4") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual aclMetadata(address, rev = 5, createdBy = user, updatedBy = user)
status shouldEqual StatusCodes.OK
}
}
}

"return an error when getting ACL with rev and ancestors = true" in {
Get(s"/v1/acls/myorg/myproj?rev=2&ancestors=true") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/myorg/myproj?rev=2&ancestors=true") ~> as(user) ~> routes ~> check {
response.asJson shouldEqual jsonContentOf("errors/acls-malformed-query-params.json")
status shouldEqual StatusCodes.BadRequest
}
}

"return an error in the case of the keyword 'events'" in {
Get(s"/v1/acls/events") ~> asUser ~> routes ~> check {
Get(s"/v1/acls/events") ~> as(user) ~> routes ~> check {
status shouldEqual StatusCodes.NotFound
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ch.epfl.bluebrain.nexus.delta.routes

import akka.http.scaladsl.model.headers.{`Last-Event-ID`, OAuth2BearerToken}
import akka.http.scaladsl.model.headers.`Last-Event-ID`
import akka.http.scaladsl.model.sse.ServerSentEvent
import akka.http.scaladsl.model.{MediaTypes, StatusCodes}
import akka.http.scaladsl.server.Route
Expand All @@ -9,12 +9,10 @@ import ch.epfl.bluebrain.nexus.delta.sdk.acls.AclSimpleCheck
import ch.epfl.bluebrain.nexus.delta.sdk.acls.model.AclAddress
import ch.epfl.bluebrain.nexus.delta.sdk.directives.DeltaSchemeDirectives
import ch.epfl.bluebrain.nexus.delta.sdk.identities.IdentitiesDummy
import ch.epfl.bluebrain.nexus.delta.sdk.identities.model.Caller
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.Permissions.events
import ch.epfl.bluebrain.nexus.delta.sdk.projects.FetchContextDummy
import ch.epfl.bluebrain.nexus.delta.sdk.sse.{ServerSentEventStream, SseElemStream}
import ch.epfl.bluebrain.nexus.delta.sdk.utils.BaseRouteSpec
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.{Anonymous, Authenticated, Group}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ProjectRef
import ch.epfl.bluebrain.nexus.delta.sourcing.offset.Offset
import ch.epfl.bluebrain.nexus.delta.sourcing.query.SelectFilter
Expand All @@ -28,11 +26,7 @@ class ElemRoutesSpec extends BaseRouteSpec with CirceLiteral {

private val aclCheck = AclSimpleCheck().accepted

implicit private val caller: Caller =
Caller(alice, Set(alice, Anonymous, Authenticated(realm), Group("group", realm)))

private val identities = IdentitiesDummy(caller)
private val asAlice = addCredentials(OAuth2BearerToken("alice"))
private val identities = IdentitiesDummy.fromUsers(alice)

private val elem1 = ServerSentEvent("""{"id":"id1"}""", "Success", "1")
private val elem2 = ServerSentEvent("""{"id":"id2"}""", "Dropped", "2")
Expand Down Expand Up @@ -102,14 +96,14 @@ class ElemRoutesSpec extends BaseRouteSpec with CirceLiteral {
}

"get the continuous elems" in {
Get("/v1/elems/org/proj/continuous") ~> asAlice ~> routes ~> check {
Get("/v1/elems/org/proj/continuous") ~> as(alice) ~> routes ~> check {
mediaType shouldBe MediaTypes.`text/event-stream`
chunksStream.asString(3).strip shouldEqual expected
}
}

"get the current elems" in {
Get("/v1/elems/org/proj/currents") ~> asAlice ~> routes ~> check {
Get("/v1/elems/org/proj/currents") ~> as(alice) ~> routes ~> check {
mediaType shouldBe MediaTypes.`text/event-stream`
chunksStream.asString(3).strip shouldEqual expected
}
Expand All @@ -123,7 +117,7 @@ class ElemRoutesSpec extends BaseRouteSpec with CirceLiteral {
"maxInstant" : "1970-01-01T00:00:00Z"}
"""

Get("/v1/elems/org/proj/remaining") ~> asAlice ~> routes ~> check {
Get("/v1/elems/org/proj/remaining") ~> as(alice) ~> routes ~> check {
response.status shouldEqual StatusCodes.OK
response.asJson shouldEqual expected
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
package ch.epfl.bluebrain.nexus.delta.routes

import akka.http.scaladsl.model.headers.{`Last-Event-ID`, OAuth2BearerToken}
import akka.http.scaladsl.model.headers.`Last-Event-ID`
import akka.http.scaladsl.model.sse.ServerSentEvent
import akka.http.scaladsl.model.{MediaTypes, StatusCodes}
import akka.http.scaladsl.server.Route
import cats.effect.IO
import ch.epfl.bluebrain.nexus.delta.sdk.acls.AclSimpleCheck
import ch.epfl.bluebrain.nexus.delta.sdk.acls.model.AclAddress
import ch.epfl.bluebrain.nexus.delta.sdk.identities.IdentitiesDummy
import ch.epfl.bluebrain.nexus.delta.sdk.identities.model.Caller
import ch.epfl.bluebrain.nexus.delta.sdk.organizations.model.OrganizationRejection.OrganizationNotFound
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.Permissions.events
import ch.epfl.bluebrain.nexus.delta.sdk.projects.model.ProjectRejection.ProjectNotFound
import ch.epfl.bluebrain.nexus.delta.sdk.sse.{ServerSentEventStream, SseEventLog}
import ch.epfl.bluebrain.nexus.delta.sdk.utils.BaseRouteSpec
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.{Anonymous, Authenticated, Group}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.{Label, ProjectRef}
import ch.epfl.bluebrain.nexus.delta.sourcing.offset.Offset
import ch.epfl.bluebrain.nexus.delta.sourcing.offset.Offset.{At, Start}
Expand All @@ -26,11 +24,7 @@ class EventsRoutesSpec extends BaseRouteSpec {

private val aclCheck = AclSimpleCheck().accepted

implicit private val caller: Caller =
Caller(alice, Set(alice, Anonymous, Authenticated(realm), Group("group", realm)))

private val identities = IdentitiesDummy(caller)
private val asAlice = addCredentials(OAuth2BearerToken("alice"))
private val identities = IdentitiesDummy.fromUsers(alice)

private val project = Label.unsafe("projects")
private val resources = Label.unsafe("resources")
Expand Down Expand Up @@ -116,14 +110,14 @@ class EventsRoutesSpec extends BaseRouteSpec {
)

forAll(endpoints) { endpoint =>
Get(endpoint) ~> asAlice ~> `Last-Event-ID`("2") ~> routes ~> check {
Get(endpoint) ~> as(alice) ~> `Last-Event-ID`("2") ~> routes ~> check {
response.status shouldEqual StatusCodes.NotFound
}
}
}

"get the resource events" in {
Get("/v1/resources/events") ~> asAlice ~> routes ~> check {
Get("/v1/resources/events") ~> as(alice) ~> routes ~> check {
mediaType shouldBe MediaTypes.`text/event-stream`
chunksStream.asString(2).strip shouldEqual contentOf("events/resource-events.txt").strip
}
Expand All @@ -136,7 +130,7 @@ class EventsRoutesSpec extends BaseRouteSpec {
)

forAll(endpoints) { endpoint =>
Get(endpoint) ~> `Last-Event-ID`("0") ~> asAlice ~> routes ~> check {
Get(endpoint) ~> `Last-Event-ID`("0") ~> as(alice) ~> routes ~> check {
mediaType shouldBe MediaTypes.`text/event-stream`
chunksStream.asString(2).strip shouldEqual contentOf("events/project-events.txt").strip
}
Expand Down
Loading