diff --git a/repository/src/main/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java b/repository/src/main/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java index 388404d15fe..76968fea262 100644 --- a/repository/src/main/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java +++ b/repository/src/main/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java @@ -1001,8 +1001,10 @@ class Analyzer extends BaseBatchProcessWorker private final Map groupsToCreate = new TreeMap(); private final Map> personParentAssocsToCreate = newPersonMap(); private final Map> personParentAssocsToDelete = newPersonMap(); + private final List personToRezone = new LinkedList<>(); private Map> groupParentAssocsToCreate = new TreeMap>(); private final Map> groupParentAssocsToDelete = new TreeMap>(); + private final List groupToRezone = new LinkedList<>(); private final Map> finalGroupChildAssocs = new TreeMap>(); private List personsProcessed = new LinkedList(); private Set allZonePersons = Collections.emptySet(); @@ -1268,7 +1270,18 @@ private void recordParentAssociationCreation(String child, String parent) parents.add(parent); } } - + + private void recordParentAssociationAuthoritiesToRezone(String child) + { + if (child != null) + { + List toRezone = AuthorityType.getAuthorityType(child) == AuthorityType.USER + ? this.personToRezone + : this.groupToRezone; + toRezone.add(child); + } + } + private void validateGroupParentAssocsToCreate() { Iterator>> i = this.groupParentAssocsToCreate.entrySet().iterator(); @@ -1432,36 +1445,55 @@ private void logRetainParentAssociations(Map> parentAssocs, String child = entry.getKey(); if (!toRetain.contains(child)) { - if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled()) + if (!shouldRezone(child)) { - if (groupList == null) - { - groupList = new StringBuilder(1024); - } - else - { - groupList.setLength(0); - } - for (String parent : entry.getValue()) + if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled()) { - if (groupList.length() > 0) + if (groupList == null) { - groupList.append(", "); + groupList = new StringBuilder(1024); } - groupList.append('\'').append( - ChainingUserRegistrySynchronizer.this.authorityService.getShortName(parent)) - .append('\''); + else + { + groupList.setLength(0); + } + for (String parent : entry.getValue()) + { + if (groupList.length() > 0) + { + groupList.append(", "); + } + groupList.append('\'').append( + ChainingUserRegistrySynchronizer.this.authorityService.getShortName(parent)) + .append('\''); + } + ChainingUserRegistrySynchronizer.logger.debug("Ignoring non-existent member '" + + ChainingUserRegistrySynchronizer.this.authorityService.getShortName(child) + + "' in groups {" + groupList.toString() + "}"); } - ChainingUserRegistrySynchronizer.logger.debug("Ignoring non-existent member '" - + ChainingUserRegistrySynchronizer.this.authorityService.getShortName(child) - + "' in groups {" + groupList.toString() + "}"); + i.remove(); + } + else { + recordParentAssociationAuthoritiesToRezone(child); } - i.remove(); } } } + private boolean shouldRezone(String authorityName) + { + boolean exists = authorityService.authorityExists(authorityName); + + if (exists) + { + Set zones = ChainingUserRegistrySynchronizer.this.authorityService.getAuthorityZones(authorityName); + return isInZone(authorityName, zones, AuthorityService.ZONE_AUTH_ALFRESCO) && !isInZone(authorityName, zones, zoneId); + } + + return false; + } + private void processGroups(UserRegistry userRegistry, boolean isFullSync, boolean splitTxns) { // MNT-12454 fix. If syncDelete is false, there is no need to pull all users and all groups from LDAP during the full synchronization. @@ -1634,6 +1666,7 @@ public String getIdentifier(Map.Entry> entry) public void process(Map.Entry> entry) throws Throwable { maintainAssociationCreations(entry.getKey()); + maintainAssociationCreationsToRezone(entry.getKey()); } }, splitTxns); } @@ -1667,6 +1700,7 @@ public void process(Map.Entry> entry) throws Throwable { maintainAssociationDeletions(entry.getKey()); maintainAssociationCreations(entry.getKey()); + maintainAssociationCreationsToRezone(entry.getKey()); } }, splitTxns); } @@ -1742,6 +1776,25 @@ private void maintainAssociationCreations(String authorityName) } } } + + private void maintainAssociationCreationsToRezone(String authorityName) + { + boolean isPerson = AuthorityType.getAuthorityType(authorityName) == AuthorityType.USER; + + List authorities = isPerson ? this.personToRezone : this.groupToRezone; + Map> parentAssocsToCreate = isPerson ? this.personParentAssocsToCreate : this.groupParentAssocsToCreate; + + if (authorities != null && !authorities.isEmpty() && parentAssocsToCreate.containsKey(authorityName)) + { + if (ChainingUserRegistrySynchronizer.logger.isDebugEnabled()) + { + ChainingUserRegistrySynchronizer.logger.debug( + "Changing '" + ChainingUserRegistrySynchronizer.this.authorityService.getShortName(authorityName) + + "' to zone '" + zoneId + "'"); + } + updateAuthorityZones(authorityName, ChainingUserRegistrySynchronizer.this.authorityService.getAuthorityZones(authorityName), zoneSet); + } + } } // end of Analyzer class // Run the first process the Group Analyzer @@ -1906,6 +1959,7 @@ else if (!allowDeletions || intersection.isEmpty()) // create cycles) groupAnalyzer.maintainAssociationDeletions(personName); groupAnalyzer.maintainAssociationCreations(personName); + groupAnalyzer.maintainAssociationCreationsToRezone(personName); synchronized (this) { @@ -2118,10 +2172,32 @@ private void updateAuthorityZones(String authorityName, Set oldZones, fi zonesToAdd.removeAll(oldZones); if (!zonesToAdd.isEmpty()) { + // Prevents the authority from being added to zones where already is + Set currentZones = this.authorityService.getAuthorityZones(authorityName); + if (currentZones != null && !currentZones.isEmpty()) + { + zonesToAdd.removeAll(currentZones); + } this.authorityService.addAuthorityToZones(authorityName, zonesToAdd); } } - + + /** + * Checks if the supplied authority is part of a certain zone + * + * @param authorityName + * the name of authority to check + * @param authorityZones + * the zones where authority is + * @param zoneToCheck + * the zone to check + * @return true in case the authority is in supplied zone + */ + private boolean isInZone(String authorityName, Set authorityZones, String zoneToCheck) + { + return authorityName != null && authorityZones != null && zoneToCheck != null && authorityZones.contains(zoneToCheck); + } + @Override protected void onBootstrap(ApplicationEvent event) {