Author: ddam Date: Thu Mar 5 18:46:22 2009 New Revision: 750545 URL: http://svn.apache.org/viewvc?rev=750545&view=rev Log: Jetspeed Security changes - Jetspeed synchronizer: fixed bugs in default synchronizer - Jetspeed synchronizer: make default synchronizer extendable - Jetspeed synchronizer: synchronize public interface methods - Jetspeed synchronizer: added optional recursive synchronization - Mapping model: added three extra methods to EntityDAO for fetching entities hierarchically - upgrade to Spring LDAP 1.3 Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/pom.xml portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/EntityDAO.java portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/impl/SpringLDAPEntityDAO.java portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedSecuritySynchronizer.java portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/OnStartupSecuritySynchronizationBean.java portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/pom.xml Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/pom.xml URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/pom.xml?rev=750545&r1=750544&r2=750545&view=diff ============================================================================== --- portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/pom.xml (original) +++ portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/pom.xml Thu Mar 5 18:46:22 2009 @@ -104,6 +104,7 @@ spring-ldap org.springframework.ldap + all Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java?rev=750545&r1=750544&r2=750545&view=diff ============================================================================== --- portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java (original) +++ portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java Thu Mar 5 18:46:22 2009 @@ -107,7 +107,7 @@ { if (synchronizer != null) { - synchronizer.synchronizeUserPrincipal(userName); + synchronizer.synchronizeUserPrincipal(userName,false); } return manager.getUser(userName); } Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/EntityDAO.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/EntityDAO.java?rev=750545&r1=750544&r2=750545&view=diff ============================================================================== --- portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/EntityDAO.java (original) +++ portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/EntityDAO.java Thu Mar 5 18:46:22 2009 @@ -40,6 +40,14 @@ Collection getEntitiesById(Collection entityIds); /** + * Fetch entity by providing an *internal* entity ID. + * + * @param internalId + * @return found entity + */ + Entity getEntityByInternalId(String internalId); + + /** * Fetch entities by providing a list of specific *internal* entity IDs. * * @param internal @@ -48,6 +56,7 @@ */ Collection getEntitiesByInternalId(Collection entityIds); + /** * Method for applying a specific filter on the complete entity set returned * by the DAO. The result would be the same as applying the specific filter @@ -60,6 +69,15 @@ Collection getEntities(Filter filter); /** + * Same as getEntities(Filter filter), except that this method only returns entities which are children of + * the given parent entity. + * @param parentEntity + * @param filter + * @return + */ + Collection getEntities(Entity parentEntity, Filter filter); + + /** * Fetch a single entity by ID. * * @param entityId @@ -68,6 +86,15 @@ Entity getEntity(String entityId); /** + * Returns the parent entity of the given entity, if there is any. + * + * @param filter a specific filter to narrow the returned entity set + * @return found entities + */ + Entity getParentEntity(Entity childEntity); + + + /** * Fetch all entities * * @return found entities Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/impl/SpringLDAPEntityDAO.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/impl/SpringLDAPEntityDAO.java?rev=750545&r1=750544&r2=750545&view=diff ============================================================================== --- portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/impl/SpringLDAPEntityDAO.java (original) +++ portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/impl/SpringLDAPEntityDAO.java Thu Mar 5 18:46:22 2009 @@ -55,22 +55,25 @@ public class SpringLDAPEntityDAO implements EntityDAO { - private enum UpdateMode { + protected enum UpdateMode { MAPPED, INTERNAL, ALL }; protected LdapTemplate ldapTemplate; - protected LDAPEntityDAOConfiguration configuration; + protected final LDAPEntityDAOConfiguration configuration; + protected final DistinguishedName searchDN; - private ContextMapper contextMapper; - - private EntityFactory entityFactory; + protected ContextMapper contextMapper; + protected EntityFactory entityFactory; + + public SpringLDAPEntityDAO(LDAPEntityDAOConfiguration configuration) { super(); this.configuration = configuration; + searchDN = new DistinguishedName(getConfiguration().getSearchDN()); this.entityFactory = new EntityFactoryImpl(configuration); this.contextMapper = new DefaultEntityContextMapper(entityFactory); } @@ -142,25 +145,44 @@ final Collection resultSet = new ArrayList(); for (Iterator iterator = internalIds.iterator(); iterator.hasNext();) { - String internalId = (String) iterator.next(); - DistinguishedName principalDN = getRelativeDN(internalId); - internalId = principalDN.toString(); - Entity resultEntity = null; + Entity resultEntity = getEntityByInternalId(iterator.next()); + if (resultEntity != null) + { + resultSet.add(resultEntity); + } + } + return resultSet; + } + + public Entity getEntityByInternalId(String internalId){ + Entity resultEntity = null; + DistinguishedName principalDN = getRelativeDN(internalId); + String relativeDN = principalDN.toCompactString(); + String searchDNStr = searchDN.toCompactString(); + if (relativeDN.equals(searchDNStr) || relativeDN.endsWith(searchDNStr)){ + internalId = principalDN.toCompactString(); + ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + resultEntity = (Entity) ldapTemplate.lookup(internalId, getContextMapper()); } finally { Thread.currentThread().setContextClassLoader(currentClassLoader); } - if (resultEntity != null) - { - resultSet.add(resultEntity); - } + } - return resultSet; + return resultEntity; + } + + public Entity getParentEntity(Entity childEntity) + { + + DistinguishedName parentDN = new DistinguishedName(childEntity.getInternalId()); + parentDN.removeLast(); + return getEntityByInternalId(parentDN.encode()); } protected DistinguishedName getRelativeDN(String fullDN) @@ -209,6 +231,25 @@ return results; } + + @SuppressWarnings("unchecked") + public Collection getEntities(Entity parent, Filter filter) + { + String filterStr = createSearchFilter(filter); + Collection results = null; + ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); + try + { + Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + String parentId = parent.getInternalId(); + DistinguishedName parentDN = getRelativeDN(parentId); + results = (Collection) ldapTemplate.search(parentDN.encode(), filterStr, SearchControls.ONELEVEL_SCOPE, getContextMapper()); + } finally{ + Thread.currentThread().setContextClassLoader(currentClassLoader); + } + + return results; + } public Collection getAllEntities() { Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedSecuritySynchronizer.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedSecuritySynchronizer.java?rev=750545&r1=750544&r2=750545&view=diff ============================================================================== --- portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedSecuritySynchronizer.java (original) +++ portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedSecuritySynchronizer.java Thu Mar 5 18:46:22 2009 @@ -22,10 +22,24 @@ */ public interface JetspeedSecuritySynchronizer { - void synchronizeUserPrincipal(String name); + + /** + * Synchronizes the user principal with the specified name. + * @param name + */ + void synchronizeUserPrincipal(String name, boolean recursive); - void synchronizePrincipalsByType(String principalTypeName); + /** + * Synchronize all principals of a certain type. + * @param principalTypeName + * @param recursive if true, all nested principals associated to this principal will be synchronized. If false, only the direct (first level) associated + * principals will be synchronized. + */ + void synchronizePrincipalsByType(String principalTypeName, boolean recursive); + /** + * Synchronizes all principals. + */ void synchronizeAll(); } Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java?rev=750545&r1=750544&r2=750545&view=diff ============================================================================== --- portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java (original) +++ portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java Thu Mar 5 18:46:22 2009 @@ -67,7 +67,7 @@ createRelations(); } - public void synchronizeAll() + public synchronized void synchronizeAll() { setSynchronizing(true); try @@ -79,7 +79,10 @@ { for (Entity entity : securityEntityManager.getAllEntities(type)) { - recursiveSynchronizeEntity(entity, synchronizationState); + // recursive is false, because that will synchronize all associated entities which are + // direct associations of the principal. Because all principal types are being processed, this ensures + // all associations are being processed. + recursiveSynchronizeEntity(entity, synchronizationState, false); } } } @@ -89,7 +92,7 @@ } } - public void synchronizePrincipalsByType(String type) + public synchronized void synchronizePrincipalsByType(String type, boolean recursive) { setSynchronizing(true); try @@ -104,7 +107,7 @@ InternalSynchronizationState synchronizationState = new InternalSynchronizationState(skipEntities); for (Entity entity : entites) { - recursiveSynchronizeEntity(entity, synchronizationState); + recursiveSynchronizeEntity(entity, synchronizationState, recursive); } } finally @@ -113,24 +116,7 @@ } } - private void recursiveSynchronizeEntity(Entity entity, InternalSynchronizationState syncState) - { - JetspeedPrincipal updatedPrincipal = null; - if (entity != null && !syncState.isProcessed(entity)) - { - // mark as processed, to avoid nasty loops - syncState.setProcessed(entity); - // update / create corresponding JetspeedPrincipal first - updatedPrincipal = synchronizePrincipalAttributes(entity); - if (updatedPrincipal != null) - { - // Synchronizing Relations - synchronizePrincipalRelation(updatedPrincipal, entity, syncState); - } - } - } - - public void synchronizeUserPrincipal(String name) + public synchronized void synchronizeUserPrincipal(String name, boolean recursive) { setSynchronizing(true); try @@ -139,7 +125,7 @@ // amounts of data. // TODO: allow processing of required relations towards users. Collection skipEntities = Arrays.asList(new String[] { JetspeedPrincipalType.USER }); - recursiveSynchronizePrincipal(securityEntityManager.getEntity(JetspeedPrincipalType.USER, name), new InternalSynchronizationState(skipEntities)); + recursiveSynchronizeEntity(securityEntityManager.getEntity(JetspeedPrincipalType.USER, name), new InternalSynchronizationState(skipEntities), recursive); } finally { @@ -147,7 +133,7 @@ } } - public JetspeedPrincipal recursiveSynchronizePrincipal(Entity entity, InternalSynchronizationState syncState) + protected JetspeedPrincipal recursiveSynchronizeEntity(Entity entity, InternalSynchronizationState syncState, boolean recursive) { JetspeedPrincipal updatedPrincipal = null; if (entity != null && !syncState.isProcessed(entity)) @@ -159,13 +145,13 @@ if (updatedPrincipal != null) { // Synchronizing Relations - synchronizePrincipalRelation(updatedPrincipal, entity, syncState); + synchronizeEntityRelations(updatedPrincipal, entity, syncState, recursive); } } return updatedPrincipal; } - protected JetspeedPrincipal synchronizePrincipalRelation(JetspeedPrincipal principal, Entity entity, InternalSynchronizationState syncState) + protected JetspeedPrincipal synchronizeEntityRelations(JetspeedPrincipal principal, Entity entity, InternalSynchronizationState syncState, boolean recursive) { if (entityToRelationTypes.values().size() != 0) // loop through all relation types for this entity type @@ -177,132 +163,78 @@ // entity if (relationTypeForThisEntity.getFromEntityType().equals(entity.getType())) { - if (syncState.shouldFollowRelationTo(relationTypeForThisEntity.getToEntityType())) + if (syncState.shouldFollowRelationTo(entity,true,relationTypeForThisEntity.getToEntityType())) { - Collection updatedAssociationToNames = synchronizeAssociations(relationTypeForThisEntity, entity, principal, true, syncState); - synchronizeRemovedAssociations(updatedAssociationToNames, relationTypeForThisEntity.getRelationType(), principal, true); + Collection updatedRelationToIds = synchronizeAddedEntityRelations(relationTypeForThisEntity, entity, principal, true, syncState, recursive); + synchronizeRemovedAssociations(updatedRelationToIds, relationTypeForThisEntity.getRelationType(), principal, true); } } // the entity can represent either side or *both* sides of // the relationship, so synchronize both ways. if (relationTypeForThisEntity.getToEntityType().equals(entity.getType())) { - if (syncState.shouldFollowRelationTo(relationTypeForThisEntity.getFromEntityType())) + if (syncState.shouldFollowRelationTo(entity,false,relationTypeForThisEntity.getFromEntityType())) { - Collection updatedAssociationFromNames = synchronizeAssociations(relationTypeForThisEntity, entity, principal, false, syncState); - synchronizeRemovedAssociations(updatedAssociationFromNames, relationTypeForThisEntity.getRelationType(), principal, false); + Collection updatedRelationFromIds = synchronizeAddedEntityRelations(relationTypeForThisEntity, entity, principal, false, syncState, recursive); + synchronizeRemovedAssociations(updatedRelationFromIds, relationTypeForThisEntity.getRelationType(), principal, false); } } } return principal; } - protected JetspeedPrincipal synchronizePrincipalRelations(JetspeedPrincipal principal, Entity entity, InternalSynchronizationState syncState) - { - if (entityToRelationTypes.values().size() != 0) - // loop through all relation types for this entity type - for (SecurityEntityRelationType relationTypeForThisEntity : entityToRelationTypes.get(entity.getType())) - { - // check at what side of the relationship this entity - // represents (from or to) and check whether - // entities on the other side should be synchronized.Entity - // entity - if (relationTypeForThisEntity.getFromEntityType().equals(entity.getType())) - { - if (syncState.shouldFollowRelationTo(relationTypeForThisEntity.getToEntityType())) - { - Collection updatedAssociationToNames = synchronizeAddedAssociations(relationTypeForThisEntity, entity, principal, true, - syncState); - synchronizeRemovedAssociations(updatedAssociationToNames, relationTypeForThisEntity.getRelationType(), principal, true); - } - } - // the entity can represent either side or *both* sides of - // the relationship, so synchronize both ways. - if (relationTypeForThisEntity.getToEntityType().equals(entity.getType())) - { - if (syncState.shouldFollowRelationTo(relationTypeForThisEntity.getFromEntityType())) - { - Collection updatedAssociationFromNames = synchronizeAddedAssociations(relationTypeForThisEntity, entity, principal, false, - syncState); - synchronizeRemovedAssociations(updatedAssociationFromNames, relationTypeForThisEntity.getRelationType(), principal, false); - } - } - } - return principal; - } - - protected Collection synchronizeAssociations(SecurityEntityRelationType relationTypeForThisEntity, Entity entity, JetspeedPrincipal principal, - boolean entityIsFromEntity, InternalSynchronizationState syncState) - { - Collection externalRelatedEntityIds = null; - Collection relatedEntities = entityIsFromEntity ? securityEntityManager.getRelatedEntitiesFrom(entity, relationTypeForThisEntity) - : securityEntityManager.getRelatedEntitiesTo(entity, relationTypeForThisEntity); - externalRelatedEntityIds = new ArrayList(); - for (Entity relatedEntity : relatedEntities) - { - Entity fromEntity = entityIsFromEntity ? entity : relatedEntity; - Entity toEntity = entityIsFromEntity ? relatedEntity : entity; - if (!syncState.isRelationProcessed(relationTypeForThisEntity, fromEntity, toEntity)) - { - // first flag the relation as processed to - // prevent synchronizing the same relation from - // the other side. - syncState.setRelationProcessed(relationTypeForThisEntity, fromEntity, toEntity, entityIsFromEntity); - // first create/update principal - // JetspeedPrincipal relatedPrincipal = recursiveSynchronizePrincipal(relatedEntity, syncState); - - //TODO change for nested level of group and roles. - JetspeedPrincipal relatedPrincipal = null; - JetspeedPrincipalManager principalManager = principalManagerProvider - .getManager(principalManagerProvider - .getPrincipalType(relatedEntity - .getType())); - if (principalManager != null) - { - relatedPrincipal = principalManager.getPrincipal(relatedEntity.getId()); - } - // .. then update associations to / from it - JetspeedPrincipal fromPrincipal = entityIsFromEntity ? principal : relatedPrincipal; - JetspeedPrincipal toPrincipal = entityIsFromEntity ? relatedPrincipal : principal; - // does association exist in DB ? - if (relatedPrincipal != null && !associationExists(fromPrincipal, toPrincipal, relationTypeForThisEntity.getRelationType())) - { - synchronizeAddedPrincipalAssocation(fromPrincipal, toPrincipal, relationTypeForThisEntity.getRelationType()); - externalRelatedEntityIds.add(relatedPrincipal.getName()); - } - } - } - return externalRelatedEntityIds; - } - - protected Collection synchronizeAddedAssociations(SecurityEntityRelationType relationTypeForThisEntity, Entity entity, JetspeedPrincipal principal, - boolean entityIsFromEntity, InternalSynchronizationState syncState) + /** + * Synchronizes all relations found in the backend store (e.g. LDAP). Returns a collections of all related entity IDs found. This list can be + * used to check whether associations found in the database should be removed, if the associated principal ID is not in this list. + * @param relationTypeForThisEntity the type of relation that should be synchronized + * @param entity the entity for which relations to other entities should be synchronized. + * @param principal the principal that corresponds with entity + * @param entityIsFromEntity the passed entity is the "from" side of a relation. + * @param syncState the internal synchronization state + * @param recursive whether related entities should be recursively synchronized (true) or not (false). + * @return + */ + protected Collection synchronizeAddedEntityRelations(SecurityEntityRelationType relationTypeForThisEntity, Entity entity, JetspeedPrincipal principal, + boolean entityIsFromEntity, InternalSynchronizationState syncState, boolean recursive) { Collection externalRelatedEntityIds = null; Collection relatedEntities = entityIsFromEntity ? securityEntityManager.getRelatedEntitiesFrom(entity, relationTypeForThisEntity) : securityEntityManager.getRelatedEntitiesTo(entity, relationTypeForThisEntity); externalRelatedEntityIds = new ArrayList(); - for (Entity relatedEntity : relatedEntities) - { - Entity fromEntity = entityIsFromEntity ? entity : relatedEntity; - Entity toEntity = entityIsFromEntity ? relatedEntity : entity; - if (!syncState.isRelationProcessed(relationTypeForThisEntity, fromEntity, toEntity)) - { - // first flag the relation as processed to - // prevent synchronizing the same relation from - // the other side. - syncState.setRelationProcessed(relationTypeForThisEntity, fromEntity, toEntity, entityIsFromEntity); - // first create/update principal - JetspeedPrincipal relatedPrincipal = recursiveSynchronizePrincipal(relatedEntity, syncState); - // .. then update associations to / from it - JetspeedPrincipal fromPrincipal = entityIsFromEntity ? principal : relatedPrincipal; - JetspeedPrincipal toPrincipal = entityIsFromEntity ? relatedPrincipal : principal; - // does association exist in DB ? - if (relatedPrincipal != null && !associationExists(fromPrincipal, toPrincipal, relationTypeForThisEntity.getRelationType())) - { - synchronizeAddedPrincipalAssocation(fromPrincipal, toPrincipal, relationTypeForThisEntity.getRelationType()); + if (relatedEntities != null){ + for (Entity relatedEntity : relatedEntities) + { + Entity fromEntity = entityIsFromEntity ? entity : relatedEntity; + Entity toEntity = entityIsFromEntity ? relatedEntity : entity; + if (!syncState.isRelationProcessed(relationTypeForThisEntity, fromEntity, toEntity)) + { + // first flag the relation as processed to + // prevent synchronizing the same relation from + // the other side. + syncState.setRelationProcessed(relationTypeForThisEntity, fromEntity, toEntity, entityIsFromEntity); + // first create/update principal + JetspeedPrincipal relatedPrincipal = null; + if (recursive){ + relatedPrincipal = recursiveSynchronizeEntity(relatedEntity, syncState,recursive); + } else { + // don't recursively synchronize the related entity. Only add an association (if missing) when the related entity was previously synchronized. + JetspeedPrincipalManager principalManager = principalManagerProvider.getManager(principalManagerProvider.getPrincipalType(relatedEntity.getType())); + if (principalManager != null) + { + relatedPrincipal = principalManager.getPrincipal(relatedEntity.getId()); + } + } + // .. then update associations to / from it + JetspeedPrincipal fromPrincipal = entityIsFromEntity ? principal : relatedPrincipal; + JetspeedPrincipal toPrincipal = entityIsFromEntity ? relatedPrincipal : principal; + // does association exist in DB ? + if (relatedPrincipal != null && !associationExists(fromPrincipal, toPrincipal, relationTypeForThisEntity.getRelationType())) + { + synchronizeAddedPrincipalAssocation(fromPrincipal, toPrincipal, relationTypeForThisEntity.getRelationType()); + externalRelatedEntityIds.add(relatedPrincipal.getName()); + } + } - externalRelatedEntityIds.add(relatedPrincipal.getName()); } } return externalRelatedEntityIds; @@ -522,7 +454,7 @@ } } - private class InternalSynchronizationState + protected class InternalSynchronizationState { // entity type to processed entity IDs map Map> processedEntities = new HashMap>(); @@ -544,18 +476,18 @@ this.skipEntities = skipEntities; } - private boolean isProcessed(Entity entity) + protected boolean isProcessed(Entity entity) { Set processedEntitiesByType = processedEntities.get(entity.getType()); return processedEntitiesByType != null && processedEntitiesByType.contains(entity.getId()); } - private boolean shouldFollowRelationTo(String relationType) + protected boolean shouldFollowRelationTo(Entity entity, boolean isFromEntity, String relationType) { return !skipEntities.contains(relationType); } - private void setProcessed(Entity entity) + protected void setProcessed(Entity entity) { Set processedEntitiesByType = processedEntities.get(entity.getType()); if (processedEntitiesByType == null) @@ -565,7 +497,7 @@ processedEntitiesByType.add(entity.getId()); } - private boolean isRelationProcessed(SecurityEntityRelationType relationType, Entity fromEntity, Entity toEntity) + protected boolean isRelationProcessed(SecurityEntityRelationType relationType, Entity fromEntity, Entity toEntity) { Map> e2eMap = processedEntityRelationsFromTo.get(relationType); if (e2eMap != null) @@ -576,7 +508,7 @@ return false; } - private void setRelationProcessed(SecurityEntityRelationType relationType, Entity startEntity, Entity endEntity, boolean startEntityIsFrom) + protected void setRelationProcessed(SecurityEntityRelationType relationType, Entity startEntity, Entity endEntity, boolean startEntityIsFrom) { if (startEntityIsFrom) { @@ -588,7 +520,7 @@ } } - private void setRelationProcessed(SecurityEntityRelationType relationType, Entity fromEntity, Entity toEntity) + protected void setRelationProcessed(SecurityEntityRelationType relationType, Entity fromEntity, Entity toEntity) { Map> e2eMap = processedEntityRelationsFromTo.get(relationType); if (e2eMap == null) Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/OnStartupSecuritySynchronizationBean.java URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/OnStartupSecuritySynchronizationBean.java?rev=750545&r1=750544&r2=750545&view=diff ============================================================================== --- portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/OnStartupSecuritySynchronizationBean.java (original) +++ portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/OnStartupSecuritySynchronizationBean.java Thu Mar 5 18:46:22 2009 @@ -35,18 +35,20 @@ private JetspeedSecuritySynchronizer synchronizer; private boolean synchronizeAllUser; private String synchronizeEntityType; + private boolean recursiveSynchronization; /** * @param synchronizer * @param userManager */ public OnStartupSecuritySynchronizationBean(JetspeedSecuritySynchronizer synchronizer, UserManager userManager, boolean synchronizeAllUser, - String synchronizeEntityType) + String synchronizeEntityType, boolean recursiveSynchronization) { this.synchronizer = synchronizer; this.userManager = userManager; this.synchronizeAllUser = synchronizeAllUser; this.synchronizeEntityType = synchronizeEntityType; + this.recursiveSynchronization=recursiveSynchronization; } public void refresh() @@ -57,7 +59,7 @@ { if (userManager.getUser(userManager.getAnonymousUser()) == null) { - synchronizer.synchronizeUserPrincipal(userManager.getAnonymousUser()); + synchronizer.synchronizeUserPrincipal(userManager.getAnonymousUser(),false); } if (synchronizeAllUser) @@ -68,7 +70,7 @@ { if (StringUtils.isNotEmpty(synchronizeEntityType)) { - synchronizer.synchronizePrincipalsByType(synchronizeEntityType); + synchronizer.synchronizePrincipalsByType(synchronizeEntityType,recursiveSynchronization); } } } Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml?rev=750545&r1=750544&r2=750545&view=diff ============================================================================== --- portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml (original) +++ portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml Thu Mar 5 18:46:22 2009 @@ -57,8 +57,11 @@ + + + Modified: portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/pom.xml URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/pom.xml?rev=750545&r1=750544&r2=750545&view=diff ============================================================================== --- portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/pom.xml (original) +++ portals/jetspeed-2/portal/branches/JETSPEED-2.2-PRE-PLUTO-2-SNAPSHOT/pom.xml Thu Mar 5 18:46:22 2009 @@ -321,7 +321,7 @@ 0.8 1.0-FCS 2.5.2 - 1.2.1 + 1.3.0.RELEASE 2.0.6 2.0-rc2 1.0.2 @@ -623,6 +623,7 @@ spring-ldap org.springframework.ldap ${spring.ldap.version} + all org.springframework --------------------------------------------------------------------- To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org For additional commands, e-mail: jetspeed-dev-help@portals.apache.org