diff --git a/.gitignore b/.gitignore index 2190e52ff..416075eef 100644 --- a/.gitignore +++ b/.gitignore @@ -46,5 +46,6 @@ ELK.Docker/shared/data-elk/ .settings/ bin/ *.classpath +.run openDMP/dmp-backend/uploads/ openDMP/dmp-backend/tmp/ diff --git a/dmp-backend/core/pom.xml b/dmp-backend/core/pom.xml index 45553cd7c..8f1812961 100644 --- a/dmp-backend/core/pom.xml +++ b/dmp-backend/core/pom.xml @@ -27,6 +27,28 @@ UTF-8 + + + dmp-backend + queryable + 1.0-SNAPSHOT + compile + + + org.springframework.boot + spring-boot-starter-validation + + + gr.cite + validation + 2.1.0 + + + gr.cite + oidc-authz + 2.1.0 + + diff --git a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java index 2ff1dfb63..1dc08d4ce 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java +++ b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java @@ -5,9 +5,8 @@ import gr.cite.tools.logging.EventId; public class AuditableAction { public static final EventId DescriptionTemplateType_Query = new EventId(1000, "DescriptionTemplateType_Query"); - - public static final EventId DescriptionTemplateType_Persist = new EventId(1001, "DescriptionTemplateType_Persist"); - - public static final EventId DescriptionTemplateType_Delete = new EventId(1002, "DescriptionTemplateType_Delete"); + public static final EventId DescriptionTemplateType_Lookup = new EventId(1001, "DescriptionTemplateType_Lookup"); + public static final EventId DescriptionTemplateType_Persist = new EventId(1002, "DescriptionTemplateType_Persist"); + public static final EventId DescriptionTemplateType_Delete = new EventId(1003, "DescriptionTemplateType_Delete"); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/authorization/AuthorizationFlags.java b/dmp-backend/core/src/main/java/eu/eudat/authorization/AuthorizationFlags.java new file mode 100644 index 000000000..e87d23b26 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/authorization/AuthorizationFlags.java @@ -0,0 +1,8 @@ +package eu.eudat.authorization; + +import java.util.EnumSet; + +public enum AuthorizationFlags { + None, Permission, Owner; + public static final EnumSet OwnerOrPermission = EnumSet.of(Owner, Permission); +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/authorization/OwnedAuthorizationRequirement.java b/dmp-backend/core/src/main/java/eu/eudat/authorization/OwnedAuthorizationRequirement.java new file mode 100644 index 000000000..e43d2cb06 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/authorization/OwnedAuthorizationRequirement.java @@ -0,0 +1,6 @@ +package eu.eudat.authorization; + +import gr.cite.commons.web.authz.policy.AuthorizationRequirement; + +public class OwnedAuthorizationRequirement implements AuthorizationRequirement { +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/authorization/OwnedResource.java b/dmp-backend/core/src/main/java/eu/eudat/authorization/OwnedResource.java new file mode 100644 index 000000000..58ab094d4 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/authorization/OwnedResource.java @@ -0,0 +1,26 @@ +package eu.eudat.authorization; + +import gr.cite.commons.web.authz.policy.AuthorizationResource; + +import java.util.List; +import java.util.UUID; + +public class OwnedResource extends AuthorizationResource { + private List userIds; + + public OwnedResource(UUID userId) { + this(List.of(userId)); + } + + public OwnedResource(List userIds) { + this.userIds = userIds; + } + + public List getUserIds() { + return userIds; + } + + public void setUserIds(List userIds) { + this.userIds = userIds; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java b/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java new file mode 100644 index 000000000..b68deaf62 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java @@ -0,0 +1,13 @@ +package eu.eudat.authorization; + +public final class Permission { + + //DescriptionTemplateType + public static String BrowseDescriptionTemplateType = "BrowseDescriptionTemplateType"; + public static String EditDescriptionTemplateType = "EditDescriptionTemplateType"; + public static String DeleteDescriptionTemplateType = "DeleteDescriptionTemplateType"; + + // UI Pages + public static String ViewDescriptionTemplateTypePage = "ViewDescriptionTemplateTypePage"; + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/JsonHandlingService.java b/dmp-backend/core/src/main/java/eu/eudat/commons/JsonHandlingService.java new file mode 100644 index 000000000..5061839cb --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/JsonHandlingService.java @@ -0,0 +1,47 @@ +package eu.eudat.commons; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) +public class JsonHandlingService { + private final ObjectMapper objectMapper; + + public JsonHandlingService() { + this.objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + } + + public String toJson(Object item) throws JsonProcessingException { + if (item == null) return null; + return objectMapper.writeValueAsString(item); + } + + public String toJsonSafe(Object item) { + if (item == null) return null; + try { + return objectMapper.writeValueAsString(item); + } catch (Exception ex) { + return null; + } + } + + public T fromJson(Class type, String json) throws JsonProcessingException { + if (json == null) return null; + return objectMapper.readValue(json, type); + } + + public T fromJsonSafe(Class type, String json) { + if (json == null) return null; + try { + return objectMapper.readValue(json, type); + } catch (Exception ex) { + return null; + } + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/DescriptionTemplateTypeStatus.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/DescriptionTemplateTypeStatus.java index 718809a01..8967908b4 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/DescriptionTemplateTypeStatus.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/DescriptionTemplateTypeStatus.java @@ -1,43 +1,28 @@ package eu.eudat.commons.enums; -public enum DescriptionTemplateTypeStatus { +import eu.eudat.data.converters.enums.DatabaseEnum; - SAVED((short) 0), FINALIZED((short) 1), DELETED((short) 99); +import java.util.Map; - private final short value; +public enum DescriptionTemplateTypeStatus implements DatabaseEnum { - DescriptionTemplateTypeStatus(short value) { + Draft((short) 0), + Finalized((short) 1); + + private final Short value; + + DescriptionTemplateTypeStatus(Short value) { this.value = value; } - public short getValue() { + public Short getValue() { return value; } - public static DescriptionTemplateTypeStatus fromInteger(int value) { - switch (value) { - case 0: - return SAVED; - case 1: - return FINALIZED; - case 99: - return DELETED; - default: - throw new RuntimeException("Unsupported Description Template Type Status"); - } - } + private static final Map map = EnumUtils.getEnumValueMap(DescriptionTemplateTypeStatus.class); - public static DescriptionTemplateTypeStatus fromLabel(String value) { - switch (value) { - case "SAVED": - return SAVED; - case "FINALISED": - return FINALIZED; - case "DELETED": - return DELETED; - default: - throw new RuntimeException("Unsupported Description Template Type Status"); - } + public static DescriptionTemplateTypeStatus of(Short i) { + return map.get(i); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/EnumUtils.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/EnumUtils.java new file mode 100644 index 000000000..404660306 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/EnumUtils.java @@ -0,0 +1,16 @@ +package eu.eudat.commons.enums; + +import eu.eudat.data.converters.enums.DatabaseEnum; + +import java.util.HashMap; +import java.util.Map; + +public class EnumUtils { + public static & DatabaseEnum, EnumValue> Map getEnumValueMap(Class enumType){ + HashMap map = new HashMap<>(); + for (EnumType v : enumType.getEnumConstants()) { + map.put(v.getValue(), v); + } + return map; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/IsActive.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/IsActive.java new file mode 100644 index 000000000..4c94619c5 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/IsActive.java @@ -0,0 +1,28 @@ +package eu.eudat.commons.enums; + +import eu.eudat.data.converters.enums.DatabaseEnum; + +import java.util.Map; + +public enum IsActive implements DatabaseEnum { + + Inactive((short)0), + Active( (short)1); + + private final Short value; + + IsActive(Short value) { + this.value = value; + } + + public Short getValue() { + return value; + } + + private static final Map map = EnumUtils.getEnumValueMap(IsActive.class); + + public static IsActive of(Short i) { + return map.get(i); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ProviderType.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ProviderType.java new file mode 100644 index 000000000..cf34c5045 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ProviderType.java @@ -0,0 +1,34 @@ +package eu.eudat.commons.enums; + +import eu.eudat.data.converters.enums.DatabaseEnum; + +import java.util.HashMap; +import java.util.Map; + +public enum ProviderType implements DatabaseEnum { + + Google (1), + Facebook ( 2), + Twitter ( 3), + LinkedIn (4), + NativeLogin ( 5), + B2Access ( 6), + ORCID (7), + OpenAire ( 8), + Configurable ( 9), + Zenodo (10), + Keycloack ( 128); + + private final Integer value; + + ProviderType(Integer value) { + this.value = value; + } + + public Integer getValue() { return this.value; } + + private static final Map map = EnumUtils.getEnumValueMap(ProviderType.class); + public static ProviderType of(Integer i) { + return map.get(i); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/scope/UserScope.java b/dmp-backend/core/src/main/java/eu/eudat/commons/scope/user/UserScope.java similarity index 96% rename from dmp-backend/core/src/main/java/eu/eudat/commons/scope/UserScope.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/scope/user/UserScope.java index 99fd79695..717f85e3d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/scope/UserScope.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/scope/user/UserScope.java @@ -1,4 +1,4 @@ -package eu.eudat.commons.scope; +package eu.eudat.commons.scope.user; import gr.cite.tools.logging.LoggerService; import org.slf4j.LoggerFactory; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/EnumNotNull.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/EnumNotNull.java new file mode 100644 index 000000000..ffa2553b5 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/EnumNotNull.java @@ -0,0 +1,11 @@ +package eu.eudat.commons.validation; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +public class EnumNotNull implements ConstraintValidator { + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { + return value != null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSet.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSet.java new file mode 100644 index 000000000..2b3893879 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSet.java @@ -0,0 +1,22 @@ +package eu.eudat.commons.validation; + + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import java.lang.annotation.*; + +@Constraint( validatedBy = { FieldNotNullIfOtherSetValidator.class } ) +@Documented +@Target( { ElementType.TYPE } ) +@Retention( RetentionPolicy.RUNTIME ) +public @interface FieldNotNullIfOtherSet { + Class[] groups() default {}; + + String notNullField() default "id"; + String otherSetField() default "hash"; + String failOn() default "hash"; + + String message() default "hash is required if id is set"; + + Class[] payload() default {}; +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSetValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSetValidator.java new file mode 100644 index 000000000..1b55849f5 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldNotNullIfOtherSetValidator.java @@ -0,0 +1,35 @@ +package eu.eudat.commons.validation; + +import org.springframework.beans.BeanWrapperImpl; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import java.util.Objects; + +public class FieldNotNullIfOtherSetValidator implements ConstraintValidator { + + private String notNullField; + private String otherSetField; + + @Override + public void initialize(FieldNotNullIfOtherSet constraintAnnotation) { + this.notNullField = constraintAnnotation.notNullField(); + this.otherSetField = constraintAnnotation.otherSetField(); + } + + @Override + public boolean isValid(Object entity, ConstraintValidatorContext context) { + Object notNullValue = new BeanWrapperImpl(entity) + .getPropertyValue(this.notNullField); + Object otherSetValue = new BeanWrapperImpl(entity) + .getPropertyValue(this.otherSetField); + + boolean hashIsString = Objects.equals(new BeanWrapperImpl(entity) + .getPropertyType(this.otherSetField), String.class); + + boolean hashValueEmpty = otherSetValue == null || (hashIsString && ((String)otherSetValue).isBlank()); + + if (notNullValue != null && hashValueEmpty) return false; + return true; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatch.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatch.java new file mode 100644 index 000000000..d08df40d0 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatch.java @@ -0,0 +1,29 @@ +package eu.eudat.commons.validation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Constraint(validatedBy = FieldsValueMatchValidator.class) +@Target({ ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +public @interface FieldsValueMatch { + Class[] groups() default {}; + + String field(); + String fieldMatch(); + String failOn(); + + String message() default "Fields values don't match!"; + + Class[] payload() default {}; + + @Target({ ElementType.TYPE }) + @Retention(RetentionPolicy.RUNTIME) + @interface List { + FieldsValueMatch[] value(); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatchValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatchValidator.java new file mode 100644 index 000000000..1f4691378 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/FieldsValueMatchValidator.java @@ -0,0 +1,31 @@ +package eu.eudat.commons.validation; + +import org.springframework.beans.BeanWrapperImpl; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +public class FieldsValueMatchValidator implements ConstraintValidator { + + private String field; + private String fieldMatch; + + @Override + public void initialize(FieldsValueMatch constraintAnnotation) { + this.field = constraintAnnotation.field(); + this.fieldMatch = constraintAnnotation.fieldMatch(); + } + + @Override + public boolean isValid(Object entity, ConstraintValidatorContext context) { + + Object fieldValue = new BeanWrapperImpl(entity).getPropertyValue(field); + Object fieldMatchValue = new BeanWrapperImpl(entity).getPropertyValue(fieldMatch); + + if (fieldValue != null) { + return fieldValue.equals(fieldMatchValue); + } else { + return fieldMatchValue == null; + } + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidEnum.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidEnum.java new file mode 100644 index 000000000..079f9e64a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidEnum.java @@ -0,0 +1,16 @@ +package eu.eudat.commons.validation; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import java.lang.annotation.*; + + +@Constraint(validatedBy = EnumNotNull.class) +@Documented +@Target({ ElementType.FIELD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface ValidEnum { + String message() default "enum is required"; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidId.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidId.java new file mode 100644 index 000000000..2f470b57b --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidId.java @@ -0,0 +1,18 @@ +package eu.eudat.commons.validation; + + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; +import java.lang.annotation.*; + +@Constraint( validatedBy = { ValidIdValidator.class } ) +@Documented +@Target( { ElementType.FIELD } ) +@Retention( RetentionPolicy.RUNTIME ) +public @interface ValidId { + Class[] groups() default {}; + + String message() default "id set but not valid"; + + Class[] payload() default {}; +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidIdValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidIdValidator.java new file mode 100644 index 000000000..7fce85251 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidIdValidator.java @@ -0,0 +1,40 @@ +package eu.eudat.commons.validation; + +import eu.eudat.convention.ConventionService; +import org.springframework.beans.factory.annotation.Autowired; + +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import java.util.UUID; + +public class ValidIdValidator implements ConstraintValidator { + + @Autowired + private ConventionService conventionService; + + @Override + public void initialize(ValidId constraintAnnotation) { } + + @Override + public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) { + if(o == null) return true; + else if(o instanceof UUID){ + UUID uuidId = (UUID)o; + return this.conventionService.isValidGuid(uuidId); + } + else if(o instanceof Integer){ + Integer intId = (Integer)o; + return this.conventionService.isValidId(intId); + } + else{ + String stringId = o.toString(); + UUID uuidId = null; + try { + uuidId = UUID.fromString(stringId); + }catch (Exception ex){ + return false; + } + return this.conventionService.isValidGuid(uuidId); + } + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationServiceImpl.java index e8c17c407..33cfa570c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/ValidationServiceImpl.java @@ -3,23 +3,20 @@ package eu.eudat.commons.validation; import eu.eudat.errorcode.ErrorThesaurusProperties; import gr.cite.tools.exception.MyValidationException; import gr.cite.tools.validation.BaseValidationService; -import jakarta.validation.Validator; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; +import jakarta.validation.Validator; import java.util.List; import java.util.Map; @Service -@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class ValidationServiceImpl extends BaseValidationService { - private ErrorThesaurusProperties errors; + private final ErrorThesaurusProperties errors; @Autowired - public ValidationServiceImpl(Validator validator, ErrorThesaurusProperties errors){ + public ValidationServiceImpl(Validator validator, ErrorThesaurusProperties errors) { super(validator); this.errors = errors; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Credential.java b/dmp-backend/core/src/main/java/eu/eudat/data/CredentialEntity.java similarity index 67% rename from dmp-backend/data/src/main/java/eu/eudat/data/entities/Credential.java rename to dmp-backend/core/src/main/java/eu/eudat/data/CredentialEntity.java index 8cb4cb96b..8c7686853 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Credential.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/CredentialEntity.java @@ -1,9 +1,13 @@ -package eu.eudat.data.entities; +package eu.eudat.data; +import eu.eudat.commons.enums.ProviderType; +import eu.eudat.commons.enums.IsActive; import eu.eudat.data.converters.DateToUTCConverter; -import eu.eudat.data.entities.helpers.EntityBinder; -import eu.eudat.queryable.queryableentity.DataEntity; +import eu.eudat.data.converters.enums.ProviderTypeConverter; +import eu.eudat.data.converters.enums.IsActiveConverter; +import eu.eudat.data.helpers.EntityBinder; +import eu.eudat.queryable.queryableentity.DataEntity; import jakarta.persistence.*; import java.util.Date; import java.util.List; @@ -12,29 +16,30 @@ import java.util.UUID; @Entity @Table(name = "\"Credential\"") -@NamedEntityGraphs({ - @NamedEntityGraph( - name = "credentialUserInfo", - attributeNodes = {@NamedAttributeNode("userInfo")}) -}) -public class Credential implements DataEntity { +//@NamedEntityGraphs({ +// @NamedEntityGraph( +// name = "credentialUserInfo", +// attributeNodes = {@NamedAttributeNode("userInfo")}) +//}) +public class CredentialEntity implements DataEntity { @Id @Column(name = "\"Id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") private UUID id; public final static String _id = "id"; - @ManyToOne - @JoinColumn(name = "\"UserId\"", nullable = false) - private UserInfo userInfo; - public final static String _userInfo = "userInfo"; //TODO: Authn + @Column(name = "\"UserId\"", columnDefinition = "uuid", nullable = false) + private UUID userId; + public final static String _userId = "userId"; @Column(name = "\"Status\"", nullable = false) - private Integer status; - public final static String _status = "status"; + @Convert(converter = IsActiveConverter.class) + private IsActive isActive; + public final static String _isActive = "isActive"; @Column(name = "\"Provider\"", nullable = false) - private Integer provider; + @Convert(converter = ProviderTypeConverter.class) + private ProviderType provider; public final static String _provider = "provider"; @Column(name = "\"Public\"", nullable = false) @@ -71,27 +76,27 @@ public class Credential implements DataEntity { this.id = id; } - public UserInfo getUserInfo() { - return userInfo; + public UUID getUserId() { + return userId; } - public void setUserInfo(UserInfo userInfo) { - this.userInfo = userInfo; + public void setUserId(UUID userId) { + this.userId = userId; } - public Integer getStatus() { - return status; + public IsActive getIsActive() { + return isActive; } - public void setStatus(Integer status) { - this.status = status; + public void setIsActive(IsActive isActive) { + this.isActive = isActive; } - public Integer getProvider() { + public ProviderType getProvider() { return provider; } - public void setProvider(Integer provider) { + public void setProvider(ProviderType provider) { this.provider = provider; } @@ -148,19 +153,19 @@ public class Credential implements DataEntity { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - Credential that = (Credential) o; + CredentialEntity that = (CredentialEntity) o; - return provider.intValue() == that.provider.intValue(); + return provider.getValue() == that.provider.getValue(); } @Override public int hashCode() { - return provider.intValue(); + return provider.getValue(); } @Override - public void update(Credential entity) { - this.status = entity.status; + public void update(CredentialEntity entity) { + this.isActive = entity.isActive; this.publicValue = entity.getPublicValue(); this.email = entity.getEmail(); this.secret = entity.getSecret(); @@ -173,7 +178,7 @@ public class Credential implements DataEntity { } @Override - public Credential buildFromTuple(List tuple, List fields, String base) { + public CredentialEntity buildFromTuple(List tuple, List fields, String base) { String currentBase = base.isEmpty() ? "" : base + "."; if (fields.contains(currentBase + "id")) this.id = EntityBinder.fromTuple(tuple, currentBase + "id"); return this; diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/DescriptionTemplateTypeEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/DescriptionTemplateTypeEntity.java index 2abf17f9e..bf584c74d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/DescriptionTemplateTypeEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/DescriptionTemplateTypeEntity.java @@ -1,31 +1,45 @@ package eu.eudat.data; +import eu.eudat.commons.enums.DescriptionTemplateTypeStatus; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.converters.enums.DescriptionTemplateTypeStatusConverter; +import eu.eudat.data.converters.enums.IsActiveConverter; import jakarta.persistence.*; -import org.hibernate.annotations.GenericGenerator; +import java.time.Instant; import java.util.UUID; @Entity @Table(name = "\"DescriptionTemplateType\"") -public class DescriptionTemplateTypeEntity implements BaseEntity { +public class DescriptionTemplateTypeEntity { @Id - @GeneratedValue - @GenericGenerator(name = "uuid2", strategy = "uuid2") - @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + @Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false) private UUID id; + public final static String _id = "id"; - public static final String _id = "id"; - - @Column(name = "\"Name\"", nullable = false) + @Column(name = "name", length = 500, nullable = false) private String name; + public final static String _name = "name"; - public static final String _name = "name"; + @Column(name = "created_at", nullable = false) + private Instant createdAt; + public final static String _createdAt = "createdAt"; - @Column(name = "\"Status\"", nullable = false) - private Short status; + @Column(name = "updated_at", nullable = false) + private Instant updatedAt; + public final static String _updatedAt = "updatedAt"; + + @Column(name = "is_active", nullable = false) + @Convert(converter = IsActiveConverter.class) + private IsActive isActive; + public final static String _isActive = "isActive"; + + @Column(name = "status", nullable = false) + @Convert(converter = DescriptionTemplateTypeStatusConverter.class) + private DescriptionTemplateTypeStatus status; + public final static String _status = "status"; - public static final String _status = "status"; public UUID getId() { return id; @@ -43,12 +57,35 @@ public class DescriptionTemplateTypeEntity implements BaseEntity { this.name = name; } - public Short getStatus() { + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } + + public DescriptionTemplateTypeStatus getStatus() { return status; } - public void setStatus(Short status) { + public void setStatus(DescriptionTemplateTypeStatus status) { this.status = status; } - } diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/DateToUTCConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/DateToUTCConverter.java new file mode 100644 index 000000000..d261435d6 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/DateToUTCConverter.java @@ -0,0 +1,48 @@ +package eu.eudat.data.converters; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +/** + * Created by ikalyvas on 9/25/2018. + */ +@Converter +public class DateToUTCConverter implements AttributeConverter { + private static final Logger logger = LoggerFactory.getLogger(DateToUTCConverter.class); + + @Override + public Date convertToDatabaseColumn(Date attribute) { + if(attribute == null) return null; + DateFormat formatterIST = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + formatterIST.setTimeZone(TimeZone.getTimeZone("UTC")); + try { + String date = formatterIST.format(attribute); + return formatterIST.parse(date); + } catch (ParseException e) { + logger.error(e.getMessage(), e); + } + return null; + } + + @Override + public Date convertToEntityAttribute(Date dbData) { + if(dbData == null) return null; + DateFormat formatterIST = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + formatterIST.setTimeZone(TimeZone.getTimeZone("UTC")); + try { + String date = formatterIST.format(dbData); + return formatterIST.parse(date); + } catch (ParseException e) { + logger.error(e.getMessage(), e); + } + return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnum.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnum.java new file mode 100644 index 000000000..aae8e87b1 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnum.java @@ -0,0 +1,5 @@ +package eu.eudat.data.converters.enums; + +public interface DatabaseEnum { + T getValue(); +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnumConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnumConverter.java new file mode 100644 index 000000000..158ddce6f --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnumConverter.java @@ -0,0 +1,21 @@ +package eu.eudat.data.converters.enums; + +import eu.eudat.commons.enums.ProviderType; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter +public abstract class DatabaseEnumConverter, T> implements AttributeConverter { + protected abstract EnumType of(T dbData); + + @Override + public T convertToDatabaseColumn(EnumType value) { + if (value == null) throw new IllegalArgumentException("value"); + return value.getValue(); + } + + @Override + public EnumType convertToEntityAttribute(T dbData) { + return this.of(dbData); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DescriptionTemplateTypeStatusConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DescriptionTemplateTypeStatusConverter.java new file mode 100644 index 000000000..cc132124f --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DescriptionTemplateTypeStatusConverter.java @@ -0,0 +1,12 @@ +package eu.eudat.data.converters.enums; + +import eu.eudat.commons.enums.DescriptionTemplateTypeStatus; +import eu.eudat.commons.enums.IsActive; +import jakarta.persistence.Converter; + +@Converter +public class DescriptionTemplateTypeStatusConverter extends DatabaseEnumConverter { + public DescriptionTemplateTypeStatus of(Short i) { + return DescriptionTemplateTypeStatus.of(i); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/IsActiveConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/IsActiveConverter.java new file mode 100644 index 000000000..b88b7f22b --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/IsActiveConverter.java @@ -0,0 +1,11 @@ +package eu.eudat.data.converters.enums; + +import eu.eudat.commons.enums.IsActive; +import jakarta.persistence.Converter; + +@Converter +public class IsActiveConverter extends DatabaseEnumConverter { + public IsActive of(Short i) { + return IsActive.of(i); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/ProviderTypeConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/ProviderTypeConverter.java new file mode 100644 index 000000000..1cc1d121b --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/ProviderTypeConverter.java @@ -0,0 +1,15 @@ +package eu.eudat.data.converters.enums; + +import eu.eudat.commons.enums.ProviderType; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +import java.util.HashMap; +import java.util.Map; + +@Converter +public class ProviderTypeConverter extends DatabaseEnumConverter { + public ProviderType of(Integer i) { + return ProviderType.of(i); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/helpers/EntityBinder.java b/dmp-backend/core/src/main/java/eu/eudat/data/helpers/EntityBinder.java new file mode 100644 index 000000000..39c921317 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/helpers/EntityBinder.java @@ -0,0 +1,15 @@ +package eu.eudat.data.helpers; + +import jakarta.persistence.Tuple; + +import java.util.List; + +public class EntityBinder { + public static T fromTuple(List tuple, String path) { + try { + return (T) tuple.get(0).get(path); + }catch (IllegalArgumentException illegalArgument){ + return null; + } + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/event/DescriptionTemplateTypeTouchedEvent.java b/dmp-backend/core/src/main/java/eu/eudat/event/DescriptionTemplateTypeTouchedEvent.java new file mode 100644 index 000000000..7b2107993 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/event/DescriptionTemplateTypeTouchedEvent.java @@ -0,0 +1,22 @@ +package eu.eudat.event; + +import java.util.UUID; + +public class DescriptionTemplateTypeTouchedEvent { + public DescriptionTemplateTypeTouchedEvent() { + } + + public DescriptionTemplateTypeTouchedEvent(UUID id) { + this.id = id; + } + + private UUID id; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java b/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java new file mode 100644 index 000000000..c8fca7df1 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/event/EventBroker.java @@ -0,0 +1,40 @@ +package eu.eudat.event; + +import gr.cite.commons.web.oidc.apikey.events.ApiKeyStaleEvent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.stereotype.Service; + +@Service +public class EventBroker { + @Autowired + private ApplicationEventPublisher applicationEventPublisher; + + public void emitApiKeyStale(String apiKey) { + this.applicationEventPublisher.publishEvent(new ApiKeyStaleEvent(apiKey)); + } + + public void emit(ApiKeyStaleEvent event) { + this.applicationEventPublisher.publishEvent(event); + } + + public void emit(TenantTouchedEvent event) { + this.applicationEventPublisher.publishEvent(event); + } + + public void emit(UserTouchedEvent event) { + this.applicationEventPublisher.publishEvent(event); + } + + public void emit(UserAddedToTenantEvent event) { + this.applicationEventPublisher.publishEvent(event); + } + + public void emit(UserRemovedFromTenantEvent event) { + this.applicationEventPublisher.publishEvent(event); + } + + public void emit(DescriptionTemplateTypeTouchedEvent event) { + this.applicationEventPublisher.publishEvent(event); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/event/TenantTouchedEvent.java b/dmp-backend/core/src/main/java/eu/eudat/event/TenantTouchedEvent.java new file mode 100644 index 000000000..52c3b0775 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/event/TenantTouchedEvent.java @@ -0,0 +1,42 @@ +package eu.eudat.event; + +import java.util.UUID; + +public class TenantTouchedEvent { + public TenantTouchedEvent() { + } + + public TenantTouchedEvent(UUID tenantId, String tenantCode, String previousTenantCode) { + this.tenantId = tenantId; + this.tenantCode = tenantCode; + this.previousTenantCode = previousTenantCode; + } + + private UUID tenantId; + private String tenantCode; + private String previousTenantCode; + + public UUID getTenantId() { + return tenantId; + } + + public void setTenantId(UUID tenantId) { + this.tenantId = tenantId; + } + + public String getTenantCode() { + return tenantCode; + } + + public void setTenantCode(String tenantCode) { + this.tenantCode = tenantCode; + } + + public String getPreviousTenantCode() { + return previousTenantCode; + } + + public void setPreviousTenantCode(String previousTenantCode) { + this.previousTenantCode = previousTenantCode; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/event/UserAddedToTenantEvent.java b/dmp-backend/core/src/main/java/eu/eudat/event/UserAddedToTenantEvent.java new file mode 100644 index 000000000..9d1e255bb --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/event/UserAddedToTenantEvent.java @@ -0,0 +1,32 @@ +package eu.eudat.event; + +import java.util.UUID; + +public class UserAddedToTenantEvent { + public UserAddedToTenantEvent() { + } + + public UserAddedToTenantEvent(UUID userId, UUID tenantId) { + this.userId = userId; + this.tenantId = tenantId; + } + + private UUID userId; + private UUID tenantId; + + public UUID getUserId() { + return userId; + } + + public void setUserId(UUID userId) { + this.userId = userId; + } + + public UUID getTenantId() { + return tenantId; + } + + public void setTenantId(UUID tenantId) { + this.tenantId = tenantId; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/event/UserRemovedFromTenantEvent.java b/dmp-backend/core/src/main/java/eu/eudat/event/UserRemovedFromTenantEvent.java new file mode 100644 index 000000000..1fe6b3ab1 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/event/UserRemovedFromTenantEvent.java @@ -0,0 +1,32 @@ +package eu.eudat.event; + +import java.util.UUID; + +public class UserRemovedFromTenantEvent { + public UserRemovedFromTenantEvent() { + } + + public UserRemovedFromTenantEvent(UUID userId, UUID tenantId) { + this.userId = userId; + this.tenantId = tenantId; + } + + private UUID userId; + private UUID tenantId; + + public UUID getUserId() { + return userId; + } + + public void setUserId(UUID userId) { + this.userId = userId; + } + + public UUID getTenantId() { + return tenantId; + } + + public void setTenantId(UUID tenantId) { + this.tenantId = tenantId; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/event/UserTouchedEvent.java b/dmp-backend/core/src/main/java/eu/eudat/event/UserTouchedEvent.java new file mode 100644 index 000000000..b22e5ba0a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/event/UserTouchedEvent.java @@ -0,0 +1,42 @@ +package eu.eudat.event; + +import java.util.UUID; + +public class UserTouchedEvent { + public UserTouchedEvent() { + } + + public UserTouchedEvent(UUID userId, String subjectId, String previousSubjectId) { + this.userId = userId; + this.subjectId = subjectId; + this.previousSubjectId = previousSubjectId; + } + + private UUID userId; + private String subjectId; + private String previousSubjectId; + + public UUID getUserId() { + return userId; + } + + public void setUserId(UUID userId) { + this.userId = userId; + } + + public String getSubjectId() { + return subjectId; + } + + public void setSubjectId(String subjectId) { + this.subjectId = subjectId; + } + + public String getPreviousSubjectId() { + return previousSubjectId; + } + + public void setPreviousSubjectId(String previousSubjectId) { + this.previousSubjectId = previousSubjectId; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/DescriptionTemplateType.java b/dmp-backend/core/src/main/java/eu/eudat/model/DescriptionTemplateType.java index c5fd4a351..e2a1d92b3 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/DescriptionTemplateType.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/DescriptionTemplateType.java @@ -1,17 +1,33 @@ package eu.eudat.model; -import com.fasterxml.jackson.annotation.JsonInclude; +import eu.eudat.commons.enums.DescriptionTemplateTypeStatus; +import eu.eudat.commons.enums.IsActive; +import java.time.Instant; import java.util.UUID; -@JsonInclude(JsonInclude.Include.NON_NULL) public class DescriptionTemplateType { + public final static String _id = "id"; private UUID id; + public final static String _name = "name"; private String name; - private Short status; + public final static String _createdAt = "createdAt"; + private Instant createdAt; + + public final static String _updatedAt = "updatedAt"; + private Instant updatedAt; + + public final static String _isActive = "isActive"; + private IsActive isActive; + + public final static String _status = "status"; + private DescriptionTemplateTypeStatus status; + + public final static String _hash = "hash"; + private String hash; public UUID getId() { return id; @@ -29,12 +45,43 @@ public class DescriptionTemplateType { this.name = name; } - public Short getStatus() { + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } + + public IsActive getIsActive() { + return isActive; + } + + public void setIsActive(IsActive isActive) { + this.isActive = isActive; + } + + public DescriptionTemplateTypeStatus getStatus() { return status; } - public void setStatus(Short status) { + public void setStatus(DescriptionTemplateTypeStatus status) { this.status = status; } + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/BaseBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/BaseBuilder.java index c91948d76..1d961a033 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/BaseBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/BaseBuilder.java @@ -3,6 +3,7 @@ package eu.eudat.model.builder; import eu.eudat.convention.ConventionService; import gr.cite.tools.data.builder.Builder; import gr.cite.tools.data.query.QueryBase; +import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; @@ -12,9 +13,7 @@ import java.util.function.Function; import java.util.stream.Collectors; public abstract class BaseBuilder implements Builder { - protected final LoggerService logger; - protected final ConventionService conventionService; public BaseBuilder( @@ -25,55 +24,49 @@ public abstract class BaseBuilder implements Builder { this.logger = logger; } - public M build(FieldSet directives, D data) { + public M build(FieldSet directives, D data) throws MyApplicationException { if (data == null) { - return null; + //this.logger.Debug(new MapLogEntry("requested build for null item requesting fields").And("fields", directives)); +// return default(M); + M model = null; + return null; //TODO } - List models = this.build(directives == null ? getFullFieldSet() : directives, List.of(data)); - return models.stream().findFirst().orElse(null); + List models = this.build(directives, Arrays.asList(data)); + return models.stream().findFirst().orElse(null); //TODO } - public abstract List build(FieldSet directives, List data); + public abstract List build(FieldSet directives, List datas) throws MyApplicationException; - /** - * Provides all the fields that can be projected on the entity listings associated with this builder - * - * @return The field set - */ - public abstract FieldSet getFullFieldSet(); - - public Map asForeignKey(QueryBase query, FieldSet directives, Function keySelector) { + public Map asForeignKey(QueryBase query, FieldSet directives, Function keySelector) throws MyApplicationException { this.logger.trace("Building references from query"); - List data = query.collectAs(directives); - this.logger.trace("collected {} items to build", Optional.ofNullable(data).map(List::size).orElse(0)); - return this.asForeignKey(data, directives, keySelector); + List datas = query.collectAs(directives); + this.logger.debug("collected {} items to build", Optional.ofNullable(datas).map(e -> e.size()).orElse(0)); + return this.asForeignKey(datas, directives, keySelector); } - public Map asForeignKey(List data, FieldSet directives, Function keySelector) { + public Map asForeignKey(List datas, FieldSet directives, Function keySelector) throws MyApplicationException { this.logger.trace("building references"); - List models = this.build(directives, data); - this.logger.trace("mapping {} build items from {} requested", Optional.ofNullable(models).map(List::size).orElse(0), Optional.ofNullable(data).map(List::size).orElse(0)); - assert models != null; - return models.stream().collect(Collectors.toMap(keySelector, o -> o)); + List models = this.build(directives, datas); + this.logger.debug("mapping {} build items from {} requested", Optional.ofNullable(models).map(e -> e.size()).orElse(0), Optional.ofNullable(datas).map(e -> e.size()).orElse(0)); + Map map = models.stream().collect(Collectors.toMap(o -> keySelector.apply(o), o -> o)); + return map; } - public Map> asMasterKey(QueryBase query, FieldSet directives, Function keySelector) { + public Map> asMasterKey(QueryBase query, FieldSet directives, Function keySelector) throws MyApplicationException { this.logger.trace("Building details from query"); - List data = query.collectAs(directives); - this.logger.trace("collected {} items to build", Optional.ofNullable(data).map(List::size).orElse(0)); - return this.asMasterKey(data, directives, keySelector); + List datas = query.collectAs(directives); + this.logger.debug("collected {} items to build", Optional.ofNullable(datas).map(e -> e.size()).orElse(0)); + return this.asMasterKey(datas, directives, keySelector); } - public Map> asMasterKey(List data, FieldSet directives, Function keySelector) { + public Map> asMasterKey(List datas, FieldSet directives, Function keySelector) throws MyApplicationException { this.logger.trace("building details"); - List models = this.build(directives, data); - this.logger.trace("mapping {} build items from {} requested", Optional.ofNullable(models).map(List::size).orElse(0), Optional.ofNullable(data).map(List::size).orElse(0)); + List models = this.build(directives, datas); + this.logger.debug("mapping {} build items from {} requested", Optional.ofNullable(models).map(e -> e.size()).orElse(0), Optional.ofNullable(datas).map(e -> e.size()).orElse(0)); Map> map = new HashMap<>(); - assert models != null; for (M model : models) { K key = keySelector.apply(model); - if (!map.containsKey(key)) - map.put(key, new ArrayList()); + if (!map.containsKey(key)) map.put(key, new ArrayList()); map.get(key).add(model); } return map; @@ -81,12 +74,13 @@ public abstract class BaseBuilder implements Builder { public Map asEmpty(List keys, Function mapper, Function keySelector) { this.logger.trace("building static references"); - List models = keys.stream().map(mapper).collect(Collectors.toList()); - this.logger.trace("mapping {} build items from {} requested", Optional.of(models).map(List::size).orElse(0), Optional.of(keys).map(List::size)); - return models.stream().collect(Collectors.toMap(keySelector, o -> o)); + List models = keys.stream().map(x -> mapper.apply(x)).collect(Collectors.toList()); + this.logger.debug("mapping {} build items from {} requested", Optional.ofNullable(models).map(x -> x.size()).orElse(0), Optional.ofNullable(keys).map(x -> x.size())); + Map map = models.stream().collect(Collectors.toMap(o -> keySelector.apply(o), o -> o)); + return map; } - protected String hashValue(Instant value) { + protected String hashValue(Instant value) throws MyApplicationException { return this.conventionService.hashValue(value); } @@ -99,3 +93,4 @@ public abstract class BaseBuilder implements Builder { } } + diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/DescriptionTemplateTypeBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/DescriptionTemplateTypeBuilder.java index edafeb799..044703435 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/DescriptionTemplateTypeBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/DescriptionTemplateTypeBuilder.java @@ -1,56 +1,62 @@ package eu.eudat.model.builder; +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.JsonHandlingService; import eu.eudat.convention.ConventionService; import eu.eudat.data.DescriptionTemplateTypeEntity; import eu.eudat.model.DescriptionTemplateType; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; import gr.cite.tools.logging.LoggerService; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.stream.Collectors; @Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class DescriptionTemplateTypeBuilder extends BaseBuilder { - public DescriptionTemplateTypeBuilder(ConventionService conventionService) { + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + @Autowired + public DescriptionTemplateTypeBuilder( + ConventionService conventionService) { super(conventionService, new LoggerService(LoggerFactory.getLogger(DescriptionTemplateTypeBuilder.class))); } + public DescriptionTemplateTypeBuilder authorize(EnumSet values) { + this.authorize = values; + return this; + } + @Override - public List build(FieldSet directives, List data) { - if (directives == null || directives.isEmpty()) - return new ArrayList<>(); + public List build(FieldSet fields, List datas) throws MyApplicationException { + this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(datas).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0)); + this.logger.trace(new DataLogEntry("requested fields", fields)); + if (fields == null || datas == null || fields.isEmpty()) return new ArrayList<>(); - List models = new ArrayList<>(100); - - if (data == null) - return models; - for (DescriptionTemplateTypeEntity d : data) { + List models = new ArrayList<>(); + for (DescriptionTemplateTypeEntity d : datas) { DescriptionTemplateType m = new DescriptionTemplateType(); - if (directives.hasField(this.asIndexer(DescriptionTemplateTypeEntity._id))) - m.setId(d.getId()); - if (directives.hasField(this.asIndexer(DescriptionTemplateTypeEntity._name))) - m.setName(d.getName()); - if (directives.hasField(this.asIndexer(DescriptionTemplateTypeEntity._status))) - m.setStatus(d.getStatus()); + if (fields.hasField(this.asIndexer(DescriptionTemplateType._id))) m.setId(d.getId()); + if (fields.hasField(this.asIndexer(DescriptionTemplateType._name))) m.setName(d.getName()); + if (fields.hasField(this.asIndexer(DescriptionTemplateType._createdAt))) m.setCreatedAt(d.getCreatedAt()); + if (fields.hasField(this.asIndexer(DescriptionTemplateType._updatedAt))) m.setUpdatedAt(d.getUpdatedAt()); + if (fields.hasField(this.asIndexer(DescriptionTemplateType._isActive))) m.setIsActive(d.getIsActive()); + if (fields.hasField(this.asIndexer(DescriptionTemplateType._status))) m.setStatus(d.getStatus()); + if (fields.hasField(this.asIndexer(DescriptionTemplateType._hash))) m.setHash(this.hashValue(d.getUpdatedAt())); models.add(m); } - + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); return models; } - - @Override - public FieldSet getFullFieldSet() { - BaseFieldSet fieldSet = new BaseFieldSet(); - fieldSet.setFields(Set.of( - DescriptionTemplateTypeEntity._id, - DescriptionTemplateTypeEntity._name, - DescriptionTemplateTypeEntity._status - )); - return fieldSet; - } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DescriptionTemplateTypeCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DescriptionTemplateTypeCensor.java index 1b621ae12..b941be7e2 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DescriptionTemplateTypeCensor.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/DescriptionTemplateTypeCensor.java @@ -1,6 +1,8 @@ package eu.eudat.model.censorship; +import eu.eudat.authorization.Permission; import eu.eudat.convention.ConventionService; +import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.DataLogEntry; import gr.cite.tools.logging.LoggerService; @@ -9,20 +11,24 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import java.util.UUID; + @Component @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class DescriptionTemplateTypeCensor extends BaseCensor{ private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateTypeCensor.class)); - - public DescriptionTemplateTypeCensor(ConventionService conventionService) { + protected final AuthorizationService authService; + public DescriptionTemplateTypeCensor(ConventionService conventionService, AuthorizationService authService) { super(conventionService); + this.authService = authService; } - public void censor(FieldSet fields) { + public void censor(FieldSet fields, UUID userId) { logger.debug(new DataLogEntry("censoring fields", fields)); - if (fields.isEmpty()) - return; + if (fields.isEmpty()) return; + + this.authService.authorizeForce(Permission.BrowseDescriptionTemplateType); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DescriptionTemplateTypeDeleter.java b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DescriptionTemplateTypeDeleter.java new file mode 100644 index 000000000..068a2b94a --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/DescriptionTemplateTypeDeleter.java @@ -0,0 +1,76 @@ +package eu.eudat.model.deleter; + +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.DescriptionTemplateTypeEntity; +import eu.eudat.query.DescriptionTemplateTypeQuery; +import gr.cite.tools.data.deleter.Deleter; +import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.management.InvalidApplicationException; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DescriptionTemplateTypeDeleter implements Deleter { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateTypeDeleter.class)); + + private final EntityManager entityManager; + protected final QueryFactory queryFactory; + protected final DeleterFactory deleterFactory; + + @Autowired + public DescriptionTemplateTypeDeleter( + EntityManager entityManager, + QueryFactory queryFactory, + DeleterFactory deleterFactory + ) { + this.entityManager = entityManager; + this.queryFactory = queryFactory; + this.deleterFactory = deleterFactory; + } + + public void deleteAndSaveByIds(List ids) throws InvalidApplicationException { + logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids)); + List data = this.queryFactory.query(DescriptionTemplateTypeQuery.class).ids(ids).collect(); + logger.trace("retrieved {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.deleteAndSave(data); + } + + public void deleteAndSave(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.delete(data); + logger.trace("saving changes"); + this.entityManager.flush(); + logger.trace("changes saved"); + } + + public void delete(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + if (data == null || data.isEmpty()) return; + + Instant now = Instant.now(); + + for (DescriptionTemplateTypeEntity item : data) { + logger.trace("deleting item {}", item.getId()); + item.setIsActive(IsActive.Inactive); + item.setUpdatedAt(now); + logger.trace("updating item"); + this.entityManager.merge(item); + logger.trace("updated item"); + } + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java new file mode 100644 index 000000000..2c0c24df8 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java @@ -0,0 +1,61 @@ +package eu.eudat.model.persist; + + +import eu.eudat.commons.enums.DescriptionTemplateTypeStatus; +import eu.eudat.commons.validation.FieldNotNullIfOtherSet; +import eu.eudat.commons.validation.ValidId; + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.util.UUID; + +@FieldNotNullIfOtherSet(message = "{validation.hashempty}") +public class DescriptionTemplateTypePersist { + + @ValidId(message = "{validation.invalidid}") + private UUID id; + + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + @Size(max = 500, message = "{validation.largerthanmax}") + private String name; + + private String hash; + + @NotNull(message = "{validation.empty}") + private DescriptionTemplateTypeStatus status; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getHash() { + return hash; + } + + public void setHash(String hash) { + this.hash = hash; + } + + public DescriptionTemplateTypeStatus getStatus() { + return status; + } + + public void setStatus(DescriptionTemplateTypeStatus status) { + this.status = status; + } +} + diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/CredentialQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/CredentialQuery.java new file mode 100644 index 000000000..9c214e4ae --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/query/CredentialQuery.java @@ -0,0 +1,125 @@ +package eu.eudat.query; + +import eu.eudat.data.CredentialEntity; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.data.query.QueryBase; +import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.Tuple; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Predicate; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class CredentialQuery extends QueryBase { + + private Collection ids; + + private Collection userIds; + + private Collection statuses; + + public CredentialQuery ids(UUID value) { + this.ids = List.of(value); + return this; + } + + public CredentialQuery ids(UUID... value) { + this.ids = Arrays.asList(value); + return this; + } + + public CredentialQuery ids(List value) { + this.ids = value; + return this; + } + + + public CredentialQuery userIds(UUID value) { + this.userIds = List.of(value); + return this; + } + + public CredentialQuery userIds(UUID... value) { + this.userIds = Arrays.asList(value); + return this; + } + + public CredentialQuery userIds(List value) { + this.userIds = value; + return this; + } + + public CredentialQuery statuses(Short value) { + this.statuses = List.of(value); + return this; + } + + public CredentialQuery statuses(Short... value) { + this.statuses = Arrays.asList(value); + return this; + } + + public CredentialQuery statuses(List value) { + this.statuses = value; + return this; + } + + @Override + protected Boolean isFalseQuery() { + return this.isEmpty(this.ids) || this.isEmpty(this.userIds) || this.isEmpty(this.statuses); + } + + @Override + protected Class entityClass() { + return CredentialEntity.class; + } + + @Override + protected Predicate applyFilters(QueryContext queryContext) { + List predicates = new ArrayList<>(); + + if (this.ids != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(CredentialEntity._id)); + for (UUID item : this.ids) + inClause.value(item); + predicates.add(inClause); + } + + if (this.userIds != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(CredentialEntity._userId)); + for (UUID item : this.userIds) + inClause.value(item); + predicates.add(inClause); + } + + if (this.statuses != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(CredentialEntity._isActive)); + for (Short item : this.statuses) + inClause.value(item); + predicates.add(inClause); + } + + if (!predicates.isEmpty()) { + Predicate[] predicatesArray = predicates.toArray(new Predicate[0]); + return queryContext.CriteriaBuilder.and(predicatesArray); + } else { + return queryContext.CriteriaBuilder.and(); + } + } + + @Override + protected String fieldNameOf(FieldResolver item) { + return null; + } + + @Override + protected CredentialEntity convert(Tuple tuple, Set columns) { + return null; + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionTemplateTypeQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionTemplateTypeQuery.java index 48131e628..13dbec3ad 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionTemplateTypeQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionTemplateTypeQuery.java @@ -1,6 +1,12 @@ package eu.eudat.query; +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.enums.DescriptionTemplateTypeStatus; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.scope.user.UserScope; import eu.eudat.data.DescriptionTemplateTypeEntity; +import eu.eudat.model.DescriptionTemplateType; +import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.query.FieldResolver; import gr.cite.tools.data.query.QueryBase; import gr.cite.tools.data.query.QueryContext; @@ -11,17 +17,24 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import java.time.Instant; import java.util.*; @Component @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class DescriptionTemplateTypeQuery extends QueryBase { + private String like; private Collection ids; + private Collection isActives; + private Collection statuses; + private Collection excludedIds; + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); - private Collection names; - - private Collection statuses; + public DescriptionTemplateTypeQuery like(String value) { + this.like = value; + return this; + } public DescriptionTemplateTypeQuery ids(UUID value) { this.ids = List.of(value); @@ -33,44 +46,70 @@ public class DescriptionTemplateTypeQuery extends QueryBase value) { - this.ids = value; + public DescriptionTemplateTypeQuery ids(Collection values) { + this.ids = values; return this; } - public DescriptionTemplateTypeQuery names(String value) { - this.names = List.of(value); + public DescriptionTemplateTypeQuery isActive(IsActive value) { + this.isActives = List.of(value); return this; } - public DescriptionTemplateTypeQuery names(String... value) { - this.names = Arrays.asList(value); + public DescriptionTemplateTypeQuery isActive(IsActive... value) { + this.isActives = Arrays.asList(value); return this; } - public DescriptionTemplateTypeQuery names(List value) { - this.names = value; + public DescriptionTemplateTypeQuery isActive(Collection values) { + this.isActives = values; return this; } - public DescriptionTemplateTypeQuery statuses(Short value) { + public DescriptionTemplateTypeQuery statuses(DescriptionTemplateTypeStatus value) { this.statuses = List.of(value); return this; } - public DescriptionTemplateTypeQuery statuses(Short... value) { + public DescriptionTemplateTypeQuery statuses(DescriptionTemplateTypeStatus... value) { this.statuses = Arrays.asList(value); return this; } - public DescriptionTemplateTypeQuery statuses(List value) { - this.statuses = value; + public DescriptionTemplateTypeQuery statuses(Collection values) { + this.statuses = values; return this; } - @Override - protected Boolean isFalseQuery() { - return Boolean.FALSE; + public DescriptionTemplateTypeQuery excludedIds(Collection values) { + this.excludedIds = values; + return this; + } + + public DescriptionTemplateTypeQuery excludedIds(UUID value) { + this.excludedIds = List.of(value); + return this; + } + + public DescriptionTemplateTypeQuery excludedIds(UUID... value) { + this.excludedIds = Arrays.asList(value); + return this; + } + + public DescriptionTemplateTypeQuery authorize(EnumSet values) { + this.authorize = values; + return this; + } + + private final UserScope userScope; + private final AuthorizationService authService; + + public DescriptionTemplateTypeQuery( + UserScope userScope, + AuthorizationService authService + ) { + this.userScope = userScope; + this.authService = authService; } @Override @@ -78,47 +117,67 @@ public class DescriptionTemplateTypeQuery extends QueryBase Predicate applyFilters(QueryContext queryContext) { List predicates = new ArrayList<>(); - if (this.ids != null) { CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionTemplateTypeEntity._id)); - for (UUID item : this.ids) - inClause.value(item); + for (UUID item : this.ids) inClause.value(item); predicates.add(inClause); } - - if (this.names != null) { - CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionTemplateTypeEntity._name)); - for (String item : this.names) - inClause.value(item); + if (this.like != null && !this.like.isEmpty()) { + predicates.add(queryContext.CriteriaBuilder.like(queryContext.Root.get(DescriptionTemplateTypeEntity._name), this.like)); + } + if (this.isActives != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionTemplateTypeEntity._isActive)); + for (IsActive item : this.isActives) inClause.value(item); predicates.add(inClause); } if (this.statuses != null) { - CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionTemplateTypeEntity._status)); - for (Short item : this.statuses) - inClause.value(item); + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionTemplateTypeEntity._status)); + for (DescriptionTemplateTypeStatus item : this.statuses) inClause.value(item); predicates.add(inClause); } - - if (!predicates.isEmpty()) { + if (this.excludedIds != null) { + CriteriaBuilder.In notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionTemplateTypeEntity._id)); + for (UUID item : this.excludedIds) notInClause.value(item); + predicates.add(notInClause.not()); + } + if (predicates.size() > 0) { Predicate[] predicatesArray = predicates.toArray(new Predicate[0]); return queryContext.CriteriaBuilder.and(predicatesArray); } else { - return queryContext.CriteriaBuilder.and(); + return null; } } - @Override - protected String fieldNameOf(FieldResolver item) { - return null; - } - @Override protected DescriptionTemplateTypeEntity convert(Tuple tuple, Set columns) { - return null; + DescriptionTemplateTypeEntity item = new DescriptionTemplateTypeEntity(); + item.setId(QueryBase.convertSafe(tuple, columns, DescriptionTemplateTypeEntity._id, UUID.class)); + item.setName(QueryBase.convertSafe(tuple, columns, DescriptionTemplateTypeEntity._name, String.class)); + item.setCreatedAt(QueryBase.convertSafe(tuple, columns, DescriptionTemplateTypeEntity._createdAt, Instant.class)); + item.setUpdatedAt(QueryBase.convertSafe(tuple, columns, DescriptionTemplateTypeEntity._updatedAt, Instant.class)); + item.setIsActive(QueryBase.convertSafe(tuple, columns, DescriptionTemplateTypeEntity._isActive, IsActive.class)); + item.setStatus(QueryBase.convertSafe(tuple, columns, DescriptionTemplateTypeEntity._status, DescriptionTemplateTypeStatus.class)); + return item; + } + + @Override + protected String fieldNameOf(FieldResolver item) { + if (item.match(DescriptionTemplateType._id)) return DescriptionTemplateType._id; + else if (item.match(DescriptionTemplateType._name)) return DescriptionTemplateType._name; + else if (item.match(DescriptionTemplateType._createdAt)) return DescriptionTemplateType._createdAt; + else if (item.match(DescriptionTemplateType._updatedAt)) return DescriptionTemplateType._updatedAt; + else if (item.match(DescriptionTemplateType._isActive)) return DescriptionTemplateType._isActive; + else if (item.match(DescriptionTemplateType._status)) return DescriptionTemplateType._status; + else return null; } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DescriptionTemplateTypeLookup.java b/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DescriptionTemplateTypeLookup.java index 3fcd57ad0..26192428a 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DescriptionTemplateTypeLookup.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/lookup/DescriptionTemplateTypeLookup.java @@ -1,37 +1,63 @@ package eu.eudat.query.lookup; +import eu.eudat.commons.enums.DescriptionTemplateTypeStatus; +import eu.eudat.commons.enums.IsActive; import eu.eudat.query.DescriptionTemplateTypeQuery; import gr.cite.tools.data.query.Lookup; import gr.cite.tools.data.query.QueryFactory; +import java.util.List; +import java.util.UUID; + public class DescriptionTemplateTypeLookup extends Lookup { - private String name; + private String like; + private List isActive; + private List statuses; + private List ids; + private List excludedIds; - private Short status; - - public String getName() { - return name; + public String getLike() { + return like; } - public void setName(String name) { - this.name = name; + public void setLike(String like) { + this.like = like; } - public Short getStatus() { - return status; + public List getIsActive() { + return isActive; } - public void setStatus(Short status) { - this.status = status; + public void setIsActive(List isActive) { + this.isActive = isActive; + } + + public List getIds() { + return ids; + } + + public void setIds(List ids) { + this.ids = ids; + } + + public List getExcludedIds() { + return excludedIds; + } + + public void setExcludedIds(List excludeIds) { + this.excludedIds = excludeIds; } public DescriptionTemplateTypeQuery enrich(QueryFactory queryFactory) { DescriptionTemplateTypeQuery query = queryFactory.query(DescriptionTemplateTypeQuery.class); - if (name != null) query.names(name); - if (status != null ) query.statuses(status); + if (this.like != null) query.like(this.like); + if (this.isActive != null) query.isActive(this.isActive); + if (this.statuses != null) query.statuses(this.statuses); + if (this.ids != null) query.ids(this.ids); + if (this.excludedIds != null) query.excludedIds(this.excludedIds); - enrichCommon(query); + this.enrichCommon(query); return query; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/DescriptionTemplateTypeService.java b/dmp-backend/core/src/main/java/eu/eudat/service/DescriptionTemplateTypeService.java index 90e52d0bd..35b8473b2 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/DescriptionTemplateTypeService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/DescriptionTemplateTypeService.java @@ -1,116 +1,18 @@ package eu.eudat.service; -import eu.eudat.commons.enums.DescriptionTemplateTypeStatus; -import eu.eudat.data.DescriptionTemplateTypeEntity; import eu.eudat.model.DescriptionTemplateType; -import eu.eudat.model.builder.DescriptionTemplateTypeBuilder; -import eu.eudat.query.DescriptionTemplateTypeQuery; -import eu.eudat.query.lookup.DescriptionTemplateTypeLookup; -import gr.cite.tools.data.builder.BuilderFactory; -import gr.cite.tools.data.query.QueryFactory; +import eu.eudat.model.persist.DescriptionTemplateTypePersist; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.exception.MyNotFoundException; -import jakarta.persistence.EntityManager; -import jakarta.persistence.PersistenceContext; -import org.springframework.context.ApplicationContext; -import org.springframework.stereotype.Service; -import org.springframework.transaction.PlatformTransactionManager; -import org.springframework.transaction.TransactionDefinition; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.support.DefaultTransactionDefinition; +import gr.cite.tools.exception.MyValidationException; +import gr.cite.tools.fieldset.FieldSet; -import java.util.List; +import javax.management.InvalidApplicationException; import java.util.UUID; -@Service -public class DescriptionTemplateTypeService { - - private final ApplicationContext applicationContext; - - private final BuilderFactory builderFactory; - - private final QueryFactory queryFactory; - - private final PlatformTransactionManager transactionManager; - - @PersistenceContext - private EntityManager entityManager; - - public DescriptionTemplateTypeService(ApplicationContext applicationContext, BuilderFactory builderFactory, QueryFactory queryFactory, PlatformTransactionManager platformTransactionManager) { - this.applicationContext = applicationContext; - this.builderFactory = builderFactory; - this.queryFactory = queryFactory; - this.transactionManager = platformTransactionManager; - } - - public List query(DescriptionTemplateTypeLookup lookup) { - DescriptionTemplateTypeQuery query = lookup.enrich(queryFactory); - List data = query.collectAs(lookup.getProject()); - - return builderFactory.builder(DescriptionTemplateTypeBuilder.class).build(lookup.getProject(), data); - } - - public DescriptionTemplateType get(UUID id) { - DescriptionTemplateTypeQuery query = applicationContext.getBean(DescriptionTemplateTypeQuery.class); - - return builderFactory - .builder(DescriptionTemplateTypeBuilder.class) - .build(null, query.ids(id).first()); - } - - public DescriptionTemplateTypeEntity getEntityByName(String name) { - DescriptionTemplateTypeQuery query = applicationContext.getBean(DescriptionTemplateTypeQuery.class); - - return query.names(name).first(); - } - - public DescriptionTemplateType persist(DescriptionTemplateType payload) { - DescriptionTemplateTypeEntity created = new DescriptionTemplateTypeEntity(); - created.setName(payload.getName()); - created.setStatus(DescriptionTemplateTypeStatus.SAVED.getValue()); - - DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); - definition.setName(UUID.randomUUID().toString()); - definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); - definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); - TransactionStatus status = null; - try { - status = transactionManager.getTransaction(definition); - entityManager.persist(created); - - entityManager.flush(); - transactionManager.commit(status); - } catch (Exception ex) { - if (status != null) - transactionManager.rollback(status); - throw ex; - } - - DescriptionTemplateTypeQuery query = applicationContext.getBean(DescriptionTemplateTypeQuery.class); - - return builderFactory - .builder(DescriptionTemplateTypeBuilder.class) - .build(null, query.ids(created.getId()).first()); - } - - public DescriptionTemplateType update(DescriptionTemplateType payload) { - DescriptionTemplateTypeEntity entity = entityManager.find(DescriptionTemplateTypeEntity.class, payload.getId()); - entity.setName(payload.getName()); - entity.setStatus(payload.getStatus()); - entityManager.merge(entity); - entityManager.flush(); - - return builderFactory.builder(DescriptionTemplateTypeBuilder.class).build(null, entity); - } - - public boolean delete(UUID id) { - DescriptionTemplateTypeEntity entity = entityManager.find(DescriptionTemplateTypeEntity.class, id); - if (entity == null) - return false; - entity.setStatus(DescriptionTemplateTypeStatus.DELETED.getValue()); - entityManager.merge(entity); - entityManager.flush(); - - return true; - } +public interface DescriptionTemplateTypeService { + DescriptionTemplateType persist(DescriptionTemplateTypePersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException; + void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/DescriptionTemplateTypeServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/DescriptionTemplateTypeServiceImpl.java new file mode 100644 index 000000000..188ff36fb --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/DescriptionTemplateTypeServiceImpl.java @@ -0,0 +1,119 @@ +package eu.eudat.service; + +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.authorization.Permission; +import eu.eudat.commons.JsonHandlingService; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DescriptionTemplateTypeEntity; +import eu.eudat.errorcode.ErrorThesaurusProperties; +import eu.eudat.event.DescriptionTemplateTypeTouchedEvent; +import eu.eudat.event.EventBroker; +import eu.eudat.model.DescriptionTemplateType; +import eu.eudat.model.builder.DescriptionTemplateTypeBuilder; +import eu.eudat.model.deleter.DescriptionTemplateTypeDeleter; +import eu.eudat.model.persist.DescriptionTemplateTypePersist; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.exception.MyValidationException; +import gr.cite.tools.fieldset.BaseFieldSet; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.web.context.annotation.RequestScope; + +import javax.management.InvalidApplicationException; +import java.time.Instant; +import java.util.List; +import java.util.UUID; + +@Service +@RequestScope +public class DescriptionTemplateTypeServiceImpl implements DescriptionTemplateTypeService { + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateTypeServiceImpl.class)); + + private final EntityManager entityManager; + private final AuthorizationService authorizationService; + private final DeleterFactory deleterFactory; + private final BuilderFactory builderFactory; + private final ConventionService conventionService; + private final ErrorThesaurusProperties errors; + private final MessageSource messageSource; + private final EventBroker eventBroker; + private final QueryFactory queryFactory; + private final JsonHandlingService jsonHandlingService; + + @Autowired + public DescriptionTemplateTypeServiceImpl( + EntityManager entityManager, + AuthorizationService authorizationService, + DeleterFactory deleterFactory, + BuilderFactory builderFactory, + ConventionService conventionService, + ErrorThesaurusProperties errors, + MessageSource messageSource, + EventBroker eventBroker, + QueryFactory queryFactory, + JsonHandlingService jsonHandlingService) { + this.entityManager = entityManager; + this.authorizationService = authorizationService; + this.deleterFactory = deleterFactory; + this.builderFactory = builderFactory; + this.conventionService = conventionService; + this.errors = errors; + this.messageSource = messageSource; + this.eventBroker = eventBroker; + this.queryFactory = queryFactory; + this.jsonHandlingService = jsonHandlingService; + } + + public DescriptionTemplateType persist(DescriptionTemplateTypePersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException { + logger.debug(new MapLogEntry("persisting data descriptionTemplateType").And("model", model).And("fields", fields)); + + this.authorizationService.authorizeForce(Permission.EditDescriptionTemplateType); + + Boolean isUpdate = this.conventionService.isValidGuid(model.getId()); + + DescriptionTemplateTypeEntity data; + if (isUpdate) { + data = this.entityManager.find(DescriptionTemplateTypeEntity.class, model.getId()); + if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getId(), DescriptionTemplateType.class.getSimpleName()}, LocaleContextHolder.getLocale())); + } else { + data = new DescriptionTemplateTypeEntity(); + data.setId(UUID.randomUUID()); + data.setIsActive(IsActive.Active); + data.setCreatedAt(Instant.now()); + } + + data.setName(model.getName()); + data.setStatus(model.getStatus()); + data.setUpdatedAt(Instant.now()); + if (isUpdate) this.entityManager.merge(data); + else this.entityManager.persist(data); + + this.entityManager.flush(); + + this.eventBroker.emit(new DescriptionTemplateTypeTouchedEvent(data.getId())); + return this.builderFactory.builder(DescriptionTemplateTypeBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(BaseFieldSet.build(fields, DescriptionTemplateType._id), data); + } + + public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { + logger.debug("deleting dataset: {}", id); + + this.authorizationService.authorizeForce(Permission.DeleteDescriptionTemplateType); + + this.deleterFactory.deleter(DescriptionTemplateTypeDeleter.class).deleteAndSaveByIds(List.of(id)); + } +} + diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDao.java index 6ddd6fa06..8e1ade6ba 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDao.java @@ -1,12 +1,12 @@ package eu.eudat.data.dao.entities.security; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.dao.DatabaseAccessLayer; -import eu.eudat.data.entities.Credential; import java.util.UUID; -public interface CredentialDao extends DatabaseAccessLayer { +public interface CredentialDao extends DatabaseAccessLayer { - Credential getLoggedInCredentials(String username, String secret, Integer provider); + CredentialEntity getLoggedInCredentials(String username, String secret, Integer provider); } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDaoImpl.java index 6fa8c94e4..a470c3ce3 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDaoImpl.java @@ -1,8 +1,8 @@ package eu.eudat.data.dao.entities.security; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.dao.DatabaseAccess; import eu.eudat.data.dao.databaselayer.service.DatabaseService; -import eu.eudat.data.entities.Credential; import eu.eudat.queryable.QueryableList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -12,26 +12,26 @@ import java.util.concurrent.CompletableFuture; @Component("credentialDao") -public class CredentialDaoImpl extends DatabaseAccess implements CredentialDao { +public class CredentialDaoImpl extends DatabaseAccess implements CredentialDao { @Autowired - public CredentialDaoImpl(DatabaseService databaseService) { + public CredentialDaoImpl(DatabaseService databaseService) { super(databaseService); } @Override - public Credential createOrUpdate(Credential item) { - return this.getDatabaseService().createOrUpdate(item, Credential.class); + public CredentialEntity createOrUpdate(CredentialEntity item) { + return this.getDatabaseService().createOrUpdate(item, CredentialEntity.class); } @Override - public Credential find(UUID id) { - return this.getDatabaseService().getQueryable(Credential.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingleOrDefault(); + public CredentialEntity find(UUID id) { + return this.getDatabaseService().getQueryable(CredentialEntity.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingleOrDefault(); } @Override - public Credential getLoggedInCredentials(String username, String secret, Integer provider) { - return this.getDatabaseService().getQueryable(Credential.class).where(((builder, root) -> + public CredentialEntity getLoggedInCredentials(String username, String secret, Integer provider) { + return this.getDatabaseService().getQueryable(CredentialEntity.class).where(((builder, root) -> builder.and( builder.equal(root.get("publicValue"), username), builder.equal(root.get("secret"), secret), @@ -40,22 +40,22 @@ public class CredentialDaoImpl extends DatabaseAccess implements Cre } @Override - public void delete(Credential item) { + public void delete(CredentialEntity item) { this.getDatabaseService().delete(item); } @Override - public QueryableList asQueryable() { - return this.getDatabaseService().getQueryable(Credential.class); + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(CredentialEntity.class); } @Override - public CompletableFuture createOrUpdateAsync(Credential item) { + public CompletableFuture createOrUpdateAsync(CredentialEntity item) { return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); } @Override - public Credential find(UUID id, String hint) { + public CredentialEntity find(UUID id, String hint) { throw new UnsupportedOperationException(); } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java index 7c9f1661e..96b52887a 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java @@ -1,5 +1,6 @@ package eu.eudat.data.entities; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.converters.DateToUTCConverter; import eu.eudat.data.entities.helpers.EntityBinder; import eu.eudat.queryable.queryableentity.DataEntity; @@ -15,7 +16,7 @@ import java.util.*; @NamedEntityGraphs({ @NamedEntityGraph( name = "userInfo", - attributeNodes = {@NamedAttributeNode("userRoles"), @NamedAttributeNode("credentials"), @NamedAttributeNode("additionalinfo")}), + attributeNodes = {@NamedAttributeNode("userRoles"), @NamedAttributeNode("additionalinfo")}), }) public class UserInfo implements DataEntity { @@ -76,8 +77,9 @@ public class UserInfo implements DataEntity { ) private Set dmps; - @OneToMany(mappedBy = "userInfo", fetch = FetchType.LAZY) - private Set credentials = new HashSet<>(); + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "Id") + private Set credentialEntities = new HashSet<>(); @OneToMany(mappedBy = "userInfo", fetch = FetchType.LAZY) private Set userRoles = new HashSet<>(); @@ -168,12 +170,12 @@ public class UserInfo implements DataEntity { this.additionalinfo = additionalinfo; } - public Set getCredentials() { - return credentials; + public Set getCredentials() { + return credentialEntities; } - public void setCredentials(Set credentials) { - this.credentials = credentials; + public void setCredentials(Set credentialEntities) { + this.credentialEntities = credentialEntities; } public Set getUserRoles() { diff --git a/dmp-backend/pom.xml b/dmp-backend/pom.xml index da398da62..c1a73edca 100644 --- a/dmp-backend/pom.xml +++ b/dmp-backend/pom.xml @@ -301,7 +301,10 @@ io.micrometer micrometer-core - + + org.springframework.boot + spring-boot-starter-validation + gr.cite @@ -334,6 +337,12 @@ 2.1.0 + + gr.cite + oidc-authz + 2.1.0 + + diff --git a/dmp-backend/web/src/main/java/eu/eudat/EuDatApplication.java b/dmp-backend/web/src/main/java/eu/eudat/EuDatApplication.java index 3b8efaa2c..1ca2a7223 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/EuDatApplication.java +++ b/dmp-backend/web/src/main/java/eu/eudat/EuDatApplication.java @@ -1,5 +1,6 @@ package eu.eudat; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; @@ -28,6 +29,7 @@ public class EuDatApplication extends SpringBootServletInitializer { @Primary public ObjectMapper primaryObjectMapper() { return JsonMapper.builder().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .serializationInclusion(JsonInclude.Include.NON_NULL) .addModule(new JavaTimeModule()).build(); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/authorization/OwnedAuthorizationHandler.java b/dmp-backend/web/src/main/java/eu/eudat/authorization/OwnedAuthorizationHandler.java new file mode 100644 index 000000000..f6ef8f821 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/authorization/OwnedAuthorizationHandler.java @@ -0,0 +1,42 @@ +package eu.eudat.authorization; + +import eu.eudat.commons.scope.user.UserScope; +import gr.cite.commons.web.authz.handler.AuthorizationHandler; +import gr.cite.commons.web.authz.handler.AuthorizationHandlerContext; +import gr.cite.commons.web.authz.policy.AuthorizationRequirement; +import gr.cite.commons.web.oidc.principal.MyPrincipal; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component("ownedAuthorizationHandler") +public class OwnedAuthorizationHandler extends AuthorizationHandler { + + private final UserScope userScope; + + @Autowired + public OwnedAuthorizationHandler(UserScope userScope) { + this.userScope = userScope; + } + + @Override + public int handleRequirement(AuthorizationHandlerContext context, Object resource, AuthorizationRequirement requirement) { + OwnedAuthorizationRequirement req = (OwnedAuthorizationRequirement) requirement; + + OwnedResource rs = (OwnedResource) resource; + + boolean isAuthenticated = ((MyPrincipal) context.getPrincipal()).isAuthenticated(); + if (!isAuthenticated) return ACCESS_NOT_DETERMINED; + + if (this.userScope.getUserIdSafe() == null) return ACCESS_NOT_DETERMINED; + + if (rs != null && rs.getUserIds() != null && rs.getUserIds().contains(this.userScope.getUserIdSafe())) return ACCESS_GRANTED; + + return ACCESS_NOT_DETERMINED; + } + + @Override + public Class supporting() { + return OwnedAuthorizationRequirement.class; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java index b26b0a7fb..f734459b6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java @@ -1,6 +1,16 @@ package eu.eudat.configurations; +import eu.eudat.authorization.OwnedAuthorizationHandler; +import eu.eudat.authorization.OwnedAuthorizationRequirement; +import eu.eudat.authorization.OwnedResource; +import gr.cite.commons.web.authz.handler.AuthorizationHandler; +import gr.cite.commons.web.authz.handler.PermissionClientAuthorizationHandler; +import gr.cite.commons.web.authz.policy.AuthorizationRequirement; +import gr.cite.commons.web.authz.policy.AuthorizationRequirementMapper; +import gr.cite.commons.web.authz.policy.AuthorizationResource; +import gr.cite.commons.web.authz.policy.resolver.AuthorizationPolicyConfigurer; +import gr.cite.commons.web.authz.policy.resolver.AuthorizationPolicyResolverStrategy; import gr.cite.commons.web.oidc.configuration.WebSecurityProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -17,24 +27,28 @@ import org.springframework.security.web.authentication.preauth.AbstractPreAuthen import jakarta.servlet.Filter; import jakarta.servlet.http.HttpServletRequest; + import java.util.List; import java.util.Set; @Configuration @EnableWebSecurity -public class SecurityConfiguration { +public class SecurityConfiguration { private final WebSecurityProperties webSecurityProperties; private final AuthenticationManagerResolver authenticationManagerResolver; private final Filter apiKeyFilter; + private final OwnedAuthorizationHandler ownedAuthorizationHandler; @Autowired public SecurityConfiguration(WebSecurityProperties webSecurityProperties, - @Qualifier("tokenAuthenticationResolver") AuthenticationManagerResolver authenticationManagerResolver, - @Qualifier("apiKeyFilter") Filter apiKeyFilter) { + @Qualifier("tokenAuthenticationResolver") AuthenticationManagerResolver authenticationManagerResolver, + @Qualifier("apiKeyFilter") Filter apiKeyFilter, + @Qualifier("ownedAuthorizationHandler") OwnedAuthorizationHandler ownedAuthorizationHandler) { this.webSecurityProperties = webSecurityProperties; this.authenticationManagerResolver = authenticationManagerResolver; this.apiKeyFilter = apiKeyFilter; + this.ownedAuthorizationHandler = ownedAuthorizationHandler; } @Bean @@ -45,67 +59,68 @@ public class SecurityConfiguration { .headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) .addFilterBefore(apiKeyFilter, AbstractPreAuthenticatedProcessingFilter.class) .authorizeHttpRequests(authRequest -> - authRequest.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).anonymous() - .requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).authenticated()) + authRequest.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).permitAll() //TODO: Authz + .requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).permitAll()) .sessionManagement( sessionManagementConfigurer-> sessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.NEVER)) .oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver)); return tempHttp.build(); } -// @Bean -// AuthorizationPolicyConfigurer authorizationPolicyConfigurer() { -// return new AuthorizationPolicyConfigurer() { -// -// @Override -// public AuthorizationPolicyResolverStrategy strategy() { -// return AuthorizationPolicyResolverStrategy.STRICT_CONSENSUS_BASED; -// } -// -// //Here you can register your custom authorization handlers, which will get used as well as the existing ones -// //This is optional and can be omitted -// //If not set / set to null, only the default authorization handlers will be used -// @Override -// public List> addCustomHandlers() { -// return null; -// } -// -// //Here you can register your custom authorization requirements (if any) -// //This is optional and can be omitted -// //If not set / set to null, only the default authorization requirements will be used -// @Override -// public List extendRequirements() { -// return List.of( -//// new TimeOfDayAuthorizationRequirement(new TimeOfDay("08:00","16:00"), true) -// ); -// } -// -// //Here you can select handlers you want to disable by providing the classes they are implemented by -// //You can disable any handler (including any custom one) -// //This is optional and can be omitted -// //If not set / set to null, all the handlers will be invoked, based on their requirement support -// //In the example below, the default client handler will be ignored by the resolver -// @Override -// public List>> disableHandlers() { -// return List.of(PermissionClientAuthorizationHandler.class); -// } -// }; -// } -// -// @Bean -// AuthorizationRequirementMapper authorizationRequirementMapper() { -// return new AuthorizationRequirementMapper() { -// @Override -// public AuthorizationRequirement map(AuthorizationResource resource, boolean matchAll, String[] permissions) { -// Class type = resource.getClass(); -// if (!AuthorizationResource.class.isAssignableFrom(type)) throw new IllegalArgumentException("resource"); -// -// if (OwnedResource.class.equals(type)) { -// return new OwnedAuthorizationRequirement(); -// } -// throw new IllegalArgumentException("resource"); -// } -// }; -// } + @Bean + AuthorizationPolicyConfigurer authorizationPolicyConfigurer() { + return new AuthorizationPolicyConfigurer() { + + @Override + public AuthorizationPolicyResolverStrategy strategy() { + return AuthorizationPolicyResolverStrategy.STRICT_CONSENSUS_BASED; + } + + //Here you can register your custom authorization handlers, which will get used as well as the existing ones + //This is optional and can be omitted + //If not set / set to null, only the default authorization handlers will be used + @Override + public List> addCustomHandlers() { + return List.of( ownedAuthorizationHandler); + } + + //Here you can register your custom authorization requirements (if any) + //This is optional and can be omitted + //If not set / set to null, only the default authorization requirements will be used + @Override + public List extendRequirements() { + return List.of( +// new TimeOfDayAuthorizationRequirement(new TimeOfDay("08:00","16:00"), true) + ); + } + + //Here you can select handlers you want to disable by providing the classes they are implemented by + //You can disable any handler (including any custom one) + //This is optional and can be omitted + //If not set / set to null, all the handlers will be invoked, based on their requirement support + //In the example below, the default client handler will be ignored by the resolver + @Override + public List>> disableHandlers() { + return List.of(PermissionClientAuthorizationHandler.class); + } + }; + } + + @Bean + AuthorizationRequirementMapper authorizationRequirementMapper() { + return new AuthorizationRequirementMapper() { + @Override + public AuthorizationRequirement map(AuthorizationResource resource, boolean matchAll, String[] permissions) { + Class type = resource.getClass(); + if (!AuthorizationResource.class.isAssignableFrom(type)) throw new IllegalArgumentException("resource"); + + if (OwnedResource.class.equals(type)) { + return new OwnedAuthorizationRequirement(); + } + throw new IllegalArgumentException("resource"); + } + }; + } + private String[] buildAntPatterns(Set endpoints) { if (endpoints == null) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java index a554d13ce..8170b8c72 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/WebMVCConfiguration.java @@ -1,6 +1,6 @@ package eu.eudat.configurations; -import eu.eudat.commons.scope.UserScope; +import eu.eudat.commons.scope.user.UserScope; import eu.eudat.interceptors.UserInterceptor; import eu.eudat.logic.handlers.PrincipalArgumentResolver; import eu.eudat.logic.services.ApiContext; diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java index b3ae6f92c..85202a611 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java @@ -66,7 +66,7 @@ public class Admin extends BaseController { DatasetProfile shortenProfile = profile.toShort(); DescriptionTemplate modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext(), descriptionTemplateTypeService); // modelDefinition.setType(getApiContext().getOperationsContext().getDatabaseRepository().getDescriptionTemplateTypeDao().findFromName(profile.getType())); - modelDefinition.setType(descriptionTemplateTypeService.getEntityByName(profile.getType())); +//TODO: dtziotzios modelDefinition.setType(descriptionTemplateTypeService.getEntityByName(profile.getType())); modelDefinition.setGroupId(UUID.randomUUID()); modelDefinition.setVersion((short) 0); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DashBoardController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DashBoardController.java index ae69957d5..5e7aedd6d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DashBoardController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DashBoardController.java @@ -33,12 +33,6 @@ public class DashBoardController extends BaseController { this.dashBoardManager = dashBoardManager; } - @RequestMapping(method = RequestMethod.GET, value = {"/dashboard/getStatistics"}, produces = "application/json") - public ResponseEntity> getStatistics() { - DashBoardStatistics statistics = dashBoardManager.getStatistics(); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(statistics)); - } - @RequestMapping(method = RequestMethod.GET, value = {"/dashboard/me/getStatistics"}, produces = "application/json") public ResponseEntity> getStatistics(Principal principal) throws IOException { DashBoardStatistics statistics = dashBoardManager.getMeStatistics(principal); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java index 2e77f4670..bf958e2c6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/LanguageController.java @@ -1,8 +1,10 @@ package eu.eudat.controllers; +import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.security.Principal; import eu.eudat.types.ApiMessageCode; +import eu.eudat.types.Authorities; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.http.HttpHeaders; @@ -12,7 +14,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.io.*; -import java.util.UUID; @RestController @CrossOrigin @@ -25,30 +26,10 @@ public class LanguageController { public LanguageController(Environment environment) { this.environment = environment; } - - @RequestMapping(value = "{lang}", method = RequestMethod.GET) - public ResponseEntity getLanguage(@PathVariable String lang) throws IOException { - - String fileName = this.environment.getProperty("language.path") + lang + ".json"; - InputStream is = new FileInputStream(fileName); - - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.setContentLength(is.available()); - responseHeaders.setContentType(MediaType.APPLICATION_JSON); - responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName); - responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); - responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); - - byte[] content = new byte[is.available()]; - is.read(content); - is.close(); - - return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); - } - + @RequestMapping(value = "update/{lang}", method = RequestMethod.POST) public @ResponseBody - ResponseEntity> updateLang(@PathVariable String lang, @RequestBody String json) throws Exception { + ResponseEntity> updateLang(@PathVariable String lang, @RequestBody String json, @ClaimedAuthorities(claims = {Authorities.ADMIN}) Principal principal) throws Exception { String fileName = this.environment.getProperty("language.path") + lang + ".json"; OutputStream os = new FileOutputStream(fileName); os.write(json.getBytes()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/PublicDashBoardController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/PublicDashBoardController.java new file mode 100644 index 000000000..3c72134da --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/PublicDashBoardController.java @@ -0,0 +1,42 @@ +package eu.eudat.controllers; + +import eu.eudat.controllers.BaseController; +import eu.eudat.logic.managers.DashBoardManager; +import eu.eudat.logic.security.claims.ClaimedAuthorities; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.models.data.dashboard.recent.RecentActivity; +import eu.eudat.models.data.dashboard.recent.model.RecentActivityModel; +import eu.eudat.models.data.dashboard.recent.tablerequest.RecentActivityTableRequest; +import eu.eudat.models.data.dashboard.searchbar.SearchBarItem; +import eu.eudat.models.data.dashboard.statistics.DashBoardStatistics; +import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.security.Principal; +import eu.eudat.types.ApiMessageCode; +import eu.eudat.types.Authorities; +import jakarta.transaction.Transactional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.util.List; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/public/dashboard/"}) +public class PublicDashBoardController extends BaseController { + + private DashBoardManager dashBoardManager; + @Autowired + public PublicDashBoardController(ApiContext apiContext, DashBoardManager dashBoardManager) { + super(apiContext); + this.dashBoardManager = dashBoardManager; + } + + @RequestMapping(method = RequestMethod.GET, value = {"getStatistics"}, produces = "application/json") + public ResponseEntity> getStatistics() { + DashBoardStatistics statistics = dashBoardManager.getStatistics(); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(statistics)); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/PublicLanguageController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/PublicLanguageController.java new file mode 100644 index 000000000..1f62ba879 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/PublicLanguageController.java @@ -0,0 +1,44 @@ +package eu.eudat.controllers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.io.*; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/public/language/"}) +public class PublicLanguageController { + + private Environment environment; + + @Autowired + public PublicLanguageController(Environment environment) { + this.environment = environment; + } + + @RequestMapping(value = "{lang}", method = RequestMethod.GET) + public ResponseEntity getLanguage(@PathVariable String lang) throws IOException { + + String fileName = this.environment.getProperty("language.path") + lang + ".json"; + InputStream is = new FileInputStream(fileName); + + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setContentLength(is.available()); + responseHeaders.setContentType(MediaType.APPLICATION_JSON); + responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName); + responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); + responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); + + byte[] content = new byte[is.available()]; + is.read(content); + is.close(); + + return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java index a715eaa6f..5d9f396d5 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java @@ -1,13 +1,9 @@ package eu.eudat.controllers; import eu.eudat.data.query.items.table.userinfo.UserInfoTableRequestItem; -import eu.eudat.exceptions.security.ExpiredTokenException; -import eu.eudat.exceptions.security.NonValidTokenException; -import eu.eudat.exceptions.security.NullEmailException; import eu.eudat.logic.managers.UserManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; -import eu.eudat.models.data.doi.DOIRequest; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.security.Principal; @@ -87,22 +83,6 @@ public class Users extends BaseController { DataTableData dataTable = userManager.getCollaboratorsPaged(userInfoTableRequestItem, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().payload(dataTable).status(ApiMessageCode.NO_MESSAGE)); } - - @Transactional - @RequestMapping(method = RequestMethod.POST, value = {"/registerDOIToken"}, consumes = "application/json", produces = "application/json") - public @ResponseBody - ResponseEntity> registerDOIToken(@RequestBody DOIRequest doiRequest, Principal principal) throws NullEmailException, IOException { - userManager.registerDOIToken(doiRequest, principal); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); - } - - @Transactional - @RequestMapping(method = RequestMethod.DELETE, value = {"/deleteDOIToken"}, consumes = "application/json", produces = "application/json") - public @ResponseBody - ResponseEntity> deleteDOIToken(Principal principal) throws NullEmailException, IOException { - userManager.deleteDOIToken(principal); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); - } @RequestMapping(method = RequestMethod.GET, value = {"/getCsv"}) public @ResponseBody diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/BaseController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/BaseController.java deleted file mode 100644 index cb3b26a4f..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/BaseController.java +++ /dev/null @@ -1,36 +0,0 @@ -package eu.eudat.controllers.v2; - -import eu.eudat.model.result.QueryResult; -import gr.cite.tools.data.query.Lookup; - -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; - -public class BaseController { - - public static QueryResult extractQueryResultWithCount(Function> service, L lookup) { - return extractQueryResultWithCountWhen(service, lookup, null); - } - - public static QueryResult extractQueryResultWithCountWhen(Function> service, L lookup, Function when) { - List result = service.apply(lookup); - lookup.setPage(null); - List all = service.apply(lookup); - long count = all.size(); - if (when == null) return new QueryResult<>(result, count); - long countOverride = count; - for (T item : all) { - if (!when.apply(item)) countOverride--; - } - return new QueryResult<>(result, count, countOverride); - } - - public static QueryResult extractQueryResultWithCount(BiFunction> service, String name, L lookup) { - List result = service.apply(name, lookup); - lookup.setPage(null); - long count = service.apply(name, lookup).size(); - return new QueryResult<>(result, count); - } - -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DescriptionTemplateTypeV2Controller.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DescriptionTemplateTypeV2Controller.java index 4eaae2942..e8df7549d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DescriptionTemplateTypeV2Controller.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/DescriptionTemplateTypeV2Controller.java @@ -1,21 +1,33 @@ package eu.eudat.controllers.v2; import eu.eudat.audit.AuditableAction; +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.data.DescriptionTemplateTypeEntity; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.model.DescriptionTemplateType; +import eu.eudat.model.builder.DescriptionTemplateTypeBuilder; import eu.eudat.model.censorship.DescriptionTemplateTypeCensor; +import eu.eudat.model.persist.DescriptionTemplateTypePersist; import eu.eudat.model.result.QueryResult; import eu.eudat.models.data.security.Principal; +import eu.eudat.query.DescriptionTemplateTypeQuery; import eu.eudat.query.lookup.DescriptionTemplateTypeLookup; import eu.eudat.service.DescriptionTemplateTypeService; import eu.eudat.types.Authorities; import gr.cite.tools.auditing.AuditService; +import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.censor.CensorFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; +import gr.cite.tools.validation.MyValidate; +import org.opensaml.xml.signature.Q; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.http.HttpStatus; @@ -24,99 +36,98 @@ import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; -import java.util.AbstractMap; -import java.util.Map; -import java.util.UUID; - -import static eu.eudat.controllers.v2.BaseController.extractQueryResultWithCount; +import javax.management.InvalidApplicationException; +import java.io.IOException; +import java.util.*; @RestController @CrossOrigin -@Transactional -@RequestMapping(path = "api/v2/descriptionTemplateType", produces = MediaType.APPLICATION_JSON_VALUE) +@RequestMapping(path = "api/description-template-type") public class DescriptionTemplateTypeV2Controller { - private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DescriptionTemplateTypeV2Controller.class)); + private final BuilderFactory builderFactory; private final AuditService auditService; - private final DescriptionTemplateTypeService descriptionTemplateTypeService; - + private final CensorFactory censorFactory; + private final QueryFactory queryFactory; private final MessageSource messageSource; - private final CensorFactory censorFactory; - - public DescriptionTemplateTypeV2Controller(AuditService auditService, DescriptionTemplateTypeService descriptionTemplateTypeService, MessageSource messageSource, CensorFactory censorFactory) { + @Autowired + public DescriptionTemplateTypeV2Controller( + BuilderFactory builderFactory, + AuditService auditService, + DescriptionTemplateTypeService descriptionTemplateTypeService, + CensorFactory censorFactory, + QueryFactory queryFactory, + MessageSource messageSource) { + this.builderFactory = builderFactory; this.auditService = auditService; this.descriptionTemplateTypeService = descriptionTemplateTypeService; - this.messageSource = messageSource; this.censorFactory = censorFactory; + this.queryFactory = queryFactory; + this.messageSource = messageSource; } @PostMapping("query") - public QueryResult query(@RequestBody DescriptionTemplateTypeLookup lookup, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal ignoredPrincipal) { + public QueryResult Query(@RequestBody DescriptionTemplateTypeLookup lookup) throws MyApplicationException, MyForbiddenException { logger.debug("querying {}", DescriptionTemplateType.class.getSimpleName()); - censorFactory.censor(DescriptionTemplateTypeCensor.class).censor(lookup.getProject()); + this.censorFactory.censor(DescriptionTemplateTypeCensor.class).censor(lookup.getProject(), null); - auditService.track(AuditableAction.DescriptionTemplateType_Query, "lookup", lookup); + DescriptionTemplateTypeQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermission); - return extractQueryResultWithCount(descriptionTemplateTypeService::query, lookup); + List data = query.collectAs(lookup.getProject()); + List models = this.builderFactory.builder(DescriptionTemplateTypeBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(lookup.getProject(), data); + long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size(); + + this.auditService.track(AuditableAction.DescriptionTemplateType_Query, "lookup", lookup); + //this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action); + + return new QueryResult<>(models, count); } @GetMapping("{id}") - public QueryResult get(@PathVariable("id") UUID id, FieldSet fieldSet, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal ignoredPrincipal) { - logger.debug(new MapLogEntry("retrieving" + DescriptionTemplateType.class.getSimpleName()).And("id", id)); + public DescriptionTemplateType Get(@PathVariable("id") UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException { + logger.debug(new MapLogEntry("retrieving" + DescriptionTemplateType.class.getSimpleName()).And("id", id).And("fields", fieldSet)); - censorFactory.censor(DescriptionTemplateTypeCensor.class).censor(fieldSet); + this.censorFactory.censor(DescriptionTemplateTypeCensor.class).censor(fieldSet, null); - DescriptionTemplateType model = descriptionTemplateTypeService.get(id); - if (model == null) - throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, DescriptionTemplateType.class.getSimpleName()}, LocaleContextHolder.getLocale())); + DescriptionTemplateTypeQuery query = this.queryFactory.query(DescriptionTemplateTypeQuery.class).authorize(AuthorizationFlags.OwnerOrPermission).ids(id); + DescriptionTemplateType model = this.builderFactory.builder(DescriptionTemplateTypeBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(fieldSet, query.firstAs(fieldSet)); + if (model == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, DescriptionTemplateType.class.getSimpleName()}, LocaleContextHolder.getLocale())); - auditService.track(AuditableAction.DescriptionTemplateType_Query, "id", id); + this.auditService.track(AuditableAction.DescriptionTemplateType_Lookup, Map.ofEntries( + new AbstractMap.SimpleEntry("id", id), + new AbstractMap.SimpleEntry("fields", fieldSet) + )); + //this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action); - return new QueryResult<>(model); + return model; } @PostMapping("persist") - public QueryResult persist(@RequestBody DescriptionTemplateType payload, FieldSet fieldSet, @ClaimedAuthorities(claims = {Authorities.ADMIN}) Principal ignoredPrincipal) { - logger.debug(new MapLogEntry("persisting" + DescriptionTemplateType.class.getSimpleName()).And("model", payload).And("fieldSet", fieldSet)); + @Transactional + public DescriptionTemplateType Persist(@MyValidate @RequestBody DescriptionTemplateTypePersist model, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { + logger.debug(new MapLogEntry("persisting" + DescriptionTemplateType.class.getSimpleName()).And("model", model).And("fieldSet", fieldSet)); + DescriptionTemplateType persisted = this.descriptionTemplateTypeService.persist(model, fieldSet); - DescriptionTemplateType persisted = descriptionTemplateTypeService.persist(payload); - - auditService.track(AuditableAction.DescriptionTemplateType_Persist, Map.ofEntries( - new AbstractMap.SimpleEntry("model", payload), + this.auditService.track(AuditableAction.DescriptionTemplateType_Persist, Map.ofEntries( + new AbstractMap.SimpleEntry("model", model), new AbstractMap.SimpleEntry("fields", fieldSet) )); - - return new QueryResult<>(persisted); + //this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action); + return persisted; } - @PostMapping("update") - public QueryResult update(@RequestBody DescriptionTemplateType payload, FieldSet fieldSet, @ClaimedAuthorities(claims = {Authorities.ADMIN}) Principal ignoredPrincipal) { - logger.debug(new MapLogEntry("persisting" + DescriptionTemplateType.class.getSimpleName()).And("model", payload).And("fieldSet", fieldSet)); + @DeleteMapping("{id}") + @Transactional + public void Delete(@PathVariable("id") UUID id) throws MyForbiddenException, InvalidApplicationException { + logger.debug(new MapLogEntry("retrieving" + DescriptionTemplateType.class.getSimpleName()).And("id", id)); - DescriptionTemplateType persisted = descriptionTemplateTypeService.update(payload); + this.descriptionTemplateTypeService.deleteAndSave(id); - auditService.track(AuditableAction.DescriptionTemplateType_Persist, Map.ofEntries( - new AbstractMap.SimpleEntry("model", payload), - new AbstractMap.SimpleEntry("fields", fieldSet) - )); - - return new QueryResult<>(persisted); + this.auditService.track(AuditableAction.DescriptionTemplateType_Delete, "id", id); + //this.auditService.trackIdentity(AuditableAction.IdentityTracking_Action); } - - @DeleteMapping("delete/{id}") - public ResponseEntity delete(@PathVariable(value = "id") UUID id, @ClaimedAuthorities(claims = {Authorities.ADMIN}) Principal ignoredPrincipal) { - logger.debug(new MapLogEntry("deleting" + DescriptionTemplateType.class.getSimpleName()).And("id", id)); - - auditService.track(AuditableAction.DescriptionTemplateType_Delete, "delete", id); - - if (descriptionTemplateTypeService.delete(id)) - return ResponseEntity.status(HttpStatus.OK).build(); - else - return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); - } - } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/PrincipalController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/PrincipalController.java index 0aaa176bd..344d5437a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/PrincipalController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/PrincipalController.java @@ -55,7 +55,8 @@ public class PrincipalController { BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._authenticatedAt), BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._expiresAt), BaseFieldSet.asIndexer(Account._principal, Account.PrincipalInfo._more), - Account._roles); + Account._roles, + Account._permissions); } MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java b/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java index e47147d18..743281495 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java +++ b/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java @@ -1,8 +1,10 @@ package eu.eudat.interceptors; -import eu.eudat.commons.scope.UserScope; -import eu.eudat.data.entities.Credential; +import eu.eudat.commons.enums.ProviderType; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.scope.user.UserScope; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserRole; import eu.eudat.exceptions.security.NullEmailException; @@ -50,7 +52,7 @@ public class UserInterceptor implements WebRequestInterceptor { @Autowired public UserInterceptor( - UserScope userScope, + UserScope userScope, ClaimExtractor claimExtractor, CurrentPrincipalResolver currentPrincipalResolver, PlatformTransactionManager transactionManager, @@ -68,7 +70,7 @@ public class UserInterceptor implements WebRequestInterceptor { UUID userId = null; if (this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) { String subjectId = this.claimExtractor.subjectString(this.currentPrincipalResolver.currentPrincipal()); - + var aa = this.claimExtractor.roles(this.currentPrincipalResolver.currentPrincipal()); UserInterceptorCacheService.UserInterceptorCacheValue cacheValue = this.userInterceptorCacheService.lookup(this.userInterceptorCacheService.buildKey(subjectId)); if (cacheValue != null) { userId = cacheValue.getUserId(); @@ -94,15 +96,15 @@ public class UserInterceptor implements WebRequestInterceptor { private UUID getUserIdFromDatabaseBySubject(String subjectId) { CriteriaBuilder credentialCriteriaBuilder = this.entityManager.getCriteriaBuilder(); CriteriaQuery credentialQuery = credentialCriteriaBuilder.createQuery(Tuple.class); - Root credentialRoot = credentialQuery.from(Credential.class); + Root credentialRoot = credentialQuery.from(CredentialEntity.class); credentialQuery.where( credentialCriteriaBuilder.and( - credentialCriteriaBuilder.equal(credentialRoot.get(Credential._externalId), subjectId), - credentialCriteriaBuilder.equal(credentialRoot.get(Credential._status), 1), //TODO: Authn - credentialCriteriaBuilder.equal(credentialRoot.get(Credential._provider), 128) + credentialCriteriaBuilder.equal(credentialRoot.get(CredentialEntity._externalId), subjectId), + credentialCriteriaBuilder.equal(credentialRoot.get(CredentialEntity._isActive), IsActive.Active), + credentialCriteriaBuilder.equal(credentialRoot.get(CredentialEntity._provider), ProviderType.Keycloack) )); - credentialQuery.multiselect(credentialRoot.get(Credential._userInfo).get(UserInfo._id).alias(UserInfo._id)); + credentialQuery.multiselect(credentialRoot.get(CredentialEntity._userId).alias(UserInfo._id)); List results = this.entityManager.createQuery(credentialQuery).getResultList(); return this.getUUIDFromTuple(results, UserInfo._id); @@ -194,17 +196,17 @@ public class UserInterceptor implements WebRequestInterceptor { user.setAdditionalinfo("{\"data\":{\"avatar\":{\"url\":\"\"},\"zenodoToken\":\"\", \"expirationDate\": \"\", \"zenodoRefresh\": \"\", \"zenodoEmail\": \"\"}}"); //TODO: Authn } - Credential credential = new Credential(); - credential.setId(UUID.randomUUID()); - credential.setUserInfo(user); - credential.setSecret(subjectId); - credential.setCreationTime(new Date()); - credential.setLastUpdateTime(new Date()); - credential.setStatus(1); - credential.setProvider(128);//TODO: Authn - credential.setExternalId(subjectId); - credential.setEmail(email); - credential.setPublicValue(email); + CredentialEntity credentialEntity = new CredentialEntity(); + credentialEntity.setId(UUID.randomUUID()); + credentialEntity.setUserId(user.getId()); + credentialEntity.setSecret(subjectId); + credentialEntity.setCreationTime(new Date()); + credentialEntity.setLastUpdateTime(new Date()); + credentialEntity.setIsActive(IsActive.Active); + credentialEntity.setProvider(ProviderType.Keycloack);//TODO: Authn + credentialEntity.setExternalId(subjectId); + credentialEntity.setEmail(email); + credentialEntity.setPublicValue(email); DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); @@ -218,12 +220,12 @@ public class UserInterceptor implements WebRequestInterceptor { user = this.entityManager.merge(user); this.entityManager.flush(); userRole.setUserInfo(user); - credential.setUserInfo(user); + credentialEntity.setUserId(user.getId()); this.entityManager.merge(userRole); - this.entityManager.merge(credential); + this.entityManager.merge(credentialEntity); } else { this.entityManager.persist(user); - this.entityManager.persist(credential); + this.entityManager.persist(credentialEntity); } this.entityManager.flush(); transactionManager.commit(status); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/CredentialBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/CredentialBuilder.java index 14cbf0822..379b704e2 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/CredentialBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/CredentialBuilder.java @@ -1,7 +1,9 @@ package eu.eudat.logic.builders.entity; +import eu.eudat.commons.enums.ProviderType; +import eu.eudat.commons.enums.IsActive; +import eu.eudat.data.CredentialEntity; import eu.eudat.logic.builders.Builder; -import eu.eudat.data.entities.Credential; import eu.eudat.data.entities.UserInfo; import java.util.Date; @@ -10,15 +12,15 @@ import java.util.UUID; /** * Created by ikalyvas on 2/15/2018. */ -public class CredentialBuilder extends Builder { +public class CredentialBuilder extends Builder { private UUID id; private UserInfo userInfo; - private Integer status; + private IsActive isActive; - private Integer provider; + private ProviderType provider; private String publicValue; @@ -42,12 +44,12 @@ public class CredentialBuilder extends Builder { return this; } - public CredentialBuilder status(Integer status) { - this.status = status; + public CredentialBuilder status(IsActive isActive) { + this.isActive = isActive; return this; } - public CredentialBuilder provider(Integer provider) { + public CredentialBuilder provider(ProviderType provider) { this.provider = provider; return this; } @@ -82,15 +84,15 @@ public class CredentialBuilder extends Builder { return this; } - public Credential build() { - Credential credential = new Credential(); - credential.setStatus(status); + public CredentialEntity build() { + CredentialEntity credential = new CredentialEntity(); + credential.setIsActive(isActive); credential.setLastUpdateTime(lastUpdateTime); credential.setCreationTime(creationTime); credential.setProvider(provider); credential.setSecret(secret); credential.setPublicValue(publicValue); - credential.setUserInfo(userInfo); + credential.setUserId(userInfo.getId()); credential.setId(id); credential.setExternalId(externalId); credential.setEmail(email); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/UserInfoBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/UserInfoBuilder.java index e932d4299..29725bffb 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/UserInfoBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/UserInfoBuilder.java @@ -1,7 +1,7 @@ package eu.eudat.logic.builders.entity; +import eu.eudat.data.CredentialEntity; import eu.eudat.logic.builders.Builder; -import eu.eudat.data.entities.Credential; import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserRole; @@ -36,7 +36,7 @@ public class UserInfoBuilder extends Builder { private Set dmps; - private Set credentials = new HashSet<>(); + private Set credentials = new HashSet<>(); private Set userRoles = new HashSet<>(); @@ -92,7 +92,7 @@ public class UserInfoBuilder extends Builder { return this; } - public UserInfoBuilder credentials(Set credentials) { + public UserInfoBuilder credentials(Set credentials) { this.credentials = credentials; return this; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java index bc5cce484..85b38c967 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java @@ -24,10 +24,6 @@ public class PrincipalBuilder extends Builder { private String culture; private String language; private String timezone; - private String zenodoToken; - private Instant zenodoDuration; - private String zenodoEmail; - private String zenodoRefresh; public PrincipalBuilder id(UUID id) { this.id = id; @@ -79,25 +75,6 @@ public class PrincipalBuilder extends Builder { return this; } - public PrincipalBuilder zenodoToken(String zenodoToken) { - this.zenodoToken = zenodoToken; - return this; - } - - public PrincipalBuilder zenodoDuration(Instant zenodoDuration) { - this.zenodoDuration = zenodoDuration; - return this; - } - - public PrincipalBuilder zenodoEmail(String zenodoEmail) { - this.zenodoEmail = zenodoEmail; - return this; - } - - public PrincipalBuilder zenodoRefresh(String zenodoRefresh) { - this.zenodoRefresh = zenodoRefresh; - return this; - } @Override public Principal build() { @@ -112,10 +89,6 @@ public class PrincipalBuilder extends Builder { principal.setCulture(culture); principal.setLanguage(language); principal.setTimezone(timezone); - principal.setZenodoToken(zenodoToken); - principal.setZenodoDuration(zenodoDuration); - principal.setZenodoEmail(zenodoEmail); - principal.setZenodoRefresh(zenodoRefresh); return principal; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java b/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java index 5cdb96839..f185cfe2e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/handlers/PrincipalArgumentResolver.java @@ -1,6 +1,6 @@ package eu.eudat.logic.handlers; -import eu.eudat.commons.scope.UserScope; +import eu.eudat.commons.scope.user.UserScope; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.operations.authentication.AuthenticationService; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java index d82e2832b..067f9860a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java @@ -39,7 +39,7 @@ public class AdminManager { DescriptionTemplateTypeEntity type; try { - type = descriptionTemplateTypeService.getEntityByName(profile.getType()); + //TODO: dtziotzios type = descriptionTemplateTypeService.getEntityByName(profile.getType()); } catch (Exception e) { throw new Exception("Description template type '" + profile.getType() + "' could not be found."); @@ -47,7 +47,7 @@ public class AdminManager { DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getBuilderFactory().getBuilder(DatasetProfileBuilder.class).definition(xml).label(profile.getLabel()) .status(profile.getStatus()).created(new Date()).description(profile.getDescription()).language(profile.getLanguage()) - .type(type) + //TODO: dtziotzios .type(type) .build(); if (descriptionTemplate.getGroupId() == null) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java index 5f90c697b..e02724e43 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java @@ -1,6 +1,6 @@ package eu.eudat.logic.managers; -import eu.eudat.data.entities.Credential; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.entities.EmailConfirmation; import eu.eudat.data.entities.UserInfo; import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException; @@ -45,7 +45,7 @@ public class EmailConfirmationManager { // Checks if mail is used by another user. If it is, merges the new the old. Long existingUsers = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).count(); if (existingUsers > 0) { - Credential credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), user)).getSingle(); + CredentialEntity credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userId"), user.getId())).getSingle(); credential.setEmail(loginConfirmationEmail.getEmail()); databaseRepository.getCredentialDao().createOrUpdate(credential); UserInfo oldUser = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).getSingle(); @@ -57,8 +57,8 @@ public class EmailConfirmationManager { user.setEmail(loginConfirmationEmail.getEmail()); databaseRepository.getUserInfoDao().createOrUpdate(user); - Credential credential = databaseRepository.getCredentialDao().asQueryable() - .where((builder, root) -> builder.equal(root.get("userInfo"), user)).getSingle(); + CredentialEntity credential = databaseRepository.getCredentialDao().asQueryable() + .where((builder, root) -> builder.equal(root.get("userId"), user.getId())).getSingle(); if(credential.getEmail() == null){ credential.setEmail(user.getEmail()); databaseRepository.getCredentialDao().createOrUpdate(credential); @@ -80,8 +80,8 @@ public class EmailConfirmationManager { } private void mergeNewUserToOld(UserInfo newUser, UserInfo oldUser) { - Credential credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), newUser)).getSingle(); - credential.setUserInfo(oldUser); + CredentialEntity credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userId"), newUser.getId())).getSingle(); + credential.setUserId(oldUser.getId()); databaseRepository.getCredentialDao().createOrUpdate(credential); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java index dad5980e0..642fb92d8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java @@ -1,6 +1,6 @@ package eu.eudat.logic.managers; -import eu.eudat.data.entities.Credential; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.entities.EmailConfirmation; import eu.eudat.data.entities.UserDMP; import eu.eudat.data.entities.UserInfo; @@ -86,8 +86,8 @@ public class MergeEmailConfirmationManager { @Transactional private void mergeNewUserToOld(UserInfo newUser, UserInfo oldUser, Integer provider) { - Credential credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.and(builder.equal(root.get("userInfo"), oldUser), builder.equal(root.get("provider"), provider))).getSingle(); - credential.setUserInfo(newUser); + CredentialEntity credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.and(builder.equal(root.get("userId"), oldUser.getId()), builder.equal(root.get("provider"), provider))).getSingle(); + credential.setUserId(newUser.getId()); databaseRepository.getCredentialDao().createOrUpdate(credential); List userDmps = databaseRepository.getUserDmpDao().asQueryable().where((builder, root) -> builder.equal(root.get("user"), oldUser)).toList(); userDmps.forEach(userDmp -> { @@ -128,7 +128,7 @@ public class MergeEmailConfirmationManager { } oldUser.setUserStatus((short)1); oldUser.setEmail(null); - List credentials = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), oldUser)).toList(); + List credentials = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userId"), oldUser.getId())).toList(); credentials.forEach(cred -> { if (cred.getId() != credential.getId()) { databaseRepository.getCredentialDao().delete(cred); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java index 06835e25c..452a11a86 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java @@ -2,7 +2,7 @@ package eu.eudat.logic.managers; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import eu.eudat.data.entities.Credential; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.entities.EmailConfirmation; import eu.eudat.data.entities.UserInfo; import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException; @@ -64,7 +64,7 @@ public class UnlinkEmailConfirmationManager { @Transactional private void unlinkUser(String emailTobeUnlinked, Integer provider){ - Credential credential = databaseRepository.getCredentialDao().asQueryable() + CredentialEntity credential = databaseRepository.getCredentialDao().asQueryable() .where((builder, root) -> builder.and(builder.equal(root.get("email"), emailTobeUnlinked), builder.equal(root.get("provider"), provider))).getSingle(); if(credential != null) { databaseRepository.getCredentialDao().delete(credential); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java index 0e74dcd46..54e009158 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java @@ -1,33 +1,28 @@ package eu.eudat.logic.managers; import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.dao.criteria.DataManagementPlanCriteria; import eu.eudat.data.dao.entities.UserInfoDao; -import eu.eudat.data.entities.*; +import eu.eudat.data.entities.DMP; +import eu.eudat.data.entities.DescriptionTemplate; +import eu.eudat.data.entities.UserInfo; +import eu.eudat.data.entities.UserRole; import eu.eudat.data.query.items.table.userinfo.UserInfoTableRequestItem; -import eu.eudat.exceptions.security.NullEmailException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.builders.entity.UserRoleBuilder; import eu.eudat.logic.builders.model.models.DataTableDataBuilder; -import eu.eudat.logic.security.customproviders.Zenodo.ZenodoAccessType; -import eu.eudat.logic.security.customproviders.Zenodo.ZenodoCustomProvider; -import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken; import eu.eudat.logic.services.ApiContext; -import eu.eudat.logic.services.operations.authentication.AuthenticationService; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.models.HintedModelFactory; import eu.eudat.models.data.dmp.DataManagementPlan; -import eu.eudat.models.data.doi.DOIRequest; import eu.eudat.models.data.helpers.common.DataTableData; -import eu.eudat.models.data.login.Credentials; -import eu.eudat.models.data.principal.PrincipalModel; import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.userinfo.UserCredential; import eu.eudat.models.data.userinfo.UserListingModel; import eu.eudat.models.data.userinfo.UserProfile; import eu.eudat.queryable.QueryableList; import eu.eudat.types.Authorities; - import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,14 +36,8 @@ import org.springframework.stereotype.Component; import org.w3c.dom.Document; import org.w3c.dom.Element; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.nio.file.Files; -import java.time.Instant; import java.util.*; import java.util.stream.Collectors; @@ -57,13 +46,11 @@ public class UserManager { private static final Logger logger = LoggerFactory.getLogger(UserManager.class); private ApiContext apiContext; - private ZenodoCustomProvider zenodoCustomProvider; private Environment environment; @Autowired - public UserManager(ApiContext apiContext, ZenodoCustomProvider zenodoCustomProvider, Environment environment) { + public UserManager(ApiContext apiContext, Environment environment) { this.apiContext = apiContext; - this.zenodoCustomProvider = zenodoCustomProvider; this.environment = environment; } @@ -89,7 +76,7 @@ public class UserManager { public List getCredentials(UUID userId) { List results = new ArrayList<>(); eu.eudat.data.entities.UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(userId); - List credentials = apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), user)).toList(); + List credentials = apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userId"), user.getId())).toList(); credentials.forEach(credential -> { UserCredential userCredential = new UserCredential(); userCredential.setEmail(credential.getEmail()); @@ -147,27 +134,6 @@ public class UserManager { return dataTableData; } - public void registerDOIToken(DOIRequest doiRequest, Principal principal) throws IOException { //TODO: Authn - ZenodoResponseToken responseToken = this.zenodoCustomProvider.getAccessToken(ZenodoAccessType.AUTHORIZATION_CODE, - doiRequest.getZenodoRequest().getCode(), this.environment.getProperty("zenodo.login.client_id"), - this.environment.getProperty("zenodo.login.client_secret"), doiRequest.getRedirectUri()); - Map settings = new HashMap<>(); - settings.put("zenodoEmail", responseToken.getEmail()); - settings.put("zenodoRefresh", responseToken.getRefreshToken()); - settings.put("zenodoToken", responseToken.getAccessToken()); - settings.put("expirationDate", Instant.now().plusSeconds(responseToken.getExpiresIn()).toEpochMilli()); - this.updateSettings(settings, principal); - } - - public void deleteDOIToken(Principal principal) throws IOException { - Map settings = new HashMap<>(); - settings.put("zenodoEmail", ""); - settings.put("zenodoRefresh", ""); - settings.put("zenodoToken", ""); - settings.put("expirationDate", 0); - this.updateSettings(settings, principal); - } - public ResponseEntity exportToCsv(Principal principal) throws IOException { if (!principal.getAuthz().contains(Authorities.ADMIN)) throw new UnauthorisedException(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoAccessType.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoAccessType.java deleted file mode 100644 index 79b077853..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoAccessType.java +++ /dev/null @@ -1,22 +0,0 @@ -package eu.eudat.logic.security.customproviders.Zenodo; - -public enum ZenodoAccessType { - AUTHORIZATION_CODE("authorization_code", "code"), - REFRESH_TOKEN("refresh_token", "refresh_token"); - - private final String grantType; - private final String property; - - ZenodoAccessType(String grantType, String property) { - this.grantType = grantType; - this.property = property; - } - - public String getGrantType() { - return grantType; - } - - public String getProperty() { - return property; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoCustomProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoCustomProvider.java deleted file mode 100644 index 0fd0e5cca..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoCustomProvider.java +++ /dev/null @@ -1,7 +0,0 @@ -package eu.eudat.logic.security.customproviders.Zenodo; - -import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken; - -public interface ZenodoCustomProvider { - ZenodoResponseToken getAccessToken(ZenodoAccessType accessType, String code, String clientId, String clientSecret, String redirectUri); -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoCustomProviderImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoCustomProviderImpl.java deleted file mode 100644 index a3f440b81..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoCustomProviderImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -package eu.eudat.logic.security.customproviders.Zenodo; - -import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoResponseToken; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; - -import java.io.IOException; -import java.util.Collections; -import java.util.Map; - -@Component("ZenodoCustomProvider") -public class ZenodoCustomProviderImpl implements ZenodoCustomProvider { - private static final Logger logger = LoggerFactory.getLogger(ZenodoCustomProviderImpl.class); - - private Environment environment; - - @Autowired - public ZenodoCustomProviderImpl(Environment environment) { - this.environment = environment; - } - - @Override - public ZenodoResponseToken getAccessToken(ZenodoAccessType accessType, String code, String clientId, String clientSecret, String redirectUri) { - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - headers.setContentType(MediaType.MULTIPART_FORM_DATA); - - MultiValueMap map = new LinkedMultiValueMap<>(); - map.add("client_id", clientId); - map.add("client_secret", clientSecret); - map.add("grant_type", accessType.getGrantType()); - map.add(accessType.getProperty(), code); - map.add("redirect_uri", redirectUri); - HttpEntity> request = new HttpEntity<>(map, headers); - - try { - Map values = restTemplate.postForObject(this.environment.getProperty("zenodo.login.access_token_url"), request, Map.class); - ZenodoResponseToken zenodoResponseToken = new ZenodoResponseToken(); - Map user = (Map) values.get("user"); - zenodoResponseToken.setUserId((String) user.get("id")); - zenodoResponseToken.setEmail((String) user.get("email")); - zenodoResponseToken.setExpiresIn((Integer) values.get("expires_in")); - zenodoResponseToken.setAccessToken((String) values.get("access_token")); - zenodoResponseToken.setRefreshToken((String) values.get("refresh_token")); - - return zenodoResponseToken; - } catch (HttpClientErrorException ex) { - logger.error(ex.getResponseBodyAsString(), ex); - } - - return null; - } - - private HttpHeaders createBearerAuthHeaders(String accessToken) { - return new HttpHeaders() {{ - String authHeader = "Bearer " + accessToken; - set("Authorization", authHeader); - }}; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoUser.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoUser.java deleted file mode 100644 index 92480c202..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/Zenodo/ZenodoUser.java +++ /dev/null @@ -1,59 +0,0 @@ -package eu.eudat.logic.security.customproviders.Zenodo; - -import java.util.Map; - -public class ZenodoUser { - private String userId; - private String email; - private String accessToken; - private Integer expiresIn; - private String refreshToken; - - public String getUserId() { - return userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - - public String getEmail() { - return email; - } - public void setEmail(String email) { - this.email = email; - } - - public String getAccessToken() { - return accessToken; - } - - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - public Integer getExpiresIn() { - return expiresIn; - } - - public void setExpiresIn(Integer expiresIn) { - this.expiresIn = expiresIn; - } - - public String getRefreshToken() { - return refreshToken; - } - - public void setRefreshToken(String refreshToken) { - this.refreshToken = refreshToken; - } - - public ZenodoUser getZenodoUser(Object data) { - this.userId = (String) ((Map) data).get("userId"); - this.email = (String) ((Map) data).get("email"); - this.accessToken = (String) ((Map) data).get("accessToken"); - this.expiresIn = (Integer) ((Map) data).get("expiresIn"); - this.refreshToken = (String) ((Map) data).get("refreshToken"); - return this; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/zenodo/helpers/ZenodoRequest.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/zenodo/helpers/ZenodoRequest.java deleted file mode 100644 index c1f4ea32a..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/zenodo/helpers/ZenodoRequest.java +++ /dev/null @@ -1,12 +0,0 @@ -package eu.eudat.logic.security.validators.zenodo.helpers; - -public class ZenodoRequest { - private String code; - - public String getCode() { - return code; - } - public void setCode(String code) { - this.code = code; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/zenodo/helpers/ZenodoResponseToken.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/zenodo/helpers/ZenodoResponseToken.java deleted file mode 100644 index 6c8783acf..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/zenodo/helpers/ZenodoResponseToken.java +++ /dev/null @@ -1,47 +0,0 @@ -package eu.eudat.logic.security.validators.zenodo.helpers; - -public class ZenodoResponseToken { - private String userId; - private String email; - private Integer expiresIn; - private String accessToken; - private String refreshToken; - - public String getUserId() { - return userId; - } - public void setUserId(String userId) { - this.userId = userId; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public Integer getExpiresIn() { - return expiresIn; - } - - public void setExpiresIn(Integer expiresIn) { - this.expiresIn = expiresIn; - } - - public String getAccessToken() { - return accessToken; - } - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - public String getRefreshToken() { - return refreshToken; - } - - public void setRefreshToken(String refreshToken) { - this.refreshToken = refreshToken; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java index 111e91649..12a341fb4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java @@ -49,10 +49,6 @@ public class NonVerifiedUserEmailAuthenticationService extends AbstractAuthentic .culture("") .language("") .timezone("") - .zenodoToken("") - .zenodoDuration(Instant.now()) - .zenodoEmail("") - .zenodoRefresh("") .build(); principalItem.setAuthorities(new HashSet<>()); principalItem.getAuthz().add(Authorities.USER); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java index 6771d50f5..36e399ae6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java @@ -38,30 +38,6 @@ public class VerifiedUserAuthenticationService extends AbstractAuthenticationSer } catch (Exception e) { avatarUrl = ""; } - String zenodoToken; - try { - zenodoToken = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoToken").asText() : ""; - } catch (Exception e) { - zenodoToken = ""; - } - Instant zenodoDuration; - try { - zenodoDuration = user.getAdditionalinfo() != null ? Instant.ofEpochMilli(new ObjectMapper().readTree(user.getAdditionalinfo()).get("expirationDate").asLong()) : Instant.now(); - } catch (Exception e) { - zenodoDuration = Instant.now(); - } - String zenodoEmail; - try { - zenodoEmail = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoEmail").asText() : ""; - } catch (Exception e) { - zenodoEmail = ""; - } - String zenodoRefresh; - try { - zenodoRefresh = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("zenodoRefresh").asText() : ""; - } catch (Exception e) { - zenodoRefresh = ""; - } String culture; try { culture = user.getAdditionalinfo() != null ? new ObjectMapper().readTree(user.getAdditionalinfo()).get("culture").get("name").asText() : ""; @@ -89,10 +65,6 @@ public class VerifiedUserAuthenticationService extends AbstractAuthenticationSer .culture(culture) .language(language) .timezone(timezone) - .zenodoToken(zenodoToken) - .zenodoDuration(zenodoDuration) - .zenodoEmail(zenodoEmail) - .zenodoRefresh(zenodoRefresh) .build(); List userRoles = apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().getUserRoles(user); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DOIRequest.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DOIRequest.java deleted file mode 100644 index 8338a75ac..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DOIRequest.java +++ /dev/null @@ -1,25 +0,0 @@ -package eu.eudat.models.data.doi; - -import eu.eudat.logic.security.validators.zenodo.helpers.ZenodoRequest; - -public class DOIRequest { - - private ZenodoRequest zenodoRequest; - private String redirectUri; - - public ZenodoRequest getZenodoRequest() { - return zenodoRequest; - } - - public void setZenodoRequest(ZenodoRequest zenodoRequest) { - this.zenodoRequest = zenodoRequest; - } - - public String getRedirectUri() { - return redirectUri; - } - - public void setRedirectUri(String redirectUri) { - this.redirectUri = redirectUri; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/loginprovider/LoginProviderUser.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/loginprovider/LoginProviderUser.java index 15ed1bda1..08e8303e4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/loginprovider/LoginProviderUser.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/loginprovider/LoginProviderUser.java @@ -8,9 +8,6 @@ public class LoginProviderUser { private String secret; private String avatarUrl; private boolean isVerified; - private String zenodoId; - private Integer zenodoExpire; - private String zenodoRefresh; public String getId() { return id; @@ -59,28 +56,4 @@ public class LoginProviderUser { public void setAvatarUrl(String avatarUrl) { this.avatarUrl = avatarUrl; } - - public String getZenodoId() { - return zenodoId; - } - - public void setZenodoId(String zenodoId) { - this.zenodoId = zenodoId; - } - - public Integer getZenodoExpire() { - return zenodoExpire; - } - - public void setZenodoExpire(Integer zenodoExpire) { - this.zenodoExpire = zenodoExpire; - } - - public String getZenodoRefresh() { - return zenodoRefresh; - } - - public void setZenodoRefresh(String zenodoRefresh) { - this.zenodoRefresh = zenodoRefresh; - } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/principal/PrincipalModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/principal/PrincipalModel.java index e5604dfb3..113a3b7e4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/principal/PrincipalModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/principal/PrincipalModel.java @@ -19,7 +19,6 @@ public class PrincipalModel { private String culture; private String language; private String timezone; - private String zenodoEmail; public UUID getId() { return id; @@ -105,14 +104,6 @@ public class PrincipalModel { this.timezone = timezone; } - public String getZenodoEmail() { - return zenodoEmail; - } - - public void setZenodoEmail(String zenodoEmail) { - this.zenodoEmail = zenodoEmail; - } - public static PrincipalModel fromEntity(Principal principal) { PrincipalModel model = new PrincipalModel(); model.setId(principal.getId()); @@ -125,7 +116,6 @@ public class PrincipalModel { model.setLanguage(principal.getLanguage()); model.setName(principal.getName()); model.setTimezone(principal.getTimezone()); - model.setZenodoEmail(principal.getZenodoEmail()); return model; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java index b7231ca78..70c9cad0c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java @@ -19,10 +19,6 @@ public class Principal { private String culture; private String language; private String timezone; - private String zenodoToken; - private Instant zenodoDuration; - private String zenodoRefresh; - private String zenodoEmail; public UUID getId() { return id; @@ -100,38 +96,6 @@ public class Principal { this.timezone = timezone; } - public String getZenodoToken() { - return zenodoToken; - } - - public void setZenodoToken(String zenodoToken) { - this.zenodoToken = zenodoToken; - } - - public Instant getZenodoDuration() { - return zenodoDuration; - } - - public void setZenodoDuration(Instant zenodoDuration) { - this.zenodoDuration = zenodoDuration; - } - - public String getZenodoRefresh() { - return zenodoRefresh; - } - - public void setZenodoRefresh(String zenodoRefresh) { - this.zenodoRefresh = zenodoRefresh; - } - - public String getZenodoEmail() { - return zenodoEmail; - } - - public void setZenodoEmail(String zenodoEmail) { - this.zenodoEmail = zenodoEmail; - } - @JsonIgnore public Set getAuthz() { return this.authorities; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserCredential.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserCredential.java index e2ce326f8..93f3a1fa3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserCredential.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserCredential.java @@ -1,18 +1,20 @@ package eu.eudat.models.data.userinfo; +import eu.eudat.commons.enums.ProviderType; + public class UserCredential { private String email; - private Integer provider; + private ProviderType provider; public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } - public Integer getProvider() { + public ProviderType getProvider() { return provider; } - public void setProvider(Integer provider) { + public void setProvider(ProviderType provider) { this.provider = provider; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserProfile.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserProfile.java index 28bea2de8..c6f04af26 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserProfile.java @@ -28,7 +28,6 @@ public class UserProfile implements DataModel associatedDmps; - private String zenodoEmail; private Map language; private String timezone; private Map culture; @@ -92,13 +91,6 @@ public class UserProfile implements DataModel getLanguage() { return language; @@ -163,7 +155,6 @@ public class UserProfile implements DataModel) additionalInfo.get("organization")); this.roleOrganization = (String) additionalInfo.get("roleOrganization"); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/v2/Account.java b/dmp-backend/web/src/main/java/eu/eudat/models/v2/Account.java index 3991ef43d..f82e33126 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/v2/Account.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/v2/Account.java @@ -139,6 +139,9 @@ public class Account { public final static String _principal = "principal"; private PrincipalInfo principal; + public final static String _permissions = "permissions"; + private List permissions; + public PrincipalInfo getPrincipal() { return principal; } @@ -162,4 +165,16 @@ public class Account { public void setRoles(List roles) { this.roles = roles; } + + public void setAuthenticated(Boolean authenticated) { + isAuthenticated = authenticated; + } + + public List getPermissions() { + return permissions; + } + + public void setPermissions(List permissions) { + this.permissions = permissions; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/v2/AccountBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/models/v2/AccountBuilder.java index 67bad2fcc..ad1a31b50 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/v2/AccountBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/v2/AccountBuilder.java @@ -1,10 +1,10 @@ package eu.eudat.models.v2; -import eu.eudat.commons.scope.UserScope; +import eu.eudat.commons.scope.user.UserScope; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserRole; import eu.eudat.logic.services.ApiContext; -import eu.eudat.types.Authorities; +import gr.cite.commons.web.authz.configuration.AuthorizationConfiguration; import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver; import gr.cite.commons.web.oidc.principal.MyPrincipal; import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor; @@ -24,11 +24,13 @@ public class AccountBuilder { private final ClaimExtractor claimExtractor; private final Set excludeMoreClaim; private final CurrentPrincipalResolver currentPrincipalResolver; + private final AuthorizationConfiguration authorizationConfiguration; private final ApiContext apiContext; private final UserScope userScope; - public AccountBuilder(ClaimExtractor claimExtractor, CurrentPrincipalResolver currentPrincipalResolver, ApiContext apiContext, UserScope userScope) { + public AccountBuilder(ClaimExtractor claimExtractor, CurrentPrincipalResolver currentPrincipalResolver, AuthorizationConfiguration authorizationConfiguration, ApiContext apiContext, UserScope userScope) { this.claimExtractor = claimExtractor; this.currentPrincipalResolver = currentPrincipalResolver; + this.authorizationConfiguration = authorizationConfiguration; this.apiContext = apiContext; this.userScope = userScope; this.excludeMoreClaim = Set.of( @@ -93,6 +95,11 @@ public class AccountBuilder { model.getRoles().add(item.getRole()); } } + if (fields.hasField(Account._permissions)) { + List roles = claimExtractor.roles(currentPrincipalResolver.currentPrincipal()); + Set permissions = authorizationConfiguration.permissionsOfRoles(roles); + model.setPermissions(new ArrayList<>(permissions)); + } return model; } } diff --git a/dmp-backend/web/src/main/resources/config/application.yml b/dmp-backend/web/src/main/resources/config/application.yml index e0cf36a95..ced49fdd3 100644 --- a/dmp-backend/web/src/main/resources/config/application.yml +++ b/dmp-backend/web/src/main/resources/config/application.yml @@ -4,6 +4,7 @@ spring: config: import: optional:classpath:config/app.env[.properties], optional:file:../config/app.env[.properties], optional:classpath:config/db.yml[.yml], optional:classpath:config/db-${spring.profiles.active}.yml[.yml], optional:file:../config/db-${spring.profiles.active}.yml[.yml], + optional:classpath:config/permissions.yml[.yml], optional:classpath:config/permissions-${spring.profiles.active}.yml[.yml], optional:file:../config/permissions-${spring.profiles.active}.yml[.yml], optional:classpath:config/security.yml[.yml], optional:classpath:config/security-${spring.profiles.active}.yml[.yml], optional:file:../config/security-${spring.profiles.active}.yml[.yml], optional:classpath:config/server.yml[.yml], optional:classpath:config/server-${spring.profiles.active}.yml[.yml], optional:file:../config/server-${spring.profiles.active}.yml[.yml], optional:classpath:config/logging.yml[.yml], optional:classpath:config/logging-${spring.profiles.active}.yml[.yml], optional:file:../config/logging-${spring.profiles.active}.yml[.yml], diff --git a/dmp-backend/web/src/main/resources/config/permissions.yml b/dmp-backend/web/src/main/resources/config/permissions.yml new file mode 100644 index 000000000..1d61b4aa4 --- /dev/null +++ b/dmp-backend/web/src/main/resources/config/permissions.yml @@ -0,0 +1,31 @@ +permissions: + extendedClaims: [ ] + policies: + # Users + BrowseDescriptionTemplateType: + roles: + - Admin + clients: [ ] + allowAnonymous: true + allowAuthenticated: false + EditDescriptionTemplateType: + roles: + - Admin + clients: [ ] + allowAnonymous: false + allowAuthenticated: false + DeleteDescriptionTemplateType: + roles: + - Admin + claims: [ ] + clients: [ ] + allowAnonymous: false + allowAuthenticated: false + + # ViewPage Permissions + ViewDescriptionTemplateTypePage: + roles: + - Admin + clients: [ ] + allowAnonymous: false + allowAuthenticated: false diff --git a/dmp-backend/web/src/main/resources/config/security.yml b/dmp-backend/web/src/main/resources/config/security.yml index 05be0b203..fc814c498 100644 --- a/dmp-backend/web/src/main/resources/config/security.yml +++ b/dmp-backend/web/src/main/resources/config/security.yml @@ -17,13 +17,4 @@ web: client-secret: ${IDP_OPAQUE_CLIENT_SECRET:} jwt: claims: [ role, x-role ] - issuer-uri: ${IDP_ISSUER_URI:} - -zenodo: - affiliation: ARGOS - community: argos - login: - access_token_url: ${ZENODO_ACCESS_TOKEN_URL:} - client_id: ${ZENODO_CLIENT_ID:} - client_secret: ${ZENODO_CLIENT_SECRET:} - redirect_uri: http://localhost:4200/login/external/zenodo \ No newline at end of file + issuer-uri: ${IDP_ISSUER_URI:} \ No newline at end of file diff --git a/dmp-db-scema/updates/00.01.001_Align_Description_Template_Type.sql b/dmp-db-scema/updates/00.01.001_Align_Description_Template_Type.sql new file mode 100644 index 000000000..f45526f8b --- /dev/null +++ b/dmp-db-scema/updates/00.01.001_Align_Description_Template_Type.sql @@ -0,0 +1,23 @@ +ALTER TABLE public."DescriptionTemplateType" + RENAME "ID" TO id; + +ALTER TABLE public."DescriptionTemplateType" + RENAME "Name" TO name; + +ALTER TABLE public."DescriptionTemplateType" + RENAME "Status" TO is_active; + +ALTER TABLE public."DescriptionTemplateType" + ADD COLUMN created_at timestamp without time zone; + +ALTER TABLE public."DescriptionTemplateType" + ADD COLUMN updated_at timestamp without time zone; + +UPDATE public."DescriptionTemplateType" SET created_at = now(); +UPDATE public."DescriptionTemplateType" SET updated_at = now(); + +ALTER TABLE public."DescriptionTemplateType" + ALTER COLUMN created_at SET NOT NULL; + +ALTER TABLE public."DescriptionTemplateType" + ALTER COLUMN updated_at SET NOT NULL; diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index 62d9578cd..d418c98f7 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -3,6 +3,7 @@ import { RouterModule, Routes } from '@angular/router'; import { ReloadHelperComponent } from '@app/ui/misc/reload-helper/reload-helper.component'; import { Oauth2DialogComponent } from './ui/misc/oauth2-dialog/oauth2-dialog.component'; import { AppComponent } from './app.component'; +import { AppPermission } from './core/common/enum/permission.enum'; const appRoutes: Routes = [ { @@ -102,8 +103,11 @@ const appRoutes: Routes = [ loadChildren: () => import('./ui/admin/description-types/description-types.module').then(m => m.DescriptionTypesModule), data: { breadcrumb: true, - title: 'GENERAL.TITLES.DESCRIPTION-TYPES' - } + title: 'GENERAL.TITLES.DESCRIPTION-TYPES', + authContext: { + permissions: [AppPermission.ViewDescriptionTemplateTypePage] + } + }, }, { path: 'contact-support', @@ -237,13 +241,6 @@ const appRoutes: Routes = [ breadcrumb: true }, }, - { - path: 'login/admin', - loadChildren: () => import('./ui/auth/admin-login/admin-login.module').then(m => m.AdminLoginModule), - data: { - breadcrumb: true - }, - }, { path: 'login', loadChildren: () => import('./ui/auth/login/login.module').then(m => m.LoginModule), @@ -255,14 +252,6 @@ const appRoutes: Routes = [ { path: 'logout', loadChildren: () => import('./ui/auth/logout/logout.module').then(m => m.LogoutModule) }, { path: 'reload', component: ReloadHelperComponent }, { path: 'oauth2', component: Oauth2DialogComponent }, - { - path: 'external', - loadChildren: () => import('./ui/external/external.module').then(m => m.ExternalModule), - data: { - breadcrumb: true, - - }, - } ]; @NgModule({ diff --git a/dmp-frontend/src/app/core/auth-guard.service.ts b/dmp-frontend/src/app/core/auth-guard.service.ts index cc1d878a4..e6df4cc28 100644 --- a/dmp-frontend/src/app/core/auth-guard.service.ts +++ b/dmp-frontend/src/app/core/auth-guard.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, CanActivate, CanLoad, Route, Router, RouterStateSnapshot } from '@angular/router'; -import { AuthService } from './services/auth/auth.service'; +import { AuthService, ResolutionContext } from './services/auth/auth.service'; import { from, Observable, of as observableOf } from 'rxjs'; import { catchError, map, tap } from 'rxjs/operators'; @@ -11,25 +11,32 @@ export class AuthGuard implements CanActivate, CanLoad { canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { const url: string = state.url; - return this.applyGuard(url); + const authContext = route.data ? route.data['authContext'] as ResolutionContext : null; + return this.applyGuard(url, authContext); } canLoad(route: Route): Observable { const url = `/${route.path}`; - return this.applyGuard(url); + const authContext = route.data ? route.data['authContext'] as ResolutionContext : null; + return this.applyGuard(url, authContext); } - private applyGuard(url: string) { - return this.checkLogin(url).pipe(tap(loggedIn => { + private applyGuard(url: string, authContext: ResolutionContext) { + return this.checkLogin(url, authContext).pipe(tap(loggedIn => { if (!loggedIn) { this.router.navigate(['/unauthorized'], { queryParams: { returnUrl: url } }); - } else{ - return true; + } else { + const authorized = this.authService.hasAccessToken() && this.authService.authorize(authContext); + if(!authorized){ + this.router.navigate(['/unauthorized']); + }else{ + return authorized; + } } })); } - private checkLogin(url: string): Observable { + private checkLogin(url: string, authContext: ResolutionContext): Observable { if (!this.authService.isLoggedIn()) { return observableOf(false); } return this.authService.hasAccessToken() diff --git a/dmp-frontend/src/app/core/common/enum/permission.enum.ts b/dmp-frontend/src/app/core/common/enum/permission.enum.ts new file mode 100644 index 000000000..063694faf --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/permission.enum.ts @@ -0,0 +1,10 @@ +export enum AppPermission { + //DescriptionTemplateType + BrowseDescriptionTemplateType = "BrowseDescriptionTemplateType", + EditDescriptionTemplateType = "EditDescriptionTemplateType", + DeleteDescriptionTemplateType = "DeleteDescriptionTemplateType", + + // UI Pages + ViewDescriptionTemplateTypePage = "ViewDescriptionTemplateTypePage" +} + diff --git a/dmp-frontend/src/app/core/model/auth/credential.ts b/dmp-frontend/src/app/core/model/auth/credential.ts deleted file mode 100644 index a8c5d4f6b..000000000 --- a/dmp-frontend/src/app/core/model/auth/credential.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface Credential { - username: string; - secret: string; -} diff --git a/dmp-frontend/src/app/core/model/auth/login-info.ts b/dmp-frontend/src/app/core/model/auth/login-info.ts deleted file mode 100644 index 6c6aa497a..000000000 --- a/dmp-frontend/src/app/core/model/auth/login-info.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { AuthProvider } from "../../common/enum/auth-provider"; - -export interface LoginInfo { - ticket: string; - provider: AuthProvider; - data?: any; -} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/auth/principal.ts b/dmp-frontend/src/app/core/model/auth/principal.ts index eb916313c..c0012e7cd 100644 --- a/dmp-frontend/src/app/core/model/auth/principal.ts +++ b/dmp-frontend/src/app/core/model/auth/principal.ts @@ -1,10 +1,12 @@ import { AppRole } from "@app/core/common/enum/app-role"; +import { AppPermission } from "@app/core/common/enum/permission.enum"; import { Guid } from "@common/types/guid"; export interface AppAccount { isAuthenticated: boolean; // permissions: AppPermission[]; roles: AppRole[]; + permissions: AppPermission[]; principal: AppPrincipalInfo; profile: UserProfileInfo; } diff --git a/dmp-frontend/src/app/core/model/configurable-provider/configurableProvider.ts b/dmp-frontend/src/app/core/model/configurable-provider/configurableProvider.ts deleted file mode 100644 index d69525c1c..000000000 --- a/dmp-frontend/src/app/core/model/configurable-provider/configurableProvider.ts +++ /dev/null @@ -1,6 +0,0 @@ -export class ConfigurableProvider { - configurableLoginId: string; - type: string; - name: string; - logoUrl: string; -} diff --git a/dmp-frontend/src/app/core/model/configurable-provider/oauth2ConfigurableProvider.ts b/dmp-frontend/src/app/core/model/configurable-provider/oauth2ConfigurableProvider.ts deleted file mode 100644 index 7080cbccc..000000000 --- a/dmp-frontend/src/app/core/model/configurable-provider/oauth2ConfigurableProvider.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ConfigurableProvider } from "./configurableProvider"; - -export class Oauth2ConfigurableProvider extends ConfigurableProvider{ - clientId: string; - redirect_uri: string; - oauthUrl: string; - scope: string; - state: string; -} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/configurable-provider/saml2ConfigurableProvider.ts b/dmp-frontend/src/app/core/model/configurable-provider/saml2ConfigurableProvider.ts deleted file mode 100644 index 997e62466..000000000 --- a/dmp-frontend/src/app/core/model/configurable-provider/saml2ConfigurableProvider.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ConfigurableProvider } from "./configurableProvider"; - -export class Saml2ConfigurableProvider extends ConfigurableProvider{ - spEntityId: string; - idpUrl: string; - binding: string; - assertionConsumerServiceUrl: string; -} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/configuration-models/keycloak-configuration.model.ts b/dmp-frontend/src/app/core/model/configuration-models/keycloak-configuration.model.ts index ff4a84d92..bb40cb15d 100644 --- a/dmp-frontend/src/app/core/model/configuration-models/keycloak-configuration.model.ts +++ b/dmp-frontend/src/app/core/model/configuration-models/keycloak-configuration.model.ts @@ -1,5 +1,4 @@ import { KeycloakFlow } from 'keycloak-js'; -import { LoginConfiguration } from './login-configuration.model'; export class KeycloakConfiguration { diff --git a/dmp-frontend/src/app/core/model/configuration-models/login-configuration.model.ts b/dmp-frontend/src/app/core/model/configuration-models/login-configuration.model.ts deleted file mode 100644 index 18f467e99..000000000 --- a/dmp-frontend/src/app/core/model/configuration-models/login-configuration.model.ts +++ /dev/null @@ -1,22 +0,0 @@ -export class LoginConfiguration { - - private _clientId: string; - get clientId(): string { - return this._clientId; - } - - private _oauthUrl: string; - get oauthUrl(): string { - return this._oauthUrl; - } - - private _redirectUri: string; - get redirectUri(): string { - return this._redirectUri; - } - - private _state: string; - get state(): string { - return this._state; - } -} diff --git a/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts b/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts index 1b2812e09..67af2f190 100644 --- a/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts +++ b/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts @@ -2,4 +2,4 @@ export interface DescriptionTemplateType { id: string; name: string; status: number; -} \ No newline at end of file +} diff --git a/dmp-frontend/src/app/core/model/orcid/orcidUser.ts b/dmp-frontend/src/app/core/model/orcid/orcidUser.ts deleted file mode 100644 index 5642ee8fb..000000000 --- a/dmp-frontend/src/app/core/model/orcid/orcidUser.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class OrcidUser { - orcidId: string; - name: string; - email: string; -} diff --git a/dmp-frontend/src/app/core/model/saml2/AuthnRequestModel.ts b/dmp-frontend/src/app/core/model/saml2/AuthnRequestModel.ts deleted file mode 100644 index 683dba6fa..000000000 --- a/dmp-frontend/src/app/core/model/saml2/AuthnRequestModel.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface AuthnRequestModel { - authnRequestXml: string; - relayState: string; - algorithm: string; - signature: string; -} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/user/user-listing.ts b/dmp-frontend/src/app/core/model/user/user-listing.ts index 89e792cff..3c79e8664 100644 --- a/dmp-frontend/src/app/core/model/user/user-listing.ts +++ b/dmp-frontend/src/app/core/model/user/user-listing.ts @@ -11,7 +11,6 @@ export interface UserListingModel { language: any; culture: any; timezone: String; - zenodoEmail: String; avatarUrl: String; organization: OrganizationModel; roleOrganization: RoleOrganizationType; diff --git a/dmp-frontend/src/app/core/model/zenodo/zenodo-token.model.ts b/dmp-frontend/src/app/core/model/zenodo/zenodo-token.model.ts deleted file mode 100644 index a1428496f..000000000 --- a/dmp-frontend/src/app/core/model/zenodo/zenodo-token.model.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class ZenodoToken { - userId: string; - expiresIn: number; - accessToken:string; - email: string; - refreshToken: string; -} diff --git a/dmp-frontend/src/app/core/query/description-template/description-template-type.lookup.ts b/dmp-frontend/src/app/core/query/description-template/description-template-type.lookup.ts index f3da70996..2acefc395 100644 --- a/dmp-frontend/src/app/core/query/description-template/description-template-type.lookup.ts +++ b/dmp-frontend/src/app/core/query/description-template/description-template-type.lookup.ts @@ -1,8 +1,12 @@ +import { Status } from "@app/core/common/enum/status"; import { Lookup } from "@common/model/lookup"; +import { Guid } from "@common/types/guid"; export class DescriptionTemplateTypeLookup extends Lookup { - name: string; - status: number; + ids: Guid[]; + excludedIds: Guid[]; + like: string; + isActive: Status[]; constructor() { super(); diff --git a/dmp-frontend/src/app/core/services/auth/auth.service.ts b/dmp-frontend/src/app/core/services/auth/auth.service.ts index 7d0e55a77..66238f10a 100644 --- a/dmp-frontend/src/app/core/services/auth/auth.service.ts +++ b/dmp-frontend/src/app/core/services/auth/auth.service.ts @@ -1,27 +1,25 @@ -import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; +import { HttpErrorResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { MatSnackBar } from '@angular/material/snack-bar'; import { Router } from '@angular/router'; -import { Credential } from '@app/core/model/auth/credential'; -import { LoginInfo } from '@app/core/model/auth/login-info'; import { AppAccount } from '@app/core/model/auth/principal'; -import { ConfigurableProvider } from '@app/core/model/configurable-provider/configurableProvider'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { BaseService } from '@common/base/base.service'; import { TranslateService } from '@ngx-translate/core'; -import { Observable, Subject, forkJoin, from, of as observableOf, throwError as observableThrowError } from 'rxjs'; -import { catchError, exhaustMap, map, takeUntil } from 'rxjs/operators'; +import { Observable, Subject, forkJoin, from, of } from 'rxjs'; +import { exhaustMap, map, takeUntil } from 'rxjs/operators'; import { ConfigurationService } from '../configuration/configuration.service'; -import { CookieService } from 'ngx-cookie-service'; import { Guid } from '@common/types/guid'; import { KeycloakEventType, KeycloakService } from 'keycloak-angular'; import { NgZone } from '@angular/core'; -import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; import { PrincipalService } from '../http/principal.service'; import { AppRole } from '@app/core/common/enum/app-role'; +import { AppPermission } from '@app/core/common/enum/permission.enum'; - +export interface ResolutionContext { + roles: AppRole[]; + permissions: AppPermission[]; +} export interface AuthenticationState { loginStatus: LoginStatus; } @@ -141,7 +139,7 @@ export class AuthService extends BaseService { return observable.pipe( map((x) => this.currentAuthenticationToken(x)), exhaustMap(() => forkJoin([ - this.principalService.me(httpParams) + this.accessToken ? this.principalService.me(httpParams) : of(null) ])), map((item) => { this.currentAccount(item[0]); @@ -309,4 +307,37 @@ export class AuthService extends BaseService { this.zone.run(() => this.router.navigate([returnUrl])); } + public hasPermission(permission: AppPermission): boolean { + // if (!this.installationConfiguration.appServiceEnabled) { return true; } //TODO: maybe reconsider + return this.evaluatePermission(this.appAccount?.permissions || [], permission); + + } + private evaluatePermission(availablePermissions: string[], permissionToCheck: string): boolean { + if (!permissionToCheck) { return false; } + if (this.hasRole(AppRole.Admin)) { return true; } + return availablePermissions.map(x => x.toLowerCase()).includes(permissionToCheck.toLowerCase()); + } + public hasAnyPermission(permissions: AppPermission[]): boolean { + if (!permissions) { return false; } + return permissions.filter((p) => this.hasPermission(p)).length > 0; + } + + public authorize(context: ResolutionContext): boolean { + + if (!context || this.hasRole(AppRole.Admin)) { return true; } + + let roleAuthorized = false; + if (context.roles && context.roles.length > 0) { + roleAuthorized = this.hasAnyRole(context.roles); + } + + let permissionAuthorized = false; + if (context.permissions && context.permissions.length > 0) { + permissionAuthorized = this.hasAnyPermission(context.permissions); + } + + if (roleAuthorized || permissionAuthorized) { return true; } + + return false; + } } diff --git a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts index 55c684f56..27e951622 100644 --- a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts +++ b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts @@ -8,7 +8,6 @@ import { HelpService } from '@app/core/model/configuration-models/help-service.m import { Logging } from '@app/core/model/configuration-models/logging.model'; import { HttpClient } from '@angular/common/http'; import { KeycloakConfiguration } from '@app/core/model/configuration-models/keycloak-configuration.model'; -import { LoginConfiguration } from '@app/core/model/configuration-models/login-configuration.model'; @Injectable({ providedIn: 'root', @@ -137,10 +136,6 @@ export class ConfigurationService extends BaseComponent { }); } - private _zenodoConfiguration: LoginConfiguration; - get zenodoConfiguration(): LoginConfiguration { - return this._zenodoConfiguration; - } private parseResponse(config: any) { @@ -150,7 +145,6 @@ export class ConfigurationService extends BaseComponent { this._defaultCulture = config.defaultCulture; this._defaultLanguage = config.defaultLanguage; this._availableLanguages = config.availableLanguages; - this._zenodoConfiguration = config.zenodoConfiguration; this._keycloak = KeycloakConfiguration.parseValue(config.keycloak); this._logging = Logging.parseValue(config.logging); this._lockInterval = config.lockInterval; diff --git a/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts b/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts index 07c43eb1f..c215246f2 100644 --- a/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts +++ b/dmp-frontend/src/app/core/services/dashboard/dashboard.service.ts @@ -12,24 +12,25 @@ import { DataTableRequest, DataTableMultiTypeRequest } from '@app/core/model/dat @Injectable() export class DashboardService { - private actionUrl: string; private headers: HttpHeaders; + private get apiBase(): string { return `${this.configurationService.server}dashboard`; } + private get publicApiBase(): string { return `${this.configurationService.server}public/dashboard`; } + constructor(private http: BaseHttpService, private configurationService: ConfigurationService) { - this.actionUrl = configurationService.server + 'dashboard/'; } getStatistics(): Observable { - return this.http.get(this.actionUrl + 'getStatistics', { headers: this.headers }); + return this.http.get(`${this.publicApiBase}/getStatistics`, { headers: this.headers }); } getUserStatistics(): Observable { - return this.http.get(this.actionUrl + 'me/getStatistics', { headers: this.headers }); + return this.http.get(`${this.apiBase}/me/getStatistics`, { headers: this.headers }); } getRecentActivity(request: DataTableMultiTypeRequest): Observable { - return this.http.post(this.actionUrl + 'recentActivity', request, {headers: this.headers}); + return this.http.post(`${this.apiBase}/recentActivity`, request, {headers: this.headers}); } // getRecentActivity(request: DataTableRequest): Observable> { diff --git a/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts b/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts index 0428d4bca..6ca3b1ab4 100644 --- a/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts +++ b/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts @@ -10,7 +10,7 @@ import { BaseHttpV2Service } from '../http/base-http-v2.service'; @Injectable() export class DescriptionTemplateTypeService { - private get apiBase(): string { return `${this.configurationService.server}v2/descriptionTemplateType`; } + private get apiBase(): string { return `${this.configurationService.server}description-template-type`; } private headers = new HttpHeaders(); constructor(private http: BaseHttpV2Service, private configurationService: ConfigurationService) {} diff --git a/dmp-frontend/src/app/core/services/language/language.service.ts b/dmp-frontend/src/app/core/services/language/language.service.ts index 4b343591d..0b76a0ffb 100644 --- a/dmp-frontend/src/app/core/services/language/language.service.ts +++ b/dmp-frontend/src/app/core/services/language/language.service.ts @@ -6,11 +6,14 @@ import { HttpResponse, HttpClient } from '@angular/common/http'; import { BaseHttpService } from '../http/base-http.service'; import { Language } from '@app/models/language/Language'; import { ConfigurationService } from '../configuration/configuration.service'; +import { BaseHttpParams } from '@common/http/base-http-params'; +import { InterceptorType } from '@common/http/interceptors/interceptor-type'; @Injectable() export class LanguageService { private currentLanguage: string; - private languageUrl : string; + private get apiBase(): string { return `${this.configurationService.server}language`; } + private get publicApiBase(): string { return `${this.configurationService.server}public/language`; } constructor( private translate: TranslateService, @@ -18,7 +21,6 @@ export class LanguageService { private baseHttp: BaseHttpService, private configurationService: ConfigurationService ) { - this.languageUrl = `${configurationService.server}language`; this.currentLanguage = this.configurationService.defaultLanguage || 'en'; } @@ -32,11 +34,17 @@ export class LanguageService { } public getCurrentLanguageJSON(): Observable> { - return this.http.get(`${this.languageUrl}/${this.currentLanguage}`, { responseType: 'blob', observe: 'response' }); + const params = new BaseHttpParams(); + // params.interceptorContext = { + // excludedInterceptors: [ + // InterceptorType.AuthToken, + // ] + // }; + return this.http.get(`${this.publicApiBase}/${this.currentLanguage}`, { params: params, responseType: 'blob', observe: 'response' }); } public updateLanguage(json: string): Observable { - return this.baseHttp.post(`${this.languageUrl}/update/${this.currentLanguage}`, json); + return this.baseHttp.post(`${this.apiBase}/update/${this.currentLanguage}`, json); } public getCurrentLanguageName() { diff --git a/dmp-frontend/src/app/core/services/language/server.loader.ts b/dmp-frontend/src/app/core/services/language/server.loader.ts index f97d19433..4f2ed4548 100644 --- a/dmp-frontend/src/app/core/services/language/server.loader.ts +++ b/dmp-frontend/src/app/core/services/language/server.loader.ts @@ -3,9 +3,11 @@ import { Observable } from 'rxjs'; import { environment } from 'environments/environment'; import { HttpClient } from '@angular/common/http'; import { ConfigurationService } from '../configuration/configuration.service'; +import { BaseHttpParams } from '@common/http/base-http-params'; +import { InterceptorType } from '@common/http/interceptors/interceptor-type'; export class TranslateServerLoader implements TranslateLoader{ - private languageUrl: string; + private get apiBase(): string { return `${this.configurationService.server}public/language`; } constructor( private http: HttpClient, @@ -14,7 +16,12 @@ export class TranslateServerLoader implements TranslateLoader{ } getTranslation(lang: string): Observable { - this.languageUrl = `${this.configurationService.server}language`; - return this.http.get(`${this.languageUrl}/${lang}`); + const params = new BaseHttpParams(); + // params.interceptorContext = { + // excludedInterceptors: [ + // InterceptorType.AuthToken, + // ] + // }; + return this.http.get(`${this.apiBase}/${lang}`, { params: params }); } } diff --git a/dmp-frontend/src/app/core/services/saml-login.service.ts b/dmp-frontend/src/app/core/services/saml-login.service.ts deleted file mode 100644 index d052205d6..000000000 --- a/dmp-frontend/src/app/core/services/saml-login.service.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { HttpHeaders, HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { ConfigurationService } from './configuration/configuration.service'; -import { BaseHttpService } from './http/base-http.service'; -import { Observable } from 'rxjs'; -import { BaseComponent } from '@common/base/base.component'; -import { AuthnRequestModel } from '../model/saml2/AuthnRequestModel'; - -@Injectable() -export class SamlLoginService extends BaseComponent { - - private actionUrl: string; - private headers = new HttpHeaders(); - - constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) { - super(); - this.actionUrl = configurationService.server + 'saml2/'; - } - - resolveConfigurableLoginId(relayState: string): string { - const decoded = decodeURIComponent(relayState); - const routeParams = new URLSearchParams(decoded); - return routeParams.has('configurableLoginId') ? routeParams.get('configurableLoginId') : undefined; - } - resolveSpId(relayState: string): string { - const decoded = decodeURIComponent(relayState); - const routeParams = new URLSearchParams(decoded); - return routeParams.has('spId') ? routeParams.get('spId') : ''; - } - - getAuthnRequest(configurableLoginId: string): Observable { - return this.http.get(this.actionUrl + 'authnRequest/' + configurableLoginId, { headers: this.headers }); - } - -} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/user/user.service.ts b/dmp-frontend/src/app/core/services/user/user.service.ts index b190322da..e91c75ce3 100644 --- a/dmp-frontend/src/app/core/services/user/user.service.ts +++ b/dmp-frontend/src/app/core/services/user/user.service.ts @@ -57,16 +57,6 @@ export class UserService { return this.http.post(this.actionUrl + 'find', email, {headers: this.headers}); } - public registerDOIToken(code: string, redirectUri: string): Observable { - const url = this.actionUrl + 'registerDOIToken'; - return this.http.post(url, {zenodoRequest: {code: code}, redirectUri: redirectUri}, { headers: this.headers }); - } - - public deleteDOIToken(): Observable { - const url = this.actionUrl + 'deleteDOIToken'; - return this.http.delete(url, { headers: this.headers }); - } - downloadCSV(): Observable> { let headerCsv: HttpHeaders = this.headers.set('Content-Type', 'application/csv') return this.httpClient.get(this.actionUrl + 'getCsv/', { responseType: 'blob', observe: 'response', headers: headerCsv }); diff --git a/dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts b/dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts index fea0e116d..70af68dcf 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts +++ b/dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts @@ -3,15 +3,43 @@ import { RouterModule, Routes } from "@angular/router"; import { AdminAuthGuard } from "@app/core/admin-auth-guard.service"; import { DescriptionTypeEditorComponent } from './editor/description-type-editor.component'; import { DescriptionTypesComponent } from "./listing/description-types.component"; +import { AuthGuard } from "@app/core/auth-guard.service"; +import { AppPermission } from "@app/core/common/enum/permission.enum"; const routes: Routes = [ - { path: '', component: DescriptionTypesComponent, canActivate: [AdminAuthGuard] }, - { path: 'new', component: DescriptionTypeEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DESCRIPTION-TYPE-NEW' } }, - { path: ':id', component: DescriptionTypeEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DESCRIPTION-TYPE-EDIT' } } + { + path: '', + component: DescriptionTypesComponent, + canActivate: [AuthGuard], + data: { + authContext: { + permissions: [AppPermission.ViewDescriptionTemplateTypePage] + } + }, + }, + { + path: 'new', + component: DescriptionTypeEditorComponent, + canActivate: [AuthGuard], + data: { + title: 'GENERAL.TITLES.DESCRIPTION-TYPE-NEW', + authContext: { + permissions: [AppPermission.EditDescriptionTemplateType] + } + } + }, + { + path: ':id', + component: DescriptionTypeEditorComponent, + canActivate: [AuthGuard], + data: { + title: 'GENERAL.TITLES.DESCRIPTION-TYPE-EDIT' + } + } ] @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) -export class DescriptionTypesRoutingModule { } \ No newline at end of file +export class DescriptionTypesRoutingModule { } diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts index 703b76f45..3e5176d97 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts @@ -150,7 +150,9 @@ export class DescriptionTypesDataSource extends DataSource(x => x.status) ] }; - + lookup.order = { + items: ['name'] + }; return this._service.query(lookup) }), map(result => { diff --git a/dmp-frontend/src/app/ui/auth/admin-login/admin-login.component.html b/dmp-frontend/src/app/ui/auth/admin-login/admin-login.component.html deleted file mode 100644 index e3c581728..000000000 --- a/dmp-frontend/src/app/ui/auth/admin-login/admin-login.component.html +++ /dev/null @@ -1,34 +0,0 @@ -
-
-
-
-
-
-

Admin Login

-
- - - - - - - - - - -
- -
-
-
-
-
-
- diff --git a/dmp-frontend/src/app/ui/auth/admin-login/admin-login.component.scss b/dmp-frontend/src/app/ui/auth/admin-login/admin-login.component.scss deleted file mode 100644 index a3145a5cc..000000000 --- a/dmp-frontend/src/app/ui/auth/admin-login/admin-login.component.scss +++ /dev/null @@ -1,148 +0,0 @@ -.container { - padding: 15px 30px; -} - -.card { - box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14); - border-radius: 6px; - color: rgba(0, 0, 0, 0.87); - background: #fff; -} - -.card-raised { - box-shadow: 0 10px 30px -12px rgba(0, 0, 0, 0.42), 0 4px 25px 0px rgba(0, 0, 0, 0.12), 0 8px 10px -5px rgba(0, 0, 0, 0.2); -} - -.page-title { - margin-top: 40px; -} - -@media (min-width: 1200px) { - .container { - width: 100%; - } -} - -@media (min-width: 992px) { - .container { - width: 100%; - } -} - -@media (min-width: 768px) { - .container { - width: 100%; - } -} - -.container { - height: 100%; - position: relative; - z-index: 1; -} - -.card { - position: relative; - padding: 20px; - display: flex; - flex-direction: column; - align-items: center; - margin-top: 90px; - top: -90px; - -webkit-animation-name: card; - -moz-animation-name: card; - -o-animation-name: card; - animation-name: card; - -webkit-animation-duration: 600ms; - -moz-animation-duration: 600ms; - -o-animation-duration: 600ms; - animation-duration: 600ms; - -webkit-animation-fill-mode: forwards; - -moz-animation-fill-mode: forwards; - -o-animation-fill-mode: forwards; - animation-fill-mode: forwards; -} - -@-webkit-keyframes card { - from { - top: -40px; - } - to { - top: 0; - } -} - -@keyframes card { - from { - top: -40px; - } - to { - top: 0; - } -} - -.card-header { - position: relative; - overflow: hidden; - top: -40px; - width: 100%; - padding: 25px; - border-radius: 3px; - background: linear-gradient(60deg, #ec407a, #d81b60); - box-shadow: 0 4px 20px 0px rgba(0, 0, 0, 0.14), 0 7px 10px -5px rgba(49, 46, 47, 0.4); - display: flex; - flex-direction: column; - align-items: center; -} - -.card-header h4 { - font-weight: 400; - color: #fff; - margin-bottom: 25px; - margin-top: 5px; -} - -.social-btns i { - font-size: 21px; - color: #fff; -} - -.social-btns button { - margin: 0 8px; -} - -.tip { - margin-top: -20px; -} - -.form-row, -.card-form, -.mat-form-field { - width: 100%; -} - -.card-form { - padding: 5px; -} - -.form-row { - position: relative; - display: flex; - align-items: center; - margin-top: 13px; -} - -.form-row i { - position: relative; - top: -5px; - margin-right: 15px; - color: #555; -} - -.card-footer { - margin: 10px; -} - -.card-footer button { - color: #e91e63; -} diff --git a/dmp-frontend/src/app/ui/auth/admin-login/admin-login.component.ts b/dmp-frontend/src/app/ui/auth/admin-login/admin-login.component.ts deleted file mode 100644 index b08b883df..000000000 --- a/dmp-frontend/src/app/ui/auth/admin-login/admin-login.component.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Component, OnInit, HostListener } from '@angular/core'; -import { Router } from '@angular/router'; -import { Credential } from '@app/core/model/auth/credential'; -import { AuthService } from '@app/core/services/auth/auth.service'; -import { CultureService } from '@app/core/services/culture/culture-service'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import { BaseComponent } from '@common/base/base.component'; -import { TranslateService } from '@ngx-translate/core'; -import { takeUntil } from 'rxjs/operators'; -import { TranslateServerLoader } from '@app/core/services/language/server.loader'; -import { LanguageService } from '@app/core/services/language/language.service'; -@Component({ - selector: 'app-admin-login', - templateUrl: './admin-login.component.html', - styleUrls: ['./admin-login.component.scss'] -}) -export class AdminLoginComponent extends BaseComponent implements OnInit { - - public auth2: any; - public credential: Credential; - - @HostListener('document:keydown.enter', ['$event']) onKeydownHandler() { - this.nativeLogin(); - } - - constructor( - private authService: AuthService, - private uiNotificationService: UiNotificationService, - private translate: TranslateService, - private cultureService: CultureService, - private router: Router, - private language: LanguageService - ) { super(); } - - - - ngOnInit() { - this.credential = { - username: null, - secret: null - } - } - - public nativeLogin() { - // this.authService.nativeLogin(this.credential) - // .pipe(takeUntil(this._destroyed)) - // .subscribe( - // res => this.onLogInSuccess(res), - // error => this.onLogInError(error) - // ); - } - - public onLogInSuccess(loginResponse: any) { - this.uiNotificationService.snackBarNotification(this.translate.instant('GENERAL.SNACK-BAR.SUCCESSFUL-LOGIN'), SnackBarNotificationLevel.Success); - if (this.authService.currentAccountIsAuthenticated() && this.authService.getUserProfileCulture()) { this.cultureService.cultureSelected(this.authService.getUserProfileCulture()); } - if (this.authService.currentAccountIsAuthenticated() && this.authService.getUserProfileLanguage()) { this.language.changeLanguage(this.authService.getUserProfileLanguage()); } - this.router.navigate(['/']); - } - - public onLogInError(errorMessage: string) { - this.uiNotificationService.snackBarNotification(this.translate.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGIN'), SnackBarNotificationLevel.Error); - } -} diff --git a/dmp-frontend/src/app/ui/auth/admin-login/admin-login.module.ts b/dmp-frontend/src/app/ui/auth/admin-login/admin-login.module.ts deleted file mode 100644 index 766ca5e31..000000000 --- a/dmp-frontend/src/app/ui/auth/admin-login/admin-login.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NgModule } from '@angular/core'; -import { AdminLoginComponent } from '@app/ui/auth/admin-login/admin-login.component'; -import { AdminLoginRoutingModule } from '@app/ui/auth/admin-login/admin-login.routing'; -import { CommonFormsModule } from '@common/forms/common-forms.module'; -import { CommonUiModule } from '@common/ui/common-ui.module'; - -@NgModule({ - imports: [ - CommonUiModule, - CommonFormsModule, - AdminLoginRoutingModule - ], - declarations: [ - AdminLoginComponent - ] -}) -export class AdminLoginModule { } diff --git a/dmp-frontend/src/app/ui/auth/admin-login/admin-login.routing.ts b/dmp-frontend/src/app/ui/auth/admin-login/admin-login.routing.ts deleted file mode 100644 index b3e6deae3..000000000 --- a/dmp-frontend/src/app/ui/auth/admin-login/admin-login.routing.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; -import { AdminLoginComponent } from './admin-login.component'; - -const routes: Routes = [ - { - path: '', - component: AdminLoginComponent, - }, -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class AdminLoginRoutingModule { } diff --git a/dmp-frontend/src/app/ui/auth/login/login.module.ts b/dmp-frontend/src/app/ui/auth/login/login.module.ts index 9742360ef..a0aae9b78 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.module.ts +++ b/dmp-frontend/src/app/ui/auth/login/login.module.ts @@ -8,7 +8,6 @@ import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; import { MergeEmailConfirmation } from './merge-email-confirmation/merge-email-confirmation.component'; import { MergeLoginService } from './utilities/merge-login.service'; -import { SamlLoginService } from '@app/core/services/saml-login.service'; import { UnlinkEmailConfirmation } from './unlink-email-confirmation/unlink-email-confirmation.component'; @NgModule({ @@ -27,6 +26,6 @@ import { UnlinkEmailConfirmation } from './unlink-email-confirmation/unlink-emai exports: [ LoginComponent ], - providers: [LoginService, MergeLoginService, SamlLoginService] + providers: [LoginService, MergeLoginService] }) export class LoginModule { } diff --git a/dmp-frontend/src/app/ui/external/external.module.ts b/dmp-frontend/src/app/ui/external/external.module.ts deleted file mode 100644 index a9f47fb22..000000000 --- a/dmp-frontend/src/app/ui/external/external.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { ZenodoComponent } from './zenodo/zenodo.component'; -import { ExternalRoutingModule } from './external.routing'; - - - -@NgModule({ - declarations: [ZenodoComponent], - imports: [ - CommonModule, - ExternalRoutingModule - ] -}) -export class ExternalModule { } diff --git a/dmp-frontend/src/app/ui/external/external.routing.ts b/dmp-frontend/src/app/ui/external/external.routing.ts deleted file mode 100644 index 36f598b4b..000000000 --- a/dmp-frontend/src/app/ui/external/external.routing.ts +++ /dev/null @@ -1,31 +0,0 @@ - -import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; -import { ZenodoComponent } from './zenodo/zenodo.component'; - - - -const routes: Routes = [ - { - path: '', - component: ZenodoComponent, - data: { - breadcrumb: true - }, - }, - { - path: 'zenodo/:id', - component: ZenodoComponent, - data: { - breadcrumb: true - }, - },]; - - - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) - -export class ExternalRoutingModule { } diff --git a/dmp-frontend/src/app/ui/external/zenodo/zenodo.component.html b/dmp-frontend/src/app/ui/external/zenodo/zenodo.component.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/dmp-frontend/src/app/ui/external/zenodo/zenodo.component.scss b/dmp-frontend/src/app/ui/external/zenodo/zenodo.component.scss deleted file mode 100644 index e69de29bb..000000000 diff --git a/dmp-frontend/src/app/ui/external/zenodo/zenodo.component.ts b/dmp-frontend/src/app/ui/external/zenodo/zenodo.component.ts deleted file mode 100644 index bf9d18321..000000000 --- a/dmp-frontend/src/app/ui/external/zenodo/zenodo.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute, Router, Params } from '@angular/router'; -import { BaseComponent } from '@common/base/base.component'; -import { takeUntil } from 'rxjs/operators'; - -@Component({ - selector: 'app-zenodo', - templateUrl: './zenodo.component.html', - styleUrls: ['./zenodo.component.scss'] -}) -export class ZenodoComponent extends BaseComponent implements OnInit { - - constructor( - private route: ActivatedRoute, - private router: Router, ) { - super(); - } - - ngOnInit() { - this.route.paramMap.pipe(takeUntil(this._destroyed)).subscribe((params: Params) => { - const id = params.params.id; - this.router.navigate([`/explore-plans/publicOverview/${id}`]); - }); - } - -} diff --git a/dmp-frontend/src/app/ui/user-profile/user-profile.component.html b/dmp-frontend/src/app/ui/user-profile/user-profile.component.html index 45d1e982f..81472e5dd 100644 --- a/dmp-frontend/src/app/ui/user-profile/user-profile.component.html +++ b/dmp-frontend/src/app/ui/user-profile/user-profile.component.html @@ -184,28 +184,6 @@ - -
-
-
-
{{ 'USER-PROFILE.ZENODO.TITLE' | translate}}
-
-
-
- - - {{'USER-PROFILE.ZENODO.DESCRIPTION' | translate}} - -
-
-
-
- -
-
-
diff --git a/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts b/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts index ac8707365..7ae044196 100644 --- a/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts +++ b/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts @@ -13,8 +13,6 @@ import * as moment from 'moment-timezone'; import { Observable, of } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; import { LanguageService } from '@app/core/services/language/language.service'; -import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; -import { Oauth2DialogService } from '../misc/oauth2-dialog/service/oauth2-dialog.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; import { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item'; @@ -51,8 +49,6 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes timezones: Observable; editMode = false; languages = []; - zenodoToken: string; - zenodoEmail: String; roleOrganizationEnum = RoleOrganizationType; authProviderEnum = AuthProvider; private oauthLock: boolean; @@ -80,7 +76,6 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes private authentication: AuthService, private languageService: LanguageService, private configurationService: ConfigurationService, - private oauth2DialogService: Oauth2DialogService, private uiNotificationService: UiNotificationService, private dialog: MatDialog, public enumUtils: EnumUtils, @@ -102,8 +97,6 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes const userId = !params['id'] ? 'me' : params['id']; this.user = this.userService.getUser(userId).pipe(map(result => { //result['additionalinfo'] = JSON.parse(result['additionalinfo']); - //this.zenodoToken = result['additionalinfo']['zenodoToken']; - this.zenodoEmail = result['zenodoEmail']; this.userProfileEditorModel = new UserProfileEditorModel().fromModel(result); this.formGroup = this.userProfileEditorModel.buildForm(this.configurationService.availableLanguages); @@ -258,46 +251,6 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes (ev.target as HTMLImageElement).src = 'assets/images/profile-placeholder.png'; } - public hasZenodo(): boolean { - return !isNullOrUndefined(this.zenodoEmail) && this.zenodoEmail !== ""; - } - - public loginToZenodo() { - this.showOauth2Dialog(this.getAccessUrl()); - } - - getAccessUrl(): string { - const redirectUri = this.configurationService.app + 'oauth2'; - const url = this.configurationService.zenodoConfiguration.oauthUrl - + '?client_id=' + this.configurationService.zenodoConfiguration.clientId - + '&response_type=code&scope=deposit:write+deposit:actions+user:email&state=astate&redirect_uri=' - + redirectUri; - return url; - } - - showOauth2Dialog(url: string) { - this.oauth2DialogService.login(url) - .pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (result !== undefined) { - if (result.oauthCode !== undefined && result.oauthCode !== null && !this.oauthLock) { - this.userService.registerDOIToken(result.oauthCode, this.configurationService.app + 'oauth2') - .pipe(takeUntil(this._destroyed)) - .subscribe(() => this.router.navigate(['/reload']).then(() => this.router.navigate(['/profile']))); - this.oauthLock = true; - } - } else { - this.oauthLock = false; - } - }); - } - - public RemoveZenodo() { - this.userService.deleteDOIToken() - .pipe(takeUntil(this._destroyed)) - .subscribe(() => this.router.navigate(['/reload']).then(() => this.router.navigate(['/profile']))); - } - public removeAccount(userCredential :UserCredentialModel) { this.dialog.open(ConfirmationDialogComponent, { data:{ diff --git a/dmp-frontend/src/assets/config/config.json b/dmp-frontend/src/assets/config/config.json index 1f88e12a3..3424746da 100644 --- a/dmp-frontend/src/assets/config/config.json +++ b/dmp-frontend/src/assets/config/config.json @@ -57,46 +57,14 @@ "flow": "standard", "clientId": "dmp_webapp", "silentCheckSsoRedirectUri": "http://localhost:4200/assets/silent-check-sso.html", - "scope": "openid profile email address phone dmp_web", + "scope": "openid profile email address phone", "clientSecret": null, "grantType": "code" }, - "loginProviders": { - "enabled": [1, 2, 3, 4, 5, 6, 7, 8], - "facebookConfiguration": { "clientId": "" }, - "googleConfiguration": { "clientId": "524432312250-sc9qsmtmbvlv05r44onl6l93ia3k9deo.apps.googleusercontent.com" }, - "linkedInConfiguration": { - "clientId": "", - "oauthUrl": "https://www.linkedin.com/oauth/v2/authorization", - "redirectUri": "http://localhost:4200/login/linkedin", - "state": "987654321" - }, - "twitterConfiguration": { - "clientId": "", - "oauthUrl": "https://api.twitter.com/oauth/authenticate" - }, - "b2accessConfiguration": { - "clientId": "", - "oauthUrl": "https://b2access-integration.fz-juelich.de:443/oauth2-as/oauth2-authz", - "redirectUri": "http://localhost:4200/api/oauth/authorized/b2access", - "state": "" - }, - "orcidConfiguration": { - "clientId": "", - "oauthUrl": "https://orcid.org/oauth/authorize", - "redirectUri": "http://localhost:4200/login/external/orcid" - }, - "openAireConfiguration": { - "clientId": "", - "oauthUrl": "", - "redirectUri": "", - "state": "987654321" - }, - "zenodoConfiguration": { - "clientId": "", - "oauthUrl": "https://sandbox.zenodo.org/oauth/authorize", - "redirectUri": "http://localhost:4200/login/external/zenodo" - } + "zenodoConfiguration": { + "clientId": "", + "oauthUrl": "https://sandbox.zenodo.org/oauth/authorize", + "redirectUri": "http://localhost:4200/login/external/zenodo" }, "logging": { "enabled": true, diff --git a/dmp-frontend/src/assets/silent-check-sso.html b/dmp-frontend/src/assets/silent-check-sso.html new file mode 100644 index 000000000..b3bd540de --- /dev/null +++ b/dmp-frontend/src/assets/silent-check-sso.html @@ -0,0 +1,7 @@ + + + + +