summaryrefslogtreecommitdiffstats
path: root/redback-authorization
diff options
context:
space:
mode:
authorOlivier Lamy <olamy@apache.org>2013-01-08 22:46:30 +0000
committerOlivier Lamy <olamy@apache.org>2013-01-08 22:46:30 +0000
commit066e3560454adad19c637bd9f535db5e4ab3a923 (patch)
tree9ad28aacfc8a60def163738ae9992815ddef5e76 /redback-authorization
parent6af58add56902be8da2ee025e971510b33c5b762 (diff)
downloadarchiva-066e3560454adad19c637bd9f535db5e4ab3a923.tar.gz
archiva-066e3560454adad19c637bd9f535db5e4ab3a923.zip
[MRM-1736] map roles to ldap groups
git-svn-id: https://svn.apache.org/repos/asf/archiva/redback/redback-core/trunk@1430601 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'redback-authorization')
-rw-r--r--redback-authorization/redback-authorization-providers/redback-authorization-ldap/pom.xml12
-rw-r--r--redback-authorization/redback-authorization-providers/redback-authorization-ldap/src/main/java/org/apache/archiva/redback/authorization/ldap/LdapAuthorizer.java261
2 files changed, 272 insertions, 1 deletions
diff --git a/redback-authorization/redback-authorization-providers/redback-authorization-ldap/pom.xml b/redback-authorization/redback-authorization-providers/redback-authorization-ldap/pom.xml
index ad56691fa..747e94c1c 100644
--- a/redback-authorization/redback-authorization-providers/redback-authorization-ldap/pom.xml
+++ b/redback-authorization/redback-authorization-providers/redback-authorization-ldap/pom.xml
@@ -37,6 +37,10 @@
<artifactId>redback-authorization-api</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.archiva.redback</groupId>
+ <artifactId>redback-rbac-model</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
@@ -62,7 +66,13 @@
</Export-Package>
<Import-Package>
org.apache.archiva.redback.authorization;version=${project.version},
- org.springframework.stereotype;version="[3,4)"
+ org.springframework.stereotype;version="[3,4)",
+ javax.inject,
+ org.apache.archiva.redback.common.ldap,
+ org.apache.archiva.redback.common.ldap.role,
+ org.apache.archiva.redback.rbac,
+ org.apache.commons.lang,
+ org.slf4j
</Import-Package>
</instructions>
</configuration>
diff --git a/redback-authorization/redback-authorization-providers/redback-authorization-ldap/src/main/java/org/apache/archiva/redback/authorization/ldap/LdapAuthorizer.java b/redback-authorization/redback-authorization-providers/redback-authorization-ldap/src/main/java/org/apache/archiva/redback/authorization/ldap/LdapAuthorizer.java
index f7191a853..22ecb5765 100644
--- a/redback-authorization/redback-authorization-providers/redback-authorization-ldap/src/main/java/org/apache/archiva/redback/authorization/ldap/LdapAuthorizer.java
+++ b/redback-authorization/redback-authorization-providers/redback-authorization-ldap/src/main/java/org/apache/archiva/redback/authorization/ldap/LdapAuthorizer.java
@@ -22,8 +22,33 @@ import org.apache.archiva.redback.authorization.AuthorizationDataSource;
import org.apache.archiva.redback.authorization.AuthorizationException;
import org.apache.archiva.redback.authorization.AuthorizationResult;
import org.apache.archiva.redback.authorization.Authorizer;
+import org.apache.archiva.redback.common.ldap.MappingException;
+import org.apache.archiva.redback.common.ldap.role.LdapRoleMapper;
+import org.apache.archiva.redback.rbac.Permission;
+import org.apache.archiva.redback.rbac.RBACManager;
+import org.apache.archiva.redback.rbac.RbacManagerException;
+import org.apache.archiva.redback.rbac.RbacObjectNotFoundException;
+import org.apache.archiva.redback.rbac.Resource;
+import org.apache.archiva.redback.rbac.Role;
+import org.apache.archiva.redback.rbac.UserAssignment;
+import org.apache.archiva.redback.users.UserManagerException;
+import org.apache.archiva.redback.users.UserNotFoundException;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
/**
* @author Olivier Lamy
* @since 2.1
@@ -32,6 +57,17 @@ import org.springframework.stereotype.Service;
public class LdapAuthorizer
implements Authorizer
{
+
+ private Logger log = LoggerFactory.getLogger( getClass() );
+
+ @Inject
+ @Named( value = "rbacManager#cached" )
+ private RBACManager rbacManager;
+
+ @Inject
+ private LdapRoleMapper ldapRoleMapper;
+
+
public String getId()
{
return "ldap";
@@ -40,7 +76,232 @@ public class LdapAuthorizer
public AuthorizationResult isAuthorized( AuthorizationDataSource source )
throws AuthorizationException
{
+
+ String userName = StringUtils.isEmpty( source.getPrincipal() ) ? "guest" : source.getPrincipal();
+ String operation = source.getPermission();
+ String resource = source.getResource();
+ try
+ {
+ List<String> ldapGroups = ldapRoleMapper.getGroups( userName );
+
+ List<String> roles = mapLdapGroups( ldapGroups );
+
+ Map<String, List<Permission>> permissionMap = getAssignedPermissionMap( roles );
+
+ if ( permissionMap.keySet().contains( operation ) )
+ {
+ for ( Permission permission : permissionMap.get( operation ) )
+ {
+
+ log.debug( "checking permission {} for operation {} resource {}",
+ ( permission != null ? permission.getName() : "null" ), operation, resource );
+
+ if ( evaluate( permission, operation, resource, userName ) )
+ {
+ return new AuthorizationResult( true, permission, null );
+ }
+ }
+
+ log.debug( "no permission found for operation {} resource {}", operation, resource );
+ }
+ else
+ {
+ log.debug( "permission map does not contain operation: {}", operation );
+ }
+
+ }
+ catch ( MappingException e )
+ {
+ log.info( "skip MappingException trying to find LDAP roles for user: '{}", userName );
+ }
+ catch ( RbacManagerException e )
+ {
+ log.info( "skip RbacManagerException trying to find LDAP roles for user: '{}", userName );
+ }
return null;
+
+ }
+
+ protected List<String> mapLdapGroups( List<String> groups )
+ throws MappingException
+ {
+ List<String> roles = new ArrayList<String>();
+
+ Map<String, String> mapping = ldapRoleMapper.getLdapGroupMappings();
+
+ for ( String group : groups )
+ {
+ String role = mapping.get( group );
+ if ( role != null )
+ {
+ roles.add( role );
+ }
+ }
+
+ return roles;
+ }
+
+ public Map<String, List<Permission>> getAssignedPermissionMap( List<String> roles )
+ throws RbacObjectNotFoundException, RbacManagerException
+ {
+ return getPermissionMapByOperation( getAssignedPermissions( roles ) );
+ }
+
+ public Set<Permission> getAssignedPermissions( List<String> roles )
+ throws RbacObjectNotFoundException, RbacManagerException
+ {
+
+ Set<Permission> permissionSet = new HashSet<Permission>();
+
+ boolean childRoleNamesUpdated = false;
+
+ Iterator<String> it = roles.iterator();
+ while ( it.hasNext() )
+ {
+ String roleName = it.next();
+ try
+ {
+ Role role = rbacManager.getRole( roleName );
+ gatherUniquePermissions( role, permissionSet );
+ }
+ catch ( RbacObjectNotFoundException e )
+ {
+ // Found a bad role name. remove it!
+ it.remove();
+ childRoleNamesUpdated = true;
+ }
+ }
+
+ return permissionSet;
+ }
+
+ private void gatherUniquePermissions( Role role, Collection<Permission> coll )
+ throws RbacManagerException
+ {
+ if ( role.getPermissions() != null )
+ {
+ for ( Permission permission : role.getPermissions() )
+ {
+ if ( !coll.contains( permission ) )
+ {
+ coll.add( permission );
+ }
+ }
+ }
+
+ if ( role.hasChildRoles() )
+ {
+ Map<String, Role> childRoles = getChildRoles( role );
+ Iterator<Role> it = childRoles.values().iterator();
+ while ( it.hasNext() )
+ {
+ Role child = it.next();
+ gatherUniquePermissions( child, coll );
+ }
+ }
+ }
+
+ public Map<String, Role> getChildRoles( Role role )
+ throws RbacManagerException
+ {
+ Map<String, Role> childRoles = new HashMap<String, Role>();
+
+ boolean childRoleNamesUpdated = false;
+
+ Iterator<String> it = role.getChildRoleNames().listIterator();
+ while ( it.hasNext() )
+ {
+ String roleName = it.next();
+ try
+ {
+ Role child = rbacManager.getRole( roleName );
+ childRoles.put( child.getName(), child );
+ }
+ catch ( RbacObjectNotFoundException e )
+ {
+ // Found a bad roleName! - remove it.
+ it.remove();
+ childRoleNamesUpdated = true;
+ }
+ }
+
+ return childRoles;
+ }
+
+
+ private Map<String, List<Permission>> getPermissionMapByOperation( Collection<Permission> permissions )
+ {
+ Map<String, List<Permission>> userPermMap = new HashMap<String, List<Permission>>();
+
+ for ( Permission permission : permissions )
+ {
+ List<Permission> permList = userPermMap.get( permission.getOperation().getName() );
+
+ if ( permList != null )
+ {
+ permList.add( permission );
+ }
+ else
+ {
+ List<Permission> newPermList = new ArrayList<Permission>( permissions.size() );
+ newPermList.add( permission );
+ userPermMap.put( permission.getOperation().getName(), newPermList );
+ }
+ }
+
+ return userPermMap;
+ }
+
+ public boolean evaluate( Permission permission, String operation, String resource, String principal )
+ {
+ String permissionResource = permission.getResource().getIdentifier();
+
+ // expression evaluation checking
+ /*if ( permissionResource.startsWith( "${" ) )
+ {
+ String tempStr = permissionResource.substring( 2, permissionResource.indexOf( '}' ) );
+
+ if ( "username".equals( tempStr ) )
+ {
+ try
+ {
+ permissionResource = userManager.findUser( principal ).getUsername();
+ }
+ catch ( UserNotFoundException e )
+ {
+ throw new PermissionEvaluationException( "unable to locate user to retrieve username", e );
+ }
+ catch ( UserManagerException e )
+ {
+ throw new PermissionEvaluationException( "trouble finding user: " + e.getMessage(), e );
+ }
+ }
+ }*/
+
+ // check if this permission applies to the operation at all
+ if ( permission.getOperation().getName().equals( operation ) )
+ {
+ // check if it is a global resource, if it is then since the operations match we return true
+ if ( Resource.GLOBAL.equals( permission.getResource().getIdentifier() ) )
+ {
+ return true;
+ }
+
+ // if we are not checking a specific resource, the operation is enough
+ if ( resource == null )
+ {
+ return true;
+ }
+
+ // check if the resource identifier of the permission matches the resource we are checking against
+ // if it does then return true
+ if ( permissionResource.equals( resource ) )
+ {
+ return true;
+ }
+ }
+
+ return false;
}
public boolean isFinalImplementation()