diff --git a/openex-model/pom.xml b/openex-model/pom.xml index 04aec32176..4286ac3d48 100644 --- a/openex-model/pom.xml +++ b/openex-model/pom.xml @@ -13,6 +13,11 @@ OpenEx model OpenEx model + + 1.7 + 1.18.26 + + org.springframework.boot @@ -52,5 +57,16 @@ validation-api ${validation-api.version} + + commons-validator + commons-validator + ${commons-validator.version} + + + org.projectlombok + lombok + ${lombok.version} + provided + diff --git a/openex-model/src/main/java/io/openex/annotation/Ipv4OrIpv6Constraint.java b/openex-model/src/main/java/io/openex/annotation/Ipv4OrIpv6Constraint.java new file mode 100644 index 0000000000..dc4507f1c5 --- /dev/null +++ b/openex-model/src/main/java/io/openex/annotation/Ipv4OrIpv6Constraint.java @@ -0,0 +1,24 @@ +package io.openex.annotation; + +import io.openex.validator.Ipv4OrIpv6Validator; + +import javax.validation.Constraint; +import javax.validation.Payload; +import javax.validation.ReportAsSingleViolation; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Target(FIELD) +@Retention(RUNTIME) +@Constraint(validatedBy = Ipv4OrIpv6Validator.class) +@ReportAsSingleViolation +public @interface Ipv4OrIpv6Constraint { + String message() default "must be ipv4 or ipv6"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/openex-model/src/main/java/io/openex/database/audit/ModelBaseListener.java b/openex-model/src/main/java/io/openex/database/audit/ModelBaseListener.java index 5380c8f1d5..e502f103f7 100644 --- a/openex-model/src/main/java/io/openex/database/audit/ModelBaseListener.java +++ b/openex-model/src/main/java/io/openex/database/audit/ModelBaseListener.java @@ -45,6 +45,7 @@ void postUpdate(Object base) { @PreRemove void preRemove(Object base) { Base instance = (Base) base; - appPublisher.publishEvent(new BaseEvent(DATA_DELETE, instance, mapper)); + BaseEvent event = new BaseEvent(DATA_DELETE, instance, mapper); + appPublisher.publishEvent(event); } } diff --git a/openex-model/src/main/java/io/openex/database/model/System.java b/openex-model/src/main/java/io/openex/database/model/System.java new file mode 100644 index 0000000000..07c99e9477 --- /dev/null +++ b/openex-model/src/main/java/io/openex/database/model/System.java @@ -0,0 +1,78 @@ +package io.openex.database.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.openex.annotation.Ipv4OrIpv6Constraint; +import io.openex.database.audit.ModelBaseListener; +import io.openex.helper.MultiIdDeserializer; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static java.time.Instant.now; + +@Getter +@Setter +@Entity +@Table(name = "systems") +@EntityListeners(ModelBaseListener.class) +public class System implements Base { + + public enum SYSTEM_TYPE { + ENDPOINT, + WEBSITE, + } + + public enum OS_TYPE { + LINUX, + WINDOWS, + } + + @Id + @Column(name = "system_id") + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @JsonProperty("system_id") + private String id; + + @Column(name = "system_created_at") + @JsonProperty("system_created_at") + private Instant createdAt = now(); + + @Column(name = "system_updated_at") + @JsonProperty("system_updated_at") + private Instant updatedAt = now(); + + @Column(name = "system_name") + @JsonProperty("system_name") + private String name; + + @Column(name = "system_type") + @JsonProperty("system_type") + @Enumerated(EnumType.STRING) + private SYSTEM_TYPE type; + + @Ipv4OrIpv6Constraint + @Column(name = "system_ip") + @JsonProperty("system_ip") + private String ip; + + @Column(name = "system_hostname") + @JsonProperty("system_hostname") + private String hostname; + + @Column(name = "system_os") + @JsonProperty("system_os") + @Enumerated(EnumType.STRING) + private OS_TYPE os; + + @ManyToMany(mappedBy = "systems", fetch = FetchType.LAZY) + @JsonSerialize(using = MultiIdDeserializer.class) + @JsonProperty("system_zones") + private List zones = new ArrayList<>(); +} diff --git a/openex-model/src/main/java/io/openex/database/model/User.java b/openex-model/src/main/java/io/openex/database/model/User.java index 5786c32316..d60717b111 100644 --- a/openex-model/src/main/java/io/openex/database/model/User.java +++ b/openex-model/src/main/java/io/openex/database/model/User.java @@ -218,7 +218,8 @@ public boolean isPlanner() { @JsonProperty("user_is_observer") public boolean isObserver() { return isAdmin() || getGroups().stream() - .mapToLong(group -> group.getGrants().size()).sum() > 0; + .flatMap(group -> group.getGrants().stream()) + .anyMatch(grant -> Grant.GRANT_TYPE.OBSERVER.equals(grant.getName())); } @JsonProperty("user_is_manager") diff --git a/openex-model/src/main/java/io/openex/database/model/Zone.java b/openex-model/src/main/java/io/openex/database/model/Zone.java new file mode 100644 index 0000000000..d414335c2d --- /dev/null +++ b/openex-model/src/main/java/io/openex/database/model/Zone.java @@ -0,0 +1,56 @@ +package io.openex.database.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.openex.annotation.Ipv4OrIpv6Constraint; +import io.openex.database.audit.ModelBaseListener; +import io.openex.helper.MultiIdDeserializer; +import lombok.Getter; +import lombok.Setter; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static java.time.Instant.now; + +@Getter +@Setter +@Entity +@Table(name = "zones") +@EntityListeners(ModelBaseListener.class) +public class Zone implements Base { + + @Id + @Column(name = "zone_id") + @GeneratedValue(generator = "UUID") + @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator") + @JsonProperty("zone_id") + private String id; + + @Column(name = "zone_name") + @JsonProperty("zone_name") + private String name; + + @Column(name = "zone_description") + @JsonProperty("zone_description") + private String description; + + @Column(name = "zone_created_at") + @JsonProperty("zone_created_at") + private Instant createdAt = now(); + + @Column(name = "zone_updated_at") + @JsonProperty("zone_updated_at") + private Instant updatedAt = now(); + + @ManyToMany(fetch = FetchType.LAZY) + @JoinTable(name = "systems_zones", + joinColumns = @JoinColumn(name = "zone_id"), + inverseJoinColumns = @JoinColumn(name = "system_id")) + @JsonSerialize(using = MultiIdDeserializer.class) + @JsonProperty("zone_systems") + private List systems = new ArrayList<>(); +} diff --git a/openex-model/src/main/java/io/openex/database/repository/SystemRepository.java b/openex-model/src/main/java/io/openex/database/repository/SystemRepository.java new file mode 100644 index 0000000000..82d866fd00 --- /dev/null +++ b/openex-model/src/main/java/io/openex/database/repository/SystemRepository.java @@ -0,0 +1,8 @@ +package io.openex.database.repository; + +import io.openex.database.model.System; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface SystemRepository extends CrudRepository { } diff --git a/openex-model/src/main/java/io/openex/database/repository/ZoneRepository.java b/openex-model/src/main/java/io/openex/database/repository/ZoneRepository.java new file mode 100644 index 0000000000..45fa3cae1a --- /dev/null +++ b/openex-model/src/main/java/io/openex/database/repository/ZoneRepository.java @@ -0,0 +1,8 @@ +package io.openex.database.repository; + +import io.openex.database.model.Zone; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ZoneRepository extends CrudRepository { } diff --git a/openex-model/src/main/java/io/openex/validator/Ipv4OrIpv6Validator.java b/openex-model/src/main/java/io/openex/validator/Ipv4OrIpv6Validator.java new file mode 100644 index 0000000000..df350e6fee --- /dev/null +++ b/openex-model/src/main/java/io/openex/validator/Ipv4OrIpv6Validator.java @@ -0,0 +1,21 @@ +package io.openex.validator; + +import io.openex.annotation.Ipv4OrIpv6Constraint; +import org.apache.commons.validator.routines.InetAddressValidator; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +public class Ipv4OrIpv6Validator implements ConstraintValidator { + + @Override + public void initialize(Ipv4OrIpv6Constraint ip) { + } + + @Override + public boolean isValid(String ip, ConstraintValidatorContext cxt) { + InetAddressValidator validator = InetAddressValidator.getInstance(); + return validator.isValid(ip); + } + +}