1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.services.security.turbine;
18
19 import java.sql.Connection;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.List;
23
24 import javax.servlet.ServletConfig;
25
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.JetspeedUser;
30 import org.apache.jetspeed.om.security.Role;
31 import org.apache.jetspeed.om.security.UserNamePrincipal;
32 import org.apache.jetspeed.om.security.turbine.TurbineGroup;
33 import org.apache.jetspeed.om.security.turbine.TurbineGroupPeer;
34 import org.apache.jetspeed.om.security.turbine.TurbineUserGroupRole;
35 import org.apache.jetspeed.om.security.turbine.TurbineUserGroupRolePeer;
36 import org.apache.jetspeed.services.JetspeedSecurity;
37 import org.apache.jetspeed.services.Profiler;
38 import org.apache.jetspeed.services.PsmlManager;
39 import org.apache.jetspeed.services.rundata.JetspeedRunData;
40 import org.apache.jetspeed.services.rundata.JetspeedRunDataService;
41 import org.apache.jetspeed.services.security.GroupException;
42 import org.apache.jetspeed.services.security.GroupManagement;
43 import org.apache.jetspeed.services.security.JetspeedSecurityException;
44 import org.apache.jetspeed.services.security.JetspeedSecurityService;
45 import org.apache.torque.Torque;
46 import org.apache.torque.om.NumberKey;
47 import org.apache.torque.util.Criteria;
48 import org.apache.turbine.services.InitializationException;
49 import org.apache.turbine.services.TurbineBaseService;
50 import org.apache.turbine.services.TurbineServices;
51 import org.apache.turbine.services.resources.ResourceService;
52 import org.apache.turbine.services.rundata.RunDataService;
53 import org.apache.turbine.util.Log;
54
55 /***
56 * Default Jetspeed-Turbine Group Management implementation
57 *
58 *
59 * @author <a href="mailto:david@bluesunrise.com">David Sean Taylor</a>
60 * @version $Id: TurbineGroupManagement.java,v 1.11 2004/02/23 03:54:49 jford Exp $
61 */
62
63 public class TurbineGroupManagement extends TurbineBaseService
64 implements GroupManagement
65 {
66 private JetspeedRunDataService runDataService = null;
67
68 private final static String CONFIG_DEFAULT_ROLE = "role.default";
69 String defaultRole = "user";
70 private final static String CASCADE_DELETE = "programmatic.cascade.delete";
71 private final static boolean DEFAULT_CASCADE_DELETE = true;
72 private boolean cascadeDelete;
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 JetspeedUser user = null;
93 try
94 {
95 user = JetspeedSecurity.getUser(new UserNamePrincipal(username));
96 }
97 catch(JetspeedSecurityException e)
98 {
99 throw new GroupException("Failed to Retrieve User: ", e);
100 }
101 Criteria criteria = new Criteria();
102 criteria.add(TurbineUserGroupRolePeer.USER_ID, user.getUserId());
103 List rels;
104 HashMap groups;
105
106 try
107 {
108 rels = TurbineUserGroupRolePeer.doSelect(criteria);
109 if (rels.size() > 0)
110 {
111 groups = new HashMap(rels.size());
112 }
113 else
114 groups = new HashMap();
115
116 for (int ix = 0; ix < rels.size(); ix++)
117 {
118 TurbineUserGroupRole rel = (TurbineUserGroupRole)rels.get(ix);
119 Group group = rel.getTurbineGroup();
120 groups.put(group.getName(), group);
121 }
122 }
123 catch(Exception e)
124 {
125 throw new GroupException("Failed to retrieve groups ", e);
126 }
127 return groups.values().iterator();
128 }
129
130 /***
131 * Retrieves all <code>Group</code>s.
132 *
133 * The security service may optionally check the current user context
134 * to determine if the requestor has permission to perform this action.
135 *
136 * @return Iterator over all groups.
137 * @exception GroupException when the security provider has a general failure.
138 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
139 */
140 public Iterator getGroups()
141 throws JetspeedSecurityException
142 {
143 Criteria criteria = new Criteria();
144 List groups;
145 try
146 {
147 groups = TurbineGroupPeer.doSelect(criteria);
148 }
149 catch(Exception e)
150 {
151 throw new GroupException("Failed to retrieve groups ", e);
152 }
153 return groups.iterator();
154 }
155
156 /***
157 * Adds a <code>Group</code> into permanent storage.
158 *
159 * The security service can throw a <code>NotUniqueEntityException</code> when the public
160 * credentials fail to meet the security provider-specific unique constraints.
161 * The security service may optionally check the current user context
162 * to determine if the requestor has permission to perform this action.
163 *
164 * @exception GroupException when the security provider has a general failure.
165 * @exception NotUniqueEntityException when the public credentials fail to meet
166 * the security provider-specific unique constraints.
167 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
168 */
169 public void addGroup(Group group)
170 throws JetspeedSecurityException
171 {
172 if(groupExists(group.getName()))
173 {
174 throw new GroupException("The group '" +
175 group.getName() + "' already exists");
176 }
177
178 try
179 {
180 TurbineGroup tgroup = new TurbineGroup();
181 tgroup.setGroupName(group.getName());
182 Criteria criteria = TurbineGroupPeer.buildCriteria(tgroup);
183 NumberKey key = (NumberKey)TurbineGroupPeer.doInsert(criteria);
184 group.setId(key.toString());
185 }
186 catch(Exception e)
187 {
188 throw new GroupException("Failed to create group '" +
189 group.getName() + "'", e);
190 }
191
192 try
193 {
194 addDefaultGroupPSML(group);
195 }
196 catch (Exception e)
197 {
198 try
199 {
200 removeGroup(group.getName());
201 }
202 catch (Exception e2)
203 {
204 }
205 throw new GroupException("failed to add default PSML for Group resource", e);
206 }
207
208 }
209
210 protected void addDefaultGroupPSML(Group group)
211 throws GroupException
212 {
213 try
214 {
215 JetspeedRunDataService runDataService =
216 (JetspeedRunDataService)TurbineServices.getInstance()
217 .getService(RunDataService.SERVICE_NAME);
218 JetspeedRunData rundata = runDataService.getCurrentRunData();
219 Profile profile = Profiler.createProfile();
220 profile.setGroup(group);
221 profile.setMediaType("html");
222 Profiler.createProfile(rundata, profile);
223 }
224 catch (ProfileException e)
225 {
226 try
227 {
228 removeGroup(group.getName());
229 }
230 catch(Exception e2)
231 {
232 }
233 throw new GroupException("Failed to create Group PSML", e);
234 }
235 }
236
237 /***
238 * Saves a <code>Group</code> into permanent storage.
239 *
240 * The security service can throw a <code>NotUniqueEntityException</code> when the public
241 * credentials fail to meet the security provider-specific unique constraints.
242 * The security service may optionally check the current user context
243 * to determine if the requestor has permission to perform this action.
244 *
245 * @exception GroupException when the security provider has a general failure.
246 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
247 */
248 public void saveGroup(Group group)
249 throws JetspeedSecurityException
250 {
251 if(!groupExists(group.getName()))
252 {
253 throw new GroupException("The group '" +
254 group.getName() + "' doesn't exists");
255 }
256
257 try
258 {
259 if (group instanceof TurbineGroup)
260 {
261 TurbineGroupPeer.doUpdate((TurbineGroup)group);
262 }
263 else
264 {
265 throw new GroupException("TurbineGroupManagment: Group is not a Turbine group, cannot update");
266 }
267
268 }
269 catch(Exception e)
270 {
271 throw new GroupException("Failed to create group '" +
272 group.getName() + "'", e);
273 }
274
275 }
276
277 /***
278 * Removes a <code>Group</code> from the permanent store.
279 *
280 * The security service may optionally check the current user context
281 * to determine if the requestor has permission to perform this action.
282 *
283 * @param groupname the principal identity of the group to be retrieved.
284 * @exception GroupException when the security provider has a general failure.
285 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
286 */
287 public void removeGroup(String groupname)
288 throws JetspeedSecurityException
289 {
290 Connection conn = null;
291 try
292 {
293 conn = Torque.getConnection();
294 Group group = this.getGroup(groupname);
295
296 Criteria criteria = new Criteria();
297 criteria.add(TurbineGroupPeer.GROUP_NAME, groupname);
298
299 if(cascadeDelete)
300 {
301
302 Criteria criteria1 = new Criteria();
303 criteria1.add(TurbineUserGroupRolePeer.GROUP_ID, group.getId());
304 TurbineUserGroupRolePeer.doDelete(criteria1, conn);
305 }
306
307 TurbineGroupPeer.doDelete(criteria, conn);
308 PsmlManager.removeGroupDocuments(group);
309
310 conn.commit();
311
312 }
313 catch(Exception e)
314 {
315 try
316 {
317 conn.rollback();
318 }
319 catch (java.sql.SQLException sqle)
320 {
321 Log.error(sqle);
322 }
323 throw new GroupException("Failed to remove group '" +
324 groupname + "'", e);
325 }
326 finally
327 {
328 try
329 {
330 Torque.closeConnection(conn);
331 }
332 catch (Exception e){}
333 }
334
335 }
336
337 /***
338 * Join a user to a group.
339 *
340 * The security service may optionally check the current user context
341 * to determine if the requestor has permission to perform this action.
342 *
343 * @exception GroupException when the security provider has a general failure retrieving users.
344 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
345 */
346 public void joinGroup(String username, String groupname)
347 throws JetspeedSecurityException
348 {
349 joinGroup(username, groupname, defaultRole);
350 }
351
352 /***
353 * Join a user to a group - specific role.
354 *
355 * The security service may optionally check the current user context
356 * to determine if the requestor has permission to perform this action.
357 *
358 * @exception GroupException when the security provider has a general failure retrieving groups.
359 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
360 */
361 public void joinGroup(String username, String groupname, String rolename)
362 throws JetspeedSecurityException
363 {
364 try
365 {
366 JetspeedUser user = JetspeedSecurity.getUser(username);
367 Group group = this.getGroup(groupname);
368 Role role = JetspeedSecurity.getRole(rolename);
369
370 Criteria criteria = new Criteria();
371 criteria.add(TurbineUserGroupRolePeer.USER_ID, user.getUserId());
372 criteria.add(TurbineUserGroupRolePeer.GROUP_ID, group.getId());
373 criteria.add(TurbineUserGroupRolePeer.ROLE_ID, role.getId());
374 TurbineUserGroupRolePeer.doInsert(criteria);
375 }
376 catch(Exception e)
377 {
378 throw new GroupException("Join group '" + groupname + "' to user '" + username + "' failed: ", e);
379 }
380 }
381
382 /***
383 * Unjoin a user from a group.
384 *
385 * The security service may optionally check the current user context
386 * to determine if the requestor has permission to perform this action.
387 *
388 * @exception GroupException when the security provider has a general failure retrieving users.
389 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
390 */
391 public void unjoinGroup(String username, String groupname)
392 throws JetspeedSecurityException
393 {
394 unjoinGroup(username, groupname, defaultRole);
395 }
396
397 /***
398 * Unjoin a user from a group in which the user has a specific role instead of <Code>JetspeedSecurity.getRole(defaultRole)</Code>
399 *
400 * The security service may optionally check the current user context
401 * to determine if the requestor has permission to perform this action.
402 *
403 * @exception GroupException when the security provider has a general failure retrieving users.
404 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
405 */
406
407 public void unjoinGroup(String username, String groupname, String rolename)
408 throws JetspeedSecurityException
409 {
410 try
411 {
412 JetspeedUser user = JetspeedSecurity.getUser(username);
413 Group group = this.getGroup(groupname);
414 Role role = JetspeedSecurity.getRole(rolename);
415
416 Criteria criteria = new Criteria();
417 criteria.add(TurbineUserGroupRolePeer.USER_ID, user.getUserId());
418 criteria.add(TurbineUserGroupRolePeer.GROUP_ID, group.getId());
419 criteria.add(TurbineUserGroupRolePeer.ROLE_ID, role.getId());
420 TurbineUserGroupRolePeer.doDelete(criteria);
421 }
422 catch(Exception e)
423 {
424 throw new GroupException("Unjoin group '" + groupname + "' to user '" + username + "' failed: ", e);
425 }
426 }
427
428
429 /***
430 * Checks for the relationship of user in a group. Returns true when the user is in the given group.
431 *
432 * The security service may optionally check the current user context
433 * to determine if the requestor has permission to perform this action.
434 *
435 * @exception GroupException when the security provider has a general failure retrieving users.
436 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
437 */
438 public boolean inGroup(String username, String groupname)
439 throws JetspeedSecurityException
440 {
441 List groups;
442
443 try
444 {
445 JetspeedUser user = JetspeedSecurity.getUser(username);
446 Group group = this.getGroup(groupname);
447
448 Criteria criteria = new Criteria();
449 criteria.add(TurbineUserGroupRolePeer.USER_ID, user.getUserId());
450 criteria.add(TurbineUserGroupRolePeer.GROUP_ID, group.getId());
451 groups = TurbineUserGroupRolePeer.doSelect(criteria);
452
453 }
454 catch(Exception e)
455 {
456 throw new GroupException("Failed to check group '" +
457 groupname + "'", e);
458 }
459 return ( groups.size() > 0 );
460 }
461
462 /***
463 * Retrieves a single <code>Group</code> for a given groupname principal.
464 *
465 * The security service may optionally check the current user context
466 * to determine if the requestor has permission to perform this action.
467 *
468 * @param groupname a group principal identity to be retrieved.
469 * @return Group the group record retrieved.
470 * @exception GroupException when the security provider has a general failure.
471 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege
472 */
473 public Group getGroup(String groupname)
474 throws JetspeedSecurityException
475 {
476 List groups;
477 try
478 {
479 Criteria criteria = new Criteria();
480 criteria.add(TurbineGroupPeer.GROUP_NAME, groupname);
481 groups = TurbineGroupPeer.doSelect(criteria);
482 }
483 catch(Exception e)
484 {
485 throw new GroupException("Failed to retrieve group '" +
486 groupname + "'", e);
487 }
488 if ( groups.size() > 1 )
489 {
490 throw new GroupException(
491 "Multiple Groups with same groupname '" + groupname + "'");
492 }
493 if ( groups.size() == 1 )
494 {
495 TurbineGroup group = (TurbineGroup)groups.get(0);
496 return group;
497 }
498 throw new GroupException("Unknown group '" + groupname + "'");
499
500 }
501
502
503
504
505
506 protected JetspeedRunData getRunData()
507 {
508 JetspeedRunData rundata = null;
509 if (this.runDataService != null)
510 {
511 rundata = this.runDataService.getCurrentRunData();
512 }
513 return rundata;
514 }
515
516 /***
517 * Check whether a specified group exists.
518 *
519 * The login name is used for looking up the account.
520 *
521 * @param groupName the name of the group to check for existence.
522 * @return true if the specified account exists
523 * @throws GroupException if there was a general db access error
524 *
525 */
526 protected boolean groupExists(String groupName)
527 throws GroupException
528 {
529 Criteria criteria = new Criteria();
530 criteria.add(TurbineGroupPeer.GROUP_NAME, groupName);
531 List groups;
532 try
533 {
534 groups = TurbineGroupPeer.doSelect(criteria);
535 }
536 catch(Exception e)
537 {
538 throw new GroupException(
539 "Failed to check account's presence", e);
540 }
541 if (groups.size() < 1)
542 {
543 return false;
544 }
545 return true;
546 }
547
548
549
550
551
552
553 /***
554 * This is the early initialization method called by the
555 * Turbine <code>Service</code> framework
556 * @param conf The <code>ServletConfig</code>
557 * @exception throws a <code>InitializationException</code> if the service
558 * fails to initialize
559 */
560 public synchronized void init(ServletConfig conf)
561 throws InitializationException
562 {
563 if (getInit()) return;
564
565 super.init(conf);
566
567
568 ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
569 .getResources(JetspeedSecurityService.SERVICE_NAME);
570
571 this.runDataService =
572 (JetspeedRunDataService)TurbineServices.getInstance()
573 .getService(RunDataService.SERVICE_NAME);
574
575 defaultRole = serviceConf.getString(CONFIG_DEFAULT_ROLE, defaultRole);
576 cascadeDelete = serviceConf.getBoolean( CASCADE_DELETE, DEFAULT_CASCADE_DELETE );
577
578 setInit(true);
579 }
580 }
581
582
583