Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
SepidehAlassi and subotic committed Jan 27, 2021
1 parent 0eeb3b3 commit 3fe8c14
Show file tree
Hide file tree
Showing 10 changed files with 756 additions and 134 deletions.
Expand Up @@ -55,7 +55,9 @@ case class CreateAdministrativePermissionAPIRequestADM(id: Option[IRI] = None,

implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
stringFormatter.validateProjectIri(forProject, throw BadRequestException(s"Invalid project IRI"))
stringFormatter.validateOptionalPermissionIri(id, throw BadRequestException(s"Invalid permission IRI"))
stringFormatter.validateOptionalPermissionIri(
id,
throw BadRequestException(s"Invalid permission IRI ${id.get} is given."))
if (hasPermissions.isEmpty) throw BadRequestException("Permissions needs to be supplied.")
}

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

implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
stringFormatter.validateProjectIri(forProject, throw BadRequestException(s"Invalid project IRI"))
stringFormatter.validateOptionalPermissionIri(id, throw BadRequestException(s"Invalid permission IRI"))
stringFormatter.validateOptionalPermissionIri(
id,
throw BadRequestException(s"Invalid permission IRI ${id.get} is given."))
forGroup match {
case Some(iri: IRI) =>
if (forResourceClass.isDefined)
Expand Down Expand Up @@ -245,7 +249,7 @@ case class PermissionChangeGroupRequestADM(permissionIri: IRI,

implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
if (!stringFormatter.isKnoraPermissionIriStr(permissionIri)) {
throw BadRequestException(s"Invalid IRI is given: $permissionIri.")
throw BadRequestException(s"Invalid permission IRI $permissionIri is given.")
}

}
Expand All @@ -268,7 +272,7 @@ case class PermissionChangeHasPermissionsRequestADM(

implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
if (!stringFormatter.isKnoraPermissionIriStr(permissionIri)) {
throw BadRequestException(s"Invalid IRI is given: $permissionIri.")
throw BadRequestException(s"Invalid permission IRI $permissionIri is given.")
}

}
Expand All @@ -291,7 +295,7 @@ case class PermissionChangeResourceClassRequestADM(

implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
if (!stringFormatter.isKnoraPermissionIriStr(permissionIri)) {
throw BadRequestException(s"Invalid IRI is given: $permissionIri.")
throw BadRequestException(s"Invalid permission IRI $permissionIri is given.")
}
}

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

implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
if (!stringFormatter.isKnoraPermissionIriStr(permissionIri)) {
throw BadRequestException(s"Invalid IRI is given: $permissionIri.")
throw BadRequestException(s"Invalid permission IRI $permissionIri is given.")
}
}

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

implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
stringFormatter.validatePermissionIri(administrativePermissionIri,
throw BadRequestException(s"Invalid permission IRI"))
stringFormatter.validatePermissionIri(
administrativePermissionIri,
throw BadRequestException(s"Invalid permission IRI $administrativePermissionIri is given."))
}

/**
Expand Down Expand Up @@ -400,7 +397,15 @@ case class AdministrativePermissionForProjectGroupGetADM(projectIri: IRI, groupI
* @param requestingUser
*/
case class AdministrativePermissionForProjectGroupGetRequestADM(projectIri: IRI, groupIri: IRI, requestingUser: UserADM)
extends PermissionsResponderRequestADM
extends PermissionsResponderRequestADM {
// Check user's permission for the operation
if (!requestingUser.isSystemAdmin
&& !requestingUser.permissions.isProjectAdmin(projectIri)
&& !requestingUser.isSystemUser) {
// not a system admin
throw ForbiddenException("Administrative permission can only be queried by system and project admin.")
}
}

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

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

implicit val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies

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

// Check user's permission for the operation
//TODO: should get the project the value belongs to and check if the requestingUser is the project admin

if (!requestingUser.isSystemAdmin
&& !requestingUser.permissions.isProjectAdminInAnyProject()
&& !requestingUser.isSystemUser) {
// not a system admin
throw ForbiddenException("Object access permissions can only be queried by system and project admin.")
}

implicit val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies

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

implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
stringFormatter.validatePermissionIri(defaultObjectAccessPermissionIri,
throw BadRequestException(s"Invalid permission IRI"))
stringFormatter.validatePermissionIri(
defaultObjectAccessPermissionIri,
throw BadRequestException(s"Invalid permission IRI $defaultObjectAccessPermissionIri is given."))
}

/**
Expand Down Expand Up @@ -697,6 +678,23 @@ case class PermissionByIriGetRequestADM(permissionIri: IRI, requestingUser: User
stringFormatter.validatePermissionIri(permissionIri,
throw BadRequestException(s"Invalid permission IRI $permissionIri is given."))
}

/**
* A message that requests deletion of a permission identified through its IRI.
* A successful response will be [[PermissionDeleteResponseADM]] with deleted=true.
*
* @param permissionIri the iri of the permission object.
* @param requestingUser the user initiating the request.
* @param apiRequestID the API request ID.
*/
case class PermissionDeleteRequestADM(permissionIri: IRI, requestingUser: UserADM, apiRequestID: UUID)
extends PermissionsResponderRequestADM {

implicit protected val stringFormatter: StringFormatter = StringFormatter.getInstanceForConstantOntologies
stringFormatter.validatePermissionIri(permissionIri,
throw BadRequestException(s"Invalid permission IRI $permissionIri is given."))
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Responses

Expand Down Expand Up @@ -792,6 +790,19 @@ case class DefaultObjectAccessPermissionCreateResponseADM(
*/
case class DefaultObjectAccessPermissionsStringResponseADM(permissionLiteral: String)

/**
* Responds to deletion of a permission by returning a success message.
*
* @param permissionIri the IRI of the permission that is deleted.
* @param deleted status of delete operation.
*/
case class PermissionDeleteResponseADM(permissionIri: IRI, deleted: Boolean)
extends KnoraResponseADM
with PermissionsADMJsonProtocol {

def toJsValue = permissionDeleteResponseADMFormat.write(this)
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Components of messages

Expand Down Expand Up @@ -1202,27 +1213,35 @@ trait PermissionsADMJsonProtocol

implicit val permissionADMFormat: JsonFormat[PermissionADM] =
jsonFormat(PermissionADM.apply, "name", "additionalInformation", "permissionCode")

implicit val permissionInfoADMFormat: JsonFormat[PermissionInfoADM] = lazyFormat(
jsonFormat(PermissionInfoADM, "iri", "permissionType"))

implicit val administrativePermissionADMFormat: JsonFormat[AdministrativePermissionADM] = lazyFormat(
jsonFormat(AdministrativePermissionADM, "iri", "forProject", "forGroup", "hasPermissions"))

implicit val objectAccessPermissionADMFormat: JsonFormat[ObjectAccessPermissionADM] =
jsonFormat(ObjectAccessPermissionADM, "forResource", "forValue", "hasPermissions")

implicit val defaultObjectAccessPermissionADMFormat: JsonFormat[DefaultObjectAccessPermissionADM] = lazyFormat(
jsonFormat6(DefaultObjectAccessPermissionADM))

implicit val permissionsDataADMFormat: JsonFormat[PermissionsDataADM] = jsonFormat2(PermissionsDataADM)

implicit val permissionsForProjectGetResponseADMFormat: RootJsonFormat[PermissionsForProjectGetResponseADM] =
jsonFormat(PermissionsForProjectGetResponseADM, "permissions")

implicit val administrativePermissionsForProjectGetResponseADMFormat
: RootJsonFormat[AdministrativePermissionsForProjectGetResponseADM] =
jsonFormat(AdministrativePermissionsForProjectGetResponseADM, "administrative_permissions")

implicit val defaultObjectAccessPermissionsForProjectGetResponseADMFormat
: RootJsonFormat[DefaultObjectAccessPermissionsForProjectGetResponseADM] =
jsonFormat(DefaultObjectAccessPermissionsForProjectGetResponseADM, "default_object_access_permissions")

implicit val administrativePermissionGetResponseADMFormat: RootJsonFormat[AdministrativePermissionGetResponseADM] =
jsonFormat(AdministrativePermissionGetResponseADM, "administrative_permission")

implicit val defaultObjectAccessPermissionGetResponseADMFormat
: RootJsonFormat[DefaultObjectAccessPermissionGetResponseADM] =
jsonFormat(DefaultObjectAccessPermissionGetResponseADM, "default_object_access_permission")
Expand All @@ -1231,6 +1250,7 @@ trait PermissionsADMJsonProtocol
: RootJsonFormat[CreateAdministrativePermissionAPIRequestADM] = rootFormat(
lazyFormat(
jsonFormat(CreateAdministrativePermissionAPIRequestADM, "id", "forProject", "forGroup", "hasPermissions")))

implicit val createDefaultObjectAccessPermissionAPIRequestADMFormat
: RootJsonFormat[CreateDefaultObjectAccessPermissionAPIRequestADM] = rootFormat(
lazyFormat(
Expand All @@ -1241,21 +1261,30 @@ trait PermissionsADMJsonProtocol
"forResourceClass",
"forProperty",
"hasPermissions")))

implicit val administrativePermissionCreateResponseADMFormat
: RootJsonFormat[AdministrativePermissionCreateResponseADM] = rootFormat(
lazyFormat(jsonFormat(AdministrativePermissionCreateResponseADM, "administrative_permission")))

implicit val defaultObjectAccessPermissionCreateResponseADMFormat
: RootJsonFormat[DefaultObjectAccessPermissionCreateResponseADM] =
jsonFormat(DefaultObjectAccessPermissionCreateResponseADM, "default_object_access_permission")

implicit val changePermissionGroupApiRequestADMFormat: RootJsonFormat[ChangePermissionGroupApiRequestADM] =
jsonFormat(ChangePermissionGroupApiRequestADM, "forGroup")

implicit val changePermissionHasPermissionsApiRequestADMFormat
: RootJsonFormat[ChangePermissionHasPermissionsApiRequestADM] =
jsonFormat(ChangePermissionHasPermissionsApiRequestADM, "hasPermissions")

implicit val changePermissionResourceClassApiRequestADMFormat
: RootJsonFormat[ChangePermissionResourceClassApiRequestADM] =
jsonFormat(ChangePermissionResourceClassApiRequestADM, "forResourceClass")

implicit val changePermissionPropertyApiRequestADMFormat: RootJsonFormat[ChangePermissionPropertyApiRequestADM] =
jsonFormat(ChangePermissionPropertyApiRequestADM, "forProperty")

implicit val permissionDeleteResponseADMFormat: RootJsonFormat[PermissionDeleteResponseADM] =
jsonFormat(PermissionDeleteResponseADM, "permissionIri", "deleted")

}

0 comments on commit 3fe8c14

Please sign in to comment.