API for roles
parent
632805d9ac
commit
7d787f98bd
|
|
@ -5,6 +5,8 @@
|
|||
*/
|
||||
package org.libreccm.api.admin.security;
|
||||
|
||||
import org.libreccm.api.ExtractedIdentifier;
|
||||
import org.libreccm.api.IdentifierExtractor;
|
||||
import org.libreccm.core.CcmObjectRepository;
|
||||
import org.libreccm.core.CoreConstants;
|
||||
import org.libreccm.api.admin.security.dto.RoleData;
|
||||
|
|
@ -36,12 +38,14 @@ import org.libreccm.security.Party;
|
|||
import org.libreccm.security.PartyRepository;
|
||||
import org.libreccm.security.Permission;
|
||||
import org.libreccm.security.PermissionManager;
|
||||
import org.libreccm.security.PermissionRepository;
|
||||
import org.libreccm.security.RequiresPrivilege;
|
||||
import org.libreccm.security.Role;
|
||||
import org.libreccm.security.RoleManager;
|
||||
import org.libreccm.security.RoleRepository;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
|
@ -57,12 +61,18 @@ public class RolesApi {
|
|||
@Inject
|
||||
private CcmObjectRepository ccmObjectRepository;
|
||||
|
||||
@Inject
|
||||
private IdentifierExtractor identifierExtractor;
|
||||
|
||||
@Inject
|
||||
private PartyRepository partyRepository;
|
||||
|
||||
@Inject
|
||||
private PermissionManager permissionManager;
|
||||
|
||||
@Inject
|
||||
private PermissionRepository permissionRepository;
|
||||
|
||||
@Inject
|
||||
private SecurityApiRepository repository;
|
||||
|
||||
|
|
@ -270,14 +280,56 @@ public class RolesApi {
|
|||
)
|
||||
)
|
||||
);
|
||||
permission = permissionManager.grantPrivilege(
|
||||
if (permissionRepository.existsPermission(
|
||||
privilege, role, object
|
||||
);
|
||||
)) {
|
||||
return Response.ok(
|
||||
String.format(
|
||||
"A permission granting privilege %s on object %s to "
|
||||
+ "role %s already exists.",
|
||||
privilege,
|
||||
object.getDisplayName(),
|
||||
role.getName()
|
||||
)
|
||||
).build();
|
||||
} else {
|
||||
permission = permissionManager.grantPrivilege(
|
||||
privilege, role, object
|
||||
);
|
||||
return Response.created(
|
||||
URI.create(
|
||||
String.format(
|
||||
"/api/admin/roles/%s/permissions/UUID-%s",
|
||||
role.getName(),
|
||||
permission.getUuid()
|
||||
)
|
||||
)
|
||||
).build();
|
||||
}
|
||||
} else {
|
||||
permission = permissionManager.grantPrivilege(privilege, role);
|
||||
}
|
||||
if (permissionRepository.existsPermission(privilege, role)) {
|
||||
return Response.ok(
|
||||
String.format(
|
||||
"A permission granting the privilege %s to "
|
||||
+ "role %s already exists.",
|
||||
privilege,
|
||||
role.getName()
|
||||
)
|
||||
).build();
|
||||
} else {
|
||||
permission = permissionManager.grantPrivilege(privilege, role);
|
||||
|
||||
throw new UnsupportedOperationException();
|
||||
return Response.created(
|
||||
URI.create(
|
||||
String.format(
|
||||
"/api/admin/roles/%s/permissions/UUID-%s",
|
||||
role.getName(),
|
||||
permission.getUuid()
|
||||
)
|
||||
)
|
||||
).build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DELETE
|
||||
|
|
@ -286,10 +338,56 @@ public class RolesApi {
|
|||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public Response removePermission(
|
||||
@PathParam("roleIdentifier") final String roleIdentifier,
|
||||
@PathParam("permissionIdentifier") final String permissionIdentifier
|
||||
@PathParam("roleIdentifier")
|
||||
final String roleIdentifier,
|
||||
@PathParam("permissionIdentifier")
|
||||
final String permissionIdentifierParam
|
||||
) {
|
||||
throw new UnsupportedOperationException();
|
||||
final Role role = repository.findRole(roleIdentifier);
|
||||
|
||||
final ExtractedIdentifier permissionIdentifier = identifierExtractor
|
||||
.extractIdentifier(roleIdentifier);
|
||||
|
||||
final Permission permission;
|
||||
switch (permissionIdentifier.getType()) {
|
||||
case ID:
|
||||
permission = permissionRepository
|
||||
.findById(
|
||||
Long.parseLong(permissionIdentifier.getIdentifier())
|
||||
)
|
||||
.orElseThrow(
|
||||
() -> new WebApplicationException(
|
||||
String.format(
|
||||
"No permission with ID %s found.",
|
||||
permissionIdentifier.getIdentifier()),
|
||||
Response.Status.NOT_FOUND
|
||||
)
|
||||
);
|
||||
break;
|
||||
case UUID:
|
||||
permission = permissionRepository
|
||||
.findByUuid(permissionIdentifier.getIdentifier())
|
||||
.orElseThrow(
|
||||
() -> new WebApplicationException(
|
||||
String.format(
|
||||
"No permission with UUID %s found.",
|
||||
permissionIdentifier.getIdentifier()
|
||||
),
|
||||
Response.Status.NOT_FOUND
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
return Response
|
||||
.status(Response.Status.BAD_REQUEST)
|
||||
.entity("Permissions can only be identified by ID or UUID.")
|
||||
.build();
|
||||
}
|
||||
|
||||
permissionRepository.delete(permission);
|
||||
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,8 +57,10 @@ public class PermissionManager implements Serializable {
|
|||
|
||||
@SuppressWarnings("PMD.LongVariable")
|
||||
private static final String QUERY_PARAM_OBJECT = "object";
|
||||
|
||||
@SuppressWarnings("PMD.LongVariable")
|
||||
private static final String QUERY_PARAM_GRANTEE = "grantee";
|
||||
|
||||
@SuppressWarnings("PMD.LongVariable")
|
||||
private static final String QUERY_PARAM_PRIVILEGE = "privilege";
|
||||
|
||||
|
|
@ -166,11 +168,15 @@ public class PermissionManager implements Serializable {
|
|||
"Can't grant a permission on object NULL.");
|
||||
}
|
||||
|
||||
if (existsInheritedPermission(privilege, grantee, object)) {
|
||||
if (permissionRepository.existsInheritedPermission(
|
||||
privilege, grantee, object
|
||||
)) {
|
||||
revokePrivilege(privilege, grantee, object);
|
||||
}
|
||||
|
||||
if (existsPermission(privilege, grantee, object)) {
|
||||
if (permissionRepository.existsPermission(
|
||||
privilege, grantee, object
|
||||
)) {
|
||||
return null;
|
||||
} else {
|
||||
final Permission permission = new Permission();
|
||||
|
|
@ -360,7 +366,9 @@ public class PermissionManager implements Serializable {
|
|||
final CcmObject object,
|
||||
final CcmObject inheritedFrom) {
|
||||
|
||||
if (!existsPermission(privilege, grantee, object)) {
|
||||
if (!permissionRepository.existsPermission(
|
||||
privilege, grantee, object
|
||||
)) {
|
||||
final Permission permission = new Permission();
|
||||
permission.setGrantee(grantee);
|
||||
permission.setGrantedPrivilege(privilege);
|
||||
|
|
@ -380,17 +388,19 @@ public class PermissionManager implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Grants a privilege to a role. If the privilege was already granted, the
|
||||
* Grants a privilege to a role.If the privilege was already granted, the
|
||||
* method does nothing.
|
||||
*
|
||||
* @param privilege The privilege to grant.
|
||||
* @param grantee The role to which the privilege is granted.
|
||||
*
|
||||
* @return The newly granted permission.
|
||||
*/
|
||||
@AuthorizationRequired
|
||||
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void grantPrivilege(final String privilege,
|
||||
final Role grantee) {
|
||||
public Permission grantPrivilege(final String privilege,
|
||||
final Role grantee) {
|
||||
if (privilege == null || privilege.isEmpty()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Can't grant a permission without a privilege.");
|
||||
|
|
@ -401,7 +411,7 @@ public class PermissionManager implements Serializable {
|
|||
"Can't grant a permission to grantee null.");
|
||||
}
|
||||
|
||||
if (!existsPermission(privilege, grantee)) {
|
||||
if (!permissionRepository.existsPermission(privilege, grantee)) {
|
||||
final Permission permission = new Permission();
|
||||
permission.setGrantee(grantee);
|
||||
permission.setGrantedPrivilege(privilege);
|
||||
|
|
@ -409,9 +419,9 @@ public class PermissionManager implements Serializable {
|
|||
permission.setUuid(UUID.randomUUID().toString());
|
||||
|
||||
entityManager.persist(permission);
|
||||
|
||||
|
||||
return permission;
|
||||
} else{
|
||||
} else {
|
||||
// ToDo
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
|
@ -453,9 +463,10 @@ public class PermissionManager implements Serializable {
|
|||
grantee.getName(),
|
||||
object.getUuid());
|
||||
|
||||
if (existsPermission(privilege, grantee, object)
|
||||
|| existsInheritedPermission(privilege, grantee, object)) {
|
||||
|
||||
if (permissionRepository.existsPermission(privilege, grantee, object)
|
||||
|| permissionRepository.existsInheritedPermission(
|
||||
privilege, grantee, object
|
||||
)) {
|
||||
LOGGER.debug("There is a permission for the provided parameters, "
|
||||
+ "revoking it...");
|
||||
|
||||
|
|
@ -512,7 +523,7 @@ public class PermissionManager implements Serializable {
|
|||
"Can't revoke a permission from grantee null.");
|
||||
}
|
||||
|
||||
if (existsPermission(privilege, grantee)) {
|
||||
if (permissionRepository.existsPermission(privilege, grantee)) {
|
||||
final Query query = entityManager.createQuery(
|
||||
"DELETE FROM Permission p "
|
||||
+ "WHERE p.grantedPrivilege = :privilege "
|
||||
|
|
@ -622,60 +633,4 @@ public class PermissionManager implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a not inherited permission granting the provided
|
||||
* {@code privilege} on the provided {@code object} to the provided
|
||||
* {@code role} exists.
|
||||
*
|
||||
* @param privilege The privilege granted by the permission.
|
||||
* @param grantee The role to which the privilege was granted.
|
||||
* @param object The object on which the privilege is granted.
|
||||
*
|
||||
* @return {@code true} if there is a matching permission, {@code false} if
|
||||
* not.
|
||||
*/
|
||||
private boolean existsPermission(final String privilege,
|
||||
final Role grantee,
|
||||
final CcmObject object) {
|
||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||
"Permission.existsDirectForPrivilegeRoleObject", Long.class);
|
||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
query.setParameter(QUERY_PARAM_OBJECT, object);
|
||||
|
||||
return query.getSingleResult() > 0;
|
||||
}
|
||||
|
||||
private boolean existsInheritedPermission(final String privilege,
|
||||
final Role grantee,
|
||||
final CcmObject object) {
|
||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||
"Permission.existsInheritedForPrivilegeRoleObject", Long.class);
|
||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
query.setParameter(QUERY_PARAM_OBJECT, object);
|
||||
|
||||
return query.getSingleResult() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a permission granting the provided {@code privilege}to the
|
||||
* provided {@code role} exists.
|
||||
*
|
||||
* @param privilege The privilege granted by the permission.
|
||||
* @param grantee The role to which the privilege was granted.
|
||||
*
|
||||
* @return {@code true} if there is a matching permission, {@code false} if
|
||||
* not.
|
||||
*/
|
||||
private boolean existsPermission(final String privilege,
|
||||
final Role grantee) {
|
||||
final TypedQuery<Long> query = entityManager.createNamedQuery(
|
||||
"Permission.existsForPrivilegeAndRole", Long.class);
|
||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
|
||||
return query.getSingleResult() > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
package org.libreccm.security;
|
||||
|
||||
import org.libreccm.core.AbstractEntityRepository;
|
||||
import org.libreccm.core.CcmObject;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.persistence.NoResultException;
|
||||
|
|
@ -39,6 +40,15 @@ public class PermissionRepository
|
|||
|
||||
private static final long serialVersionUID = -4240674229117593486L;
|
||||
|
||||
@SuppressWarnings("PMD.LongVariable")
|
||||
private static final String QUERY_PARAM_OBJECT = "object";
|
||||
|
||||
@SuppressWarnings("PMD.LongVariable")
|
||||
private static final String QUERY_PARAM_GRANTEE = "grantee";
|
||||
|
||||
@SuppressWarnings("PMD.LongVariable")
|
||||
private static final String QUERY_PARAM_PRIVILEGE = "privilege";
|
||||
|
||||
@Override
|
||||
public Class<Permission> getEntityClass() {
|
||||
return Permission.class;
|
||||
|
|
@ -63,19 +73,19 @@ public class PermissionRepository
|
|||
}
|
||||
|
||||
@Override
|
||||
public void initNewEntity(final Permission permission) {
|
||||
|
||||
public void initNewEntity(final Permission permission) {
|
||||
|
||||
permission.setUuid(UUID.randomUUID().toString());
|
||||
}
|
||||
|
||||
|
||||
public Optional<Permission> findByUuid(final String uuid) {
|
||||
final TypedQuery<Permission> query = getEntityManager()
|
||||
.createNamedQuery("Permission.findByUuid", Permission.class);
|
||||
.createNamedQuery("Permission.findByUuid", Permission.class);
|
||||
query.setParameter("uuid", uuid);
|
||||
|
||||
|
||||
return getSingleResult(query);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds a {@link Permission} by the privilege, the grantee and the object.
|
||||
* Where the grantee has been granted the given privilege on the given
|
||||
|
|
@ -106,4 +116,62 @@ public class PermissionRepository
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a not inherited permission granting the provided
|
||||
* {@code privilege} on the provided {@code object} to the provided
|
||||
* {@code role} exists.
|
||||
*
|
||||
* @param privilege The privilege granted by the permission.
|
||||
* @param grantee The role to which the privilege was granted.
|
||||
* @param object The object on which the privilege is granted.
|
||||
*
|
||||
* @return {@code true} if there is a matching permission, {@code false} if
|
||||
* not.
|
||||
*/
|
||||
public boolean existsPermission(final String privilege,
|
||||
final Role grantee,
|
||||
final CcmObject object) {
|
||||
final TypedQuery<Long> query = getEntityManager()
|
||||
.createNamedQuery(
|
||||
"Permission.existsDirectForPrivilegeRoleObject", Long.class
|
||||
);
|
||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
query.setParameter(QUERY_PARAM_OBJECT, object);
|
||||
|
||||
return query.getSingleResult() > 0;
|
||||
}
|
||||
|
||||
public boolean existsInheritedPermission(final String privilege,
|
||||
final Role grantee,
|
||||
final CcmObject object) {
|
||||
final TypedQuery<Long> query = getEntityManager().createNamedQuery(
|
||||
"Permission.existsInheritedForPrivilegeRoleObject", Long.class);
|
||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
query.setParameter(QUERY_PARAM_OBJECT, object);
|
||||
|
||||
return query.getSingleResult() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a permission granting the provided {@code privilege}to the
|
||||
* provided {@code role} exists.
|
||||
*
|
||||
* @param privilege The privilege granted by the permission.
|
||||
* @param grantee The role to which the privilege was granted.
|
||||
*
|
||||
* @return {@code true} if there is a matching permission, {@code false} if
|
||||
* not.
|
||||
*/
|
||||
public boolean existsPermission(final String privilege,
|
||||
final Role grantee) {
|
||||
final TypedQuery<Long> query = getEntityManager().createNamedQuery(
|
||||
"Permission.existsForPrivilegeAndRole", Long.class);
|
||||
query.setParameter(QUERY_PARAM_PRIVILEGE, privilege);
|
||||
query.setParameter(QUERY_PARAM_GRANTEE, grantee);
|
||||
|
||||
return query.getSingleResult() > 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue