Skip to content

Commit

Permalink
fix: Find the right doap when looking for by ForWhat (#3460)
Browse files Browse the repository at this point in the history
  • Loading branch information
seakayone authored Jan 17, 2025
1 parent f96d579 commit 265cb99
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ object DspIngestTestContainer {
.withEnv("DB_JDBC_URL", "jdbc:sqlite:/tmp/ingest.sqlite")
.withFileSystemBind(imagesVolume.hostPath, assetDir, BindMode.READ_WRITE)
.withFileSystemBind(tempVolume.hostPath, tempDir, BindMode.READ_WRITE)
.withLogConsumer(frame => print("DSP-INGEST:" + frame.getUtf8String))
}

val layer: URLayer[SharedVolumes.Volumes, DspIngestTestContainer] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,24 +94,24 @@ abstract class AbstractEntityRepo[E <: EntityWithId[Id], Id <: StringValue](
}
}

protected def findOneByTriplePattern(pattern: RdfSubject => TriplePattern): Task[Option[E]] =
findOneByQuery(findByTriplePatternQuery(pattern))
protected def findOneByPattern(pattern: RdfSubject => GraphPattern): Task[Option[E]] =
findOneByQuery(findByPatternQuery(pattern))

protected def findAllByTriplePattern(pattern: RdfSubject => TriplePattern): Task[Chunk[E]] =
findAllByQuery(findByTriplePatternQuery(pattern))
protected def findAllByPattern(pattern: RdfSubject => GraphPattern): Task[Chunk[E]] =
findAllByQuery(findByPatternQuery(pattern))

private def findByTriplePatternQuery(pattern: RdfSubject => TriplePattern) = {
private def findByPatternQuery(pattern: RdfSubject => GraphPattern) = {
val s = variable("s")
val query: String = entityQuery(tripleP(s), graphP(s).and(pattern(s))).getQueryString
Construct(query)
}

protected def findOneByQuery(construct: Construct): Task[Option[E]] =
private def findOneByQuery(construct: Construct): Task[Option[E]] =
runQuery(construct)
.map(_.nextOption())
.flatMap(ZIO.foreach(_)(mapper.toEntity(_).mapError(TriplestoreResponseException.apply)))

protected def findAllByQuery(construct: Construct): Task[Chunk[E]] =
private def findAllByQuery(construct: Construct): Task[Chunk[E]] =
runQuery(construct).flatMap(
ZStream.fromIterator(_).mapZIO(mapper.toEntity(_).mapError(TriplestoreResponseException.apply)).runCollect,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ final case class AdministrativePermissionRepoLive(
groupIri: GroupIri,
projectIri: ProjectIri,
): Task[Option[AdministrativePermission]] =
findOneByTriplePattern(
findOneByPattern(
_.has(Vocabulary.KnoraAdmin.forGroup, Rdf.iri(groupIri.value))
.andHas(Vocabulary.KnoraAdmin.forProject, Rdf.iri(projectIri.value)),
)

override def findByProject(projectIri: ProjectIri): Task[Chunk[AdministrativePermission]] =
findAllByTriplePattern(_.has(Vocabulary.KnoraAdmin.forProject, Rdf.iri(projectIri.value)))
findAllByPattern(_.has(Vocabulary.KnoraAdmin.forProject, Rdf.iri(projectIri.value)))
}

object AdministrativePermissionRepoLive {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package org.knora.webapi.slice.admin.repo.service

import org.eclipse.rdf4j.common.net.ParsedIRI
import org.eclipse.rdf4j.sparqlbuilder.core.SparqlBuilder.`var` as variable
import org.eclipse.rdf4j.sparqlbuilder.graphpattern.TriplePattern
import org.eclipse.rdf4j.sparqlbuilder.rdf.Iri
import org.eclipse.rdf4j.sparqlbuilder.rdf.Rdf
Expand Down Expand Up @@ -54,15 +55,23 @@ final case class DefaultObjectAccessPermissionRepoLive(
)

override def findByProject(projectIri: ProjectIri): Task[Chunk[DefaultObjectAccessPermission]] =
findAllByTriplePattern(_.has(Vocabulary.KnoraAdmin.forProject, Rdf.iri(projectIri.value)))
findAllByPattern(_.has(Vocabulary.KnoraAdmin.forProject, Rdf.iri(projectIri.value)))

def findByProjectAndForWhat(projectIri: ProjectIri, forWhat: ForWhat): Task[Option[DefaultObjectAccessPermission]] =
findOneByTriplePattern(p =>
findOneByPattern(p =>
val pattern = p.has(Vocabulary.KnoraAdmin.forProject, Rdf.iri(projectIri.value))
forWhat match {
case Group(g) => pattern.andHas(Vocabulary.KnoraAdmin.forGroup, Rdf.iri(g.value))
case ResourceClass(rc) => pattern.andHas(Vocabulary.KnoraAdmin.forResourceClass, Rdf.iri(rc.value))
case Property(prop) => pattern.andHas(Vocabulary.KnoraAdmin.forProperty, Rdf.iri(prop.value))
case Group(g) => pattern.andHas(Vocabulary.KnoraAdmin.forGroup, Rdf.iri(g.value))
case ResourceClass(rc) =>
pattern
.andHas(Vocabulary.KnoraAdmin.forResourceClass, Rdf.iri(rc.value))
.filterNotExists(p.has(Vocabulary.KnoraAdmin.forProperty, variable("prop")))

case Property(prop) =>
pattern
.andHas(Vocabulary.KnoraAdmin.forProperty, Rdf.iri(prop.value))
.filterNotExists(p.has(Vocabulary.KnoraAdmin.forResourceClass, variable("rc")))

case ResourceClassAndProperty(rc, prop) =>
pattern
.andHas(Vocabulary.KnoraAdmin.forResourceClass, Rdf.iri(rc.value))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ final case class KnoraGroupRepoLive(
super.save(group)

override def findByName(name: GroupName): Task[Option[KnoraGroup]] =
findOneByTriplePattern(_.has(groupName, Rdf.literalOf(name.value)))
findOneByPattern(_.has(groupName, Rdf.literalOf(name.value)))
.map(_.orElse(KnoraGroupRepo.builtIn.findOneBy(_.groupName == name)))

override def findByProjectIri(projectIri: ProjectIri): Task[Chunk[KnoraGroup]] =
findAllByTriplePattern(_.has(belongsToProject, Rdf.iri(projectIri.value)))
findAllByPattern(_.has(belongsToProject, Rdf.iri(projectIri.value)))
}

object KnoraGroupRepoLive {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ final case class KnoraProjectRepoLive(
super.findById(id).map(_.orElse(KnoraProjectRepo.builtIn.findOneBy(_.id == id)))

override def findByShortcode(shortcode: Shortcode): Task[Option[KnoraProject]] =
findOneByTriplePattern(_.has(Vocabulary.KnoraAdmin.projectShortcode, shortcode.value))
findOneByPattern(_.has(Vocabulary.KnoraAdmin.projectShortcode, shortcode.value))
.map(_.orElse(KnoraProjectRepo.builtIn.findOneBy(_.shortcode == shortcode)))

override def findByShortname(shortname: Shortname): Task[Option[KnoraProject]] =
findOneByTriplePattern(_.has(Vocabulary.KnoraAdmin.projectShortname, shortname.value))
findOneByPattern(_.has(Vocabulary.KnoraAdmin.projectShortname, shortname.value))
.map(_.orElse(KnoraProjectRepo.builtIn.findOneBy(_.shortname == shortname)))

override def findAll(): Task[Chunk[KnoraProject]] = super.findAll().map(_ ++ KnoraProjectRepo.builtIn.all)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,23 @@ final case class KnoraUserRepoLive(
super.findById(id).map(_.orElse(KnoraUserRepo.builtIn.findOneBy(_.id == id)))

override def findByProjectAdminMembership(projectIri: ProjectIri): Task[Chunk[KnoraUser]] =
findAllByTriplePattern(_.has(isInProjectAdminGroup, Rdf.iri(projectIri.value)))
findAllByPattern(_.has(isInProjectAdminGroup, Rdf.iri(projectIri.value)))
.map(_ ++ KnoraUserRepo.builtIn.findAllBy(_.isInProjectAdminGroup.contains(projectIri)))

override def findByProjectMembership(projectIri: ProjectIri): Task[Chunk[KnoraUser]] =
findAllByTriplePattern(_.has(isInProject, Rdf.iri(projectIri.value)))
findAllByPattern(_.has(isInProject, Rdf.iri(projectIri.value)))
.map(_ ++ KnoraUserRepo.builtIn.findAllBy(_.isInProject.contains(projectIri)))

override def findByGroupMembership(groupIri: GroupIri): Task[Chunk[KnoraUser]] =
findAllByTriplePattern(_.has(isInGroup, Rdf.iri(groupIri.value)))
findAllByPattern(_.has(isInGroup, Rdf.iri(groupIri.value)))
.map(_ ++ KnoraUserRepo.builtIn.findAllBy(_.isInGroup.contains(groupIri)))

override def findByEmail(mail: Email): Task[Option[KnoraUser]] =
findOneByTriplePattern(_.has(email, Rdf.literalOf(mail.value)))
findOneByPattern(_.has(email, Rdf.literalOf(mail.value)))
.map(_.orElse(KnoraUserRepo.builtIn.findOneBy(_.email == mail)))

override def findByUsername(name: Username): Task[Option[KnoraUser]] =
findOneByTriplePattern(_.has(username, Rdf.literalOf(name.value)))
findOneByPattern(_.has(username, Rdf.literalOf(name.value)))
.map(_.orElse(KnoraUserRepo.builtIn.findOneBy(_.username == name)))

override def save(user: KnoraUser): Task[KnoraUser] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,47 @@ object DefaultObjectAccessPermissionRepoLiveSpec extends ZIOSpecDefault {
private def permission(forWhat: ForWhat, permissions: Chunk[DefaultObjectAccessPermissionPart]) =
DefaultObjectAccessPermission(PermissionIri.makeNew(shortcode), projectIri, forWhat, permissions)

private val resourceClassIri: InternalIri = InternalIri("https://example.com/rc")
private val propertyIri: InternalIri = InternalIri("https://example.com/p")
private val expected = permission(
ForWhat.ResourceClassAndProperty(InternalIri("https://example.com/rc"), InternalIri("https://example.com/p")),
ForWhat.ResourceClassAndProperty(resourceClassIri, propertyIri),
Chunk(
DefaultObjectAccessPermissionPart(RestrictedView, NonEmptyChunk(groupIri)),
DefaultObjectAccessPermissionPart(View, NonEmptyChunk(GroupIri.makeNew(shortcode), GroupIri.makeNew(shortcode))),
),
)

val spec = suite("AdministrativePermissionRepoLive")(
val spec = suite("DefaultObjectAccessPermissionRepoLive")(
test("should save and find") {
for {
saved <- repo(_.save(expected))
found <- repo(_.findById(saved.id))
} yield assertTrue(found.contains(saved), saved == expected)
},
test("given ForWhat Property and ForWhat ResourceClassAndProperty exist should findByProjectAndForWhat") {
val rc = permission(
ForWhat.ResourceClass(resourceClassIri),
Chunk(DefaultObjectAccessPermissionPart(View, NonEmptyChunk(GroupIri.makeNew(shortcode)))),
)
val p = permission(
ForWhat.Property(propertyIri),
Chunk(DefaultObjectAccessPermissionPart(View, NonEmptyChunk(GroupIri.makeNew(shortcode)))),
)
val rcp = permission(
ForWhat.ResourceClassAndProperty(resourceClassIri, propertyIri),
Chunk(DefaultObjectAccessPermissionPart(View, NonEmptyChunk(GroupIri.makeNew(shortcode)))),
)
for {
_ <- repo(_.saveAll(List(p, rc, rcp)))
foundPp <- repo(_.findByProjectAndForWhat(projectIri, p.forWhat))
foundRc <- repo(_.findByProjectAndForWhat(projectIri, rc.forWhat))
foundRcp <- repo(_.findByProjectAndForWhat(projectIri, rcp.forWhat))
} yield assertTrue(
foundPp.contains(p),
foundRc.contains(rc),
foundRcp.contains(rcp),
)
},
test("should delete") {
for {
saved <- repo(_.save(expected))
Expand Down

0 comments on commit 265cb99

Please sign in to comment.