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 );
246 List<String> userGroups = new ArrayList<String>();
248 LdapConnection ldapConnection = null;
250 NamingEnumeration<SearchResult> namingEnumeration = null;
253 ldapConnection = ldapConnectionFactory.getConnection();
255 DirContext context = ldapConnection.getDirContext();
257 SearchControls searchControls = new SearchControls();
259 searchControls.setDerefLinkFlag( true );
260 searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
263 new StringBuilder().append( "(&" ).append( "(objectClass=" + getLdapGroupClass() + ")" ).append(
264 "(uniquemember=" ).append( "uid=" + username + "," + this.getBaseDn() ).append( ")" ).append(
267 log.debug( "filter: {}", filter );
269 namingEnumeration = context.search( getGroupsDn(), filter, searchControls );
271 while ( namingEnumeration.hasMore() )
273 SearchResult searchResult = namingEnumeration.next();
275 List<String> allMembers = new ArrayList<String>();
277 Attribute uniqueMemberAttr = searchResult.getAttributes().get( "uniquemember" );
279 if ( uniqueMemberAttr != null )
281 NamingEnumeration<String> allMembersEnum = (NamingEnumeration<String>) uniqueMemberAttr.getAll();
282 while ( allMembersEnum.hasMore() )
284 String userName = allMembersEnum.next();
285 // uid=blabla we only want bla bla
286 userName = StringUtils.substringAfter( userName, "=" );
287 userName = StringUtils.substringBefore( userName, "," );
288 //log.debug( "found group for username {}: '{}", group, userName );
290 allMembers.add( userName );
292 close( allMembersEnum );
295 if ( allMembers.contains( username ) )
297 String groupName = searchResult.getName();
298 // cn=blabla we only want bla bla
299 groupName = StringUtils.substringAfter( groupName, "=" );
300 userGroups.add( groupName );
309 catch ( LdapException e )
311 throw new MappingException( e.getMessage(), e );
313 catch ( NamingException e )
315 throw new MappingException( e.getMessage(), e );
320 if ( ldapConnection != null )
322 ldapConnection.close();
324 close( namingEnumeration );
329 private void close( NamingEnumeration namingEnumeration )
331 if ( namingEnumeration != null )
335 namingEnumeration.close();
337 catch ( NamingException e )
339 log.warn( "fail to close namingEnumeration: {}", e.getMessage() );
344 public String getGroupsDn()
346 return this.groupsDn;
349 public String getLdapGroupClass()
351 return this.ldapGroupClass;
354 public void addLdapMapping( String role, String ldapGroup )
356 log.warn( "addLdapMapping not implemented" );
359 public void removeLdapMapping( String role )
361 log.warn( "removeLdapMapping not implemented" );
364 public Map<String, String> getLdapGroupMappings()
366 log.warn( "getLdapGroupMappings not implemented" );
367 return Collections.emptyMap();
370 //---------------------------------
371 // setters for unit tests
372 //---------------------------------
375 public void setGroupsDn( String groupsDn )
377 this.groupsDn = groupsDn;
380 public void setLdapGroupClass( String ldapGroupClass )
382 this.ldapGroupClass = ldapGroupClass;
385 public void setUserConf( UserConfiguration userConf )
387 this.userConf = userConf;
390 public void setLdapConnectionFactory( LdapConnectionFactory ldapConnectionFactory )
392 this.ldapConnectionFactory = ldapConnectionFactory;
395 public String getBaseDn()
400 public void setBaseDn( String baseDn )
402 this.baseDn = baseDn;