Skip to content

Commit 3fe8c14

Browse files
feat(permissions): Delete permissions: (DSP-1169) (#1787)
* delete permission message + tests * test (deletePermission) requesting user test * feature (deletePermission) template * feature (deletePermission) response message * feature (deletePermission) responder + tests * test (deletePermission) e2e test * test (deletePermission) more tests * refactor (permissions) correct date of copy right for new files * feature (permissionsEndpoint) systematically check requesting user's permission for operation + tests Co-authored-by: Ivan Subotic <400790+subotic@users.noreply.github.com>
1 parent 0eeb3b3 commit 3fe8c14

File tree

10 files changed

+756
-134
lines changed

10 files changed

+756
-134
lines changed

webapi/src/main/scala/org/knora/webapi/messages/admin/responder/permissionsmessages/PermissionsMessagesADM.scala

Lines changed: 74 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ case class CreateAdministrativePermissionAPIRequestADM(id: Option[IRI] = None,
5555

5656
implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
5757
stringFormatter.validateProjectIri(forProject, throw BadRequestException(s"Invalid project IRI"))
58-
stringFormatter.validateOptionalPermissionIri(id, throw BadRequestException(s"Invalid permission IRI"))
58+
stringFormatter.validateOptionalPermissionIri(
59+
id,
60+
throw BadRequestException(s"Invalid permission IRI ${id.get} is given."))
5961
if (hasPermissions.isEmpty) throw BadRequestException("Permissions needs to be supplied.")
6062
}
6163

@@ -80,7 +82,9 @@ case class CreateDefaultObjectAccessPermissionAPIRequestADM(id: Option[IRI] = No
8082

8183
implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
8284
stringFormatter.validateProjectIri(forProject, throw BadRequestException(s"Invalid project IRI"))
83-
stringFormatter.validateOptionalPermissionIri(id, throw BadRequestException(s"Invalid permission IRI"))
85+
stringFormatter.validateOptionalPermissionIri(
86+
id,
87+
throw BadRequestException(s"Invalid permission IRI ${id.get} is given."))
8488
forGroup match {
8589
case Some(iri: IRI) =>
8690
if (forResourceClass.isDefined)
@@ -245,7 +249,7 @@ case class PermissionChangeGroupRequestADM(permissionIri: IRI,
245249

246250
implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
247251
if (!stringFormatter.isKnoraPermissionIriStr(permissionIri)) {
248-
throw BadRequestException(s"Invalid IRI is given: $permissionIri.")
252+
throw BadRequestException(s"Invalid permission IRI $permissionIri is given.")
249253
}
250254

251255
}
@@ -268,7 +272,7 @@ case class PermissionChangeHasPermissionsRequestADM(
268272

269273
implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
270274
if (!stringFormatter.isKnoraPermissionIriStr(permissionIri)) {
271-
throw BadRequestException(s"Invalid IRI is given: $permissionIri.")
275+
throw BadRequestException(s"Invalid permission IRI $permissionIri is given.")
272276
}
273277

274278
}
@@ -291,7 +295,7 @@ case class PermissionChangeResourceClassRequestADM(
291295

292296
implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
293297
if (!stringFormatter.isKnoraPermissionIriStr(permissionIri)) {
294-
throw BadRequestException(s"Invalid IRI is given: $permissionIri.")
298+
throw BadRequestException(s"Invalid permission IRI $permissionIri is given.")
295299
}
296300
}
297301

@@ -312,7 +316,7 @@ case class PermissionChangePropertyRequestADM(permissionIri: IRI,
312316

313317
implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
314318
if (!stringFormatter.isKnoraPermissionIriStr(permissionIri)) {
315-
throw BadRequestException(s"Invalid IRI is given: $permissionIri.")
319+
throw BadRequestException(s"Invalid permission IRI $permissionIri is given.")
316320
}
317321
}
318322

@@ -354,18 +358,11 @@ case class AdministrativePermissionForIriGetRequestADM(administrativePermissionI
354358
requestingUser: UserADM,
355359
apiRequestID: UUID)
356360
extends PermissionsResponderRequestADM {
357-
// Check user's permission for the operation
358-
//TODO: should get the project the permission is assigned to and check if the requesting user is the project admin
359-
if (!requestingUser.isSystemAdmin
360-
&& !requestingUser.permissions.isProjectAdminInAnyProject()
361-
&& !requestingUser.isSystemUser) {
362-
// not a system admin
363-
throw ForbiddenException("Administrative permission can only be queried by system and project admin.")
364-
}
365361

366362
implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
367-
stringFormatter.validatePermissionIri(administrativePermissionIri,
368-
throw BadRequestException(s"Invalid permission IRI"))
363+
stringFormatter.validatePermissionIri(
364+
administrativePermissionIri,
365+
throw BadRequestException(s"Invalid permission IRI $administrativePermissionIri is given."))
369366
}
370367

371368
/**
@@ -400,7 +397,15 @@ case class AdministrativePermissionForProjectGroupGetADM(projectIri: IRI, groupI
400397
* @param requestingUser
401398
*/
402399
case class AdministrativePermissionForProjectGroupGetRequestADM(projectIri: IRI, groupIri: IRI, requestingUser: UserADM)
403-
extends PermissionsResponderRequestADM
400+
extends PermissionsResponderRequestADM {
401+
// Check user's permission for the operation
402+
if (!requestingUser.isSystemAdmin
403+
&& !requestingUser.permissions.isProjectAdmin(projectIri)
404+
&& !requestingUser.isSystemUser) {
405+
// not a system admin
406+
throw ForbiddenException("Administrative permission can only be queried by system and project admin.")
407+
}
408+
}
404409

405410
/**
406411
* Create a single [[AdministrativePermissionADM]].
@@ -421,7 +426,7 @@ case class AdministrativePermissionCreateRequestADM(createRequest: CreateAdminis
421426
&& !requestingUser.permissions.isProjectAdmin(createRequest.forProject)
422427
&& !requestingUser.isSystemUser) {
423428
// not a system admin
424-
throw ForbiddenException("A new administrative permission can only be added by a system admin.")
429+
throw ForbiddenException("A new administrative permission can only be added by system or project admin.")
425430
}
426431
}
427432

@@ -434,14 +439,6 @@ case class AdministrativePermissionCreateRequestADM(createRequest: CreateAdminis
434439
*/
435440
case class ObjectAccessPermissionsForResourceGetADM(resourceIri: IRI, requestingUser: UserADM)
436441
extends PermissionsResponderRequestADM {
437-
// Check user's permission for the operation
438-
//TODO: should get the project the resource belongs to and check if the requestingUser is the project admin
439-
if (!requestingUser.isSystemAdmin
440-
&& !requestingUser.permissions.isProjectAdminInAnyProject()
441-
&& !requestingUser.isSystemUser) {
442-
// not a system admin
443-
throw ForbiddenException("Object access permissions can only be queried by system and project admin.")
444-
}
445442

446443
implicit val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
447444

@@ -459,16 +456,6 @@ case class ObjectAccessPermissionsForResourceGetADM(resourceIri: IRI, requesting
459456
case class ObjectAccessPermissionsForValueGetADM(valueIri: IRI, requestingUser: UserADM)
460457
extends PermissionsResponderRequestADM {
461458

462-
// Check user's permission for the operation
463-
//TODO: should get the project the value belongs to and check if the requestingUser is the project admin
464-
465-
if (!requestingUser.isSystemAdmin
466-
&& !requestingUser.permissions.isProjectAdminInAnyProject()
467-
&& !requestingUser.isSystemUser) {
468-
// not a system admin
469-
throw ForbiddenException("Object access permissions can only be queried by system and project admin.")
470-
}
471-
472459
implicit val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
473460

474461
if (!stringFormatter.toSmartIri(valueIri).isKnoraValueIri) {
@@ -573,17 +560,11 @@ case class DefaultObjectAccessPermissionForIriGetRequestADM(defaultObjectAccessP
573560
requestingUser: UserADM,
574561
apiRequestID: UUID)
575562
extends PermissionsResponderRequestADM {
576-
// Check user's permission for the operation
577-
if (!requestingUser.isSystemAdmin
578-
&& !requestingUser.permissions.isProjectAdminInAnyProject()
579-
&& !requestingUser.isSystemUser) {
580-
// not a system admin
581-
throw ForbiddenException("Default object access permissions can only be queried by system and project admin.")
582-
}
583563

584564
implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
585-
stringFormatter.validatePermissionIri(defaultObjectAccessPermissionIri,
586-
throw BadRequestException(s"Invalid permission IRI"))
565+
stringFormatter.validatePermissionIri(
566+
defaultObjectAccessPermissionIri,
567+
throw BadRequestException(s"Invalid permission IRI $defaultObjectAccessPermissionIri is given."))
587568
}
588569

589570
/**
@@ -697,6 +678,23 @@ case class PermissionByIriGetRequestADM(permissionIri: IRI, requestingUser: User
697678
stringFormatter.validatePermissionIri(permissionIri,
698679
throw BadRequestException(s"Invalid permission IRI $permissionIri is given."))
699680
}
681+
682+
/**
683+
* A message that requests deletion of a permission identified through its IRI.
684+
* A successful response will be [[PermissionDeleteResponseADM]] with deleted=true.
685+
*
686+
* @param permissionIri the iri of the permission object.
687+
* @param requestingUser the user initiating the request.
688+
* @param apiRequestID the API request ID.
689+
*/
690+
case class PermissionDeleteRequestADM(permissionIri: IRI, requestingUser: UserADM, apiRequestID: UUID)
691+
extends PermissionsResponderRequestADM {
692+
693+
implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
694+
stringFormatter.validatePermissionIri(permissionIri,
695+
throw BadRequestException(s"Invalid permission IRI $permissionIri is given."))
696+
}
697+
700698
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
701699
// Responses
702700

@@ -792,6 +790,19 @@ case class DefaultObjectAccessPermissionCreateResponseADM(
792790
*/
793791
case class DefaultObjectAccessPermissionsStringResponseADM(permissionLiteral: String)
794792

793+
/**
794+
* Responds to deletion of a permission by returning a success message.
795+
*
796+
* @param permissionIri the IRI of the permission that is deleted.
797+
* @param deleted status of delete operation.
798+
*/
799+
case class PermissionDeleteResponseADM(permissionIri: IRI, deleted: Boolean)
800+
extends KnoraResponseADM
801+
with PermissionsADMJsonProtocol {
802+
803+
def toJsValue = permissionDeleteResponseADMFormat.write(this)
804+
}
805+
795806
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
796807
// Components of messages
797808

@@ -1202,27 +1213,35 @@ trait PermissionsADMJsonProtocol
12021213

12031214
implicit val permissionADMFormat: JsonFormat[PermissionADM] =
12041215
jsonFormat(PermissionADM.apply, "name", "additionalInformation", "permissionCode")
1216+
12051217
implicit val permissionInfoADMFormat: JsonFormat[PermissionInfoADM] = lazyFormat(
12061218
jsonFormat(PermissionInfoADM, "iri", "permissionType"))
1219+
12071220
implicit val administrativePermissionADMFormat: JsonFormat[AdministrativePermissionADM] = lazyFormat(
12081221
jsonFormat(AdministrativePermissionADM, "iri", "forProject", "forGroup", "hasPermissions"))
1222+
12091223
implicit val objectAccessPermissionADMFormat: JsonFormat[ObjectAccessPermissionADM] =
12101224
jsonFormat(ObjectAccessPermissionADM, "forResource", "forValue", "hasPermissions")
1225+
12111226
implicit val defaultObjectAccessPermissionADMFormat: JsonFormat[DefaultObjectAccessPermissionADM] = lazyFormat(
12121227
jsonFormat6(DefaultObjectAccessPermissionADM))
1228+
12131229
implicit val permissionsDataADMFormat: JsonFormat[PermissionsDataADM] = jsonFormat2(PermissionsDataADM)
12141230

12151231
implicit val permissionsForProjectGetResponseADMFormat: RootJsonFormat[PermissionsForProjectGetResponseADM] =
12161232
jsonFormat(PermissionsForProjectGetResponseADM, "permissions")
1233+
12171234
implicit val administrativePermissionsForProjectGetResponseADMFormat
12181235
: RootJsonFormat[AdministrativePermissionsForProjectGetResponseADM] =
12191236
jsonFormat(AdministrativePermissionsForProjectGetResponseADM, "administrative_permissions")
1237+
12201238
implicit val defaultObjectAccessPermissionsForProjectGetResponseADMFormat
12211239
: RootJsonFormat[DefaultObjectAccessPermissionsForProjectGetResponseADM] =
12221240
jsonFormat(DefaultObjectAccessPermissionsForProjectGetResponseADM, "default_object_access_permissions")
12231241

12241242
implicit val administrativePermissionGetResponseADMFormat: RootJsonFormat[AdministrativePermissionGetResponseADM] =
12251243
jsonFormat(AdministrativePermissionGetResponseADM, "administrative_permission")
1244+
12261245
implicit val defaultObjectAccessPermissionGetResponseADMFormat
12271246
: RootJsonFormat[DefaultObjectAccessPermissionGetResponseADM] =
12281247
jsonFormat(DefaultObjectAccessPermissionGetResponseADM, "default_object_access_permission")
@@ -1231,6 +1250,7 @@ trait PermissionsADMJsonProtocol
12311250
: RootJsonFormat[CreateAdministrativePermissionAPIRequestADM] = rootFormat(
12321251
lazyFormat(
12331252
jsonFormat(CreateAdministrativePermissionAPIRequestADM, "id", "forProject", "forGroup", "hasPermissions")))
1253+
12341254
implicit val createDefaultObjectAccessPermissionAPIRequestADMFormat
12351255
: RootJsonFormat[CreateDefaultObjectAccessPermissionAPIRequestADM] = rootFormat(
12361256
lazyFormat(
@@ -1241,21 +1261,30 @@ trait PermissionsADMJsonProtocol
12411261
"forResourceClass",
12421262
"forProperty",
12431263
"hasPermissions")))
1264+
12441265
implicit val administrativePermissionCreateResponseADMFormat
12451266
: RootJsonFormat[AdministrativePermissionCreateResponseADM] = rootFormat(
12461267
lazyFormat(jsonFormat(AdministrativePermissionCreateResponseADM, "administrative_permission")))
1268+
12471269
implicit val defaultObjectAccessPermissionCreateResponseADMFormat
12481270
: RootJsonFormat[DefaultObjectAccessPermissionCreateResponseADM] =
12491271
jsonFormat(DefaultObjectAccessPermissionCreateResponseADM, "default_object_access_permission")
12501272

12511273
implicit val changePermissionGroupApiRequestADMFormat: RootJsonFormat[ChangePermissionGroupApiRequestADM] =
12521274
jsonFormat(ChangePermissionGroupApiRequestADM, "forGroup")
1275+
12531276
implicit val changePermissionHasPermissionsApiRequestADMFormat
12541277
: RootJsonFormat[ChangePermissionHasPermissionsApiRequestADM] =
12551278
jsonFormat(ChangePermissionHasPermissionsApiRequestADM, "hasPermissions")
1279+
12561280
implicit val changePermissionResourceClassApiRequestADMFormat
12571281
: RootJsonFormat[ChangePermissionResourceClassApiRequestADM] =
12581282
jsonFormat(ChangePermissionResourceClassApiRequestADM, "forResourceClass")
1283+
12591284
implicit val changePermissionPropertyApiRequestADMFormat: RootJsonFormat[ChangePermissionPropertyApiRequestADM] =
12601285
jsonFormat(ChangePermissionPropertyApiRequestADM, "forProperty")
1286+
1287+
implicit val permissionDeleteResponseADMFormat: RootJsonFormat[PermissionDeleteResponseADM] =
1288+
jsonFormat(PermissionDeleteResponseADM, "permissionIri", "deleted")
1289+
12611290
}

0 commit comments

Comments
 (0)