Skip to content

Commit

Permalink
Merge branch 'master' into 4309-fix-resource-fetch
Browse files Browse the repository at this point in the history
  • Loading branch information
imsdu authored Sep 27, 2023
2 parents 8cfab9e + 2c9929a commit 4800f4e
Show file tree
Hide file tree
Showing 23 changed files with 378 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package ch.epfl.bluebrain.nexus.delta.routes

import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import ch.epfl.bluebrain.nexus.delta.sdk.acls.AclCheck
import ch.epfl.bluebrain.nexus.delta.sdk.circe.CirceUnmarshalling
import ch.epfl.bluebrain.nexus.delta.sdk.directives.AuthDirectives
import ch.epfl.bluebrain.nexus.delta.sdk.directives.DeltaDirectives._
import ch.epfl.bluebrain.nexus.delta.sdk.identities.Identities
import ch.epfl.bluebrain.nexus.delta.sdk.model.BaseUri
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.model.Permission

/**
* The user permissions routes. Used for checking whether the current logged in user has certain permissions.
*
* @param identities
* the identities operations bundle
* @param aclCheck
* verify the acls for users
*/
final class UserPermissionsRoutes(identities: Identities, aclCheck: AclCheck)(implicit
baseUri: BaseUri
) extends AuthDirectives(identities, aclCheck)
with CirceUnmarshalling {

def routes: Route =
baseUriPrefix(baseUri.prefix) {
pathPrefix("user") {
pathPrefix("permissions") {
projectRef { project =>
extractCaller { implicit caller =>
head {
parameter("permission".as[Permission]) { permission =>
authorizeFor(project, permission)(caller) {
complete(StatusCodes.NoContent)
}
}
}
}
}
}
}
}
}

object UserPermissionsRoutes {
def apply(identities: Identities, aclCheck: AclCheck)(implicit
baseUri: BaseUri
): Route =
new UserPermissionsRoutes(identities, aclCheck: AclCheck).routes
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package ch.epfl.bluebrain.nexus.delta.wiring

import akka.http.scaladsl.server.RouteConcatenation
import cats.effect.Clock
import ch.epfl.bluebrain.nexus.delta.Main.pluginsMaxPriority
import ch.epfl.bluebrain.nexus.delta.config.AppConfig
import ch.epfl.bluebrain.nexus.delta.rdf.Vocabulary.contexts
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.{ContextValue, RemoteContextResolution}
import ch.epfl.bluebrain.nexus.delta.rdf.utils.JsonKeyOrdering
import ch.epfl.bluebrain.nexus.delta.routes.AclsRoutes
import ch.epfl.bluebrain.nexus.delta.routes.{AclsRoutes, UserPermissionsRoutes}
import ch.epfl.bluebrain.nexus.delta.sdk._
import ch.epfl.bluebrain.nexus.delta.sdk.acls.model.AclEvent
import ch.epfl.bluebrain.nexus.delta.sdk.acls.{AclCheck, Acls, AclsImpl}
Expand Down Expand Up @@ -71,8 +72,16 @@ object AclsModule extends ModuleDef {
} yield RemoteContextResolution.fixed(contexts.acls -> aclsCtx, contexts.aclsMetadata -> aclsMetaCtx)
)

many[PriorityRoute].add { (route: AclsRoutes) =>
PriorityRoute(pluginsMaxPriority + 5, route.routes, requiresStrictEntity = true)
make[UserPermissionsRoutes].from { (identities: Identities, aclCheck: AclCheck, baseUri: BaseUri) =>
new UserPermissionsRoutes(identities, aclCheck)(baseUri)
}

many[PriorityRoute].add { (alcs: AclsRoutes, userPermissions: UserPermissionsRoutes) =>
PriorityRoute(
pluginsMaxPriority + 5,
RouteConcatenation.concat(alcs.routes, userPermissions.routes),
requiresStrictEntity = true
)
}
}
// $COVERAGE-ON$
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,30 @@
"type": "keyword"
}
}
},
"remoteContexts": {
"type": "nested",
"properties": {
"iri": {
"type": "keyword"
},
"@type": {
"type": "keyword"
},
"resource": {
"properties": {
"id": {
"type": "keyword"
},
"project": {
"type": "keyword"
},
"rev": {
"type": "long"
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package ch.epfl.bluebrain.nexus.delta.plugins.graph.analytics.indexing
import ch.epfl.bluebrain.nexus.delta.plugins.graph.analytics.model.JsonLdDocument
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.JsonLdContext.keywords
import io.circe.{Encoder, Json}
import ch.epfl.bluebrain.nexus.delta.sdk.model.jsonld.RemoteContextRef
import ch.epfl.bluebrain.nexus.delta.sdk.syntax._
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.Subject
import ch.epfl.bluebrain.nexus.delta.sourcing.model.ProjectRef
import io.circe.syntax.{EncoderOps, KeyOps}
import io.circe.{Encoder, Json}

import java.time.Instant

Expand Down Expand Up @@ -43,6 +44,7 @@ object GraphAnalyticsResult {
final case class Index private (
project: ProjectRef,
id: Iri,
remoteContexts: Set[RemoteContextRef],
rev: Int,
deprecated: Boolean,
types: Set[Iri],
Expand All @@ -58,6 +60,7 @@ object GraphAnalyticsResult {
def active(
project: ProjectRef,
id: Iri,
remoteContexts: Set[RemoteContextRef],
rev: Int,
types: Set[Iri],
createdAt: Instant,
Expand All @@ -66,32 +69,34 @@ object GraphAnalyticsResult {
updatedBy: Subject,
value: JsonLdDocument
) =
new Index(project, id, rev, false, types, createdAt, createdBy, updatedAt, updatedBy, Some(value))
new Index(project, id, remoteContexts, rev, false, types, createdAt, createdBy, updatedAt, updatedBy, Some(value))

def deprecated(
project: ProjectRef,
id: Iri,
remoteContexts: Set[RemoteContextRef],
rev: Int,
types: Set[Iri],
createdAt: Instant,
createdBy: Subject,
updatedAt: Instant,
updatedBy: Subject
) =
new Index(project, id, rev, true, types, createdAt, createdBy, updatedAt, updatedBy, None)
new Index(project, id, remoteContexts, rev, true, types, createdAt, createdBy, updatedAt, updatedBy, None)

implicit val encoder: Encoder[Index] = Encoder.instance { i =>
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.Database._
Json
.obj(
keywords.id := i.id,
"_project" := i.project,
"_rev" := i.rev,
"_deprecated" := i.deprecated,
"_createdAt" := i.createdAt,
"_createdBy" := i.createdBy,
"_updatedAt" := i.updatedAt,
"_updatedBy" := i.updatedBy
keywords.id := i.id,
"remoteContexts" := i.remoteContexts,
"_project" := i.project,
"_rev" := i.rev,
"_deprecated" := i.deprecated,
"_createdAt" := i.createdAt,
"_createdBy" := i.createdBy,
"_updatedAt" := i.updatedAt,
"_updatedBy" := i.updatedBy
)
.addIfNonEmpty(keywords.tpe, i.types)
.deepMerge(i.value.map(_.asJson).getOrElse(Json.obj()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,10 @@ object GraphAnalyticsStream {
}
case Resources.entityType =>
Task.fromEither(ResourceState.serializer.codec.decodeJson(json)).flatMap {
case s if s.deprecated =>
Task.pure(
Index.deprecated(s.project, s.id, s.rev, s.types, s.createdAt, s.createdBy, s.updatedAt, s.updatedBy)
)
case s =>
JsonLdDocument.fromExpanded(s.expanded, findRelationships(project, xas, relationshipBatch)).map { d =>
Index.active(s.project, s.id, s.rev, s.types, s.createdAt, s.createdBy, s.updatedAt, s.updatedBy, d)
case state if state.deprecated => deprecatedIndex(state)
case state =>
JsonLdDocument.fromExpanded(state.expanded, findRelationships(project, xas, relationshipBatch)).map {
doc => activeIndex(state, doc)
}
}
case _ => Task.pure(Noop)
Expand All @@ -107,4 +104,34 @@ object GraphAnalyticsStream {
StreamingQuery.elems(project, start, SelectFilter.latest, qc, xas, decode)
}
// $COVERAGE-ON$

private def deprecatedIndex(state: ResourceState) =
Task.pure(
Index.deprecated(
state.project,
state.id,
state.remoteContexts,
state.rev,
state.types,
state.createdAt,
state.createdBy,
state.updatedAt,
state.updatedBy
)
)

private def activeIndex(state: ResourceState, doc: JsonLdDocument) =
Index.active(
state.project,
state.id,
state.remoteContexts,
state.rev,
state.types,
state.createdAt,
state.createdBy,
state.updatedAt,
state.updatedBy,
doc
)

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
"http://www.w3.org/ns/prov#Entity",
"https://neuroshapes.org/ResponseTrace"
],
"remoteContexts": [
{
"iri": "https://bluebrain.github.io/nexus/contexts/metadata.json",
"@type": "StaticContextRef"
}
],
"_project": "myorg/myproject",
"_rev": 1,
"_deprecated": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
"http://www.w3.org/ns/prov#Entity",
"https://neuroshapes.org/ResponseTrace"
],
"remoteContexts": [
{
"iri": "https://bluebrain.github.io/nexus/contexts/metadata.json",
"@type": "StaticContextRef"
}
],
"_project": "myorg/myproject",
"_rev": 1,
"_deprecated": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
"http://schema.org/Dataset",
"http://www.w3.org/ns/prov#Entity"
],
"remoteContexts": [
{
"iri": "https://bluebrain.github.io/nexus/contexts/metadata.json",
"@type": "StaticContextRef"
}
],
"_project": "myorg/myproject",
"_rev": 1,
"_deprecated": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
"https://neuroshapes.org/NeuroMorphology"
],
"@id": "http://localhost/deprecated",
"remoteContexts": [
{
"iri": "https://bluebrain.github.io/nexus/contexts/metadata.json",
"@type": "StaticContextRef"
}
],
"_project": "myorg/myproject",
"_rev": 1,
"_deprecated": true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import ch.epfl.bluebrain.nexus.delta.plugins.graph.analytics.model.JsonLdDocumen
import ch.epfl.bluebrain.nexus.delta.plugins.storage.files.nxvFile
import ch.epfl.bluebrain.nexus.delta.rdf.IriOrBNode.Iri
import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.ExpandedJsonLd
import ch.epfl.bluebrain.nexus.delta.sdk.model.jsonld.RemoteContextRef
import ch.epfl.bluebrain.nexus.delta.sdk.resources.Resources
import ch.epfl.bluebrain.nexus.delta.sdk.syntax._
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.Anonymous
Expand Down Expand Up @@ -41,6 +42,9 @@ class GraphAnalyticsSinkSuite

private val project = ProjectRef.unsafe("myorg", "myproject")

private val remoteContexts: Set[RemoteContextRef] =
Set(RemoteContextRef.StaticContextRef(iri"https://bluebrain.github.io/nexus/contexts/metadata.json"))

// resource1 has references to 'resource3', 'file1' and 'generatedBy',
// 'generatedBy' remains unresolved
private val resource1 = iri"http://localhost/resource1"
Expand Down Expand Up @@ -102,13 +106,17 @@ class GraphAnalyticsSinkSuite
types <- getTypes(expanded)
doc <- JsonLdDocument.fromExpanded(expanded, _ => findRelationships)
} yield {
val result = Index.active(project, id, 1, types, Instant.EPOCH, Anonymous, Instant.EPOCH, Anonymous, doc)
val result =
Index.active(project, id, remoteContexts, 1, types, Instant.EPOCH, Anonymous, Instant.EPOCH, Anonymous, doc)
success(id, result)
}
}

def indexDeprecated(id: Iri, types: Set[Iri]) =
success(id, Index.deprecated(project, id, 1, types, Instant.EPOCH, Anonymous, Instant.EPOCH, Anonymous))
success(
id,
Index.deprecated(project, id, remoteContexts, 1, types, Instant.EPOCH, Anonymous, Instant.EPOCH, Anonymous)
)

for {
active1 <- indexActive(resource1, expanded1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ch.epfl.bluebrain.nexus.delta.rdf.jsonld.context.{ContextValue, JsonLdCon
import ch.epfl.bluebrain.nexus.delta.sdk.implicits._
import ch.epfl.bluebrain.nexus.delta.sdk.marshalling.QueryParamsUnmarshalling.{IriBase, IriVocab}
import ch.epfl.bluebrain.nexus.delta.sdk.model.{BaseUri, IdSegment}
import ch.epfl.bluebrain.nexus.delta.sdk.permissions.model.Permission
import ch.epfl.bluebrain.nexus.delta.sdk.projects.model.{ApiMappings, ProjectContext}
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Identity.Subject
import ch.epfl.bluebrain.nexus.delta.sourcing.model.Label
Expand Down Expand Up @@ -90,6 +91,14 @@ trait QueryParamsUnmarshalling {
}
}

implicit def permissionFromStringUnmarshaller: FromStringUnmarshaller[Permission] =
Unmarshaller.strict[String, Permission] { string =>
Permission(string) match {
case Right(value) => value
case Left(err) => throw new IllegalArgumentException(err.getMessage)
}
}

/**
* Unmarsaller to transform an Iri to a Subject
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@
"path": "http://schema.org/worksFor"
}
],
"remoteContexts": [
{
"@type": "ProjectRemoteContextRef",
"iri": "https://bbp.epfl.ch/contexts/person",
"resource": {
"id": "https://bbp.epfl.ch/contexts/person",
"project": "myorg/myproj",
"rev": 1
}
}
],
"_createdAt": "2023-08-08T15:49:14.081Z",
"_createdBy": {
"@type": "User",
Expand Down
Loading

0 comments on commit 4800f4e

Please sign in to comment.