1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.services.security.ldap;
18
19 import java.util.Enumeration;
20 import java.util.Iterator;
21 import java.util.StringTokenizer;
22 import java.util.Vector;
23 import java.util.HashMap;
24 import javax.naming.directory.BasicAttributes;
25 import javax.servlet.ServletConfig;
26 import org.apache.jetspeed.om.profile.Profile;
27 import org.apache.jetspeed.om.profile.ProfileException;
28 import org.apache.jetspeed.om.security.Group;
29 import org.apache.jetspeed.om.security.UserNamePrincipal;
30 import org.apache.jetspeed.om.security.ldap.LDAPGroup;
31 import org.apache.jetspeed.om.security.ldap.LDAPRole;
32 import org.apache.jetspeed.om.security.ldap.LDAPUser;
33 import org.apache.jetspeed.services.JetspeedLDAP;
34 import org.apache.jetspeed.services.JetspeedSecurity;
35 import org.apache.jetspeed.services.Profiler;
36 import org.apache.jetspeed.services.PsmlManager;
37 import org.apache.jetspeed.services.ldap.LDAPURL;
38 import org.apache.jetspeed.services.rundata.JetspeedRunData;
39 import org.apache.jetspeed.services.rundata.JetspeedRunDataService;
40 import org.apache.jetspeed.services.security.GroupException;
41 import org.apache.jetspeed.services.security.GroupManagement;
42 import org.apache.jetspeed.services.security.JetspeedSecurityException;
43 import org.apache.jetspeed.services.security.JetspeedSecurityService;
44 import org.apache.jetspeed.services.security.UnknownUserException;
45 import org.apache.turbine.services.InitializationException;
46 import org.apache.turbine.services.TurbineBaseService;
47 import org.apache.turbine.services.TurbineServices;
48 import org.apache.turbine.services.resources.ResourceService;
49 import org.apache.turbine.services.rundata.RunDataService;
50
51 /***
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 */
59 public class LDAPGroupManagement extends TurbineBaseService
60 implements GroupManagement
61 {
62
63 private final static String CONFIG_DEFAULT_ROLE = "role.default";
64 private final static String CASCADE_DELETE = "programmatic.cascade.delete";
65 private final static String DEFAULT_DEFAULT_ROLE = "user";
66 private final static boolean DEFAULT_CASCADE_DELETE = true;
67 private final static String[] ATTRS = { "ou", "uid", "groupname" };
68
69
70 private JetspeedRunDataService runDataService = null;
71 private boolean cascadeDelete = false;
72 private String defaultRole = null;
73
74
75
76
77
78 /***
79 * Retrieves all <code>Group</code>s for a given username principal.
80 *
81 * The security service may optionally check the current user context
82 * 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 privilege
88 */
89 public Iterator getGroups(String username)
90 throws JetspeedSecurityException
91 {
92 Vector groups = new Vector();
93 StringTokenizer st;
94 LDAPUser user;
95
96 try
97 {
98 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
99 }
100 catch(JetspeedSecurityException e)
101 {
102 throw new GroupException("Failed to Retrieve User: ", e);
103 }
104
105 try
106 {
107 for (Enumeration enum = user.getGroupRoles().elements() ;enum.hasMoreElements() ;)
108 {
109 st = new StringTokenizer((String)enum.nextElement(),",");
110 groups.add(new LDAPGroup(st.nextToken(), false));
111 }
112 }
113 catch(Exception e)
114 {
115 throw new GroupException("Failed to retrieve groups ", e);
116 }
117
118 return groups.iterator();
119 }
120
121 /***
122 * Retrieves all <code>Group</code>s.
123 *
124 * The security service may optionally check the current user context
125 * 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 privilege
130 */
131 public Iterator getGroups()
132 throws JetspeedSecurityException
133 {
134 BasicAttributes attr= new BasicAttributes();
135 Vector groups = new Vector();
136 Vector groupurls;
137
138 try
139 {
140 groupurls = JetspeedLDAP.search(JetspeedLDAP.buildURL("ou=groups"),
141 "(objectclass=jetspeedgroup)", ATTRS, true);
142 if (groupurls.size() > 0)
143 {
144 for (Enumeration enum = groupurls.elements();enum.hasMoreElements() ;)
145 {
146 groups.add(new LDAPGroup((LDAPURL) (((Vector)enum.nextElement()).firstElement())));
147 }
148 }
149 else
150 {
151 throw new UnknownUserException("No groups");
152 }
153 }
154 catch(Exception e)
155 {
156 throw new GroupException("Failed to retrieve groups ", e);
157 }
158
159 return groups.iterator();
160 }
161
162 /***
163 * Adds a <code>Group</code> into permanent storage.
164 *
165 * The security service can throw a <code>NotUniqueEntityException</code> when the public
166 * credentials fail to meet the security provider-specific unique constraints.
167 * The security service may optionally check the current user context
168 * 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 meet
172 * the security provider-specific unique constraints.
173 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
174 *
175 */
176 public void addGroup(Group group)
177 throws JetspeedSecurityException
178 {
179 LDAPGroup ldapGroup = null;
180
181 if(groupExists(group.getName()))
182 {
183 throw new GroupException("The group '" +
184 group.getName() + "' already exists");
185 }
186 try
187 {
188 ldapGroup = new LDAPGroup(group.getName(), true);
189 ldapGroup.update(true);
190 }
191 catch(Exception e)
192 {
193 throw new GroupException("Failed to create group '" +
194 group.getName() + "'", e);
195 }
196
197 try
198 {
199 addDefaultGroupPSML(ldapGroup);
200 }
201 catch (Exception e)
202 {
203 try
204 {
205 removeGroup(ldapGroup.getName());
206 }
207 catch (Exception e2)
208 {
209 }
210 throw new GroupException("failed to add default PSML for Group resource", e);
211 }
212
213 }
214 protected void addDefaultGroupPSML(Group group)
215 throws GroupException
216 {
217 try
218 {
219 JetspeedRunDataService runDataService =
220 (JetspeedRunDataService)TurbineServices.getInstance()
221 .getService(RunDataService.SERVICE_NAME);
222
223 JetspeedRunData rundata = runDataService.getCurrentRunData();
224 Profile profile = Profiler.createProfile();
225 profile.setGroup(group);
226 profile.setMediaType("html");
227 Profiler.createProfile(rundata, profile);
228 }
229 catch (ProfileException e)
230 {
231 try
232 {
233 removeGroup(group.getName());
234 }
235 catch(Exception e2)
236 {
237 }
238 throw new GroupException("Failed to create Group PSML", e);
239 }
240 }
241
242 /***
243 * Saves a <code>Group</code> into permanent storage.
244 *
245 * The security service can throw a <code>NotUniqueEntityException</code> when the public
246 * credentials fail to meet the security provider-specific unique constraints.
247 * The security service may optionally check the current user context
248 * 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 privilege
252 */
253 public void saveGroup(Group group)
254 throws JetspeedSecurityException
255 {
256 if(!groupExists(group.getName()))
257 {
258 throw new GroupException("The group '" +
259 group.getName() + "' doesn't exists");
260 }
261
262 try
263 {
264 }
265 catch(Exception e)
266 {
267 throw new GroupException("Failed to create group '" +
268 group.getName() + "'", e);
269 }
270 }
271
272 /***
273 * Removes a <code>Group</code> from the permanent store.
274 *
275 * The security service may optionally check the current user context
276 * 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 privilege
281 */
282 public void removeGroup(String groupname)
283 throws JetspeedSecurityException
284 {
285 try
286 {
287 LDAPGroup group = new LDAPGroup(groupname, false);
288 JetspeedLDAP.deleteEntry(group.getldapurl());
289
290 if(cascadeDelete)
291 {
292 }
293
294 PsmlManager.removeGroupDocuments(group);
295 }
296 catch(Exception e)
297 {
298 throw new GroupException("Failed to remove group '" +
299 groupname + "'", e);
300 }
301 }
302
303 /***
304 * Join a user to a group.
305 *
306 * The security service may optionally check the current user context
307 * 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 privilege
311 */
312 public void joinGroup(String username, String groupname)
313 throws JetspeedSecurityException
314 {
315 LDAPUser user;
316 try
317 {
318 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
319 }
320 catch(JetspeedSecurityException e)
321 {
322 throw new GroupException("Failed to Retrieve User: ", e);
323 }
324 try
325 {
326 user.addGroupRole(groupname, defaultRole);
327 user.update(false);
328 }
329 catch(Exception e)
330 {
331 throw new GroupException("Failed to add group info ", e);
332 }
333 }
334
335 /***
336 * Join a user to a group - specific role.
337 *
338 * The security service may optionally check the current user context
339 * 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 privilege
343 */
344 public void joinGroup(String username, String groupname, String rolename)
345 throws JetspeedSecurityException
346 {
347 LDAPUser user;
348 LDAPRole role;
349
350 try
351 {
352 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
353 role = (LDAPRole)JetspeedSecurity.getRole(rolename);
354 }
355 catch(JetspeedSecurityException e)
356 {
357 throw new GroupException("Failed to Retrieve User: ", e);
358 }
359 try
360 {
361 user.addGroupRole(groupname, rolename);
362 user.update(false);
363 }
364 catch(Exception e)
365 {
366 throw new GroupException("Failed to add group info ", e);
367 }
368 }
369
370 /***
371 * Unjoin a user from a group.
372 *
373 * The security service may optionally check the current user context
374 * 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 privilege
378 */
379 public void unjoinGroup(String username, String groupName)
380 throws JetspeedSecurityException
381 {
382 LDAPUser user;
383
384 try
385 {
386 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
387 }
388 catch(JetspeedSecurityException e)
389 {
390 throw new GroupException("Failed to Retrieve User: ", e);
391 }
392
393 try
394 {
395 user.removeGroup(groupName);
396 user.update(false);
397 }
398 catch(Exception e)
399 {
400 throw new GroupException("Failed to add group info ", e);
401 }
402 }
403
404 /***
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 context
408 * 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 privilege
412 */
413 public void unjoinGroup(String username, String groupName, String rolename)
414 throws JetspeedSecurityException
415 {
416 LDAPUser user;
417
418 try
419 {
420 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
421 }
422 catch(JetspeedSecurityException e)
423 {
424 throw new GroupException("Failed to Retrieve User: ", e);
425 }
426
427 try
428 {
429 user.removeGroup(groupName);
430 user.update(false);
431 }
432 catch(Exception e)
433 {
434 throw new GroupException("Failed to add group info ", e);
435 }
436 }
437
438
439 /***
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 context
443 * 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 privilege
447 */
448 public boolean inGroup(String username, String groupname)
449 throws JetspeedSecurityException
450 {
451 Vector groups= new Vector();
452 StringTokenizer st;
453 LDAPUser user;
454
455 try
456 {
457 user = (LDAPUser)JetspeedSecurity.getUser(new UserNamePrincipal(username));
458 }
459 catch(JetspeedSecurityException e)
460 {
461 throw new GroupException("Failed to Retrieve User: ", e);
462 }
463
464 try
465 {
466 for (Enumeration enum = user.getGroupRoles().elements() ;enum.hasMoreElements() ;)
467 {
468 st = new StringTokenizer((String)enum.nextElement(),",");
469
470 if (st.nextToken().equalsIgnoreCase(groupname))
471 {
472 return true;
473 }
474 }
475 }
476 catch(Exception e)
477 {
478 throw new GroupException("Failed to retrieve groups ", e);
479 }
480
481 return false;
482 }
483
484 /***
485 * Retrieves a single <code>Group</code> for a given groupname principal.
486 *
487 * The security service may optionally check the current user context
488 * 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 privilege
496 *
497 */
498 public Group getGroup(String groupname)
499 throws JetspeedSecurityException
500 {
501 BasicAttributes attr= new BasicAttributes();
502 LDAPGroup group;
503 Vector groupurls;
504
505 try
506 {
507 groupurls = JetspeedLDAP.search(JetspeedLDAP.buildURL("ou=groups"),
508 "(&(uid="+ groupname+")(objectclass=jetspeedgroup))", ATTRS, true);
509 if (groupurls.size() == 1)
510 {
511 return new LDAPGroup((LDAPURL)((Vector)groupurls.elementAt(0)).firstElement());
512 }
513 else if(groupurls.size() > 1)
514 {
515 throw new GroupException("Multiple groups with same name");
516 }
517 else
518 {
519 throw new GroupException("Unknown group '" + groupname + "'");
520 }
521 }
522 catch(Exception e)
523 {
524 throw new GroupException("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 context
531 * 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 */
537 public HashMap getTurbineGroupRole(String username)
538 throws JetspeedSecurityException
539 {
540 BasicAttributes attr= new BasicAttributes();
541 LDAPGroup group;
542 Vector groupurls;
543 HashMap h = new HashMap();
544 return h;
545 }
546
547
548
549
550
551
552 protected JetspeedRunData getRunData()
553 {
554 JetspeedRunData rundata = null;
555
556 if (this.runDataService != null)
557 {
558 rundata = this.runDataService.getCurrentRunData();
559 }
560
561 return rundata;
562 }
563
564 /***
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 exists
571 * @throws GroupException if there was a general db access error
572 *
573 */
574 protected boolean groupExists(String groupName)
575 throws GroupException
576 {
577 BasicAttributes attr= new BasicAttributes();
578 Vector groupurls;
579
580 try
581 {
582 groupurls = JetspeedLDAP.search(JetspeedLDAP.buildURL("ou=groups"),
583 "(&(uid="+ groupName+")(objectclass=jetspeedgroup))", ATTRS, true);
584 if (groupurls.size() > 0)
585 {
586 return true;
587 }
588 else
589 {
590 return false;
591 }
592 }
593 catch(Exception e)
594 {
595 throw new GroupException("Failed to retrieve groups ", e);
596 }
597 }
598
599
600
601
602
603 /***
604 * This is the early initialization method called by the
605 * Turbine <code>Service</code> framework
606 * @param conf The <code>ServletConfig</code>
607 * @exception throws a <code>InitializationException</code> if the service
608 * fails to initialize
609 */
610 public synchronized void init(ServletConfig conf)
611 throws InitializationException
612 {
613 if (getInit()) return;
614 super.init(conf);
615
616
617 ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
618 .getResources(JetspeedSecurityService.SERVICE_NAME);
619
620 this.runDataService =
621 (JetspeedRunDataService)TurbineServices.getInstance()
622 .getService(RunDataService.SERVICE_NAME);
623
624 defaultRole = serviceConf.getString(CONFIG_DEFAULT_ROLE, DEFAULT_DEFAULT_ROLE);
625 cascadeDelete = serviceConf.getBoolean( CASCADE_DELETE, DEFAULT_CASCADE_DELETE );
626
627 setInit(true);
628 }
629
630
631 }