package eu.eudat.authorization.authorizationcontentresolver; import eu.eudat.authorization.AffiliatedResource; 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; import org.springframework.stereotype.Service; import org.springframework.web.context.annotation.RequestScope; import java.util.*; import java.util.stream.Collectors; @Service @RequestScope public class AuthorizationContentResolverImpl implements AuthorizationContentResolver { private final QueryFactory queryFactory; private final UserScope userScope; private final AffiliationCacheService affiliationCacheService; private final PermissionNameProvider permissionNameProvider; public AuthorizationContentResolverImpl(QueryFactory queryFactory, UserScope userScope, AffiliationCacheService affiliationCacheService, PermissionNameProvider permissionNameProvider) { this.queryFactory = queryFactory; this.userScope = userScope; this.affiliationCacheService = affiliationCacheService; this.permissionNameProvider = permissionNameProvider; } @Override public List getPermissionNames() { return permissionNameProvider.getPermissions(); } @Override public AffiliatedResource dmpAffiliation(UUID id) { return this.dmpsAffiliation(List.of(id)).getOrDefault(id, new AffiliatedResource()); } @Override public Map dmpsAffiliation(List ids){ UUID userId = this.userScope.getUserIdSafe(); Map affiliatedResources = new HashMap<>(); for (UUID id : ids){ affiliatedResources.put(id, new AffiliatedResource()); } if (userId == null || !userScope.isSet()) return affiliatedResources; List idsToResolve = this.getAffiliatedFromCache(ids, userId, affiliatedResources, DmpEntity.class.getSimpleName()); if (idsToResolve.isEmpty()) return affiliatedResources; List 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()); } this.ensureAffiliatedInCache(idsToResolve, userId, affiliatedResources, DmpEntity.class.getSimpleName()); return affiliatedResources; } @Override public AffiliatedResource descriptionAffiliation(UUID id) { return this.descriptionsAffiliation(List.of(id)).getOrDefault(id, new AffiliatedResource()); } @Override public Map descriptionsAffiliation(List ids){ UUID userId = this.userScope.getUserIdSafe(); Map affiliatedResources = new HashMap<>(); for (UUID id : ids){ affiliatedResources.put(id, new AffiliatedResource()); } if (userId == null || !userScope.isSet()) return affiliatedResources; List idsToResolve = this.getAffiliatedFromCache(ids, userId, affiliatedResources, DescriptionEntity.class.getSimpleName()); if (idsToResolve.isEmpty()) return affiliatedResources; List descriptionEntities = this.queryFactory.query(DescriptionQuery.class).ids(ids).collectAs(new BaseFieldSet().ensure(Description._id).ensure(Description._dmpDescriptionTemplate).ensure(Description._dmp)); List dmpDescriptionTemplateEntities = this.queryFactory.query(DmpDescriptionTemplateQuery.class).ids(descriptionEntities.stream().map(DescriptionEntity::getDmpDescriptionTemplateId).distinct().toList()).collectAs(new BaseFieldSet().ensure(DmpDescriptionTemplate._id).ensure(DmpDescriptionTemplate._sectionId)); Map dmpDescriptionTemplateEntityMap = dmpDescriptionTemplateEntities == null ? new HashMap<>() : dmpDescriptionTemplateEntities.stream().collect(Collectors.toMap(DmpDescriptionTemplateEntity::getId, x-> x)); List 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> dmpUsersMap = dmpUsers.stream().collect(Collectors.groupingBy(DmpUserEntity::getDmpId)); for (DescriptionEntity description : descriptionEntities){ List dmpDescriptionUsers = dmpUsersMap.getOrDefault(description.getDmpId(), new ArrayList<>()); for (DmpUserEntity dmpUser : dmpDescriptionUsers) { 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()); } } } } this.ensureAffiliatedInCache(idsToResolve, userId, affiliatedResources, DescriptionEntity.class.getSimpleName()); return affiliatedResources; } @Override public AffiliatedResource descriptionsAffiliationBySection(UUID dmpId, UUID sectionId){ return this.descriptionsAffiliationBySections(dmpId, List.of(sectionId)).getOrDefault(sectionId, new AffiliatedResource()); } @Override public Map descriptionsAffiliationBySections(UUID dmpId, List sectionIds){ UUID userId = this.userScope.getUserIdSafe(); Map affiliatedResources = new HashMap<>(); for (UUID id : sectionIds){ affiliatedResources.put(id, new AffiliatedResource()); } if (userId == null || !userScope.isSet()) return affiliatedResources; List 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 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 getAffiliatedFromCache(List ids, UUID userId, Map affiliatedResources, String entityType){ List idsToResolve = new ArrayList<>(); for (UUID id : ids){ AffiliationCacheService.AffiliationCacheValue cacheValue = this.affiliationCacheService.lookup(this.affiliationCacheService.buildKey(userId, id, entityType)); if (cacheValue != null) affiliatedResources.put(id, cacheValue.getAffiliatedResource()); else idsToResolve.add(id); } return idsToResolve; } private void ensureAffiliatedInCache(List idsToResolve, UUID userId, Map affiliatedResources, String entityType){ for (UUID id : idsToResolve){ AffiliatedResource affiliatedResource = affiliatedResources.getOrDefault(id, null); if (affiliatedResource != null) { AffiliationCacheService.AffiliationCacheValue cacheValue = new AffiliationCacheService.AffiliationCacheValue(userId, id, entityType, affiliatedResource); this.affiliationCacheService.put(cacheValue); } } } }