add dmp associated user query
This commit is contained in:
parent
1a567c9a81
commit
c9640bcb54
|
@ -86,6 +86,7 @@ public class AuditableAction {
|
||||||
public static final EventId User_MergeConfirm = new EventId(11011, "User_MergeConfirm");
|
public static final EventId User_MergeConfirm = new EventId(11011, "User_MergeConfirm");
|
||||||
public static final EventId User_RemoveCredentialRequest = new EventId(11012, "User_RemoveCredentialRequest");
|
public static final EventId User_RemoveCredentialRequest = new EventId(11012, "User_RemoveCredentialRequest");
|
||||||
public static final EventId User_RemoveCredentialConfirm = new EventId(11013, "User_RemoveCredentialConfirm");
|
public static final EventId User_RemoveCredentialConfirm = new EventId(11013, "User_RemoveCredentialConfirm");
|
||||||
|
public static final EventId User_DmpAssociatedQuery = new EventId(11014, "User_DmpAssociatedQuery");
|
||||||
|
|
||||||
public static final EventId Tenant_Query = new EventId(12000, "Tenant_Query");
|
public static final EventId Tenant_Query = new EventId(12000, "Tenant_Query");
|
||||||
public static final EventId Tenant_Lookup = new EventId(12001, "Tenant_Lookup");
|
public static final EventId Tenant_Lookup = new EventId(12001, "Tenant_Lookup");
|
||||||
|
|
|
@ -56,7 +56,7 @@ public final class Permission {
|
||||||
public static String EditUser = "EditUser";
|
public static String EditUser = "EditUser";
|
||||||
public static String DeleteUser = "DeleteUser";
|
public static String DeleteUser = "DeleteUser";
|
||||||
public static String ExportUsers = "ExportUsers";
|
public static String ExportUsers = "ExportUsers";
|
||||||
|
public static String BrowseDmpAssociatedUser = "BrowseDmpAssociatedUser";
|
||||||
|
|
||||||
|
|
||||||
//StorageFile
|
//StorageFile
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package eu.eudat.model;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class DmpAssociatedUser {
|
||||||
|
|
||||||
|
private UUID id;
|
||||||
|
public static final String _id = "id";
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
public static final String _name = "name";
|
||||||
|
|
||||||
|
private String email;
|
||||||
|
public static final String _email = "email";
|
||||||
|
|
||||||
|
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 getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmail(String email) {
|
||||||
|
this.email = email;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
package eu.eudat.model.builder;
|
||||||
|
|
||||||
|
import eu.eudat.authorization.AuthorizationFlags;
|
||||||
|
import eu.eudat.commons.JsonHandlingService;
|
||||||
|
import eu.eudat.commons.enums.ContactInfoType;
|
||||||
|
import eu.eudat.commons.types.user.AdditionalInfoEntity;
|
||||||
|
import eu.eudat.convention.ConventionService;
|
||||||
|
import eu.eudat.data.UserEntity;
|
||||||
|
import eu.eudat.model.*;
|
||||||
|
import eu.eudat.model.referencetypedefinition.ReferenceTypeSourceBaseConfiguration;
|
||||||
|
import eu.eudat.query.TenantUserQuery;
|
||||||
|
import eu.eudat.query.UserContactInfoQuery;
|
||||||
|
import eu.eudat.query.UserCredentialQuery;
|
||||||
|
import eu.eudat.query.UserRoleQuery;
|
||||||
|
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.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class DmpAssociatedUserBuilder extends BaseBuilder<DmpAssociatedUser, UserEntity> {
|
||||||
|
|
||||||
|
private final QueryFactory queryFactory;
|
||||||
|
|
||||||
|
private final BuilderFactory builderFactory;
|
||||||
|
|
||||||
|
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public DmpAssociatedUserBuilder(ConventionService conventionService,
|
||||||
|
QueryFactory queryFactory,
|
||||||
|
BuilderFactory builderFactory) {
|
||||||
|
super(conventionService, new LoggerService(LoggerFactory.getLogger(DmpAssociatedUserBuilder.class)));
|
||||||
|
this.queryFactory = queryFactory;
|
||||||
|
this.builderFactory = builderFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DmpAssociatedUserBuilder authorize(EnumSet<AuthorizationFlags> values) {
|
||||||
|
this.authorize = values;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DmpAssociatedUser> build(FieldSet fields, List<UserEntity> data) throws MyApplicationException {
|
||||||
|
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).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 || data == null || fields.isEmpty())
|
||||||
|
return new ArrayList<>();
|
||||||
|
|
||||||
|
List<DmpAssociatedUser> models = new ArrayList<>();
|
||||||
|
|
||||||
|
Map<UUID, List<UserContactInfo>> contactsMap = this.collectUserContactInfos(new BaseFieldSet().ensure(UserContactInfo._value).ensure(UserContactInfo._type).ensure(UserContactInfo._ordinal), data);
|
||||||
|
|
||||||
|
for (UserEntity d : data) {
|
||||||
|
DmpAssociatedUser m = new DmpAssociatedUser();
|
||||||
|
if (fields.hasField(this.asIndexer(User._id))) m.setId(d.getId());
|
||||||
|
if (fields.hasField(this.asIndexer(User._name))) m.setName(d.getName());
|
||||||
|
if (contactsMap != null && contactsMap.containsKey(d.getId())){
|
||||||
|
List<UserContactInfo> contactInfos = contactsMap.get(d.getId());
|
||||||
|
if (contactInfos != null) {
|
||||||
|
contactInfos.sort(Comparator.comparing(UserContactInfo::getOrdinal));
|
||||||
|
m.setEmail(contactInfos.stream().filter(x -> ContactInfoType.Email.equals(x.getType())).map(UserContactInfo::getValue).findFirst().orElse(null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
models.add(m);
|
||||||
|
}
|
||||||
|
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
|
||||||
|
|
||||||
|
return models;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<UUID, List<UserContactInfo>> collectUserContactInfos(FieldSet fields, List<UserEntity> data) throws MyApplicationException {
|
||||||
|
if (fields.isEmpty() || data.isEmpty()) return null;
|
||||||
|
this.logger.debug("checking related - {}", UserContactInfo.class.getSimpleName());
|
||||||
|
|
||||||
|
Map<UUID, List<UserContactInfo>> itemMap;
|
||||||
|
FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(this.asIndexer(UserContactInfo._user, User._id));
|
||||||
|
UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).authorize(this.authorize).userIds(data.stream().map(UserEntity::getId).distinct().collect(Collectors.toList()));
|
||||||
|
itemMap = this.builderFactory.builder(UserContactInfoBuilder.class).authorize(this.authorize).asMasterKey(query, clone, x -> x.getUser().getId());
|
||||||
|
|
||||||
|
if (!fields.hasField(this.asIndexer(UserContactInfo._user, User._id))) {
|
||||||
|
itemMap.values().stream().flatMap(List::stream).filter(x -> x != null && x.getUser() != null).peek(x -> {
|
||||||
|
x.getUser().setId(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package eu.eudat.model.censorship;
|
||||||
|
|
||||||
|
import eu.eudat.authorization.OwnedResource;
|
||||||
|
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;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
public class DmpAssociatedUserCensor extends BaseCensor {
|
||||||
|
|
||||||
|
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpAssociatedUserCensor.class));
|
||||||
|
|
||||||
|
protected final AuthorizationService authService;
|
||||||
|
|
||||||
|
|
||||||
|
public DmpAssociatedUserCensor(ConventionService conventionService, AuthorizationService authService) {
|
||||||
|
super(conventionService);
|
||||||
|
this.authService = authService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void censor(FieldSet fields, UUID userId) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -5,22 +5,23 @@ import eu.eudat.authorization.Permission;
|
||||||
import eu.eudat.commons.enums.IsActive;
|
import eu.eudat.commons.enums.IsActive;
|
||||||
import eu.eudat.commons.scope.user.UserScope;
|
import eu.eudat.commons.scope.user.UserScope;
|
||||||
import eu.eudat.data.*;
|
import eu.eudat.data.*;
|
||||||
import eu.eudat.model.DmpDescriptionTemplate;
|
import eu.eudat.model.Language;
|
||||||
import eu.eudat.model.User;
|
import eu.eudat.model.User;
|
||||||
import eu.eudat.model.PublicUser;
|
import eu.eudat.model.PublicUser;
|
||||||
import eu.eudat.model.UserRole;
|
|
||||||
import eu.eudat.query.utils.BuildSubQueryInput;
|
import eu.eudat.query.utils.BuildSubQueryInput;
|
||||||
import eu.eudat.query.utils.QueryUtilsService;
|
import eu.eudat.query.utils.QueryUtilsService;
|
||||||
import gr.cite.commons.web.authz.service.AuthorizationService;
|
import gr.cite.commons.web.authz.service.AuthorizationService;
|
||||||
import gr.cite.tools.data.query.FieldResolver;
|
import gr.cite.tools.data.query.FieldResolver;
|
||||||
import gr.cite.tools.data.query.QueryBase;
|
import gr.cite.tools.data.query.QueryBase;
|
||||||
import gr.cite.tools.data.query.QueryContext;
|
import gr.cite.tools.data.query.QueryContext;
|
||||||
|
import gr.cite.tools.exception.MyNotFoundException;
|
||||||
import jakarta.persistence.Tuple;
|
import jakarta.persistence.Tuple;
|
||||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||||
import jakarta.persistence.criteria.Predicate;
|
import jakarta.persistence.criteria.Predicate;
|
||||||
import jakarta.persistence.criteria.Subquery;
|
import jakarta.persistence.criteria.Subquery;
|
||||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
|
import org.springframework.context.i18n.LocaleContextHolder;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
@ -30,6 +31,7 @@ import java.util.*;
|
||||||
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
public class UserQuery extends QueryBase<UserEntity> {
|
public class UserQuery extends QueryBase<UserEntity> {
|
||||||
private String like;
|
private String like;
|
||||||
|
private Boolean dmpAssociated;
|
||||||
private Collection<UUID> ids;
|
private Collection<UUID> ids;
|
||||||
private Collection<String> emails;
|
private Collection<String> emails;
|
||||||
private Collection<UUID> excludedIds;
|
private Collection<UUID> excludedIds;
|
||||||
|
@ -117,6 +119,11 @@ public class UserQuery extends QueryBase<UserEntity> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UserQuery dmpAssociated(Boolean dmpAssociated) {
|
||||||
|
this.dmpAssociated = dmpAssociated;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public UserQuery authorize(EnumSet<AuthorizationFlags> values) {
|
public UserQuery authorize(EnumSet<AuthorizationFlags> values) {
|
||||||
this.authorize = values;
|
this.authorize = values;
|
||||||
return this;
|
return this;
|
||||||
|
@ -186,7 +193,7 @@ public class UserQuery extends QueryBase<UserEntity> {
|
||||||
new BuildSubQueryInput.Builder<>(UserContactInfoQuery.class, UUID.class, queryContext)
|
new BuildSubQueryInput.Builder<>(UserContactInfoQuery.class, UUID.class, queryContext)
|
||||||
.keyPathFunc((subQueryRoot) -> subQueryRoot.get(UserContactInfoEntity._id))
|
.keyPathFunc((subQueryRoot) -> subQueryRoot.get(UserContactInfoEntity._id))
|
||||||
.filterFunc((subQueryRoot, cb) -> {
|
.filterFunc((subQueryRoot, cb) -> {
|
||||||
CriteriaBuilder.In<String> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserContactInfoEntity._value));
|
CriteriaBuilder.In<String> inClause = cb.in(subQueryRoot.get(UserContactInfoEntity._value));
|
||||||
for (String item : this.emails)
|
for (String item : this.emails)
|
||||||
inClause.value(item);
|
inClause.value(item);
|
||||||
return inClause;
|
return inClause;
|
||||||
|
@ -199,6 +206,30 @@ public class UserQuery extends QueryBase<UserEntity> {
|
||||||
QueryContext<UserRoleEntity, UUID> subQuery = this.applySubQuery(this.userRoleQuery, queryContext, UUID.class, userRoleEntityRoot -> userRoleEntityRoot.get(UserRoleEntity._userId));
|
QueryContext<UserRoleEntity, UUID> subQuery = this.applySubQuery(this.userRoleQuery, queryContext, UUID.class, userRoleEntityRoot -> userRoleEntityRoot.get(UserRoleEntity._userId));
|
||||||
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(UserEntity._id)).value(subQuery.Query));
|
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(UserEntity._id)).value(subQuery.Query));
|
||||||
}
|
}
|
||||||
|
if (this.dmpAssociated){
|
||||||
|
UUID userId;
|
||||||
|
if (this.userScope.isSet()) userId = this.userScope.getUserIdSafe();
|
||||||
|
else throw new MyNotFoundException("Only user scoped allowed");
|
||||||
|
|
||||||
|
Subquery<UUID> dmpUserDmpQuery = queryUtilsService.buildSubQuery(new BuildSubQueryInput<>(
|
||||||
|
new BuildSubQueryInput.Builder<>(DmpUserQuery.class, UUID.class, queryContext)
|
||||||
|
.keyPathFunc((subQueryRoot) -> subQueryRoot.get(DmpUserEntity._dmpId))
|
||||||
|
.filterFunc((subQueryRoot, cb) -> cb.and(
|
||||||
|
cb.equal(subQueryRoot.get(DmpUserEntity._userId), userId),
|
||||||
|
cb.equal(subQueryRoot.get(DmpUserEntity._isActive), IsActive.Active)
|
||||||
|
))
|
||||||
|
));
|
||||||
|
|
||||||
|
Subquery<UUID> dmpUserUserQuery = queryUtilsService.buildSubQuery(new BuildSubQueryInput<>(
|
||||||
|
new BuildSubQueryInput.Builder<>(DmpUserQuery.class, UUID.class, queryContext)
|
||||||
|
.keyPathFunc((subQueryRoot) -> subQueryRoot.get(DmpUserEntity._userId))
|
||||||
|
.filterFunc((subQueryRoot, cb) -> cb.and(
|
||||||
|
cb.in(subQueryRoot.get(DmpUserEntity._dmpId)).value(dmpUserDmpQuery) ,
|
||||||
|
cb.equal(subQueryRoot.get(DmpUserEntity._isActive), IsActive.Active)
|
||||||
|
))
|
||||||
|
));
|
||||||
|
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(UserEntity._id)).value(dmpUserUserQuery));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!predicates.isEmpty()) {
|
if (!predicates.isEmpty()) {
|
||||||
|
|
|
@ -3,12 +3,16 @@ package eu.eudat.controllers.v2;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import eu.eudat.audit.AuditableAction;
|
import eu.eudat.audit.AuditableAction;
|
||||||
import eu.eudat.authorization.AuthorizationFlags;
|
import eu.eudat.authorization.AuthorizationFlags;
|
||||||
|
import eu.eudat.commons.enums.IsActive;
|
||||||
import eu.eudat.commons.scope.user.UserScope;
|
import eu.eudat.commons.scope.user.UserScope;
|
||||||
import eu.eudat.commons.validation.ValidationFilterAnnotation;
|
import eu.eudat.commons.validation.ValidationFilterAnnotation;
|
||||||
import eu.eudat.data.UserEntity;
|
import eu.eudat.data.UserEntity;
|
||||||
|
import eu.eudat.model.DmpAssociatedUser;
|
||||||
import eu.eudat.model.User;
|
import eu.eudat.model.User;
|
||||||
import eu.eudat.model.UserRole;
|
import eu.eudat.model.UserRole;
|
||||||
|
import eu.eudat.model.builder.DmpAssociatedUserBuilder;
|
||||||
import eu.eudat.model.builder.UserBuilder;
|
import eu.eudat.model.builder.UserBuilder;
|
||||||
|
import eu.eudat.model.censorship.DmpAssociatedUserCensor;
|
||||||
import eu.eudat.model.censorship.UserCensor;
|
import eu.eudat.model.censorship.UserCensor;
|
||||||
import eu.eudat.model.persist.UserPersist;
|
import eu.eudat.model.persist.UserPersist;
|
||||||
import eu.eudat.model.persist.UserRolePatchPersist;
|
import eu.eudat.model.persist.UserRolePatchPersist;
|
||||||
|
@ -107,6 +111,23 @@ public class UserController {
|
||||||
return new QueryResult<>(models, count);
|
return new QueryResult<>(models, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("dmp-associated/query")
|
||||||
|
public QueryResult<DmpAssociatedUser> queryDmpAssociated(@RequestBody UserLookup lookup) throws MyApplicationException, MyForbiddenException {
|
||||||
|
logger.debug("querying {}", User.class.getSimpleName());
|
||||||
|
|
||||||
|
this.censorFactory.censor(DmpAssociatedUserCensor.class).censor(lookup.getProject(), null);
|
||||||
|
|
||||||
|
UserQuery query = lookup.enrich(this.queryFactory).dmpAssociated(true).isActive(IsActive.Active);
|
||||||
|
|
||||||
|
List<UserEntity> data = query.collectAs(lookup.getProject());
|
||||||
|
List<DmpAssociatedUser> models = this.builderFactory.builder(DmpAssociatedUserBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(lookup.getProject(), data);
|
||||||
|
long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size();
|
||||||
|
|
||||||
|
this.auditService.track(AuditableAction.User_DmpAssociatedQuery, "lookup", lookup);
|
||||||
|
|
||||||
|
return new QueryResult<>(models, count);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("{id}")
|
@GetMapping("{id}")
|
||||||
public User get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
|
public User get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException {
|
||||||
logger.debug(new MapLogEntry("retrieving" + User.class.getSimpleName()).And("id", id).And("fields", fieldSet));
|
logger.debug(new MapLogEntry("retrieving" + User.class.getSimpleName()).And("id", id).And("fields", fieldSet));
|
||||||
|
|
|
@ -217,6 +217,16 @@ permissions:
|
||||||
clients: [ ]
|
clients: [ ]
|
||||||
allowAnonymous: false
|
allowAnonymous: false
|
||||||
allowAuthenticated: false
|
allowAuthenticated: false
|
||||||
|
BrowseDmpAssociatedUser:
|
||||||
|
roles:
|
||||||
|
- Admin
|
||||||
|
- DescriptionTemplateEditor
|
||||||
|
- Manager
|
||||||
|
- User
|
||||||
|
claims: [ ]
|
||||||
|
clients: [ ]
|
||||||
|
allowAnonymous: false
|
||||||
|
allowAuthenticated: false
|
||||||
# DescriptionTemplateType
|
# DescriptionTemplateType
|
||||||
BrowseDescriptionTemplateType:
|
BrowseDescriptionTemplateType:
|
||||||
roles:
|
roles:
|
||||||
|
|
Loading…
Reference in New Issue