String nameAttribute = getUserFullNameAttribute();
String passwordAttribute = getPasswordAttribute();
- String userId = ( LdapUtils.getAttributeValue( attributes, userIdAttribute, "username" ) );
+ String userId = LdapUtils.getAttributeValue( attributes, userIdAttribute, "username" );
LdapUser user = new LdapUser( userId );
user.setOriginalAttributes( attributes );
String LDAP_BINDDN = "ldap.config.bind.dn";
+ String LDAP_GROUPS_CLASS = "ldap.config.groups.class";
+
+ String LDAP_GROUPS_BASEDN = "ldap.config.groups.base.dn";
+
+ String LDAP_GROUPS_ROLE_START_KEY = "ldap.config.groups.role.";
+
String APPLICATION_URL = "application.url";
String EMAIL_URL_PATH = "email.url.path";
<module>redback-rbac-jdo</module>
<module>redback-rbac-memory</module>
<module>redback-rbac-cached</module>
- <!--module>redback-rbac-ldap</module-->
+ <module>redback-rbac-ldap</module>
</modules>
</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.archiva.redback</groupId>
+ <artifactId>redback-rbac-providers</artifactId>
+ <version>2.1-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>redback-rbac-ldap</artifactId>
+ <packaging>bundle</packaging>
+ <name>Redback :: RBAC Provider :: Ldap</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.archiva.redback</groupId>
+ <artifactId>redback-system</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva.redback</groupId>
+ <artifactId>redback-authorization-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva.redback</groupId>
+ <artifactId>redback-rbac-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva.redback</groupId>
+ <artifactId>redback-common-ldap</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva.redback.components.cache</groupId>
+ <artifactId>spring-cache-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva.redback.components.cache</groupId>
+ <artifactId>spring-cache-ehcache</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.ehcache</groupId>
+ <artifactId>ehcache-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context-support</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>javax.annotation</groupId>
+ <artifactId>jsr250-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva.redback</groupId>
+ <artifactId>redback-users-ldap</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.archiva.redback</groupId>
+ <artifactId>redback-rbac-tests</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easytesting</groupId>
+ <artifactId>fest-assert</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
--- /dev/null
+package org.apache.archiva.redback.rbac.ldap;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+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;
+import org.apache.archiva.redback.configuration.UserConfigurationKeys;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.SearchControls;
+import javax.naming.directory.SearchResult;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Olivier Lamy
+ * @since 2.1
+ */
+@Service( "ldapRoleMapper#default" )
+public class DefaultLdapRoleMapper
+ implements LdapRoleMapper
+{
+
+ private Logger log = LoggerFactory.getLogger( getClass() );
+
+ @Inject
+ private LdapConnectionFactory ldapConnectionFactory;
+
+ @Inject
+ @Named( value = "userConfiguration#default" )
+ private UserConfiguration userConf;
+
+ //---------------------------
+ // fields
+ //---------------------------
+
+ private String ldapGroupClass = "groupOfUniqueNames";
+
+ private String groupsDn;
+
+ @PostConstruct
+ public void initialize()
+ {
+ this.ldapGroupClass = userConf.getString( UserConfigurationKeys.LDAP_GROUPS_CLASS, this.ldapGroupClass );
+
+ this.groupsDn = userConf.getString( UserConfigurationKeys.LDAP_GROUPS_BASEDN, this.groupsDn );
+ }
+
+ public String getLdapGroup( String role )
+ {
+ return userConf.getString( UserConfigurationKeys.LDAP_GROUPS_ROLE_START_KEY + role );
+ }
+
+ public List<String> getAllGroups()
+ throws MappingException
+ {
+ // TODO caching
+ LdapConnection ldapConnection = null;
+
+ NamingEnumeration<SearchResult> namingEnumeration = null;
+ try
+ {
+ ldapConnection = ldapConnectionFactory.getConnection();
+
+ DirContext context = ldapConnection.getDirContext();
+
+ SearchControls searchControls = new SearchControls();
+
+ searchControls.setDerefLinkFlag( true );
+ searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+
+ String filter = "objectClass=" + getLdapGroupClass();
+
+ namingEnumeration = context.search( getGroupsDn(), filter, searchControls );
+
+ List<String> allGroups = new ArrayList<String>();
+
+ while ( namingEnumeration.hasMore() )
+ {
+ SearchResult searchResult = namingEnumeration.next();
+
+ String groupName = searchResult.getName();
+ // cn=blabla we only want bla bla
+ groupName = StringUtils.substringAfter( groupName, "=" );
+
+ log.debug( "found groupName: '{}", groupName );
+
+ allGroups.add( groupName );
+
+ }
+
+ return allGroups;
+ }
+ catch ( LdapException e )
+ {
+ throw new MappingException( e.getMessage(), e );
+ }
+ catch ( NamingException e )
+ {
+ throw new MappingException( e.getMessage(), e );
+ }
+
+ finally
+ {
+ if ( ldapConnection != null )
+ {
+ ldapConnection.close();
+ }
+ if ( namingEnumeration != null )
+ {
+ try
+ {
+ namingEnumeration.close();
+ }
+ catch ( NamingException e )
+ {
+ log.warn( "failed to close search results", e );
+ }
+ }
+ }
+ }
+
+ public List<String> getGroupsMember( String group )
+ throws MappingException
+ {
+ // TODO caching
+ LdapConnection ldapConnection = null;
+
+ NamingEnumeration<SearchResult> namingEnumeration = null;
+ try
+ {
+ ldapConnection = ldapConnectionFactory.getConnection();
+
+ DirContext context = ldapConnection.getDirContext();
+
+ SearchControls searchControls = new SearchControls();
+
+ searchControls.setDerefLinkFlag( true );
+ searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
+
+ String filter = "objectClass=" + getLdapGroupClass();
+
+ namingEnumeration = context.search( "cn=" + group + "," + getGroupsDn(), filter, searchControls );
+
+ List<String> allMembers = new ArrayList<String>();
+
+ while ( namingEnumeration.hasMore() )
+ {
+ SearchResult searchResult = namingEnumeration.next();
+
+ Attribute uniqueMemberAttr = searchResult.getAttributes().get( "uniquemember" );
+
+ if ( uniqueMemberAttr != null )
+ {
+ NamingEnumeration<String> allMembersEnum = (NamingEnumeration<String>) uniqueMemberAttr.getAll();
+ while ( allMembersEnum.hasMore() )
+ {
+ String userName = allMembersEnum.next();
+ // uid=blabla we only want bla bla
+ userName = StringUtils.substringAfter( userName, "=" );
+ userName = StringUtils.substringBefore( userName, "," );
+ log.debug( "found userName for group {}: '{}", group, userName );
+
+ allMembers.add( userName );
+ }
+ close( allMembersEnum );
+ }
+
+
+ }
+
+ return allMembers;
+ }
+ catch ( LdapException e )
+ {
+ throw new MappingException( e.getMessage(), e );
+ }
+ catch ( NamingException e )
+ {
+ throw new MappingException( e.getMessage(), e );
+ }
+
+ finally
+ {
+ if ( ldapConnection != null )
+ {
+ ldapConnection.close();
+ }
+ close( namingEnumeration );
+ }
+ }
+
+ public List<String> getGroups( String username )
+ throws MappingException
+ {
+ // TODO caching and a filter with uid
+ List<String> allGroups = getAllGroups();
+ List<String> userGroups = new ArrayList<String>();
+ for ( String group : allGroups )
+ {
+ List<String> users = getGroupsMember( group );
+ if ( users.contains( username ) )
+ {
+ userGroups.add( group );
+ }
+ }
+ return userGroups;
+ }
+
+ private void close( NamingEnumeration namingEnumeration )
+ {
+ if ( namingEnumeration != null )
+ {
+ try
+ {
+ namingEnumeration.close();
+ }
+ catch ( NamingException e )
+ {
+ log.warn( "fail to close namingEnumeration: {}", e.getMessage() );
+ }
+ }
+ }
+
+ public String getGroupsDn()
+ {
+ return this.groupsDn;
+ }
+
+ public String getLdapGroupClass()
+ {
+ return this.ldapGroupClass;
+ }
+
+ public void addLdapMapping( String role, String ldapGroup )
+ {
+ log.warn( "addLdapMapping not implemented" );
+ }
+
+ public void removeLdapMapping( String role )
+ {
+ log.warn( "removeLdapMapping not implemented" );
+ }
+
+ public Map<String, String> getLdapGroupMappings()
+ {
+ log.warn( "getLdapGroupMappings not implemented" );
+ return Collections.emptyMap();
+ }
+
+ //---------------------------------
+ // setters for unit tests
+ //---------------------------------
+
+
+ public void setGroupsDn( String groupsDn )
+ {
+ this.groupsDn = groupsDn;
+ }
+
+ public void setLdapGroupClass( String ldapGroupClass )
+ {
+ this.ldapGroupClass = ldapGroupClass;
+ }
+
+ public void setUserConf( UserConfiguration userConf )
+ {
+ this.userConf = userConf;
+ }
+
+ public void setLdapConnectionFactory( LdapConnectionFactory ldapConnectionFactory )
+ {
+ this.ldapConnectionFactory = ldapConnectionFactory;
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.rbac.ldap;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
+import org.apache.archiva.redback.rbac.AbstractRBACManager;
+import org.apache.archiva.redback.rbac.AbstractRole;
+import org.apache.archiva.redback.rbac.AbstractUserAssignment;
+import org.apache.archiva.redback.rbac.Operation;
+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.RbacObjectInvalidException;
+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.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Olivier Lamy
+ * @since 2.1
+ */
+@Service( "rbacManager#ldap" )
+public class LdapRbacManager
+ extends AbstractRBACManager
+ implements RBACManager
+{
+
+ @Inject
+ private LdapConnectionFactory ldapConnectionFactory;
+
+ public Role createRole( String name )
+ {
+ return new MockRole();
+ }
+
+ public Role saveRole( Role role )
+ throws RbacManagerException
+ {
+ return role;
+ }
+
+ public void saveRoles( Collection<Role> roles )
+ throws RbacManagerException
+ {
+ // no op
+ }
+
+ public Role getRole( String roleName )
+ throws RbacManagerException
+ {
+ // TODO
+ return null;
+ }
+
+ public List<Role> getAllRoles()
+ throws RbacManagerException
+ {
+ // TODO
+ return Collections.emptyList();
+ }
+
+ public void removeRole( Role role )
+ throws RbacManagerException
+ {
+ // no op
+ }
+
+ public Permission createPermission( String name )
+ throws RbacManagerException
+ {
+ return new MockPermission();
+ }
+
+ public Permission createPermission( String name, String operationName, String resourceIdentifier )
+ throws RbacManagerException
+ {
+ return new MockPermission();
+ }
+
+ public Permission savePermission( Permission permission )
+ throws RbacManagerException
+ {
+ return permission;
+ }
+
+ public Permission getPermission( String permissionName )
+ throws RbacManagerException
+ {
+ return new MockPermission();
+ }
+
+ public List<Permission> getAllPermissions()
+ throws RbacManagerException
+ {
+ // TODO
+ return Collections.emptyList();
+ }
+
+ public void removePermission( Permission permission )
+ throws RbacManagerException
+ {
+ // no op
+ }
+
+ public Operation createOperation( String name )
+ throws RbacManagerException
+ {
+ return new MockOperation();
+ }
+
+ public Operation saveOperation( Operation operation )
+ throws RbacManagerException
+ {
+ return operation;
+ }
+
+ public Operation getOperation( String operationName )
+ throws RbacManagerException
+ {
+ return new MockOperation();
+ }
+
+ public List<Operation> getAllOperations()
+ throws RbacManagerException
+ {
+ // TODO
+ return Collections.emptyList();
+ }
+
+ public void removeOperation( Operation operation )
+ throws RbacManagerException
+ {
+ // no op
+ }
+
+ public Resource createResource( String identifier )
+ throws RbacManagerException
+ {
+ return new MockResource();
+ }
+
+ public Resource saveResource( Resource resource )
+ throws RbacManagerException
+ {
+ return resource;
+ }
+
+ public Resource getResource( String resourceIdentifier )
+ throws RbacManagerException
+ {
+ // TODO
+ return new MockResource();
+ }
+
+ public List<Resource> getAllResources()
+ throws RbacManagerException
+ {
+ // TODO
+ return Collections.emptyList();
+ }
+
+ public void removeResource( Resource resource )
+ throws RbacManagerException
+ {
+ // no op
+ }
+
+ public UserAssignment createUserAssignment( String principal )
+ throws RbacManagerException
+ {
+ return new MockUserAssignment();
+ }
+
+ public UserAssignment saveUserAssignment( UserAssignment userAssignment )
+ throws RbacManagerException
+ {
+ return userAssignment;
+ }
+
+ public UserAssignment getUserAssignment( String principal )
+ throws RbacManagerException
+ {
+ // TODO
+ return new MockUserAssignment();
+ }
+
+ public List<UserAssignment> getAllUserAssignments()
+ throws RbacManagerException
+ {
+ // TODO
+ return Collections.emptyList();
+ }
+
+ public List<UserAssignment> getUserAssignmentsForRoles( Collection<String> roleNames )
+ throws RbacManagerException
+ {
+ // TODO
+ return Collections.emptyList();
+ }
+
+ public void removeUserAssignment( UserAssignment userAssignment )
+ throws RbacManagerException
+ {
+ // no op
+ }
+
+ public void eraseDatabase()
+ {
+ // no op
+ }
+
+ //-------------------------------
+ // Mock classes
+ //-------------------------------
+
+ private static class MockRole
+ extends AbstractRole
+ implements Role
+ {
+ public void addPermission( Permission permission )
+ {
+ // no op
+ }
+
+ public void addChildRoleName( String name )
+ {
+ // no op
+ }
+
+ public List<String> getChildRoleNames()
+ {
+ return Collections.emptyList();
+ }
+
+ public String getDescription()
+ {
+ return null;
+ }
+
+ public String getName()
+ {
+ return null;
+ }
+
+ public List<Permission> getPermissions()
+ {
+ return Collections.emptyList();
+ }
+
+ public boolean isAssignable()
+ {
+ return false;
+ }
+
+ public void removePermission( Permission permission )
+ {
+ // no op
+ }
+
+ public void setAssignable( boolean assignable )
+ {
+ // no op
+ }
+
+ public void setChildRoleNames( List<String> names )
+ {
+ // no op
+ }
+
+ public void setDescription( String description )
+ {
+ // no op
+ }
+
+ public void setName( String name )
+ {
+ // no op
+ }
+
+ public void setPermissions( List<Permission> permissions )
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean isPermanent()
+ {
+ return false;
+ }
+
+ public void setPermanent( boolean permanent )
+ {
+ // no op
+ }
+ }
+
+ private static class MockPermission
+ implements Permission
+ {
+ public String getDescription()
+ {
+ return null;
+ }
+
+ public String getName()
+ {
+ return null;
+ }
+
+ public Operation getOperation()
+ {
+ return null;
+ }
+
+ public Resource getResource()
+ {
+ return null;
+ }
+
+ public void setDescription( String description )
+ {
+ // no op
+ }
+
+ public void setName( String name )
+ {
+ // no op
+ }
+
+ public void setOperation( Operation operation )
+ {
+ // no op
+ }
+
+ public void setResource( Resource resource )
+ {
+ // no op
+ }
+
+ public boolean isPermanent()
+ {
+ return false;
+ }
+
+ public void setPermanent( boolean permanent )
+ {
+ // no op
+ }
+ }
+
+ private static class MockOperation
+ implements Operation
+ {
+ public String getDescription()
+ {
+ return null;
+ }
+
+ public String getName()
+ {
+ return null;
+ }
+
+ public void setDescription( String description )
+ {
+ // no op
+ }
+
+ public void setName( String name )
+ {
+ // no op
+ }
+
+ public boolean isPermanent()
+ {
+ return false;
+ }
+
+ public void setPermanent( boolean permanent )
+ {
+ // no op
+ }
+ }
+
+ private static class MockResource
+ implements Resource
+ {
+ public String getIdentifier()
+ {
+ return null;
+ }
+
+ public boolean isPattern()
+ {
+ return false;
+ }
+
+ public void setIdentifier( String identifier )
+ {
+ // no op
+ }
+
+ public void setPattern( boolean pattern )
+ {
+ // no op
+ }
+
+ public boolean isPermanent()
+ {
+ return false;
+ }
+
+ public void setPermanent( boolean permanent )
+ {
+ // no op
+ }
+ }
+
+ private static class MockUserAssignment
+ extends AbstractUserAssignment
+ implements UserAssignment
+ {
+ public String getPrincipal()
+ {
+ return null;
+ }
+
+ public List<String> getRoleNames()
+ {
+ return Collections.emptyList();
+ }
+
+ public void setPrincipal( String principal )
+ {
+ // no op
+ }
+
+ public void setRoleNames( List<String> roles )
+ {
+ // no op
+ }
+
+ public boolean isPermanent()
+ {
+ return false;
+ }
+
+ public void setPermanent( boolean permanent )
+ {
+ // no op
+ }
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.rbac.ldap;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.archiva.redback.common.ldap.MappingException;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * will map ldap group to redback role
+ *
+ * @author Olivier Lamy
+ * @since 2.1
+ */
+public interface LdapRoleMapper
+{
+ /**
+ * @param role redback role
+ * @return corresponding LDAP group
+ */
+ String getLdapGroup( String role )
+ throws MappingException;
+
+ // for continuum ?
+ //String getLdapGroup( String role, String resource );
+
+
+ /**
+ * @return all LDAP groups
+ */
+ List<String> getAllGroups()
+ throws MappingException;
+
+
+ /**
+ * @return the base dn which contains all ldap groups
+ */
+ String getGroupsDn();
+
+ /**
+ * @return the class used for group usually groupOfUniqueNames
+ */
+ String getLdapGroupClass();
+
+ /**
+ * @param group ldap group
+ * @return uids of group members
+ * @throws MappingException
+ */
+ List<String> getGroupsMember( String group )
+ throws MappingException;
+
+ List<String> getGroups( String username )
+ throws MappingException;
+
+ /**
+ * add mapping redback role <-> ldap group
+ *
+ * @param role redback role
+ * @param ldapGroup ldap group
+ */
+ void addLdapMapping( String role, String ldapGroup )
+ throws MappingException;
+
+ /**
+ * remove a mapping
+ *
+ * @param role redback role
+ */
+ void removeLdapMapping( String role )
+ throws MappingException;
+
+ /**
+ * @return Map of corresponding Redback role (key) and LDAP group (value)
+ */
+ Map<String, String> getLdapGroupMappings()
+ throws MappingException;
+
+}
--- /dev/null
+<?xml version="1.0"?>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+ http://www.springframework.org/schema/context
+ http://www.springframework.org/schema/context/spring-context-3.0.xsd"
+ default-lazy-init="true">
+
+ <context:annotation-config />
+ <context:component-scan
+ base-package="org.apache.archiva.redback.rbac.ldap"/>
+
+ <bean name="cache#operations" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache"
+ init-method="initialize">
+ <property name="diskPersistent" value="false"/>
+ <property name="eternal" value="false"/>
+ <property name="maxElementsInMemory" value="1000"/>
+ <property name="memoryEvictionPolicy" value="LRU"/>
+ <property name="name" value="operations"/>
+ <property name="timeToIdleSeconds" value="1800"/>
+ <property name="timeToLiveSeconds" value="14400"/>
+ </bean>
+
+ <bean name="cache#permissions" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache"
+ init-method="initialize">
+ <property name="diskPersistent" value="false"/>
+ <property name="eternal" value="false"/>
+ <property name="maxElementsInMemory" value="1000"/>
+ <property name="memoryEvictionPolicy" value="LRU"/>
+ <property name="name" value="permissions"/>
+ <property name="timeToIdleSeconds" value="1800"/>
+ <property name="timeToLiveSeconds" value="14400"/>
+ </bean>
+
+ <bean name="cache#resources" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache"
+ init-method="initialize">
+ <property name="diskPersistent" value="false"/>
+ <property name="eternal" value="false"/>
+ <property name="maxElementsInMemory" value="1000"/>
+ <property name="memoryEvictionPolicy" value="LRU"/>
+ <property name="name" value="resources"/>
+ <property name="timeToIdleSeconds" value="1800"/>
+ <property name="timeToLiveSeconds" value="14400"/>
+ </bean>
+
+ <bean name="cache#roles" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache"
+ init-method="initialize">
+ <property name="diskPersistent" value="false"/>
+ <property name="eternal" value="false"/>
+ <property name="maxElementsInMemory" value="1000"/>
+ <property name="memoryEvictionPolicy" value="LRU"/>
+ <property name="name" value="roles"/>
+ <property name="timeToIdleSeconds" value="1800"/>
+ <property name="timeToLiveSeconds" value="14400"/>
+ </bean>
+
+ <bean name="cache#effectiveRoleSet" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache"
+ init-method="initialize">
+ <property name="diskPersistent" value="false"/>
+ <property name="eternal" value="false"/>
+ <property name="maxElementsInMemory" value="1000"/>
+ <property name="memoryEvictionPolicy" value="LRU"/>
+ <property name="name" value="effectiveRoleSet"/>
+ <property name="timeToIdleSeconds" value="1800"/>
+ <property name="timeToLiveSeconds" value="14400"/>
+ </bean>
+
+ <!-- ================================================================
+ Caches with Short Term entries
+ ================================================================ -->
+
+ <bean name="cache#userAssignments" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache"
+ init-method="initialize">
+ <property name="diskPersistent" value="false"/>
+ <property name="eternal" value="false"/>
+ <property name="maxElementsInMemory" value="1000"/>
+ <property name="memoryEvictionPolicy" value="LRU"/>
+ <property name="name" value="userAssignments"/>
+ <property name="timeToIdleSeconds" value="300"/>
+ <property name="timeToLiveSeconds" value="600"/>
+ </bean>
+
+ <bean name="cache#userPermissions" class="org.apache.archiva.redback.components.cache.ehcache.EhcacheCache"
+ init-method="initialize">
+ <property name="diskPersistent" value="false"/>
+ <property name="eternal" value="false"/>
+ <property name="maxElementsInMemory" value="1000"/>
+ <property name="memoryEvictionPolicy" value="LRU"/>
+ <property name="name" value="userPermissions"/>
+ <property name="timeToIdleSeconds" value="300"/>
+ <property name="timeToLiveSeconds" value="600"/>
+ </bean>
+
+</beans>
\ No newline at end of file
--- /dev/null
+package org.apache.archiva.redback.rbac.ldap;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import junit.framework.TestCase;
+import org.fest.assertions.Assertions;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.List;
+
+/**
+ * @author Olivier Lamy
+ */
+@RunWith( SpringJUnit4ClassRunner.class )
+@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
+@DirtiesContext( classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD )
+public class TestLdapRoleMapper
+ extends TestCase
+{
+
+ Logger log = LoggerFactory.getLogger( getClass() );
+
+ @Inject
+ @Named( value = "ldapRoleMapper#test" )
+ LdapRoleMapper ldapRoleMapper;
+
+
+ @Test
+ public void getAllGroups()
+ throws Exception
+ {
+ List<String> allGroups = ldapRoleMapper.getAllGroups();
+
+ log.info( "allGroups: {}", allGroups );
+
+ Assertions.assertThat( allGroups ).isNotNull().isNotEmpty().contains( "archiva-admin",
+ "internal-repo-manager" );
+ }
+
+ @Test
+ public void getGroupsMember()
+ throws Exception
+ {
+ List<String> users = ldapRoleMapper.getGroupsMember( "archiva-admin" );
+
+ log.info( "users for archiva-admin: {}", users );
+
+ Assertions.assertThat( users ).isNotNull().isNotEmpty().contains( "admin", "user.7" );
+ }
+
+ @Test
+ public void getGroups()
+ throws Exception
+ {
+ List<String> roles = ldapRoleMapper.getGroups( "admin" );
+
+ log.info( "roles for admin: {}", roles );
+
+ Assertions.assertThat( roles ).isNotNull().isNotEmpty().contains( "archiva-admin", "internal-repo-manager" );
+ }
+}
--- /dev/null
+<?xml version="1.0"?>
+
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
+ default-lazy-init="false">
+
+ <alias name="userConfiguration#redback" alias="userConfiguration#default"/>
+
+ <bean name="ldapConnectionFactory#configurable" class="org.apache.archiva.redback.common.ldap.connection.ConfigurableLdapConnectionFactory">
+ <property name="hostname" value="localhost"/>
+ <property name="port" value="1389"/>
+ <!--property name="baseDn" value="dc=redback,dc=plexus,dc=codehaus,dc=org"/-->
+ <property name="baseDn" value="dc=archiva,dc=apache,dc=org"/>
+ <property name="contextFactory" value="com.sun.jndi.ldap.LdapCtxFactory"/>
+ <property name="password" value="theadmin"/>
+ <!--property name="bindDn" value="uid=admin,ou=system"/-->
+ <property name="bindDn" value="uid=admin,ou=People,dc=archiva,dc=apache,dc=org"/>
+ <property name="userConf" ref="userConfiguration#default"/>
+ </bean>
+
+
+
+ <bean name="ldapRoleMapper#test" class="org.apache.archiva.redback.rbac.ldap.DefaultLdapRoleMapper">
+ <property name="groupsDn" value="dc=archiva,dc=apache,dc=org"/>
+ <property name="ldapGroupClass" value="groupOfUniqueNames"/>
+ <property name="ldapConnectionFactory" ref="ldapConnectionFactory#configurable"/>
+ <property name="userConf" ref="userConfiguration#default"/>
+ </bean>
+
+</beans>
\ No newline at end of file