package gr.cite.annotation.authorization.authorizationcontentresolver; import gr.cite.annotation.authorization.AffiliatedResource; import gr.cite.annotation.authorization.PermissionNameProvider; import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.scope.user.UserScope; import gr.cite.annotation.data.AnnotationEntity; import gr.cite.annotation.data.EntityUserEntity; import gr.cite.annotation.model.Annotation; import gr.cite.annotation.model.EntityUser; import gr.cite.annotation.query.AnnotationQuery; import gr.cite.annotation.query.EntityUserQuery; 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 AffiliatedResource entityAffiliation(UUID id) { return this.entitiesAffiliation(List.of(id)).getOrDefault(id, new AffiliatedResource()); } @Override public Map entitiesAffiliation(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, AnnotationEntity._entityId); if (idsToResolve.isEmpty()) return affiliatedResources; List entityUsers = this.queryFactory.query(EntityUserQuery.class).entityIds(ids).userIds(userId).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(EntityUser._id).ensure(EntityUser._entityId)); for (UUID entityId : entityUsers.stream().map(EntityUserEntity::getEntityId).distinct().toList()){ affiliatedResources.get(entityId).setAffiliated(true); } this.ensureAffiliatedInCache(idsToResolve, userId, affiliatedResources, AnnotationEntity._entityId); return affiliatedResources; } @Override public List getPermissionNames() { return permissionNameProvider.getPermissions(); } @Override public AffiliatedResource annotationAffiliation(UUID id) { return this.annotationsAffiliation(List.of(id)).getOrDefault(id, new AffiliatedResource()); } @Override public Map annotationsAffiliation(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, AnnotationEntity.class.getSimpleName()); if (idsToResolve.isEmpty()) return affiliatedResources; List annotationEntities = this.queryFactory.query(AnnotationQuery.class).ids(ids).collectAs(new BaseFieldSet().ensure(Annotation._id).ensure(Annotation._entityId).ensure(Annotation._id)); List entityUsers = this.queryFactory.query(EntityUserQuery.class).entityIds(annotationEntities.stream().map(AnnotationEntity::getEntityId).distinct().toList()).userIds(userId).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(EntityUser._id).ensure(EntityUser._entityId)); Map> dmpUsersMap = entityUsers.stream().collect(Collectors.groupingBy(EntityUserEntity::getEntityId)); for (AnnotationEntity annotation : annotationEntities){ List dmpDescriptionUsers = dmpUsersMap.getOrDefault(annotation.getEntityId(), new ArrayList<>()); if (!dmpDescriptionUsers.isEmpty()) { affiliatedResources.get(annotation.getId()).setAffiliated(true); } } this.ensureAffiliatedInCache(idsToResolve, userId, affiliatedResources, AnnotationEntity.class.getSimpleName()); 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); } } } }