prepare for improved user privilege system

This commit is contained in:
anhefti 2023-12-06 09:01:22 +01:00
parent 05c7407651
commit f2a0034150
5 changed files with 83 additions and 59 deletions

View file

@ -17,7 +17,6 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.user.UserAccount;
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
@ -110,13 +109,21 @@ public final class Privilege {
final Long institutionId,
final String ownerId) {
return this.hasBasePrivilege(privilegeType)
|| ((institutionId != null) &&
(this.hasInstitutionalPrivilege(privilegeType)
&& userInstitutionId.longValue() == institutionId
.longValue())
|| (this.hasOwnershipPrivilege(privilegeType)
&& isOwner(ownerId, userId)));
// Has base privilege?
if (this.hasBasePrivilege(privilegeType)) {
return true;
}
// has institutional privilege?
if ((institutionId != null)
&& (this.hasInstitutionalPrivilege(privilegeType)
&& userInstitutionId.longValue() == institutionId.longValue())) {
return true;
}
// has owner privilege?
return this.hasOwnershipPrivilege(privilegeType) && isOwner(ownerId, userId);
}
private boolean isOwner(final String ownerId, final String userId) {
@ -135,54 +142,6 @@ public final class Privilege {
+ ", ownershipPrivilege=" + this.ownershipPrivilege + "]";
}
/** A key that combines UserRole EntityType identity */
public static final class RoleTypeKey {
@JsonProperty("entityType")
public final EntityType entityType;
@JsonProperty("userRole")
public final UserRole userRole;
@JsonCreator
public RoleTypeKey(
@JsonProperty("entityType") final EntityType type,
@JsonProperty("userRole") final UserRole role) {
this.entityType = type;
this.userRole = role;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.userRole == null) ? 0 : this.userRole.hashCode());
result = prime * result + ((this.entityType == null) ? 0 : this.entityType.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final RoleTypeKey other = (RoleTypeKey) obj;
if (this.userRole != other.userRole)
return false;
if (this.entityType != other.entityType)
return false;
return true;
}
@Override
public String toString() {
return "RoleTypeKey [entityType=" + this.entityType + ", userRole=" + this.userRole + "]";
}
}
/** Checks if the current user has role based edit access to a specified user account.
* <p>
* If user account has UserRole.SEB_SERVER_ADMIN this always gives true

View file

@ -0,0 +1,56 @@
package ch.ethz.seb.sebserver.gbl.api.authorization;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* A key that combines UserRole EntityType identity
*/
public final class RoleTypeKey {
@JsonProperty("entityType")
public final EntityType entityType;
@JsonProperty("userRole")
public final UserRole userRole;
@JsonCreator
public RoleTypeKey(
@JsonProperty("entityType") final EntityType type,
@JsonProperty("userRole") final UserRole role) {
this.entityType = type;
this.userRole = role;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((this.userRole == null) ? 0 : this.userRole.hashCode());
result = prime * result + ((this.entityType == null) ? 0 : this.entityType.hashCode());
return result;
}
@Override
public boolean equals(final Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final RoleTypeKey other = (RoleTypeKey) obj;
if (this.userRole != other.userRole)
return false;
if (this.entityType != other.entityType)
return false;
return true;
}
@Override
public String toString() {
return "RoleTypeKey [entityType=" + this.entityType + ", userRole=" + this.userRole + "]";
}
}

View file

@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.gbl.model.user;
import java.io.Serializable;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.validation.constraints.Email;
@ -17,6 +18,7 @@ import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import ch.ethz.seb.sebserver.gbl.api.authorization.RoleTypeKey;
import com.fasterxml.jackson.annotation.*;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
@ -111,6 +113,9 @@ public final class UserInfo implements UserAccount, Serializable {
@JsonProperty(ATTR_ENTITY_PRIVILEGES)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public final Collection<EntityPrivilege> entityPrivileges;
@JsonIgnore
public final Map<EntityKey, EntityPrivilege> entityPrivilegeMap;
@JsonProperty(ATTR_FEATURE_PRIVILEGES)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public final Collection<FeaturePrivilege> featurePrivileges;
@ -143,6 +148,10 @@ public final class UserInfo implements UserAccount, Serializable {
this.timeZone = timeZone;
this.roles = Utils.immutableSetOf(roles);
this.entityPrivileges = Utils.immutableCollectionOf(entityPrivileges);
this.entityPrivilegeMap = Utils.immutableMapOf(
this.entityPrivileges.stream().collect(Collectors.toMap(
e -> new EntityKey(e.entityId, e.entityType),
Function.identity())));
this.featurePrivileges = Utils.immutableCollectionOf(featurePrivileges);
}

View file

@ -28,7 +28,7 @@ import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege.RoleTypeKey;
import ch.ethz.seb.sebserver.gbl.api.authorization.RoleTypeKey;
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
import ch.ethz.seb.sebserver.gbl.model.GrantEntity;
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;

View file

@ -21,7 +21,7 @@ import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege;
import ch.ethz.seb.sebserver.gbl.api.authorization.Privilege.RoleTypeKey;
import ch.ethz.seb.sebserver.gbl.api.authorization.RoleTypeKey;
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
@ -36,7 +36,7 @@ public class AuthorizationServiceImpl implements AuthorizationService {
private final UserService userService;
/** Map of role based grants for specified entity types. */
private final Map<Privilege.RoleTypeKey, Privilege> privileges = new HashMap<>();
private final Map<RoleTypeKey, Privilege> privileges = new HashMap<>();
public AuthorizationServiceImpl(final UserService userService) {
this.userService = userService;