]> source.dussan.org Git - archiva.git/commitdiff
map a ldap group to n roles
authorOlivier Lamy <olamy@apache.org>
Wed, 16 Jan 2013 14:48:58 +0000 (14:48 +0000)
committerOlivier Lamy <olamy@apache.org>
Wed, 16 Jan 2013 14:48:58 +0000 (14:48 +0000)
git-svn-id: https://svn.apache.org/repos/asf/archiva/redback/redback-core/trunk@1433962 13f79535-47bb-0310-9956-ffa450edef68

redback-common/redback-common-ldap/src/main/java/org/apache/archiva/redback/common/ldap/role/DefaultLdapRoleMapper.java
redback-common/redback-common-ldap/src/main/java/org/apache/archiva/redback/common/ldap/role/LdapRoleMapper.java
redback-configuration/src/main/java/org/apache/archiva/redback/configuration/UserConfigurationKeys.java
redback-rbac/redback-rbac-providers/redback-rbac-ldap/src/main/java/org/apache/archiva/redback/rbac/ldap/LdapRbacManager.java

index bfa828ef0e43d9cd9d6ab0c0a407fd6276a3926b..6520542c87c1f4e60eaeda398b2eea3e7934700f 100644 (file)
@@ -18,9 +18,9 @@ package org.apache.archiva.redback.common.ldap.role;
  * under the License.
  */
 
-import com.google.common.collect.HashBiMap;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
 import org.apache.archiva.redback.common.ldap.MappingException;
-import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
 import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
 import org.apache.archiva.redback.common.ldap.connection.LdapException;
 import org.apache.archiva.redback.configuration.UserConfiguration;
@@ -44,12 +44,12 @@ import javax.naming.directory.ModificationItem;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * @author Olivier Lamy
@@ -79,6 +79,10 @@ public class DefaultLdapRoleMapper
 
     private String baseDn;
 
+    private boolean writableLdap = false;
+
+    private boolean useDefaultRoleName = false;
+
     @PostConstruct
     public void initialize()
     {
@@ -92,6 +96,11 @@ public class DefaultLdapRoleMapper
         {
             this.groupsDn = this.baseDn;
         }
+
+        this.writableLdap = userConf.getBoolean( UserConfigurationKeys.LDAP_WRITABLE, this.writableLdap );
+
+        this.useDefaultRoleName =
+            userConf.getBoolean( UserConfigurationKeys.LDAP_GROUPS_USE_ROLENAME, this.useDefaultRoleName );
     }
 
     public String getLdapGroup( String role )
@@ -164,6 +173,53 @@ public class DefaultLdapRoleMapper
         }
     }
 
+    public boolean hasRole( DirContext context, String roleName )
+        throws MappingException
+    {
+        String groupName = findGroupName( roleName );
+
+        if ( groupName == null )
+        {
+            if ( this.useDefaultRoleName )
+            {
+                groupName = roleName;
+            }
+            else
+            {
+                log.warn( "skip group creation as no mapping fro roleName:'{}'", roleName );
+                return false;
+            }
+        }
+        NamingEnumeration<SearchResult> namingEnumeration = null;
+        try
+        {
+
+            SearchControls searchControls = new SearchControls();
+
+            searchControls.setDerefLinkFlag( true );
+            searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+
+            String filter = "objectClass=" + getLdapGroupClass();
+
+            namingEnumeration = context.search( "cn=" + groupName + "," + getGroupsDn(), filter, searchControls );
+
+            return namingEnumeration.hasMore();
+        }
+        catch ( LdapException e )
+        {
+            throw new MappingException( e.getMessage(), e );
+        }
+        catch ( NamingException e )
+        {
+            throw new MappingException( e.getMessage(), e );
+        }
+
+        finally
+        {
+            close( namingEnumeration );
+        }
+    }
+
     public List<String> getAllRoles( DirContext context )
         throws MappingException
     {
@@ -174,20 +230,23 @@ public class DefaultLdapRoleMapper
             return Collections.emptyList();
         }
 
-        List<String> roles = new ArrayList<String>( groups.size() );
+        Set<String> roles = new HashSet<String>( groups.size() );
 
-        Map<String, String> mapping = getLdapGroupMappings();
+        Map<String, Collection<String>> mapping = getLdapGroupMappings();
 
         for ( String group : groups )
         {
-            String role = mapping.get( group );
-            if ( role != null )
+            Collection<String> rolesPerGroup = mapping.get( group );
+            if ( rolesPerGroup != null )
             {
-                roles.add( role );
+                for ( String role : rolesPerGroup )
+                {
+                    roles.add( role );
+                }
             }
         }
 
-        return roles;
+        return new ArrayList<String>( roles );
     }
 
     public List<String> getGroupsMember( String group, DirContext context )
@@ -330,20 +389,23 @@ public class DefaultLdapRoleMapper
     {
         List<String> groups = getGroups( username, context );
 
-        Map<String, String> rolesMapping = getLdapGroupMappings();
+        Map<String, Collection<String>> rolesMapping = getLdapGroupMappings();
 
-        List<String> roles = new ArrayList<String>( groups.size() );
+        Set<String> roles = new HashSet<String>( groups.size() );
 
         for ( String group : groups )
         {
-            String role = rolesMapping.get( group );
-            if ( role != null )
+            Collection<String> rolesPerGroup = rolesMapping.get( group );
+            if ( rolesPerGroup != null )
             {
-                roles.add( role );
+                for ( String role : rolesPerGroup )
+                {
+                    roles.add( role );
+                }
             }
         }
 
-        return roles;
+        return new ArrayList<String>( roles );
     }
 
     private void close( NamingEnumeration namingEnumeration )
@@ -381,15 +443,15 @@ public class DefaultLdapRoleMapper
         log.warn( "removeLdapMapping not implemented" );
     }
 
-    public void setLdapGroupMappings( Map<String, String> mappings )
+    public void setLdapGroupMappings( Map<String, Collection<String>> mappings )
         throws MappingException
     {
         log.warn( "setLdapGroupMappings not implemented" );
     }
 
-    public Map<String, String> getLdapGroupMappings()
+    public Map<String, Collection<String>> getLdapGroupMappings()
     {
-        Map<String, String> map = new HashMap<String, String>();
+        Multimap<String, String> map = ArrayListMultimap.create();
 
         Collection<String> keys = userConf.getKeys();
 
@@ -397,23 +459,36 @@ public class DefaultLdapRoleMapper
         {
             if ( key.startsWith( UserConfigurationKeys.LDAP_GROUPS_ROLE_START_KEY ) )
             {
-                map.put( StringUtils.substringAfter( key, UserConfigurationKeys.LDAP_GROUPS_ROLE_START_KEY ),
-                         userConf.getString( key ) );
+                String val = userConf.getString( key );
+                String[] roles = StringUtils.split( val, ',' );
+                for ( String role : roles )
+                {
+                    map.put( StringUtils.substringAfter( key, UserConfigurationKeys.LDAP_GROUPS_ROLE_START_KEY ),
+                             role );
+                }
             }
         }
 
-        return map;
+        return map.asMap();
     }
 
     public boolean saveRole( String roleName, DirContext context )
         throws MappingException
     {
 
-        String groupName = HashBiMap.create( getLdapGroupMappings() ).inverse().get( roleName );
+        String groupName = findGroupName( roleName );
+
         if ( groupName == null )
         {
-            log.warn( "skip group creation as no mapping fro roleName:'{}'", roleName );
-            return false;
+            if ( this.useDefaultRoleName )
+            {
+                groupName = roleName;
+            }
+            else
+            {
+                log.warn( "skip group creation as no mapping fro roleName:'{}'", roleName );
+                return false;
+            }
         }
 
         List<String> allGroups = getAllGroups( context );
@@ -461,12 +536,12 @@ public class DefaultLdapRoleMapper
         throws MappingException
     {
 
-        String groupName = HashBiMap.create( getLdapGroupMappings() ).inverse().get( roleName );
+        String groupName = findGroupName( roleName );
 
         if ( groupName == null )
         {
             log.warn( "no group found for role '{}", roleName );
-            return false;
+            groupName = roleName;
         }
 
         NamingEnumeration<SearchResult> namingEnumeration = null;
@@ -531,7 +606,7 @@ public class DefaultLdapRoleMapper
     public boolean removeUserRole( String roleName, String username, DirContext context )
         throws MappingException
     {
-        String groupName = HashBiMap.create( getLdapGroupMappings() ).inverse().get( roleName );
+        String groupName = findGroupName( roleName );
 
         if ( groupName == null )
         {
@@ -627,7 +702,7 @@ public class DefaultLdapRoleMapper
         throws MappingException
     {
 
-        String groupName = HashBiMap.create( getLdapGroupMappings() ).inverse().get( roleName );
+        String groupName = findGroupName( roleName );
 
         try
         {
@@ -684,4 +759,22 @@ public class DefaultLdapRoleMapper
     {
         this.baseDn = baseDn;
     }
+
+    //-------------------
+    // utils methods
+    //-------------------
+
+    protected String findGroupName( String role )
+    {
+        Map<String, Collection<String>> mapping = getLdapGroupMappings();
+
+        for ( Map.Entry<String, Collection<String>> entry : mapping.entrySet() )
+        {
+            if ( entry.getValue().contains( role ) )
+            {
+                return entry.getKey();
+            }
+        }
+        return null;
+    }
 }
index 56d5e3be6a66296bd60da7a6f6b9b3469c1d61fa..a801b7d9acd55ca1b0b7b1b770c08ca79af9a350 100644 (file)
@@ -21,6 +21,7 @@ package org.apache.archiva.redback.common.ldap.role;
 import org.apache.archiva.redback.common.ldap.MappingException;
 
 import javax.naming.directory.DirContext;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -60,6 +61,9 @@ public interface LdapRoleMapper
     List<String> getAllRoles( DirContext context )
         throws MappingException;
 
+    boolean hasRole( DirContext context, String role )
+        throws MappingException;
+
 
     /**
      * @return the base dn which contains all ldap groups
@@ -103,12 +107,12 @@ public interface LdapRoleMapper
         throws MappingException;
 
     /**
-     * @return Map of corresponding LDAP group (key) and Redback role (value)
+     * @return Map of corresponding LDAP group (key) and Redback roles (value)
      */
-    Map<String, String> getLdapGroupMappings()
+    Map<String, Collection<String>> getLdapGroupMappings()
         throws MappingException;
 
-    void setLdapGroupMappings( Map<String, String> mappings )
+    void setLdapGroupMappings( Map<String, Collection<String>> mappings )
         throws MappingException;
 
     /**
index b22204121f8469e7045150996b69bda00745c924..2bf1dbee7389f8dbd2b895f9c8f977fa91593b13 100644 (file)
@@ -82,6 +82,8 @@ public interface UserConfigurationKeys
 
     String LDAP_GROUPS_ROLE_START_KEY = "ldap.config.groups.role.";
 
+    String LDAP_GROUPS_USE_ROLENAME  = "ldap.config.groups.use.rolename";
+
     String LDAP_WRITABLE = "ldap.config.writable";
 
     String APPLICATION_URL = "application.url";
index b46bd32e46e0c18a864debb95d5510e60f5a8d1b..91a3027acf4e3cbbe03ca2b65f45e0d8bb711ec5 100644 (file)
@@ -61,6 +61,7 @@ import javax.naming.directory.DirContext;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -195,16 +196,19 @@ public class LdapRbacManager
     {
         try
         {
-            Collection<String> roleNames = ldapRoleMapper.getLdapGroupMappings().values();
+            Collection<Collection<String>> roleNames = ldapRoleMapper.getLdapGroupMappings().values();
 
-            List<Role> roles = new ArrayList<Role>();
+            Set<Role> roles = new HashSet<Role>();
 
-            for ( String name : roleNames )
+            for ( Collection<String> names : roleNames )
             {
-                roles.add( new RoleImpl( name ) );
+                for ( String name : names )
+                {
+                    roles.add( new RoleImpl( name ) );
+                }
             }
 
-            return roles;
+            return new ArrayList<Role>( roles );
         }
         catch ( MappingException e )
         {
@@ -340,16 +344,19 @@ public class LdapRbacManager
         }
 
         List<Role> roles = new ArrayList<Role>( groups.size() );
-        Map<String, String> mappedGroups = ldapRoleMapper.getLdapGroupMappings();
+        Map<String, Collection<String>> mappedGroups = ldapRoleMapper.getLdapGroupMappings();
         for ( String group : groups )
         {
-            String roleName = mappedGroups.get( group );
-            if ( roleName != null )
+            Collection<String> roleNames = mappedGroups.get( group );
+            if ( roleNames != null )
             {
-                Role role = getRole( roleName );
-                if ( role != null )
+                for ( String roleName : roleNames )
                 {
-                    roles.add( role );
+                    Role role = getRole( roleName );
+                    if ( role != null )
+                    {
+                        roles.add( role );
+                    }
                 }
             }
         }
@@ -471,7 +478,7 @@ public class LdapRbacManager
         {
             ldapConnection = ldapConnectionFactory.getConnection();
             context = ldapConnection.getDirContext();
-            if ( !ldapRoleMapper.getAllRoles( context ).contains( roleName ) )
+            if ( !ldapRoleMapper.hasRole( context, roleName ) )
             {
                 return null;
             }
@@ -484,7 +491,9 @@ public class LdapRbacManager
         {
             throw new RbacManagerException( e.getMessage(), e );
         }
-        return this.rbacImpl.getRole( roleName );
+        Role role = this.rbacImpl.getRole( roleName );
+        return ( role == null ) ? new RoleImpl( roleName ) : role;
+
     }
 
     public Map<String, Role> getRoles( Collection<String> roleNames )