You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by dd...@apache.org on 2009/03/05 20:30:36 UTC

svn commit: r750558 - in /portals/jetspeed-2/portal/trunk: ./ components/jetspeed-security/ components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/ components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ld...

Author: ddam
Date: Thu Mar  5 19:30:36 2009
New Revision: 750558

URL: http://svn.apache.org/viewvc?rev=750558&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/trunk/components/jetspeed-security/pom.xml
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/EntityDAO.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/impl/SpringLDAPEntityDAO.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedSecuritySynchronizer.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/OnStartupSecuritySynchronizationBean.java
    portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/mapping/stubs/StubEntityDAO.java
    portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml
    portals/jetspeed-2/portal/trunk/pom.xml

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/pom.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/pom.xml?rev=750558&r1=750557&r2=750558&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/pom.xml (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/pom.xml Thu Mar  5 19:30:36 2009
@@ -109,6 +109,7 @@
         <dependency>      
             <artifactId>spring-ldap</artifactId>
             <groupId>org.springframework.ldap</groupId>
+            <classifier>all</classifier>
         </dependency>
 
         <dependency>      

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java?rev=750558&r1=750557&r2=750558&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/impl/LdapAuthenticationProvider.java Thu Mar  5 19:30:36 2009
@@ -107,7 +107,7 @@
     {
         if (synchronizer != null)
         {
-            synchronizer.synchronizeUserPrincipal(userName);
+            synchronizer.synchronizeUserPrincipal(userName,false);
         }
         return manager.getUser(userName);
     }

Modified: portals/jetspeed-2/portal/trunk/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/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/EntityDAO.java?rev=750558&r1=750557&r2=750558&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/EntityDAO.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/EntityDAO.java Thu Mar  5 19:30:36 2009
@@ -40,6 +40,14 @@
     Collection<Entity> getEntitiesById(Collection<String> 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<Entity> getEntitiesByInternalId(Collection<String> 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<Entity> 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<Entity> 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/trunk/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/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/impl/SpringLDAPEntityDAO.java?rev=750558&r1=750557&r2=750558&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/impl/SpringLDAPEntityDAO.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/mapping/ldap/dao/impl/SpringLDAPEntityDAO.java Thu Mar  5 19:30:36 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<Entity> resultSet = new ArrayList<Entity>();
         for (Iterator<String> 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<Entity> getEntities(Entity parent, Filter filter)
+    {
+        String filterStr = createSearchFilter(filter);
+        Collection<Entity> results = null;
+        ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+        try
+        {
+            Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
+            String parentId = parent.getInternalId();
+            DistinguishedName parentDN = getRelativeDN(parentId);
+            results = (Collection<Entity>) ldapTemplate.search(parentDN.encode(), filterStr, SearchControls.ONELEVEL_SCOPE, getContextMapper());
+        } finally{
+            Thread.currentThread().setContextClassLoader(currentClassLoader);
+        }
+
+        return results;
+    }
 
     public Collection<Entity> getAllEntities()
     {
@@ -496,4 +537,4 @@
         { configuration.getLdapIdAttribute(), entityId});
     }
     
-}
+}
\ No newline at end of file

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedSecuritySynchronizer.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedSecuritySynchronizer.java?rev=750558&r1=750557&r2=750558&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedSecuritySynchronizer.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/JetspeedSecuritySynchronizer.java Thu Mar  5 19:30:36 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/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java?rev=750558&r1=750557&r2=750558&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/DefaultJetspeedSecuritySynchronizer.java Thu Mar  5 19:30:36 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<String> 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<String> updatedAssociationToNames = synchronizeAssociations(relationTypeForThisEntity, entity, principal, true, syncState);
-                        synchronizeRemovedAssociations(updatedAssociationToNames, relationTypeForThisEntity.getRelationType(), principal, true);
+                        Collection<String> 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<String> updatedAssociationFromNames = synchronizeAssociations(relationTypeForThisEntity, entity, principal, false, syncState);
-                        synchronizeRemovedAssociations(updatedAssociationFromNames, relationTypeForThisEntity.getRelationType(), principal, false);
+                        Collection<String> 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<String> 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<String> updatedAssociationFromNames = synchronizeAddedAssociations(relationTypeForThisEntity, entity, principal, false,
-                                                                                                      syncState);
-                        synchronizeRemovedAssociations(updatedAssociationFromNames, relationTypeForThisEntity.getRelationType(), principal, false);
-                    }
-                }
-            }
-        return principal;
-    }
-
-    protected Collection<String> synchronizeAssociations(SecurityEntityRelationType relationTypeForThisEntity, Entity entity, JetspeedPrincipal principal,
-                                                         boolean entityIsFromEntity, InternalSynchronizationState syncState)
-    {
-        Collection<String> externalRelatedEntityIds = null;
-        Collection<Entity> relatedEntities = entityIsFromEntity ? securityEntityManager.getRelatedEntitiesFrom(entity, relationTypeForThisEntity)
-                                                               : securityEntityManager.getRelatedEntitiesTo(entity, relationTypeForThisEntity);
-        externalRelatedEntityIds = new ArrayList<String>();
-        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<String> 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<String> synchronizeAddedEntityRelations(SecurityEntityRelationType relationTypeForThisEntity, Entity entity, JetspeedPrincipal principal,
+                                                              boolean entityIsFromEntity, InternalSynchronizationState syncState, boolean recursive)
     {
         Collection<String> externalRelatedEntityIds = null;
         Collection<Entity> relatedEntities = entityIsFromEntity ? securityEntityManager.getRelatedEntitiesFrom(entity, relationTypeForThisEntity)
                                                                : securityEntityManager.getRelatedEntitiesTo(entity, relationTypeForThisEntity);
         externalRelatedEntityIds = new ArrayList<String>();
-        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<String, Set<String>> processedEntities = new HashMap<String, Set<String>>();
@@ -544,18 +476,18 @@
             this.skipEntities = skipEntities;
         }
 
-        private boolean isProcessed(Entity entity)
+        protected boolean isProcessed(Entity entity)
         {
             Set<String> 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<String> 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<String, Collection<String>> 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<String, Collection<String>> e2eMap = processedEntityRelationsFromTo.get(relationType);
             if (e2eMap == null)

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/OnStartupSecuritySynchronizationBean.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/OnStartupSecuritySynchronizationBean.java?rev=750558&r1=750557&r2=750558&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/OnStartupSecuritySynchronizationBean.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/main/java/org/apache/jetspeed/security/spi/impl/OnStartupSecuritySynchronizationBean.java Thu Mar  5 19:30:36 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);
                     }
                 }
             }
@@ -81,4 +83,4 @@
             }
         }
     }
-}
+}
\ No newline at end of file

Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/mapping/stubs/StubEntityDAO.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/mapping/stubs/StubEntityDAO.java?rev=750558&r1=750557&r2=750558&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/mapping/stubs/StubEntityDAO.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-security/src/test/java/org/apache/jetspeed/security/mapping/stubs/StubEntityDAO.java Thu Mar  5 19:30:36 2009
@@ -33,6 +33,24 @@
 
     private Map<String,Entity> entities = new HashMap<String,Entity>();
     
+    public Collection<Entity> getEntities(Entity parentEntity, Filter filter)
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Entity getEntityByInternalId(String internalId)
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Entity getParentEntity(Entity childEntity)
+    {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
     public void addEntity(Entity entity)
     {
         entities.put(entity.getId(),entity);
@@ -111,4 +129,4 @@
         
     }
 
-}
+}
\ No newline at end of file

Modified: portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml?rev=750558&r1=750557&r2=750558&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml (original)
+++ portals/jetspeed-2/portal/trunk/jetspeed-portal-resources/src/main/resources/assembly/security-ldap.xml Thu Mar  5 19:30:36 2009
@@ -57,8 +57,11 @@
       <bean class="org.apache.jetspeed.security.spi.impl.OnStartupSecuritySynchronizationBean">
         <constructor-arg index="0" ref="org.apache.jetspeed.security.spi.JetspeedSecuritySynchronizer" />
         <constructor-arg index="1" ref="org.apache.jetspeed.security.UserManager" />
+        <!-- synchronized all users ? -->
         <constructor-arg index="2" type="boolean" value="false" />
         <constructor-arg index="3" value="group" />
+        <!-- recursive synchronization -->
+        <constructor-arg index="4" type="boolean" value="false" />
       </bean>
     </constructor-arg>
   </bean>

Modified: portals/jetspeed-2/portal/trunk/pom.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/pom.xml?rev=750558&r1=750557&r2=750558&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/pom.xml (original)
+++ portals/jetspeed-2/portal/trunk/pom.xml Thu Mar  5 19:30:36 2009
@@ -323,7 +323,7 @@
     <rome.version>0.8</rome.version>
     <saxpath.version>1.0-FCS</saxpath.version>
     <spring.version>2.5.2</spring.version>
-    <spring.ldap.version>1.2.1</spring.ldap.version>
+    <spring.ldap.version>1.3.0.RELEASE</spring.ldap.version>
     <spring.portlet.version>2.0.6</spring.portlet.version>
     <spring.modules.version>2.0-rc2</spring.modules.version>    
     <taglibs-random.version>1.0.2</taglibs-random.version>
@@ -635,6 +635,7 @@
         <artifactId>spring-ldap</artifactId>
         <groupId>org.springframework.ldap</groupId>
         <version>${spring.ldap.version}</version>
+        <classifier>all</classifier>
       </dependency>
       <dependency>
         <groupId>org.springframework</groupId>



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org