authz changes
This commit is contained in:
parent
b49975931b
commit
c480e8e508
|
@ -56,7 +56,8 @@ public class AuditableAction {
|
|||
public static final EventId Description_UploadFieldFiles = new EventId(6007, "Description_UploadFieldFiles");
|
||||
public static final EventId Description_GetFieldFile = new EventId(6008, "Description_GetFieldFile");
|
||||
public static final EventId Description_Validate = new EventId(6009, "Description_Validate");
|
||||
|
||||
public static final EventId Description_GetDescriptionSectionPermissions = new EventId(6010, "Description_GetDescriptionSectionPermissions");
|
||||
|
||||
|
||||
public static final EventId Reference_Query = new EventId(7000, "Reference_Query");
|
||||
public static final EventId Reference_Lookup = new EventId(7001, "Reference_Lookup");
|
||||
|
|
|
@ -74,7 +74,6 @@ public final class Permission {
|
|||
public static String DeleteDmp = "DeleteDmp";
|
||||
public static String CloneDmp = "CloneDmp";
|
||||
public static String CreateNewVersionDmp = "CreateNewVersionDmp";
|
||||
public static String ExportDmp = "ExportDmp";
|
||||
public static String FinalizeDmp = "FinalizeDmp";
|
||||
public static String UndoFinalizeDmp = "UndoFinalizeDmp";
|
||||
public static String AssignDmpUsers = "AssignDmpUsers";
|
||||
|
|
|
@ -16,4 +16,8 @@ public interface AuthorizationContentResolver {
|
|||
AffiliatedResource descriptionAffiliation(UUID id);
|
||||
|
||||
Map<UUID, AffiliatedResource> descriptionsAffiliation(List<UUID> ids);
|
||||
|
||||
AffiliatedResource descriptionsAffiliationBySection(UUID dmpId, UUID sectionId);
|
||||
|
||||
Map<UUID, AffiliatedResource> descriptionsAffiliationBySections(UUID dmpId, List<UUID> sectionIds);
|
||||
}
|
||||
|
|
|
@ -5,11 +5,14 @@ import eu.eudat.authorization.PermissionNameProvider;
|
|||
import eu.eudat.commons.enums.IsActive;
|
||||
import eu.eudat.commons.scope.user.UserScope;
|
||||
import eu.eudat.data.DescriptionEntity;
|
||||
import eu.eudat.data.DmpDescriptionTemplateEntity;
|
||||
import eu.eudat.data.DmpEntity;
|
||||
import eu.eudat.data.DmpUserEntity;
|
||||
import eu.eudat.model.Description;
|
||||
import eu.eudat.model.DmpDescriptionTemplate;
|
||||
import eu.eudat.model.DmpUser;
|
||||
import eu.eudat.query.DescriptionQuery;
|
||||
import eu.eudat.query.DmpDescriptionTemplateQuery;
|
||||
import eu.eudat.query.DmpUserQuery;
|
||||
import gr.cite.tools.data.query.QueryFactory;
|
||||
import gr.cite.tools.fieldset.BaseFieldSet;
|
||||
|
@ -54,7 +57,7 @@ public class AuthorizationContentResolverImpl implements AuthorizationContentRes
|
|||
List<UUID> idsToResolve = this.getAffiliatedFromCache(ids, userId, affiliatedResources, DmpEntity.class.getSimpleName());
|
||||
if (idsToResolve.isEmpty()) return affiliatedResources;
|
||||
|
||||
List<DmpUserEntity> dmpUsers = this.queryFactory.query(DmpUserQuery.class).dmpIds(ids).userIds(userId).isActives(IsActive.Active).collectAs(new BaseFieldSet().ensure(DmpUser._role).ensure(DmpUser._dmp));
|
||||
List<DmpUserEntity> dmpUsers = this.queryFactory.query(DmpUserQuery.class).dmpIds(ids).sectionIsEmpty(true).userIds(userId).isActives(IsActive.Active).collectAs(new BaseFieldSet().ensure(DmpUser._role).ensure(DmpUser._dmp));
|
||||
|
||||
for (DmpUserEntity dmpUser : dmpUsers){
|
||||
affiliatedResources.get(dmpUser.getDmpId()).getDmpUserRoles().add(dmpUser.getRole());
|
||||
|
@ -80,14 +83,23 @@ public class AuthorizationContentResolverImpl implements AuthorizationContentRes
|
|||
List<UUID> idsToResolve = this.getAffiliatedFromCache(ids, userId, affiliatedResources, DescriptionEntity.class.getSimpleName());
|
||||
if (idsToResolve.isEmpty()) return affiliatedResources;
|
||||
|
||||
List<DescriptionEntity> descriptionEntities = this.queryFactory.query(DescriptionQuery.class).ids(ids).collectAs(new BaseFieldSet().ensure(Description._id).ensure(Description._dmp));
|
||||
List<DmpUserEntity> dmpUsers = this.queryFactory.query(DmpUserQuery.class).descriptionIds(ids).userIds(userId).isActives(IsActive.Active).collectAs(new BaseFieldSet().ensure(DmpUser._role).ensure(DmpUser._dmp));
|
||||
List<DescriptionEntity> descriptionEntities = this.queryFactory.query(DescriptionQuery.class).ids(ids).collectAs(new BaseFieldSet().ensure(Description._id).ensure(Description._dmpDescriptionTemplate).ensure(Description._dmp));
|
||||
List<DmpDescriptionTemplateEntity> dmpDescriptionTemplateEntities = this.queryFactory.query(DmpDescriptionTemplateQuery.class).ids(descriptionEntities.stream().map(DescriptionEntity::getDmpDescriptionTemplateId).distinct().toList()).collectAs(new BaseFieldSet().ensure(DmpDescriptionTemplate._id).ensure(DmpDescriptionTemplate._sectionId));
|
||||
Map<UUID, DmpDescriptionTemplateEntity> dmpDescriptionTemplateEntityMap = dmpDescriptionTemplateEntities == null ? new HashMap<>() : dmpDescriptionTemplateEntities.stream().collect(Collectors.toMap(DmpDescriptionTemplateEntity::getId, x-> x));
|
||||
|
||||
List<DmpUserEntity> dmpUsers = this.queryFactory.query(DmpUserQuery.class).descriptionIds(ids).userIds(userId).isActives(IsActive.Active).collectAs(new BaseFieldSet().ensure(DmpUser._role).ensure(DmpUser._sectionId).ensure(DmpUser._dmp));
|
||||
Map<UUID, List<DmpUserEntity>> dmpUsersMap = dmpUsers.stream().collect(Collectors.groupingBy(DmpUserEntity::getDmpId));
|
||||
|
||||
for (DescriptionEntity description : descriptionEntities){
|
||||
List<DmpUserEntity> dmpDescriptionUsers = dmpUsersMap.getOrDefault(description.getDmpId(), new ArrayList<>());
|
||||
for (DmpUserEntity dmpUser : dmpDescriptionUsers) {
|
||||
affiliatedResources.get(description.getId()).getDmpUserRoles().add(dmpUser.getRole());
|
||||
if (dmpUser.getSectionId() == null) affiliatedResources.get(description.getId()).getDmpUserRoles().add(dmpUser.getRole());
|
||||
else {
|
||||
DmpDescriptionTemplateEntity dmpDescriptionTemplateEntity = dmpDescriptionTemplateEntityMap.getOrDefault(description.getDmpDescriptionTemplateId(), null);
|
||||
if (dmpDescriptionTemplateEntity != null && dmpUser.getSectionId().equals(dmpDescriptionTemplateEntity.getSectionId())){
|
||||
affiliatedResources.get(description.getId()).getDmpUserRoles().add(dmpUser.getRole());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,6 +107,37 @@ public class AuthorizationContentResolverImpl implements AuthorizationContentRes
|
|||
return affiliatedResources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffiliatedResource descriptionsAffiliationBySection(UUID dmpId, UUID sectionId){
|
||||
return this.descriptionsAffiliationBySections(dmpId, List.of(sectionId)).getOrDefault(sectionId, new AffiliatedResource());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, AffiliatedResource> descriptionsAffiliationBySections(UUID dmpId, List<UUID> sectionIds){
|
||||
UUID userId = this.userScope.getUserIdSafe();
|
||||
Map<UUID, AffiliatedResource> affiliatedResources = new HashMap<>();
|
||||
for (UUID id : sectionIds){
|
||||
affiliatedResources.put(id, new AffiliatedResource());
|
||||
}
|
||||
if (userId == null || !userScope.isSet()) return affiliatedResources;
|
||||
|
||||
List<DmpUserEntity> dmpUsers = this.queryFactory.query(DmpUserQuery.class).dmpIds(dmpId).userIds(userId).isActives(IsActive.Active).collectAs(new BaseFieldSet().ensure(DmpUser._role).ensure(DmpUser._sectionId).ensure(DmpUser._dmp));
|
||||
|
||||
for (UUID sectionId : sectionIds.stream().distinct().toList()){
|
||||
List<DmpUserEntity> dmpSectionUsers = dmpUsers.stream().filter(x-> x.getSectionId() == null || x.getSectionId().equals(sectionId)).toList();
|
||||
for (DmpUserEntity dmpUser : dmpSectionUsers) {
|
||||
if (dmpUser.getSectionId() == null) affiliatedResources.get(sectionId).getDmpUserRoles().add(dmpUser.getRole());
|
||||
else {
|
||||
if (dmpUser.getSectionId().equals(sectionId)){
|
||||
affiliatedResources.get(sectionId).getDmpUserRoles().add(dmpUser.getRole());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return affiliatedResources;
|
||||
}
|
||||
|
||||
private List<UUID> getAffiliatedFromCache(List<UUID> ids, UUID userId, Map<UUID, AffiliatedResource> affiliatedResources, String entityType){
|
||||
List<UUID> idsToResolve = new ArrayList<>();
|
||||
for (UUID id : ids){
|
||||
|
|
|
@ -33,7 +33,7 @@ public class DmpAssociatedUserCensor extends BaseCensor {
|
|||
logger.debug(new DataLogEntry("censoring fields", fields));
|
||||
if (fields == null || fields.isEmpty())
|
||||
return;
|
||||
this.authService.authorizeAtLeastOneForce(userId != null ? List.of(new OwnedResource(userId)) : null, Permission.BrowseDmpAssociatedUser);
|
||||
this.authService.authorizeAtLeastOneForce(userId != null ? List.of(new OwnedResource(userId)) : null, Permission.BrowseDmpAssociatedUser, Permission.DeferredAffiliation);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,6 +32,10 @@ public class Section {
|
|||
public final static String _prefillingSources = "prefillingSources";
|
||||
private List<PrefillingSource> prefillingSources;
|
||||
|
||||
public final static String _canCreate = "canCreate";
|
||||
private Boolean canCreate;
|
||||
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -95,6 +99,14 @@ public class Section {
|
|||
public void setPrefillingSources(List<PrefillingSource> prefillingSources) {
|
||||
this.prefillingSources = prefillingSources;
|
||||
}
|
||||
|
||||
public Boolean getCanCreate() {
|
||||
return canCreate;
|
||||
}
|
||||
|
||||
public void setCanCreate(Boolean canCreate) {
|
||||
this.canCreate = canCreate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
package eu.eudat.model.persist;
|
||||
|
||||
import eu.eudat.commons.validation.BaseValidator;
|
||||
import eu.eudat.convention.ConventionService;
|
||||
import eu.eudat.errorcode.ErrorThesaurusProperties;
|
||||
import gr.cite.tools.validation.specification.Specification;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DescriptionSectionPermissionResolver {
|
||||
|
||||
private UUID dmpId;
|
||||
public static final String _dmpId = "dmpId";
|
||||
|
||||
private List<UUID> sectionIds;
|
||||
|
||||
public static final String _sectionIds = "sectionIds";
|
||||
|
||||
private List<String> permissions;
|
||||
|
||||
public static final String _permissions = "permissions";
|
||||
|
||||
public UUID getDmpId() {
|
||||
return dmpId;
|
||||
}
|
||||
|
||||
public void setDmpId(UUID dmpId) {
|
||||
this.dmpId = dmpId;
|
||||
}
|
||||
|
||||
public List<UUID> getSectionIds() {
|
||||
return sectionIds;
|
||||
}
|
||||
|
||||
public void setSectionIds(List<UUID> sectionIds) {
|
||||
this.sectionIds = sectionIds;
|
||||
}
|
||||
|
||||
public List<String> getPermissions() {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public void setPermissions(List<String> permissions) {
|
||||
this.permissions = permissions;
|
||||
}
|
||||
|
||||
@Component(DescriptionSectionPermissionResolverPersistValidator.ValidatorName)
|
||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||
public static class DescriptionSectionPermissionResolverPersistValidator extends BaseValidator<DescriptionSectionPermissionResolver> {
|
||||
|
||||
public static final String ValidatorName = "DescriptionSectionPermissionResolverPersistValidator";
|
||||
|
||||
private final MessageSource messageSource;
|
||||
|
||||
protected DescriptionSectionPermissionResolverPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) {
|
||||
super(conventionService, errors);
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<DescriptionSectionPermissionResolver> modelClass() {
|
||||
return DescriptionSectionPermissionResolver.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<Specification> specifications(DescriptionSectionPermissionResolver item) {
|
||||
return Arrays.asList(
|
||||
this.spec()
|
||||
.must(() -> this.isValidGuid(item.getDmpId()))
|
||||
.failOn(DescriptionSectionPermissionResolver._dmpId).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionSectionPermissionResolver._dmpId}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.must(() -> item.getPermissions() != null && !item.getPermissions().isEmpty())
|
||||
.failOn(DescriptionSectionPermissionResolver._permissions).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionSectionPermissionResolver._permissions}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.must(() -> item.getSectionIds() != null && !item.getSectionIds().isEmpty())
|
||||
.failOn(DescriptionSectionPermissionResolver._sectionIds).failWith(messageSource.getMessage("Validation_Required", new Object[]{DescriptionSectionPermissionResolver._sectionIds}, LocaleContextHolder.getLocale()))
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -118,3 +118,4 @@ public class LockPersist {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -158,15 +158,7 @@ public class DescriptionReferenceQuery extends QueryBase<DescriptionReferenceEnt
|
|||
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
if (userId != null || usePublic ) {
|
||||
UUID finalUserId = userId;
|
||||
Subquery<UUID> descriptionSubquery = queryUtilsService.buildSubQuery(new BuildSubQueryInput<>(
|
||||
new BuildSubQueryInput.Builder<>(DescriptionEntity.class, UUID.class, queryContext)
|
||||
.keyPathFunc((subQueryRoot) -> subQueryRoot.get(DescriptionEntity._id))
|
||||
.filterFunc((subQueryRoot, cb) ->
|
||||
cb.in(subQueryRoot.get(DescriptionEntity._dmpDescriptionTemplateId)).value(queryUtilsService.buildDmpAuthZSubQuery(queryContext.Query, queryContext.CriteriaBuilder, finalUserId, usePublic))
|
||||
)
|
||||
));
|
||||
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionReferenceEntity._descriptionId)).value(descriptionSubquery));
|
||||
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionReferenceEntity._descriptionId)).value(queryUtilsService.buildDescriptionAuthZSubQuery(queryContext.Query, queryContext.CriteriaBuilder, userId, usePublic)));
|
||||
}
|
||||
if (!predicates.isEmpty()) {
|
||||
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
||||
|
|
|
@ -144,37 +144,6 @@ public class DescriptionTagQuery extends QueryBase<DescriptionTagEntity> {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected <X, Y> Predicate applyAuthZ(QueryContext<X, Y> queryContext) {
|
||||
if (this.authorize.contains(AuthorizationFlags.None)) return null;
|
||||
if (this.authorize.contains(AuthorizationFlags.Permission) && this.authService.authorize(Permission.BrowseDescriptionTag)) return null;
|
||||
UUID userId;
|
||||
boolean usePublic = this.authorize.contains(AuthorizationFlags.Public);
|
||||
if (this.authorize.contains(AuthorizationFlags.DmpAssociated)) userId = this.userScope.getUserIdSafe();
|
||||
else userId = null;
|
||||
if (this.authorize.contains(AuthorizationFlags.Owner)) userId = this.userScope.getUserIdSafe();
|
||||
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
if (userId != null || usePublic ) {
|
||||
UUID finalUserId = userId;
|
||||
Subquery<UUID> descriptionSubquery = queryUtilsService.buildSubQuery(new BuildSubQueryInput<>(
|
||||
new BuildSubQueryInput.Builder<>(DescriptionEntity.class, UUID.class, queryContext)
|
||||
.keyPathFunc((subQueryRoot) -> subQueryRoot.get(DescriptionEntity._id))
|
||||
.filterFunc((subQueryRoot, cb) ->
|
||||
cb.in(subQueryRoot.get(DescriptionEntity._dmpDescriptionTemplateId)).value(queryUtilsService.buildDmpAuthZSubQuery(queryContext.Query, queryContext.CriteriaBuilder, finalUserId, usePublic))
|
||||
)
|
||||
));
|
||||
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionTagEntity._descriptionId)).value(descriptionSubquery));
|
||||
}
|
||||
if (predicates.size() > 0) {
|
||||
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
|
||||
return queryContext.CriteriaBuilder.and(predicatesArray);
|
||||
} else {
|
||||
return queryContext.CriteriaBuilder.or(); //Creates a false query
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
|
|
|
@ -42,6 +42,7 @@ public class DmpUserQuery extends QueryBase<DmpUserEntity> {
|
|||
private Collection<DmpUserRole> userRoles;
|
||||
|
||||
private Collection<UUID> sectionIds;
|
||||
private Boolean sectionIsEmpty;
|
||||
|
||||
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
||||
|
||||
|
@ -149,6 +150,11 @@ public class DmpUserQuery extends QueryBase<DmpUserEntity> {
|
|||
this.sectionIds = values;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DmpUserQuery sectionIsEmpty(Boolean sectionIsEmpty) {
|
||||
this.sectionIsEmpty = sectionIsEmpty;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DmpUserQuery authorize(EnumSet<AuthorizationFlags> values) {
|
||||
this.authorize = values;
|
||||
|
@ -224,6 +230,10 @@ public class DmpUserQuery extends QueryBase<DmpUserEntity> {
|
|||
inClause.value(item);
|
||||
predicates.add(inClause);
|
||||
}
|
||||
if (this.sectionIsEmpty != null){
|
||||
if(this.sectionIsEmpty) predicates.add(queryContext.CriteriaBuilder.isNull(queryContext.Root.get(DmpUserEntity._sectionId)));
|
||||
else predicates.add(queryContext.CriteriaBuilder.isNotNull(queryContext.Root.get(DmpUserEntity._sectionId)));
|
||||
}
|
||||
if (this.descriptionIds != null) {
|
||||
Subquery<UUID> descriptionSubquery = queryUtilsService.buildSubQuery(new BuildSubQueryInput<>(
|
||||
new BuildSubQueryInput.Builder<>(DescriptionEntity.class, UUID.class, queryContext)
|
||||
|
|
|
@ -159,7 +159,7 @@ public class UserQuery extends QueryBase<UserEntity> {
|
|||
UUID finalUserId = userId;
|
||||
predicates.add(queryContext.CriteriaBuilder.or(
|
||||
userId != null ? queryContext.CriteriaBuilder.in(queryContext.Root.get(UserEntity._id)).value(userId) : queryContext.CriteriaBuilder.or(), //Creates a false query
|
||||
queryContext.CriteriaBuilder.in(queryContext.Root.get(ReferenceEntity._id)).value(queryUtilsService.buildSubQuery(new BuildSubQueryInput<>(new BuildSubQueryInput.Builder<>(DmpUserEntity.class, UUID.class)
|
||||
queryContext.CriteriaBuilder.in(queryContext.Root.get(UserEntity._id)).value(queryUtilsService.buildSubQuery(new BuildSubQueryInput<>(new BuildSubQueryInput.Builder<>(DmpUserEntity.class, UUID.class)
|
||||
.query(queryContext.Query)
|
||||
.criteriaBuilder(queryContext.CriteriaBuilder)
|
||||
.keyPathFunc((subQueryRoot) -> subQueryRoot.get(DmpUserEntity._userId))
|
||||
|
|
|
@ -53,9 +53,13 @@ public class QueryUtilsServiceImpl implements QueryUtilsService {
|
|||
usePublic ? cb.and(
|
||||
cb.equal(subQueryRoot.get(DescriptionEntity._status), DescriptionStatus.Finalized),
|
||||
cb.equal(subQueryRoot.get(DescriptionEntity._isActive), IsActive.Active),
|
||||
cb.in(subQueryRoot.get(DescriptionEntity._dmpId)).value(this.buildDmpAuthZSubQuery(query, criteriaBuilder, userId, usePublic))
|
||||
cb.in(subQueryRoot.get(DescriptionEntity._dmpId)).value(this.buildPublicDmpAuthZSubQuery(query, criteriaBuilder, usePublic))
|
||||
): cb.or(), //Creates a false query
|
||||
userId != null ? cb.equal(subQueryRoot.get(DescriptionEntity._createdById), userId) : cb.or() //Creates a false query
|
||||
userId != null ?
|
||||
cb.or(
|
||||
cb.equal(subQueryRoot.get(DescriptionEntity._createdById), userId),
|
||||
cb.in(subQueryRoot.get(DescriptionEntity._dmpId)).value(this.buildDmpUserAuthZSubQuery(query, criteriaBuilder, userId))
|
||||
) : cb.or() //Creates a false query
|
||||
)
|
||||
)
|
||||
));
|
||||
|
|
|
@ -6,6 +6,7 @@ import eu.eudat.model.DescriptionValidationResult;
|
|||
import eu.eudat.model.StorageFile;
|
||||
import eu.eudat.model.persist.DescriptionFieldFilePersist;
|
||||
import eu.eudat.model.persist.DescriptionPersist;
|
||||
import eu.eudat.model.persist.DescriptionSectionPermissionResolver;
|
||||
import eu.eudat.model.persist.DescriptionStatusPersist;
|
||||
import gr.cite.tools.exception.MyApplicationException;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
|
@ -18,11 +19,14 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
import javax.management.InvalidApplicationException;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface DescriptionService {
|
||||
|
||||
Description persist(DescriptionPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, IOException;
|
||||
Map<UUID, List<String>> getDescriptionSectionPermissions(DescriptionSectionPermissionResolver model);
|
||||
|
||||
Description persist(DescriptionPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, IOException;
|
||||
Description persistStatus(DescriptionStatusPersist model, FieldSet fields) throws IOException;
|
||||
|
||||
void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException, IOException;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package eu.eudat.service.description;
|
||||
|
||||
import eu.eudat.authorization.AffiliatedResource;
|
||||
import eu.eudat.authorization.AuthorizationFlags;
|
||||
import eu.eudat.authorization.Permission;
|
||||
import eu.eudat.authorization.authorizationcontentresolver.AuthorizationContentResolver;
|
||||
|
@ -26,7 +27,6 @@ import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEvent;
|
|||
import eu.eudat.integrationevent.outbox.notification.NotifyIntegrationEventHandler;
|
||||
import eu.eudat.model.*;
|
||||
import eu.eudat.model.builder.DescriptionBuilder;
|
||||
import eu.eudat.model.builder.DescriptionTemplateBuilder;
|
||||
import eu.eudat.model.deleter.DescriptionDeleter;
|
||||
import eu.eudat.model.deleter.DescriptionReferenceDeleter;
|
||||
import eu.eudat.model.deleter.DescriptionTagDeleter;
|
||||
|
@ -50,7 +50,6 @@ 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 gr.cite.tools.validation.ValidationResult;
|
||||
import gr.cite.tools.validation.ValidatorFactory;
|
||||
import jakarta.persistence.EntityManager;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
@ -138,6 +137,24 @@ public class DescriptionServiceImpl implements DescriptionService {
|
|||
this.authorizationContentResolver = authorizationContentResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<UUID, List<String>> getDescriptionSectionPermissions(DescriptionSectionPermissionResolver model) {
|
||||
logger.debug(new MapLogEntry("get description section permissions").And("model", model));
|
||||
|
||||
Map<UUID, List<String>> response = new HashMap<>();
|
||||
|
||||
Map<UUID, AffiliatedResource> affiliatedResourceMap = this.authorizationContentResolver.descriptionsAffiliationBySections(model.getDmpId(), model.getSectionIds());
|
||||
for (UUID sectionId : model.getSectionIds().stream().distinct().toList()){
|
||||
AffiliatedResource affiliatedResource = affiliatedResourceMap.getOrDefault(sectionId, null);
|
||||
response.put(sectionId, new ArrayList<>());
|
||||
for (String permission : model.getPermissions()){
|
||||
if (this.authorizationService.authorizeAtLeastOne(List.of(affiliatedResource), permission)) response.get(sectionId).add(permission);
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
//region Persist
|
||||
|
||||
@Override
|
||||
|
@ -145,9 +162,12 @@ public class DescriptionServiceImpl implements DescriptionService {
|
|||
logger.debug(new MapLogEntry("persisting data description").And("model", model).And("fields", fields));
|
||||
|
||||
Boolean isUpdate = this.conventionService.isValidGuid(model.getId());
|
||||
if (isUpdate) this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.descriptionAffiliation(model.getId())), Permission.EditDescription);
|
||||
else this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.dmpAffiliation(model.getDmpId())), Permission.EditDescription);
|
||||
|
||||
DmpDescriptionTemplateEntity dmpDescriptionTemplate = this.entityManager.find(DmpDescriptionTemplateEntity.class, model.getDmpDescriptionTemplateId());
|
||||
if (dmpDescriptionTemplate == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getDmpDescriptionTemplateId(), DmpDescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
|
||||
if (isUpdate) this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.descriptionAffiliation(model.getId())), Permission.EditDescription);
|
||||
else this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.descriptionsAffiliationBySection(model.getDmpId(), dmpDescriptionTemplate.getSectionId())), Permission.EditDescription);
|
||||
|
||||
DescriptionEntity data;
|
||||
if (isUpdate) {
|
||||
|
@ -167,9 +187,6 @@ public class DescriptionServiceImpl implements DescriptionService {
|
|||
data.setDmpDescriptionTemplateId(model.getDmpDescriptionTemplateId());
|
||||
}
|
||||
|
||||
DmpDescriptionTemplateEntity dmpDescriptionTemplate = this.entityManager.find(DmpDescriptionTemplateEntity.class, data.getDmpDescriptionTemplateId());
|
||||
if (dmpDescriptionTemplate == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{data.getDmpDescriptionTemplateId(), DmpDescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
|
||||
DescriptionTemplateEntity descriptionTemplateEntity = this.entityManager.find(DescriptionTemplateEntity.class, model.getDescriptionTemplateId());
|
||||
if (descriptionTemplateEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getDescriptionTemplateId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale()));
|
||||
|
||||
|
@ -267,11 +284,14 @@ public class DescriptionServiceImpl implements DescriptionService {
|
|||
switch (status) {
|
||||
case Draft:
|
||||
event.setNotificationType(notificationProperties.getDescriptionModifiedType());
|
||||
break;
|
||||
case Finalized:
|
||||
event.setNotificationType(notificationProperties.getDescriptionFinalisedType());
|
||||
break;
|
||||
default:
|
||||
throw new MyApplicationException("Unsupported Description Status.");
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
// public List<eu.eudat.commons.types.descriptiontemplate.FieldEntity> getFieldById(String id){
|
||||
|
|
|
@ -32,7 +32,7 @@ public interface DmpService {
|
|||
|
||||
Dmp buildClone(CloneDmpPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, IOException, InvalidApplicationException;
|
||||
|
||||
List<DmpUser> assignUsers(UUID dmp, List<DmpUserPersist> model, FieldSet fields) throws InvalidApplicationException, IOException;
|
||||
List<DmpUser> assignUsers(UUID dmp, List<DmpUserPersist> model, FieldSet fields, boolean disableDelete) throws InvalidApplicationException, IOException;
|
||||
Dmp removeUser(DmpUserRemovePersist model, FieldSet fields) throws InvalidApplicationException, IOException;
|
||||
|
||||
ResponseEntity<byte[]> export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException;
|
||||
|
|
|
@ -492,7 +492,7 @@ public class DmpServiceImpl implements DmpService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<DmpUser> assignUsers(UUID dmpId, List<DmpUserPersist> model, FieldSet fieldSet) throws InvalidApplicationException, IOException {
|
||||
public List<DmpUser> assignUsers(UUID dmpId, List<DmpUserPersist> model, FieldSet fieldSet, boolean disableDelete) throws InvalidApplicationException, IOException {
|
||||
this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.dmpAffiliation(dmpId)), Permission.AssignDmpUsers);
|
||||
|
||||
DmpEntity dmpEntity = this.entityManager.find(DmpEntity.class, dmpId);
|
||||
|
@ -522,7 +522,7 @@ public class DmpServiceImpl implements DmpService {
|
|||
}
|
||||
|
||||
List<DmpUserEntity> toDelete = existingUsers.stream().filter(x-> updatedCreatedIds.stream().noneMatch(y-> y.equals(x.getUserId()))).collect(Collectors.toList());
|
||||
if (!toDelete.isEmpty()) this.deleterFactory.deleter(DmpUserDeleter.class).delete(toDelete);
|
||||
if (!toDelete.isEmpty() && !disableDelete) this.deleterFactory.deleter(DmpUserDeleter.class).delete(toDelete);
|
||||
|
||||
this.entityManager.flush();
|
||||
|
||||
|
@ -913,7 +913,7 @@ public class DmpServiceImpl implements DmpService {
|
|||
}
|
||||
|
||||
}
|
||||
if(!usersToAssign.isEmpty()) this.assignUsers(id, usersToAssign, null);
|
||||
if(!usersToAssign.isEmpty()) this.assignUsers(id, usersToAssign, null, true);
|
||||
}
|
||||
|
||||
private void sendDmpInvitationExistingUser(UUID userId, DmpEntity dmp, DmpUserRole role) throws InvalidApplicationException {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package eu.eudat.service.lock;
|
||||
|
||||
import eu.eudat.authorization.AffiliatedResource;
|
||||
import eu.eudat.authorization.AuthorizationFlags;
|
||||
import eu.eudat.authorization.Permission;
|
||||
import eu.eudat.authorization.authorizationcontentresolver.AuthorizationContentResolver;
|
||||
|
@ -80,7 +81,9 @@ public class LockServiceImpl implements LockService {
|
|||
public Lock persist(LockPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException {
|
||||
logger.debug(new MapLogEntry("persisting data").And("model", model).And("fields", fields));
|
||||
|
||||
this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.dmpAffiliation(model.getTarget())), Permission.EditLock);
|
||||
AffiliatedResource affiliatedResourceDmp = this.authorizationContentResolver.dmpAffiliation(model.getTarget());
|
||||
AffiliatedResource affiliatedResourceDescription = this.authorizationContentResolver.descriptionAffiliation(model.getTarget());
|
||||
this.authorizationService.authorizeAtLeastOneForce(List.of(affiliatedResourceDmp, affiliatedResourceDescription), Permission.EditLock);
|
||||
|
||||
Boolean isUpdate = this.conventionService.isValidGuid(model.getId());
|
||||
|
||||
|
@ -179,7 +182,9 @@ public class LockServiceImpl implements LockService {
|
|||
public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException {
|
||||
logger.debug("deleting : {}", id);
|
||||
|
||||
this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.dmpAffiliation(id)), Permission.DeleteLock);
|
||||
AffiliatedResource affiliatedResourceDmp = this.authorizationContentResolver.dmpAffiliation(id);
|
||||
AffiliatedResource affiliatedResourceDescription = this.authorizationContentResolver.descriptionAffiliation(id);
|
||||
this.authorizationService.authorizeAtLeastOneForce(List.of(affiliatedResourceDmp, affiliatedResourceDescription), Permission.DeleteLock);
|
||||
|
||||
this.deleterFactory.deleter(LockDeleter.class).deleteAndSaveByIds(List.of(id));
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import eu.eudat.data.StorageFileEntity;
|
|||
import eu.eudat.model.*;
|
||||
import eu.eudat.model.builder.PublicDescriptionBuilder;
|
||||
import eu.eudat.model.persist.DescriptionFieldFilePersist;
|
||||
import eu.eudat.model.persist.DescriptionSectionPermissionResolver;
|
||||
import eu.eudat.service.storage.StorageFileService;
|
||||
import gr.cite.tools.validation.ValidationFilterAnnotation;
|
||||
import eu.eudat.model.builder.DescriptionBuilder;
|
||||
|
@ -185,6 +186,19 @@ public class DescriptionController {
|
|||
return persisted;
|
||||
}
|
||||
|
||||
@PostMapping("get-description-section-permissions")
|
||||
@ValidationFilterAnnotation(validator = DescriptionSectionPermissionResolver.DescriptionSectionPermissionResolverPersistValidator.ValidatorName, argumentName = "model")
|
||||
public Map<UUID, List<String>> getDescriptionSectionPermissions(@RequestBody DescriptionSectionPermissionResolver model) {
|
||||
logger.debug(new MapLogEntry("persisting" + Description.class.getSimpleName()).And("model", model));
|
||||
Map<UUID, List<String>> persisted = this.descriptionService.getDescriptionSectionPermissions(model);
|
||||
|
||||
this.auditService.track(AuditableAction.Description_GetDescriptionSectionPermissions, Map.ofEntries(
|
||||
new AbstractMap.SimpleEntry<String, Object>("model", model)
|
||||
));
|
||||
|
||||
return persisted;
|
||||
}
|
||||
|
||||
@GetMapping("validate")
|
||||
public List<DescriptionValidationResult> validate(@RequestParam(value="descriptionIds") List<UUID> descriptionIds) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
|
||||
logger.debug(new MapLogEntry("validating" + Description.class.getSimpleName()).And("descriptionIds", descriptionIds));
|
||||
|
|
|
@ -242,7 +242,7 @@ public class DmpController {
|
|||
public QueryResult<DmpUser> assignUsers(@PathVariable("id") UUID id, @RequestBody List<DmpUserPersist> model, FieldSet fieldSet) throws InvalidApplicationException, IOException {
|
||||
logger.debug(new MapLogEntry("assigning users to dmp").And("model", model).And("fieldSet", fieldSet));
|
||||
|
||||
List<DmpUser> persisted = this.dmpService.assignUsers(id, model, fieldSet);
|
||||
List<DmpUser> persisted = this.dmpService.assignUsers(id, model, fieldSet, false);
|
||||
|
||||
this.auditService.track(AuditableAction.Dmp_Assign_Users, Map.ofEntries(
|
||||
new AbstractMap.SimpleEntry<String, Object>("model", model),
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package eu.eudat.controllers;
|
||||
|
||||
import eu.eudat.audit.AuditableAction;
|
||||
import eu.eudat.authorization.AffiliatedResource;
|
||||
import eu.eudat.authorization.AuthorizationFlags;
|
||||
import eu.eudat.authorization.Permission;
|
||||
import eu.eudat.authorization.authorizationcontentresolver.AuthorizationContentResolver;
|
||||
|
@ -156,7 +157,7 @@ public class LockController {
|
|||
@GetMapping("target/status/{id}")
|
||||
public Boolean getLocked(@PathVariable("id") UUID targetId) throws Exception {
|
||||
logger.debug(new MapLogEntry("is locked" + Lock.class.getSimpleName()).And("targetId", targetId));
|
||||
this.authService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.dmpAffiliation(targetId)), Permission.BrowseLock);
|
||||
this.authService.authorizeForce(Permission.BrowseLock);
|
||||
|
||||
Boolean isLocked = this.lockService.isLocked(targetId);
|
||||
this.auditService.track(AuditableAction.Lock_IsLocked, Map.ofEntries(
|
||||
|
@ -168,8 +169,9 @@ public class LockController {
|
|||
@Transactional
|
||||
@DeleteMapping("target/unlock/{id}")
|
||||
public boolean unlock(@PathVariable("id") UUID targetId) throws Exception {
|
||||
logger.debug(new MapLogEntry("unlock" + Lock.class.getSimpleName()).And("targetId", targetId));
|
||||
this.authService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.dmpAffiliation(targetId)), Permission.BrowseLock);
|
||||
AffiliatedResource affiliatedResourceDmp = this.authorizationContentResolver.dmpAffiliation(targetId);
|
||||
AffiliatedResource affiliatedResourceDescription = this.authorizationContentResolver.descriptionAffiliation(targetId);
|
||||
this.authService.authorizeAtLeastOneForce(List.of(affiliatedResourceDmp, affiliatedResourceDescription), Permission.EditLock);
|
||||
|
||||
this.lockService.unlock(targetId);
|
||||
this.auditService.track(AuditableAction.Lock_UnLocked, Map.ofEntries(
|
||||
|
|
|
@ -147,9 +147,7 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
|
@ -159,9 +157,7 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
|
@ -171,9 +167,7 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -184,9 +178,7 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -241,6 +233,12 @@ permissions:
|
|||
BrowseDmpAssociatedUser:
|
||||
roles:
|
||||
- Admin
|
||||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -380,9 +378,6 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -393,9 +388,6 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -406,9 +398,6 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -419,22 +408,6 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
ExportDmp:
|
||||
roles:
|
||||
- Admin
|
||||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -445,9 +418,6 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -458,9 +428,6 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -471,9 +438,6 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -484,9 +448,6 @@ permissions:
|
|||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
claims: [ ]
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
|
@ -806,12 +767,9 @@ permissions:
|
|||
BrowseLock:
|
||||
roles:
|
||||
- Admin
|
||||
dmp:
|
||||
roles:
|
||||
- Owner
|
||||
- User
|
||||
- DescriptionContributor
|
||||
- Reviewer
|
||||
- DescriptionTemplateEditor
|
||||
- Manager
|
||||
- User
|
||||
clients: [ ]
|
||||
allowAnonymous: false
|
||||
allowAuthenticated: false
|
||||
|
|
|
@ -10,7 +10,6 @@ export enum AppPermission {
|
|||
DeleteDmpBlueprint = "DeleteDmpBlueprint",
|
||||
|
||||
//Description
|
||||
NewDescription = "NewDescription",
|
||||
BrowseDescription = "BrowseDescription",
|
||||
EditDescription = "EditDescription",
|
||||
FinalizeDescription = "FinalizeDescription",
|
||||
|
|
|
@ -144,3 +144,8 @@ export interface PublicDescriptionTemplate {
|
|||
label: string;
|
||||
description: string;
|
||||
}
|
||||
export interface DescriptionSectionPermissionResolver {
|
||||
dmpId: Guid;
|
||||
sectionIds: Guid[];
|
||||
permissions: string[];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { HttpClient, HttpHeaders, HttpParamsOptions, HttpResponse } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { Description, DescriptionPersist, DescriptionStatusPersist, PublicDescription } from '@app/core/model/description/description';
|
||||
import { Description, DescriptionPersist, DescriptionSectionPermissionResolver, DescriptionStatusPersist, PublicDescription } from '@app/core/model/description/description';
|
||||
import { DescriptionLookup } from '@app/core/query/description.lookup';
|
||||
import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration';
|
||||
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
||||
|
@ -33,6 +33,11 @@ export class DescriptionService {
|
|||
return this.http.post<QueryResult<Description>>(url, q).pipe(catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
getDescriptionSectionPermissions(q: DescriptionSectionPermissionResolver): Observable<Map<Guid, string[]>> {
|
||||
const url = `${this.apiBase}/get-description-section-permissions`;
|
||||
return this.http.post<Map<Guid, string[]>>(url, q).pipe(catchError((error: any) => throwError(error)));
|
||||
}
|
||||
|
||||
publicQuery(q: DescriptionLookup): Observable<QueryResult<PublicDescription>> {
|
||||
const url = `${this.apiBase}/public/query`;
|
||||
const params = new BaseHttpParams();
|
||||
|
|
|
@ -6,7 +6,7 @@ import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
|||
import { DmpStatus } from '@app/core/common/enum/dmp-status';
|
||||
import { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||
import { Description, DescriptionPersist, DescriptionStatusPersist } from '@app/core/model/description/description';
|
||||
import { Description, DescriptionPersist, DescriptionSectionPermissionResolver, DescriptionStatusPersist } from '@app/core/model/description/description';
|
||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||
import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service';
|
||||
import { DescriptionService } from '@app/core/services/description/description.service';
|
||||
|
@ -588,18 +588,29 @@ export class DescriptionEditorComponent extends BaseEditor<DescriptionEditorMode
|
|||
}
|
||||
|
||||
buildForm() {
|
||||
const canedit = this.isNew ? this.authService.hasPermission(AppPermission.NewDescription) :
|
||||
this.item.authorizationFlags?.some(x => x === AppPermission.EditDescription) || this.item.dmp.authorizationFlags?.some(x => x === AppPermission.EditDmp) ||this.authService.hasPermission(AppPermission.EditDescription);
|
||||
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !canedit);
|
||||
//this.visibilityRulesService.buildVisibilityRules(this.visibilityRulesService.getVisibilityRulesFromDescriptionTempalte(this.item.descriptionTemplate), this.formGroup);
|
||||
|
||||
// this.selectedSystemFields = this.selectedSystemFieldDisabled();
|
||||
this.descriptionEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
|
||||
if (this.editorModel.status == DescriptionStatus.Finalized || this.isDeleted) {
|
||||
this.formGroup.disable();
|
||||
const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
|
||||
dmpId: this.item.dmp.id,
|
||||
sectionIds: [this.item.dmpDescriptionTemplate.sectionId],
|
||||
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription]
|
||||
}
|
||||
this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel)
|
||||
.pipe(takeUntil(this._destroyed)).subscribe(
|
||||
permissionPerSection => {
|
||||
const canedit = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.EditDescription);
|
||||
this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !canedit);
|
||||
//this.visibilityRulesService.buildVisibilityRules(this.visibilityRulesService.getVisibilityRulesFromDescriptionTempalte(this.item.descriptionTemplate), this.formGroup);
|
||||
|
||||
// this.selectedSystemFields = this.selectedSystemFieldDisabled();
|
||||
this.descriptionEditorService.setValidationErrorModel(this.editorModel.validationErrorModel);
|
||||
if (this.editorModel.status == DescriptionStatus.Finalized || this.isDeleted) {
|
||||
this.formGroup.disable();
|
||||
}
|
||||
|
||||
this.registerFormListeners();
|
||||
},
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
|
||||
this.registerFormListeners();
|
||||
}
|
||||
|
||||
refreshData(): void {
|
||||
|
|
|
@ -39,10 +39,11 @@ const routes: Routes = [
|
|||
data: {
|
||||
...BreadcrumbService.generateRouteDataConfiguration({
|
||||
title: 'BREADCRUMBS.EDIT-DESCRIPTION'
|
||||
}),
|
||||
authContext: {
|
||||
permissions: [AppPermission.EditDescription]
|
||||
}
|
||||
})
|
||||
// ,
|
||||
// authContext: {
|
||||
// permissions: [AppPermission.EditDescription]
|
||||
// }
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -90,12 +90,12 @@
|
|||
<li *ngFor="let description of descriptionsInSection(section.id); let descriptionIndex = index" (click)="editDescription(description.id, false)" class="active-dataset">
|
||||
<div class="d-flex flex-direction-row">
|
||||
<div class="label" matTooltip="{{description.label}}">{{'DMP-EDITOR.DESCRIPTION' | translate}}: {{ description.label }}</div>
|
||||
<mat-icon *ngIf="description.status !== descriptionStatusEnum.Finalized" class="ml-2 mr-2 remove-dataset size-16" matTooltip="{{'DMP-EDITOR.ACTIONS.DELETE' | translate}}" (click)="$event.stopPropagation(); removeDescription(description.id)">close</mat-icon>
|
||||
<mat-icon *ngIf="description.status !== descriptionStatusEnum.Finalized && canDeleteSection(section.id)" class="ml-2 mr-2 remove-dataset size-16" matTooltip="{{'DMP-EDITOR.ACTIONS.DELETE' | translate}}" (click)="$event.stopPropagation(); removeDescription(description.id)">close</mat-icon>
|
||||
<mat-icon *ngIf="description.status === descriptionStatusEnum.Finalized" class="ml-2 mr-2 status-icon check-icon size-16" matTooltip="{{'TYPES.DATASET-STATUS.FINALISED' | translate}}">check</mat-icon>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
<ul *ngIf="item.id && section.hasTemplates" class="add-dataset-option">
|
||||
<ul *ngIf="item.id && section.hasTemplates && canEditSection(section.id)" class="add-dataset-option">
|
||||
<li>
|
||||
<a class="add-dataset-action" [routerLink]="['/descriptions/edit/' + item.id + '/' + section.id]">
|
||||
<mat-icon>add</mat-icon>{{'DMP-EDITOR.ACTIONS.ADD-DESCRIPTION-IN-SECTION' | translate}}
|
||||
|
|
|
@ -47,6 +47,8 @@ import { DmpEditorService } from './dmp-editor.service';
|
|||
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
|
||||
import { DmpUserType } from '@app/core/common/enum/dmp-user-type';
|
||||
import { DescriptionService } from '@app/core/services/description/description.service';
|
||||
import { DescriptionSectionPermissionResolver } from '@app/core/model/description/description';
|
||||
import { UUID } from 'crypto';
|
||||
|
||||
@Component({
|
||||
selector: 'app-dmp-editor',
|
||||
|
@ -73,6 +75,9 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
dmpUserTypeEnum = DmpUserType;
|
||||
dmpUserTypeEnumValues = this.enumUtils.getEnumValues<DmpUserType>(DmpUserType);
|
||||
dmpUserRoleEnumValues = this.enumUtils.getEnumValues<DmpUserRole>(DmpUserRole);
|
||||
|
||||
permissionPerSection: Map<Guid, string[]>;
|
||||
|
||||
singleAutocompleteBlueprintConfiguration: SingleAutoCompleteConfiguration = {
|
||||
initialItems: (data?: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(null, null, null, [DmpBlueprintStatus.Finalized])).pipe(map(x => x.items)),
|
||||
filterFn: (searchQuery: string, data?: any) => this.dmpBlueprintService.query(this.dmpBlueprintService.buildAutocompleteLookup(searchQuery, null, null, [DmpBlueprintStatus.Finalized])).pipe(map(x => x.items)),
|
||||
|
@ -94,6 +99,19 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
return !this.isDeleted && (this.hasPermission(this.authService.permissionEnum.EditDmp) || this.item?.authorizationFlags?.some(x => x === AppPermission.EditDmp));
|
||||
}
|
||||
|
||||
protected canEditSection(id: Guid): boolean {
|
||||
return !this.isDeleted && (this.hasPermission(this.authService.permissionEnum.EditDescription) || this.item?.authorizationFlags?.some(x => x === AppPermission.EditDescription) || (
|
||||
this.permissionPerSection && this.permissionPerSection[id.toString()] && this.permissionPerSection[id.toString()].some(x => x === AppPermission.EditDescription)
|
||||
));
|
||||
}
|
||||
|
||||
protected canDeleteSection(id: Guid): boolean {
|
||||
return !this.isDeleted && (this.hasPermission(this.authService.permissionEnum.DeleteDescription) || this.item?.authorizationFlags?.some(x => x === AppPermission.DeleteDescription) || (
|
||||
this.permissionPerSection && this.permissionPerSection[id.toString()] && this.permissionPerSection[id.toString()].some(x => x === AppPermission.DeleteDescription)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private hasPermission(permission: AppPermission): boolean {
|
||||
return this.authService.hasPermission(permission) || this.item?.authorizationFlags?.some(x => x === permission) || this.editorModel?.permissions?.includes(permission);
|
||||
|
@ -190,15 +208,29 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
|||
if (data.descriptions) {
|
||||
if (data.status == DmpStatus.Finalized) {
|
||||
data.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
|
||||
} else {
|
||||
} else {
|
||||
data.descriptions = data.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled);
|
||||
}
|
||||
}
|
||||
this.item = data;
|
||||
|
||||
|
||||
this.selectedBlueprint = data?.blueprint;
|
||||
this.isDeleted = data ? data.isActive === IsActive.Inactive : false;
|
||||
this.buildForm();
|
||||
|
||||
const descriptionSectionPermissionResolverModel: DescriptionSectionPermissionResolver = {
|
||||
dmpId: data.id,
|
||||
sectionIds: data?.blueprint?.definition?.sections?.map(x => x.id),
|
||||
permissions: [AppPermission.EditDescription, AppPermission.DeleteDescription]
|
||||
}
|
||||
this.descriptionService.getDescriptionSectionPermissions(descriptionSectionPermissionResolverModel)
|
||||
.pipe(takeUntil(this._destroyed)).subscribe(
|
||||
complete => {
|
||||
this.permissionPerSection = complete,
|
||||
this.buildForm();
|
||||
},
|
||||
error => this.onCallbackError(error)
|
||||
);
|
||||
|
||||
} catch (error) {
|
||||
this.logger.error('Could not parse Dmp item: ' + data + error);
|
||||
this.uiNotificationService.snackBarNotification(this.language.instant('COMMONS.ERRORS.DEFAULT'), SnackBarNotificationLevel.Error);
|
||||
|
|
|
@ -42,6 +42,7 @@ export class DmpEditorResolver extends BaseEditorResolver {
|
|||
|
||||
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.EditDmp].join('.'),
|
||||
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.DeleteDmp].join('.'),
|
||||
[nameof<Dmp>(x => x.authorizationFlags), AppPermission.EditDescription].join('.'),
|
||||
|
||||
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.dmpBlueprintValues), nameof<DmpBlueprintValue>(x => x.fieldId)].join('.'),
|
||||
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.dmpBlueprintValues), nameof<DmpBlueprintValue>(x => x.fieldValue)].join('.'),
|
||||
|
|
Loading…
Reference in New Issue