]> source.dussan.org Git - archiva.git/blob
4df4bc731672ec0208abf23c82a1ef1cef1a9e1b
[archiva.git] /
1 package org.apache.archiva.redback.rbac.ldap;
2 /*
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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
18  * under the License.
19  */
20
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;
31
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;
44 import java.util.Map;
45
46 /**
47  * @author Olivier Lamy
48  * @since 2.1
49  */
50 @Service( "ldapRoleMapper#default" )
51 public class DefaultLdapRoleMapper
52     implements LdapRoleMapper
53 {
54
55     private Logger log = LoggerFactory.getLogger( getClass() );
56
57     @Inject
58     private LdapConnectionFactory ldapConnectionFactory;
59
60     @Inject
61     @Named( value = "userConfiguration#default" )
62     private UserConfiguration userConf;
63
64     //---------------------------
65     // fields
66     //---------------------------
67
68     private String ldapGroupClass = "groupOfUniqueNames";
69
70     private String groupsDn;
71
72     private String baseDn;
73
74     @PostConstruct
75     public void initialize()
76     {
77         this.ldapGroupClass = userConf.getString( UserConfigurationKeys.LDAP_GROUPS_CLASS, this.ldapGroupClass );
78
79         this.groupsDn = userConf.getString( UserConfigurationKeys.LDAP_GROUPS_BASEDN, this.groupsDn );
80
81         this.baseDn = userConf.getString( UserConfigurationKeys.LDAP_BASEDN, this.baseDn );
82     }
83
84     public String getLdapGroup( String role )
85     {
86         return userConf.getString( UserConfigurationKeys.LDAP_GROUPS_ROLE_START_KEY + role );
87     }
88
89     public List<String> getAllGroups()
90         throws MappingException
91     {
92         // TODO caching
93         LdapConnection ldapConnection = null;
94
95         NamingEnumeration<SearchResult> namingEnumeration = null;
96         try
97         {
98             ldapConnection = ldapConnectionFactory.getConnection();
99
100             DirContext context = ldapConnection.getDirContext();
101
102             SearchControls searchControls = new SearchControls();
103
104             searchControls.setDerefLinkFlag( true );
105             searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
106
107             String filter = "objectClass=" + getLdapGroupClass();
108
109             namingEnumeration = context.search( getGroupsDn(), filter, searchControls );
110
111             List<String> allGroups = new ArrayList<String>();
112
113             while ( namingEnumeration.hasMore() )
114             {
115                 SearchResult searchResult = namingEnumeration.next();
116
117                 String groupName = searchResult.getName();
118                 // cn=blabla we only want bla bla
119                 groupName = StringUtils.substringAfter( groupName, "=" );
120
121                 log.debug( "found groupName: '{}", groupName );
122
123                 allGroups.add( groupName );
124
125             }
126
127             return allGroups;
128         }
129         catch ( LdapException e )
130         {
131             throw new MappingException( e.getMessage(), e );
132         }
133         catch ( NamingException e )
134         {
135             throw new MappingException( e.getMessage(), e );
136         }
137
138         finally
139         {
140             if ( ldapConnection != null )
141             {
142                 ldapConnection.close();
143             }
144             if ( namingEnumeration != null )
145             {
146                 try
147                 {
148                     namingEnumeration.close();
149                 }
150                 catch ( NamingException e )
151                 {
152                     log.warn( "failed to close search results", e );
153                 }
154             }
155         }
156     }
157
158     public List<String> getGroupsMember( String group )
159         throws MappingException
160     {
161         // TODO caching
162         LdapConnection ldapConnection = null;
163
164         NamingEnumeration<SearchResult> namingEnumeration = null;
165         try
166         {
167             ldapConnection = ldapConnectionFactory.getConnection();
168
169             DirContext context = ldapConnection.getDirContext();
170
171             SearchControls searchControls = new SearchControls();
172
173             searchControls.setDerefLinkFlag( true );
174             searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
175
176             String filter = "objectClass=" + getLdapGroupClass();
177
178             namingEnumeration = context.search( "cn=" + group + "," + getGroupsDn(), filter, searchControls );
179
180             List<String> allMembers = new ArrayList<String>();
181
182             while ( namingEnumeration.hasMore() )
183             {
184                 SearchResult searchResult = namingEnumeration.next();
185
186                 Attribute uniqueMemberAttr = searchResult.getAttributes().get( "uniquemember" );
187
188                 if ( uniqueMemberAttr != null )
189                 {
190                     NamingEnumeration<String> allMembersEnum = (NamingEnumeration<String>) uniqueMemberAttr.getAll();
191                     while ( allMembersEnum.hasMore() )
192                     {
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 );
198
199                         allMembers.add( userName );
200                     }
201                     close( allMembersEnum );
202                 }
203
204
205             }
206
207             return allMembers;
208         }
209         catch ( LdapException e )
210         {
211             throw new MappingException( e.getMessage(), e );
212         }
213         catch ( NamingException e )
214         {
215             throw new MappingException( e.getMessage(), e );
216         }
217
218         finally
219         {
220             if ( ldapConnection != null )
221             {
222                 ldapConnection.close();
223             }
224             close( namingEnumeration );
225         }
226     }
227
228     public List<String> getGroups( String username )
229         throws MappingException
230     {
231         // TODO caching and a filter with uid
232
233         /*List<String> allGroups = getAllGroups();
234         List<String> userGroups = new ArrayList<String>();
235         for ( String group : allGroups )
236         {
237             List<String> users = getGroupsMember( group );
238             if ( users.contains( username ) )
239             {
240                 userGroups.add( group );
241             }
242         }
243         return userGroups;
244         */
245
246         List<String> userGroups = new ArrayList<String>();
247
248         LdapConnection ldapConnection = null;
249
250         NamingEnumeration<SearchResult> namingEnumeration = null;
251         try
252         {
253             ldapConnection = ldapConnectionFactory.getConnection();
254
255             DirContext context = ldapConnection.getDirContext();
256
257             SearchControls searchControls = new SearchControls();
258
259             searchControls.setDerefLinkFlag( true );
260             searchControls.setSearchScope( SearchControls.SUBTREE_SCOPE );
261
262             String filter =
263                 new StringBuilder().append( "(&" ).append( "(objectClass=" + getLdapGroupClass() + ")" ).append(
264                     "(uniquemember=" ).append( "uid=" + username + "," + this.getBaseDn() ).append( ")" ).append(
265                     ")" ).toString();
266
267             log.debug( "filter: {}", filter );
268
269             namingEnumeration = context.search( getGroupsDn(), filter, searchControls );
270
271             while ( namingEnumeration.hasMore() )
272             {
273                 SearchResult searchResult = namingEnumeration.next();
274
275                 List<String> allMembers = new ArrayList<String>();
276
277                 Attribute uniqueMemberAttr = searchResult.getAttributes().get( "uniquemember" );
278
279                 if ( uniqueMemberAttr != null )
280                 {
281                     NamingEnumeration<String> allMembersEnum = (NamingEnumeration<String>) uniqueMemberAttr.getAll();
282                     while ( allMembersEnum.hasMore() )
283                     {
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 );
289
290                         allMembers.add( userName );
291                     }
292                     close( allMembersEnum );
293                 }
294
295                 if ( allMembers.contains( username ) )
296                 {
297                     String groupName = searchResult.getName();
298                     // cn=blabla we only want bla bla
299                     groupName = StringUtils.substringAfter( groupName, "=" );
300                     userGroups.add( groupName );
301
302                 }
303
304
305             }
306
307             return userGroups;
308         }
309         catch ( LdapException e )
310         {
311             throw new MappingException( e.getMessage(), e );
312         }
313         catch ( NamingException e )
314         {
315             throw new MappingException( e.getMessage(), e );
316         }
317
318         finally
319         {
320             if ( ldapConnection != null )
321             {
322                 ldapConnection.close();
323             }
324             close( namingEnumeration );
325         }
326
327     }
328
329     private void close( NamingEnumeration namingEnumeration )
330     {
331         if ( namingEnumeration != null )
332         {
333             try
334             {
335                 namingEnumeration.close();
336             }
337             catch ( NamingException e )
338             {
339                 log.warn( "fail to close namingEnumeration: {}", e.getMessage() );
340             }
341         }
342     }
343
344     public String getGroupsDn()
345     {
346         return this.groupsDn;
347     }
348
349     public String getLdapGroupClass()
350     {
351         return this.ldapGroupClass;
352     }
353
354     public void addLdapMapping( String role, String ldapGroup )
355     {
356         log.warn( "addLdapMapping not implemented" );
357     }
358
359     public void removeLdapMapping( String role )
360     {
361         log.warn( "removeLdapMapping not implemented" );
362     }
363
364     public Map<String, String> getLdapGroupMappings()
365     {
366         log.warn( "getLdapGroupMappings not implemented" );
367         return Collections.emptyMap();
368     }
369
370     //---------------------------------
371     // setters for unit tests
372     //---------------------------------
373
374
375     public void setGroupsDn( String groupsDn )
376     {
377         this.groupsDn = groupsDn;
378     }
379
380     public void setLdapGroupClass( String ldapGroupClass )
381     {
382         this.ldapGroupClass = ldapGroupClass;
383     }
384
385     public void setUserConf( UserConfiguration userConf )
386     {
387         this.userConf = userConf;
388     }
389
390     public void setLdapConnectionFactory( LdapConnectionFactory ldapConnectionFactory )
391     {
392         this.ldapConnectionFactory = ldapConnectionFactory;
393     }
394
395     public String getBaseDn()
396     {
397         return baseDn;
398     }
399
400     public void setBaseDn( String baseDn )
401     {
402         this.baseDn = baseDn;
403     }
404 }