JSonAccessFilter with initially working (hardcoded) grand parent role
This commit is contained in:
		@@ -1,15 +1,12 @@
 | 
			
		||||
package org.hostsharing.hsadminng.domain;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonIgnore;
 | 
			
		||||
 | 
			
		||||
import javax.persistence.*;
 | 
			
		||||
import javax.validation.constraints.*;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A Customer.
 | 
			
		||||
@@ -65,13 +62,21 @@ public class Customer implements Serializable {
 | 
			
		||||
 | 
			
		||||
    @OneToMany(mappedBy = "customer")
 | 
			
		||||
    private Set<Membership> memberships = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
    @OneToMany(mappedBy = "customer")
 | 
			
		||||
    private Set<SepaMandate> sepamandates = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
    // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
 | 
			
		||||
 | 
			
		||||
    public Long getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Customer id(long id) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setId(Long id) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
@@ -229,6 +234,7 @@ public class Customer implements Serializable {
 | 
			
		||||
    public void setSepamandates(Set<SepaMandate> sepaMandates) {
 | 
			
		||||
        this.sepamandates = sepaMandates;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,16 @@
 | 
			
		||||
package org.hostsharing.hsadminng.domain;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonIgnore;
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 | 
			
		||||
 | 
			
		||||
import javax.persistence.*;
 | 
			
		||||
import javax.validation.constraints.*;
 | 
			
		||||
 | 
			
		||||
import javax.validation.constraints.NotNull;
 | 
			
		||||
import javax.validation.constraints.Size;
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.time.LocalDate;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A Membership.
 | 
			
		||||
@@ -46,18 +45,26 @@ public class Membership implements Serializable {
 | 
			
		||||
 | 
			
		||||
    @OneToMany(mappedBy = "membership")
 | 
			
		||||
    private Set<Share> shares = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
    @OneToMany(mappedBy = "membership")
 | 
			
		||||
    private Set<Asset> assets = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
    @ManyToOne(optional = false)
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @JsonIgnoreProperties("memberships")
 | 
			
		||||
    private Customer customer;
 | 
			
		||||
 | 
			
		||||
    // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
 | 
			
		||||
 | 
			
		||||
    public Long getId() {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public Membership id(Long id) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
        return this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setId(Long id) {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
@@ -176,6 +183,7 @@ public class Membership implements Serializable {
 | 
			
		||||
    public void setCustomer(Customer customer) {
 | 
			
		||||
        this.customer = customer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@ import org.hostsharing.hsadminng.service.dto.CustomerDTO;
 | 
			
		||||
import org.hostsharing.hsadminng.service.mapper.CustomerMapper;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import org.springframework.data.domain.Page;
 | 
			
		||||
import org.springframework.data.domain.Pageable;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
@@ -19,7 +18,7 @@ import java.util.Optional;
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
@Transactional
 | 
			
		||||
public class CustomerService {
 | 
			
		||||
public class CustomerService implements DtoLoader<CustomerDTO> {
 | 
			
		||||
 | 
			
		||||
    private final Logger log = LoggerFactory.getLogger(CustomerService.class);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,7 @@
 | 
			
		||||
package org.hostsharing.hsadminng.service;
 | 
			
		||||
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
 | 
			
		||||
public interface DtoLoader<T> {
 | 
			
		||||
    Optional<? extends T> findOne(Long id);
 | 
			
		||||
}
 | 
			
		||||
@@ -19,7 +19,7 @@ import java.util.Optional;
 | 
			
		||||
 */
 | 
			
		||||
@Service
 | 
			
		||||
@Transactional
 | 
			
		||||
public class MembershipService {
 | 
			
		||||
public class MembershipService implements DtoLoader<MembershipDTO> {
 | 
			
		||||
 | 
			
		||||
    private final Logger log = LoggerFactory.getLogger(MembershipService.class);
 | 
			
		||||
 | 
			
		||||
@@ -73,6 +73,7 @@ public class MembershipService {
 | 
			
		||||
     * @param id the id of the entity
 | 
			
		||||
     * @return the entity
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(readOnly = true)
 | 
			
		||||
    public Optional<MembershipDTO> findOne(Long id) {
 | 
			
		||||
        log.debug("Request to get Membership : {}", id);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +1,33 @@
 | 
			
		||||
package org.hostsharing.hsadminng.service.accessfilter;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.lang3.NotImplementedException;
 | 
			
		||||
import org.hostsharing.hsadminng.security.SecurityUtils;
 | 
			
		||||
import org.hostsharing.hsadminng.service.CustomerService;
 | 
			
		||||
import org.hostsharing.hsadminng.service.DtoLoader;
 | 
			
		||||
import org.hostsharing.hsadminng.service.MembershipService;
 | 
			
		||||
import org.hostsharing.hsadminng.service.dto.CustomerDTO;
 | 
			
		||||
import org.hostsharing.hsadminng.service.dto.MembershipDTO;
 | 
			
		||||
import org.hostsharing.hsadminng.service.util.ReflectionUtil;
 | 
			
		||||
import org.springframework.context.ApplicationContext;
 | 
			
		||||
 | 
			
		||||
import java.lang.annotation.Annotation;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
 | 
			
		||||
abstract class JSonAccessFilter<T> {
 | 
			
		||||
    private final ApplicationContext ctx;
 | 
			
		||||
    final T dto;
 | 
			
		||||
    Field selfIdField = null;
 | 
			
		||||
    Field parentIdField = null;
 | 
			
		||||
    final Field selfIdField;
 | 
			
		||||
    final Field parentIdField;
 | 
			
		||||
 | 
			
		||||
    JSonAccessFilter(final T dto) {
 | 
			
		||||
    JSonAccessFilter(final ApplicationContext ctx, final T dto) {
 | 
			
		||||
        this.ctx = ctx;
 | 
			
		||||
        this.dto = dto;
 | 
			
		||||
        determineIdFields();
 | 
			
		||||
        this.selfIdField = determineFieldWithAnnotation(dto.getClass(), SelfId.class);
 | 
			
		||||
        this.parentIdField = determineFieldWithAnnotation(dto.getClass(), ParentId.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void determineIdFields() {
 | 
			
		||||
        for (Field field : dto.getClass().getDeclaredFields()) {
 | 
			
		||||
            if (field.isAnnotationPresent(SelfId.class)) {
 | 
			
		||||
                if (selfIdField != null) {
 | 
			
		||||
                    throw new AssertionError("multiple @" + SelfId.class.getSimpleName() + " detected in " + field.getDeclaringClass().getSimpleName());
 | 
			
		||||
                }
 | 
			
		||||
                selfIdField = field;
 | 
			
		||||
            }
 | 
			
		||||
            if (field.isAnnotationPresent(ParentId.class)) {
 | 
			
		||||
                if (parentIdField != null) {
 | 
			
		||||
                    throw new AssertionError("multiple @" + ParentId.class.getSimpleName() + " detected in " + field.getDeclaringClass().getSimpleName());
 | 
			
		||||
                }
 | 
			
		||||
                parentIdField = field;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    boolean isParentIdField(final Field field) {
 | 
			
		||||
        return field.equals(parentIdField);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Long getId() {
 | 
			
		||||
@@ -39,27 +37,68 @@ abstract class JSonAccessFilter<T> {
 | 
			
		||||
        return (Long) ReflectionUtil.getValue(dto, selfIdField);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param field to get a display representation for
 | 
			
		||||
     * @return a simplified, decently user readable, display representation of the given field
 | 
			
		||||
     */
 | 
			
		||||
    String toDisplay(final Field field) {
 | 
			
		||||
        return field.getDeclaringClass().getSimpleName() + "." + field.getName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return the role of the login user in relation to the dto, this filter is created for.
 | 
			
		||||
     */
 | 
			
		||||
    Role getLoginUserRole() {
 | 
			
		||||
        final Role roleOnSelf = getLoginUserRoleOnSelf();
 | 
			
		||||
        final Role roleOnParent = getLoginUserRoleOnParent();
 | 
			
		||||
        return roleOnSelf.covers(roleOnParent) ? roleOnSelf : roleOnParent;
 | 
			
		||||
        if ( roleOnSelf.isIndependent() ) {
 | 
			
		||||
            return roleOnSelf;
 | 
			
		||||
        }
 | 
			
		||||
        return getLoginUserRoleOnAncestorOfDtoClassIfHigher(roleOnSelf, dto);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private Role getLoginUserRoleOnSelf() {
 | 
			
		||||
        // TODO: find broadest role in self and recursively in parent
 | 
			
		||||
        return SecurityUtils.getLoginUserRoleFor(dto.getClass(), getId() );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Role getLoginUserRoleOnParent() {
 | 
			
		||||
    private Role getLoginUserRoleOnAncestorOfDtoClassIfHigher(final Role baseRole, final Object dto) {
 | 
			
		||||
        final Field parentIdField = determineFieldWithAnnotation(dto.getClass(), ParentId.class);
 | 
			
		||||
 | 
			
		||||
        if ( parentIdField == null ) {
 | 
			
		||||
            return Role.ANYBODY;
 | 
			
		||||
            return baseRole;
 | 
			
		||||
        }
 | 
			
		||||
        final ParentId parentId = parentIdField.getAnnotation(ParentId.class);
 | 
			
		||||
        return SecurityUtils.getLoginUserRoleFor(parentId.value(), (Long) ReflectionUtil.getValue(dto, parentIdField) );
 | 
			
		||||
 | 
			
		||||
        final ParentId parentIdAnnot = parentIdField.getAnnotation(ParentId.class);
 | 
			
		||||
        final Class<?> parentDtoClass = parentIdAnnot.value();
 | 
			
		||||
        final Long parentId = (Long) ReflectionUtil.getValue(dto, parentIdField);
 | 
			
		||||
        final Role roleOnParent = SecurityUtils.getLoginUserRoleFor(parentDtoClass, parentId);
 | 
			
		||||
 | 
			
		||||
        final Object parentEntity = findParentDto(parentDtoClass, parentId);
 | 
			
		||||
        return Role.broadest(baseRole, getLoginUserRoleOnAncestorOfDtoClassIfHigher(roleOnParent, parentEntity));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Object findParentDto(Class<?> parentDtoClass, Long parentId) {
 | 
			
		||||
        // TODO: generalize, e.g. via "all beans that implement DtoLoader<CustomerDTO>
 | 
			
		||||
        if ( parentDtoClass == MembershipDTO.class ) {
 | 
			
		||||
            final DtoLoader<MembershipDTO> dtoLoader = ctx.getAutowireCapableBeanFactory().createBean(MembershipService.class);
 | 
			
		||||
            return dtoLoader.findOne(parentId).get();
 | 
			
		||||
        }
 | 
			
		||||
        if ( parentDtoClass == CustomerDTO.class ) {
 | 
			
		||||
            final DtoLoader<CustomerDTO> dtoLoader = ctx.getAutowireCapableBeanFactory().createBean(CustomerService.class);
 | 
			
		||||
            return dtoLoader.findOne(parentId).get();
 | 
			
		||||
        }
 | 
			
		||||
        throw new NotImplementedException("no DtoLoader implemented for " + parentDtoClass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static Field determineFieldWithAnnotation(final Class<?> dtoClass, final Class<? extends Annotation> idAnnotationClass) {
 | 
			
		||||
        Field parentIdField = null;
 | 
			
		||||
        for (Field field : dtoClass.getDeclaredFields()) {
 | 
			
		||||
            if (field.isAnnotationPresent(idAnnotationClass)) {
 | 
			
		||||
                if (parentIdField != null) {
 | 
			
		||||
                    throw new AssertionError("multiple @" + idAnnotationClass.getSimpleName() + " detected in " + field.getDeclaringClass().getSimpleName());
 | 
			
		||||
                }
 | 
			
		||||
                parentIdField = field;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return parentIdField;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.node.TextNode;
 | 
			
		||||
import org.apache.commons.lang3.NotImplementedException;
 | 
			
		||||
import org.hostsharing.hsadminng.service.util.ReflectionUtil;
 | 
			
		||||
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
 | 
			
		||||
import org.springframework.context.ApplicationContext;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
@@ -21,8 +22,8 @@ public class JSonDeserializerWithAccessFilter<T> extends JSonAccessFilter<T> {
 | 
			
		||||
    private final TreeNode treeNode;
 | 
			
		||||
    private final Set<Field> modifiedFields = new HashSet<>();
 | 
			
		||||
 | 
			
		||||
    public JSonDeserializerWithAccessFilter(final JsonParser jsonParser, final DeserializationContext deserializationContext, Class<T> dtoClass) {
 | 
			
		||||
        super(unchecked(dtoClass::newInstance));
 | 
			
		||||
    public JSonDeserializerWithAccessFilter(final ApplicationContext ctx, final JsonParser jsonParser, final DeserializationContext deserializationContext, Class<T> dtoClass) {
 | 
			
		||||
        super(ctx, unchecked(dtoClass::newInstance));
 | 
			
		||||
        this.treeNode = unchecked(() -> jsonParser.getCodec().readTree(jsonParser));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,18 +4,21 @@ package org.hostsharing.hsadminng.service.accessfilter;
 | 
			
		||||
import com.fasterxml.jackson.core.JsonGenerator;
 | 
			
		||||
import com.fasterxml.jackson.databind.SerializerProvider;
 | 
			
		||||
import org.apache.commons.lang3.NotImplementedException;
 | 
			
		||||
import org.springframework.context.ApplicationContext;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.Field;
 | 
			
		||||
import java.time.LocalDate;
 | 
			
		||||
 | 
			
		||||
public class JSonSerializerWithAccessFilter <T> extends JSonAccessFilter<T> {
 | 
			
		||||
    private final JsonGenerator jsonGenerator;
 | 
			
		||||
    private final SerializerProvider serializerProvider;
 | 
			
		||||
 | 
			
		||||
    public JSonSerializerWithAccessFilter(final JsonGenerator jsonGenerator,
 | 
			
		||||
    public JSonSerializerWithAccessFilter(final ApplicationContext ctx,
 | 
			
		||||
                                          final JsonGenerator jsonGenerator,
 | 
			
		||||
                                          final SerializerProvider serializerProvider,
 | 
			
		||||
                                          final T dto) {
 | 
			
		||||
        super(dto);
 | 
			
		||||
        super(ctx, dto);
 | 
			
		||||
        this.jsonGenerator = jsonGenerator;
 | 
			
		||||
        this.serializerProvider = serializerProvider;
 | 
			
		||||
    }
 | 
			
		||||
@@ -42,6 +45,10 @@ public class JSonSerializerWithAccessFilter <T> extends JSonAccessFilter<T> {
 | 
			
		||||
                jsonGenerator.writeNumberField(fieldName, (int) get(dto, prop));
 | 
			
		||||
            } else if (Long.class.isAssignableFrom(prop.getType()) || long.class.isAssignableFrom(prop.getType())) {
 | 
			
		||||
                jsonGenerator.writeNumberField(fieldName, (long) get(dto, prop));
 | 
			
		||||
            } else if (LocalDate.class.isAssignableFrom(prop.getType())) {
 | 
			
		||||
                jsonGenerator.writeStringField(fieldName, get(dto, prop).toString()); // TODO proper format
 | 
			
		||||
            } else if (Enum.class.isAssignableFrom(prop.getType())) {
 | 
			
		||||
                jsonGenerator.writeStringField(fieldName, get(dto, prop).toString()); // TODO proper representation
 | 
			
		||||
            } else if (String.class.isAssignableFrom(prop.getType())) {
 | 
			
		||||
                jsonGenerator.writeStringField(fieldName, (String) get(dto, prop));
 | 
			
		||||
            } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -87,6 +87,26 @@ public enum Role {
 | 
			
		||||
        this.level = level;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @return true if this role is independent of a target object, false otherwise.
 | 
			
		||||
     */
 | 
			
		||||
    public boolean isIndependent() {
 | 
			
		||||
        return covers(Role.SUPPORTER);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    @return the role with the broadest access rights
 | 
			
		||||
     */
 | 
			
		||||
    public static Role broadest(final Role role, final Role... roles) {
 | 
			
		||||
        Role broadests = role;
 | 
			
		||||
        for ( Role r: roles ) {
 | 
			
		||||
            if ( r.covers(broadests)) {
 | 
			
		||||
                broadests = r;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return broadests;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Determines if the given role is covered by this role.
 | 
			
		||||
     *
 | 
			
		||||
@@ -163,5 +183,4 @@ public enum Role {
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.JsonSerializer;
 | 
			
		||||
import com.fasterxml.jackson.databind.SerializerProvider;
 | 
			
		||||
import org.hostsharing.hsadminng.service.accessfilter.*;
 | 
			
		||||
import org.springframework.boot.jackson.JsonComponent;
 | 
			
		||||
import org.springframework.context.ApplicationContext;
 | 
			
		||||
 | 
			
		||||
import javax.validation.constraints.*;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
@@ -172,24 +173,34 @@ public class CustomerDTO implements Serializable {
 | 
			
		||||
    @JsonComponent
 | 
			
		||||
    public static class CustomerJsonSerializer extends JsonSerializer<CustomerDTO> {
 | 
			
		||||
 | 
			
		||||
        private final ApplicationContext ctx;
 | 
			
		||||
 | 
			
		||||
        public CustomerJsonSerializer(final ApplicationContext ctx) {
 | 
			
		||||
            this.ctx = ctx;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public void serialize(final CustomerDTO customerDTO, final JsonGenerator jsonGenerator,
 | 
			
		||||
                              final SerializerProvider serializerProvider) throws IOException {
 | 
			
		||||
 | 
			
		||||
           new JSonSerializerWithAccessFilter<>(jsonGenerator, serializerProvider, customerDTO).serialize();
 | 
			
		||||
           new JSonSerializerWithAccessFilter<>(ctx, jsonGenerator, serializerProvider, customerDTO).serialize();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @JsonComponent
 | 
			
		||||
    public static class CustomerJsonDeserializer extends JsonDeserializer<CustomerDTO> {
 | 
			
		||||
 | 
			
		||||
        private final ApplicationContext ctx;
 | 
			
		||||
 | 
			
		||||
        public CustomerJsonDeserializer(final ApplicationContext ctx) {
 | 
			
		||||
            this.ctx = ctx;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public CustomerDTO deserialize(final JsonParser jsonParser,
 | 
			
		||||
                                       final DeserializationContext deserializationContext) {
 | 
			
		||||
 | 
			
		||||
            return new JSonDeserializerWithAccessFilter<>(jsonParser, deserializationContext, CustomerDTO.class).deserialize();
 | 
			
		||||
            return new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, deserializationContext, CustomerDTO.class).deserialize();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,10 +37,10 @@ public class MembershipDTO implements Serializable {
 | 
			
		||||
    private String remark;
 | 
			
		||||
 | 
			
		||||
    @ParentId(CustomerDTO.class)
 | 
			
		||||
    @AccessFor(init = Role.ADMIN, read = Role.SUPPORTER)
 | 
			
		||||
    @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
 | 
			
		||||
    private Long customerId;
 | 
			
		||||
 | 
			
		||||
    @AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
 | 
			
		||||
    @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
 | 
			
		||||
    private String customerPrefix;
 | 
			
		||||
 | 
			
		||||
    public MembershipDTO with(
 | 
			
		||||
 
 | 
			
		||||
@@ -1,35 +1,51 @@
 | 
			
		||||
package org.hostsharing.hsadminng.service.dto;
 | 
			
		||||
import java.time.LocalDate;
 | 
			
		||||
import javax.validation.constraints.*;
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
import org.hostsharing.hsadminng.domain.enumeration.ShareAction;
 | 
			
		||||
import org.hostsharing.hsadminng.service.accessfilter.AccessFor;
 | 
			
		||||
import org.hostsharing.hsadminng.service.accessfilter.ParentId;
 | 
			
		||||
import org.hostsharing.hsadminng.service.accessfilter.Role;
 | 
			
		||||
import org.hostsharing.hsadminng.service.accessfilter.SelfId;
 | 
			
		||||
 | 
			
		||||
import javax.validation.constraints.NotNull;
 | 
			
		||||
import javax.validation.constraints.Size;
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.time.LocalDate;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A DTO for the Share entity.
 | 
			
		||||
 */
 | 
			
		||||
public class ShareDTO implements Serializable {
 | 
			
		||||
 | 
			
		||||
    @SelfId
 | 
			
		||||
    @AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
 | 
			
		||||
    private Long id;
 | 
			
		||||
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
 | 
			
		||||
    private LocalDate documentDate;
 | 
			
		||||
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
 | 
			
		||||
    private LocalDate valueDate;
 | 
			
		||||
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
 | 
			
		||||
    private ShareAction action;
 | 
			
		||||
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
 | 
			
		||||
    private Integer quantity;
 | 
			
		||||
 | 
			
		||||
    @Size(max = 160)
 | 
			
		||||
    @AccessFor(init = Role.ADMIN, read = Role.SUPPORTER)
 | 
			
		||||
    private String remark;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @ParentId(MembershipDTO.class)
 | 
			
		||||
    @AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
 | 
			
		||||
    private Long membershipId;
 | 
			
		||||
 | 
			
		||||
    @AccessFor(init = Role.ADMIN, read = Role.SUPPORTER)
 | 
			
		||||
    private String membershipDocumentDate;
 | 
			
		||||
 | 
			
		||||
    public Long getId() {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user