SEBSERV-452 applied ExamPrivilege and FeaturePrivilege to UserInfo for future privilege improvements
This commit is contained in:
parent
4cc1eca23e
commit
5bea674ddc
14 changed files with 357 additions and 65 deletions
|
@ -24,7 +24,7 @@ import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
|||
|
||||
/** Defines a Privilege by combining a PrivilegeType for base (overall) rights,
|
||||
* institutional rights and ownership rights.
|
||||
*
|
||||
* <p>
|
||||
* A base-, institutional- and ownership- grant is checked in this exact order and the
|
||||
* first match fund makes a grant or a denied if none of the three privilege levels has a match */
|
||||
public final class Privilege {
|
||||
|
@ -87,11 +87,11 @@ public final class Privilege {
|
|||
}
|
||||
|
||||
/** Checks if this Privilege has a grant for a given context.
|
||||
*
|
||||
* <p>
|
||||
* The privilege grant check function always checks first the base privilege with no institutional or owner grant.
|
||||
* If user has a grant on base privileges this returns true without checking further institutional or owner grant
|
||||
* If user has no base privilege grant the function checks further grants, first the institutional grant, where
|
||||
* the institution id and the users institution id must match and further more the owner grant, where ownerId
|
||||
* the institution id and the users institution id must match and furthermore the owner grant, where ownerId
|
||||
* and the users id must match.
|
||||
*
|
||||
* @param userId The user identifier of the user to check the grant on
|
||||
|
@ -184,7 +184,7 @@ public final class Privilege {
|
|||
}
|
||||
|
||||
/** 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
|
||||
* If user account has UserRole.INSTITUTIONAL_ADMIN this is true if the given user account has
|
||||
* not the UserRole.SEB_SERVER_ADMIN (institutional administrators should not be able to edit SEB Server
|
||||
|
@ -197,17 +197,15 @@ public final class Privilege {
|
|||
public static boolean hasRoleBasedUserAccountEditGrant(final UserAccount userAccount, final UserInfo currentUser) {
|
||||
final EnumSet<UserRole> userRolesOfUserAccount = userAccount.getUserRoles();
|
||||
final EnumSet<UserRole> userRolesOfCurrentUser = currentUser.getUserRoles();
|
||||
|
||||
if (userRolesOfCurrentUser.contains(UserRole.SEB_SERVER_ADMIN)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (userRolesOfCurrentUser.contains(UserRole.INSTITUTIONAL_ADMIN)) {
|
||||
return !userRolesOfUserAccount.contains(UserRole.SEB_SERVER_ADMIN);
|
||||
}
|
||||
if (currentUser.equals(userAccount)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return currentUser.equals(userAccount);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,18 +8,38 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gbl.api.authorization;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/** Defines SEB-Server internal privilege types **/
|
||||
public enum PrivilegeType {
|
||||
/** No privilege type at all (placeholder) */
|
||||
NONE,
|
||||
NONE(0, 'n'),
|
||||
/** Only assigned entity privileges for the specific entity type. This is used as a marker to indicate that
|
||||
* the user has no overall entity type privileges but might have assigned entity privileges. */
|
||||
ASSIGNED(1, 'a'),
|
||||
/** The read privilege type for read access */
|
||||
READ,
|
||||
READ( 2, 'r'),
|
||||
/** The modify privilege type includes read-only type privilege plus privilege for editing right but without create
|
||||
* and delete
|
||||
* rights */
|
||||
MODIFY,
|
||||
* and delete rights */
|
||||
MODIFY(3, 'm'),
|
||||
/** The write privilege type including modify privilege type plus creation and deletion rights */
|
||||
WRITE;
|
||||
WRITE(4, 'w');
|
||||
|
||||
public final byte key;
|
||||
public final char code;
|
||||
|
||||
PrivilegeType(final int key, final char code) {
|
||||
this.key = (byte) key;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public static PrivilegeType byKey(final byte key) {
|
||||
return Arrays.stream(PrivilegeType.values()).filter(t -> t.key == key).findFirst().orElse(NONE);
|
||||
}
|
||||
|
||||
public static PrivilegeType byCode(final char code) {
|
||||
return Arrays.stream(PrivilegeType.values()).filter(t -> t.code == code).findFirst().orElse(NONE);
|
||||
}
|
||||
|
||||
/** Use this to check implicit privilege.
|
||||
* <p>
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2023 ETH Zürich, Educational Development and Technology (LET)
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.gbl.model.user;
|
||||
|
||||
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain.*;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class EntityPrivilege {
|
||||
|
||||
@JsonProperty(ENTITY_PRIVILEGE.ATTR_ID)
|
||||
public final Long id;
|
||||
|
||||
@JsonProperty(ENTITY_PRIVILEGE.ATTR_ENTITY_TYPE)
|
||||
public final EntityType entityType;
|
||||
|
||||
@JsonProperty(ENTITY_PRIVILEGE.ATTR_ENTITY_ID)
|
||||
public final Long entityId;
|
||||
|
||||
@JsonProperty(ENTITY_PRIVILEGE.ATTR_USER_UUID)
|
||||
public final String userUUID;
|
||||
|
||||
@JsonProperty(ENTITY_PRIVILEGE.ATTR_PRIVILEGE_TYPE)
|
||||
public final PrivilegeType privilegeType;
|
||||
|
||||
@JsonCreator
|
||||
public EntityPrivilege(
|
||||
@JsonProperty(ENTITY_PRIVILEGE.ATTR_ID) final Long id,
|
||||
@JsonProperty(ENTITY_PRIVILEGE.ATTR_ENTITY_TYPE) final EntityType entityType,
|
||||
@JsonProperty(ENTITY_PRIVILEGE.ATTR_ENTITY_ID) final Long entityId,
|
||||
@JsonProperty(ENTITY_PRIVILEGE.ATTR_USER_UUID) final String userUUID,
|
||||
@JsonProperty(ENTITY_PRIVILEGE.ATTR_PRIVILEGE_TYPE) final PrivilegeType privilegeType) {
|
||||
|
||||
this.id = id;
|
||||
this.entityType = entityType;
|
||||
this.entityId = entityId;
|
||||
this.userUUID = userUUID;
|
||||
this.privilegeType = privilegeType;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public EntityType getEntityType() {
|
||||
return this.entityType;
|
||||
}
|
||||
|
||||
public Long getEntityId() {
|
||||
return this.entityId;
|
||||
}
|
||||
|
||||
public String getUserUUID() {
|
||||
return this.userUUID;
|
||||
}
|
||||
|
||||
public PrivilegeType getPrivilegeType() {
|
||||
return this.privilegeType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final EntityPrivilege other = (EntityPrivilege) obj;
|
||||
return Objects.equals(this.id, other.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("EntityPrivilege [id=");
|
||||
builder.append(this.id);
|
||||
builder.append(", entityType=");
|
||||
builder.append(this.entityType);
|
||||
builder.append(", entityId=");
|
||||
builder.append(this.entityId);
|
||||
builder.append(", userUUID=");
|
||||
builder.append(this.userUUID);
|
||||
builder.append(", privilegeType=");
|
||||
builder.append(this.privilegeType);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package ch.ethz.seb.sebserver.gbl.model.user;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain.*;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class FeaturePrivilege {
|
||||
|
||||
@JsonProperty(FEATURE_PRIVILEGE.ATTR_ID)
|
||||
public final Long id;
|
||||
@JsonProperty(FEATURE_PRIVILEGE.ATTR_FEATURE_ID)
|
||||
public final Long featureId;
|
||||
|
||||
@JsonProperty(FEATURE_PRIVILEGE.ATTR_USER_UUID)
|
||||
public final String userUUID;
|
||||
|
||||
public FeaturePrivilege(
|
||||
@JsonProperty(FEATURE_PRIVILEGE.ATTR_ID) final Long id,
|
||||
@JsonProperty(FEATURE_PRIVILEGE.ATTR_FEATURE_ID) final Long featureId,
|
||||
@JsonProperty(FEATURE_PRIVILEGE.ATTR_USER_UUID) final String userUUID) {
|
||||
|
||||
this.id = id;
|
||||
this.featureId = featureId;
|
||||
this.userUUID = userUUID;
|
||||
}
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getFeatureId() {
|
||||
return featureId;
|
||||
}
|
||||
|
||||
public String getUserUUID() {
|
||||
return userUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
final FeaturePrivilege that = (FeaturePrivilege) o;
|
||||
return Objects.equals(id, that.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FeaturePrivilege{" +
|
||||
"id=" + id +
|
||||
", featureId=" + featureId +
|
||||
", userUUID='" + userUUID + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -8,12 +8,9 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gbl.model.user;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
|
@ -21,17 +18,13 @@ import javax.validation.constraints.NotEmpty;
|
|||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import com.fasterxml.jackson.annotation.*;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain.USER;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE;
|
||||
|
@ -40,16 +33,20 @@ import ch.ethz.seb.sebserver.gbl.model.EntityName;
|
|||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||
|
||||
/** The user info domain model contains primary user information
|
||||
*
|
||||
* <p>
|
||||
* This domain model is annotated and fully serializable and deserializable
|
||||
* to and from JSON within the Jackson library.
|
||||
*
|
||||
* <p>
|
||||
* This domain model is immutable and thread-save */
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public final class UserInfo implements UserAccount, Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 2526446136264377808L;
|
||||
|
||||
public static final String ATTR_ENTITY_PRIVILEGES = "entityPrivileges";
|
||||
public static final String ATTR_FEATURE_PRIVILEGES = "featurePrivileges";
|
||||
|
||||
public static final String FILTER_ATTR_SURNAME = "surname";
|
||||
public static final String FILTER_ATTR_USER_NAME = "username";
|
||||
public static final String FILTER_ATTR_EMAIL = "email";
|
||||
|
@ -112,6 +109,13 @@ public final class UserInfo implements UserAccount, Serializable {
|
|||
@JsonProperty(USER_ROLE.REFERENCE_NAME)
|
||||
public final Set<String> roles;
|
||||
|
||||
@JsonProperty(ATTR_ENTITY_PRIVILEGES)
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
public final Collection<EntityPrivilege> entityPrivileges;
|
||||
@JsonProperty(ATTR_FEATURE_PRIVILEGES)
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
public final Collection<FeaturePrivilege> featurePrivileges;
|
||||
|
||||
@JsonCreator
|
||||
public UserInfo(
|
||||
@JsonProperty(USER.ATTR_UUID) final String uuid,
|
||||
|
@ -124,7 +128,9 @@ public final class UserInfo implements UserAccount, Serializable {
|
|||
@JsonProperty(USER.ATTR_ACTIVE) final Boolean active,
|
||||
@JsonProperty(USER.ATTR_LANGUAGE) final Locale language,
|
||||
@JsonProperty(USER.ATTR_TIMEZONE) final DateTimeZone timeZone,
|
||||
@JsonProperty(USER_ROLE.REFERENCE_NAME) final Set<String> roles) {
|
||||
@JsonProperty(USER_ROLE.REFERENCE_NAME) final Set<String> roles,
|
||||
@JsonProperty(ATTR_ENTITY_PRIVILEGES) final Collection<EntityPrivilege> entityPrivileges,
|
||||
@JsonProperty(ATTR_FEATURE_PRIVILEGES) final Collection<FeaturePrivilege> featurePrivileges) {
|
||||
|
||||
this.uuid = uuid;
|
||||
this.institutionId = institutionId;
|
||||
|
@ -137,6 +143,8 @@ public final class UserInfo implements UserAccount, Serializable {
|
|||
this.language = language;
|
||||
this.timeZone = timeZone;
|
||||
this.roles = Utils.immutableSetOf(roles);
|
||||
this.entityPrivileges = Utils.immutableCollectionOf(entityPrivileges);
|
||||
this.featurePrivileges = Utils.immutableCollectionOf(featurePrivileges);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -213,6 +221,14 @@ public final class UserInfo implements UserAccount, Serializable {
|
|||
return this.roles;
|
||||
}
|
||||
|
||||
public Collection<EntityPrivilege> getEntityPrivileges() {
|
||||
return entityPrivileges;
|
||||
}
|
||||
|
||||
public Collection<FeaturePrivilege> getFeaturePrivileges() {
|
||||
return featurePrivileges;
|
||||
}
|
||||
|
||||
@Override
|
||||
@JsonIgnore
|
||||
public EnumSet<UserRole> getUserRoles() {
|
||||
|
@ -323,7 +339,9 @@ public final class UserInfo implements UserAccount, Serializable {
|
|||
userInfo.getActive(),
|
||||
userInfo.getLanguage(),
|
||||
userInfo.getTimeZone(),
|
||||
userInfo.roles);
|
||||
userInfo.roles,
|
||||
userInfo.entityPrivileges,
|
||||
userInfo.featurePrivileges);
|
||||
}
|
||||
|
||||
/** Use this to create a copy of a given UserInfo by overriding available arguments.
|
||||
|
@ -358,7 +376,9 @@ public final class UserInfo implements UserAccount, Serializable {
|
|||
userInfo.getActive(),
|
||||
(language != null) ? language : userInfo.getLanguage(),
|
||||
(timeZone != null) ? timeZone : userInfo.getTimeZone(),
|
||||
(roles != null) ? new HashSet<>(Arrays.asList(roles)) : userInfo.roles);
|
||||
(roles != null) ? new HashSet<>(Arrays.asList(roles)) : userInfo.roles,
|
||||
userInfo.entityPrivileges,
|
||||
userInfo.featurePrivileges);
|
||||
}
|
||||
|
||||
public static UserInfo withEMail(final UserInfo userInfo, final String email) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.beans.PropertyEditorSupport;
|
|||
import java.security.Principal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -140,11 +141,12 @@ public class UserServiceImpl implements UserService {
|
|||
private static final SEBServerUser ANONYMOUS_USER = new SEBServerUser(
|
||||
-1L,
|
||||
new UserInfo("SEB_SERVER_ANONYMOUS_USER", -2L, null, "anonymous", "anonymous", "anonymous", null, false,
|
||||
null,
|
||||
null,
|
||||
null, null,
|
||||
Arrays.stream(UserRole.values())
|
||||
.map(Enum::name)
|
||||
.collect(Collectors.toSet())),
|
||||
.collect(Collectors.toSet()),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList()),
|
||||
null);
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,11 @@ import java.util.stream.Collectors;
|
|||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.api.authorization.PrivilegeType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.*;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.*;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.EntityPrivilegeRecord;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.FeaturePrivilegeRecord;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.joda.time.DateTime;
|
||||
|
@ -47,16 +52,8 @@ import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
|||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityDependency;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||
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.UserMod;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.InstitutionRecordDynamicSqlSupport;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.RoleRecordDynamicSqlSupport;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.RoleRecordMapper;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserRecordDynamicSqlSupport;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.UserRecordMapper;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.RoleRecord;
|
||||
import ch.ethz.seb.sebserver.webservice.datalayer.batis.model.UserRecord;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.impl.SEBServerUser;
|
||||
|
@ -75,15 +72,21 @@ public class UserDAOImpl implements UserDAO {
|
|||
|
||||
private final UserRecordMapper userRecordMapper;
|
||||
private final RoleRecordMapper roleRecordMapper;
|
||||
private final EntityPrivilegeRecordMapper entityPrivilegeRecordMapper;
|
||||
private final FeaturePrivilegeRecordMapper featurePrivilegeRecordMapper;
|
||||
private final PasswordEncoder userPasswordEncoder;
|
||||
|
||||
public UserDAOImpl(
|
||||
final UserRecordMapper userRecordMapper,
|
||||
final RoleRecordMapper roleRecordMapper,
|
||||
final EntityPrivilegeRecordMapper entityPrivilegeRecordMapper,
|
||||
final FeaturePrivilegeRecordMapper featurePrivilegeRecordMapper,
|
||||
@Qualifier(WebSecurityConfig.USER_PASSWORD_ENCODER_BEAN_NAME) final PasswordEncoder userPasswordEncoder) {
|
||||
|
||||
this.userRecordMapper = userRecordMapper;
|
||||
this.roleRecordMapper = roleRecordMapper;
|
||||
this.entityPrivilegeRecordMapper = entityPrivilegeRecordMapper;
|
||||
this.featurePrivilegeRecordMapper = featurePrivilegeRecordMapper;
|
||||
this.userPasswordEncoder = userPasswordEncoder;
|
||||
}
|
||||
|
||||
|
@ -442,7 +445,7 @@ public class UserDAOImpl implements UserDAO {
|
|||
} else {
|
||||
try {
|
||||
|
||||
if (keys == null || keys.isEmpty()) {
|
||||
if (keys.isEmpty()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
|
@ -524,6 +527,7 @@ public class UserDAOImpl implements UserDAO {
|
|||
|
||||
return Result.tryCatch(() -> {
|
||||
|
||||
final String uuid = record.getUuid();
|
||||
final List<RoleRecord> roles = getRoles(record);
|
||||
Set<String> userRoles = Collections.emptySet();
|
||||
if (roles != null) {
|
||||
|
@ -534,7 +538,7 @@ public class UserDAOImpl implements UserDAO {
|
|||
}
|
||||
|
||||
return new UserInfo(
|
||||
record.getUuid(),
|
||||
uuid,
|
||||
record.getInstitutionId(),
|
||||
record.getCreationDate(),
|
||||
record.getName(),
|
||||
|
@ -544,10 +548,66 @@ public class UserDAOImpl implements UserDAO {
|
|||
BooleanUtils.toBooleanObject(record.getActive()),
|
||||
Locale.forLanguageTag(record.getLanguage()),
|
||||
DateTimeZone.forID(record.getTimezone()),
|
||||
userRoles);
|
||||
userRoles,
|
||||
getEntityPrivileges(uuid),
|
||||
getFeaturePrivileges(uuid));
|
||||
});
|
||||
}
|
||||
|
||||
private Collection<FeaturePrivilege> getFeaturePrivileges(final String uuid) {
|
||||
try {
|
||||
|
||||
return this.featurePrivilegeRecordMapper
|
||||
.selectByExample()
|
||||
.where(FeaturePrivilegeRecordDynamicSqlSupport.userUuid, isEqualTo(uuid))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
.map(this::toFeaturePrivilegeModel)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to load feature privileges for user: {}", uuid);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Collection<EntityPrivilege> getEntityPrivileges(final String uuid) {
|
||||
try {
|
||||
|
||||
return this.entityPrivilegeRecordMapper
|
||||
.selectByExample()
|
||||
.where(EntityPrivilegeRecordDynamicSqlSupport.userUuid, isEqualTo(uuid))
|
||||
.build()
|
||||
.execute()
|
||||
.stream()
|
||||
.map(this::toEntityPrivilegeModel)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
} catch (final Exception e) {
|
||||
log.error("Failed to load entity privileges for user: {}", uuid);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private EntityPrivilege toEntityPrivilegeModel(final EntityPrivilegeRecord record) {
|
||||
return new EntityPrivilege(
|
||||
record.getId(),
|
||||
EntityType.valueOf(record.getEntityType()),
|
||||
record.getEntityId(),
|
||||
record.getUserUuid(),
|
||||
PrivilegeType.byKey(record.getPrivilegeType()));
|
||||
}
|
||||
|
||||
private FeaturePrivilege toFeaturePrivilegeModel(final FeaturePrivilegeRecord record) {
|
||||
return new FeaturePrivilege(
|
||||
record.getId(),
|
||||
record.getFeatureId(),
|
||||
record.getUserUuid());
|
||||
}
|
||||
|
||||
private Result<SEBServerUser> sebServerUserFromRecord(final UserRecord record) {
|
||||
return toDomainModel(record)
|
||||
.map(userInfo -> new SEBServerUser(
|
||||
|
|
|
@ -85,7 +85,9 @@ public class ModelObjectJSONGenerator {
|
|||
|
||||
Object domainObject = new UserInfo("uuid", 1L, DateTime.now(), "name", "surname", "username", "email",
|
||||
true, Locale.ENGLISH, DateTimeZone.UTC,
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name(), UserRole.EXAM_SUPPORTER.name())));
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name(), UserRole.EXAM_SUPPORTER.name())),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
|
||||
System.out.println(domainObject.getClass().getSimpleName() + ":");
|
||||
System.out.println(writerWithDefaultPrettyPrinter.writeValueAsString(domainObject));
|
||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gbl.model.user;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -29,15 +30,21 @@ public class UserInfoTest {
|
|||
new UserInfo("id1", 1L, new DateTime(0, DateTimeZone.UTC), "user1", "", "user1", "user1@inst2.none",
|
||||
true, Locale.ENGLISH,
|
||||
DateTimeZone.UTC,
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name()))),
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name())),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList()),
|
||||
new UserInfo("id2", 3L, new DateTime(0, DateTimeZone.UTC), "user2", "", "user2", "user2@inst2.none",
|
||||
true, Locale.ENGLISH,
|
||||
DateTimeZone.UTC,
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name()))),
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name())),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList()),
|
||||
new UserInfo("id3", 4L, new DateTime(0, DateTimeZone.UTC), "user3", "", "user3", "user3@inst2.none",
|
||||
false, Locale.GERMAN,
|
||||
DateTimeZone.UTC,
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name())))));
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name())),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList())));
|
||||
|
||||
final JSONMapper jsonMapper = new JSONMapper();
|
||||
//final ObjectWriter writerWithDefaultPrettyPrinter = jsonMapper.writerWithDefaultPrettyPrinter();
|
||||
|
|
|
@ -10,10 +10,7 @@ package ch.ethz.seb.sebserver.webservice.integration.api.admin;
|
|||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
@ -59,7 +56,11 @@ public class ConfigurationAttributeAPITest extends AdministrationAPIIntegrationT
|
|||
this.userServiceImpl.setAuthenticationIfAbsent(new SEBServerUser(
|
||||
-1L,
|
||||
new UserInfo("user1", 1L, null, "admin", null, null, null, true, null, null,
|
||||
EnumSet.allOf(UserRole.class).stream().map(r -> r.name()).collect(Collectors.toSet())),
|
||||
EnumSet.allOf(UserRole.class).stream().map(r -> r.name()).collect(Collectors.toSet()),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList()
|
||||
|
||||
),
|
||||
null));
|
||||
Mockito.when(this.mockRequest.getQueryString()).thenReturn("");
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.webservice.integration.api.admin;
|
|||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -55,7 +56,9 @@ public class OrientationAPITest extends AdministrationAPIIntegrationTester {
|
|||
this.userServiceImpl.setAuthenticationIfAbsent(new SEBServerUser(
|
||||
-1L,
|
||||
new UserInfo("user1", 1L, null, "admin", null, null, null, true, null, null,
|
||||
EnumSet.allOf(UserRole.class).stream().map(r -> r.name()).collect(Collectors.toSet())),
|
||||
EnumSet.allOf(UserRole.class).stream().map(r -> r.name()).collect(Collectors.toSet()),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList()),
|
||||
null));
|
||||
Mockito.when(this.mockRequest.getQueryString()).thenReturn("");
|
||||
}
|
||||
|
|
|
@ -12,12 +12,7 @@ import static org.junit.Assert.*;
|
|||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
@ -598,7 +593,9 @@ public class UserAPITest extends AdministrationAPIIntegrationTester {
|
|||
user.getActive(),
|
||||
user.getLanguage(),
|
||||
user.getTimeZone(),
|
||||
Stream.of(UserRole.EXAM_ADMIN.name(), UserRole.EXAM_SUPPORTER.name()).collect(Collectors.toSet()));
|
||||
Stream.of(UserRole.EXAM_ADMIN.name(), UserRole.EXAM_SUPPORTER.name()).collect(Collectors.toSet()),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
final String modifyUserJson = this.jsonMapper.writeValueAsString(modifyUser);
|
||||
|
||||
UserInfo modifiedUserResult = this.jsonMapper.readValue(
|
||||
|
@ -756,7 +753,9 @@ public class UserAPITest extends AdministrationAPIIntegrationTester {
|
|||
final UserInfo userInfo = new UserInfo(
|
||||
"NewTestUser", 2L, new DateTime(0, DateTimeZone.UTC), "NewTestUser", "", "NewTestUser",
|
||||
"", true, Locale.CANADA, DateTimeZone.UTC,
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name())));
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name())),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
final String newUserJson = this.jsonMapper.writeValueAsString(userInfo);
|
||||
this.mockMvc.perform(put(this.endpoint + API.USER_ACCOUNT_ENDPOINT)
|
||||
.header("Authorization", "Bearer " + token)
|
||||
|
@ -783,7 +782,9 @@ public class UserAPITest extends AdministrationAPIIntegrationTester {
|
|||
final UserInfo userInfo = new UserInfo(
|
||||
"NewTestUser", 2L, new DateTime(0, DateTimeZone.UTC), "NewTestUser", "", "NewTestUser",
|
||||
"", true, Locale.CANADA, DateTimeZone.UTC,
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name())));
|
||||
new HashSet<>(Arrays.asList(UserRole.EXAM_ADMIN.name())),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
//final UserMod newUser = new UserMod(userInfo, "12345678", "12345678");
|
||||
final String newUserJson = this.jsonMapper.writeValueAsString(userInfo);
|
||||
this.mockMvc.perform(put(this.endpoint + API.USER_ACCOUNT_ENDPOINT)
|
||||
|
|
|
@ -75,7 +75,9 @@ public class AuthorizationServiceTest {
|
|||
DateTimeZone.UTC,
|
||||
roles != null
|
||||
? new HashSet<>(Arrays.asList(roles).stream().map(r -> r.name()).collect(Collectors.toList()))
|
||||
: Collections.emptySet());
|
||||
: Collections.emptySet(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
return new SEBServerUser(0L, userInfo, "");
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import static org.junit.Assert.*;
|
|||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
@ -145,7 +146,11 @@ public class ExamJITSIProctoringServiceTest {
|
|||
private JitsiProctoringService getMockup() {
|
||||
final UserService userService = Mockito.mock(UserService.class);
|
||||
Mockito.when(userService.getCurrentUser()).thenReturn(new SEBServerUser(1L,
|
||||
new UserInfo("1", 1L, null, "proctor-user", null, null, null, null, null, null, null), ""));
|
||||
new UserInfo("1", 1L, null, "proctor-user", null,
|
||||
null, null, null, null, null, null,
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList())
|
||||
, ""));
|
||||
|
||||
final AuthorizationService authorizationService = Mockito.mock(AuthorizationService.class);
|
||||
Mockito.when(authorizationService.getUserService()).thenReturn(userService);
|
||||
|
|
Loading…
Reference in a new issue