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,7 +87,7 @@ 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 | ||||
|  | @ -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…
	
	Add table
		
		Reference in a new issue
	
	 anhefti
						anhefti