1/*2 * Copyright 2000-2001,2004 The Apache Software Foundation.3 * 4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 * 8 * http://www.apache.org/licenses/LICENSE-2.09 * 10 * Unless required by applicable law or agreed to in writing, software11 * distributed under the License is distributed on an "AS IS" BASIS,12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 * See the License for the specific language governing permissions and14 * limitations under the License.15 */1617packageorg.apache.jetspeed.services.security.ldap;
1819import java.util.Enumeration;
20import java.util.Iterator;
21import java.util.StringTokenizer;
22import java.util.Vector;
23import java.util.HashMap;
24import javax.naming.directory.BasicAttributes;
25import javax.servlet.ServletConfig;
26import org.apache.jetspeed.om.profile.Profile;
27import org.apache.jetspeed.om.profile.ProfileException;
28import org.apache.jetspeed.om.security.Group;
29import org.apache.jetspeed.om.security.UserNamePrincipal;
30import org.apache.jetspeed.om.security.ldap.LDAPGroup;
31import org.apache.jetspeed.om.security.ldap.LDAPRole;
32import org.apache.jetspeed.om.security.ldap.LDAPUser;
33import org.apache.jetspeed.services.JetspeedLDAP;
34import org.apache.jetspeed.services.JetspeedSecurity;
35import org.apache.jetspeed.services.Profiler;
36import org.apache.jetspeed.services.PsmlManager;
37import org.apache.jetspeed.services.ldap.LDAPURL;
38import org.apache.jetspeed.services.rundata.JetspeedRunData;
39import org.apache.jetspeed.services.rundata.JetspeedRunDataService;
40import org.apache.jetspeed.services.security.GroupException;
41import org.apache.jetspeed.services.security.GroupManagement;
42import org.apache.jetspeed.services.security.JetspeedSecurityException;
43import org.apache.jetspeed.services.security.JetspeedSecurityService;
44import org.apache.jetspeed.services.security.UnknownUserException;
45import org.apache.turbine.services.InitializationException;
46import org.apache.turbine.services.TurbineBaseService;
47import org.apache.turbine.services.TurbineServices;
48import org.apache.turbine.services.resources.ResourceService;
49import org.apache.turbine.services.rundata.RunDataService;
5051/***52 *53 * @author <a href="mailto:ender@kilicoglu.nom.tr">Ender KILICOGLU</a>54 * @author <a href="mailto:sami.leino@netorek.fi">Sami Leino</a>55 *56 * @version $Id: LDAPGroupManagement.java,v 1.8 2004/02/23 03:52:33 jford Exp $57 *58 */59publicclassLDAPGroupManagementextends TurbineBaseService
60 implements GroupManagement61 {
62// Constants63privatefinalstatic String CONFIG_DEFAULT_ROLE = "role.default";
64privatefinalstatic String CASCADE_DELETE = "programmatic.cascade.delete";
65privatefinalstatic String DEFAULT_DEFAULT_ROLE = "user";
66privatefinalstaticboolean DEFAULT_CASCADE_DELETE = true;
67privatefinalstatic String[] ATTRS = { "ou", "uid", "groupname" };
6869// Instance variables70privateJetspeedRunDataService runDataService = null;
71privateboolean cascadeDelete = false;
72private String defaultRole = null;
7374///////////////////////////////////////////////////////////////////////////75// Group Management Interfaces76///////////////////////////////////////////////////////////////////////////7778/***79 * Retrieves all <code>Group</code>s for a given username principal.80 *81 * The security service may optionally check the current user context82 * to determine if the requestor has permission to perform this action.83 *84 * @param username a user principal identity to be retrieved.85 * @return Iterator over all groups associated to the user principal.86 * @exception GroupException when the security provider has a general failure.87 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege88 */89public Iterator getGroups(String username)
90 throws JetspeedSecurityException91 {
92 Vector groups = new Vector();
93 StringTokenizer st;
94LDAPUser user;
9596try97 {
98 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
99 }
100catch(JetspeedSecurityException e)
101 {
102thrownewGroupException("Failed to Retrieve User: ", e);
103 }
104105try106 {
107for (Enumeration enum = user.getGroupRoles().elements() ;enum.hasMoreElements() ;)
108 {
109 st = new StringTokenizer((String)enum.nextElement(),",");
110 groups.add(newLDAPGroup(st.nextToken(), false));
111 }
112 }
113catch(Exception e)
114 {
115thrownewGroupException("Failed to retrieve groups ", e);
116 }
117118return groups.iterator();
119 }
120121/***122 * Retrieves all <code>Group</code>s.123 *124 * The security service may optionally check the current user context125 * to determine if the requestor has permission to perform this action.126 *127 * @return Iterator over all groups.128 * @exception GroupException when the security provider has a general failure.129 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege130 */131public Iterator getGroups()
132 throws JetspeedSecurityException133 {
134 BasicAttributes attr= new BasicAttributes();
135 Vector groups = new Vector();
136 Vector groupurls;
137138try139 {
140 groupurls = JetspeedLDAP.search(JetspeedLDAP.buildURL("ou=groups"),
141"(objectclass=jetspeedgroup)", ATTRS, true);
142if (groupurls.size() > 0)
143 {
144for (Enumeration enum = groupurls.elements();enum.hasMoreElements() ;)
145 {
146 groups.add(newLDAPGroup((LDAPURL) (((Vector)enum.nextElement()).firstElement())));
147 }
148 }
149else150 {
151thrownewUnknownUserException("No groups");
152 }
153 }
154catch(Exception e)
155 {
156thrownewGroupException("Failed to retrieve groups ", e);
157 }
158159return groups.iterator();
160 }
161162/***163 * Adds a <code>Group</code> into permanent storage.164 *165 * The security service can throw a <code>NotUniqueEntityException</code> when the public166 * credentials fail to meet the security provider-specific unique constraints.167 * The security service may optionally check the current user context168 * to determine if the requestor has permission to perform this action.169 *170 * @exception GroupException when the security provider has a general failure.171 * @exception NotUniqueEntityException when the public credentials fail to meet172 * the security provider-specific unique constraints.173 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege174 *175 */176publicvoid addGroup(Group group)
177 throws JetspeedSecurityException178 {
179LDAPGroup ldapGroup = null;
180181if(groupExists(group.getName()))
182 {
183thrownewGroupException("The group '" +
184 group.getName() + "' already exists");
185 }
186try187 {
188 ldapGroup = newLDAPGroup(group.getName(), true);
189 ldapGroup.update(true);
190 }
191catch(Exception e)
192 {
193thrownewGroupException("Failed to create group '" +
194 group.getName() + "'", e);
195 }
196197try198 {
199 addDefaultGroupPSML(ldapGroup);
200 }
201catch (Exception e)
202 {
203try204 {
205 removeGroup(ldapGroup.getName());
206 }
207catch (Exception e2)
208 {
209 }
210thrownewGroupException("failed to add default PSML for Group resource", e);
211 }
212213 }
214protectedvoid addDefaultGroupPSML(Group group)
215 throws GroupException216 {
217try218 {
219JetspeedRunDataService runDataService =
220 (JetspeedRunDataService)TurbineServices.getInstance()
221 .getService(RunDataService.SERVICE_NAME);
222223JetspeedRunData rundata = runDataService.getCurrentRunData();
224Profile profile = Profiler.createProfile();
225 profile.setGroup(group);
226 profile.setMediaType("html");
227 Profiler.createProfile(rundata, profile);
228 }
229catch (ProfileException e)
230 {
231try232 {
233 removeGroup(group.getName());
234 }
235catch(Exception e2)
236 {
237 }
238thrownewGroupException("Failed to create Group PSML", e);
239 }
240 }
241242/***243 * Saves a <code>Group</code> into permanent storage.244 *245 * The security service can throw a <code>NotUniqueEntityException</code> when the public246 * credentials fail to meet the security provider-specific unique constraints.247 * The security service may optionally check the current user context248 * to determine if the requestor has permission to perform this action.249 *250 * @exception GroupException when the security provider has a general failure.251 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege252 */253publicvoid saveGroup(Group group)
254 throws JetspeedSecurityException255 {
256if(!groupExists(group.getName()))
257 {
258thrownewGroupException("The group '" +
259 group.getName() + "' doesn't exists");
260 }
261262try263 {
264 }
265catch(Exception e)
266 {
267thrownewGroupException("Failed to create group '" +
268 group.getName() + "'", e);
269 }
270 }
271272/***273 * Removes a <code>Group</code> from the permanent store.274 *275 * The security service may optionally check the current user context276 * to determine if the requestor has permission to perform this action.277 *278 * @param groupname the principal identity of the group to be retrieved.279 * @exception GroupException when the security provider has a general failure.280 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege281 */282publicvoid removeGroup(String groupname)
283 throws JetspeedSecurityException284 {
285try286 {
287LDAPGroup group = newLDAPGroup(groupname, false);
288 JetspeedLDAP.deleteEntry(group.getldapurl());
289290if(cascadeDelete)
291 {
292 }
293294 PsmlManager.removeGroupDocuments(group);
295 }
296catch(Exception e)
297 {
298thrownewGroupException("Failed to remove group '" +
299 groupname + "'", e);
300 }
301 }
302303/***304 * Join a user to a group.305 *306 * The security service may optionally check the current user context307 * to determine if the requestor has permission to perform this action.308 *309 * @exception GroupException when the security provider has a general failure retrieving users.310 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege311 */312publicvoid joinGroup(String username, String groupname)
313 throws JetspeedSecurityException314 {
315LDAPUser user;
316try317 {
318 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
319 }
320catch(JetspeedSecurityException e)
321 {
322thrownewGroupException("Failed to Retrieve User: ", e);
323 }
324try325 {
326 user.addGroupRole(groupname, defaultRole);
327 user.update(false);
328 }
329catch(Exception e)
330 {
331thrownewGroupException("Failed to add group info ", e);
332 }
333 }
334335/***336 * Join a user to a group - specific role.337 *338 * The security service may optionally check the current user context339 * to determine if the requestor has permission to perform this action.340 *341 * @exception GroupException when the security provider has a general failure retrieving groups.342 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege343 */344publicvoid joinGroup(String username, String groupname, String rolename)
345 throws JetspeedSecurityException346 {
347LDAPUser user;
348LDAPRole role;
349350try351 {
352 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
353 role = (LDAPRole)JetspeedSecurity.getRole(rolename);
354 }
355catch(JetspeedSecurityException e)
356 {
357thrownewGroupException("Failed to Retrieve User: ", e);
358 }
359try360 {
361 user.addGroupRole(groupname, rolename);
362 user.update(false);
363 }
364catch(Exception e)
365 {
366thrownewGroupException("Failed to add group info ", e);
367 }
368 }
369370/***371 * Unjoin a user from a group.372 *373 * The security service may optionally check the current user context374 * to determine if the requestor has permission to perform this action.375 *376 * @exception GroupException when the security provider has a general failure retrieving users.377 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege378 */379publicvoid unjoinGroup(String username, String groupName)
380 throws JetspeedSecurityException381 {
382LDAPUser user;
383384try385 {
386 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
387 }
388catch(JetspeedSecurityException e)
389 {
390thrownewGroupException("Failed to Retrieve User: ", e);
391 }
392393try394 {
395 user.removeGroup(groupName);
396 user.update(false);
397 }
398catch(Exception e)
399 {
400thrownewGroupException("Failed to add group info ", e);
401 }
402 }
403404/***405 * Unjoin a user from a group in which the user has a specific role.406 *407 * The security service may optionally check the current user context408 * to determine if the requestor has permission to perform this action.409 *410 * @exception GroupException when the security provider has a general failure retrieving users.411 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege412 */413publicvoid unjoinGroup(String username, String groupName, String rolename)
414 throws JetspeedSecurityException415 {
416LDAPUser user;
417418try419 {
420 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
421 }
422catch(JetspeedSecurityException e)
423 {
424thrownewGroupException("Failed to Retrieve User: ", e);
425 }
426427try428 {
429 user.removeGroup(groupName);
430 user.update(false);
431 }
432catch(Exception e)
433 {
434thrownewGroupException("Failed to add group info ", e);
435 }
436 }
437438439/***440 * Checks for the relationship of user in a group. Returns true when the user is in the given group.441 *442 * The security service may optionally check the current user context443 * to determine if the requestor has permission to perform this action.444 *445 * @exception GroupException when the security provider has a general failure retrieving users.446 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege447 */448publicboolean inGroup(String username, String groupname)
449 throws JetspeedSecurityException450 {
451 Vector groups= new Vector();
452 StringTokenizer st;
453LDAPUser user;
454455try456 {
457 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
458 }
459catch(JetspeedSecurityException e)
460 {
461thrownewGroupException("Failed to Retrieve User: ", e);
462 }
463464try465 {
466for (Enumeration enum = user.getGroupRoles().elements() ;enum.hasMoreElements() ;)
467 {
468 st = new StringTokenizer((String)enum.nextElement(),",");
469470if (st.nextToken().equalsIgnoreCase(groupname))
471 {
472returntrue;
473 }
474 }
475 }
476catch(Exception e)
477 {
478thrownewGroupException("Failed to retrieve groups ", e);
479 }
480481return false;
482 }
483484/***485 * Retrieves a single <code>Group</code> for a given groupname principal.486 *487 * The security service may optionally check the current user context488 * to determine if the requestor has permission to perform this action.489 *490 * @param groupname a group principal identity to be retrieved.491 *492 * @return Group the group record retrieved.493 *494 * @exception GroupException when the security provider has a general failure.495 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege496 *497 */498publicGroup getGroup(String groupname)
499 throws JetspeedSecurityException500 {
501 BasicAttributes attr= new BasicAttributes();
502LDAPGroup group;
503 Vector groupurls;
504505try506 {
507 groupurls = JetspeedLDAP.search(JetspeedLDAP.buildURL("ou=groups"),
508"(&(uid="+ groupname+")(objectclass=jetspeedgroup))", ATTRS, true);
509if (groupurls.size() == 1)
510 {
511returnnewLDAPGroup((LDAPURL)((Vector)groupurls.elementAt(0)).firstElement());
512 }
513elseif(groupurls.size() > 1)
514 {
515thrownewGroupException("Multiple groups with same name");
516 }
517else518 {
519thrownew GroupException("Unknown group '" + groupname + "'");
520 }
521 }
522catch(Exception e)
523 {
524thrownewGroupException("Failed to retrieve groups ", e);
525 }
526 }
527/***528 * Retrieves a hashtable which associates Groups with Roles for a given username principal.529 *530 * The security service may optionally check the current user context531 * to determine if the requestor has permission to perform this action.532 *533 * @param username a user principal identity to be retrieved.534 * @return Hashtable record retrieved.535 * @exception GroupException when the security provider has a general failure.536 */537public HashMap getTurbineGroupRole(String username)
538 throws JetspeedSecurityException539 {
540 BasicAttributes attr= new BasicAttributes();
541LDAPGroup group;
542 Vector groupurls;
543 HashMap h = new HashMap();
544return h;
545 }
546547548///////////////////////////////////////////////////////////////////////////549// Internal550///////////////////////////////////////////////////////////////////////////551552protectedJetspeedRunData getRunData()
553 {
554JetspeedRunData rundata = null;
555556if (this.runDataService != null)
557 {
558 rundata = this.runDataService.getCurrentRunData();
559 }
560561return rundata;
562 }
563564/***565 * Check whether a specified group exists.566 *567 * The login name is used for looking up the account.568 *569 * @param groupName the name of the group to check for existence.570 * @return true if the specified account exists571 * @throws GroupException if there was a general db access error572 *573 */574protectedboolean groupExists(String groupName)
575 throws GroupException576 {
577 BasicAttributes attr= new BasicAttributes();
578 Vector groupurls;
579580try581 {
582 groupurls = JetspeedLDAP.search(JetspeedLDAP.buildURL("ou=groups"),
583"(&(uid="+ groupName+")(objectclass=jetspeedgroup))", ATTRS, true);
584if (groupurls.size() > 0)
585 {
586returntrue;
587 }
588else589 {
590return false;
591 }
592 }
593catch(Exception e)
594 {
595thrownewGroupException("Failed to retrieve groups ", e);
596 }
597 }
598599///////////////////////////////////////////////////////////////////////////600// Service Init601///////////////////////////////////////////////////////////////////////////602603/***604 * This is the early initialization method called by the605 * Turbine <code>Service</code> framework606 * @param conf The <code>ServletConfig</code>607 * @exception throws a <code>InitializationException</code> if the service608 * fails to initialize609 */610publicsynchronizedvoid init(ServletConfig conf)
611 throws InitializationException
612 {
613if (getInit()) return;
614super.init(conf);
615616// get configuration parameters from Jetspeed Resources617 ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
618 .getResources(JetspeedSecurityService.SERVICE_NAME);
619620this.runDataService =
621 (JetspeedRunDataService)TurbineServices.getInstance()
622 .getService(RunDataService.SERVICE_NAME);
623624 defaultRole = serviceConf.getString(CONFIG_DEFAULT_ROLE, DEFAULT_DEFAULT_ROLE);
625 cascadeDelete = serviceConf.getBoolean( CASCADE_DELETE, DEFAULT_CASCADE_DELETE );
626627 setInit(true);
628 }
629630631 }