1 package org.apache.archiva.redback.rbac.ldap;
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
21 import org.apache.archiva.redback.common.ldap.MappingException;
22 import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
23 import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
24 import org.apache.archiva.redback.common.ldap.connection.LdapException;
25 import org.apache.archiva.redback.configuration.UserConfiguration;
26 import org.apache.archiva.redback.configuration.UserConfigurationKeys;
27 import org.apache.commons.lang.StringUtils;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.springframework.stereotype.Service;
32 import javax.annotation.PostConstruct;
33 import javax.inject.Inject;
34 import javax.inject.Named;
35 import javax.naming.NamingEnumeration;
36 import javax.naming.NamingException;
37 import javax.naming.directory.Attribute;
38 import javax.naming.directory.DirContext;
39 import javax.naming.directory.SearchControls;
40 import javax.naming.directory.SearchResult;
41 import java.util.ArrayList;
42 import java.util.Collections;
43 import java.util.List;
47 * @author Olivier Lamy
50 @Service( "ldapRoleMapper#default" )
51 public class DefaultLdapRoleMapper
52 implements LdapRoleMapper
55 private Logger log = LoggerFactory.getLogger( getClass() );
58 private LdapConnectionFactory ldapConnectionFactory;
61 @Named( value = "userConfiguration#default" )
62 private UserConfiguration userConf;
64 //---------------------------
66 //---------------------------
68 private String ldapGroupClass = "groupOfUniqueNames";
70 private String groupsDn;
72 private String baseDn;
75 public void initialize()
77 this.ldapGroupClass = userConf.getString( UserConfigurationKeys.LDAP_GROUPS_CLASS, this.ldapGroupClass );
79 this.groupsDn = userConf.getString( UserConfigurationKeys.LDAP_GROUPS_BASEDN, this.groupsDn );
81 this.baseDn = userConf.getString( UserConfigurationKeys.LDAP_BASEDN, this.baseDn );
84 public String getLdapGroup( String role )
86 return userConf.getString( UserConfigurationKeys.LDAP_GROUPS_ROLE_START_KEY + role );
89 public List<String> getAllGroups()
90 throws MappingException
93 LdapConnection ldapConnection = null;
95 NamingEnumeration<SearchResult> namingEnumeration = null;
98 ldapConnection = ldapConnectionFactory.getConnection();
100 DirContext context = ldapConnection.getDirContext();
102 SearchControls searchControls = new SearchControls();
104 searchControls.setDerefLinkFlag( true );
105 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
107 String filter = "objectClass=" + getLdapGroupClass();
109 namingEnumeration = context.search( getGroupsDn(), filter, searchControls );
111 List<String> allGroups = new ArrayList<String>();
113 while ( namingEnumeration.hasMore() )
115 SearchResult searchResult = namingEnumeration.next();
117 String groupName = searchResult.getName();
118 // cn=blabla we only want bla bla
119 groupName = StringUtils.substringAfter( groupName, "=" );
121 log.debug( "found groupName: '{}", groupName );
123 allGroups.add( groupName );
129 catch ( LdapException e )
131 throw new MappingException( e.getMessage(), e );
133 catch ( NamingException e )
135 throw new MappingException( e.getMessage(), e );
140 if ( ldapConnection != null )
142 ldapConnection.close();
144 if ( namingEnumeration != null )
148 namingEnumeration.close();
150 catch ( NamingException e )
152 log.warn( "failed to close search results", e );
158 public List<String> getGroupsMember( String group )
159 throws MappingException
162 LdapConnection ldapConnection = null;
164 NamingEnumeration<SearchResult> namingEnumeration = null;
167 ldapConnection = ldapConnectionFactory.getConnection();
169 DirContext context = ldapConnection.getDirContext();
171 SearchControls searchControls = new SearchControls();
173 searchControls.setDerefLinkFlag( true );
174 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
176 String filter = "objectClass=" + getLdapGroupClass();
178 namingEnumeration = context.search( "cn=" + group + "," + getGroupsDn(), filter, searchControls );
180 List<String> allMembers = new ArrayList<String>();
182 while ( namingEnumeration.hasMore() )
184 SearchResult searchResult = namingEnumeration.next();
186 Attribute uniqueMemberAttr = searchResult.getAttributes().get( "uniquemember" );
188 if ( uniqueMemberAttr != null )
190 NamingEnumeration<String> allMembersEnum = (NamingEnumeration<String>) uniqueMemberAttr.getAll();
191 while ( allMembersEnum.hasMore() )
193 String userName = allMembersEnum.next();
194 // uid=blabla we only want bla bla
195 userName = StringUtils.substringAfter( userName, "=" );
196 userName = StringUtils.substringBefore( userName, "," );
197 log.debug( "found userName for group {}: '{}", group, userName );
199 allMembers.add( userName );
201 close( allMembersEnum );
209 catch ( LdapException e )
211 throw new MappingException( e.getMessage(), e );
213 catch ( NamingException e )
215 throw new MappingException( e.getMessage(), e );
220 if ( ldapConnection != null )
222 ldapConnection.close();
224 close( namingEnumeration );
228 public List<String> getGroups( String username )
229 throws MappingException
231 // TODO caching and a filter with uid
233 List<String> allGroups = getAllGroups();
234 List<String> userGroups = new ArrayList<String>();
235 for ( String group : allGroups )
237 List<String> users = getGroupsMember( group );
238 if ( users.contains( username ) )
240 userGroups.add( group );
245 List<String> userGroups = new ArrayList<String>();
247 LdapConnection ldapConnection = null;
249 NamingEnumeration<SearchResult> namingEnumeration = null;
252 ldapConnection = ldapConnectionFactory.getConnection();
254 DirContext context = ldapConnection.getDirContext();
256 SearchControls searchControls = new SearchControls();
258 searchControls.setDerefLinkFlag( true );
259 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
262 // "(&(objectClass=" + getLdapGroupClass() + ") (uniquemember=uid" + username + "," + this.getGroupsDn()
266 new StringBuilder().append( "(&" ).append( "(objectClass=" + getLdapGroupClass() + ")" ).append(
267 "(uniquemember=" ).append( "uid=" + username + "," + this.getBaseDn() ).append( ")" ).append(
270 namingEnumeration = context.search( getGroupsDn(), filter, searchControls );
272 List<String> allMembers = new ArrayList<String>();
274 while ( namingEnumeration.hasMore() )
276 SearchResult searchResult = namingEnumeration.next();
278 Attribute uniqueMemberAttr = searchResult.getAttributes().get( "uniquemember" );
280 if ( uniqueMemberAttr != null )
282 NamingEnumeration<String> allMembersEnum = (NamingEnumeration<String>) uniqueMemberAttr.getAll();
283 while ( allMembersEnum.hasMore() )
285 String userName = allMembersEnum.next();
286 // uid=blabla we only want bla bla
287 userName = StringUtils.substringAfter( userName, "=" );
288 userName = StringUtils.substringBefore( userName, "," );
289 //log.debug( "found group for username {}: '{}", group, userName );
291 allMembers.add( userName );
293 close( allMembersEnum );
301 catch ( LdapException e )
303 throw new MappingException( e.getMessage(), e );
305 catch ( NamingException e )
307 throw new MappingException( e.getMessage(), e );
312 if ( ldapConnection != null )
314 ldapConnection.close();
316 close( namingEnumeration );
321 private void close( NamingEnumeration namingEnumeration )
323 if ( namingEnumeration != null )
327 namingEnumeration.close();
329 catch ( NamingException e )
331 log.warn( "fail to close namingEnumeration: {}", e.getMessage() );
336 public String getGroupsDn()
338 return this.groupsDn;
341 public String getLdapGroupClass()
343 return this.ldapGroupClass;
346 public void addLdapMapping( String role, String ldapGroup )
348 log.warn( "addLdapMapping not implemented" );
351 public void removeLdapMapping( String role )
353 log.warn( "removeLdapMapping not implemented" );
356 public Map<String, String> getLdapGroupMappings()
358 log.warn( "getLdapGroupMappings not implemented" );
359 return Collections.emptyMap();
362 //---------------------------------
363 // setters for unit tests
364 //---------------------------------
367 public void setGroupsDn( String groupsDn )
369 this.groupsDn = groupsDn;
372 public void setLdapGroupClass( String ldapGroupClass )
374 this.ldapGroupClass = ldapGroupClass;
377 public void setUserConf( UserConfiguration userConf )
379 this.userConf = userConf;
382 public void setLdapConnectionFactory( LdapConnectionFactory ldapConnectionFactory )
384 this.ldapConnectionFactory = ldapConnectionFactory;
387 public String getBaseDn()
392 public void setBaseDn( String baseDn )
394 this.baseDn = baseDn;