Skip to content

Commit

Permalink
fix: The GroupIri should allow "knora-admin:" prefixed iris and expan…
Browse files Browse the repository at this point in the history
…d it
  • Loading branch information
seakayone committed Jul 1, 2024
1 parent 923a7b0 commit 1630381
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import org.knora.webapi.messages.admin.responder.permissionsmessages.PermissionT
import org.knora.webapi.messages.twirl.SparqlTemplateLinkUpdate
import org.knora.webapi.messages.twirl.queries.sparql
import org.knora.webapi.messages.util.KnoraSystemInstances
import org.knora.webapi.messages.util.KnoraSystemInstances.Users.SystemUser
import org.knora.webapi.messages.util.PermissionUtilADM
import org.knora.webapi.messages.util.PermissionUtilADM.*
import org.knora.webapi.messages.util.search.gravsearch.GravsearchParser
Expand Down Expand Up @@ -154,12 +155,7 @@ final case class ValuesResponderV2Live(

// Get the resource's metadata and relevant property objects, using the adjusted property. Do this as the system user,
// so we can see objects that the user doesn't have permission to see.
resourceInfo <-
getResourceWithPropertyValues(
resourceIri = valueToCreate.resourceIri,
propertyInfo = adjustedInternalPropertyInfo,
requestingUser = KnoraSystemInstances.Users.SystemUser,
)
resourceInfo <- getResourceWithPropertyValues(valueToCreate.resourceIri, adjustedInternalPropertyInfo)

// Check that the user has permission to modify the resource.
_ <- resourceUtilV2.checkResourcePermission(
Expand Down Expand Up @@ -479,7 +475,7 @@ final case class ValuesResponderV2Live(
sourceResourceInfo = resourceInfo,
linkPropertyIri = OntologyConstants.KnoraBase.HasStandoffLinkTo.toSmartIri,
targetResourceIri = targetResourceIri,
valueCreator = KnoraUserRepo.builtIn.SystemUser.id.value,
valueCreator = valueCreator,
valuePermissions = standoffLinkValuePermissions,
)
}.toVector
Expand Down Expand Up @@ -675,12 +671,7 @@ final case class ValuesResponderV2Live(

// Get the resource's metadata and relevant property objects, using the adjusted property. Do this as the system user,
// so we can see objects that the user doesn't have permission to see.
resourceInfo <-
getResourceWithPropertyValues(
resourceIri = resourceIri,
propertyInfo = adjustedInternalPropertyInfo,
requestingUser = KnoraSystemInstances.Users.SystemUser,
)
resourceInfo <- getResourceWithPropertyValues(resourceIri, adjustedInternalPropertyInfo)

_ <-
ZIO.when(resourceInfo.resourceClassIri != submittedExternalResourceClassIri.toOntologySchema(InternalSchema))(
Expand Down Expand Up @@ -1054,7 +1045,7 @@ final case class ValuesResponderV2Live(
sourceResourceInfo = resourceInfo,
linkPropertyIri = OntologyConstants.KnoraBase.HasStandoffLinkTo.toSmartIri,
targetResourceIri = targetResourceIri,
valueCreator = KnoraUserRepo.builtIn.SystemUser.id.value,
valueCreator = valueCreator,
valuePermissions = standoffLinkValuePermissions,
)
}
Expand All @@ -1069,7 +1060,7 @@ final case class ValuesResponderV2Live(
sourceResourceInfo = resourceInfo,
linkPropertyIri = OntologyConstants.KnoraBase.HasStandoffLinkTo.toSmartIri,
targetResourceIri = removedTargetResource,
valueCreator = KnoraUserRepo.builtIn.SystemUser.id.value,
valueCreator = valueCreator,
valuePermissions = standoffLinkValuePermissions,
)
}
Expand Down Expand Up @@ -1299,12 +1290,7 @@ final case class ValuesResponderV2Live(

// Get the resource's metadata and relevant property objects, using the adjusted property. Do this as the system user,
// so we can see objects that the user doesn't have permission to see.
resourceInfo <-
getResourceWithPropertyValues(
resourceIri = deleteValue.resourceIri,
propertyInfo = adjustedInternalPropertyInfo,
requestingUser = KnoraSystemInstances.Users.SystemUser,
)
resourceInfo <- getResourceWithPropertyValues(deleteValue.resourceIri, adjustedInternalPropertyInfo)

// Check that the resource belongs to the class that the client submitted.
_ <- ZIO.when(resourceInfo.resourceClassIri != deleteValue.resourceClassIri.toOntologySchema(InternalSchema)) {
Expand Down Expand Up @@ -1568,7 +1554,7 @@ final case class ValuesResponderV2Live(
sourceResourceInfo = resourceInfo,
linkPropertyIri = OntologyConstants.KnoraBase.HasStandoffLinkTo.toSmartIri,
targetResourceIri = removedTargetResource,
valueCreator = KnoraUserRepo.builtIn.SystemUser.id.value,
valueCreator = requestingUser.id,
valuePermissions = standoffLinkValuePermissions,
)
}
Expand Down Expand Up @@ -1677,14 +1663,9 @@ final case class ValuesResponderV2Live(
* @param propertyInfo the property definition (in the internal schema). If the caller wants to query a link, this must be the link property,
* not the link value property.
*
* @param requestingUser the user making the request.
* @return a [[ReadResourceV2]] containing only the resource's metadata and its values for the specified property.
*/
private def getResourceWithPropertyValues(
resourceIri: IRI,
propertyInfo: ReadPropertyInfoV2,
requestingUser: User,
): Task[ReadResourceV2] =
private def getResourceWithPropertyValues(resourceIri: IRI, propertyInfo: ReadPropertyInfoV2): Task[ReadResourceV2] =
for {
// Get the property's object class constraint.
objectClassConstraint <-
Expand Down Expand Up @@ -1721,9 +1702,8 @@ final case class ValuesResponderV2Live(
.toString()

// Run the query.
query <- ZIO.succeed(GravsearchParser.parseQuery(gravsearchQuery))
searchResponse <-
searchResponderV2.gravsearchV2(query, apiV2SchemaWithOption(MarkupRendering.Xml), requestingUser)
query <- ZIO.succeed(GravsearchParser.parseQuery(gravsearchQuery))
searchResponse <- searchResponderV2.gravsearchV2(query, apiV2SchemaWithOption(MarkupRendering.Xml), SystemUser)
} yield searchResponse.toResource(resourceIri)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import sttp.tapir.CodecFormat
import zio.Chunk
import zio.json.DeriveJsonCodec
import zio.json.JsonCodec

import dsp.valueobjects.Iri
import dsp.valueobjects.UuidUtil
import org.knora.webapi.IRI
Expand Down Expand Up @@ -103,9 +102,10 @@ object GroupIri extends StringValueCompanion[GroupIri] {
private def isBuiltInGroupIri(iri: String): Boolean = BuiltInGroups.contains(iri)

def from(value: String): Either[String, GroupIri] = value match {
case _ if value.isEmpty => Left("Group IRI cannot be empty.")
case _ if isGroupIriValid(value) => Right(GroupIri(value))
case v => Left(s"Group IRI is invalid: $v")
case _ if value.isEmpty => Left("Group IRI cannot be empty.")
case _ if value.startsWith("knora-admin:") => from(value.replace("knora-admin:", KnoraAdminPrefixExpansion))
case _ if isGroupIriValid(value) => Right(GroupIri(value))
case v => Left(s"Group IRI is invalid: $v")
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

package org.knora.webapi.slice.admin.domain.model

import org.knora.webapi.messages.OntologyConstants.KnoraAdmin.KnoraAdminPrefixExpansion
import zio.Chunk
import zio.test.Gen
import zio.test.Spec
import zio.test.ZIOSpecDefault
Expand All @@ -16,6 +18,13 @@ object GroupIriSpec extends ZIOSpecDefault {
test("not be created from an empty value") {
assertTrue(GroupIri.from("") == Left("Group IRI cannot be empty."))
},
test("allow prefixed builtin GroupIris") {
val builtIn = Chunk("UnknownUser", "KnownUser", "Creator", "ProjectMember", "ProjectAdmin", "SystemAdmin")
.map("knora-admin:" + _)
check(Gen.fromIterable(builtIn)) { it =>
assertTrue(GroupIri.from(it).map(_.value) == Right(it.replace("knora-admin:", KnoraAdminPrefixExpansion)))
}
},
test("be created from a valid value") {
val validIris = Gen.fromIterable(
Seq(
Expand Down

0 comments on commit 1630381

Please sign in to comment.