From 74d43441e6960acd6e86ea2a67ebdf3f6fdf4125 Mon Sep 17 00:00:00 2001 From: Marcin Procyk Date: Thu, 3 Feb 2022 12:08:03 +0100 Subject: [PATCH] feat(UUID): add IRI validation that allows only to create IRIs using UUID version 4 and 5 (DEV-402) (#1990) * add method that checks if UUID version is correct * improve UUID version checking implementation * add UUID check to admin velue objects * fix bad test IRIs * add permission iri validation * add resource iri validation * fix permisson bad IRIs * add value iri validation * cleanup * more cleanup * refactor validate methods * refactor UUID method * fix typos * fix failing tests --- .../webapi/messages/StringFormatter.scala | 53 +++++++++++++++++-- .../PermissionsMessagesADM.scala | 38 +++++++------ .../valueObjects/GroupsValueObjectsADM.scala | 5 ++ .../valueObjects/ListsValueObjectsADM.scala | 6 +++ .../ProjectsValueObjectsADM.scala | 8 ++- .../valueObjects/UsersValueObjectsADM.scala | 6 +++ .../util/standoff/XMLToStandoffUtil.scala | 2 +- .../resourcemessages/ResourceMessagesV2.scala | 13 +++-- .../valuemessages/ValueMessagesV2.scala | 9 +++- .../webapi/e2e/admin/GroupsADME2ESpec.scala | 2 +- .../e2e/admin/PermissionsADME2ESpec.scala | 6 +-- .../webapi/e2e/admin/ProjectsADME2ESpec.scala | 9 +--- .../webapi/e2e/admin/UsersADME2ESpec.scala | 4 +- .../OldListsRouteADMFeatureE2ESpec.scala | 4 +- .../e2e/v2/ResourcesRouteV2E2ESpec.scala | 2 +- .../webapi/e2e/v2/ValuesRouteV2E2ESpec.scala | 5 +- .../webapi/messages/StringFormatterSpec.scala | 37 ++++++++++--- .../PermissionsMessagesADMSpec.scala | 37 +++++++++++++ .../GroupsValueObjectsADMSpec.scala | 5 ++ .../ListsValueObjectsADMSpec.scala | 3 ++ .../ProjectsValueObjectsADMSpec.scala | 8 +-- .../UsersValueObjectsADMSpec.scala | 3 ++ .../admin/PermissionsResponderADMSpec.scala | 6 +-- .../sharedtestdata/SharedTestDataADM.scala | 6 +-- 24 files changed, 208 insertions(+), 69 deletions(-) diff --git a/webapi/src/main/scala/org/knora/webapi/messages/StringFormatter.scala b/webapi/src/main/scala/org/knora/webapi/messages/StringFormatter.scala index fdca967275..0e66c26dc3 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/StringFormatter.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/StringFormatter.scala @@ -47,6 +47,7 @@ import scala.util.{Failure, Success, Try} * Provides instances of [[StringFormatter]], as well as string formatting constants. */ object StringFormatter { + val UUID_INVALID_ERROR = "Invalid UUID used to create IRI. Only versions 4 and 5 are supported." // A non-printing delimiter character, Unicode INFORMATION SEPARATOR ONE, that should never occur in data. val INFORMATION_SEPARATOR_ONE = '\u001F' @@ -898,7 +899,7 @@ class StringFormatter private ( * about the IRI being constructed. * @param errorFun a function that throws an exception. It will be called if the IRI is invalid. */ - private class SmartIriImpl(iriStr: IRI, parsedIriInfo: Option[SmartIriInfo], errorFun: => Nothing) extends SmartIri { + class SmartIriImpl(iriStr: IRI, parsedIriInfo: Option[SmartIriInfo], errorFun: => Nothing) extends SmartIri { def this(iriStr: IRI) = this(iriStr, None, throw DataConversionException(s"Couldn't parse IRI: $iriStr")) def this(iriStr: IRI, parsedIriInfo: Option[SmartIriInfo]) = @@ -2961,14 +2962,56 @@ class StringFormatter private ( errorFun } + /** + * Gets the last segment of IRI, decodes UUID and gets the version. + * @param s the string (IRI) to be checked. + * @return UUID version. + */ + def getUUIDVersion(s: IRI): Int = { + val encodedUUID = s.split("/").last + decodeUuid(encodedUUID).version() + } + + /** + * Checks if UUID used to create IRI has correct version (4 and 5 are allowed). + * @param s the string (IRI) to be checked. + * @return TRUE for correct versions, FALSE for incorrect. + */ + def isUUIDVersion4Or5(s: IRI): Boolean = + if (getUUIDVersion(s) == 4 || getUUIDVersion(s) == 5) { + true + } else { + false + } + /** * Checks if a string is the right length to be a canonical or Base64-encoded UUID. * - * @param idStr the string to check. - * @return `true` if the string is the right length to be a canonical or Base64-encoded UUID. + * @param s the string to check. + * @return TRUE if the string is the right length to be a canonical or Base64-encoded UUID. */ - def couldBeUuid(idStr: String): Boolean = - idStr.length == CanonicalUuidLength || idStr.length == Base64UuidLength + def hasUUIDLength(s: String): Boolean = + s.length == CanonicalUuidLength || s.length == Base64UuidLength + + /** + * Validates resource IRI + * @param iri to be validated + */ + def validateUUIDOfResourceIRI(iri: SmartIri): Unit = + if (iri.isKnoraResourceIri && hasUUIDLength(iri.toString.split("/").last) && !isUUIDVersion4Or5(iri.toString)) { + throw BadRequestException(UUID_INVALID_ERROR) + } + + /** + * Validates permission IRI + * @param iri to be validated. + */ + def validatePermissionIRI(iri: IRI): Unit = + if (isKnoraPermissionIriStr(iri) && !isUUIDVersion4Or5(iri)) { + throw BadRequestException(UUID_INVALID_ERROR) + } else { + validatePermissionIri(iri, throw BadRequestException(s"Invalid permission IRI ${iri} is given.")) + } /** * Creates a new resource IRI based on a UUID. diff --git a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADM.scala b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADM.scala index fd51cde7f0..99f5829cae 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADM.scala @@ -9,7 +9,7 @@ import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport import org.knora.webapi._ import org.knora.webapi.exceptions.{BadRequestException, ForbiddenException} import org.knora.webapi.feature.FeatureFactoryConfig -import org.knora.webapi.messages.admin.responder.permissionsmessages.PermissionProfileType.Restricted +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectsADMJsonProtocol import org.knora.webapi.messages.admin.responder.usersmessages.UserADM import org.knora.webapi.messages.admin.responder.{KnoraRequestADM, KnoraResponseADM} @@ -37,19 +37,21 @@ case class CreateAdministrativePermissionAPIRequestADM( forGroup: IRI, hasPermissions: Set[PermissionADM] ) extends PermissionsADMJsonProtocol { + implicit protected val sf: StringFormatter = StringFormatter.getInstanceForConstantOntologies + + id match { + case Some(iri) => sf.validatePermissionIRI(iri) + case None => None + } def toJsValue: JsValue = createAdministrativePermissionAPIRequestADMFormat.write(this) - implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies - stringFormatter.validateAndEscapeProjectIri(forProject, throw BadRequestException(s"Invalid project IRI $forProject")) - stringFormatter.validateOptionalPermissionIri( - id, - throw BadRequestException(s"Invalid permission IRI ${id.get} is given.") - ) + sf.validateAndEscapeProjectIri(forProject, throw BadRequestException(s"Invalid project IRI $forProject")) + if (hasPermissions.isEmpty) throw BadRequestException("Permissions needs to be supplied.") if (!OntologyConstants.KnoraAdmin.BuiltInGroups.contains(forGroup)) { - stringFormatter.validateGroupIri(forGroup, throw BadRequestException(s"Invalid group IRI $forGroup")) + sf.validateGroupIri(forGroup, throw BadRequestException(s"Invalid group IRI $forGroup")) } def prepareHasPermissions: CreateAdministrativePermissionAPIRequestADM = @@ -76,14 +78,16 @@ case class CreateDefaultObjectAccessPermissionAPIRequestADM( forProperty: Option[IRI] = None, hasPermissions: Set[PermissionADM] ) extends PermissionsADMJsonProtocol { + implicit protected val sf: StringFormatter = StringFormatter.getInstanceForConstantOntologies + + id match { + case Some(iri) => sf.validatePermissionIRI(iri) + case None => None + } + def toJsValue: JsValue = createDefaultObjectAccessPermissionAPIRequestADMFormat.write(this) - implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies - stringFormatter.validateAndEscapeProjectIri(forProject, throw BadRequestException(s"Invalid project IRI $forProject")) - stringFormatter.validateOptionalPermissionIri( - id, - throw BadRequestException(s"Invalid permission IRI ${id.get} is given.") - ) + sf.validateAndEscapeProjectIri(forProject, throw BadRequestException(s"Invalid project IRI $forProject")) forGroup match { case Some(iri: IRI) => @@ -93,7 +97,7 @@ case class CreateDefaultObjectAccessPermissionAPIRequestADM( throw BadRequestException("Not allowed to supply groupIri and propertyIri together.") else { if (!OntologyConstants.KnoraAdmin.BuiltInGroups.contains(iri)) { - stringFormatter.validateOptionalGroupIri( + sf.validateOptionalGroupIri( forGroup, throw BadRequestException(s"Invalid group IRI ${forGroup.get}") ) @@ -109,7 +113,7 @@ case class CreateDefaultObjectAccessPermissionAPIRequestADM( forResourceClass match { case Some(iri) => - if (!stringFormatter.toSmartIri(iri).isKnoraEntityIri) { + if (!sf.toSmartIri(iri).isKnoraEntityIri) { throw BadRequestException(s"Invalid resource class IRI: $iri") } case None => None @@ -117,7 +121,7 @@ case class CreateDefaultObjectAccessPermissionAPIRequestADM( forProperty match { case Some(iri) => - if (!stringFormatter.toSmartIri(iri).isKnoraEntityIri) { + if (!sf.toSmartIri(iri).isKnoraEntityIri) { throw BadRequestException(s"Invalid property IRI: $iri") } case None => None diff --git a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/GroupsValueObjectsADM.scala b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/GroupsValueObjectsADM.scala index db78324db2..7401a2bff7 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/GroupsValueObjectsADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/GroupsValueObjectsADM.scala @@ -7,6 +7,7 @@ package org.knora.webapi.messages.admin.responder.valueObjects import org.knora.webapi.exceptions.BadRequestException import org.knora.webapi.messages.StringFormatter +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.groupsmessages.GroupsErrorMessagesADM._ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2 import zio.prelude.Validation @@ -22,8 +23,12 @@ object GroupIRI { self => if (value.isEmpty) { Validation.fail(BadRequestException(GROUP_IRI_MISSING_ERROR)) } else { + val isUUID: Boolean = sf.hasUUIDLength(value.split("/").last) + if (!sf.isKnoraGroupIriStr(value)) { Validation.fail(BadRequestException(GROUP_IRI_INVALID_ERROR)) + } else if (isUUID && !sf.isUUIDVersion4Or5(value)) { + Validation.fail(BadRequestException(UUID_INVALID_ERROR)) } else { val validatedValue = Validation( sf.validateAndEscapeIri(value, throw BadRequestException(GROUP_IRI_INVALID_ERROR)) diff --git a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ListsValueObjectsADM.scala b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ListsValueObjectsADM.scala index c9aece684a..8a7181a345 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ListsValueObjectsADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ListsValueObjectsADM.scala @@ -7,7 +7,9 @@ package org.knora.webapi.messages.admin.responder.valueObjects import org.knora.webapi.exceptions.BadRequestException import org.knora.webapi.messages.StringFormatter +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.listsmessages.ListsErrorMessagesADM._ +import org.knora.webapi.messages.admin.responder.valueObjects.GroupIRI.sf import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2 import zio.prelude.Validation @@ -22,8 +24,12 @@ object ListIRI { self => if (value.isEmpty) { Validation.fail(BadRequestException(LIST_NODE_IRI_MISSING_ERROR)) } else { + val isUUID: Boolean = sf.hasUUIDLength(value.split("/").last) + if (!sf.isKnoraListIriStr(value)) { Validation.fail(BadRequestException(LIST_NODE_IRI_INVALID_ERROR)) + } else if (isUUID && !sf.isUUIDVersion4Or5(value)) { + Validation.fail(BadRequestException(UUID_INVALID_ERROR)) } else { val validatedValue = Validation( sf.validateAndEscapeIri(value, throw BadRequestException(LIST_NODE_IRI_INVALID_ERROR)) diff --git a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ProjectsValueObjectsADM.scala b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ProjectsValueObjectsADM.scala index 89f1f6f0b3..1fd75e5525 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ProjectsValueObjectsADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/ProjectsValueObjectsADM.scala @@ -7,7 +7,9 @@ package org.knora.webapi.messages.admin.responder.valueObjects import org.knora.webapi.exceptions.BadRequestException import org.knora.webapi.messages.StringFormatter +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectsErrorMessagesADM._ +import org.knora.webapi.messages.admin.responder.valueObjects.GroupIRI.sf import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2 import zio.prelude.Validation @@ -16,14 +18,18 @@ import zio.prelude.Validation */ sealed abstract case class ProjectIRI private (value: String) object ProjectIRI { self => - val sf: StringFormatter = StringFormatter.getGeneralInstance + private val sf: StringFormatter = StringFormatter.getGeneralInstance def make(value: String): Validation[Throwable, ProjectIRI] = if (value.isEmpty) { Validation.fail(BadRequestException(PROJECT_IRI_MISSING_ERROR)) } else { + val isUUID: Boolean = sf.hasUUIDLength(value.split("/").last) + if (!sf.isKnoraProjectIriStr(value)) { Validation.fail(BadRequestException(PROJECT_IRI_INVALID_ERROR)) + } else if (isUUID && !sf.isUUIDVersion4Or5(value)) { + Validation.fail(BadRequestException(UUID_INVALID_ERROR)) } else { val validatedValue = Validation( sf.validateAndEscapeProjectIri(value, throw BadRequestException(PROJECT_IRI_INVALID_ERROR)) diff --git a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/UsersValueObjectsADM.scala b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/UsersValueObjectsADM.scala index 9cdd5141e4..89084d8e49 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/UsersValueObjectsADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/admin/responder/valueObjects/UsersValueObjectsADM.scala @@ -8,7 +8,9 @@ package org.knora.webapi.messages.admin.responder.valueObjects import org.knora.webapi.LanguageCodes import org.knora.webapi.exceptions.BadRequestException import org.knora.webapi.messages.StringFormatter +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.usersmessages.UsersErrorMessagesADM._ +import org.knora.webapi.messages.admin.responder.valueObjects.GroupIRI.sf import zio.prelude.Validation import scala.util.matching.Regex @@ -24,8 +26,12 @@ object UserIRI { self => if (value.isEmpty) { Validation.fail(BadRequestException(USER_IRI_MISSING_ERROR)) } else { + val isUUID: Boolean = sf.hasUUIDLength(value.split("/").last) + if (!sf.isKnoraUserIriStr(value)) { Validation.fail(BadRequestException(USER_IRI_INVALID_ERROR)) + } else if (isUUID && !sf.isUUIDVersion4Or5(value)) { + Validation.fail(BadRequestException(UUID_INVALID_ERROR)) } else { val validatedValue = Validation( sf.validateAndEscapeUserIri(value, throw BadRequestException(USER_IRI_INVALID_ERROR)) diff --git a/webapi/src/main/scala/org/knora/webapi/messages/util/standoff/XMLToStandoffUtil.scala b/webapi/src/main/scala/org/knora/webapi/messages/util/standoff/XMLToStandoffUtil.scala index 505e9c2d97..ef3cd58ccc 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/util/standoff/XMLToStandoffUtil.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/util/standoff/XMLToStandoffUtil.scala @@ -746,7 +746,7 @@ class XMLToStandoffUtil( case Some(existingUuid) => existingUuid case None => // Otherwise, try to parse the ID as a UUID. - if (stringFormatter.couldBeUuid(id)) { + if (stringFormatter.hasUUIDLength(id)) { stringFormatter.decodeUuid(id) } else { // If the ID doesn't seem to be a UUID, replace it with a random UUID. TODO: this should throw an exception instead. diff --git a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/resourcemessages/ResourceMessagesV2.scala b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/resourcemessages/ResourceMessagesV2.scala index f5f116cf11..d6929f1118 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/resourcemessages/ResourceMessagesV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/resourcemessages/ResourceMessagesV2.scala @@ -15,6 +15,7 @@ import org.knora.webapi._ import org.knora.webapi.exceptions._ import org.knora.webapi.feature.FeatureFactoryConfig import org.knora.webapi.messages.IriConversions._ +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.projectsmessages.{ ProjectADM, ProjectGetRequestADM, @@ -724,12 +725,14 @@ object CreateResourceRequestV2 extends KnoraJsonLDRequestReaderV2[CreateResource requestingUser = requestingUser )).mapTo[ProjectGetResponseADM] - _ = maybeCustomResourceIri.foreach { definedResourceIri => - if (!definedResourceIri.isKnoraResourceIri) { - throw BadRequestException(s"<$definedResourceIri> is not a Knora resource IRI") + _ = maybeCustomResourceIri.foreach { iri => + if (!iri.isKnoraResourceIri) { + throw BadRequestException(s"<$iri> is not a Knora resource IRI") } - if (!definedResourceIri.getProjectCode.contains(projectInfoResponse.project.shortcode)) { + stringFormatter.validateUUIDOfResourceIRI(iri) + + if (!iri.getProjectCode.contains(projectInfoResponse.project.shortcode)) { throw BadRequestException(s"The provided resource IRI does not contain the correct project code") } } @@ -930,6 +933,8 @@ object UpdateResourceMetadataRequestV2 extends KnoraJsonLDRequestReaderV2[Update throw BadRequestException(s"Invalid resource IRI: <$resourceIri>") } + stringFormatter.validateUUIDOfResourceIRI(resourceIri) + val resourceClassIri: SmartIri = jsonLDDocument.requireTypeAsKnoraTypeIri val maybeLastModificationDate: Option[Instant] = jsonLDDocument.maybeDatatypeValueInObject( diff --git a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/valuemessages/ValueMessagesV2.scala b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/valuemessages/ValueMessagesV2.scala index f568b8b8a4..079664e3ae 100644 --- a/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/valuemessages/ValueMessagesV2.scala +++ b/webapi/src/main/scala/org/knora/webapi/messages/v2/responder/valuemessages/ValueMessagesV2.scala @@ -7,7 +7,6 @@ package org.knora.webapi.messages.v2.responder.valuemessages import java.time.Instant import java.util.UUID - import akka.actor.ActorRef import akka.event.LoggingAdapter import akka.http.scaladsl.util.FastFuture @@ -17,6 +16,7 @@ import org.knora.webapi._ import org.knora.webapi.exceptions.{AssertionException, BadRequestException, NotImplementedException, SipiException} import org.knora.webapi.feature.FeatureFactoryConfig import org.knora.webapi.messages.IriConversions._ +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectADM import org.knora.webapi.messages.admin.responder.usersmessages.UserADM import org.knora.webapi.messages.store.sipimessages.{GetFileMetadataRequest, GetFileMetadataResponse} @@ -500,6 +500,13 @@ object DeleteValueRequestV2 extends KnoraJsonLDRequestReaderV2[DeleteValueReques throw BadRequestException(s"Invalid value IRI: <$valueIri>") } + if ( + stringFormatter.hasUUIDLength(valueIri.toString.split("/").last) + && !stringFormatter.isUUIDVersion4Or5(valueIri.toString) + ) { + throw BadRequestException(UUID_INVALID_ERROR) + } + val valueTypeIri: SmartIri = jsonLDObject.requireTypeAsKnoraApiV2ComplexTypeIri val deleteComment: Option[String] = jsonLDObject.maybeStringWithValidation( diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/admin/GroupsADME2ESpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/admin/GroupsADME2ESpec.scala index 55fc0d12e6..b63bdc6758 100644 --- a/webapi/src/test/scala/org/knora/webapi/e2e/admin/GroupsADME2ESpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/e2e/admin/GroupsADME2ESpec.scala @@ -88,7 +88,7 @@ class GroupsADME2ESpec extends E2ESpec(GroupsADME2ESpec.config) with GroupsADMJs } "given a custom Iri" should { - val customGroupIri = "http://rdfh.ch/groups/00FF/3eFYejZEduOCowwXQq5Iqg" + val customGroupIri = "http://rdfh.ch/groups/00FF/gNdJSNYrTDu2lGpPUs94nQ" "create a group with the provided custom IRI " in { val createGroupWithCustomIriRequest: String = s"""{ "id": "$customGroupIri", diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/admin/PermissionsADME2ESpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/admin/PermissionsADME2ESpec.scala index b5ee9a28c6..7b1caf2d4d 100644 --- a/webapi/src/test/scala/org/knora/webapi/e2e/admin/PermissionsADME2ESpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/e2e/admin/PermissionsADME2ESpec.scala @@ -37,9 +37,8 @@ class PermissionsADME2ESpec extends E2ESpec(PermissionsADME2ESpec.config) with T // Collects client test data private val clientTestDataCollector = new ClientTestDataCollector(settings) - private val customDOAPIri = "http://rdfh.ch/permissions/00FF/eIAywlYBJA3a_5yI77UsMQ" + private val customDOAPIri = "http://rdfh.ch/permissions/00FF/zTOK3HlWTLGgTO8ZWVnotg" "The Permissions Route ('admin/permissions')" when { - "getting permissions" should { "return a group's administrative permission" in { @@ -72,7 +71,6 @@ class PermissionsADME2ESpec extends E2ESpec(PermissionsADME2ESpec.config) with T } "return a project's administrative permissions" in { - val projectIri = java.net.URLEncoder.encode(SharedTestDataV1.imagesProjectInfo.id, "utf-8") val request = Get(baseApiUrl + s"/admin/permissions/ap/$projectIri") ~> addCredentials( @@ -98,7 +96,6 @@ class PermissionsADME2ESpec extends E2ESpec(PermissionsADME2ESpec.config) with T } "return a project's default object access permissions" in { - val projectIri = java.net.URLEncoder.encode(SharedTestDataV1.imagesProjectInfo.id, "utf-8") val request = Get(baseApiUrl + s"/admin/permissions/doap/$projectIri") ~> addCredentials( @@ -124,7 +121,6 @@ class PermissionsADME2ESpec extends E2ESpec(PermissionsADME2ESpec.config) with T } "return a project's all permissions" in { - val projectIri = java.net.URLEncoder.encode(SharedTestDataV1.imagesProjectInfo.id, "utf-8") val request = Get(baseApiUrl + s"/admin/permissions/$projectIri") ~> addCredentials( diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala index 6e9560b8d0..9eb18f9e1c 100644 --- a/webapi/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/e2e/admin/ProjectsADME2ESpec.scala @@ -64,9 +64,7 @@ class ProjectsADME2ESpec ) "The Projects Route ('admin/projects')" when { - "used to query for project information" should { - "return all projects" in { val request = Get(baseApiUrl + s"/admin/projects") ~> addCredentials(BasicHttpCredentials(rootEmail, testPass)) val response: HttpResponse = singleAwaitingRequest(request) @@ -182,7 +180,7 @@ class ProjectsADME2ESpec } "given a custom Iri" should { - val customProjectIri: IRI = "http://rdfh.ch/projects/XGze0w7g6P3p3z6tj_SXPQ" + val customProjectIri: IRI = "http://rdfh.ch/projects/wahxssy1TDqPuSk6ee8EdQ" "CREATE a new project with the provided custom Iri" in { val createProjectWithCustomIRIRequest: String = @@ -272,7 +270,6 @@ class ProjectsADME2ESpec } "used to modify project information" should { - val newProjectIri = new MutableTestIri "CREATE a new project and return the project info if the supplied shortname is unique" in { @@ -519,7 +516,6 @@ class ProjectsADME2ESpec } "DELETE a project" in { - val projectIriEncoded = URLEncoder.encode(newProjectIri.get, "utf-8") val request = Delete(baseApiUrl + s"/admin/projects/iri/" + projectIriEncoded) ~> addCredentials( BasicHttpCredentials(rootEmail, testPass) @@ -546,7 +542,6 @@ class ProjectsADME2ESpec } "used to query members [FUNCTIONALITY]" should { - "return all members of a project identified by iri" in { val request = Get(baseApiUrl + s"/admin/projects/iri/$projectIriEnc/members") ~> addCredentials( BasicHttpCredentials(rootEmail, testPass) @@ -642,7 +637,6 @@ class ProjectsADME2ESpec } "used to query members [PERMISSIONS]" should { - "return members of a project to a SystemAdmin" in { val request = Get(baseApiUrl + s"/admin/projects/iri/$projectIriEnc/members") ~> addCredentials( BasicHttpCredentials(rootEmail, testPass) @@ -693,7 +687,6 @@ class ProjectsADME2ESpec } "used to query keywords" should { - "return all unique keywords for all projects" in { val request = Get(baseApiUrl + s"/admin/projects/Keywords") ~> addCredentials(BasicHttpCredentials(rootEmail, testPass)) diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/admin/UsersADME2ESpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/admin/UsersADME2ESpec.scala index 6ef460b565..44e4981c67 100644 --- a/webapi/src/test/scala/org/knora/webapi/e2e/admin/UsersADME2ESpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/e2e/admin/UsersADME2ESpec.scala @@ -76,8 +76,8 @@ class UsersADME2ESpec private val imagesReviewerGroupIri = SharedTestDataADM.imagesReviewerGroup.id private val imagesReviewerGroupIriEnc = java.net.URLEncoder.encode(imagesReviewerGroupIri, "utf-8") - private val customUserIri = "http://rdfh.ch/users/prWbAoyJA7fECqhKwhSUtQ" - private val otherCustomUserIri = "http://rdfh.ch/users/prWbAoyJA7fECqhKohSUtQ" + private val customUserIri = "http://rdfh.ch/users/14pxW-LAQIaGcCRiNCPJcQ" + private val otherCustomUserIri = "http://rdfh.ch/users/v8_12VcJRlGNFCjYzqJ5cA" private val donaldIri = new MutableTestIri private val systemUserIriEncoded = java.net.URLEncoder.encode(KnoraSystemInstances.Users.SystemUser.id, "utf-8") diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/admin/lists/OldListsRouteADMFeatureE2ESpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/admin/lists/OldListsRouteADMFeatureE2ESpec.scala index 7b223752f9..2be095cd46 100644 --- a/webapi/src/test/scala/org/knora/webapi/e2e/admin/lists/OldListsRouteADMFeatureE2ESpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/e2e/admin/lists/OldListsRouteADMFeatureE2ESpec.scala @@ -74,7 +74,7 @@ class OldListsRouteADMFeatureE2ESpec private val treeListInfo: ListRootNodeInfoADM = SharedListsTestDataADM.treeListInfo private val treeListNodes: Seq[ListChildNodeADM] = SharedListsTestDataADM.treeListChildNodes - private val customChildNodeIRI = "http://rdfh.ch/lists/0001/JbKZ-L_i5rTwHlv4dSNp4A" + private val customChildNodeIRI = "http://rdfh.ch/lists/0001/vQgijJZKSqawFooJPyhYkw" def addChildListNodeRequest(parentNodeIri: IRI, name: String, label: String, comment: String): String = s"""{ | "parentNodeIri": "$parentNodeIri", @@ -1140,9 +1140,7 @@ class OldListsRouteADMFeatureE2ESpec } "add flat nodes" ignore {} - "add hierarchical nodes" ignore {} - "change node order" ignore {} } } diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala index f5c2d287c0..97b24ab237 100644 --- a/webapi/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/e2e/v2/ResourcesRouteV2E2ESpec.scala @@ -1154,8 +1154,8 @@ class ResourcesRouteV2E2ESpec extends E2ESpec(ResourcesRouteV2E2ESpec.config) { } "return a DuplicateValueException during resource creation when the supplied resource IRI is not unique" in { - // duplicate resource IRI + val params = s"""{ | "@id" : "$aThingIri", diff --git a/webapi/src/test/scala/org/knora/webapi/e2e/v2/ValuesRouteV2E2ESpec.scala b/webapi/src/test/scala/org/knora/webapi/e2e/v2/ValuesRouteV2E2ESpec.scala index 79150865e8..adeae97d3b 100644 --- a/webapi/src/test/scala/org/knora/webapi/e2e/v2/ValuesRouteV2E2ESpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/e2e/v2/ValuesRouteV2E2ESpec.scala @@ -869,7 +869,6 @@ class ValuesRouteV2E2ESpec extends E2ESpec { } "return a DuplicateValueException during value creation when the supplied value IRI is not unique" in { - // duplicate value IRI val params = s"""{ @@ -3597,7 +3596,7 @@ class ValuesRouteV2E2ESpec extends E2ESpec { val propertyIri: SmartIri = "http://0.0.0.0:3333/ontology/0001/anything/v2#hasInteger".toSmartIri val intValue: Int = 7 val maybeResourceLastModDate: Option[Instant] = getResourceLastModificationDate(resourceIri, anythingUserEmail) - val newValueVersionIri: IRI = s"http://rdfh.ch/0001/a-thing/values/DrXts3Up3DijGriI403nhg" + val newValueVersionIri: IRI = s"http://rdfh.ch/0001/a-thing/values/W8COP_RXRpqVsjW9NL2JYg" val jsonLDEntity = updateIntValueWithCustomNewValueVersionIriRequest( resourceIri = resourceIri, @@ -3635,7 +3634,7 @@ class ValuesRouteV2E2ESpec extends E2ESpec { "not update an integer value with a custom new value version IRI that is the same as the current IRI" in { val resourceIri: IRI = AThing.iri val intValue: Int = 8 - val newValueVersionIri: IRI = s"http://rdfh.ch/0001/a-thing/values/DrXts3Up3DijGriI403nhg" + val newValueVersionIri: IRI = s"http://rdfh.ch/0001/a-thing/values/W8COP_RXRpqVsjW9NL2JYg" val jsonLDEntity = updateIntValueWithCustomNewValueVersionIriRequest( resourceIri = resourceIri, diff --git a/webapi/src/test/scala/org/knora/webapi/messages/StringFormatterSpec.scala b/webapi/src/test/scala/org/knora/webapi/messages/StringFormatterSpec.scala index b9f020299e..1e6a7bf7b7 100644 --- a/webapi/src/test/scala/org/knora/webapi/messages/StringFormatterSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/messages/StringFormatterSpec.scala @@ -7,7 +7,6 @@ package org.knora.webapi.messages import java.time.Instant import java.util.UUID - import org.knora.webapi._ import org.knora.webapi.exceptions.{AssertionException, BadRequestException} import org.knora.webapi.messages.IriConversions._ @@ -795,13 +794,13 @@ class StringFormatterSpec extends CoreSpec() { assert(internalEntityIri.toString == externalEntityIri.toString && !externalEntityIri.isKnoraIri) } - "parse http://rdfh.ch/0000/0123456789abcdef" in { - val dataIri = "http://rdfh.ch/0000/0123456789abcdef".toSmartIri + "parse http://rdfh.ch/0000/Ef9heHjPWDS7dMR_gGax2Q" in { + val dataIri = "http://rdfh.ch/0000/Ef9heHjPWDS7dMR_gGax2Q".toSmartIri assert(dataIri.isKnoraDataIri) } - "parse http://rdfh.ch/0123456789abcdef" in { - val dataIri = "http://rdfh.ch/0123456789abcdef".toSmartIri + "parse http://rdfh.ch/Ef9heHjPWDS7dMR_gGax2Q" in { + val dataIri = "http://rdfh.ch/Ef9heHjPWDS7dMR_gGax2Q".toSmartIri assert(dataIri.isKnoraDataIri) } @@ -1216,7 +1215,6 @@ class StringFormatterSpec extends CoreSpec() { } "The StringFormatter class for User and Project" should { - "validate project IRI" in { stringFormatter.validateAndEscapeProjectIri( SharedTestDataADM.incunabulaProject.id, @@ -1296,7 +1294,6 @@ class StringFormatterSpec extends CoreSpec() { } "validate username" in { - // 4 - 50 characters long an[AssertionException] should be thrownBy { stringFormatter.validateAndEscapeUsername("abc", throw AssertionException("not valid")) @@ -1345,7 +1342,6 @@ class StringFormatterSpec extends CoreSpec() { } "validate email" in { - stringFormatter.validateEmailAndThrow("donald.duck@example.com", throw AssertionException("not valid")) should be( "donald.duck@example.com" ) @@ -1361,5 +1357,30 @@ class StringFormatterSpec extends CoreSpec() { val base4DecodedUuid = stringFormatter.base64DecodeUuid(base64EncodedUuid) uuid should be(base4DecodedUuid) } + + "return TRUE if IRI contains UUID version 4 or 5, otherwise return FALSE" in { + val iri3 = "http://rdfh.ch/0000/rKAU0FNjPUKWqOT8MEW_UQ" + val iri4 = "http://rdfh.ch/0001/cmfk1DMHRBiR4-_6HXpEFA" + val iri5 = "http://rdfh.ch/080C/Ef9heHjPWDS7dMR_gGax2Q" + + val testIRIFromVersion3UUID = stringFormatter.isUUIDVersion4Or5(iri3) + val testIRIFromVersion4UUID = stringFormatter.isUUIDVersion4Or5(iri4) + val testIRIFromVersion5UUID = stringFormatter.isUUIDVersion4Or5(iri5) + + val iri = "http://rdfh.ch/0001/rYAMw7wSTbGw3boYHefByg" + + println( + 777, + stringFormatter.makeRandomBase64EncodedUuid, + stringFormatter.makeRandomBase64EncodedUuid, + stringFormatter.getUUIDVersion(iri), + stringFormatter.hasUUIDLength(iri.split("/").last), + stringFormatter.isUUIDVersion4Or5(iri) + ) + + testIRIFromVersion3UUID should be(false) + testIRIFromVersion4UUID should be(true) + testIRIFromVersion5UUID should be(true) + } } } diff --git a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADMSpec.scala index 31f1413f65..e18f458810 100644 --- a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADMSpec.scala @@ -11,6 +11,7 @@ import org.knora.webapi.exceptions.{BadRequestException, ForbiddenException} import org.knora.webapi.messages.OntologyConstants import org.knora.webapi.messages.OntologyConstants.KnoraAdmin.AdministrativePermissionAbbreviations import org.knora.webapi.messages.OntologyConstants.KnoraBase.EntityPermissionAbbreviations +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.permissionsmessages.PermissionsMessagesUtilADM.PermissionTypeAndCodes import org.knora.webapi.sharedtestdata.SharedOntologyTestDataADM._ import org.knora.webapi.sharedtestdata.SharedTestDataV1._ @@ -145,6 +146,24 @@ class PermissionsMessagesADMSpec extends CoreSpec() { assert(caught.getMessage === s"Invalid permission IRI $permissionIri is given.") } + "throw 'BadRequest' for AdministrativePermissionCreateRequestADM if the supplied permission IRI contains bad UUID version" in { + val permissionIRIWithUUIDVersion3 = "http://rdfh.ch/permissions/0001/Ul3IYhDMOQ2fyoVY0ePz0w" + val caught = intercept[BadRequestException]( + AdministrativePermissionCreateRequestADM( + createRequest = CreateAdministrativePermissionAPIRequestADM( + id = Some(permissionIRIWithUUIDVersion3), + forProject = SharedTestDataADM.IMAGES_PROJECT_IRI, + forGroup = OntologyConstants.KnoraAdmin.ProjectMember, + hasPermissions = Set(PermissionADM.ProjectAdminAllPermission) + ).prepareHasPermissions, + featureFactoryConfig = defaultFeatureFactoryConfig, + requestingUser = SharedTestDataADM.imagesUser01, + apiRequestID = UUID.randomUUID() + ) + ) + assert(caught.getMessage === UUID_INVALID_ERROR) + } + "return 'BadRequest' if the no permissions supplied for AdministrativePermissionCreateRequestADM" in { val invalidName = "Delete" val hasPermissions = Set( @@ -524,6 +543,24 @@ class PermissionsMessagesADMSpec extends CoreSpec() { assert(caught.getMessage === s"Invalid permission IRI $permissionIri is given.") } + "throw 'BadRequest' for DefaultObjectAccessPermissionCreateRequestADM if the supplied permission IRI contains bad UUID version" in { + val permissionIRIWithUUIDVersion3 = "http://rdfh.ch/permissions/0001/Ul3IYhDMOQ2fyoVY0ePz0w" + val caught = intercept[BadRequestException]( + DefaultObjectAccessPermissionCreateRequestADM( + createRequest = CreateDefaultObjectAccessPermissionAPIRequestADM( + id = Some(permissionIRIWithUUIDVersion3), + forProject = SharedTestDataADM.ANYTHING_PROJECT_IRI, + forGroup = Some(OntologyConstants.KnoraAdmin.ProjectMember), + hasPermissions = Set(PermissionADM.changeRightsPermission(OntologyConstants.KnoraAdmin.ProjectMember)) + ).prepareHasPermissions, + featureFactoryConfig = defaultFeatureFactoryConfig, + requestingUser = SharedTestDataADM.imagesUser01, + apiRequestID = UUID.randomUUID() + ) + ) + assert(caught.getMessage === UUID_INVALID_ERROR) + } + "return 'BadRequest' if the no permissions supplied for DefaultObjectAccessPermissionCreateRequestADM" in { val caught = intercept[BadRequestException]( DefaultObjectAccessPermissionCreateRequestADM( diff --git a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/GroupsValueObjectsADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/GroupsValueObjectsADMSpec.scala index f9c9664a8c..2f3d3a33bd 100644 --- a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/GroupsValueObjectsADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/GroupsValueObjectsADMSpec.scala @@ -7,6 +7,7 @@ package org.knora.webapi.messages.admin.responder.valueObjects import org.knora.webapi.UnitSpec import org.knora.webapi.exceptions.BadRequestException +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.groupsmessages.GroupsErrorMessagesADM._ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2 import zio.prelude.Validation @@ -17,6 +18,7 @@ import zio.prelude.Validation class GroupsValueObjectsADMSpec extends UnitSpec(ValueObjectsADMSpec.config) { "GroupIRI value object" when { val validGroupIri = "http://rdfh.ch/groups/0803/qBCJAdzZSCqC_2snW5Q7Nw" + val groupIRIWithUUIDVersion3 = "http://rdfh.ch/groups/0803/rKAU0FNjPUKWqOT8MEW_UQ" "created using empty value" should { "throw BadRequestException" in { @@ -26,6 +28,9 @@ class GroupsValueObjectsADMSpec extends UnitSpec(ValueObjectsADMSpec.config) { "created using invalid value" should { "throw BadRequestException" in { GroupIRI.make("not a group IRI") should equal(Validation.fail(BadRequestException(GROUP_IRI_INVALID_ERROR))) + GroupIRI.make(groupIRIWithUUIDVersion3) should equal( + Validation.fail(BadRequestException(UUID_INVALID_ERROR)) + ) } } "created using valid value" should { diff --git a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/ListsValueObjectsADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/ListsValueObjectsADMSpec.scala index c89ac6941e..740d5c8ef5 100644 --- a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/ListsValueObjectsADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/ListsValueObjectsADMSpec.scala @@ -7,6 +7,7 @@ package org.knora.webapi.messages.admin.responder.valueObjects import org.knora.webapi.UnitSpec import org.knora.webapi.exceptions.BadRequestException +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.listsmessages.ListsErrorMessagesADM._ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2 import zio.prelude.Validation @@ -17,6 +18,7 @@ import zio.prelude.Validation class ListsValueObjectsADMSpec extends UnitSpec(ValueObjectsADMSpec.config) { "ListIRI value object" when { val validListIri = "http://rdfh.ch/lists/0803/qBCJAdzZSCqC_2snW5Q7Nw" + val listIRIWithUUIDVersion3 = "http://rdfh.ch/lists/0803/6_xROK_UN1S2ZVNSzLlSXQ" "created using empty value" should { "throw BadRequestException" in { @@ -26,6 +28,7 @@ class ListsValueObjectsADMSpec extends UnitSpec(ValueObjectsADMSpec.config) { "created using invalid value" should { "throw BadRequestException" in { ListIRI.make("not a list IRI") should equal(Validation.fail(BadRequestException(LIST_NODE_IRI_INVALID_ERROR))) + ListIRI.make(listIRIWithUUIDVersion3) should equal(Validation.fail(BadRequestException(UUID_INVALID_ERROR))) } } "created using valid value" should { diff --git a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/ProjectsValueObjectsADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/ProjectsValueObjectsADMSpec.scala index e078190801..f233eafad5 100644 --- a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/ProjectsValueObjectsADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/ProjectsValueObjectsADMSpec.scala @@ -7,6 +7,7 @@ package org.knora.webapi.messages.admin.responder.valueObjects import org.knora.webapi.UnitSpec import org.knora.webapi.exceptions.BadRequestException +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectsErrorMessagesADM._ import org.knora.webapi.messages.store.triplestoremessages.StringLiteralV2 import zio.prelude.Validation @@ -17,6 +18,7 @@ import zio.prelude.Validation class ProjectsValueObjectsADMSpec extends UnitSpec(ValueObjectsADMSpec.config) { "ProjectIRI value object" when { val validProjectIri = "http://rdfh.ch/projects/0001" + val projectIRIWithUUIDVersion3 = "http://rdfh.ch/projects/tZjZhGSZMeCLA5VeUmwAmg" "created using empty value" should { "throw BadRequestException" in { @@ -28,6 +30,9 @@ class ProjectsValueObjectsADMSpec extends UnitSpec(ValueObjectsADMSpec.config) { ProjectIRI.make("not a project IRI") should equal( Validation.fail(BadRequestException(PROJECT_IRI_INVALID_ERROR)) ) + ProjectIRI.make(projectIRIWithUUIDVersion3) should equal( + Validation.fail(BadRequestException(UUID_INVALID_ERROR)) + ) } } "created using valid value" should { @@ -38,9 +43,6 @@ class ProjectsValueObjectsADMSpec extends UnitSpec(ValueObjectsADMSpec.config) { } "return value passed to value object" in { ProjectIRI.make(validProjectIri).toOption.get.value should equal(validProjectIri) - ProjectIRI.make(validProjectIri) should not equal Validation.fail( - BadRequestException(PROJECT_IRI_INVALID_ERROR) - ) } } } diff --git a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/UsersValueObjectsADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/UsersValueObjectsADMSpec.scala index e7c7d35af6..2cb994a0c5 100644 --- a/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/UsersValueObjectsADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/messages/admin/responder/valueObjects/UsersValueObjectsADMSpec.scala @@ -7,6 +7,7 @@ package org.knora.webapi.messages.admin.responder.valueObjects import org.knora.webapi.UnitSpec import org.knora.webapi.exceptions.BadRequestException +import org.knora.webapi.messages.StringFormatter.UUID_INVALID_ERROR import org.knora.webapi.messages.admin.responder.usersmessages.UsersErrorMessagesADM._ import zio.prelude.Validation @@ -16,6 +17,7 @@ import zio.prelude.Validation class UsersValueObjectsADMSpec extends UnitSpec(ValueObjectsADMSpec.config) { "UserIRI value object" when { val validUserIRI = "http://rdfh.ch/users/jDEEitJESRi3pDaDjjQ1WQ" + val userIRIWithUUIDVersion3 = "http://rdfh.ch/users/cCmdcpn2MO211YYOplR1hQ" "created using empty value" should { "throw BadRequestException" in { @@ -25,6 +27,7 @@ class UsersValueObjectsADMSpec extends UnitSpec(ValueObjectsADMSpec.config) { "created using invalid value" should { "throw BadRequestException" in { UserIRI.make("not a user IRI") should equal(Validation.fail(BadRequestException(USER_IRI_INVALID_ERROR))) + UserIRI.make(userIRIWithUUIDVersion3) should equal(Validation.fail(BadRequestException(UUID_INVALID_ERROR))) } } "created using valid value" should { diff --git a/webapi/src/test/scala/org/knora/webapi/responders/admin/PermissionsResponderADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/responders/admin/PermissionsResponderADMSpec.scala index 40ea122a07..3c55c6106c 100644 --- a/webapi/src/test/scala/org/knora/webapi/responders/admin/PermissionsResponderADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/responders/admin/PermissionsResponderADMSpec.scala @@ -248,7 +248,7 @@ class PermissionsResponderADMSpec } "create and return an administrative permission with a custom IRI" in { - val customIri = "http://rdfh.ch/permissions/0001/YCHszszUkzmZp5YURnmBDA" + val customIri = "http://rdfh.ch/permissions/0001/24RD7QcoTKqEJKrDBE885Q" responderManager ! AdministrativePermissionCreateRequestADM( createRequest = CreateAdministrativePermissionAPIRequestADM( id = Some(customIri), @@ -268,7 +268,7 @@ class PermissionsResponderADMSpec } "create and return an administrative permission even if irrelevant values were given for name and code of its permission" in { - val customIri = "http://rdfh.ch/permissions/0001/cEVBtj2JpzsdJQBJN1J-vg" + val customIri = "http://rdfh.ch/permissions/0001/0pd-VUDeShWNJ2Nq3fGGGQ" val hasPermissions = Set( PermissionADM( name = OntologyConstants.KnoraAdmin.ProjectResourceCreateAllPermission, @@ -479,7 +479,7 @@ class PermissionsResponderADMSpec } "create a DefaultObjectAccessPermission for project and group with custom IRI" in { - val customIri = "http://rdfh.ch/permissions/0001/mnL_QA0D06zkE7p9LMqBCA" + val customIri = "http://rdfh.ch/permissions/0001/4PnSvolsTEa86KJ2EG76SQ" responderManager ! DefaultObjectAccessPermissionCreateRequestADM( createRequest = CreateDefaultObjectAccessPermissionAPIRequestADM( id = Some(customIri), diff --git a/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala b/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala index 0ac7cbb1d6..efd4796029 100644 --- a/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala +++ b/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedTestDataADM.scala @@ -477,8 +477,8 @@ object SharedTestDataADM { */ val ANYTHING_PROJECT_IRI = "http://rdfh.ch/projects/0001" - val customResourceIRI: IRI = "http://rdfh.ch/0001/aUrDPcJRmFNzBHW_AlR1hw" - val customResourceIRI_resourceWithValues: IRI = "http://rdfh.ch/0001/5zCt1EMJKezFUOW_RCB0Gw" + val customResourceIRI: IRI = "http://rdfh.ch/0001/rYAMw7wSTbGw3boYHefByg" + val customResourceIRI_resourceWithValues: IRI = "http://rdfh.ch/0001/4PnSvolsTEa86KJ2EG76SQ" val customValueIRI_withResourceIriAndValueIRIAndValueUUID: IRI = "http://rdfh.ch/0001/5zCt1EMJKezFUOW_RCB0Gw/values/fdqCOaqT6dP19pWI84X1XQ" val customValueUUID = "fdqCOaqT6dP19pWI84X1XQ" @@ -486,7 +486,7 @@ object SharedTestDataADM { val customResourceCreationDate: Instant = Instant.parse("2019-01-09T15:45:54.502951Z") val customValueCreationDate: Instant = Instant.parse("2020-06-09T17:04:54.502951Z") - val customListIRI: IRI = "http://rdfh.ch/lists/0001/WYHQu7y6BGrTBcnRtg76Tg" + val customListIRI: IRI = "http://rdfh.ch/lists/0001/qq54wdGKR0S5zsbR5-9wtg" def anythingAdminUser: UserADM = UserADM(