Merge branch 'master' of ssh://dev.hostsharing.net:29418/hsadmin/hsadmin-ng

This commit is contained in:
Michael Hierweck 2019-04-25 17:17:18 +02:00
commit 070f321a06
77 changed files with 2131 additions and 283 deletions

41
package-lock.json generated
View File

@ -6025,7 +6025,8 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -6046,12 +6047,14 @@
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -6066,17 +6069,20 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -6193,7 +6199,8 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -6205,6 +6212,7 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -6219,6 +6227,7 @@
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@ -6226,12 +6235,14 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.3.5", "version": "2.3.5",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -6250,6 +6261,7 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@ -6330,7 +6342,8 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@ -6342,6 +6355,7 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -6427,7 +6441,8 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -6463,6 +6478,7 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -6482,6 +6498,7 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -6525,12 +6542,14 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.3", "version": "3.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
} }
} }
}, },

View File

@ -1,11 +1,11 @@
package org.hostsharing.hsadminng; package org.hostsharing.hsadminng;
import io.github.jhipster.config.JHipsterConstants;
import org.apache.commons.lang3.StringUtils;
import org.hostsharing.hsadminng.config.ApplicationProperties; import org.hostsharing.hsadminng.config.ApplicationProperties;
import org.hostsharing.hsadminng.config.DefaultProfileUtil; import org.hostsharing.hsadminng.config.DefaultProfileUtil;
import org.hostsharing.hsadminng.security.SecurityUtils;
import io.github.jhipster.config.JHipsterConstants; import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
@ -41,6 +41,10 @@ public class HsadminNgApp {
*/ */
@PostConstruct @PostConstruct
public void initApplication() { public void initApplication() {
// TODO: remove this hack once proper user roles are implemented
SecurityUtils.addUserRole(null, null, Role.HOSTMASTER);
Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles()); Collection<String> activeProfiles = Arrays.asList(env.getActiveProfiles());
if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) { if (activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_DEVELOPMENT) && activeProfiles.contains(JHipsterConstants.SPRING_PROFILE_PRODUCTION)) {
log.error("You have misconfigured your application! It should not run " + log.error("You have misconfigured your application! It should not run " +

View File

@ -2,17 +2,16 @@ package org.hostsharing.hsadminng.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.*; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Objects; import java.util.Objects;
import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
/** /**
* A Asset. * A Asset.
*/ */

View File

@ -1,20 +1,16 @@
package org.hostsharing.hsadminng.domain; package org.hostsharing.hsadminng.domain;
import com.fasterxml.jackson.annotation.JsonIgnore; import org.hostsharing.hsadminng.domain.enumeration.CustomerKind;
import org.hostsharing.hsadminng.domain.enumeration.VatRegion;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.*; import javax.validation.constraints.*;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import org.hostsharing.hsadminng.domain.enumeration.CustomerKind;
import org.hostsharing.hsadminng.domain.enumeration.VatRegion;
/** /**
* A Customer. * A Customer.
@ -99,13 +95,21 @@ public class Customer implements Serializable {
@OneToMany(mappedBy = "customer") @OneToMany(mappedBy = "customer")
private Set<Membership> memberships = new HashSet<>(); private Set<Membership> memberships = new HashSet<>();
@OneToMany(mappedBy = "customer") @OneToMany(mappedBy = "customer")
private Set<SepaMandate> sepamandates = new HashSet<>(); private Set<SepaMandate> sepamandates = new HashSet<>();
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
public Long getId() { public Long getId() {
return id; return id;
} }
public Customer id(long id) {
this.id = id;
return this;
}
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
@ -354,6 +358,7 @@ public class Customer implements Serializable {
public void setSepamandates(Set<SepaMandate> sepaMandates) { public void setSepamandates(Set<SepaMandate> sepaMandates) {
this.sepamandates = sepaMandates; this.sepamandates = sepaMandates;
} }
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
@Override @Override

View File

@ -1,17 +1,16 @@
package org.hostsharing.hsadminng.domain; package org.hostsharing.hsadminng.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.*; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
/** /**
* A Membership. * A Membership.
@ -49,18 +48,26 @@ public class Membership implements Serializable {
@OneToMany(mappedBy = "membership") @OneToMany(mappedBy = "membership")
private Set<Share> shares = new HashSet<>(); private Set<Share> shares = new HashSet<>();
@OneToMany(mappedBy = "membership") @OneToMany(mappedBy = "membership")
private Set<Asset> assets = new HashSet<>(); private Set<Asset> assets = new HashSet<>();
@ManyToOne(optional = false) @ManyToOne(optional = false)
@NotNull @NotNull
@JsonIgnoreProperties("memberships") @JsonIgnoreProperties("memberships")
private Customer customer; private Customer customer;
// jhipster-needle-entity-add-field - JHipster will add fields here, do not remove // jhipster-needle-entity-add-field - JHipster will add fields here, do not remove
public Long getId() { public Long getId() {
return id; return id;
} }
public Membership id(Long id) {
this.id = id;
return this;
}
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
@ -192,6 +199,7 @@ public class Membership implements Serializable {
public void setCustomer(Customer customer) { public void setCustomer(Customer customer) {
this.customer = customer; this.customer = customer;
} }
// jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here, do not remove
@Override @Override

View File

@ -4,8 +4,8 @@ package org.hostsharing.hsadminng.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.*; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Objects; import java.util.Objects;

View File

@ -2,16 +2,15 @@ package org.hostsharing.hsadminng.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.hostsharing.hsadminng.domain.enumeration.ShareAction;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.*; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.Objects; import java.util.Objects;
import org.hostsharing.hsadminng.domain.enumeration.ShareAction;
/** /**
* A Share. * A Share.
*/ */

View File

@ -5,8 +5,12 @@ package org.hostsharing.hsadminng.security;
*/ */
public final class AuthoritiesConstants { public final class AuthoritiesConstants {
public static final String HOSTMASTER = "ROLE_HOSTMASTER";
public static final String ADMIN = "ROLE_ADMIN"; public static final String ADMIN = "ROLE_ADMIN";
public static final String SUPPORTER = "ROLE_SUPPORTER";
public static final String USER = "ROLE_USER"; public static final String USER = "ROLE_USER";
public static final String ANONYMOUS = "ROLE_ANONYMOUS"; public static final String ANONYMOUS = "ROLE_ANONYMOUS";

View File

@ -1,9 +1,12 @@
package org.hostsharing.hsadminng.security; package org.hostsharing.hsadminng.security;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional; import java.util.Optional;
/** /**
@ -11,6 +14,8 @@ import java.util.Optional;
*/ */
public final class SecurityUtils { public final class SecurityUtils {
private static List<UserRoleAssignment> userRoleAssignments = new ArrayList<>();
private SecurityUtils() { private SecurityUtils() {
} }
@ -73,4 +78,41 @@ public final class SecurityUtils {
.anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(authority))) .anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(authority)))
.orElse(false); .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);
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) {
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;
}
}
} }

View File

@ -6,7 +6,6 @@ import org.hostsharing.hsadminng.service.dto.AssetDTO;
import org.hostsharing.hsadminng.service.mapper.AssetMapper; import org.hostsharing.hsadminng.service.mapper.AssetMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;

View File

@ -1,9 +1,14 @@
package org.hostsharing.hsadminng.service; package org.hostsharing.hsadminng.service;
import java.util.List; import io.github.jhipster.service.QueryService;
import org.hostsharing.hsadminng.domain.Customer;
import javax.persistence.criteria.JoinType; import org.hostsharing.hsadminng.domain.Customer_;
import org.hostsharing.hsadminng.domain.Membership_;
import org.hostsharing.hsadminng.domain.SepaMandate_;
import org.hostsharing.hsadminng.repository.CustomerRepository;
import org.hostsharing.hsadminng.service.dto.CustomerCriteria;
import org.hostsharing.hsadminng.service.dto.CustomerDTO;
import org.hostsharing.hsadminng.service.mapper.CustomerMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@ -12,14 +17,8 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import io.github.jhipster.service.QueryService; import javax.persistence.criteria.JoinType;
import java.util.List;
import org.hostsharing.hsadminng.domain.Customer;
import org.hostsharing.hsadminng.domain.*; // for static metamodels
import org.hostsharing.hsadminng.repository.CustomerRepository;
import org.hostsharing.hsadminng.service.dto.CustomerCriteria;
import org.hostsharing.hsadminng.service.dto.CustomerDTO;
import org.hostsharing.hsadminng.service.mapper.CustomerMapper;
/** /**
* Service for executing complex queries for Customer entities in the database. * Service for executing complex queries for Customer entities in the database.

View File

@ -6,7 +6,6 @@ import org.hostsharing.hsadminng.service.dto.CustomerDTO;
import org.hostsharing.hsadminng.service.mapper.CustomerMapper; import org.hostsharing.hsadminng.service.mapper.CustomerMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -19,7 +18,7 @@ import java.util.Optional;
*/ */
@Service @Service
@Transactional @Transactional
public class CustomerService { public class CustomerService implements IdToDtoResolver<CustomerDTO> {
private final Logger log = LoggerFactory.getLogger(CustomerService.class); private final Logger log = LoggerFactory.getLogger(CustomerService.class);

View File

@ -0,0 +1,7 @@
package org.hostsharing.hsadminng.service;
import java.util.Optional;
public interface IdToDtoResolver<T> {
Optional<T> findOne(Long id);
}

View File

@ -1,9 +1,11 @@
package org.hostsharing.hsadminng.service; package org.hostsharing.hsadminng.service;
import java.util.List; import io.github.jhipster.service.QueryService;
import org.hostsharing.hsadminng.domain.*;
import javax.persistence.criteria.JoinType; import org.hostsharing.hsadminng.repository.MembershipRepository;
import org.hostsharing.hsadminng.service.dto.MembershipCriteria;
import org.hostsharing.hsadminng.service.dto.MembershipDTO;
import org.hostsharing.hsadminng.service.mapper.MembershipMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@ -12,14 +14,8 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import io.github.jhipster.service.QueryService; import javax.persistence.criteria.JoinType;
import java.util.List;
import org.hostsharing.hsadminng.domain.Membership;
import org.hostsharing.hsadminng.domain.*; // for static metamodels
import org.hostsharing.hsadminng.repository.MembershipRepository;
import org.hostsharing.hsadminng.service.dto.MembershipCriteria;
import org.hostsharing.hsadminng.service.dto.MembershipDTO;
import org.hostsharing.hsadminng.service.mapper.MembershipMapper;
/** /**
* Service for executing complex queries for Membership entities in the database. * Service for executing complex queries for Membership entities in the database.

View File

@ -19,7 +19,7 @@ import java.util.Optional;
*/ */
@Service @Service
@Transactional @Transactional
public class MembershipService { public class MembershipService implements IdToDtoResolver<MembershipDTO> {
private final Logger log = LoggerFactory.getLogger(MembershipService.class); private final Logger log = LoggerFactory.getLogger(MembershipService.class);
@ -73,6 +73,7 @@ public class MembershipService {
* @param id the id of the entity * @param id the id of the entity
* @return the entity * @return the entity
*/ */
@Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public Optional<MembershipDTO> findOne(Long id) { public Optional<MembershipDTO> findOne(Long id) {
log.debug("Request to get Membership : {}", id); log.debug("Request to get Membership : {}", id);

View File

@ -1,9 +1,13 @@
package org.hostsharing.hsadminng.service; package org.hostsharing.hsadminng.service;
import java.util.List; import io.github.jhipster.service.QueryService;
import org.hostsharing.hsadminng.domain.Customer_;
import javax.persistence.criteria.JoinType; import org.hostsharing.hsadminng.domain.SepaMandate;
import org.hostsharing.hsadminng.domain.SepaMandate_;
import org.hostsharing.hsadminng.repository.SepaMandateRepository;
import org.hostsharing.hsadminng.service.dto.SepaMandateCriteria;
import org.hostsharing.hsadminng.service.dto.SepaMandateDTO;
import org.hostsharing.hsadminng.service.mapper.SepaMandateMapper;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@ -12,14 +16,8 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import io.github.jhipster.service.QueryService; import javax.persistence.criteria.JoinType;
import java.util.List;
import org.hostsharing.hsadminng.domain.SepaMandate;
import org.hostsharing.hsadminng.domain.*; // for static metamodels
import org.hostsharing.hsadminng.repository.SepaMandateRepository;
import org.hostsharing.hsadminng.service.dto.SepaMandateCriteria;
import org.hostsharing.hsadminng.service.dto.SepaMandateDTO;
import org.hostsharing.hsadminng.service.mapper.SepaMandateMapper;
/** /**
* Service for executing complex queries for SepaMandate entities in the database. * Service for executing complex queries for SepaMandate entities in the database.

View File

@ -1,7 +1,6 @@
package org.hostsharing.hsadminng.service; package org.hostsharing.hsadminng.service;
import org.hostsharing.hsadminng.domain.Share; import org.hostsharing.hsadminng.domain.Share;
import org.hostsharing.hsadminng.domain.enumeration.ShareAction;
import org.hostsharing.hsadminng.repository.ShareRepository; import org.hostsharing.hsadminng.repository.ShareRepository;
import org.hostsharing.hsadminng.service.dto.ShareDTO; import org.hostsharing.hsadminng.service.dto.ShareDTO;
import org.hostsharing.hsadminng.service.mapper.ShareMapper; import org.hostsharing.hsadminng.service.mapper.ShareMapper;
@ -20,7 +19,7 @@ import java.util.Optional;
*/ */
@Service @Service
@Transactional @Transactional
public class ShareService { public class ShareService implements IdToDtoResolver<ShareDTO> {
private final Logger log = LoggerFactory.getLogger(ShareService.class); private final Logger log = LoggerFactory.getLogger(ShareService.class);

View File

@ -0,0 +1,16 @@
package org.hostsharing.hsadminng.service.accessfilter;
import java.lang.annotation.*;
@Documented
@Target({ElementType.FIELD, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessFor {
Role[] init() default Role.NOBODY;
Role[] update() default Role.NOBODY;
Role[] read() default Role.NOBODY;
}

View File

@ -0,0 +1,121 @@
package org.hostsharing.hsadminng.service.accessfilter;
import org.hostsharing.hsadminng.security.SecurityUtils;
import org.hostsharing.hsadminng.service.IdToDtoResolver;
import org.hostsharing.hsadminng.service.dto.MembershipDTO;
import org.hostsharing.hsadminng.service.util.ReflectionUtil;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import static com.google.common.base.Verify.verify;
abstract class JSonAccessFilter<T> {
private final ApplicationContext ctx;
final T dto;
final Field selfIdField;
final Field parentIdField;
JSonAccessFilter(final ApplicationContext ctx, final T dto) {
this.ctx = ctx;
this.dto = dto;
this.selfIdField = determineFieldWithAnnotation(dto.getClass(), SelfId.class);
this.parentIdField = determineFieldWithAnnotation(dto.getClass(), ParentId.class);
}
boolean isParentIdField(final Field field) {
return field.equals(parentIdField);
}
Long getId() {
if (selfIdField == null) {
return null;
}
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();
if (roleOnSelf.isIndependent()) {
return roleOnSelf;
}
return getLoginUserRoleOnAncestorOfDtoClassIfHigher(roleOnSelf, dto);
}
private Role getLoginUserRoleOnSelf() {
return SecurityUtils.getLoginUserRoleFor(dto.getClass(), getId());
}
private Role getLoginUserRoleOnAncestorOfDtoClassIfHigher(final Role baseRole, final Object dto) {
final Field parentIdField = determineFieldWithAnnotation(dto.getClass(), ParentId.class);
if (parentIdField == null) {
return baseRole;
}
final ParentId parentIdAnnot = parentIdField.getAnnotation(ParentId.class);
final Class<? extends IdToDtoResolver> parentDtoLoader = parentIdAnnot.resolver();
final Class<?> parentDtoClass = getGenericClassParameter(parentDtoLoader);
final Long parentId = (Long) ReflectionUtil.getValue(dto, parentIdField);
final Role roleOnParent = SecurityUtils.getLoginUserRoleFor(parentDtoClass, parentId);
final Object parentEntity = loadDto(parentDtoLoader, parentId);
return Role.broadest(baseRole, getLoginUserRoleOnAncestorOfDtoClassIfHigher(roleOnParent, parentEntity));
}
@SuppressWarnings("unchecked")
private Class<T> getGenericClassParameter(Class<? extends IdToDtoResolver> parentDtoLoader) {
for (Type genericInterface : parentDtoLoader.getGenericInterfaces()) {
if (genericInterface instanceof ParameterizedType) {
final ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
if (parameterizedType.getRawType()== IdToDtoResolver.class) {
return (Class<T>) parameterizedType.getActualTypeArguments()[0];
}
}
}
throw new AssertionError(parentDtoLoader.getSimpleName() + " expected to implement " + IdToDtoResolver.class.getSimpleName() + "<...DTO>");
}
@SuppressWarnings("unchecked")
protected Object loadDto(final Class<? extends IdToDtoResolver> resolverClass, final Long id) {
verify(id != null, "id must not be null");
final AutowireCapableBeanFactory beanFactory = ctx.getAutowireCapableBeanFactory();
verify(beanFactory != null, "no bean factory found, probably missing mock configuration for ApplicationContext, e.g. given(...)");
final IdToDtoResolver<MembershipDTO> resolverBean = beanFactory.createBean(resolverClass);
verify(resolverBean != null, "no " + resolverClass.getSimpleName() + " bean created, probably missing mock configuration for AutowireCapableBeanFactory, e.g. given(...)");
return resolverBean.findOne(id).orElseThrow(() -> new BadRequestAlertException("Can't resolve entity ID " + id + " via " + resolverClass, resolverClass.getSimpleName(), "isNotFound"));
}
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;
}
}

View File

@ -0,0 +1,140 @@
package org.hostsharing.hsadminng.service.accessfilter;
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 org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.ObjectUtils;
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.time.LocalDate;
import java.util.HashSet;
import java.util.Set;
import static org.hostsharing.hsadminng.service.util.ReflectionUtil.unchecked;
public class JSonDeserializerWithAccessFilter<T> extends JSonAccessFilter<T> {
private final TreeNode treeNode;
private final Set<Field> writtenFields = new HashSet<>();
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));
}
// Jackson deserializes from the JsonParser, thus no input parameter needed.
public T deserialize() {
deserializeValues();
final T currentDto = loadCurrentDto(getId());
overwriteUnmodifiedFieldsWithCurrentValues(currentDto);
checkAccessToWrittenFields(currentDto);
return dto;
}
private void deserializeValues() {
treeNode.fieldNames().forEachRemaining(fieldName -> {
try {
final Field field = dto.getClass().getDeclaredField(fieldName);
final Object newValue = readValue(treeNode, field);
writeValue(dto, field, newValue);
} catch (NoSuchFieldException e) {
throw new RuntimeException("setting field " + fieldName + " failed", e);
}
});
}
@SuppressWarnings("unchecked")
private T loadCurrentDto(final Long id) {
if (id != null) {
return (T) loadDto(selfIdField.getAnnotation(SelfId.class).resolver(), id);
}
return null;
}
private void overwriteUnmodifiedFieldsWithCurrentValues(final Object currentDto) {
if (currentDto == null) {
return;
}
for (Field field : currentDto.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(AccessFor.class) && !writtenFields.contains(field)) {
final Object value = ReflectionUtil.getValue(currentDto, field);
ReflectionUtil.setValue(dto, field, value);
}
}
}
private Object readValue(final TreeNode treeNode, final Field field) {
return readValue(treeNode, field.getName(), field.getType());
}
private Object readValue(final TreeNode treeNode, final String fieldName, final Class<?> fieldClass) {
final TreeNode fieldNode = treeNode.get(fieldName);
if (fieldNode instanceof NullNode) {
return null;
}
if (fieldNode instanceof TextNode) {
return ((TextNode) fieldNode).asText();
}
if (fieldNode instanceof IntNode) {
return ((IntNode) fieldNode).asInt();
}
if (fieldNode instanceof LongNode) {
return ((LongNode) fieldNode).asLong();
}
if (fieldNode instanceof ArrayNode && LocalDate.class.isAssignableFrom(fieldClass)) {
return LocalDate.of(((ArrayNode) fieldNode).get(0).asInt(), ((ArrayNode) fieldNode).get(1).asInt(), ((ArrayNode) fieldNode).get(2).asInt());
}
{
throw new NotImplementedException("property type not yet implemented: " + fieldNode + " -> " + fieldName + ": " + fieldClass);
}
}
private void writeValue(final T dto, final Field field, final Object value) {
if (value == null) {
ReflectionUtil.setValue(dto, field, null);
} else if (field.getType().isAssignableFrom(value.getClass())) {
ReflectionUtil.setValue(dto, field, value);
} else if (Integer.class.isAssignableFrom(field.getType()) || int.class.isAssignableFrom(field.getType())) {
ReflectionUtil.setValue(dto, field, ((Number) value).intValue());
} else if (Long.class.isAssignableFrom(field.getType()) || long.class.isAssignableFrom(field.getType())) {
ReflectionUtil.setValue(dto, field, ((Number) value).longValue());
} else if (field.getType().isEnum()) {
ReflectionUtil.setValue(dto, field, Enum.valueOf((Class<Enum>) field.getType(), value.toString()));
} else if (LocalDate.class.isAssignableFrom(field.getType())) {
ReflectionUtil.setValue(dto, field, LocalDate.parse(value.toString()));
} else {
throw new NotImplementedException("property type not yet implemented: " + field);
}
writtenFields.add(field);
}
private void checkAccessToWrittenFields(final T currentDto) {
writtenFields.forEach(field -> {
if (!field.equals(selfIdField)) {
final Role role = getLoginUserRole();
if (getId() == null) {
if (!role.isAllowedToInit(field)) {
if (!field.equals(parentIdField)) {
throw new BadRequestAlertException("Initialization of field " + toDisplay(field) + " prohibited for current user role " + role, toDisplay(field), "initializationProhibited");
} else {
throw new BadRequestAlertException("Referencing field " + toDisplay(field) + " prohibited for current user role " + role, toDisplay(field), "referencingProhibited");
}
}
} else if (isUpdate(field, dto, currentDto) && !getLoginUserRole().isAllowedToUpdate(field)) {
throw new BadRequestAlertException("Update of field " + toDisplay(field) + " prohibited for current user role " + role, toDisplay(field), "updateProhibited");
}
}
});
}
private boolean isUpdate(final Field field, final T dto, T currentDto) {
return ObjectUtils.notEqual(ReflectionUtil.getValue(dto, field), ReflectionUtil.getValue(currentDto, field));
}
}

View File

@ -0,0 +1,72 @@
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 ApplicationContext ctx,
final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider,
final T dto) {
super(ctx, dto);
this.jsonGenerator = jsonGenerator;
this.serializerProvider = serializerProvider;
}
// Jackson serializes into the JsonGenerator, thus no return value needed.
public void serialize() throws IOException {
jsonGenerator.writeStartObject();
for (Field field : dto.getClass().getDeclaredFields()) {
toJSon(dto, jsonGenerator, field);
}
jsonGenerator.writeEndObject();
}
private void toJSon(final Object dto, final JsonGenerator jsonGenerator, final Field field) throws IOException {
if (getLoginUserRole().isAllowedToRead(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).
// Alternatively extract the supported types to subclasses of some abstract class and
// here as well as in the deserializer just access the matching implementation through a map.
// Or even completely switch from Jackson to GSON?
final Object fieldValue = get(dto, field);
if (fieldValue == null) {
jsonGenerator.writeNullField(fieldName);
} else if (Integer.class.isAssignableFrom(field.getType()) || int.class.isAssignableFrom(field.getType())) {
jsonGenerator.writeNumberField(fieldName, (int) fieldValue);
} else if (Long.class.isAssignableFrom(field.getType()) || long.class.isAssignableFrom(field.getType())) {
jsonGenerator.writeNumberField(fieldName, (long) fieldValue);
} else if (LocalDate.class.isAssignableFrom(field.getType())) {
jsonGenerator.writeStringField(fieldName, fieldValue.toString()); // TODO proper format
} else if (Enum.class.isAssignableFrom(field.getType())) {
jsonGenerator.writeStringField(fieldName, fieldValue.toString()); // TODO proper representation
} else if (String.class.isAssignableFrom(field.getType())) {
jsonGenerator.writeStringField(fieldName, (String) fieldValue);
} else {
throw new NotImplementedException("property type not yet implemented: " + field);
}
}
}
private Object get(final Object dto, final Field field) {
try {
field.setAccessible(true);
return field.get(dto);
} catch (IllegalAccessException e) {
throw new RuntimeException("getting field " + field + " failed", e);
}
}
}

View File

@ -0,0 +1,19 @@
package org.hostsharing.hsadminng.service.accessfilter;
import org.hostsharing.hsadminng.service.IdToDtoResolver;
import java.lang.annotation.*;
/**
* Used to mark a field within a DTO as containing the id of a referenced entity,
* it's needed to determine access rights for entity creation.
*
* @see AccessFor
*/
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ParentId {
/// The service which can load the referenced DTO.
Class<? extends IdToDtoResolver<?>> resolver();
}

View File

@ -0,0 +1,186 @@
package org.hostsharing.hsadminng.service.accessfilter;
import java.lang.reflect.Field;
/**
* These enum values are on the one hand used to define the minimum role required to grant access to resources,
* but on the other hand also for the roles users can be assigned to.
*
* TODO: Maybe splitting it up into UserRole and RequiredRole would make it more clear?
* And maybe instead of a level, we could then add the comprised roles in the constructor?
* This could also be a better way to express that the financial contact has no rights to
* other users resources (see also ACTUAL_CUSTOMER_USEr vs. ANY_CUSTOMER_USER).
*/
public enum Role {
/**
* Default for access rights requirement. You can read it as: 'Nobody is allowed to ...'.
* This is usually used for fields which are managed by hsadminNg itself.
*/
NOBODY(0),
/**
* Hostmasters are initialize/update/read and field which, except where NOBODY is allowed to.
*/
HOSTMASTER(1),
/**
* This role is for administrators, e.g. to create memberships and book shared and assets.
*/
ADMIN(2),
/**
* This role is for members of the support team.
*/
SUPPORTER(3),
/**
* This role is for contractual contacts of a customer, like a director of the company.
* Who has this role, has the broadest access to all resources which belong to this customer.
* Everything which relates to the contract with the customer, needs this role.
*/
CONTRACTUAL_CONTACT(20),
/**
* This role is for financial contacts of a customer, e.g. for accessing billing data.
*/
FINANCIAL_CONTACT(22) {
@Override
public boolean covers(final Role role) {
if (role == ACTUAL_CUSTOMER_USER) {
return false;
}
return super.covers(role);
}
},
/**
* This role is for technical contacts of a customer.
*/
TECHNICAL_CONTACT(22),
/**
* This meta-role is to specify that any kind of customer contact can get access to the resource.
*/
ANY_CUSTOMER_CONTACT(29),
/**
* Any user which belongs to a customer has at least this role.
*/
ACTUAL_CUSTOMER_USER(80),
/**
* Use this to grant rights to any user, also special function users who have no
* rights on other users resources.
*/
ANY_CUSTOMER_USER(89),
/**
* 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);
private final int level;
Role(final int level) {
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.
*
* Where 'this' means the Java instance itself as a role of a system user.
*
* {@code
* Role.HOSTMASTER.covers(Role.ANY_CUSTOMER_USER) == true
* }
*
* @param role The required role for a resource.
*
* @return whether this role comprises the given role
*/
public boolean covers(final Role role) {
return this == role || this.level < role.level;
}
/**
* Checks if this role of a user allows to initialize the given field when creating the resource.
*
* @param field a field of the DTO of a resource
*
* @return true if allowed
*/
public boolean isAllowedToInit(final Field field) {
final AccessFor accessFor = field.getAnnotation(AccessFor.class);
if (accessFor == null) {
return false;
}
return isRoleCovered(accessFor.init());
}
/**
* Checks if this role of a user allows to update the given field.
*
* @param field a field of the DTO of a resource
*
* @return true if allowed
*/
public boolean isAllowedToUpdate(final Field field) {
final AccessFor accessFor = field.getAnnotation(AccessFor.class);
if (accessFor == null) {
return false;
}
return isRoleCovered(accessFor.update());
}
/**
* Checks if this role of a user allows to read the given field.
*
* @param field a field of the DTO of a resource
*
* @return true if allowed
*/
public boolean isAllowedToRead(final Field field) {
final AccessFor accessFor = field.getAnnotation(AccessFor.class);
if (accessFor == null) {
return false;
}
return isRoleCovered(accessFor.read());
}
private boolean isRoleCovered(final Role[] requiredRoles) {
for (Role accessAllowedForRole : requiredRoles) {
if (this.covers(accessAllowedForRole)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,21 @@
package org.hostsharing.hsadminng.service.accessfilter;
import org.hostsharing.hsadminng.service.IdToDtoResolver;
import java.lang.annotation.*;
/**
* Used to mark a field within a DTO as containing the own id,
* it's needed to identify an existing entity for update functions.
* Initialization and update rights have no meaning for such fields,
* its initialized automatically and never updated.
*
* @see AccessFor
*/
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SelfId {
/// The service which can load the referenced DTO.
Class<? extends IdToDtoResolver<?>> resolver();
}

View File

@ -1,10 +1,13 @@
package org.hostsharing.hsadminng.service.dto; package org.hostsharing.hsadminng.service.dto;
import java.time.LocalDate;
import javax.validation.constraints.*; import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Objects; import java.util.Objects;
import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
/** /**
* A DTO for the Asset entity. * A DTO for the Asset entity.
@ -31,7 +34,7 @@ public class AssetDTO implements Serializable {
private Long membershipId; private Long membershipId;
private String membershipAdmissionDocumentDate; private String membershipDisplayReference;
public Long getId() { public Long getId() {
return id; return id;
@ -89,12 +92,12 @@ public class AssetDTO implements Serializable {
this.membershipId = membershipId; this.membershipId = membershipId;
} }
public String getMembershipAdmissionDocumentDate() { public String getMembershipDisplayReference() {
return membershipAdmissionDocumentDate; return membershipDisplayReference;
} }
public void setMembershipAdmissionDocumentDate(String membershipAdmissionDocumentDate) { public void setMembershipDisplayReference(String membershipDisplayReference) {
this.membershipAdmissionDocumentDate = membershipAdmissionDocumentDate; this.membershipDisplayReference = membershipDisplayReference;
} }
@Override @Override
@ -128,7 +131,7 @@ public class AssetDTO implements Serializable {
", amount=" + getAmount() + ", amount=" + getAmount() +
", remark='" + getRemark() + "'" + ", remark='" + getRemark() + "'" +
", membership=" + getMembershipId() + ", membership=" + getMembershipId() +
", membership='" + getMembershipAdmissionDocumentDate() + "'" + ", membership='" + getMembershipDisplayReference() + "'" +
"}"; "}";
} }
} }

View File

@ -1,17 +1,11 @@
package org.hostsharing.hsadminng.service.dto; package org.hostsharing.hsadminng.service.dto;
import io.github.jhipster.service.filter.*;
import org.hostsharing.hsadminng.domain.enumeration.CustomerKind;
import org.hostsharing.hsadminng.domain.enumeration.VatRegion;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import org.hostsharing.hsadminng.domain.enumeration.CustomerKind;
import org.hostsharing.hsadminng.domain.enumeration.VatRegion;
import io.github.jhipster.service.filter.BooleanFilter;
import io.github.jhipster.service.filter.DoubleFilter;
import io.github.jhipster.service.filter.Filter;
import io.github.jhipster.service.filter.FloatFilter;
import io.github.jhipster.service.filter.IntegerFilter;
import io.github.jhipster.service.filter.LongFilter;
import io.github.jhipster.service.filter.StringFilter;
import io.github.jhipster.service.filter.LocalDateFilter;
/** /**
* Criteria class for the Customer entity. This class is used in CustomerResource to * Criteria class for the Customer entity. This class is used in CustomerResource to

View File

@ -1,69 +1,98 @@
package org.hostsharing.hsadminng.service.dto; package org.hostsharing.hsadminng.service.dto;
import java.time.LocalDate;
import javax.validation.constraints.*; import com.fasterxml.jackson.core.JsonGenerator;
import java.io.Serializable; import com.fasterxml.jackson.core.JsonParser;
import java.util.Objects; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.hostsharing.hsadminng.domain.enumeration.CustomerKind; import org.hostsharing.hsadminng.domain.enumeration.CustomerKind;
import org.hostsharing.hsadminng.domain.enumeration.VatRegion; import org.hostsharing.hsadminng.domain.enumeration.VatRegion;
import org.hostsharing.hsadminng.service.CustomerService;
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;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Objects;
/** /**
* A DTO for the Customer entity. * A DTO for the Customer entity.
*/ */
public class CustomerDTO implements Serializable { public class CustomerDTO extends FluentBuilder<CustomerDTO> implements Serializable {
@SelfId(resolver = CustomerService.class)
@AccessFor(read = Role.ANY_CUSTOMER_USER)
private Long id; private Long id;
@NotNull @NotNull
@Min(value = 10000) @Min(value = 10000)
@Max(value = 99999) @Max(value = 99999)
@AccessFor(init = Role.ADMIN, read = Role.ANY_CUSTOMER_USER)
private Integer reference; private Integer reference;
@NotNull @NotNull
@Size(max = 3) @Size(max = 3)
@Pattern(regexp = "[a-z][a-z0-9]+") @Pattern(regexp = "[a-z][a-z0-9]+")
@AccessFor(init = Role.ADMIN, read = Role.ANY_CUSTOMER_USER)
private String prefix; private String prefix;
@NotNull @NotNull
@Size(max = 80) @Size(max = 80)
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.ANY_CUSTOMER_USER)
private String name; private String name;
@NotNull @NotNull
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.CONTRACTUAL_CONTACT)
private CustomerKind kind; private CustomerKind kind;
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate birthDate; private LocalDate birthDate;
@Size(max = 80) @Size(max = 80)
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private String birthPlace; private String birthPlace;
@Size(max = 80) @Size(max = 80)
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private String registrationCourt; private String registrationCourt;
@Size(max = 80) @Size(max = 80)
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private String registrationNumber; private String registrationNumber;
@NotNull @NotNull
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private VatRegion vatRegion; private VatRegion vatRegion;
@Size(max = 40) @Size(max = 40)
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private String vatNumber; private String vatNumber;
@Size(max = 80) @Size(max = 80)
@AccessFor(init = Role.ADMIN, update = Role.CONTRACTUAL_CONTACT, read = Role.CONTRACTUAL_CONTACT)
private String contractualSalutation; private String contractualSalutation;
@NotNull @NotNull
@Size(max = 400) @Size(max = 400)
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = Role.CONTRACTUAL_CONTACT)
private String contractualAddress; private String contractualAddress;
@Size(max = 80) @Size(max = 80)
@AccessFor(init = Role.ADMIN, update = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT}, read = Role.CONTRACTUAL_CONTACT)
private String billingSalutation; private String billingSalutation;
@Size(max = 400) @Size(max = 400)
@AccessFor(init = Role.ADMIN, update = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private String billingAddress; private String billingAddress;
@Size(max = 160) @Size(max = 160)
@AccessFor(init = Role.ADMIN, update = Role.SUPPORTER, read = Role.SUPPORTER)
private String remark; private String remark;
public Long getId() { public Long getId() {
return id; return id;
} }
@ -234,4 +263,39 @@ public class CustomerDTO implements Serializable {
", remark='" + getRemark() + "'" + ", remark='" + getRemark() + "'" +
"}"; "}";
} }
@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<>(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<>(ctx, jsonParser, deserializationContext, CustomerDTO.class).deserialize();
}
}
} }

View File

@ -0,0 +1,15 @@
package org.hostsharing.hsadminng.service.dto;
import java.util.function.Consumer;
public class FluentBuilder<T> {
@SuppressWarnings("unchecked")
public T with(
Consumer<T> builderFunction) {
builderFunction.accept((T) this);
return (T) this;
}
}

View File

@ -1,15 +1,12 @@
package org.hostsharing.hsadminng.service.dto; package org.hostsharing.hsadminng.service.dto;
import io.github.jhipster.service.filter.Filter;
import io.github.jhipster.service.filter.LocalDateFilter;
import io.github.jhipster.service.filter.LongFilter;
import io.github.jhipster.service.filter.StringFilter;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import io.github.jhipster.service.filter.BooleanFilter;
import io.github.jhipster.service.filter.DoubleFilter;
import io.github.jhipster.service.filter.Filter;
import io.github.jhipster.service.filter.FloatFilter;
import io.github.jhipster.service.filter.IntegerFilter;
import io.github.jhipster.service.filter.LongFilter;
import io.github.jhipster.service.filter.StringFilter;
import io.github.jhipster.service.filter.LocalDateFilter;
/** /**
* Criteria class for the Membership entity. This class is used in MembershipResource to * Criteria class for the Membership entity. This class is used in MembershipResource to

View File

@ -1,41 +1,52 @@
package org.hostsharing.hsadminng.service.dto; package org.hostsharing.hsadminng.service.dto;
import java.time.LocalDate;
import javax.validation.constraints.*; import org.hostsharing.hsadminng.service.CustomerService;
import org.hostsharing.hsadminng.service.MembershipService;
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.io.Serializable;
import java.time.LocalDate;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer;
/** /**
* A DTO for the Membership entity. * A DTO for the Membership entity.
*/ */
public class MembershipDTO implements Serializable { public class MembershipDTO extends FluentBuilder<MembershipDTO> implements Serializable {
@SelfId(resolver = MembershipService.class)
@AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private Long id; private Long id;
@NotNull @NotNull
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate admissionDocumentDate; private LocalDate admissionDocumentDate;
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate cancellationDocumentDate; private LocalDate cancellationDocumentDate;
@NotNull @NotNull
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate memberFromDate; private LocalDate memberFromDate;
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate memberUntilDate; private LocalDate memberUntilDate;
@Size(max = 160) @Size(max = 160)
@AccessFor(init = Role.ADMIN, read = Role.SUPPORTER)
private String remark; private String remark;
@ParentId(resolver = CustomerService.class)
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private Long customerId; private Long customerId;
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private String customerPrefix; private String customerPrefix;
public MembershipDTO with(
Consumer<MembershipDTO> builderFunction) {
builderFunction.accept(this);
return this;
}
public Long getId() { public Long getId() {
return id; return id;
} }

View File

@ -1,15 +1,12 @@
package org.hostsharing.hsadminng.service.dto; package org.hostsharing.hsadminng.service.dto;
import io.github.jhipster.service.filter.Filter;
import io.github.jhipster.service.filter.LocalDateFilter;
import io.github.jhipster.service.filter.LongFilter;
import io.github.jhipster.service.filter.StringFilter;
import java.io.Serializable; import java.io.Serializable;
import java.util.Objects; import java.util.Objects;
import io.github.jhipster.service.filter.BooleanFilter;
import io.github.jhipster.service.filter.DoubleFilter;
import io.github.jhipster.service.filter.Filter;
import io.github.jhipster.service.filter.FloatFilter;
import io.github.jhipster.service.filter.IntegerFilter;
import io.github.jhipster.service.filter.LongFilter;
import io.github.jhipster.service.filter.StringFilter;
import io.github.jhipster.service.filter.LocalDateFilter;
/** /**
* Criteria class for the SepaMandate entity. This class is used in SepaMandateResource to * Criteria class for the SepaMandate entity. This class is used in SepaMandateResource to

View File

@ -1,7 +1,9 @@
package org.hostsharing.hsadminng.service.dto; package org.hostsharing.hsadminng.service.dto;
import java.time.LocalDate;
import javax.validation.constraints.*; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDate;
import java.util.Objects; import java.util.Objects;
/** /**

View File

@ -1,36 +1,54 @@
package org.hostsharing.hsadminng.service.dto; 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.domain.enumeration.ShareAction;
import org.hostsharing.hsadminng.service.MembershipService;
import org.hostsharing.hsadminng.service.ShareService;
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. * A DTO for the Share entity.
*/ */
public class ShareDTO implements Serializable { public class ShareDTO implements Serializable {
@SelfId(resolver = ShareService.class)
@AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private Long id; private Long id;
@NotNull @NotNull
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate documentDate; private LocalDate documentDate;
@NotNull @NotNull
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private LocalDate valueDate; private LocalDate valueDate;
@NotNull @NotNull
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private ShareAction action; private ShareAction action;
@NotNull @NotNull
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private Integer quantity; private Integer quantity;
@Size(max = 160) @Size(max = 160)
@AccessFor(init = Role.ADMIN, read = Role.SUPPORTER)
private String remark; private String remark;
@ParentId(resolver = MembershipService.class)
@AccessFor(init = Role.ADMIN, read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private Long membershipId; private Long membershipId;
private String membershipAdmissionDocumentDate; @AccessFor(read = {Role.CONTRACTUAL_CONTACT, Role.FINANCIAL_CONTACT})
private String membershipDisplayReference;
public Long getId() { public Long getId() {
return id; return id;
@ -88,12 +106,12 @@ public class ShareDTO implements Serializable {
this.membershipId = membershipId; this.membershipId = membershipId;
} }
public String getMembershipAdmissionDocumentDate() { public String getMembershipDisplayReference() {
return membershipAdmissionDocumentDate; return membershipDisplayReference;
} }
public void setMembershipAdmissionDocumentDate(String membershipAdmissionDocumentDate) { public void setMembershipDisplayReference(String membershipDisplayReference) {
this.membershipAdmissionDocumentDate = membershipAdmissionDocumentDate; this.membershipDisplayReference = membershipDisplayReference;
} }
@Override @Override
@ -127,7 +145,7 @@ public class ShareDTO implements Serializable {
", quantity=" + getQuantity() + ", quantity=" + getQuantity() +
", remark='" + getRemark() + "'" + ", remark='" + getRemark() + "'" +
", membership=" + getMembershipId() + ", membership=" + getMembershipId() +
", membership='" + getMembershipAdmissionDocumentDate() + "'" + ", membership='" + getMembershipDisplayReference() + "'" +
"}"; "}";
} }
} }

View File

@ -1,9 +1,9 @@
package org.hostsharing.hsadminng.service.mapper; package org.hostsharing.hsadminng.service.mapper;
import org.hostsharing.hsadminng.domain.*; import org.hostsharing.hsadminng.domain.Asset;
import org.hostsharing.hsadminng.service.dto.AssetDTO; import org.hostsharing.hsadminng.service.dto.AssetDTO;
import org.mapstruct.Mapper;
import org.mapstruct.*; import org.mapstruct.Mapping;
/** /**
* Mapper for the entity Asset and its DTO AssetDTO. * Mapper for the entity Asset and its DTO AssetDTO.
@ -12,7 +12,7 @@ import org.mapstruct.*;
public interface AssetMapper extends EntityMapper<AssetDTO, Asset> { public interface AssetMapper extends EntityMapper<AssetDTO, Asset> {
@Mapping(source = "membership.id", target = "membershipId") @Mapping(source = "membership.id", target = "membershipId")
@Mapping(source = "membership.admissionDocumentDate", target = "membershipAdmissionDocumentDate") @Mapping(source = "membership.admissionDocumentDate", target = "membershipDisplayReference")
AssetDTO toDto(Asset asset); AssetDTO toDto(Asset asset);
@Mapping(source = "membershipId", target = "membership") @Mapping(source = "membershipId", target = "membership")

View File

@ -1,9 +1,9 @@
package org.hostsharing.hsadminng.service.mapper; package org.hostsharing.hsadminng.service.mapper;
import org.hostsharing.hsadminng.domain.*; import org.hostsharing.hsadminng.domain.Share;
import org.hostsharing.hsadminng.service.dto.ShareDTO; import org.hostsharing.hsadminng.service.dto.ShareDTO;
import org.mapstruct.Mapper;
import org.mapstruct.*; import org.mapstruct.Mapping;
/** /**
* Mapper for the entity Share and its DTO ShareDTO. * Mapper for the entity Share and its DTO ShareDTO.
@ -12,7 +12,7 @@ import org.mapstruct.*;
public interface ShareMapper extends EntityMapper<ShareDTO, Share> { public interface ShareMapper extends EntityMapper<ShareDTO, Share> {
@Mapping(source = "membership.id", target = "membershipId") @Mapping(source = "membership.id", target = "membershipId")
@Mapping(source = "membership.admissionDocumentDate", target = "membershipAdmissionDocumentDate") @Mapping(source = "membership.admissionDocumentDate", target = "membershipDisplayReference")
ShareDTO toDto(Share share); ShareDTO toDto(Share share);
@Mapping(source = "membershipId", target = "membership") @Mapping(source = "membershipId", target = "membership")

View File

@ -0,0 +1,47 @@
package org.hostsharing.hsadminng.service.util;
import java.lang.reflect.Field;
public class ReflectionUtil {
public static <T> void setValue(final T dto, final String fieldName, final Object value) {
try {
final Field field = dto.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(dto, value);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public static <T> void setValue(final T dto, final Field field, final Object value) {
try {
field.setAccessible(true);
field.set(dto, value);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public static <T> T getValue(final T dto, final Field field) {
try {
field.setAccessible(true);
return (T) field.get(dto);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
@FunctionalInterface
public interface ThrowingSupplier<T> {
T get() throws Exception;
}
public static <T> T unchecked(final ThrowingSupplier<T> supplier) {
try {
return supplier.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -1,25 +1,24 @@
package org.hostsharing.hsadminng.web.rest; package org.hostsharing.hsadminng.web.rest;
import io.github.jhipster.web.util.ResponseUtil;
import org.hostsharing.hsadminng.service.AssetQueryService;
import org.hostsharing.hsadminng.service.AssetService; import org.hostsharing.hsadminng.service.AssetService;
import org.hostsharing.hsadminng.service.dto.AssetCriteria;
import org.hostsharing.hsadminng.service.dto.AssetDTO;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.hostsharing.hsadminng.web.rest.util.HeaderUtil; import org.hostsharing.hsadminng.web.rest.util.HeaderUtil;
import org.hostsharing.hsadminng.web.rest.util.PaginationUtil; import org.hostsharing.hsadminng.web.rest.util.PaginationUtil;
import org.hostsharing.hsadminng.service.dto.AssetDTO;
import org.hostsharing.hsadminng.service.dto.AssetCriteria;
import org.hostsharing.hsadminng.service.AssetQueryService;
import io.github.jhipster.web.util.ResponseUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;

View File

@ -1,25 +1,24 @@
package org.hostsharing.hsadminng.web.rest; package org.hostsharing.hsadminng.web.rest;
import io.github.jhipster.web.util.ResponseUtil;
import org.hostsharing.hsadminng.service.CustomerQueryService;
import org.hostsharing.hsadminng.service.CustomerService; import org.hostsharing.hsadminng.service.CustomerService;
import org.hostsharing.hsadminng.service.dto.CustomerCriteria;
import org.hostsharing.hsadminng.service.dto.CustomerDTO;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.hostsharing.hsadminng.web.rest.util.HeaderUtil; import org.hostsharing.hsadminng.web.rest.util.HeaderUtil;
import org.hostsharing.hsadminng.web.rest.util.PaginationUtil; import org.hostsharing.hsadminng.web.rest.util.PaginationUtil;
import org.hostsharing.hsadminng.service.dto.CustomerDTO;
import org.hostsharing.hsadminng.service.dto.CustomerCriteria;
import org.hostsharing.hsadminng.service.CustomerQueryService;
import io.github.jhipster.web.util.ResponseUtil;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -72,7 +71,7 @@ public class CustomerResource {
* @throws URISyntaxException if the Location URI syntax is incorrect * @throws URISyntaxException if the Location URI syntax is incorrect
*/ */
@PutMapping("/customers") @PutMapping("/customers")
public ResponseEntity<CustomerDTO> updateCustomer(@Valid @RequestBody CustomerDTO customerDTO) throws URISyntaxException { public ResponseEntity<CustomerDTO> updateCustomer(@RequestBody CustomerDTO customerDTO) {
log.debug("REST request to update Customer : {}", customerDTO); log.debug("REST request to update Customer : {}", customerDTO);
if (customerDTO.getId() == null) { if (customerDTO.getId() == null) {
throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");

View File

@ -11,32 +11,32 @@ public class BadRequestAlertException extends AbstractThrowableProblem {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final String entityName; private final String param;
private final String errorKey; private final String errorKey;
public BadRequestAlertException(String defaultMessage, String entityName, String errorKey) { public BadRequestAlertException(String defaultMessage, String param, String errorKey) {
this(ErrorConstants.DEFAULT_TYPE, defaultMessage, entityName, errorKey); this(ErrorConstants.DEFAULT_TYPE, defaultMessage, param, errorKey);
} }
public BadRequestAlertException(URI type, String defaultMessage, String entityName, String errorKey) { public BadRequestAlertException(URI type, String defaultMessage, String param, String errorKey) {
super(type, defaultMessage, Status.BAD_REQUEST, null, null, null, getAlertParameters(entityName, errorKey)); super(type, defaultMessage, Status.BAD_REQUEST, null, null, null, getAlertParameters(param, errorKey));
this.entityName = entityName; this.param = param;
this.errorKey = errorKey; this.errorKey = errorKey;
} }
public String getEntityName() { public String getParam() {
return entityName; return param;
} }
public String getErrorKey() { public String getErrorKey() {
return errorKey; return errorKey;
} }
private static Map<String, Object> getAlertParameters(String entityName, String errorKey) { private static Map<String, Object> getAlertParameters(String param, String errorKey) {
Map<String, Object> parameters = new HashMap<>(); Map<String, Object> parameters = new HashMap<>();
parameters.put("message", "error." + errorKey); parameters.put("message", "error." + errorKey);
parameters.put("params", entityName); parameters.put("params", param);
return parameters; return parameters;
} }
} }

View File

@ -104,7 +104,7 @@ public class ExceptionTranslator implements ProblemHandling {
@ExceptionHandler @ExceptionHandler
public ResponseEntity<Problem> handleBadRequestAlertException(BadRequestAlertException ex, NativeWebRequest request) { public ResponseEntity<Problem> handleBadRequestAlertException(BadRequestAlertException ex, NativeWebRequest request) {
return create(ex, request, HeaderUtil.createFailureAlert(ex.getEntityName(), ex.getErrorKey(), ex.getMessage())); return create(ex, request, HeaderUtil.createFailureAlert(ex.getParam(), ex.getErrorKey(), ex.getMessage()));
} }
@ExceptionHandler @ExceptionHandler

View File

@ -1,5 +1,5 @@
#H2 Server Properties #H2 Server Properties
#Wed Apr 03 13:36:25 CEST 2019 #Thu Apr 25 12:42:42 CEST 2019
0=JHipster H2 (Memory)|org.h2.Driver|jdbc\:h2\:mem\:hsadminng|hsadminNg 0=JHipster H2 (Memory)|org.h2.Driver|jdbc\:h2\:mem\:hsadminng|hsadminNg
webAllowOthers=true webAllowOthers=true
webPort=8082 webPort=8082

View File

@ -1,3 +1,5 @@
name name
ROLE_HOSTMASTER
ROLE_ADMIN ROLE_ADMIN
ROLE_SUPPORTER
ROLE_USER ROLE_USER

1 name
2 ROLE_HOSTMASTER
3 ROLE_ADMIN
4 ROLE_SUPPORTER
5 ROLE_USER

View File

@ -1,10 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog <databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<property name="now" value="now()" dbms="h2"/> <property name="now" value="now()" dbms="h2"/>

View File

@ -1,10 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog <databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<property name="now" value="now()" dbms="h2"/> <property name="now" value="now()" dbms="h2"/>

View File

@ -1,10 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog <databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<property name="now" value="now()" dbms="h2"/> <property name="now" value="now()" dbms="h2"/>

View File

@ -1,10 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog <databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<property name="now" value="now()" dbms="h2"/> <property name="now" value="now()" dbms="h2"/>

View File

@ -1,10 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog <databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd">
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<property name="now" value="now()" dbms="h2"/> <property name="now" value="now()" dbms="h2"/>

View File

@ -1,4 +1,5 @@
user_id;authority_name user_id;authority_name
1;ROLE_HOSTMASTER
1;ROLE_ADMIN 1;ROLE_ADMIN
1;ROLE_USER 1;ROLE_USER
3;ROLE_ADMIN 3;ROLE_ADMIN

1 user_id authority_name
2 1 ROLE_HOSTMASTER
3 1 ROLE_ADMIN
4 1 ROLE_USER
5 3 ROLE_ADMIN

View File

@ -28,7 +28,7 @@
<dt><span jhiTranslate="hsadminNgApp.asset.membership">Membership</span></dt> <dt><span jhiTranslate="hsadminNgApp.asset.membership">Membership</span></dt>
<dd> <dd>
<div *ngIf="asset.membershipId"> <div *ngIf="asset.membershipId">
<a [routerLink]="['/membership', asset.membershipId, 'view']">{{asset.membershipAdmissionDocumentDate}}</a> <a [routerLink]="['/membership', asset.membershipId, 'view']">{{asset.membershipDisplayReference}}</a>
</div> </div>
</dd> </dd>
</dl> </dl>

View File

@ -20,7 +20,7 @@
<th jhiSortBy="action"><span jhiTranslate="hsadminNgApp.asset.action">Action</span> <fa-icon [icon]="'sort'"></fa-icon></th> <th jhiSortBy="action"><span jhiTranslate="hsadminNgApp.asset.action">Action</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="amount"><span jhiTranslate="hsadminNgApp.asset.amount">Amount</span> <fa-icon [icon]="'sort'"></fa-icon></th> <th jhiSortBy="amount"><span jhiTranslate="hsadminNgApp.asset.amount">Amount</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="remark"><span jhiTranslate="hsadminNgApp.asset.remark">Remark</span> <fa-icon [icon]="'sort'"></fa-icon></th> <th jhiSortBy="remark"><span jhiTranslate="hsadminNgApp.asset.remark">Remark</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="membershipAdmissionDocumentDate"><span jhiTranslate="hsadminNgApp.asset.membership">Membership</span> <fa-icon [icon]="'sort'"></fa-icon></th> <th jhiSortBy="membershipDisplayReference"><span jhiTranslate="hsadminNgApp.asset.membership">Membership</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@ -34,7 +34,7 @@
<td>{{asset.remark}}</td> <td>{{asset.remark}}</td>
<td> <td>
<div *ngIf="asset.membershipId"> <div *ngIf="asset.membershipId">
<a [routerLink]="['../membership', asset.membershipId , 'view' ]" >{{asset.membershipAdmissionDocumentDate}}</a> <a [routerLink]="['../membership', asset.membershipId , 'view' ]" >{{asset.membershipDisplayReference}}</a>
</div> </div>
</td> </td>
<td class="text-right"> <td class="text-right">

View File

@ -1,9 +1,7 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import * as moment from 'moment';
import { ICustomer } from 'app/shared/model/customer.model'; import { ICustomer } from 'app/shared/model/customer.model';
import { CustomerService } from './customer.service'; import { CustomerService } from './customer.service';

View File

@ -1,8 +1,7 @@
import { Component, OnInit, OnDestroy } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { HttpErrorResponse, HttpHeaders, HttpResponse } from '@angular/common/http'; import { HttpErrorResponse, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { filter, map } from 'rxjs/operators'; import { JhiAlertService, JhiEventManager, JhiParseLinks } from 'ng-jhipster';
import { JhiEventManager, JhiParseLinks, JhiAlertService } from 'ng-jhipster';
import { ICustomer } from 'app/shared/model/customer.model'; import { ICustomer } from 'app/shared/model/customer.model';
import { AccountService } from 'app/core'; import { AccountService } from 'app/core';

View File

@ -1,9 +1,8 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { filter, map } from 'rxjs/operators'; import { filter, map } from 'rxjs/operators';
import * as moment from 'moment';
import { JhiAlertService } from 'ng-jhipster'; import { JhiAlertService } from 'ng-jhipster';
import { IMembership } from 'app/shared/model/membership.model'; import { IMembership } from 'app/shared/model/membership.model';
import { MembershipService } from './membership.service'; import { MembershipService } from './membership.service';

View File

@ -1,9 +1,8 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { HttpResponse, HttpErrorResponse } from '@angular/common/http'; import { HttpErrorResponse, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { filter, map } from 'rxjs/operators'; import { filter, map } from 'rxjs/operators';
import * as moment from 'moment';
import { JhiAlertService } from 'ng-jhipster'; import { JhiAlertService } from 'ng-jhipster';
import { ISepaMandate } from 'app/shared/model/sepa-mandate.model'; import { ISepaMandate } from 'app/shared/model/sepa-mandate.model';
import { SepaMandateService } from './sepa-mandate.service'; import { SepaMandateService } from './sepa-mandate.service';

View File

@ -28,7 +28,7 @@
<dt><span jhiTranslate="hsadminNgApp.share.membership">Membership</span></dt> <dt><span jhiTranslate="hsadminNgApp.share.membership">Membership</span></dt>
<dd> <dd>
<div *ngIf="share.membershipId"> <div *ngIf="share.membershipId">
<a [routerLink]="['/membership', share.membershipId, 'view']">{{share.membershipAdmissionDocumentDate}}</a> <a [routerLink]="['/membership', share.membershipId, 'view']">{{share.membershipDisplayReference}}</a>
</div> </div>
</dd> </dd>
</dl> </dl>

View File

@ -20,7 +20,7 @@
<th jhiSortBy="action"><span jhiTranslate="hsadminNgApp.share.action">Action</span> <fa-icon [icon]="'sort'"></fa-icon></th> <th jhiSortBy="action"><span jhiTranslate="hsadminNgApp.share.action">Action</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="quantity"><span jhiTranslate="hsadminNgApp.share.quantity">Quantity</span> <fa-icon [icon]="'sort'"></fa-icon></th> <th jhiSortBy="quantity"><span jhiTranslate="hsadminNgApp.share.quantity">Quantity</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="remark"><span jhiTranslate="hsadminNgApp.share.remark">Remark</span> <fa-icon [icon]="'sort'"></fa-icon></th> <th jhiSortBy="remark"><span jhiTranslate="hsadminNgApp.share.remark">Remark</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th jhiSortBy="membershipAdmissionDocumentDate"><span jhiTranslate="hsadminNgApp.share.membership">Membership</span> <fa-icon [icon]="'sort'"></fa-icon></th> <th jhiSortBy="membershipDisplayReference"><span jhiTranslate="hsadminNgApp.share.membership">Membership</span> <fa-icon [icon]="'sort'"></fa-icon></th>
<th></th> <th></th>
</tr> </tr>
</thead> </thead>
@ -34,7 +34,7 @@
<td>{{share.remark}}</td> <td>{{share.remark}}</td>
<td> <td>
<div *ngIf="share.membershipId"> <div *ngIf="share.membershipId">
<a [routerLink]="['../membership', share.membershipId , 'view' ]" >{{share.membershipAdmissionDocumentDate}}</a> <a [routerLink]="['../membership', share.membershipId , 'view' ]" >{{share.membershipDisplayReference}}</a>
</div> </div>
</td> </td>
<td class="text-right"> <td class="text-right">

View File

@ -16,7 +16,7 @@ export interface IAsset {
action?: AssetAction; action?: AssetAction;
amount?: number; amount?: number;
remark?: string; remark?: string;
membershipAdmissionDocumentDate?: string; membershipDisplayReference?: string;
membershipId?: number; membershipId?: number;
} }
@ -28,7 +28,7 @@ export class Asset implements IAsset {
public action?: AssetAction, public action?: AssetAction,
public amount?: number, public amount?: number,
public remark?: string, public remark?: string,
public membershipAdmissionDocumentDate?: string, public membershipDisplayReference?: string,
public membershipId?: number public membershipId?: number
) {} ) {}
} }

View File

@ -12,7 +12,7 @@ export interface IShare {
action?: ShareAction; action?: ShareAction;
quantity?: number; quantity?: number;
remark?: string; remark?: string;
membershipAdmissionDocumentDate?: string; membershipDisplayReference?: string;
membershipId?: number; membershipId?: number;
} }
@ -24,7 +24,7 @@ export class Share implements IShare {
public action?: ShareAction, public action?: ShareAction,
public quantity?: number, public quantity?: number,
public remark?: string, public remark?: string,
public membershipAdmissionDocumentDate?: string, public membershipDisplayReference?: string,
public membershipId?: number public membershipId?: number
) {} ) {}
} }

View File

@ -1,13 +1,16 @@
{ {
"error": { "error": {
"idNotFound": "Technische Datensatz-ID nicht gefunden",
"shareSubscriptionPositiveQuantity": "Zeichnungen von Geschäftsanteilen erfordern eine positive Stückzahl", "shareSubscriptionPositiveQuantity": "Zeichnungen von Geschäftsanteilen erfordern eine positive Stückzahl",
"shareCancellationNegativeQuantity": "Kündigungen von Geschäftsanteilen erfordern eine negative Stückzahl", "shareCancellationNegativeQuantity": "Kündigungen von Geschäftsanteilen erfordern eine negative Stückzahl",
"shareTransactionImmutable": "Transaktionen mit Geschäftsanteilen sind unveränderlich", "shareTransactionImmutable": "Transaktionen mit Geschäftsanteilen sind unveränderlich",
"membershipNotDeletable": "Mitgliedschaft kann nicht gelöscht werden, setze stattdessen das 'untilDate'", "membershipNotDeletable": "Mitgliedschaft kann nicht gelöscht werden, setze stattdessen das 'untilDate'",
"untilDateMustBeAfterSinceDate": "Mitgliedshaftsaustrittsdatum muss nach dem Beitrittsdatum liegen", "untilDateMustBeAfterSinceDate": "Mitgliedshafts-Austrittsdatum muss nach dem Beitrittsdatum liegen",
"anotherUncancelledMembershipExists": "Nur eine einzige ungekündigte Mitgliedschaft pro Kunde ist zulässig",
"initializationProhibited": "Initialisierung des Feldes unzulässig",
"updateProhibited": "Aktualisierung des Feldes unzulässig",
"documentDateMayNotBeAfterValueDate": "Belegdatum darf nicht vor dem Buchungsdatum liegen", "documentDateMayNotBeAfterValueDate": "Belegdatum darf nicht vor dem Buchungsdatum liegen",
"assetTransactionImmutable": "Transaktionen mit Geschäftsguthaben sind unveränderlich", "assetTransactionImmutable": "Transaktionen mit Geschäftsguthaben sind unveränderlich",
"anotherUncancelledMembershipExists": "Nur eine einzige ungekündigte Mitgliedschaft pro Kunde ist zulässig",
"assetPaymentsPositiveAmount": "Einzahlungen von Geschäftsguthaben erfordern einen positiven Betrag", "assetPaymentsPositiveAmount": "Einzahlungen von Geschäftsguthaben erfordern einen positiven Betrag",
"assetAdoptionsPositiveAmount": "Übernahmen von Geschäftsguthaben erfordern einen positiven Betrag", "assetAdoptionsPositiveAmount": "Übernahmen von Geschäftsguthaben erfordern einen positiven Betrag",
"assetPaybacksNegativeAmount": "Auszahlungen von Geschäftsguthaben erfordern einen negativen Betrag", "assetPaybacksNegativeAmount": "Auszahlungen von Geschäftsguthaben erfordern einen negativen Betrag",

View File

@ -1,12 +1,15 @@
{ {
"error": { "error": {
"idNotFound": "Technical record-ID not found",
"shareSubscriptionPositiveQuantity": "Share subscriptions require a positive quantity", "shareSubscriptionPositiveQuantity": "Share subscriptions require a positive quantity",
"shareCancellationNegativeQuantity": "Share cancellations require a negative quantity", "shareCancellationNegativeQuantity": "Share cancellations require a negative quantity",
"shareTransactionImmutable": "Share transactions are immutable", "shareTransactionImmutable": "Share transactions are immutable",
"membershipNotDeletable": "Membership cannot be deleted, instead set 'untilDate'", "membershipNotDeletable": "Membership cannot be deleted, instead set 'untilDate'",
"untilDateMustBeAfterSinceDate": "Membership until date must be after since date", "untilDateMustBeAfterSinceDate": "Membership until date must be after since date",
"documentDateMayNotBeAfterValueDate": "Document date may not be after value date",
"anotherUncancelledMembershipExists": "Only a single uncancelled membership allowed per customer", "anotherUncancelledMembershipExists": "Only a single uncancelled membership allowed per customer",
"initializationProhibited": "Initialization of the field prohibited",
"updateProhibited": "Update of the field prohibited",
"documentDateMayNotBeAfterValueDate": "Document date may not be after value date",
"assetTransactionImmutable": "Asset transactions are immutable", "assetTransactionImmutable": "Asset transactions are immutable",
"assetPaymentsPositiveAmount": "Asset payments require a positive amount", "assetPaymentsPositiveAmount": "Asset payments require a positive amount",
"assetAdoptionsPositiveAmount": "Asset adoptions require a positive amount", "assetAdoptionsPositiveAmount": "Asset adoptions require a positive amount",

View File

@ -3,7 +3,6 @@ package org.hostsharing.hsadminng.service;
import org.apache.commons.lang3.RandomUtils; import org.apache.commons.lang3.RandomUtils;
import org.assertj.core.api.AbstractThrowableAssert; import org.assertj.core.api.AbstractThrowableAssert;
import org.hostsharing.hsadminng.domain.enumeration.ShareAction; import org.hostsharing.hsadminng.domain.enumeration.ShareAction;
import org.hostsharing.hsadminng.service.dto.AssetDTO;
import org.hostsharing.hsadminng.service.dto.ShareDTO; import org.hostsharing.hsadminng.service.dto.ShareDTO;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException; import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.junit.Test; import org.junit.Test;

View File

@ -0,0 +1,27 @@
package org.hostsharing.hsadminng.service.accessfilter;
import org.apache.commons.lang3.tuple.ImmutablePair;
public class JSonBuilder {
@SafeVarargs
public static String asJSon(final ImmutablePair<String, Object>... properties) {
final StringBuilder json = new StringBuilder();
for (ImmutablePair<String, Object> prop : properties) {
json.append(inQuotes(prop.left));
json.append(": ");
if (prop.right instanceof Number) {
json.append(prop.right);
} else {
json.append(inQuotes(prop.right));
}
json.append(",\n");
}
return "{\n" + json.substring(0, json.length() - 2) + "\n}";
}
private static String inQuotes(Object value) {
return value != null ? "\"" + value.toString() + "\"" : "null";
}
}

View File

@ -0,0 +1,315 @@
package org.hostsharing.hsadminng.service.accessfilter;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.hostsharing.hsadminng.service.IdToDtoResolver;
import org.hostsharing.hsadminng.service.dto.FluentBuilder;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import java.io.IOException;
import java.util.Optional;
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;
@SuppressWarnings("ALL")
public class JSonDeserializerWithAccessFilterUnitTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private ApplicationContext ctx;
@Mock
private AutowireCapableBeanFactory autowireCapableBeanFactory;
@Mock
private JsonParser jsonParser;
@Mock
private ObjectCodec codec;
@Mock
private TreeNode treeNode;
@Mock
private GivenService givenService;
@Mock
private GivenChildService givenChildService;
@Before
public void init() {
givenAuthenticatedUser();
givenUserHavingRole(GivenDto.class, 1234L, Role.ACTUAL_CUSTOMER_USER);
given (ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory);
given(autowireCapableBeanFactory.createBean(GivenService.class)).willReturn(givenService);
given(givenService.findOne(1234L)).willReturn(Optional.of(new GivenDto()
.with(dto -> dto.id = 1234L)
.with(dto -> dto.openIntegerField = 1)
.with(dto -> dto.openLongField = 2L)
.with(dto -> dto.openStringField = "3")
.with(dto -> dto.restrictedField = "initial value of restricted field")
));
given(jsonParser.getCodec()).willReturn(codec);
}
@Test
public void shouldDeserializeNullField() throws IOException {
// given
givenJSonTree(asJSon(
ImmutablePair.of("id", 1234L),
ImmutablePair.of("openStringField", null)));
// when
GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize();
// then
assertThat(actualDto.openStringField).isNull();
}
@Test
public void shouldDeserializeStringField() throws IOException {
// given
givenJSonTree(asJSon(
ImmutablePair.of("id", 1234L),
ImmutablePair.of("openStringField", "String Value")));
// when
GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize();
// then
assertThat(actualDto.openStringField).isEqualTo("String Value");
}
@Test
public void shouldDeserializeIntegerField() throws IOException {
// given
givenJSonTree(asJSon(
ImmutablePair.of("id", 1234L),
ImmutablePair.of("openIntegerField", 1234)));
// when
GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize();
// then
assertThat(actualDto.openIntegerField).isEqualTo(1234);
}
@Test
public void shouldDeserializeLongField() throws IOException {
// given
givenJSonTree(asJSon(
ImmutablePair.of("id", 1234L),
ImmutablePair.of("openLongField", 1234L)));
// when
GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize();
// then
assertThat(actualDto.openLongField).isEqualTo(1234L);
}
@Test
public void shouldDeserializeStringFieldIfRequiredRoleIsCoveredByUser() throws IOException {
// given
givenAuthenticatedUser();
givenUserHavingRole(GivenDto.class, 1234L, Role.FINANCIAL_CONTACT);
givenJSonTree(asJSon(
ImmutablePair.of("id", 1234L),
ImmutablePair.of("restrictedField", "update value of restricted field")));
// when
GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize();
// then
assertThat(actualDto.restrictedField).isEqualTo("update value of restricted field");
}
@Test
public void shouldDeserializeUnchangedStringFieldIfRequiredRoleIsNotCoveredByUser() throws IOException {
// given
givenAuthenticatedUser();
givenUserHavingRole(GivenDto.class, 1234L, Role.ANY_CUSTOMER_USER);
givenJSonTree(asJSon(
ImmutablePair.of("id", 1234L),
ImmutablePair.of("restrictedField", "initial value of restricted field")));
// when
GivenDto actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize();
// then
assertThat(actualDto.restrictedField).isEqualTo("initial value of restricted field");
}
@Test
public void shouldNotDeserializeUpatedStringFieldIfRequiredRoleIsNotCoveredByUser() throws IOException {
// given
givenAuthenticatedUser();
givenUserHavingRole(GivenDto.class, 1L, Role.ANY_CUSTOMER_USER);
givenJSonTree(asJSon(ImmutablePair.of("restrictedField", "updated value of restricted field")));
// when
Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize());
// then
assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> {
assertThat(badRequestAlertException.getParam()).isEqualTo("GivenDto.restrictedField");
assertThat(badRequestAlertException.getErrorKey()).isEqualTo("initializationProhibited");
});
}
@Test
public void shouldInitializeFieldIfRequiredRoleIsNotCoveredByUser() throws IOException {
// given
givenAuthenticatedUser();
givenUserHavingRole(GivenDto.class, 1L, Role.ANY_CUSTOMER_USER);
givenJSonTree(asJSon(ImmutablePair.of("restrictedField", "another value of restricted field")));
// when
Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize());
// then
assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> {
assertThat(badRequestAlertException.getParam()).isEqualTo("GivenDto.restrictedField");
assertThat(badRequestAlertException.getErrorKey()).isEqualTo("initializationProhibited");
});
}
@Test
public void shouldNotCreateIfRoleRequiredByParentEntityIsNotCoveredByUser() throws IOException {
// given
givenAuthenticatedUser();
givenUserHavingRole(GivenDto.class, 9999L, Role.CONTRACTUAL_CONTACT);
givenJSonTree(asJSon(ImmutablePair.of("parentId", 1234L)));
// when
Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenChildDto.class).deserialize());
// then
assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> {
assertThat(badRequestAlertException.getParam()).isEqualTo("GivenChildDto.parentId");
assertThat(badRequestAlertException.getErrorKey()).isEqualTo("referencingProhibited");
});
}
@Test
public void shouldCreateIfRoleRequiredByReferencedEntityIsCoveredByUser() throws IOException {
// given
givenAuthenticatedUser();
givenUserHavingRole(GivenDto.class, 1234L, Role.CONTRACTUAL_CONTACT);
givenJSonTree(asJSon(ImmutablePair.of("parentId", 1234L)));
// when
final GivenChildDto actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenChildDto.class).deserialize();
// then
assertThat(actualDto.parentId).isEqualTo(1234L);
}
@Test
public void shouldNotUpdateFieldIfRequiredRoleIsNotCoveredByUser() throws IOException {
// given
givenAuthenticatedUser();
givenUserHavingRole(GivenDto.class, 1234L, Role.ANY_CUSTOMER_USER);
givenJSonTree(asJSon(
ImmutablePair.of("id", 1234L),
ImmutablePair.of("restrictedField", "Restricted String Value")));
// when
Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDto.class).deserialize());
// then
assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> {
assertThat(badRequestAlertException.getParam()).isEqualTo("GivenDto.restrictedField");
assertThat(badRequestAlertException.getErrorKey()).isEqualTo("updateProhibited");
});
}
@Test
public void shouldDetectMultipleSelfIdFields() throws IOException {
// given
givenJSonTree(asJSon(ImmutablePair.of("id", 1111L)));
// when
Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, GivenDtoWithMultipleSelfId.class).deserialize());
// then
assertThat(exception).isInstanceOf(AssertionError.class).hasMessage("multiple @SelfId detected in GivenDtoWithMultipleSelfId");
}
// --- only fixture code below ---
private void givenJSonTree(String givenJSon) throws IOException {
given(codec.readTree(jsonParser)).willReturn(new ObjectMapper().readTree(givenJSon));
}
abstract class GivenService implements IdToDtoResolver<GivenDto> {
}
public static class GivenDto extends FluentBuilder<GivenDto> {
@SelfId(resolver = GivenService.class)
@AccessFor(read = Role.ANY_CUSTOMER_USER)
Long id;
@AccessFor(init = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT}, update = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT})
String restrictedField;
@AccessFor(init = Role.ANYBODY, update = Role.ANYBODY)
String openStringField;
@AccessFor(init = Role.ANYBODY, update = Role.ANYBODY)
Integer openIntegerField;
@AccessFor(init = Role.ANYBODY, update = Role.ANYBODY)
Long openLongField;
}
abstract class GivenChildService implements IdToDtoResolver<GivenChildDto> {
}
public static class GivenChildDto extends FluentBuilder<GivenChildDto> {
@SelfId(resolver = GivenChildService.class)
@AccessFor(read = Role.ANY_CUSTOMER_USER)
Long id;
@AccessFor(init = Role.CONTRACTUAL_CONTACT, update = Role.CONTRACTUAL_CONTACT, read = Role.ACTUAL_CUSTOMER_USER)
@ParentId(resolver = GivenService.class)
Long parentId;
@AccessFor(init = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT}, update = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT})
String restrictedField;
}
public static class GivenDtoWithMultipleSelfId {
@SelfId(resolver = GivenChildService.class)
@AccessFor(read = Role.ANY_CUSTOMER_USER)
Long id;
@SelfId(resolver = GivenChildService.class)
@AccessFor(read = Role.ANY_CUSTOMER_USER)
Long id2;
}
}

View File

@ -0,0 +1,162 @@
package org.hostsharing.hsadminng.service.accessfilter;
import com.fasterxml.jackson.core.JsonGenerator;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.hostsharing.hsadminng.service.IdToDtoResolver;
import org.hostsharing.hsadminng.service.dto.FluentBuilder;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import java.io.IOException;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
public class JSonSerializerWithAccessFilterUnitTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private ApplicationContext ctx;
@Mock
private AutowireCapableBeanFactory autowireCapableBeanFactory;
@Mock
private JsonGenerator jsonGenerator;
@Mock
private GivenCustomerService givenCustomerService;
private final GivenDto givenDTO = createSampleDto();
@Before
public void init() {
MockSecurityContext.givenAuthenticatedUser();
MockSecurityContext.givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ANY_CUSTOMER_USER);
given(ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory);
given(autowireCapableBeanFactory.createBean(GivenCustomerService.class)).willReturn(givenCustomerService);
given(givenCustomerService.findOne(888L)).willReturn(Optional.of(new GivenCustomerDto()
.with(dto -> dto.id = 888L)
));
}
@Test
public void shouldSerializeStringField() throws IOException {
// when
new JSonSerializerWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize();
// then
verify(jsonGenerator).writeStringField("openStringField", givenDTO.openStringField);
}
@Test
public void shouldSerializeRestrictedFieldIfRequiredRoleIsCoveredByUser() throws IOException {
// given
MockSecurityContext.givenAuthenticatedUser();
MockSecurityContext.givenUserHavingRole(GivenCustomerDto.class, 888L, Role.FINANCIAL_CONTACT);
// when
new JSonSerializerWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize();
// then
verify(jsonGenerator).writeStringField("restrictedField", givenDTO.restrictedField);
}
@Test
public void shouldNotSerializeRestrictedFieldIfRequiredRoleIsNotCoveredByUser() throws IOException {
// given
MockSecurityContext.givenAuthenticatedUser();
MockSecurityContext.givenUserHavingRole(GivenCustomerDto.class, 888L, Role.ANY_CUSTOMER_USER);
// when
new JSonSerializerWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize();
// then
verify(jsonGenerator, never()).writeStringField("restrictedField", givenDTO.restrictedField);
}
@Test
public void shouldThrowExceptionForUnimplementedFieldType() {
// given
class Arbitrary {
}
class GivenDtoWithUnimplementedFieldType {
@AccessFor(read = Role.ANYBODY)
Arbitrary fieldWithUnimplementedType = new Arbitrary();
}
final GivenDtoWithUnimplementedFieldType givenDtoWithUnimplementedFieldType = new GivenDtoWithUnimplementedFieldType();
// when
final Throwable actual = catchThrowable(() -> new JSonSerializerWithAccessFilter<>(ctx, jsonGenerator, null, givenDtoWithUnimplementedFieldType).serialize());
// then
assertThat(actual).isInstanceOf(NotImplementedException.class);
}
// --- fixture code below ---
private GivenDto createSampleDto() {
final GivenDto dto = new GivenDto();
dto.customerId = 888L;
dto.restrictedField = RandomStringUtils.randomAlphabetic(10);
dto.openStringField = RandomStringUtils.randomAlphabetic(10);
dto.openIntegerField = RandomUtils.nextInt();
dto.openLongField = RandomUtils.nextLong();
return dto;
}
private static class GivenCustomerDto extends FluentBuilder<GivenCustomerDto> {
@SelfId(resolver = GivenService.class)
@AccessFor(read = Role.ANYBODY)
Long id;
}
private abstract class GivenCustomerService implements IdToDtoResolver<GivenCustomerDto> {
}
private static class GivenDto {
@SelfId(resolver = GivenService.class)
@AccessFor(read = Role.ANYBODY)
Long id;
@ParentId(resolver = GivenCustomerService.class)
@AccessFor(read = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT})
Long customerId;
@AccessFor(read = {Role.TECHNICAL_CONTACT, Role.FINANCIAL_CONTACT})
String restrictedField;
@AccessFor(read = Role.ANYBODY)
String openStringField;
@AccessFor(read = Role.ANYBODY)
Integer openIntegerField;
@AccessFor(read = Role.ANYBODY)
Long openLongField;
}
private abstract class GivenService implements IdToDtoResolver<GivenService> {
}
}

View File

@ -0,0 +1,32 @@
package org.hostsharing.hsadminng.service.accessfilter;
import org.hostsharing.hsadminng.security.SecurityUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import static org.assertj.core.api.Assertions.assertThat;
public class MockSecurityContext {
public static void givenAuthenticatedUser() {
SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
securityContext.setAuthentication(new UsernamePasswordAuthenticationToken("dummyUser", "dummyPassword"));
SecurityContextHolder.setContext(securityContext);
SecurityUtils.clearUserRoles();
assertThat(SecurityUtils.getCurrentUserLogin()).describedAs("precondition failed").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 roles like " + role + " missing DtoClass and ID");
}
SecurityUtils.addUserRole(onClass, onId, role);
}
public static void givenUserHavingRole(final Role role) {
givenUserHavingRole(null, null, role);
}
}

View File

@ -0,0 +1,83 @@
package org.hostsharing.hsadminng.service.accessfilter;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class RoleUnitTest {
@Test
public void allUserRolesShouldCoverSameRequiredRole() {
assertThat(Role.HOSTMASTER.covers(Role.HOSTMASTER)).isTrue();
assertThat(Role.ADMIN.covers(Role.ADMIN)).isTrue();
assertThat(Role.SUPPORTER.covers(Role.SUPPORTER)).isTrue();
assertThat(Role.CONTRACTUAL_CONTACT.covers(Role.CONTRACTUAL_CONTACT)).isTrue();
assertThat(Role.FINANCIAL_CONTACT.covers(Role.FINANCIAL_CONTACT)).isTrue();
assertThat(Role.TECHNICAL_CONTACT.covers(Role.TECHNICAL_CONTACT)).isTrue();
assertThat(Role.ACTUAL_CUSTOMER_USER.covers((Role.ACTUAL_CUSTOMER_USER))).isTrue();
assertThat(Role.ANY_CUSTOMER_USER.covers((Role.ANY_CUSTOMER_USER))).isTrue();
}
@Test
public void lowerUserRolesShouldNotCoverHigherRequiredRoles() {
assertThat(Role.HOSTMASTER.covers(Role.NOBODY)).isFalse();
assertThat(Role.ADMIN.covers(Role.HOSTMASTER)).isFalse();
assertThat(Role.SUPPORTER.covers(Role.ADMIN)).isFalse();
assertThat(Role.ANY_CUSTOMER_CONTACT.covers(Role.SUPPORTER)).isFalse();
assertThat(Role.ANY_CUSTOMER_CONTACT.covers(Role.CONTRACTUAL_CONTACT)).isFalse();
assertThat(Role.FINANCIAL_CONTACT.covers(Role.CONTRACTUAL_CONTACT)).isFalse();
assertThat(Role.FINANCIAL_CONTACT.covers(Role.TECHNICAL_CONTACT)).isFalse();
assertThat(Role.TECHNICAL_CONTACT.covers(Role.CONTRACTUAL_CONTACT)).isFalse();
assertThat(Role.TECHNICAL_CONTACT.covers(Role.FINANCIAL_CONTACT)).isFalse();
assertThat(Role.ACTUAL_CUSTOMER_USER.covers((Role.ANY_CUSTOMER_CONTACT))).isFalse();
assertThat(Role.ACTUAL_CUSTOMER_USER.covers((Role.CONTRACTUAL_CONTACT))).isFalse();
assertThat(Role.ACTUAL_CUSTOMER_USER.covers((Role.TECHNICAL_CONTACT))).isFalse();
assertThat(Role.ACTUAL_CUSTOMER_USER.covers((Role.FINANCIAL_CONTACT))).isFalse();
assertThat(Role.ANY_CUSTOMER_USER.covers((Role.ACTUAL_CUSTOMER_USER))).isFalse();
assertThat(Role.ANY_CUSTOMER_USER.covers((Role.ANY_CUSTOMER_CONTACT))).isFalse();
assertThat(Role.ANY_CUSTOMER_USER.covers((Role.CONTRACTUAL_CONTACT))).isFalse();
assertThat(Role.ANY_CUSTOMER_USER.covers((Role.TECHNICAL_CONTACT))).isFalse();
assertThat(Role.ANY_CUSTOMER_USER.covers((Role.FINANCIAL_CONTACT))).isFalse();
assertThat(Role.ANYBODY.covers((Role.ANY_CUSTOMER_USER))).isFalse();
}
@Test
public void higherUserRolesShouldCoverLowerRequiredRoles() {
assertThat(Role.HOSTMASTER.covers(Role.SUPPORTER)).isTrue();
assertThat(Role.ADMIN.covers(Role.SUPPORTER)).isTrue();
assertThat(Role.SUPPORTER.covers(Role.ANY_CUSTOMER_CONTACT)).isTrue();
assertThat(Role.CONTRACTUAL_CONTACT.covers(Role.ANY_CUSTOMER_CONTACT)).isTrue();
assertThat(Role.CONTRACTUAL_CONTACT.covers(Role.FINANCIAL_CONTACT)).isTrue();
assertThat(Role.CONTRACTUAL_CONTACT.covers(Role.TECHNICAL_CONTACT)).isTrue();
assertThat(Role.TECHNICAL_CONTACT.covers(Role.ANY_CUSTOMER_USER)).isTrue();
assertThat(Role.ACTUAL_CUSTOMER_USER.covers((Role.ANY_CUSTOMER_USER))).isTrue();
assertThat(Role.ANY_CUSTOMER_USER.covers((Role.ANYBODY))).isTrue();
}
@Test
public void financialContactShouldNotCoverAnyCustomersUsersRoleRequirement() {
assertThat(Role.FINANCIAL_CONTACT.covers(Role.ACTUAL_CUSTOMER_USER)).isFalse();
}
@Test
public void isAllowedToInit() {
}
@Test
public void isAllowedToUpdate() {
}
@Test
public void isAllowedToRead() {
}
}

View File

@ -0,0 +1,191 @@
package org.hostsharing.hsadminng.service.dto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.hostsharing.hsadminng.domain.Customer;
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.accessfilter.Role;
import org.hostsharing.hsadminng.service.mapper.CustomerMapper;
import org.hostsharing.hsadminng.service.mapper.CustomerMapperImpl;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.JsonTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.IOException;
import java.util.Optional;
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;
@JsonTest
@SpringBootTest(classes = {CustomerMapperImpl.class, CustomerRepository.class, CustomerService.class, CustomerDTO.CustomerJsonSerializer.class, CustomerDTO.CustomerJsonDeserializer.class})
@RunWith(SpringRunner.class)
public class CustomerDTOUnitTest {
@Rule
public MockitoRule mockito = MockitoJUnit.rule();
@Autowired
private ObjectMapper objectMapper;
@Autowired
private CustomerMapper customerMapper;
@MockBean
private CustomerRepository customerRepository;
@MockBean
private CustomerService customerService;
@Test
public void testSerializationAsContractualCustomerContact() throws JsonProcessingException {
// given
givenAuthenticatedUser();
givenUserHavingRole(CustomerDTO.class, 1234L, Role.CONTRACTUAL_CONTACT);
CustomerDTO given = createSomeCustomerDTO(1234L);
// when
String actual = objectMapper.writeValueAsString(given);
// then
given.setRemark(null);
assertEquals(createExpectedJSon(given), actual);
}
@Test
public void testSerializationAsTechnicalCustomerUser() throws JsonProcessingException {
// given
givenAuthenticatedUser();
givenUserHavingRole(CustomerDTO.class, 1234L, Role.TECHNICAL_CONTACT);
CustomerDTO given = createSomeCustomerDTO(1234L);
// when
String actual = objectMapper.writeValueAsString(given);
// then
final String expectedJSon = "{" +
toJSonFieldDefinition("id", given.getId()) + "," +
toJSonFieldDefinition("reference", given.getReference()) + "," +
toJSonFieldDefinition("prefix", given.getPrefix()) + "," +
toJSonFieldDefinition("name", given.getName()) +
"}";
assertEquals(expectedJSon, actual);
}
@Test
public void testSerializationAsSupporter() throws JsonProcessingException {
// given
givenAuthenticatedUser();
givenUserHavingRole(CustomerDTO.class, null, Role.SUPPORTER);
CustomerDTO given = createSomeCustomerDTO(1234L);
// when
String actual = objectMapper.writeValueAsString(given);
// then
assertThat(actual).isEqualTo(createExpectedJSon(given));
}
@Test
public void testDeserializeAsContractualCustomerContact() throws IOException {
// given
givenAuthenticatedUser();
givenUserHavingRole(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\"}";
// when
CustomerDTO actual = objectMapper.readValue(json, CustomerDTO.class);
// then
CustomerDTO expected = new CustomerDTO();
expected.setId(1234L);
expected.setContractualSalutation("Hallo Updated");
expected.setBillingSalutation("Moin Updated");
assertThat(actual).isEqualToComparingFieldByField(expected);
}
// --- only test fixture below ---
private String createExpectedJSon(CustomerDTO dto) {
String json = // the fields in alphanumeric order:
toJSonFieldDefinitionIfPresent("id", dto.getId()) +
toJSonFieldDefinitionIfPresent("reference", dto.getReference()) +
toJSonFieldDefinitionIfPresent("prefix", dto.getPrefix()) +
toJSonFieldDefinitionIfPresent("name", dto.getName()) +
toJSonFieldDefinitionIfPresent("kind", "LEGAL") +
toJSonNullFieldDefinition("birthDate") +
toJSonNullFieldDefinition("birthPlace") +
toJSonFieldDefinitionIfPresent("registrationCourt", "Registergericht") +
toJSonFieldDefinitionIfPresent("registrationNumber", "Registernummer") +
toJSonFieldDefinitionIfPresent("vatRegion", "DOMESTIC") +
toJSonFieldDefinitionIfPresent("vatNumber", "DE1234") +
toJSonFieldDefinitionIfPresent("contractualSalutation", dto.getContractualSalutation()) +
toJSonFieldDefinitionIfPresent("contractualAddress", dto.getContractualAddress()) +
toJSonFieldDefinitionIfPresent("billingSalutation", dto.getBillingSalutation()) +
toJSonFieldDefinitionIfPresent("billingAddress", dto.getBillingAddress()) +
toJSonFieldDefinitionIfPresent("remark", dto.getRemark());
return "{" + json.substring(0, json.length() - 1) + "}";
}
private String toJSonFieldDefinition(String name, String value) {
return inQuotes(name) + ":" + (value != null ? inQuotes(value) : "null");
}
private String toJSonFieldDefinition(String name, Number value) {
return inQuotes(name) + ":" + (value != null ? value : "null");
}
private String toJSonNullFieldDefinition(String name) {
return inQuotes(name) + ":null,";
}
private String toJSonFieldDefinitionIfPresent(String name, String value) {
return value != null ? inQuotes(name) + ":" + inQuotes(value) + "," : "";
}
private String toJSonFieldDefinitionIfPresent(String name, Number value) {
return value != null ? inQuotes(name) + ":" + value + "," : "";
}
private String inQuotes(Object value) {
return "\"" + value.toString() + "\"";
}
private CustomerDTO createSomeCustomerDTO(final long id) {
final CustomerDTO given = new CustomerDTO();
given.setId(id);
given.setReference(10001);
given.setPrefix("abc");
given.setName("Mein Name");
given.setKind(CustomerKind.LEGAL);
given.setRegistrationCourt("Registergericht");
given.setRegistrationNumber("Registernummer");
given.setVatRegion(VatRegion.DOMESTIC);
given.setVatNumber("DE1234");
given.setContractualAddress("Eine Adresse");
given.setContractualSalutation("Hallo");
given.setBillingAddress("Noch eine Adresse");
given.setBillingSalutation("Moin");
given.setRemark("Eine Bemerkung");
return given;
}
}

View File

@ -0,0 +1,105 @@
package org.hostsharing.hsadminng.service.dto;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.hostsharing.hsadminng.service.CustomerService;
import org.hostsharing.hsadminng.service.MembershipService;
import org.hostsharing.hsadminng.service.accessfilter.JSonDeserializerWithAccessFilter;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import java.io.IOException;
import java.util.Optional;
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;
public class MembershipDTOUnitTest {
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private ApplicationContext ctx;
@Mock
private AutowireCapableBeanFactory autowireCapableBeanFactory;
@Mock
private JsonParser jsonParser;
@Mock
private ObjectCodec codec;
@Mock
private TreeNode treeNode;
@Mock
private MembershipService membershipService;
@Mock
private CustomerService customerService;
@Before
public void init() {
given(jsonParser.getCodec()).willReturn(codec);
given (ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory);
given(autowireCapableBeanFactory.createBean(MembershipService.class)).willReturn(membershipService);
given(autowireCapableBeanFactory.createBean(CustomerService.class)).willReturn(customerService);
given(customerService.findOne(1234L)).willReturn(Optional.of(new CustomerDTO()
.with(dto -> dto.setId(1234L))
));
}
@Test
public void adminShouldHaveRightToCreate() throws IOException {
givenAuthenticatedUser();
givenUserHavingRole(null, null, Role.ADMIN);
givenJSonTree(asJSon(ImmutablePair.of("customerId", 1234L)));
// when
final MembershipDTO actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, MembershipDTO.class).deserialize();
// then
assertThat(actualDto.getCustomerId()).isEqualTo(1234L);
}
@Test
public void contractualContactShouldNotHaveRightToCreate() throws IOException {
givenAuthenticatedUser();
givenUserHavingRole(CustomerDTO.class, 1234L, Role.CONTRACTUAL_CONTACT);
givenJSonTree(asJSon(ImmutablePair.of("customerId", 1234L)));
// when
Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, MembershipDTO.class).deserialize());
// then
assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> {
assertThat(badRequestAlertException.getParam()).isEqualTo("MembershipDTO.customerId");
assertThat(badRequestAlertException.getErrorKey()).isEqualTo("referencingProhibited");
});
}
// --- only fixture code below ---
private void givenJSonTree(String givenJSon) throws IOException {
given(codec.readTree(jsonParser)).willReturn(new ObjectMapper().readTree(givenJSon));
}
}

View File

@ -0,0 +1,163 @@
package org.hostsharing.hsadminng.service.dto;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.hostsharing.hsadminng.domain.enumeration.ShareAction;
import org.hostsharing.hsadminng.service.CustomerService;
import org.hostsharing.hsadminng.service.MembershipService;
import org.hostsharing.hsadminng.service.accessfilter.JSonDeserializerWithAccessFilter;
import org.hostsharing.hsadminng.service.accessfilter.JSonSerializerWithAccessFilter;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.hostsharing.hsadminng.web.rest.errors.BadRequestAlertException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import java.io.IOException;
import java.time.LocalDate;
import java.util.Optional;
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.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
public class ShareDTOUnitTest {
private static final long SOME_MEMBERSHIP_ID = 12345L;
private static final long SOME_CUSTOMER_ID = 1234L;
@Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock
private ApplicationContext ctx;
@Mock
private AutowireCapableBeanFactory autowireCapableBeanFactory;
@Mock
private JsonParser jsonParser;
@Mock
private JsonGenerator jsonGenerator;
@Mock
private ObjectCodec codec;
@Mock
private TreeNode treeNode;
@Mock
private CustomerService customerService;
@Mock
private MembershipService membershipService;
@Before
public void init() {
given(jsonParser.getCodec()).willReturn(codec);
given(ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory);
given(ctx.getAutowireCapableBeanFactory()).willReturn(autowireCapableBeanFactory);
given(autowireCapableBeanFactory.createBean(CustomerService.class)).willReturn(customerService);
given(autowireCapableBeanFactory.createBean(MembershipService.class)).willReturn(membershipService);
given(customerService.findOne(SOME_CUSTOMER_ID)).willReturn(Optional.of(new CustomerDTO()));
given(membershipService.findOne(SOME_MEMBERSHIP_ID)).willReturn(Optional.of(new MembershipDTO().with(dto -> dto.setCustomerId(SOME_CUSTOMER_ID))));
}
@Test
public void adminShouldHaveRightToCreate() throws IOException {
givenAuthenticatedUser();
givenUserHavingRole(null, null, Role.ADMIN);
givenJSonTree(asJSon(ImmutablePair.of("membershipId", SOME_MEMBERSHIP_ID)));
// when
final ShareDTO actualDto = new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, ShareDTO.class).deserialize();
// then
assertThat(actualDto.getMembershipId()).isEqualTo(SOME_MEMBERSHIP_ID);
}
@Test
public void contractualContactShouldNotHaveRightToCreate() throws IOException {
givenAuthenticatedUser();
givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.CONTRACTUAL_CONTACT);
givenJSonTree(asJSon(ImmutablePair.of("membershipId", ShareDTOUnitTest.SOME_MEMBERSHIP_ID)));
// when
Throwable exception = catchThrowable(() -> new JSonDeserializerWithAccessFilter<>(ctx, jsonParser, null, ShareDTO.class).deserialize());
// then
assertThat(exception).isInstanceOfSatisfying(BadRequestAlertException.class, badRequestAlertException -> {
assertThat(badRequestAlertException.getParam()).isEqualTo("ShareDTO.membershipId");
assertThat(badRequestAlertException.getErrorKey()).isEqualTo("referencingProhibited");
});
}
@Test
public void financialContactShouldHaveRightToReadAllButRemark() throws IOException {
givenAuthenticatedUser();
givenUserHavingRole(CustomerDTO.class, SOME_CUSTOMER_ID, Role.FINANCIAL_CONTACT);
final ShareDTO givenDTO = createShareDto();
// when
new JSonSerializerWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize();
// then
verify(jsonGenerator).writeNumberField("id", givenDTO.getId());
verify(jsonGenerator).writeNumberField("membershipId", givenDTO.getMembershipId());
verify(jsonGenerator, never()).writeStringField(eq("remark"), anyString());
}
@Test
public void supporterShouldHaveRightToRead() throws IOException {
givenAuthenticatedUser();
givenUserHavingRole(null, null, Role.SUPPORTER);
final ShareDTO givenDTO = createShareDto();
// when
new JSonSerializerWithAccessFilter<>(ctx, jsonGenerator, null, givenDTO).serialize();
// then
verify(jsonGenerator).writeNumberField("id", givenDTO.getId());
verify(jsonGenerator).writeNumberField("membershipId", givenDTO.getMembershipId());
verify(jsonGenerator).writeStringField("remark", givenDTO.getRemark());
}
// --- only fixture code below ---
private void givenJSonTree(String givenJSon) throws IOException {
given(codec.readTree(jsonParser)).willReturn(new ObjectMapper().readTree(givenJSon));
}
private ShareDTO createShareDto() {
final ShareDTO givenDTO = new ShareDTO();
givenDTO.setId(1234567L);
givenDTO.setMembershipId(SOME_MEMBERSHIP_ID);
givenDTO.setAction(ShareAction.SUBSCRIPTION);
givenDTO.setQuantity(3);
givenDTO.setDocumentDate(LocalDate.parse("2019-04-22"));
givenDTO.setMembershipDisplayReference("2019-04-21"); // TODO: why is this not a LocalDate?
givenDTO.setValueDate(LocalDate.parse("2019-04-30"));
givenDTO.setRemark("Some Remark");
return givenDTO;
}
}

View File

@ -1,17 +1,15 @@
package org.hostsharing.hsadminng.web.rest; package org.hostsharing.hsadminng.web.rest;
import org.hostsharing.hsadminng.HsadminNgApp; import org.hostsharing.hsadminng.HsadminNgApp;
import org.hostsharing.hsadminng.domain.Asset; import org.hostsharing.hsadminng.domain.Asset;
import org.hostsharing.hsadminng.domain.Membership; import org.hostsharing.hsadminng.domain.Membership;
import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
import org.hostsharing.hsadminng.repository.AssetRepository; import org.hostsharing.hsadminng.repository.AssetRepository;
import org.hostsharing.hsadminng.service.AssetQueryService;
import org.hostsharing.hsadminng.service.AssetService; import org.hostsharing.hsadminng.service.AssetService;
import org.hostsharing.hsadminng.service.dto.AssetDTO; import org.hostsharing.hsadminng.service.dto.AssetDTO;
import org.hostsharing.hsadminng.service.mapper.AssetMapper; import org.hostsharing.hsadminng.service.mapper.AssetMapper;
import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator; import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator;
import org.hostsharing.hsadminng.service.dto.AssetCriteria;
import org.hostsharing.hsadminng.service.AssetQueryService;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -33,14 +31,11 @@ import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.List; import java.util.List;
import static org.hostsharing.hsadminng.web.rest.TestUtil.createFormattingConversionService;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
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.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.hostsharing.hsadminng.domain.enumeration.AssetAction;
/** /**
* Test class for the AssetResource REST controller. * Test class for the AssetResource REST controller.
* *

View File

@ -1,18 +1,18 @@
package org.hostsharing.hsadminng.web.rest; package org.hostsharing.hsadminng.web.rest;
import org.hostsharing.hsadminng.HsadminNgApp; import org.hostsharing.hsadminng.HsadminNgApp;
import org.hostsharing.hsadminng.domain.Customer; import org.hostsharing.hsadminng.domain.Customer;
import org.hostsharing.hsadminng.domain.Membership; import org.hostsharing.hsadminng.domain.Membership;
import org.hostsharing.hsadminng.domain.SepaMandate; import org.hostsharing.hsadminng.domain.SepaMandate;
import org.hostsharing.hsadminng.domain.enumeration.CustomerKind;
import org.hostsharing.hsadminng.domain.enumeration.VatRegion;
import org.hostsharing.hsadminng.repository.CustomerRepository; import org.hostsharing.hsadminng.repository.CustomerRepository;
import org.hostsharing.hsadminng.service.CustomerQueryService;
import org.hostsharing.hsadminng.service.CustomerService; import org.hostsharing.hsadminng.service.CustomerService;
import org.hostsharing.hsadminng.service.accessfilter.Role;
import org.hostsharing.hsadminng.service.dto.CustomerDTO; import org.hostsharing.hsadminng.service.dto.CustomerDTO;
import org.hostsharing.hsadminng.service.mapper.CustomerMapper; import org.hostsharing.hsadminng.service.mapper.CustomerMapper;
import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator; import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator;
import org.hostsharing.hsadminng.service.dto.CustomerCriteria;
import org.hostsharing.hsadminng.service.CustomerQueryService;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -33,15 +33,14 @@ import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.List; import java.util.List;
import static org.hostsharing.hsadminng.web.rest.TestUtil.createFormattingConversionService;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem; 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.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.hostsharing.hsadminng.domain.enumeration.CustomerKind;
import org.hostsharing.hsadminng.domain.enumeration.VatRegion;
/** /**
* Test class for the CustomerResource REST controller. * Test class for the CustomerResource REST controller.
* *
@ -138,6 +137,10 @@ public class CustomerResourceIntTest {
@Before @Before
public void setup() { public void setup() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
givenAuthenticatedUser();
givenUserHavingRole(Role.ADMIN);
final CustomerResource customerResource = new CustomerResource(customerService, customerQueryService); final CustomerResource customerResource = new CustomerResource(customerService, customerQueryService);
this.restCustomerMockMvc = MockMvcBuilders.standaloneSetup(customerResource) this.restCustomerMockMvc = MockMvcBuilders.standaloneSetup(customerResource)
.setCustomArgumentResolvers(pageableArgumentResolver) .setCustomArgumentResolvers(pageableArgumentResolver)
@ -149,7 +152,7 @@ public class CustomerResourceIntTest {
/** /**
* Create an entity for this test. * Create an entity for this test.
* * <p>
* This is a static method, as tests for other entities might also need it, * This is a static method, as tests for other entities might also need it,
* if they test an entity which requires the current entity. * if they test an entity which requires the current entity.
*/ */
@ -175,7 +178,7 @@ public class CustomerResourceIntTest {
/** /**
* Create another entity for tests. * Create another entity for tests.
* * <p>
* This is a static method, as tests for other entities might also need it, * This is a static method, as tests for other entities might also need it,
* if they test an entity which requires the current entity. * if they test an entity which requires the current entity.
*/ */
@ -377,22 +380,22 @@ public class CustomerResourceIntTest {
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$.[*].id").value(hasItem(customer.getId().intValue()))) .andExpect(jsonPath("$.[*].id").value(hasItem(customer.getId().intValue())))
.andExpect(jsonPath("$.[*].reference").value(hasItem(DEFAULT_REFERENCE))) .andExpect(jsonPath("$.[*].reference").value(hasItem(DEFAULT_REFERENCE)))
.andExpect(jsonPath("$.[*].prefix").value(hasItem(DEFAULT_PREFIX.toString()))) .andExpect(jsonPath("$.[*].prefix").value(hasItem(DEFAULT_PREFIX)))
.andExpect(jsonPath("$.[*].name").value(hasItem(DEFAULT_NAME.toString()))) .andExpect(jsonPath("$.[*].name").value(hasItem(DEFAULT_NAME)))
.andExpect(jsonPath("$.[*].kind").value(hasItem(DEFAULT_KIND.toString()))) .andExpect(jsonPath("$.[*].kind").value(hasItem(DEFAULT_KIND.toString())))
.andExpect(jsonPath("$.[*].birthDate").value(hasItem(DEFAULT_BIRTH_DATE.toString()))) .andExpect(jsonPath("$.[*].birthDate").value(hasItem(DEFAULT_BIRTH_DATE.toString())))
.andExpect(jsonPath("$.[*].birthPlace").value(hasItem(DEFAULT_BIRTH_PLACE.toString()))) .andExpect(jsonPath("$.[*].birthPlace").value(hasItem(DEFAULT_BIRTH_PLACE)))
.andExpect(jsonPath("$.[*].registrationCourt").value(hasItem(DEFAULT_REGISTRATION_COURT.toString()))) .andExpect(jsonPath("$.[*].registrationCourt").value(hasItem(DEFAULT_REGISTRATION_COURT)))
.andExpect(jsonPath("$.[*].registrationNumber").value(hasItem(DEFAULT_REGISTRATION_NUMBER.toString()))) .andExpect(jsonPath("$.[*].registrationNumber").value(hasItem(DEFAULT_REGISTRATION_NUMBER)))
.andExpect(jsonPath("$.[*].vatRegion").value(hasItem(DEFAULT_VAT_REGION.toString()))) .andExpect(jsonPath("$.[*].vatRegion").value(hasItem(DEFAULT_VAT_REGION.toString())))
.andExpect(jsonPath("$.[*].vatNumber").value(hasItem(DEFAULT_VAT_NUMBER.toString()))) .andExpect(jsonPath("$.[*].vatNumber").value(hasItem(DEFAULT_VAT_NUMBER)))
.andExpect(jsonPath("$.[*].contractualSalutation").value(hasItem(DEFAULT_CONTRACTUAL_SALUTATION.toString()))) .andExpect(jsonPath("$.[*].contractualSalutation").value(hasItem(DEFAULT_CONTRACTUAL_SALUTATION)))
.andExpect(jsonPath("$.[*].contractualAddress").value(hasItem(DEFAULT_CONTRACTUAL_ADDRESS.toString()))) .andExpect(jsonPath("$.[*].contractualAddress").value(hasItem(DEFAULT_CONTRACTUAL_ADDRESS)))
.andExpect(jsonPath("$.[*].billingSalutation").value(hasItem(DEFAULT_BILLING_SALUTATION.toString()))) .andExpect(jsonPath("$.[*].billingSalutation").value(hasItem(DEFAULT_BILLING_SALUTATION)))
.andExpect(jsonPath("$.[*].billingAddress").value(hasItem(DEFAULT_BILLING_ADDRESS.toString()))) .andExpect(jsonPath("$.[*].billingAddress").value(hasItem(DEFAULT_BILLING_ADDRESS)))
.andExpect(jsonPath("$.[*].remark").value(hasItem(DEFAULT_REMARK.toString()))); .andExpect(jsonPath("$.[*].remark").value(hasItem(DEFAULT_REMARK)));
} }
@Test @Test
@Transactional @Transactional
public void getCustomer() throws Exception { public void getCustomer() throws Exception {
@ -1167,8 +1170,8 @@ public class CustomerResourceIntTest {
// Disconnect from session so that the updates on updatedCustomer are not directly saved in db // Disconnect from session so that the updates on updatedCustomer are not directly saved in db
em.detach(updatedCustomer); em.detach(updatedCustomer);
updatedCustomer updatedCustomer
.reference(UPDATED_REFERENCE) .reference(null)
.prefix(UPDATED_PREFIX) .prefix(null)
.name(UPDATED_NAME) .name(UPDATED_NAME)
.kind(UPDATED_KIND) .kind(UPDATED_KIND)
.birthDate(UPDATED_BIRTH_DATE) .birthDate(UPDATED_BIRTH_DATE)
@ -1193,8 +1196,8 @@ public class CustomerResourceIntTest {
List<Customer> customerList = customerRepository.findAll(); List<Customer> customerList = customerRepository.findAll();
assertThat(customerList).hasSize(databaseSizeBeforeUpdate); assertThat(customerList).hasSize(databaseSizeBeforeUpdate);
Customer testCustomer = customerList.get(customerList.size() - 1); Customer testCustomer = customerList.get(customerList.size() - 1);
assertThat(testCustomer.getReference()).isEqualTo(UPDATED_REFERENCE); assertThat(testCustomer.getReference()).isEqualTo(DEFAULT_REFERENCE);
assertThat(testCustomer.getPrefix()).isEqualTo(UPDATED_PREFIX); assertThat(testCustomer.getPrefix()).isEqualTo(DEFAULT_PREFIX);
assertThat(testCustomer.getName()).isEqualTo(UPDATED_NAME); assertThat(testCustomer.getName()).isEqualTo(UPDATED_NAME);
assertThat(testCustomer.getKind()).isEqualTo(UPDATED_KIND); assertThat(testCustomer.getKind()).isEqualTo(UPDATED_KIND);
assertThat(testCustomer.getBirthDate()).isEqualTo(UPDATED_BIRTH_DATE); assertThat(testCustomer.getBirthDate()).isEqualTo(UPDATED_BIRTH_DATE);

View File

@ -7,12 +7,10 @@ import org.hostsharing.hsadminng.domain.Membership;
import org.hostsharing.hsadminng.domain.Share; import org.hostsharing.hsadminng.domain.Share;
import org.hostsharing.hsadminng.repository.MembershipRepository; import org.hostsharing.hsadminng.repository.MembershipRepository;
import org.hostsharing.hsadminng.service.MembershipQueryService; import org.hostsharing.hsadminng.service.MembershipQueryService;
import org.hostsharing.hsadminng.service.MembershipService; import org.hostsharing.hsadminng.service.MembershipService;
import org.hostsharing.hsadminng.service.dto.MembershipDTO; import org.hostsharing.hsadminng.service.dto.MembershipDTO;
import org.hostsharing.hsadminng.service.mapper.MembershipMapper; import org.hostsharing.hsadminng.service.mapper.MembershipMapper;
import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator; import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -36,10 +34,6 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
import static org.hostsharing.hsadminng.web.rest.TestUtil.createFormattingConversionService; import static org.hostsharing.hsadminng.web.rest.TestUtil.createFormattingConversionService;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

View File

@ -1,16 +1,14 @@
package org.hostsharing.hsadminng.web.rest; package org.hostsharing.hsadminng.web.rest;
import org.hostsharing.hsadminng.HsadminNgApp; import org.hostsharing.hsadminng.HsadminNgApp;
import org.hostsharing.hsadminng.domain.SepaMandate;
import org.hostsharing.hsadminng.domain.Customer; import org.hostsharing.hsadminng.domain.Customer;
import org.hostsharing.hsadminng.domain.SepaMandate;
import org.hostsharing.hsadminng.repository.SepaMandateRepository; import org.hostsharing.hsadminng.repository.SepaMandateRepository;
import org.hostsharing.hsadminng.service.SepaMandateQueryService;
import org.hostsharing.hsadminng.service.SepaMandateService; import org.hostsharing.hsadminng.service.SepaMandateService;
import org.hostsharing.hsadminng.service.dto.SepaMandateDTO; import org.hostsharing.hsadminng.service.dto.SepaMandateDTO;
import org.hostsharing.hsadminng.service.mapper.SepaMandateMapper; import org.hostsharing.hsadminng.service.mapper.SepaMandateMapper;
import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator; import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator;
import org.hostsharing.hsadminng.service.SepaMandateQueryService;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -31,10 +29,9 @@ import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.List; import java.util.List;
import static org.hostsharing.hsadminng.web.rest.TestUtil.createFormattingConversionService;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
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.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

View File

@ -1,17 +1,15 @@
package org.hostsharing.hsadminng.web.rest; package org.hostsharing.hsadminng.web.rest;
import org.hostsharing.hsadminng.HsadminNgApp; import org.hostsharing.hsadminng.HsadminNgApp;
import org.hostsharing.hsadminng.domain.Share;
import org.hostsharing.hsadminng.domain.Membership; import org.hostsharing.hsadminng.domain.Membership;
import org.hostsharing.hsadminng.domain.Share;
import org.hostsharing.hsadminng.domain.enumeration.ShareAction;
import org.hostsharing.hsadminng.repository.ShareRepository; import org.hostsharing.hsadminng.repository.ShareRepository;
import org.hostsharing.hsadminng.service.ShareQueryService;
import org.hostsharing.hsadminng.service.ShareService; import org.hostsharing.hsadminng.service.ShareService;
import org.hostsharing.hsadminng.service.dto.ShareDTO; import org.hostsharing.hsadminng.service.dto.ShareDTO;
import org.hostsharing.hsadminng.service.mapper.ShareMapper; import org.hostsharing.hsadminng.service.mapper.ShareMapper;
import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator; import org.hostsharing.hsadminng.web.rest.errors.ExceptionTranslator;
import org.hostsharing.hsadminng.service.dto.ShareCriteria;
import org.hostsharing.hsadminng.service.ShareQueryService;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -32,14 +30,11 @@ import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.List; import java.util.List;
import static org.hostsharing.hsadminng.web.rest.TestUtil.createFormattingConversionService;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
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.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.hostsharing.hsadminng.domain.enumeration.ShareAction;
/** /**
* Test class for the ShareResource REST controller. * Test class for the ShareResource REST controller.
* *

View File

@ -1,13 +1,11 @@
/* tslint:disable max-line-length */ /* tslint:disable max-line-length */
import { TestBed, getTestBed } from '@angular/core/testing'; import { getTestBed, TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClient, HttpResponse } from '@angular/common/http'; import { map, take } from 'rxjs/operators';
import { of } from 'rxjs';
import { take, map } from 'rxjs/operators';
import * as moment from 'moment'; import * as moment from 'moment';
import { DATE_FORMAT } from 'app/shared/constants/input.constants'; import { DATE_FORMAT } from 'app/shared/constants/input.constants';
import { CustomerService } from 'app/entities/customer/customer.service'; import { CustomerService } from 'app/entities/customer/customer.service';
import { ICustomer, Customer, CustomerKind, VatRegion } from 'app/shared/model/customer.model'; import { Customer, CustomerKind, ICustomer, VatRegion } from 'app/shared/model/customer.model';
describe('Service Tests', () => { describe('Service Tests', () => {
describe('Customer Service', () => { describe('Customer Service', () => {

View File

@ -1,9 +1,7 @@
/* tslint:disable max-line-length */ /* tslint:disable max-line-length */
import { TestBed, getTestBed } from '@angular/core/testing'; import { getTestBed, TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClient, HttpResponse } from '@angular/common/http'; import { map, take } from 'rxjs/operators';
import { of } from 'rxjs';
import { take, map } from 'rxjs/operators';
import * as moment from 'moment'; import * as moment from 'moment';
import { DATE_FORMAT } from 'app/shared/constants/input.constants'; import { DATE_FORMAT } from 'app/shared/constants/input.constants';
import { MembershipService } from 'app/entities/membership/membership.service'; import { MembershipService } from 'app/entities/membership/membership.service';

View File

@ -1,9 +1,7 @@
/* tslint:disable max-line-length */ /* tslint:disable max-line-length */
import { TestBed, getTestBed } from '@angular/core/testing'; import { getTestBed, TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClient, HttpResponse } from '@angular/common/http'; import { map, take } from 'rxjs/operators';
import { of } from 'rxjs';
import { take, map } from 'rxjs/operators';
import * as moment from 'moment'; import * as moment from 'moment';
import { DATE_FORMAT } from 'app/shared/constants/input.constants'; import { DATE_FORMAT } from 'app/shared/constants/input.constants';
import { SepaMandateService } from 'app/entities/sepa-mandate/sepa-mandate.service'; import { SepaMandateService } from 'app/entities/sepa-mandate/sepa-mandate.service';