diff --git a/docs/03-apis/api-admin/permissions.md b/docs/03-apis/api-admin/permissions.md index 0581183b3b..e5f3603b13 100644 --- a/docs/03-apis/api-admin/permissions.md +++ b/docs/03-apis/api-admin/permissions.md @@ -79,6 +79,10 @@ As a response, the created administrative permission and its IRI are returned as } } ``` +Note that during the creation of a new project, a default set of administrative permissions are added to its ProjectAdmin and +ProjectMember groups (See [Default set of permissions for a new project](./projects.md#default-set-of-permissions-for-a-new-project)). +Therefore, it is not possible to create new administrative permissions for the ProjectAdmin and ProjectMember groups of +a project. However, the default permissions set for these groups can be modified (See [update permission](./permissions.md#updating-a-permissions-scope)). - `POST: /admin/permissions/doap` : create a new default object access permission. A single instance of `knora-admin:DefaultObjectAccessPermission` must @@ -133,6 +137,10 @@ The response contains the newly created permission and its IRI, as: } } ``` +Note that during the creation of a new project, a set of default object access permissions are created for its +ProjectAdmin and ProjectMember groups (See [Default set of permissions for a new project](./projects.md#default-set-of-permissions-for-a-new-project)). +Therefore, it is not possible to create new default object access permissions for the ProjectAdmin and ProjectMember +groups of a project. However, the default permissions set for these groups can be modified; see below for more information. ### Updating a Permission's Group: - `PUT: /admin/permissions//group` to change the group for which an administrative or a default object @@ -183,4 +191,9 @@ updating a default object acceess permission. The IRI of the new property must b ``` Note that if the default object access permission was originally defined for a group, with this operation, the permission will be defined for the given property instead of the group. That means the value of the `forGroup` will -be deleted. \ No newline at end of file +be deleted. + +### Deleting a permission: +- `DELETE: /admin/permissions/` to delete an administrative, or a default object access permission. The +IRI of the permission must be given in encoded form. + diff --git a/docs/03-apis/api-admin/projects.md b/docs/03-apis/api-admin/projects.md index 01d70bc969..ce1f24052f 100644 --- a/docs/03-apis/api-admin/projects.md +++ b/docs/03-apis/api-admin/projects.md @@ -100,6 +100,24 @@ Additionally, each project can have an optional custom IRI (of [Knora IRI](../ap "selfjoin": false } ``` +#### Default set of permissions for a new project: +When a new project is created, following default permissions are added to its admins and members: +- ProjectAdmin group receives an administrative permission to do all project level operations and to create resources +within the new project. This administrative permission is retrievable through its IRI: +`http://rdfh.ch/permissions/[projectShortcode]/defaultApForAdmin` + +ProjectAdmin group also gets a default object access permission to change rights, delete, modify, view, +and restricted view of any entity that belongs to the project. This default object access permission is retrievable +through its IRI: +`http://rdfh.ch/permissions/[projectShortcode]/defaultDoapForAdmin` + +- ProjectMember group receives an administrative permission to create resources within the new project. This +administrative permission is retrievable through its IRI: +`http://rdfh.ch/permissions/[projectShortcode]/defaultApForMember` + +ProjectMember group also gets a default object access permission to modify, view, and restricted view of any entity that +belongs to the project. This default object access permission is retrievable through its IRI: +`http://rdfh.ch/permissions/[projectShortcode]/defaultDoapForMember` ### Update project information: diff --git a/test_data/all_data/permissions-data.ttl b/test_data/all_data/permissions-data.ttl index efcfb9bdc2..4a73b4093f 100644 --- a/test_data/all_data/permissions-data.ttl +++ b/test_data/all_data/permissions-data.ttl @@ -132,7 +132,7 @@ knora-base:hasPermissions "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser"^^xsd:string . -### Default Object Access Permissions on ProjectMember Group +### Default Object Access Permissions on KnownUser Group rdf:type knora-admin:DefaultObjectAccessPermission ; @@ -210,6 +210,28 @@ knora-base:hasPermissions "CR knora-admin:Creator|M knora-admin:ProjectMember|V knora-admin:KnownUser|RV knora-admin:UnknownUser"^^xsd:string . +### Default Object Access Permissions on incunabula:partOfValue property + + + rdf:type knora-admin:DefaultObjectAccessPermission ; + + knora-admin:forProject ; + + knora-admin:forProperty incunabula:partOfValue ; + + knora-base:hasPermissions "V knora-admin:KnownUser|RV knora-admin:UnknownUser"^^xsd:string . + + +### Default Object Access Permissions on incunabula:partOfValue property + + + rdf:type knora-admin:DefaultObjectAccessPermission ; + + knora-admin:forProject ; + knora-admin:forResourceClass incunabula:page ; + knora-admin:forProperty incunabula:partOfValue ; + + knora-base:hasPermissions "M knora-admin:ProjectMember"^^xsd:string . ########################################################## # diff --git a/webapi/src/main/scala/org/knora/webapi/responders/admin/PermissionsResponderADM.scala b/webapi/src/main/scala/org/knora/webapi/responders/admin/PermissionsResponderADM.scala index 01d294017d..ee38d4614e 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/admin/PermissionsResponderADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/admin/PermissionsResponderADM.scala @@ -613,16 +613,19 @@ class PermissionsResponderADM(responderData: ResponderData) extends Responder(re for { // does the permission already exist - checkResult <- administrativePermissionForProjectGroupGetADM( + checkResult: Option[AdministrativePermissionADM] <- administrativePermissionForProjectGroupGetADM( createRequest.forProject, createRequest.forGroup, requestingUser = KnoraSystemInstances.Users.SystemUser ) _ = checkResult match { - case Some(ap) => + case Some(ap: AdministrativePermissionADM) => throw DuplicateValueException( - s"Permission for project: '${createRequest.forProject}' and group: '${createRequest.forGroup}' combination already exists.") + s"An administrative permission for project: '${createRequest.forProject}' and group: '${createRequest.forGroup}' combination already exists. " + + s"This permission currently has the scope '${PermissionUtilADM + .formatPermissionADMs(ap.hasPermissions, PermissionType.AP)}'. " + + s"Use its IRI ${ap.iri} to modify it, if necessary.") case None => () } @@ -653,6 +656,7 @@ class PermissionsResponderADM(responderData: ResponderData) extends Responder(re throw NotFoundException(s"Group '${createRequest.forGroup}' not found. Aborting request.")) } yield group.id } + customPermissionIri: Option[SmartIri] = createRequest.id.map(iri => iri.toSmartIri) newPermissionIri: IRI <- checkOrCreateEntityIri(customPermissionIri, stringFormatter.makeRandomPermissionIri(project.shortcode)) @@ -1445,8 +1449,25 @@ class PermissionsResponderADM(responderData: ResponderData) extends Responder(re createRequest.forProperty) _ = checkResult match { - case Some(doap) => throw DuplicateValueException(s"Default object access permission already exists.") - case None => () + case Some(doap: DefaultObjectAccessPermissionADM) => + val errorMessage = if (doap.forGroup.nonEmpty) { + s"and group: '${doap.forGroup.get}' " + } else { + val resourceClassExists = if (doap.forResourceClass.nonEmpty) { + s"and resourceClass: '${doap.forResourceClass.get}' " + } else "" + val propExists = if (doap.forProperty.nonEmpty) { + s"and property: '${doap.forProperty.get}' " + } else "" + resourceClassExists + propExists + } + throw DuplicateValueException( + s"A default object access permission for project: '${createRequest.forProject}' " + + errorMessage + "combination already exists. " + + s"This permission currently has the scope '${PermissionUtilADM + .formatPermissionADMs(doap.hasPermissions, PermissionType.OAP)}'. " + + s"Use its IRI ${doap.iri} to modify it, if necessary.") + case None => () } // get project diff --git a/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala b/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala index 4c47a70727..29d744c599 100644 --- a/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala +++ b/webapi/src/main/scala/org/knora/webapi/responders/admin/ProjectsResponderADM.scala @@ -31,6 +31,7 @@ import org.knora.webapi.exceptions._ import org.knora.webapi.feature.FeatureFactoryConfig import org.knora.webapi.instrumentation.InstrumentationSupport import org.knora.webapi.messages.IriConversions._ +import org.knora.webapi.messages.StringFormatter.IriDomain import org.knora.webapi.messages.admin.responder.projectsmessages._ import org.knora.webapi.messages.admin.responder.usersmessages.{ UserADM, @@ -38,6 +39,8 @@ import org.knora.webapi.messages.admin.responder.usersmessages.{ UserIdentifierADM, UserInformationTypeADM } +import org.knora.webapi.messages.admin.responder.permissionsmessages._ + import org.knora.webapi.messages.store.cacheservicemessages.{ CacheServiceGetProjectADM, CacheServicePutProjectADM, @@ -968,6 +971,84 @@ class ProjectsResponderADM(responderData: ResponderData) extends Responder(respo requestingUser: UserADM, apiRequestID: UUID): Future[ProjectOperationResponseADM] = { + /** + * Creates following permissions for the new project + * 1. Permissions for project admins to do all operations on project level and to create, modify, delete, change rights, + * view, and restricted view of all new resources and values that belong to this project. + * 2. Permissions for project members to create, modify, view and restricted view of all new resources and values that belong to this project. + * + * @param projectIri the IRI of the new project. + * @throws BadRequestException if a permission is not created. + */ + def createPermissionsForAdminsAndMembersOfNewProject(projectIri: IRI, projectShortCode: String): Future[Unit] = + for { + baseIri: String <- Future.successful(s"http://$IriDomain/permissions/$projectShortCode/") + // Give the admins of the new project rights for any operation in project level, and rights to create resources. + apPermissionForProjectAdmin: AdministrativePermissionCreateResponseADM <- (responderManager ? AdministrativePermissionCreateRequestADM( + createRequest = CreateAdministrativePermissionAPIRequestADM( + id = Some(baseIri + "defaultApForAdmin"), + forProject = projectIri, + forGroup = OntologyConstants.KnoraAdmin.ProjectAdmin, + hasPermissions = + Set(PermissionADM.ProjectAdminAllPermission, PermissionADM.ProjectResourceCreateAllPermission) + ), + featureFactoryConfig = featureFactoryConfig, + requestingUser = requestingUser, + apiRequestID = UUID.randomUUID() + )).mapTo[AdministrativePermissionCreateResponseADM] + + // Give the members of the new project rights to create resources. + apPermissionForProjectMember: AdministrativePermissionCreateResponseADM <- (responderManager ? AdministrativePermissionCreateRequestADM( + createRequest = CreateAdministrativePermissionAPIRequestADM( + id = Some(baseIri + "defaultApForMember"), + forProject = projectIri, + forGroup = OntologyConstants.KnoraAdmin.ProjectMember, + hasPermissions = Set(PermissionADM.ProjectResourceCreateAllPermission) + ), + featureFactoryConfig = featureFactoryConfig, + requestingUser = requestingUser, + apiRequestID = UUID.randomUUID() + )).mapTo[AdministrativePermissionCreateResponseADM] + + // Give the admins of the new project rights to change rights, modify, delete, view, + // and restricted view of all resources and values that belong to the project. + doapForProjectAdmin <- (responderManager ? DefaultObjectAccessPermissionCreateRequestADM( + createRequest = CreateDefaultObjectAccessPermissionAPIRequestADM( + id = Some(baseIri + "defaultDoapForAdmin"), + forProject = projectIri, + forGroup = Some(OntologyConstants.KnoraAdmin.ProjectAdmin), + hasPermissions = Set( + PermissionADM.changeRightsPermission(OntologyConstants.KnoraAdmin.ProjectAdmin), + PermissionADM.deletePermission(OntologyConstants.KnoraAdmin.ProjectAdmin), + PermissionADM.modifyPermission(OntologyConstants.KnoraAdmin.ProjectAdmin), + PermissionADM.viewPermission(OntologyConstants.KnoraAdmin.ProjectAdmin), + PermissionADM.restrictedViewPermission(OntologyConstants.KnoraAdmin.ProjectAdmin) + ) + ), + featureFactoryConfig = featureFactoryConfig, + requestingUser = requestingUser, + apiRequestID = UUID.randomUUID() + )).mapTo[DefaultObjectAccessPermissionCreateResponseADM] + + // Give the members of the new project rights to modify, view, and restricted view of all resources and values + // that belong to the project. + doapForProjectMember <- (responderManager ? DefaultObjectAccessPermissionCreateRequestADM( + createRequest = CreateDefaultObjectAccessPermissionAPIRequestADM( + id = Some(baseIri + "defaultDoapForMember"), + forProject = projectIri, + forGroup = Some(OntologyConstants.KnoraAdmin.ProjectMember), + hasPermissions = Set( + PermissionADM.modifyPermission(OntologyConstants.KnoraAdmin.ProjectMember), + PermissionADM.viewPermission(OntologyConstants.KnoraAdmin.ProjectMember), + PermissionADM.restrictedViewPermission(OntologyConstants.KnoraAdmin.ProjectMember) + ) + ), + featureFactoryConfig = featureFactoryConfig, + requestingUser = requestingUser, + apiRequestID = UUID.randomUUID() + )).mapTo[DefaultObjectAccessPermissionCreateResponseADM] + } yield () + def projectCreateTask(createProjectRequest: CreateProjectApiRequestADM, requestingUser: UserADM): Future[ProjectOperationResponseADM] = for { @@ -1044,6 +1125,8 @@ class ProjectsResponderADM(responderData: ResponderData) extends Responder(respo throw UpdateNotPerformedException( s"Project $newProjectIRI was not created. Please report this as a possible bug.") ) + // create permissions for admins and members of the new group + _ <- createPermissionsForAdminsAndMembersOfNewProject(newProjectIRI, newProjectADM.shortcode) } yield ProjectOperationResponseADM(project = newProjectADM) 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 78a8737852..4462299df7 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 @@ -288,9 +288,9 @@ class PermissionsADME2ESpec extends E2ESpec(PermissionsADME2ESpec.config) with T val permissionPayload = s"""{ - | "forGroup":"http://www.knora.org/ontology/knora-admin#ProjectMember", + | "forGroup":"http://www.knora.org/ontology/knora-admin#KnownUser", | "forProject":"$projectIri", - | "hasPermissions":[{"additionalInformation":null,"name":"ProjectAdminGroupAllPermission","permissionCode":null}] + | "hasPermissions":[{"additionalInformation":null,"name":"ProjectResourceCreateAllPermission","permissionCode":null}] |}""".stripMargin val permissionRequest = Post(baseApiUrl + s"/admin/permissions/ap", 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 c47e1b85be..ea1949f689 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 @@ -28,7 +28,7 @@ import org.knora.webapi._ import org.knora.webapi.exceptions.{BadRequestException, DuplicateValueException, ForbiddenException, NotFoundException} import org.knora.webapi.messages.admin.responder.permissionsmessages._ import org.knora.webapi.messages.store.triplestoremessages.RdfDataObject -import org.knora.webapi.messages.util.KnoraSystemInstances +import org.knora.webapi.messages.util.{KnoraSystemInstances, PermissionUtilADM} import org.knora.webapi.messages.{OntologyConstants, StringFormatter} import org.knora.webapi.sharedtestdata.SharedPermissionsTestData._ import org.knora.webapi.sharedtestdata.{SharedOntologyTestDataADM, SharedTestDataADM, SharedTestDataV1} @@ -241,7 +241,10 @@ class PermissionsResponderADMSpec apiRequestID = UUID.randomUUID() ) expectMsg(Failure(DuplicateValueException( - s"Permission for project: '${SharedTestDataADM.IMAGES_PROJECT_IRI}' and group: '${OntologyConstants.KnoraAdmin.ProjectMember}' combination already exists."))) + s"An administrative permission for project: '${SharedTestDataADM.IMAGES_PROJECT_IRI}' and group: '${OntologyConstants.KnoraAdmin.ProjectMember}' combination already exists. " + + s"This permission currently has the scope '${PermissionUtilADM + .formatPermissionADMs(perm002_a1.p.hasPermissions, PermissionType.AP)}'. " + + s"Use its IRI ${perm002_a1.iri} to modify it, if necessary."))) } "create and return an administrative permission with a custom IRI" in { @@ -492,7 +495,7 @@ class PermissionsResponderADMSpec .contains(PermissionADM.changeRightsPermission(OntologyConstants.KnoraAdmin.Creator))) } - "fail and return a 'DuplicateValueException' when permission for project / group / resource class / property combination already exists" in { + "fail and return a 'DuplicateValueException' when a doap permission for project and group combination already exists" in { responderManager ! DefaultObjectAccessPermissionCreateRequestADM( createRequest = CreateDefaultObjectAccessPermissionAPIRequestADM( forProject = SharedTestDataV1.INCUNABULA_PROJECT_IRI, @@ -503,7 +506,80 @@ class PermissionsResponderADMSpec requestingUser = rootUser, apiRequestID = UUID.randomUUID() ) - expectMsg(Failure(DuplicateValueException(s"Default object access permission already exists."))) + expectMsg(Failure(DuplicateValueException( + s"A default object access permission for project: '${SharedTestDataV1.INCUNABULA_PROJECT_IRI}' and group: '${OntologyConstants.KnoraAdmin.ProjectMember}' " + + "combination already exists. " + + s"This permission currently has the scope '${PermissionUtilADM + .formatPermissionADMs(perm003_d1.p.hasPermissions, PermissionType.OAP)}'. " + + s"Use its IRI ${perm003_d1.iri} to modify it, if necessary."))) + } + + "fail and return a 'DuplicateValueException' when a doap permission for project and resourceClass combination already exists" in { + responderManager ! DefaultObjectAccessPermissionCreateRequestADM( + createRequest = CreateDefaultObjectAccessPermissionAPIRequestADM( + forProject = SharedTestDataV1.INCUNABULA_PROJECT_IRI, + forResourceClass = Some(SharedOntologyTestDataADM.INCUNABULA_BOOK_RESOURCE_CLASS), + hasPermissions = Set( + PermissionADM.changeRightsPermission(OntologyConstants.KnoraAdmin.Creator), + PermissionADM.modifyPermission(OntologyConstants.KnoraAdmin.ProjectMember) + ) + ), + featureFactoryConfig = defaultFeatureFactoryConfig, + requestingUser = rootUser, + apiRequestID = UUID.randomUUID() + ) + expectMsg(Failure(DuplicateValueException( + s"A default object access permission for project: '${SharedTestDataV1.INCUNABULA_PROJECT_IRI}' and resourceClass: '${SharedOntologyTestDataADM.INCUNABULA_BOOK_RESOURCE_CLASS}' " + + "combination already exists. " + + s"This permission currently has the scope '${PermissionUtilADM + .formatPermissionADMs(perm003_d2.p.hasPermissions, PermissionType.OAP)}'. " + + s"Use its IRI ${perm003_d2.iri} to modify it, if necessary."))) + } + + "fail and return a 'DuplicateValueException' when a doap permission for project and property combination already exists" in { + responderManager ! DefaultObjectAccessPermissionCreateRequestADM( + createRequest = CreateDefaultObjectAccessPermissionAPIRequestADM( + forProject = SharedTestDataV1.INCUNABULA_PROJECT_IRI, + forProperty = Some(SharedOntologyTestDataADM.INCUNABULA_PartOf_Property), + hasPermissions = Set( + PermissionADM.modifyPermission(OntologyConstants.KnoraAdmin.KnownUser) + ) + ), + featureFactoryConfig = defaultFeatureFactoryConfig, + requestingUser = rootUser, + apiRequestID = UUID.randomUUID() + ) + expectMsg(Failure(DuplicateValueException( + s"A default object access permission for project: '${SharedTestDataV1.INCUNABULA_PROJECT_IRI}' and property: '${SharedOntologyTestDataADM.INCUNABULA_PartOf_Property}' " + + "combination already exists. " + + s"This permission currently has the scope '${PermissionUtilADM + .formatPermissionADMs(perm003_d4.p.hasPermissions, PermissionType.OAP)}'. " + + s"Use its IRI ${perm003_d4.iri} to modify it, if necessary."))) + } + + "fail and return a 'DuplicateValueException' when a doap permission for project, resource class, and property combination already exists" in { + responderManager ! DefaultObjectAccessPermissionCreateRequestADM( + createRequest = CreateDefaultObjectAccessPermissionAPIRequestADM( + forProject = SharedTestDataV1.INCUNABULA_PROJECT_IRI, + forResourceClass = Some(SharedOntologyTestDataADM.INCUNABULA_PAGE_RESOURCE_CLASS), + forProperty = Some(SharedOntologyTestDataADM.INCUNABULA_PartOf_Property), + hasPermissions = Set( + PermissionADM.changeRightsPermission(OntologyConstants.KnoraAdmin.Creator), + PermissionADM.modifyPermission(OntologyConstants.KnoraAdmin.ProjectMember) + ) + ), + featureFactoryConfig = defaultFeatureFactoryConfig, + requestingUser = rootUser, + apiRequestID = UUID.randomUUID() + ) + expectMsg( + Failure(DuplicateValueException( + s"A default object access permission for project: '${SharedTestDataV1.INCUNABULA_PROJECT_IRI}' and resourceClass: '${SharedOntologyTestDataADM.INCUNABULA_PAGE_RESOURCE_CLASS}' " + + s"and property: '${SharedOntologyTestDataADM.INCUNABULA_PartOf_Property}' " + + "combination already exists. " + + s"This permission currently has the scope '${PermissionUtilADM + .formatPermissionADMs(perm003_d5.p.hasPermissions, PermissionType.OAP)}'. " + + s"Use its IRI ${perm003_d5.iri} to modify it, if necessary."))) } } @@ -533,7 +609,9 @@ class PermissionsResponderADMSpec PermissionInfoADM(perm003_a2.iri, OntologyConstants.KnoraAdmin.AdministrativePermission), PermissionInfoADM(perm003_d1.iri, OntologyConstants.KnoraAdmin.DefaultObjectAccessPermission), PermissionInfoADM(perm003_d2.iri, OntologyConstants.KnoraAdmin.DefaultObjectAccessPermission), - PermissionInfoADM(perm003_d3.iri, OntologyConstants.KnoraAdmin.DefaultObjectAccessPermission) + PermissionInfoADM(perm003_d3.iri, OntologyConstants.KnoraAdmin.DefaultObjectAccessPermission), + PermissionInfoADM(perm003_d4.iri, OntologyConstants.KnoraAdmin.DefaultObjectAccessPermission), + PermissionInfoADM(perm003_d5.iri, OntologyConstants.KnoraAdmin.DefaultObjectAccessPermission) ))) } } diff --git a/webapi/src/test/scala/org/knora/webapi/responders/admin/ProjectsResponderADMSpec.scala b/webapi/src/test/scala/org/knora/webapi/responders/admin/ProjectsResponderADMSpec.scala index 5fc9bd0114..e1085e9edd 100644 --- a/webapi/src/test/scala/org/knora/webapi/responders/admin/ProjectsResponderADMSpec.scala +++ b/webapi/src/test/scala/org/knora/webapi/responders/admin/ProjectsResponderADMSpec.scala @@ -30,7 +30,13 @@ import akka.testkit.ImplicitSender import com.typesafe.config.{Config, ConfigFactory} import org.knora.webapi._ import org.knora.webapi.exceptions.{BadRequestException, DuplicateValueException, NotFoundException} -import org.knora.webapi.messages.StringFormatter +import org.knora.webapi.messages.{OntologyConstants, StringFormatter} +import org.knora.webapi.messages.admin.responder.permissionsmessages.{ + AdministrativePermissionGetResponseADM, + DefaultObjectAccessPermissionGetResponseADM, + PermissionADM, + PermissionByIriGetRequestADM +} import org.knora.webapi.messages.admin.responder.projectsmessages._ import org.knora.webapi.messages.admin.responder.usersmessages.UserInformationTypeADM import org.knora.webapi.messages.store.triplestoremessages._ @@ -205,10 +211,11 @@ class ProjectsResponderADMSpec extends CoreSpec(ProjectsResponderADMSpec.config) val newProjectIri = new MutableTestIri "CREATE a project and return the project info if the supplied shortname is unique" in { + val shortCode = "111c" responderManager ! ProjectCreateRequestADM( CreateProjectApiRequestADM( shortname = "newproject", - shortcode = "111c", // lower case + shortcode = shortCode, // lower case longname = Some("project longname"), description = Seq(StringLiteralV2(value = "project description", language = Some("en"))), keywords = Seq("keywords"), @@ -223,13 +230,79 @@ class ProjectsResponderADMSpec extends CoreSpec(ProjectsResponderADMSpec.config) val received: ProjectOperationResponseADM = expectMsgType[ProjectOperationResponseADM](timeout) received.project.shortname should be("newproject") - received.project.shortcode should be("111C") // upper case + received.project.shortcode should be(shortCode.toUpperCase) // upper case received.project.longname should contain("project longname") received.project.description should be( Seq(StringLiteralV2(value = "project description", language = Some("en")))) newProjectIri.set(received.project.id) - //println(s"newProjectIri: ${newProjectIri.get}") + + /* Check that ProjectAdmin group has got administrative and default object access permissions */ + // Check Administrative Permission of ProjectAdmin + responderManager ! PermissionByIriGetRequestADM( + permissionIri = s"http://rdfh.ch/permissions/${shortCode.toUpperCase}/defaultApForAdmin", + requestingUser = rootUser + ) + + val receivedApAdmin: AdministrativePermissionGetResponseADM = + expectMsgType[AdministrativePermissionGetResponseADM] + receivedApAdmin.administrativePermission.forProject should be(received.project.id) + receivedApAdmin.administrativePermission.forGroup should be(OntologyConstants.KnoraAdmin.ProjectAdmin) + val expectedAdminApPermissions: Set[PermissionADM] = + Set(PermissionADM.ProjectAdminAllPermission, PermissionADM.ProjectResourceCreateAllPermission) + assert(receivedApAdmin.administrativePermission.hasPermissions === expectedAdminApPermissions) + + // Check Default Object Access permission of ProjectAdmin + responderManager ! PermissionByIriGetRequestADM( + permissionIri = s"http://rdfh.ch/permissions/${shortCode.toUpperCase}/defaultDoapForAdmin", + requestingUser = rootUser + ) + val receivedDoapAdmin: DefaultObjectAccessPermissionGetResponseADM = + expectMsgType[DefaultObjectAccessPermissionGetResponseADM] + receivedDoapAdmin.defaultObjectAccessPermission.forProject should be(received.project.id) + receivedDoapAdmin.defaultObjectAccessPermission.forGroup should be( + Some(OntologyConstants.KnoraAdmin.ProjectAdmin)) + val expectedAdminDoapPermissions: Set[PermissionADM] = + Set( + PermissionADM.changeRightsPermission(OntologyConstants.KnoraAdmin.ProjectAdmin), + PermissionADM.deletePermission(OntologyConstants.KnoraAdmin.ProjectAdmin), + PermissionADM.modifyPermission(OntologyConstants.KnoraAdmin.ProjectAdmin), + PermissionADM.viewPermission(OntologyConstants.KnoraAdmin.ProjectAdmin), + PermissionADM.restrictedViewPermission(OntologyConstants.KnoraAdmin.ProjectAdmin) + ) + assert(receivedDoapAdmin.defaultObjectAccessPermission.hasPermissions === expectedAdminDoapPermissions) + + /* Check that ProjectMember group has got administrative and default object access permissions */ + // Check Administrative Permission of ProjectMember + responderManager ! PermissionByIriGetRequestADM( + permissionIri = s"http://rdfh.ch/permissions/${shortCode.toUpperCase}/defaultApForMember", + requestingUser = rootUser + ) + val receivedApMember: AdministrativePermissionGetResponseADM = + expectMsgType[AdministrativePermissionGetResponseADM] + receivedApMember.administrativePermission.forProject should be(received.project.id) + receivedApMember.administrativePermission.forGroup should be(OntologyConstants.KnoraAdmin.ProjectMember) + val expectedMemberApPermissions: Set[PermissionADM] = + Set(PermissionADM.ProjectResourceCreateAllPermission) + assert(receivedApMember.administrativePermission.hasPermissions === expectedMemberApPermissions) + + // Check Default Object Access permission of ProjectMember + responderManager ! PermissionByIriGetRequestADM( + permissionIri = s"http://rdfh.ch/permissions/${shortCode.toUpperCase}/defaultDoapForMember", + requestingUser = rootUser + ) + val receivedDoapMember: DefaultObjectAccessPermissionGetResponseADM = + expectMsgType[DefaultObjectAccessPermissionGetResponseADM] + receivedDoapMember.defaultObjectAccessPermission.forProject should be(received.project.id) + receivedDoapMember.defaultObjectAccessPermission.forGroup should be( + Some(OntologyConstants.KnoraAdmin.ProjectMember)) + val expectedMemberDoapPermissions: Set[PermissionADM] = + Set( + PermissionADM.modifyPermission(OntologyConstants.KnoraAdmin.ProjectMember), + PermissionADM.viewPermission(OntologyConstants.KnoraAdmin.ProjectMember), + PermissionADM.restrictedViewPermission(OntologyConstants.KnoraAdmin.ProjectMember) + ) + assert(receivedDoapMember.defaultObjectAccessPermission.hasPermissions === expectedMemberDoapPermissions) } "CREATE a project and return the project info if the supplied shortname and shortcode is unique" in { diff --git a/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedOntologyTestDataADM.scala b/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedOntologyTestDataADM.scala index 11562fb1c9..928b3076f4 100644 --- a/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedOntologyTestDataADM.scala +++ b/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedOntologyTestDataADM.scala @@ -64,6 +64,7 @@ object SharedOntologyTestDataADM { val INCUNABULA_BOOK_RESOURCE_CLASS_LocalHost: IRI = INCUNABULA_ONTOLOGY_IRI_LocalHost + "#" + "book" val INCUNABULA_PAGE_RESOURCE_CLASS: IRI = INCUNABULA_ONTOLOGY_IRI + "#" + "page" val INCUNABULA_PAGE_RESOURCE_CLASS_LocalHost: IRI = INCUNABULA_ONTOLOGY_IRI_LocalHost + "#" + "page" + val INCUNABULA_PartOf_Property: IRI = INCUNABULA_ONTOLOGY_IRI + "#" + "partOfValue" val INCUNABULA_PartOf_Property_LocalHost: IRI = INCUNABULA_ONTOLOGY_IRI_LocalHost + "#" + "partOfValue" // dokubib diff --git a/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedPermissionsTestData.scala b/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedPermissionsTestData.scala index 429b2b8c00..350d319956 100644 --- a/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedPermissionsTestData.scala +++ b/webapi/src/test/scala/org/knora/webapi/sharedtestdata/SharedPermissionsTestData.scala @@ -275,6 +275,34 @@ object SharedPermissionsTestData { ) ) + val perm003_d4: doap = + doap( + iri = "http://rdfh.ch/permissions/0803/003-d4", + p = DefaultObjectAccessPermissionADM( + iri = "http://rdfh.ch/permissions/0803/003-d4", + forProject = SharedTestDataV1.INCUNABULA_PROJECT_IRI, + forProperty = Some(INCUNABULA_PartOf_Property), + hasPermissions = Set( + PermissionADM.viewPermission(OntologyConstants.KnoraAdmin.KnownUser), + PermissionADM.restrictedViewPermission(OntologyConstants.KnoraAdmin.UnknownUser) + ) + ) + ) + + val perm003_d5: doap = + doap( + iri = "http://rdfh.ch/permissions/0803/003-d5", + p = DefaultObjectAccessPermissionADM( + iri = "http://rdfh.ch/permissions/0803/003-d5", + forProject = SharedTestDataV1.INCUNABULA_PROJECT_IRI, + forResourceClass = Some(INCUNABULA_PAGE_RESOURCE_CLASS), + forProperty = Some(INCUNABULA_PartOf_Property), + hasPermissions = Set( + PermissionADM.modifyPermission(OntologyConstants.KnoraAdmin.ProjectMember) + ) + ) + ) + /************************************/ /** Anything Project Permissions **/ /************************************/