diff --git a/src/main/java/org/hostsharing/hsadminng/HsadminNgApp.java b/src/main/java/org/hostsharing/hsadminng/HsadminNgApp.java index d96b3bd5..52e4136f 100644 --- a/src/main/java/org/hostsharing/hsadminng/HsadminNgApp.java +++ b/src/main/java/org/hostsharing/hsadminng/HsadminNgApp.java @@ -3,8 +3,6 @@ package org.hostsharing.hsadminng; import org.hostsharing.hsadminng.config.ApplicationProperties; import org.hostsharing.hsadminng.config.DefaultProfileUtil; -import org.hostsharing.hsadminng.security.SecurityUtils; -import org.hostsharing.hsadminng.service.accessfilter.Role; import io.github.jhipster.config.JHipsterConstants; @@ -60,14 +58,6 @@ public class HsadminNgApp { "You have misconfigured your application! It should not " + "run with both the 'dev' and 'cloud' profiles at the same time."); } - - // TODO: remove this hack once proper user roles are implemented - if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT)) { - // For some strange reasons, HsadminNgApp is created in locally running tests, - // but not on Jenkins, therefore the login user had no rights and many tests - // failed. - SecurityUtils.addUserRole(null, null, Role.HOSTMASTER); - } } /** diff --git a/src/main/java/org/hostsharing/hsadminng/config/CacheConfiguration.java b/src/main/java/org/hostsharing/hsadminng/config/CacheConfiguration.java index 73cf132f..02c5479a 100644 --- a/src/main/java/org/hostsharing/hsadminng/config/CacheConfiguration.java +++ b/src/main/java/org/hostsharing/hsadminng/config/CacheConfiguration.java @@ -36,6 +36,10 @@ public class CacheConfiguration { cm.createCache(org.hostsharing.hsadminng.repository.UserRepository.USERS_BY_LOGIN_CACHE, jcacheConfiguration); cm.createCache(org.hostsharing.hsadminng.repository.UserRepository.USERS_BY_EMAIL_CACHE, jcacheConfiguration); // jhipster-needle-ehcache-add-entry + + cm.createCache( + org.hostsharing.hsadminng.repository.UserRoleAssignmentRepository.CURRENT_USER_ROLE_ASSIGNMENTS_CACHE, + jcacheConfiguration); }; } } diff --git a/src/main/java/org/hostsharing/hsadminng/domain/UserRoleAssignment.java b/src/main/java/org/hostsharing/hsadminng/domain/UserRoleAssignment.java index e2021eeb..dfe5ea18 100644 --- a/src/main/java/org/hostsharing/hsadminng/domain/UserRoleAssignment.java +++ b/src/main/java/org/hostsharing/hsadminng/domain/UserRoleAssignment.java @@ -1,7 +1,7 @@ // Licensed under Apache-2.0 package org.hostsharing.hsadminng.domain; -import org.hostsharing.hsadminng.domain.enumeration.UserRole; +import org.hostsharing.hsadminng.service.accessfilter.Role; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -37,13 +37,14 @@ public class UserRoleAssignment implements Serializable { @NotNull @Enumerated(EnumType.STRING) @Column(name = "assigned_role", nullable = false) - private UserRole assignedRole; + private Role assignedRole; @ManyToOne @JsonIgnoreProperties("requireds") private User user; // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove + public Long getId() { return id; } @@ -78,16 +79,16 @@ public class UserRoleAssignment implements Serializable { this.entityObjectId = entityObjectId; } - public UserRole getAssignedRole() { + public Role getAssignedRole() { return assignedRole; } - public UserRoleAssignment assignedRole(UserRole assignedRole) { + public UserRoleAssignment assignedRole(Role assignedRole) { this.assignedRole = assignedRole; return this; } - public void setAssignedRole(UserRole assignedRole) { + public void setAssignedRole(Role assignedRole) { this.assignedRole = assignedRole; } @@ -103,6 +104,7 @@ public class UserRoleAssignment implements Serializable { public void setUser(User user) { this.user = user; } + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove @Override diff --git a/src/main/java/org/hostsharing/hsadminng/domain/enumeration/UserRole.java b/src/main/java/org/hostsharing/hsadminng/domain/enumeration/UserRole.java deleted file mode 100644 index 86bfa199..00000000 --- a/src/main/java/org/hostsharing/hsadminng/domain/enumeration/UserRole.java +++ /dev/null @@ -1,15 +0,0 @@ -// Licensed under Apache-2.0 -package org.hostsharing.hsadminng.domain.enumeration; - -/** - * The UserRole enumeration. - */ -public enum UserRole { - HOSTMASTER, - ADMIN, - SUPPORTER, - CONTRACTUAL_CONTACT, - FINANCIAL_CONTACT, - TECHNICAL_CONTACT, - CUSTOMER_USER -} diff --git a/src/main/java/org/hostsharing/hsadminng/repository/UserRoleAssignmentRepository.java b/src/main/java/org/hostsharing/hsadminng/repository/UserRoleAssignmentRepository.java index 167f37a0..0fdf64c9 100644 --- a/src/main/java/org/hostsharing/hsadminng/repository/UserRoleAssignmentRepository.java +++ b/src/main/java/org/hostsharing/hsadminng/repository/UserRoleAssignmentRepository.java @@ -3,7 +3,10 @@ package org.hostsharing.hsadminng.repository; import org.hostsharing.hsadminng.domain.UserRoleAssignment; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.data.jpa.repository.*; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.util.List; @@ -16,7 +19,14 @@ import java.util.List; public interface UserRoleAssignmentRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("select user_role_assignment from UserRoleAssignment user_role_assignment where user_role_assignment.user.login = ?#{principal.username}") - List findByUserIsCurrentUser(); + String CURRENT_USER_ROLE_ASSIGNMENTS_CACHE = "currentUserRoleAssignments"; + // TODO mhoennig: optimize with query by id + @Cacheable(CURRENT_USER_ROLE_ASSIGNMENTS_CACHE) + @Query("select user_role_assignment from UserRoleAssignment user_role_assignment where user_role_assignment.user.login = :login") + List findByLogin(@Param("login") final String login); + + @CacheEvict(value = CURRENT_USER_ROLE_ASSIGNMENTS_CACHE, allEntries = true) + default void evictCache() { + } } diff --git a/src/main/java/org/hostsharing/hsadminng/security/SecurityUtils.java b/src/main/java/org/hostsharing/hsadminng/security/SecurityUtils.java index 0145b2f6..1096009e 100644 --- a/src/main/java/org/hostsharing/hsadminng/security/SecurityUtils.java +++ b/src/main/java/org/hostsharing/hsadminng/security/SecurityUtils.java @@ -1,16 +1,12 @@ // Licensed under Apache-2.0 package org.hostsharing.hsadminng.security; -import org.hostsharing.hsadminng.service.accessfilter.Role; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; -import java.util.ArrayList; -import java.util.List; import java.util.Optional; /** @@ -20,8 +16,6 @@ public final class SecurityUtils { private static final Logger log = LoggerFactory.getLogger(SecurityUtils.class); - private static List userRoleAssignments = new ArrayList<>(); - private SecurityUtils() { } @@ -83,52 +77,12 @@ public final class SecurityUtils { */ public static boolean isCurrentUserInRole(String authority) { SecurityContext securityContext = SecurityContextHolder.getContext(); - return Optional.ofNullable(securityContext.getAuthentication()) + final Boolean isCurrentUserInRole = Optional.ofNullable(securityContext.getAuthentication()) .map( authentication -> authentication.getAuthorities() .stream() .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(authority))) .orElse(false); - } - - public static Role getLoginUserRoleFor(final Class onDtoClass, final Long onId) { - final Role highestRole = userRoleAssignments.stream() - .map( - ura -> matches(onDtoClass, onId, ura) - ? ura.role - : Role.ANYBODY) - .reduce(Role.ANYBODY, (r1, r2) -> r1.covers(r2) ? r1 : r2); - log.debug("getLoginUserRoleFor({}, {}) returned {}", onDtoClass, onId, highestRole); - return highestRole; - } - - private static boolean matches(Class onDtoClass, Long onId, UserRoleAssignment ura) { - final boolean matches = (ura.onClass == null || onDtoClass == ura.onClass) - && (ura.onId == null || ura.onId.equals(onId)); - return matches; - } - - // TODO: depends on https://plan.hostsharing.net/project/hsadmin/us/67?milestone=34 - public static void addUserRole(final Class onClass, final Long onId, final Role role) { - log.info("addUserRole({}, {}, {})", onClass, onId, role); - userRoleAssignments.add(new UserRoleAssignment(onClass, onId, role)); - - } - - public static void clearUserRoles() { - userRoleAssignments.clear(); - } - - private static class UserRoleAssignment { - - final Class onClass; - final Long onId; - final Role role; - - UserRoleAssignment(Class onClass, Long onId, Role role) { - this.onClass = onClass; - this.onId = onId; - this.role = role; - } + return isCurrentUserInRole; } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/UserRoleAssignmentService.java b/src/main/java/org/hostsharing/hsadminng/service/UserRoleAssignmentService.java index cb43d61b..e9db678d 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/UserRoleAssignmentService.java +++ b/src/main/java/org/hostsharing/hsadminng/service/UserRoleAssignmentService.java @@ -1,8 +1,13 @@ // Licensed under Apache-2.0 package org.hostsharing.hsadminng.service; +import static com.google.common.base.Verify.verify; + import org.hostsharing.hsadminng.domain.UserRoleAssignment; +import org.hostsharing.hsadminng.repository.UserRepository; import org.hostsharing.hsadminng.repository.UserRoleAssignmentRepository; +import org.hostsharing.hsadminng.security.SecurityUtils; +import org.hostsharing.hsadminng.service.accessfilter.Role; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,7 +16,10 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Collections; import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; /** * Service Implementation for managing UserRoleAssignment. @@ -24,7 +32,9 @@ public class UserRoleAssignmentService { private final UserRoleAssignmentRepository userRoleAssignmentRepository; - public UserRoleAssignmentService(UserRoleAssignmentRepository userRoleAssignmentRepository) { + public UserRoleAssignmentService( + final UserRepository userRepository, + final UserRoleAssignmentRepository userRoleAssignmentRepository) { this.userRoleAssignmentRepository = userRoleAssignmentRepository; } @@ -72,4 +82,30 @@ public class UserRoleAssignmentService { log.debug("Request to delete UserRoleAssignment : {}", id); userRoleAssignmentRepository.deleteById(id); } + + /** + * Collects all roles assigned to the current login user for the specified entity. + * + * @param entityTypeId the type id of the entity, e.g. "customer.Customer", not null + * @param entityObjectId id of entity instance in given entity type + * @return a set of all roles assigned to the current login user + */ + public Set getEffectiveRoleOfCurrentUser(final String entityTypeId, final long entityObjectId) { + verify(entityTypeId != null); + + // findByLogin is cached, thus I presume this is faster more specific query which would result in many DB roundtrips + final Set roles = SecurityUtils.getCurrentUserLogin() + .map( + login -> userRoleAssignmentRepository.findByLogin(login) + .stream() + .filter(ura -> matches(entityTypeId, entityObjectId, ura)) + .map(UserRoleAssignment::getAssignedRole) + .collect(Collectors.toSet())) + .orElse(Collections.emptySet()); + return roles; + } + + private static boolean matches(final String entityTypeId, final long entityObjectId, final UserRoleAssignment ura) { + return ura.getEntityTypeId().equals(entityTypeId) && ura.getEntityObjectId().equals(entityObjectId); + } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilter.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilter.java index e1aed4bf..93d67f04 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilter.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilter.java @@ -2,9 +2,13 @@ package org.hostsharing.hsadminng.service.accessfilter; import static com.google.common.base.Verify.verify; +import static com.google.common.collect.Sets.union; +import static java.util.Collections.EMPTY_SET; +import static org.thymeleaf.util.SetUtils.singletonSet; import org.hostsharing.hsadminng.security.SecurityUtils; import org.hostsharing.hsadminng.service.IdToDtoResolver; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.dto.MembershipDTO; import org.hostsharing.hsadminng.service.util.ReflectionUtil; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; @@ -14,16 +18,22 @@ import org.springframework.context.ApplicationContext; import java.lang.annotation.Annotation; import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; abstract class JSonAccessFilter { private final ApplicationContext ctx; + private final UserRoleAssignmentService userRoleAssignmentService; + final T dto; final Field selfIdField; final Field parentIdField; - JSonAccessFilter(final ApplicationContext ctx, final T dto) { + JSonAccessFilter(final ApplicationContext ctx, final UserRoleAssignmentService userRoleAssignmentService, final T dto) { this.ctx = ctx; + this.userRoleAssignmentService = userRoleAssignmentService; this.dto = dto; this.selfIdField = determineFieldWithAnnotation(dto.getClass(), SelfId.class); this.parentIdField = determineFieldWithAnnotation(dto.getClass(), ParentId.class); @@ -45,25 +55,23 @@ abstract class JSonAccessFilter { } /** - * @return the role of the login user in relation to the dto, this filter is created for. + * @return all roles of the login user in relation to the dto, for which this filter is created. */ - Role getLoginUserRole() { - final Role roleOnSelf = getLoginUserRoleOnSelf(); - if (roleOnSelf.isIndependent()) { - return roleOnSelf; - } - return getLoginUserRoleOnAncestorOfDtoClassIfHigher(roleOnSelf, dto); + Set getLoginUserRoles() { + final Set independentRoles = Arrays.stream(Role.values()) + // TODO mhoennig: ugly and risky filter condition => refactor! + .filter(role -> role.isIndependent() && SecurityUtils.isCurrentUserInRole(role.asAuthority())) + .collect(Collectors.toSet()); + + final Set rolesOnThis = getId() != null ? getLoginUserDirectRolesFor(dto.getClass(), getId()) : EMPTY_SET; + return union(independentRoles, union(rolesOnThis, getLoginUserRoleOnAncestorIfHigher(dto))); } - private Role getLoginUserRoleOnSelf() { - return SecurityUtils.getLoginUserRoleFor(dto.getClass(), getId()); - } - - private Role getLoginUserRoleOnAncestorOfDtoClassIfHigher(final Role baseRole, final Object dto) { + private Set getLoginUserRoleOnAncestorIfHigher(final Object dto) { final Field parentIdField = determineFieldWithAnnotation(dto.getClass(), ParentId.class); if (parentIdField == null) { - return baseRole; + return singletonSet(Role.ANYBODY); } final ParentId parentIdAnnot = parentIdField.getAnnotation(ParentId.class); @@ -72,10 +80,23 @@ abstract class JSonAccessFilter { final Class parentDtoClass = ReflectionUtil. determineGenericInterfaceParameter(parentDtoLoader, rawType, 0); final Long parentId = ReflectionUtil.getValue(dto, parentIdField); - final Role roleOnParent = SecurityUtils.getLoginUserRoleFor(parentDtoClass, parentId); + final Set rolesOnParent = getLoginUserDirectRolesFor(parentDtoClass, parentId); final Object parentEntity = loadDto(parentDtoLoader, parentId); - return Role.broadest(baseRole, getLoginUserRoleOnAncestorOfDtoClassIfHigher(roleOnParent, parentEntity)); + return union(rolesOnParent, getLoginUserRoleOnAncestorIfHigher(parentEntity)); + } + + private Set getLoginUserDirectRolesFor(final Class dtoClass, final Long id) { + if (!SecurityUtils.isAuthenticated()) { + return singletonSet(Role.ANYBODY); + } + + final EntityTypeId entityTypeId = dtoClass.getAnnotation(EntityTypeId.class); + if (entityTypeId == null) { + return singletonSet(Role.ANYBODY); // TODO mhoennig: all of such singletonSets -> emptySet + } + + return userRoleAssignmentService.getEffectiveRoleOfCurrentUser(entityTypeId.value(), id); } @SuppressWarnings("unchecked") diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializationWithAccessFilter.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializationWithAccessFilter.java index c594ebc8..c79f4809 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializationWithAccessFilter.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializationWithAccessFilter.java @@ -3,6 +3,7 @@ package org.hostsharing.hsadminng.service.accessfilter; import static org.hostsharing.hsadminng.service.util.ReflectionUtil.unchecked; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.util.ReflectionUtil; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; @@ -10,6 +11,7 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.node.*; +import com.google.common.base.Joiner; import org.apache.commons.lang3.NotImplementedException; import org.apache.commons.lang3.ObjectUtils; @@ -35,10 +37,11 @@ public class JSonDeserializationWithAccessFilter extends JSonAccessFilter public JSonDeserializationWithAccessFilter( final ApplicationContext ctx, + final UserRoleAssignmentService userRoleAssignmentService, final JsonParser jsonParser, final DeserializationContext deserializationContext, Class dtoClass) { - super(ctx, unchecked(dtoClass::newInstance)); + super(ctx, userRoleAssignmentService, unchecked(dtoClass::newInstance)); this.treeNode = unchecked(() -> jsonParser.getCodec().readTree(jsonParser)); } @@ -151,26 +154,28 @@ public class JSonDeserializationWithAccessFilter extends JSonAccessFilter field -> { // TODO this ugly code needs cleanup if (!field.equals(selfIdField)) { - final Role role = getLoginUserRole(); + final Set roles = getLoginUserRoles(); if (isInitAccess()) { - if (!role.isAllowedToInit(field)) { + if (!isAllowedToInit(roles, field)) { if (!field.equals(parentIdField)) { throw new BadRequestAlertException( - "Initialization of field " + toDisplay(field) + " prohibited for current user role " - + role, + "Initialization of field " + toDisplay(field) + + " prohibited for current user roles " + + Joiner.on("+").join(roles), toDisplay(field), "initializationProhibited"); } else { throw new BadRequestAlertException( - "Referencing field " + toDisplay(field) + " prohibited for current user role " - + role, + "Referencing field " + toDisplay(field) + " prohibited for current user roles " + + Joiner.on("+").join(roles), toDisplay(field), "referencingProhibited"); } } - } else if (!Role.toBeIgnoredForUpdates(field) && !getLoginUserRole().isAllowedToUpdate(field)) { + } else if (!Role.toBeIgnoredForUpdates(field) && !isAllowedToUpdate(getLoginUserRoles(), field)) { throw new BadRequestAlertException( - "Update of field " + toDisplay(field) + " prohibited for current user role " + role, + "Update of field " + toDisplay(field) + " prohibited for current user roles " + + Joiner.on("+").join(roles), toDisplay(field), "updateProhibited"); } @@ -178,6 +183,24 @@ public class JSonDeserializationWithAccessFilter extends JSonAccessFilter }); } + private boolean isAllowedToInit(final Set roles, final Field field) { + for (Role role : roles) { + if (role.isAllowedToInit(field)) { + return true; + } + } + return false; + } + + private boolean isAllowedToUpdate(final Set roles, final Field field) { + for (Role role : roles) { + if (role.isAllowedToUpdate(field)) { + return true; + } + } + return false; + } + private boolean isInitAccess() { return getId() == null; } diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializationWithAccessFilter.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializationWithAccessFilter.java index 0b61e0c1..904660e8 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializationWithAccessFilter.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializationWithAccessFilter.java @@ -1,6 +1,7 @@ // Licensed under Apache-2.0 package org.hostsharing.hsadminng.service.accessfilter; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.util.ReflectionUtil; import com.fasterxml.jackson.core.JsonGenerator; @@ -13,6 +14,7 @@ import java.io.IOException; import java.lang.reflect.Field; import java.math.BigDecimal; import java.time.LocalDate; +import java.util.Set; /** * Actual implementation of JSON serialization, where {link JsonSerializerWithAccessFilter} @@ -28,10 +30,11 @@ public class JSonSerializationWithAccessFilter extends JSonAccessFilter { public JSonSerializationWithAccessFilter( final ApplicationContext ctx, + final UserRoleAssignmentService userRoleAssignmentService, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider, final T dto) { - super(ctx, dto); + super(ctx, userRoleAssignmentService, dto); this.jsonGenerator = jsonGenerator; this.serializerProvider = serializerProvider; } @@ -47,7 +50,7 @@ public class JSonSerializationWithAccessFilter extends JSonAccessFilter { } private void toJSon(final Object dto, final JsonGenerator jsonGenerator, final Field field) throws IOException { - if (getLoginUserRole().isAllowedToRead(field)) { + if (isAllowedToRead(getLoginUserRoles(), field)) { final String fieldName = field.getName(); // TODO: maybe replace by serializerProvider.defaultSerialize...()? // But that makes it difficult for parallel structure with the deserializer (clumsy API). @@ -77,4 +80,13 @@ public class JSonSerializationWithAccessFilter extends JSonAccessFilter { } } + private boolean isAllowedToRead(final Set roles, final Field field) { + for (Role role : roles) { + if (role.isAllowedToRead(field)) { + return true; + } + } + return false; + } + } diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JsonDeserializerWithAccessFilter.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JsonDeserializerWithAccessFilter.java index 19e8255a..85dc4130 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JsonDeserializerWithAccessFilter.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JsonDeserializerWithAccessFilter.java @@ -1,6 +1,7 @@ // Licensed under Apache-2.0 package org.hostsharing.hsadminng.service.accessfilter; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.util.ReflectionUtil; import com.fasterxml.jackson.core.JsonParser; @@ -12,9 +13,13 @@ import org.springframework.context.ApplicationContext; public abstract class JsonDeserializerWithAccessFilter extends JsonDeserializer { private final ApplicationContext ctx; + private final UserRoleAssignmentService userRoleAssignmentService; - public JsonDeserializerWithAccessFilter(final ApplicationContext ctx) { + public JsonDeserializerWithAccessFilter( + final ApplicationContext ctx, + final UserRoleAssignmentService userRoleAssignmentService) { this.ctx = ctx; + this.userRoleAssignmentService = userRoleAssignmentService; } @Override @@ -24,6 +29,11 @@ public abstract class JsonDeserializerWithAccessFilter final Class dtoClass = ReflectionUtil .determineGenericClassParameter(this.getClass(), JsonDeserializerWithAccessFilter.class, 0); - return new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, deserializationContext, dtoClass).deserialize(); + return new JSonDeserializationWithAccessFilter( + ctx, + userRoleAssignmentService, + jsonParser, + deserializationContext, + dtoClass).deserialize(); } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JsonSerializerWithAccessFilter.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JsonSerializerWithAccessFilter.java index 86972af9..0991355d 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JsonSerializerWithAccessFilter.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/JsonSerializerWithAccessFilter.java @@ -1,6 +1,8 @@ // Licensed under Apache-2.0 package org.hostsharing.hsadminng.service.accessfilter; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; + import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; @@ -20,9 +22,13 @@ import java.io.IOException; public abstract class JsonSerializerWithAccessFilter extends JsonSerializer { protected final ApplicationContext ctx; + protected final UserRoleAssignmentService userRoleAssignmentService; - public JsonSerializerWithAccessFilter(final ApplicationContext ctx) { + public JsonSerializerWithAccessFilter( + final ApplicationContext ctx, + final UserRoleAssignmentService userRoleAssignmentService) { this.ctx = ctx; + this.userRoleAssignmentService = userRoleAssignmentService; } @Override @@ -31,6 +37,7 @@ public abstract class JsonSerializerWithAccessFilter e final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) throws IOException { - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, serializerProvider, dto).serialize(); + new JSonSerializationWithAccessFilter(ctx, userRoleAssignmentService, jsonGenerator, serializerProvider, dto) + .serialize(); } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/Role.java b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/Role.java index 1393e07e..a6e62ed1 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/accessfilter/Role.java +++ b/src/main/java/org/hostsharing/hsadminng/service/accessfilter/Role.java @@ -3,6 +3,8 @@ package org.hostsharing.hsadminng.service.accessfilter; import static com.google.common.base.Verify.verify; +import org.hostsharing.hsadminng.security.AuthoritiesConstants; + import java.lang.reflect.Field; /** @@ -24,17 +26,17 @@ public enum Role { /** * Hostmasters are initialize/update/read and field which, except where NOBODY is allowed to. */ - HOSTMASTER(1), + HOSTMASTER(1, AuthoritiesConstants.HOSTMASTER), /** * This role is for administrators, e.g. to create memberships and book shared and assets. */ - ADMIN(2), + ADMIN(2, AuthoritiesConstants.ADMIN), /** * This role is for members of the support team. */ - SUPPORTER(3), + SUPPORTER(3, AuthoritiesConstants.SUPPORTER), /** * This role is for contractual contacts of a customer, like a director of the company. @@ -82,7 +84,7 @@ public enum Role { * This role is meant to specify that a resources can be accessed by anybody, even without login. * It's currently only used for technical purposes. */ - ANYBODY(99), + ANYBODY(99, AuthoritiesConstants.ANONYMOUS), /** * Pseudo-role to mark init/update access as ignored because the field is display-only. @@ -92,13 +94,21 @@ public enum Role { IGNORED; private final Integer level; + private final String authority; - Role() { - this.level = null; + Role(final int level, final String authority) { + this.level = level; + this.authority = authority; } Role(final int level) { this.level = level; + this.authority = AuthoritiesConstants.USER; + } + + Role() { + this.level = null; + this.authority = null; } /** @@ -114,6 +124,10 @@ public enum Role { return updateAccessFor.length == 1 && updateAccessFor[0].isIgnored(); } + public String asAuthority() { + return authority; + } + /** * @return true if the role is the IGNORED role */ @@ -125,7 +139,7 @@ public enum Role { * @return true if this role is independent of a target object, false otherwise. */ public boolean isIndependent() { - return covers(Role.SUPPORTER); + return this != NOBODY && covers(Role.SUPPORTER); } /** diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/AssetDTO.java b/src/main/java/org/hostsharing/hsadminng/service/dto/AssetDTO.java index 6616c68f..c0595ea3 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/AssetDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/AssetDTO.java @@ -5,6 +5,7 @@ import org.hostsharing.hsadminng.domain.Asset; import org.hostsharing.hsadminng.domain.enumeration.AssetAction; import org.hostsharing.hsadminng.service.AssetService; import org.hostsharing.hsadminng.service.MembershipService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.*; import org.springframework.boot.jackson.JsonComponent; @@ -157,16 +158,16 @@ public class AssetDTO implements Serializable, AccessMappings { @JsonComponent public static class JsonSerializer extends JsonSerializerWithAccessFilter { - public JsonSerializer(final ApplicationContext ctx) { - super(ctx); + public JsonSerializer(final ApplicationContext ctx, final UserRoleAssignmentService userRoleAssignmentService) { + super(ctx, userRoleAssignmentService); } } @JsonComponent public static class JsonDeserializer extends JsonDeserializerWithAccessFilter { - public JsonDeserializer(final ApplicationContext ctx) { - super(ctx); + public JsonDeserializer(final ApplicationContext ctx, final UserRoleAssignmentService userRoleAssignmentService) { + super(ctx, userRoleAssignmentService); } } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/CustomerDTO.java b/src/main/java/org/hostsharing/hsadminng/service/dto/CustomerDTO.java index bcb73875..78dd39f9 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/CustomerDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/CustomerDTO.java @@ -5,6 +5,7 @@ import org.hostsharing.hsadminng.domain.Customer; import org.hostsharing.hsadminng.domain.enumeration.CustomerKind; import org.hostsharing.hsadminng.domain.enumeration.VatRegion; import org.hostsharing.hsadminng.service.CustomerService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.*; import org.springframework.boot.jackson.JsonComponent; @@ -22,24 +23,24 @@ import javax.validation.constraints.*; public class CustomerDTO implements AccessMappings, FluentBuilder { @SelfId(resolver = CustomerService.class) - @AccessFor(read = Role.ANY_CUSTOMER_USER) + @AccessFor(read = Role.ACTUAL_CUSTOMER_USER) private Long id; @NotNull @Min(value = 10000) @Max(value = 99999) - @AccessFor(init = Role.ADMIN, read = Role.ANY_CUSTOMER_USER) + @AccessFor(init = Role.ADMIN, read = Role.ACTUAL_CUSTOMER_USER) private Integer reference; @NotNull @Size(max = 3) @Pattern(regexp = "[a-z][a-z0-9]+") - @AccessFor(init = Role.ADMIN, read = Role.ANY_CUSTOMER_USER) + @AccessFor(init = Role.ADMIN, read = Role.ACTUAL_CUSTOMER_USER) private String prefix; @NotNull @Size(max = 80) - @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.ANY_CUSTOMER_USER) + @AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.ACTUAL_CUSTOMER_USER) private String name; @NotNull @@ -93,7 +94,7 @@ public class CustomerDTO implements AccessMappings, FluentBuilder { @AccessFor(init = Role.ADMIN, update = Role.SUPPORTER, read = Role.SUPPORTER) private String remark; - @AccessFor(init = Role.ANYBODY, update = Role.ANYBODY, read = Role.ANY_CUSTOMER_USER) + @AccessFor(init = Role.ANYBODY, update = Role.ANYBODY, read = Role.ACTUAL_CUSTOMER_USER) private String displayLabel; public Long getId() { @@ -278,16 +279,18 @@ public class CustomerDTO implements AccessMappings, FluentBuilder { @JsonComponent public static class CustomerJsonSerializer extends JsonSerializerWithAccessFilter { - public CustomerJsonSerializer(final ApplicationContext ctx) { - super(ctx); + public CustomerJsonSerializer(final ApplicationContext ctx, final UserRoleAssignmentService userRoleAssignmentService) { + super(ctx, userRoleAssignmentService); } } @JsonComponent public static class CustomerJsonDeserializer extends JsonDeserializerWithAccessFilter { - public CustomerJsonDeserializer(final ApplicationContext ctx) { - super(ctx); + public CustomerJsonDeserializer( + final ApplicationContext ctx, + final UserRoleAssignmentService userRoleAssignmentService) { + super(ctx, userRoleAssignmentService); } } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/MembershipDTO.java b/src/main/java/org/hostsharing/hsadminng/service/dto/MembershipDTO.java index 5fb9ee31..55f9d2f8 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/MembershipDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/MembershipDTO.java @@ -4,6 +4,7 @@ package org.hostsharing.hsadminng.service.dto; import org.hostsharing.hsadminng.domain.Membership; import org.hostsharing.hsadminng.service.CustomerService; import org.hostsharing.hsadminng.service.MembershipService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.*; import org.springframework.boot.jackson.JsonComponent; @@ -174,16 +175,20 @@ public class MembershipDTO implements AccessMappings, FluentBuilder { - public MembershipJsonSerializer(final ApplicationContext ctx) { - super(ctx); + public MembershipJsonSerializer( + final ApplicationContext ctx, + final UserRoleAssignmentService userRoleAssignmentService) { + super(ctx, userRoleAssignmentService); } } @JsonComponent public static class MembershipJsonDeserializer extends JsonDeserializerWithAccessFilter { - public MembershipJsonDeserializer(final ApplicationContext ctx) { - super(ctx); + public MembershipJsonDeserializer( + final ApplicationContext ctx, + final UserRoleAssignmentService userRoleAssignmentService) { + super(ctx, userRoleAssignmentService); } } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/SepaMandateDTO.java b/src/main/java/org/hostsharing/hsadminng/service/dto/SepaMandateDTO.java index 5fb29c37..e6d2c19b 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/SepaMandateDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/SepaMandateDTO.java @@ -4,6 +4,7 @@ package org.hostsharing.hsadminng.service.dto; import org.hostsharing.hsadminng.domain.SepaMandate; import org.hostsharing.hsadminng.service.CustomerService; import org.hostsharing.hsadminng.service.SepaMandateService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.*; import org.springframework.boot.jackson.JsonComponent; @@ -222,16 +223,16 @@ public class SepaMandateDTO implements AccessMappings, FluentBuilder { - public JsonSerializer(final ApplicationContext ctx) { - super(ctx); + public JsonSerializer(final ApplicationContext ctx, final UserRoleAssignmentService userRoleAssignmentService) { + super(ctx, userRoleAssignmentService); } } @JsonComponent public static class JsonDeserializer extends JsonDeserializerWithAccessFilter { - public JsonDeserializer(final ApplicationContext ctx) { - super(ctx); + public JsonDeserializer(final ApplicationContext ctx, final UserRoleAssignmentService userRoleAssignmentService) { + super(ctx, userRoleAssignmentService); } } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/ShareDTO.java b/src/main/java/org/hostsharing/hsadminng/service/dto/ShareDTO.java index deac9f30..00c30597 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/ShareDTO.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/ShareDTO.java @@ -5,6 +5,7 @@ import org.hostsharing.hsadminng.domain.Share; import org.hostsharing.hsadminng.domain.enumeration.ShareAction; import org.hostsharing.hsadminng.service.MembershipService; import org.hostsharing.hsadminng.service.ShareService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.*; import org.springframework.boot.jackson.JsonComponent; @@ -156,16 +157,16 @@ public class ShareDTO implements Serializable, AccessMappings { @JsonComponent public static class JsonSerializer extends JsonSerializerWithAccessFilter { - public JsonSerializer(final ApplicationContext ctx) { - super(ctx); + public JsonSerializer(final ApplicationContext ctx, final UserRoleAssignmentService userRoleAssignmentService) { + super(ctx, userRoleAssignmentService); } } @JsonComponent public static class JsonDeserializer extends JsonDeserializerWithAccessFilter { - public JsonDeserializer(final ApplicationContext ctx) { - super(ctx); + public JsonDeserializer(final ApplicationContext ctx, final UserRoleAssignmentService userRoleAssignmentService) { + super(ctx, userRoleAssignmentService); } } } diff --git a/src/main/java/org/hostsharing/hsadminng/service/dto/UserRoleAssignmentCriteria.java b/src/main/java/org/hostsharing/hsadminng/service/dto/UserRoleAssignmentCriteria.java index 72951aab..6a9d0e14 100644 --- a/src/main/java/org/hostsharing/hsadminng/service/dto/UserRoleAssignmentCriteria.java +++ b/src/main/java/org/hostsharing/hsadminng/service/dto/UserRoleAssignmentCriteria.java @@ -1,7 +1,7 @@ // Licensed under Apache-2.0 package org.hostsharing.hsadminng.service.dto; -import org.hostsharing.hsadminng.domain.enumeration.UserRole; +import org.hostsharing.hsadminng.service.accessfilter.Role; import io.github.jhipster.service.filter.Filter; import io.github.jhipster.service.filter.LongFilter; @@ -23,7 +23,7 @@ public class UserRoleAssignmentCriteria implements Serializable { /** * Class for filtering UserRole */ - public static class UserRoleFilter extends Filter { + public static class UserRoleFilter extends Filter { } private static final long serialVersionUID = 1L; diff --git a/src/test/java/org/hostsharing/hsadminng/service/UserRoleAssignmentServiceUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/UserRoleAssignmentServiceUnitTest.java new file mode 100644 index 00000000..11fb276b --- /dev/null +++ b/src/test/java/org/hostsharing/hsadminng/service/UserRoleAssignmentServiceUnitTest.java @@ -0,0 +1,95 @@ +// Licensed under Apache-2.0 +package org.hostsharing.hsadminng.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.catchThrowable; +import static org.mockito.BDDMockito.given; + +import org.hostsharing.hsadminng.domain.UserRoleAssignment; +import org.hostsharing.hsadminng.repository.UserRoleAssignmentRepository; +import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; +import org.hostsharing.hsadminng.service.accessfilter.Role; + +import com.google.common.base.VerifyException; + +import org.junit.Rule; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.util.Arrays; +import java.util.Set; + +public class UserRoleAssignmentServiceUnitTest { + + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Mock + private UserRoleAssignmentRepository userRoleAssignmentRepository; + + @InjectMocks + private UserRoleAssignmentService userRoleAssignmentService; + + @Test + public void getEffectiveRoleOfCurrentUserReturnsEmptySetIfUserNotAuthenticated() { + // when + final Set actual = userRoleAssignmentService.getEffectiveRoleOfCurrentUser("test.Something", 1L); + + // then + assertThat(actual).isEmpty(); + } + + @Test + public void getEffectiveRoleOfCurrentUserReturnsEmptySetIfUserAuthenticatedButNoRolesAssigned() { + // given + new MockSecurityContext().havingAuthenticatedUser(); + + // when + final Set actual = userRoleAssignmentService.getEffectiveRoleOfCurrentUser("test.Something", 1L); + + // then + assertThat(actual).isEmpty(); + } + + @Test + public void getEffectiveRoleOfCurrentUserReturnsExactlyAssignedRoles() { + // given + final String givenUserLogin = "someUser"; + new MockSecurityContext().havingAuthenticatedUser(givenUserLogin); + final long givenEntityObjectId = 2L; + final String givenEntityTypeId = "test.Something"; + given(userRoleAssignmentRepository.findByLogin(givenUserLogin)).willReturn( + Arrays.asList( + new UserRoleAssignment().entityTypeId("test.SomethingElse") + .entityObjectId(givenEntityObjectId) + .assignedRole(Role.CONTRACTUAL_CONTACT), + new UserRoleAssignment().entityTypeId(givenEntityTypeId) + .entityObjectId(givenEntityObjectId) + .assignedRole(Role.FINANCIAL_CONTACT), + new UserRoleAssignment().entityTypeId(givenEntityTypeId) + .entityObjectId(givenEntityObjectId) + .assignedRole(Role.TECHNICAL_CONTACT), + new UserRoleAssignment().entityTypeId(givenEntityTypeId) + .entityObjectId(3L) + .assignedRole(Role.CONTRACTUAL_CONTACT))); + + // when + final Set actual = userRoleAssignmentService + .getEffectiveRoleOfCurrentUser(givenEntityTypeId, givenEntityObjectId); + + // then + assertThat(actual).containsExactlyInAnyOrder(Role.FINANCIAL_CONTACT, Role.TECHNICAL_CONTACT); + } + + @Test + public void getEffectiveRoleOfCurrentUserThrowsExceptionIfEntityTypeIdIsMissing() { + // when + final Throwable actual = catchThrowable(() -> userRoleAssignmentService.getEffectiveRoleOfCurrentUser(null, 1L)); + + // then + assertThat(actual).isInstanceOf(VerifyException.class); + } +} diff --git a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilterTestFixture.java b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilterTestFixture.java index 5ecc0368..87f03c35 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilterTestFixture.java +++ b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonAccessFilterTestFixture.java @@ -33,6 +33,7 @@ public class JSonAccessFilterTestFixture { return dto; } + @EntityTypeId("test.GivenCustomer") static class GivenCustomerDto implements FluentBuilder { @SelfId(resolver = GivenService.class) @@ -47,6 +48,7 @@ public class JSonAccessFilterTestFixture { static abstract class GivenCustomerService implements IdToDtoResolver { } + @EntityTypeId("test.Given") static class GivenDto implements FluentBuilder { @SelfId(resolver = GivenService.class) diff --git a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializationWithAccessFilterUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializationWithAccessFilterUnitTest.java index 1f894e15..a68b16a1 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializationWithAccessFilterUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonDeserializationWithAccessFilterUnitTest.java @@ -6,10 +6,9 @@ import static org.assertj.core.api.Assertions.catchThrowable; import static org.assertj.core.api.Assumptions.assumeThat; import static org.hostsharing.hsadminng.service.accessfilter.JSonAccessFilterTestFixture.*; import static org.hostsharing.hsadminng.service.accessfilter.JSonBuilder.asJSon; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole; import static org.mockito.BDDMockito.given; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; import com.fasterxml.jackson.core.JsonParser; @@ -61,6 +60,9 @@ public class JSonDeserializationWithAccessFilterUnitTest { @Mock private TreeNode treeNode; + @Mock + private UserRoleAssignmentService userRoleAssignmentService; + @Mock private GivenService givenService; @@ -70,10 +72,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { @Mock private GivenCustomerService givenCustomerService; + private MockSecurityContext givenSecurityContext; + @Before public void init() { - givenAuthenticatedUser(); - givenUserHavingRole(GivenDto.class, 1234L, Role.ACTUAL_CUSTOMER_USER); + givenSecurityContext = new MockSecurityContext(userRoleAssignmentService); + givenSecurityContext.havingAuthenticatedUser().withRole(GivenDto.class, 1234L, Role.ACTUAL_CUSTOMER_USER); given(ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory); given(autowireCapableBeanFactory.createBean(GivenService.class)).willReturn(givenService); @@ -113,7 +117,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { ImmutablePair.of("openStringField", null))); // when - GivenDto actualDto = new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize(); + GivenDto actualDto = new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize(); // then assertThat(actualDto.openStringField).isNull(); @@ -129,7 +138,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { ImmutablePair.of("openStringField", "String Value"))); // when - GivenDto actualDto = new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize(); + GivenDto actualDto = new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize(); // then assertThat(actualDto.openStringField).isEqualTo("String Value"); @@ -145,7 +159,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { ImmutablePair.of("openIntegerField", 1234))); // when - GivenDto actualDto = new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize(); + GivenDto actualDto = new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize(); // then assertThat(actualDto.openIntegerField).isEqualTo(1234); @@ -162,7 +181,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { ImmutablePair.of("restrictedBigDecimalField", SOME_BIG_DECIMAL_WITH_ANOTHER_SCALE))); // when - GivenDto actualDto = new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize(); + GivenDto actualDto = new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize(); // then assertThat(actualDto.restrictedBigDecimalField).isEqualByComparingTo(SOME_BIG_DECIMAL); @@ -192,7 +216,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { ImmutablePair.of("openEnumField", TestEnum.GREEN))); // when - GivenDto actualDto = new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize(); + GivenDto actualDto = new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize(); // then assertThat(actualDto.openIntegerField).isEqualTo(11); @@ -218,7 +247,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { // when Throwable exception = catchThrowable( - () -> new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize()); + () -> new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize()); // then assertThat(exception).isInstanceOf(NotImplementedException.class); @@ -227,8 +261,7 @@ public class JSonDeserializationWithAccessFilterUnitTest { @Test public void shouldDeserializeStringFieldIfRequiredRoleIsCoveredByUser() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(GivenCustomerDto.class, 888L, Role.FINANCIAL_CONTACT); + givenSecurityContext.havingAuthenticatedUser().withRole(GivenCustomerDto.class, 888L, Role.FINANCIAL_CONTACT); givenJSonTree( asJSon( ImmutablePair.of("id", 1234L), @@ -236,7 +269,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { ImmutablePair.of("restrictedField", "update value of restricted field"))); // when - GivenDto actualDto = new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize(); + GivenDto actualDto = new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize(); // then assertThat(actualDto.restrictedField).isEqualTo("update value of restricted field"); @@ -245,8 +283,7 @@ public class JSonDeserializationWithAccessFilterUnitTest { @Test public void shouldDeserializeUnchangedStringFieldIfRequiredRoleIsNotCoveredByUser() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ACTUAL_CUSTOMER_USER); + givenSecurityContext.havingAuthenticatedUser().withRole(GivenCustomerDto.class, 888L, Role.ACTUAL_CUSTOMER_USER); givenJSonTree( asJSon( ImmutablePair.of("id", 1234L), @@ -254,7 +291,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { ImmutablePair.of("restrictedField", "initial value of restricted field"))); // when - GivenDto actualDto = new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize(); + GivenDto actualDto = new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize(); // then assertThat(actualDto.restrictedField).isEqualTo("initial value of restricted field"); @@ -263,8 +305,7 @@ public class JSonDeserializationWithAccessFilterUnitTest { @Test public void shouldNotDeserializeUpatedStringFieldIfRequiredRoleIsNotCoveredByUser() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ACTUAL_CUSTOMER_USER); + givenSecurityContext.havingAuthenticatedUser().withRole(GivenCustomerDto.class, 888L, Role.ACTUAL_CUSTOMER_USER); givenJSonTree( asJSon( ImmutablePair.of("customerId", 888L), @@ -272,7 +313,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { // when Throwable exception = catchThrowable( - () -> new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize()); + () -> new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize()); // then assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> { @@ -284,8 +330,7 @@ public class JSonDeserializationWithAccessFilterUnitTest { @Test public void shouldInitializeFieldIfRequiredRoleIsNotCoveredByUser() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ACTUAL_CUSTOMER_USER); + givenSecurityContext.havingAuthenticatedUser().withRole(GivenCustomerDto.class, 888L, Role.ACTUAL_CUSTOMER_USER); givenJSonTree( asJSon( ImmutablePair.of("customerId", 888L), @@ -293,7 +338,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { // when Throwable exception = catchThrowable( - () -> new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize()); + () -> new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize()); // then assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> { @@ -305,15 +355,19 @@ public class JSonDeserializationWithAccessFilterUnitTest { @Test public void shouldNotCreateIfRoleRequiredByParentEntityIsNotCoveredByUser() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(GivenDto.class, 9999L, Role.CONTRACTUAL_CONTACT); + givenSecurityContext.havingAuthenticatedUser().withRole(GivenCustomerDto.class, 9999L, Role.CONTRACTUAL_CONTACT); givenJSonTree( asJSon( ImmutablePair.of("parentId", 1234L))); // when Throwable exception = catchThrowable( - () -> new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenChildDto.class).deserialize()); + () -> new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenChildDto.class).deserialize()); // then assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> { @@ -325,15 +379,19 @@ public class JSonDeserializationWithAccessFilterUnitTest { @Test public void shouldCreateIfRoleRequiredByReferencedEntityIsCoveredByUser() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(GivenDto.class, 1234L, Role.CONTRACTUAL_CONTACT); + givenSecurityContext.havingAuthenticatedUser().withRole(GivenCustomerDto.class, 888L, Role.CONTRACTUAL_CONTACT); givenJSonTree( asJSon( ImmutablePair.of("parentId", 1234L))); // when - final GivenChildDto actualDto = new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenChildDto.class) - .deserialize(); + final GivenChildDto actualDto = new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenChildDto.class) + .deserialize(); // then assertThat(actualDto.parentId).isEqualTo(1234L); @@ -342,8 +400,7 @@ public class JSonDeserializationWithAccessFilterUnitTest { @Test public void shouldNotUpdateFieldIfRequiredRoleIsNotCoveredByUser() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ACTUAL_CUSTOMER_USER); + givenSecurityContext.havingAuthenticatedUser().withRole(GivenCustomerDto.class, 888L, Role.ACTUAL_CUSTOMER_USER); givenJSonTree( asJSon( ImmutablePair.of("id", 1234L), @@ -352,7 +409,12 @@ public class JSonDeserializationWithAccessFilterUnitTest { // when Throwable exception = catchThrowable( - () -> new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize()); + () -> new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDto.class).deserialize()); // then assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> { @@ -368,8 +430,13 @@ public class JSonDeserializationWithAccessFilterUnitTest { // when Throwable exception = catchThrowable( - () -> new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDtoWithMultipleSelfId.class) - .deserialize()); + () -> new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDtoWithMultipleSelfId.class) + .deserialize()); // then assertThat(exception).isInstanceOf(AssertionError.class) @@ -379,14 +446,18 @@ public class JSonDeserializationWithAccessFilterUnitTest { @Test public void shouldDetectUnknownFieldType() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(Role.ADMIN); + givenSecurityContext.havingAuthenticatedUser().withRole(Role.ADMIN); givenJSonTree(asJSon(ImmutablePair.of("unknown", new Arbitrary()))); // when Throwable exception = catchThrowable( - () -> new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, GivenDtoWithUnknownFieldType.class) - .deserialize()); + () -> new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + GivenDtoWithUnknownFieldType.class) + .deserialize()); // then assertThat(exception).isInstanceOf(NotImplementedException.class) diff --git a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializationWithAccessFilterUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializationWithAccessFilterUnitTest.java index 451c086e..97c7eb3e 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializationWithAccessFilterUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/JSonSerializationWithAccessFilterUnitTest.java @@ -8,6 +8,8 @@ import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; + import com.fasterxml.jackson.core.JsonGenerator; import org.apache.commons.lang3.NotImplementedException; @@ -37,15 +39,20 @@ public class JSonSerializationWithAccessFilterUnitTest { @Mock private JsonGenerator jsonGenerator; + @Mock + private UserRoleAssignmentService userRoleAssignmentService; + @Mock private GivenCustomerService givenCustomerService; + private MockSecurityContext securityContext; + private final GivenDto givenDTO = createSampleDto(); @Before public void init() { - MockSecurityContext.givenAuthenticatedUser(); - MockSecurityContext.givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ANY_CUSTOMER_USER); + securityContext = new MockSecurityContext(userRoleAssignmentService).havingAuthenticatedUser() + .withRole(GivenCustomerDto.class, 888L, Role.ANY_CUSTOMER_USER); given(ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory); given(autowireCapableBeanFactory.createBean(GivenCustomerService.class)).willReturn(givenCustomerService); @@ -58,7 +65,7 @@ public class JSonSerializationWithAccessFilterUnitTest { @Test public void shouldSerializeStringField() throws IOException { // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeStringField("openStringField", givenDTO.openStringField); @@ -67,7 +74,7 @@ public class JSonSerializationWithAccessFilterUnitTest { @Test public void shouldSerializeIntegerField() throws IOException { // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeNumberField("openIntegerField", givenDTO.openIntegerField); @@ -76,7 +83,7 @@ public class JSonSerializationWithAccessFilterUnitTest { @Test public void shouldSerializePrimitiveIntField() throws IOException { // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeNumberField("openPrimitiveIntField", givenDTO.openPrimitiveIntField); @@ -85,7 +92,7 @@ public class JSonSerializationWithAccessFilterUnitTest { @Test public void shouldSerializeLongField() throws IOException { // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeNumberField("openLongField", givenDTO.openLongField); @@ -94,7 +101,7 @@ public class JSonSerializationWithAccessFilterUnitTest { @Test public void shouldSerializePrimitiveLongField() throws IOException { // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeNumberField("openPrimitiveLongField", givenDTO.openPrimitiveLongField); @@ -103,7 +110,7 @@ public class JSonSerializationWithAccessFilterUnitTest { @Test public void shouldSerializeBooleanField() throws IOException { // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeBooleanField("openBooleanField", givenDTO.openBooleanField); @@ -112,7 +119,7 @@ public class JSonSerializationWithAccessFilterUnitTest { @Test public void shouldSerializePrimitiveBooleanField() throws IOException { // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeBooleanField("openPrimitiveBooleanField", givenDTO.openPrimitiveBooleanField); @@ -121,7 +128,7 @@ public class JSonSerializationWithAccessFilterUnitTest { @Test public void shouldSerializeBigDecimalField() throws IOException { // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeNumberField("openBigDecimalField", givenDTO.openBigDecimalField); @@ -130,7 +137,7 @@ public class JSonSerializationWithAccessFilterUnitTest { @Test public void shouldSerializeLocalDateField() throws IOException { // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeStringField("openLocalDateField", givenDTO.openLocalDateFieldAsString); @@ -139,7 +146,7 @@ public class JSonSerializationWithAccessFilterUnitTest { @Test public void shouldSerializeEnumField() throws IOException { // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeStringField("openEnumField", givenDTO.openEnumFieldAsString); @@ -149,11 +156,10 @@ public class JSonSerializationWithAccessFilterUnitTest { public void shouldSerializeRestrictedFieldIfRequiredRoleIsCoveredByUser() throws IOException { // given - MockSecurityContext.givenAuthenticatedUser(); - MockSecurityContext.givenUserHavingRole(GivenCustomerDto.class, 888L, Role.FINANCIAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(GivenCustomerDto.class, 888L, Role.FINANCIAL_CONTACT); // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator).writeStringField("restrictedField", givenDTO.restrictedField); @@ -163,11 +169,10 @@ public class JSonSerializationWithAccessFilterUnitTest { public void shouldNotSerializeRestrictedFieldIfRequiredRoleIsNotCoveredByUser() throws IOException { // given - MockSecurityContext.givenAuthenticatedUser(); - MockSecurityContext.givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ANY_CUSTOMER_USER); + securityContext.havingAuthenticatedUser().withRole(GivenCustomerDto.class, 888L, Role.ANY_CUSTOMER_USER); // when - new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize(); + new JSonSerializationWithAccessFilter<>(ctx, userRoleAssignmentService, jsonGenerator, null, givenDTO).serialize(); // then verify(jsonGenerator, never()).writeStringField("restrictedField", givenDTO.restrictedField); @@ -188,8 +193,13 @@ public class JSonSerializationWithAccessFilterUnitTest { // when final Throwable actual = catchThrowable( - () -> new JSonSerializationWithAccessFilter<>(ctx, jsonGenerator, null, givenDtoWithUnimplementedFieldType) - .serialize()); + () -> new JSonSerializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonGenerator, + null, + givenDtoWithUnimplementedFieldType) + .serialize()); // then assertThat(actual).isInstanceOf(NotImplementedException.class); diff --git a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/MockSecurityContext.java b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/MockSecurityContext.java index a110627b..4c1adfaa 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/MockSecurityContext.java +++ b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/MockSecurityContext.java @@ -2,33 +2,95 @@ package org.hostsharing.hsadminng.service.accessfilter; import static org.assertj.core.api.Assumptions.assumeThat; +import static org.mockito.BDDMockito.given; import org.hostsharing.hsadminng.security.SecurityUtils; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; +import org.mockito.Mockito; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; + public class MockSecurityContext { - public static void givenAuthenticatedUser() { + private final UserRoleAssignmentService userRoleAssignmentService; + private final Collection authorities; + + // TODO mhoennig: refactor this ctor to method withMock(...) returning a subclass to avoid null checks + public MockSecurityContext(final UserRoleAssignmentService userRoleAssignmentService) { + this.userRoleAssignmentService = userRoleAssignmentService; + this.authorities = new ArrayList<>(); + } + + public MockSecurityContext() { + this(null); + } + + public MockSecurityContext havingAuthenticatedUser() { + return havingAuthenticatedUser("dummyUser"); + } + + public MockSecurityContext havingAuthenticatedUser(final String login) { SecurityContext securityContext = SecurityContextHolder.createEmptyContext(); - securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("dummyUser", "dummyPassword")); + + securityContext.setAuthentication(new UsernamePasswordAuthenticationToken(login, "dummyPassword") { + + @Override + public Collection getAuthorities() { + return authorities; + } + }); SecurityContextHolder.setContext(securityContext); - SecurityUtils.clearUserRoles(); - assumeThat(SecurityUtils.getCurrentUserLogin()).hasValue("dummyUser"); - } - - public static void givenUserHavingRole(final Class onClass, final Long onId, final Role role) { - if ((onClass == null || onId == null) && !role.isIndependent()) { - throw new IllegalArgumentException("dependent role " + role + " needs DtoClass and ID"); + assumeThat(SecurityUtils.getCurrentUserLogin()).hasValue(login); + if (userRoleAssignmentService != null) { + Mockito.reset(userRoleAssignmentService); } - SecurityUtils.addUserRole(onClass, onId, role); + authorities.clear(); + return this; } - public static void givenUserHavingRole(final Role role) { - givenUserHavingRole(null, null, role); + public MockSecurityContext withRole(final Class onClass, final Long onId, final Role... roles) { + if (userRoleAssignmentService == null) { + throw new IllegalStateException("mock not registered for: " + UserRoleAssignmentService.class.getSimpleName()); + } + final EntityTypeId entityTypeId = onClass.getAnnotation(EntityTypeId.class); + assumeThat(entityTypeId).as("@" + EntityTypeId.class.getSimpleName() + " missing on class " + onClass.toString()) + .isNotNull(); + given(userRoleAssignmentService.getEffectiveRoleOfCurrentUser(entityTypeId.value(), onId)) + .willReturn(new HashSet(Arrays.asList(roles))); + return this; } + public MockSecurityContext withRole(final Role role) { + authorities.add(new GrantedAuthority() { + + @Override + public String getAuthority() { + return role.asAuthority(); + } + }); + return this; + } + + private static class FakePrincipal { + + private final String username; + + public FakePrincipal(final String username) { + this.username = username; + } + + @Override + public String toString() { + return username; + } + } } diff --git a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/RoleUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/RoleUnitTest.java index 54807f98..267e31b5 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/accessfilter/RoleUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/accessfilter/RoleUnitTest.java @@ -123,6 +123,14 @@ public class RoleUnitTest { assertThat(Role.ANY_CUSTOMER_USER.isIndependent()).isFalse(); } + @Test + public void asAuthority() { + assertThat(Role.HOSTMASTER.asAuthority()).isEqualTo("ROLE_HOSTMASTER"); + assertThat(Role.ADMIN.asAuthority()).isEqualTo("ROLE_ADMIN"); + assertThat(Role.SUPPORTER.asAuthority()).isEqualTo("ROLE_SUPPORTER"); + assertThat(Role.CONTRACTUAL_CONTACT.asAuthority()).isEqualTo("ROLE_USER"); + } + @Test public void isBroadest() { assertThat(Role.broadest(Role.HOSTMASTER, Role.CONTRACTUAL_CONTACT)).isEqualTo(Role.HOSTMASTER); diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOIntTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOIntTest.java index 6f32c382..37c985e0 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/AssetDTOIntTest.java @@ -3,8 +3,6 @@ package org.hostsharing.hsadminng.service.dto; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole; import static org.junit.Assert.assertEquals; import static org.mockito.BDDMockito.given; @@ -18,7 +16,9 @@ import org.hostsharing.hsadminng.repository.MembershipRepository; import org.hostsharing.hsadminng.service.AssetService; import org.hostsharing.hsadminng.service.AssetValidator; import org.hostsharing.hsadminng.service.MembershipValidator; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.JSonBuilder; +import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.service.mapper.AssetMapper; import org.hostsharing.hsadminng.service.mapper.AssetMapperImpl; @@ -110,19 +110,25 @@ public class AssetDTOIntTest { @MockBean private EntityManager em; + @MockBean + private UserRoleAssignmentService userRoleAssignmentService; + + private MockSecurityContext securityContext; + @Before public void init() { given(customerRepository.findById(SOME_CUSTOMER_ID)).willReturn(Optional.of(SOME_CUSTOMER)); given(membershipRepository.findById(SOME_MEMBERSHIP_ID)).willReturn(Optional.of(SOME_MEMBERSHIP)); given(assetRepository.findById(SOME_ASSET_ID)).willReturn((Optional.of(SOME_ASSET))); + + securityContext = new MockSecurityContext(userRoleAssignmentService); } @Test public void shouldSerializePartiallyForFinancialCustomerContact() throws JsonProcessingException { // given - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.FINANCIAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.FINANCIAL_CONTACT); final AssetDTO given = createSomeAssetDTO(SOME_ASSET_ID); // when @@ -137,8 +143,7 @@ public class AssetDTOIntTest { public void shouldSerializeCompletelyForSupporter() throws JsonProcessingException { // given - givenAuthenticatedUser(); - givenUserHavingRole(Role.SUPPORTER); + securityContext.havingAuthenticatedUser().withRole(Role.SUPPORTER); final AssetDTO given = createSomeAssetDTO(SOME_ASSET_ID); // when @@ -151,8 +156,7 @@ public class AssetDTOIntTest { @Test public void shouldNotDeserializeForContractualCustomerContact() { // given - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.CONTRACTUAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.CONTRACTUAL_CONTACT); final String json = new JSonBuilder() .withFieldValue("id", SOME_ASSET_ID) .withFieldValue("remark", "Updated Remark") @@ -165,14 +169,14 @@ public class AssetDTOIntTest { assertThat(actual).isInstanceOfSatisfying( BadRequestAlertException.class, bre -> assertThat(bre.getMessage()) - .isEqualTo("Update of field AssetDTO.remark prohibited for current user role CONTRACTUAL_CONTACT")); + .isEqualTo( + "Update of field AssetDTO.remark prohibited for current user roles CONTRACTUAL_CONTACT+ANYBODY")); } @Test public void shouldDeserializeForAdminIfRemarkIsChanged() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(Role.ADMIN); + securityContext.havingAuthenticatedUser().withRole(Role.ADMIN); final String json = new JSonBuilder() .withFieldValue("id", SOME_ASSET_ID) .withFieldValue("remark", "Updated Remark") diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/CustomerDTOUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/CustomerDTOUnitTest.java index 75d8e84d..1494561e 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/CustomerDTOUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/CustomerDTOUnitTest.java @@ -2,8 +2,6 @@ package org.hostsharing.hsadminng.service.dto; import static org.assertj.core.api.Assertions.assertThat; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole; import static org.junit.Assert.assertEquals; import static org.mockito.BDDMockito.given; @@ -12,7 +10,9 @@ import org.hostsharing.hsadminng.domain.enumeration.CustomerKind; import org.hostsharing.hsadminng.domain.enumeration.VatRegion; import org.hostsharing.hsadminng.repository.CustomerRepository; import org.hostsharing.hsadminng.service.CustomerService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.JSonBuilder; +import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.service.mapper.CustomerMapper; import org.hostsharing.hsadminng.service.mapper.CustomerMapperImpl; @@ -20,6 +20,7 @@ import org.hostsharing.hsadminng.service.mapper.CustomerMapperImpl; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -60,12 +61,21 @@ public class CustomerDTOUnitTest { @MockBean private CustomerService customerService; + @MockBean + private UserRoleAssignmentService userRoleAssignmentService; + + private MockSecurityContext securityContext; + + @Before + public void init() { + securityContext = new MockSecurityContext(userRoleAssignmentService); + } + @Test public void testSerializationAsContractualCustomerContact() throws JsonProcessingException { // given - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, 1234L, Role.CONTRACTUAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(CustomerDTO.class, 1234L, Role.CONTRACTUAL_CONTACT); CustomerDTO given = createSomeCustomerDTO(1234L); // when @@ -80,8 +90,7 @@ public class CustomerDTOUnitTest { public void testSerializationAsTechnicalCustomerUser() throws JsonProcessingException { // given - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, 1234L, Role.TECHNICAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(CustomerDTO.class, 1234L, Role.TECHNICAL_CONTACT); CustomerDTO given = createSomeCustomerDTO(1234L); // when @@ -102,8 +111,7 @@ public class CustomerDTOUnitTest { public void testSerializationAsSupporter() throws JsonProcessingException { // given - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, null, Role.SUPPORTER); + securityContext.havingAuthenticatedUser().withRole(Role.SUPPORTER); CustomerDTO given = createSomeCustomerDTO(1234L); // when @@ -116,8 +124,7 @@ public class CustomerDTOUnitTest { @Test public void testDeserializeAsContractualCustomerContact() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, 1234L, Role.CONTRACTUAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(CustomerDTO.class, 1234L, Role.CONTRACTUAL_CONTACT); given(customerRepository.findById(1234L)).willReturn(Optional.of(new Customer().id(1234L))); String json = "{\"id\":1234,\"contractualSalutation\":\"Hallo Updated\",\"billingSalutation\":\"Moin Updated\"}"; diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/MembershipDTOUnitTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/MembershipDTOUnitTest.java index db2cb976..c21845b5 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/MembershipDTOUnitTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/MembershipDTOUnitTest.java @@ -4,13 +4,13 @@ package org.hostsharing.hsadminng.service.dto; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; import static org.hostsharing.hsadminng.service.accessfilter.JSonBuilder.asJSon; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole; import static org.mockito.BDDMockito.given; import org.hostsharing.hsadminng.service.CustomerService; import org.hostsharing.hsadminng.service.MembershipService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.JSonDeserializationWithAccessFilter; +import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; @@ -52,12 +52,17 @@ public class MembershipDTOUnitTest { @Mock private TreeNode treeNode; + @Mock + private UserRoleAssignmentService userRoleAssignmentService; + @Mock private MembershipService membershipService; @Mock private CustomerService customerService; + private MockSecurityContext securityContext; + @Before public void init() { given(jsonParser.getCodec()).willReturn(codec); @@ -69,17 +74,23 @@ public class MembershipDTOUnitTest { Optional.of( new CustomerDTO() .with(dto -> dto.setId(1234L)))); + + securityContext = new MockSecurityContext(userRoleAssignmentService); } @Test public void adminShouldHaveRightToCreate() throws IOException { - givenAuthenticatedUser(); - givenUserHavingRole(null, null, Role.ADMIN); + securityContext.havingAuthenticatedUser().withRole(Role.ADMIN); givenJSonTree(asJSon(ImmutablePair.of("customerId", 1234L))); // when - final MembershipDTO actualDto = new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, MembershipDTO.class) - .deserialize(); + final MembershipDTO actualDto = new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + MembershipDTO.class) + .deserialize(); // then assertThat(actualDto.getCustomerId()).isEqualTo(1234L); @@ -87,13 +98,17 @@ public class MembershipDTOUnitTest { @Test public void contractualContactShouldNotHaveRightToCreate() throws IOException { - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, 1234L, Role.CONTRACTUAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(CustomerDTO.class, 1234L, Role.CONTRACTUAL_CONTACT); givenJSonTree(asJSon(ImmutablePair.of("customerId", 1234L))); // when Throwable exception = catchThrowable( - () -> new JSonDeserializationWithAccessFilter<>(ctx, jsonParser, null, MembershipDTO.class).deserialize()); + () -> new JSonDeserializationWithAccessFilter<>( + ctx, + userRoleAssignmentService, + jsonParser, + null, + MembershipDTO.class).deserialize()); // then assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> { diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/SepaMandateDTOIntTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/SepaMandateDTOIntTest.java index 46ac0a26..f85a64ab 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/SepaMandateDTOIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/SepaMandateDTOIntTest.java @@ -3,8 +3,6 @@ package org.hostsharing.hsadminng.service.dto; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole; import static org.hostsharing.hsadminng.service.dto.SepaMandateDTOUnitTest.createSampleDTO; import static org.junit.Assert.assertEquals; import static org.mockito.BDDMockito.given; @@ -16,7 +14,9 @@ import org.hostsharing.hsadminng.repository.MembershipRepository; import org.hostsharing.hsadminng.repository.SepaMandateRepository; import org.hostsharing.hsadminng.service.MembershipValidator; import org.hostsharing.hsadminng.service.SepaMandateService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.JSonBuilder; +import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.service.mapper.CustomerMapperImpl; import org.hostsharing.hsadminng.service.mapper.MembershipMapperImpl; @@ -98,18 +98,24 @@ public class SepaMandateDTOIntTest { @MockBean private EntityManager em; + @MockBean + public UserRoleAssignmentService userRoleAssignmentService; + + private MockSecurityContext securityContext; + @Before public void init() { given(customerRepository.findById(SOME_CUSTOMER_ID)).willReturn(Optional.of(SOME_CUSTOMER)); given(sepaMandateRepository.findById(SOME_SEPA_MANDATE_ID)).willReturn((Optional.of(SOME_SEPA_MANDATE))); + + securityContext = new MockSecurityContext(userRoleAssignmentService); } @Test public void shouldSerializePartiallyForFinancialCustomerContact() throws JsonProcessingException { // given - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.FINANCIAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.FINANCIAL_CONTACT); final SepaMandateDTO given = createSampleDTO(SOME_SEPA_MANDATE_ID, SOME_CUSTOMER_ID); // when @@ -124,8 +130,7 @@ public class SepaMandateDTOIntTest { public void shouldSerializeCompletelyForSupporter() throws JsonProcessingException { // given - givenAuthenticatedUser(); - givenUserHavingRole(Role.SUPPORTER); + securityContext.havingAuthenticatedUser().withRole(Role.SUPPORTER); final SepaMandateDTO given = createSampleDTO(SOME_SEPA_MANDATE_ID, SOME_CUSTOMER_ID); // when @@ -138,8 +143,7 @@ public class SepaMandateDTOIntTest { @Test public void shouldNotDeserializeForContractualCustomerContact() { // given - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.CONTRACTUAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.CONTRACTUAL_CONTACT); final String json = new JSonBuilder() .withFieldValue("id", SOME_SEPA_MANDATE_ID) .withFieldValue("remark", "Updated Remark") @@ -152,14 +156,13 @@ public class SepaMandateDTOIntTest { assertThat(actual).isInstanceOfSatisfying( BadRequestAlertException.class, bre -> assertThat(bre.getMessage()).isEqualTo( - "Update of field SepaMandateDTO.remark prohibited for current user role CONTRACTUAL_CONTACT")); + "Update of field SepaMandateDTO.remark prohibited for current user roles CONTRACTUAL_CONTACT+ANYBODY")); } @Test public void shouldDeserializeForAdminIfRemarkIsChanged() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(Role.ADMIN); + securityContext.havingAuthenticatedUser().withRole(Role.ADMIN); final String json = new JSonBuilder() .withFieldValue("id", SOME_SEPA_MANDATE_ID) .withFieldValue("remark", "Updated Remark") diff --git a/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOIntTest.java b/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOIntTest.java index 8c505609..f646edf3 100644 --- a/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/service/dto/ShareDTOIntTest.java @@ -3,8 +3,6 @@ package org.hostsharing.hsadminng.service.dto; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.catchThrowable; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole; import static org.junit.Assert.assertEquals; import static org.mockito.BDDMockito.given; @@ -18,7 +16,9 @@ import org.hostsharing.hsadminng.repository.ShareRepository; import org.hostsharing.hsadminng.service.MembershipValidator; import org.hostsharing.hsadminng.service.ShareService; import org.hostsharing.hsadminng.service.ShareValidator; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.JSonBuilder; +import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.service.mapper.CustomerMapperImpl; import org.hostsharing.hsadminng.service.mapper.MembershipMapperImpl; @@ -109,19 +109,25 @@ public class ShareDTOIntTest { @MockBean private EntityManager em; + @MockBean + private UserRoleAssignmentService userRoleAssignmentService; + + private MockSecurityContext securityContext; + @Before public void init() { given(customerRepository.findById(SOME_CUSTOMER_ID)).willReturn(Optional.of(SOME_CUSTOMER)); given(membershipRepository.findById(SOME_MEMBERSHIP_ID)).willReturn(Optional.of(SOME_MEMBERSHIP)); given(shareRepository.findById(SOME_SHARE_ID)).willReturn((Optional.of(SOME_SHARE))); + + securityContext = new MockSecurityContext(userRoleAssignmentService); } @Test public void shouldSerializePartiallyForFinancialCustomerContact() throws JsonProcessingException { // given - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.FINANCIAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.FINANCIAL_CONTACT); final ShareDTO given = createSomeShareDTO(SOME_SHARE_ID); // when @@ -136,8 +142,7 @@ public class ShareDTOIntTest { public void shouldSerializeCompletelyForSupporter() throws JsonProcessingException { // given - givenAuthenticatedUser(); - givenUserHavingRole(Role.SUPPORTER); + securityContext.havingAuthenticatedUser().withRole(Role.SUPPORTER); final ShareDTO given = createSomeShareDTO(SOME_SHARE_ID); // when @@ -150,8 +155,7 @@ public class ShareDTOIntTest { @Test public void shouldNotDeserializeForContractualCustomerContact() { // given - givenAuthenticatedUser(); - givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.CONTRACTUAL_CONTACT); + securityContext.havingAuthenticatedUser().withRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.CONTRACTUAL_CONTACT); final String json = new JSonBuilder() .withFieldValue("id", SOME_SHARE_ID) .withFieldValue("remark", "Updated Remark") @@ -164,14 +168,14 @@ public class ShareDTOIntTest { assertThat(actual).isInstanceOfSatisfying( BadRequestAlertException.class, bre -> assertThat(bre.getMessage()) - .isEqualTo("Update of field ShareDTO.remark prohibited for current user role CONTRACTUAL_CONTACT")); + .isEqualTo( + "Update of field ShareDTO.remark prohibited for current user roles CONTRACTUAL_CONTACT+ANYBODY")); } @Test public void shouldDeserializeForAdminIfRemarkIsChanged() throws IOException { // given - givenAuthenticatedUser(); - givenUserHavingRole(Role.ADMIN); + securityContext.havingAuthenticatedUser().withRole(Role.ADMIN); final String json = new JSonBuilder() .withFieldValue("id", SOME_SHARE_ID) .withFieldValue("remark", "Updated Remark") diff --git a/src/test/java/org/hostsharing/hsadminng/web/rest/AssetResourceIntTest.java b/src/test/java/org/hostsharing/hsadminng/web/rest/AssetResourceIntTest.java index 05f50ff2..d82927a4 100644 --- a/src/test/java/org/hostsharing/hsadminng/web/rest/AssetResourceIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/web/rest/AssetResourceIntTest.java @@ -14,6 +14,7 @@ import org.hostsharing.hsadminng.domain.enumeration.AssetAction; import org.hostsharing.hsadminng.repository.AssetRepository; import org.hostsharing.hsadminng.service.AssetQueryService; import org.hostsharing.hsadminng.service.AssetService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.service.dto.AssetDTO; @@ -26,6 +27,7 @@ import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; @@ -94,14 +96,18 @@ public class AssetResourceIntTest { @Autowired private Validator validator; + @MockBean + private UserRoleAssignmentService userRoleAssignmentService; + + private MockSecurityContext securityContext; + private MockMvc restAssetMockMvc; private Asset asset; @Before public void setup() { - MockSecurityContext.givenAuthenticatedUser(); - MockSecurityContext.givenUserHavingRole(Role.ADMIN); + securityContext = new MockSecurityContext(userRoleAssignmentService).havingAuthenticatedUser().withRole(Role.ADMIN); MockitoAnnotations.initMocks(this); final AssetResource assetResource = new AssetResource(assetService, assetQueryService); diff --git a/src/test/java/org/hostsharing/hsadminng/web/rest/CustomerResourceIntTest.java b/src/test/java/org/hostsharing/hsadminng/web/rest/CustomerResourceIntTest.java index aca16349..4c1ec4e6 100644 --- a/src/test/java/org/hostsharing/hsadminng/web/rest/CustomerResourceIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/web/rest/CustomerResourceIntTest.java @@ -3,8 +3,6 @@ package org.hostsharing.hsadminng.web.rest; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.hasItem; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenAuthenticatedUser; -import static org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext.givenUserHavingRole; import static org.hostsharing.hsadminng.web.rest.TestUtil.createFormattingConversionService; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -18,6 +16,7 @@ import org.hostsharing.hsadminng.domain.enumeration.VatRegion; import org.hostsharing.hsadminng.repository.CustomerRepository; import org.hostsharing.hsadminng.service.CustomerQueryService; import org.hostsharing.hsadminng.service.CustomerService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.service.dto.CustomerDTO; @@ -30,9 +29,12 @@ import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Bean; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -107,6 +109,11 @@ public class CustomerResourceIntTest { private static int otherCounter = 0; + @Bean + public SecurityEvaluationContextExtension securityEvaluationContextExtension() { + return new SecurityEvaluationContextExtension(); + } + @Autowired private CustomerRepository customerRepository; @@ -134,19 +141,19 @@ public class CustomerResourceIntTest { @Autowired private Validator validator; + @MockBean + private UserRoleAssignmentService userRoleAssignmentService; + + private MockSecurityContext securityContext; + private MockMvc restCustomerMockMvc; private Customer customer; @Before public void setup() { - MockSecurityContext.givenAuthenticatedUser(); - MockSecurityContext.givenUserHavingRole(Role.ADMIN); - MockitoAnnotations.initMocks(this); - - givenAuthenticatedUser(); - givenUserHavingRole(Role.ADMIN); + securityContext = new MockSecurityContext(userRoleAssignmentService).havingAuthenticatedUser().withRole(Role.ADMIN); final CustomerResource customerResource = new CustomerResource(customerService, customerQueryService); this.restCustomerMockMvc = MockMvcBuilders.standaloneSetup(customerResource) diff --git a/src/test/java/org/hostsharing/hsadminng/web/rest/MembershipResourceIntTest.java b/src/test/java/org/hostsharing/hsadminng/web/rest/MembershipResourceIntTest.java index 9fa53732..ead3d339 100644 --- a/src/test/java/org/hostsharing/hsadminng/web/rest/MembershipResourceIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/web/rest/MembershipResourceIntTest.java @@ -15,6 +15,7 @@ import org.hostsharing.hsadminng.domain.Share; import org.hostsharing.hsadminng.repository.MembershipRepository; import org.hostsharing.hsadminng.service.MembershipQueryService; import org.hostsharing.hsadminng.service.MembershipService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.service.dto.MembershipDTO; @@ -27,6 +28,7 @@ import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; @@ -100,14 +102,18 @@ public class MembershipResourceIntTest { @Autowired private Validator validator; + @MockBean + private UserRoleAssignmentService userRoleAssignmentService; + + private MockSecurityContext securityContext; + private MockMvc restMembershipMockMvc; private Membership membership; @Before public void setup() { - MockSecurityContext.givenAuthenticatedUser(); - MockSecurityContext.givenUserHavingRole(Role.ADMIN); + securityContext = new MockSecurityContext(userRoleAssignmentService).havingAuthenticatedUser().withRole(Role.ADMIN); MockitoAnnotations.initMocks(this); final MembershipResource membershipResource = new MembershipResource(membershipService, membershipQueryService); diff --git a/src/test/java/org/hostsharing/hsadminng/web/rest/SepaMandateResourceIntTest.java b/src/test/java/org/hostsharing/hsadminng/web/rest/SepaMandateResourceIntTest.java index fce4c551..3c5b464a 100644 --- a/src/test/java/org/hostsharing/hsadminng/web/rest/SepaMandateResourceIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/web/rest/SepaMandateResourceIntTest.java @@ -13,6 +13,7 @@ import org.hostsharing.hsadminng.domain.SepaMandate; import org.hostsharing.hsadminng.repository.SepaMandateRepository; import org.hostsharing.hsadminng.service.SepaMandateQueryService; import org.hostsharing.hsadminng.service.SepaMandateService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.service.dto.CustomerDTO; @@ -26,6 +27,7 @@ import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; @@ -104,14 +106,18 @@ public class SepaMandateResourceIntTest { @Autowired private Validator validator; + @MockBean + private UserRoleAssignmentService userRoleAssignmentService; + + private MockSecurityContext securityContext; + private MockMvc restSepaMandateMockMvc; private SepaMandate sepaMandate; @Before public void setup() { - MockSecurityContext.givenAuthenticatedUser(); - MockSecurityContext.givenUserHavingRole(Role.ADMIN); + securityContext = new MockSecurityContext(userRoleAssignmentService).havingAuthenticatedUser().withRole(Role.ADMIN); MockitoAnnotations.initMocks(this); final SepaMandateResource sepaMandateResource = new SepaMandateResource(sepaMandateService, sepaMandateQueryService); @@ -187,8 +193,8 @@ public class SepaMandateResourceIntTest { sepaMandateDTO.setRemark(null); sepaMandateDTO.setRevokationDocumentDate(null); sepaMandateDTO.setLastUsedDate(null); - MockSecurityContext.givenAuthenticatedUser(); - MockSecurityContext.givenUserHavingRole(CustomerDTO.class, sepaMandateDTO.getCustomerId(), Role.FINANCIAL_CONTACT); + securityContext.havingAuthenticatedUser() + .withRole(CustomerDTO.class, sepaMandateDTO.getCustomerId(), Role.FINANCIAL_CONTACT); restSepaMandateMockMvc.perform( post("/api/sepa-mandates") diff --git a/src/test/java/org/hostsharing/hsadminng/web/rest/ShareResourceIntTest.java b/src/test/java/org/hostsharing/hsadminng/web/rest/ShareResourceIntTest.java index c5df9da4..b70dc6ec 100644 --- a/src/test/java/org/hostsharing/hsadminng/web/rest/ShareResourceIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/web/rest/ShareResourceIntTest.java @@ -14,6 +14,7 @@ import org.hostsharing.hsadminng.domain.enumeration.ShareAction; import org.hostsharing.hsadminng.repository.ShareRepository; import org.hostsharing.hsadminng.service.ShareQueryService; import org.hostsharing.hsadminng.service.ShareService; +import org.hostsharing.hsadminng.service.UserRoleAssignmentService; import org.hostsharing.hsadminng.service.accessfilter.MockSecurityContext; import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.service.dto.ShareDTO; @@ -26,6 +27,7 @@ import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.web.PageableHandlerMethodArgumentResolver; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; @@ -92,14 +94,18 @@ public class ShareResourceIntTest { @Autowired private Validator validator; + @MockBean + private UserRoleAssignmentService userRoleAssignmentService; + + private MockSecurityContext securityContext; + private MockMvc restShareMockMvc; private Share share; @Before public void setup() { - MockSecurityContext.givenAuthenticatedUser(); - MockSecurityContext.givenUserHavingRole(Role.ADMIN); + securityContext = new MockSecurityContext(userRoleAssignmentService).havingAuthenticatedUser().withRole(Role.ADMIN); MockitoAnnotations.initMocks(this); final ShareResource shareResource = new ShareResource(shareService, shareQueryService); diff --git a/src/test/java/org/hostsharing/hsadminng/web/rest/UserRoleAssignmentResourceIntTest.java b/src/test/java/org/hostsharing/hsadminng/web/rest/UserRoleAssignmentResourceIntTest.java index 12dd6d84..55114319 100644 --- a/src/test/java/org/hostsharing/hsadminng/web/rest/UserRoleAssignmentResourceIntTest.java +++ b/src/test/java/org/hostsharing/hsadminng/web/rest/UserRoleAssignmentResourceIntTest.java @@ -10,10 +10,10 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import org.hostsharing.hsadminng.HsadminNgApp; import org.hostsharing.hsadminng.domain.User; import org.hostsharing.hsadminng.domain.UserRoleAssignment; -import org.hostsharing.hsadminng.domain.enumeration.UserRole; import org.hostsharing.hsadminng.repository.UserRoleAssignmentRepository; import org.hostsharing.hsadminng.service.UserRoleAssignmentQueryService; import org.hostsharing.hsadminng.service.UserRoleAssignmentService; +import org.hostsharing.hsadminng.service.accessfilter.Role; import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator; import org.junit.Before; @@ -50,8 +50,8 @@ public class UserRoleAssignmentResourceIntTest { private static final Long DEFAULT_ENTITY_OBJECT_ID = 1L; private static final Long UPDATED_ENTITY_OBJECT_ID = 2L; - private static final UserRole DEFAULT_ASSIGNED_ROLE = UserRole.HOSTMASTER; - private static final UserRole UPDATED_ASSIGNED_ROLE = UserRole.ADMIN; + private static final Role DEFAULT_ASSIGNED_ROLE = Role.HOSTMASTER; + private static final Role UPDATED_ASSIGNED_ROLE = Role.ADMIN; @Autowired private UserRoleAssignmentRepository userRoleAssignmentRepository;