1/*2 * Copyright 2000-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.turbine;
1819import java.sql.Connection;
20import java.util.HashMap;
21import java.util.Iterator;
22import java.util.List;
2324import javax.servlet.ServletConfig;
2526import org.apache.jetspeed.om.profile.Profile;
27import org.apache.jetspeed.om.profile.ProfileException;
28import org.apache.jetspeed.om.security.BaseJetspeedGroupRole;
29import org.apache.jetspeed.om.security.Group;
30import org.apache.jetspeed.om.security.GroupRole;
31import org.apache.jetspeed.om.security.JetspeedUser;
32import org.apache.jetspeed.om.security.Role;
33import org.apache.jetspeed.om.security.UserNamePrincipal;
34import org.apache.jetspeed.om.security.turbine.TurbineRole;
35import org.apache.jetspeed.om.security.turbine.TurbineRolePeer;
36import org.apache.jetspeed.om.security.turbine.TurbineRolePermissionPeer;
37import org.apache.jetspeed.om.security.turbine.TurbineUserGroupRole;
38import org.apache.jetspeed.om.security.turbine.TurbineUserGroupRolePeer;
39import org.apache.jetspeed.services.JetspeedSecurity;
40import org.apache.jetspeed.services.Profiler;
41import org.apache.jetspeed.services.PsmlManager;
42import org.apache.jetspeed.services.rundata.JetspeedRunData;
43import org.apache.jetspeed.services.rundata.JetspeedRunDataService;
44import org.apache.jetspeed.services.security.CachedAcl;
45import org.apache.jetspeed.services.security.GroupManagement;
46import org.apache.jetspeed.services.security.JetspeedSecurityCache;
47import org.apache.jetspeed.services.security.JetspeedSecurityException;
48import org.apache.jetspeed.services.security.JetspeedSecurityService;
49import org.apache.jetspeed.services.security.RoleException;
50import org.apache.jetspeed.services.security.RoleManagement;
51import org.apache.torque.Torque;
52import org.apache.torque.om.NumberKey;
53import org.apache.torque.util.Criteria;
54import org.apache.turbine.services.InitializationException;
55import org.apache.turbine.services.TurbineBaseService;
56import org.apache.turbine.services.TurbineServices;
57import org.apache.turbine.services.resources.ResourceService;
58import org.apache.turbine.services.rundata.RunDataService;
59import org.apache.turbine.util.Log;
6061/***62 * Default Jetspeed-Turbine Role Management implementation63 *64 *65 * @author <a href="mailto:david@bluesunrise.com">David Sean Taylor</a>66 * @author <a href="mailto:morciuch@apache.org">Mark Orciuch</a>67 * @version $Id: TurbineRoleManagement.java,v 1.14 2004/02/23 03:54:49 jford Exp $68 */6970publicclassTurbineRoleManagementextends TurbineBaseService
71 implements RoleManagement72 {
73privateJetspeedRunDataService runDataService = null;
74privatefinalstatic String CASCADE_DELETE = "programmatic.cascade.delete";
75privatefinalstaticboolean DEFAULT_CASCADE_DELETE = true;
76privateboolean cascadeDelete;
77privatefinalstatic String CACHING_ENABLE = "caching.enable";
78privateboolean cachingEnable = true;
798081///////////////////////////////////////////////////////////////////////////82// Role Management Interfaces83///////////////////////////////////////////////////////////////////////////8485/***86 * Retrieves all <code>Role</code>s for a given username principal.87 *88 * The security service may optionally check the current user context89 * to determine if the requestor has permission to perform this action.90 *91 * @param username a user principal identity to be retrieved.92 * @return Iterator over all roles associated to the user principal (iterator of GroupRole objects keyed on group+role).93 * @exception RoleException when the security provider has a general failure.94 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege95 */96public Iterator getRoles(String username)
97 throws JetspeedSecurityException98 {
99JetspeedUser user = null;
100try101 {
102if (cachingEnable)
103 {
104 Iterator result = JetspeedSecurityCache.getRoles(username);
105if (null != result)
106 {
107return result;
108 }
109 }
110 user = JetspeedSecurity.getUser(newUserNamePrincipal(username));
111 }
112catch(JetspeedSecurityException e)
113 {
114thrownewRoleException("Failed to Retrieve User: ", e);
115 }
116 Criteria criteria = new Criteria();
117 criteria.add(TurbineUserGroupRolePeer.USER_ID, user.getUserId());
118 List rels;
119 HashMap roles;
120121try122 {
123 rels = TurbineUserGroupRolePeer.doSelect(criteria);
124if (rels.size() > 0)
125 {
126 roles = new HashMap(rels.size());
127 }
128else129 {
130 roles = new HashMap();
131 }
132133for (int ix = 0; ix < rels.size(); ix++)
134 {
135 TurbineUserGroupRole rel = (TurbineUserGroupRole) rels.get(ix);
136 Role role = rel.getTurbineRole();
137 Group group = rel.getTurbineGroup();
138 GroupRole groupRole = newBaseJetspeedGroupRole();
139 groupRole.setGroup(group);
140 groupRole.setRole(role);
141 roles.put(group.getName() + role.getName(), groupRole);
142 }
143 }
144catch(Exception e)
145 {
146thrownewRoleException("Failed to retrieve roles ", e);
147 }
148return roles.values().iterator();
149 }
150151/***152 * Retrieves all <code>Role</code>s.153 *154 * The security service may optionally check the current user context155 * to determine if the requestor has permission to perform this action.156 *157 * @return Iterator over all roles.158 * @exception RoleException when the security provider has a general failure.159 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege160 */161public Iterator getRoles()
162 throws JetspeedSecurityException163 {
164 Criteria criteria = new Criteria();
165 List roles;
166try167 {
168 roles = TurbineRolePeer.doSelect(criteria);
169 }
170catch(Exception e)
171 {
172thrownewRoleException("Failed to retrieve roles ", e);
173 }
174return roles.iterator();
175 }
176177/***178 * Adds a <code>Role</code> into permanent storage.179 *180 * The security service may optionally check the current user context181 * to determine if the requestor has permission to perform this action.182 *183 * @exception RoleException when the security provider has a general failure.184 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege185 */186publicvoid addRole(Role role)
187 throws JetspeedSecurityException188 {
189if(roleExists(role.getName()))
190 {
191thrownewRoleException("The role '" +
192 role.getName() + "' already exists");
193 }
194195try196 {
197TurbineRole trole = newTurbineRole();
198 trole.setRoleName(role.getName());
199 Criteria criteria = TurbineRolePeer.buildCriteria(trole);
200 NumberKey key = (NumberKey)TurbineRolePeer.doInsert(criteria);
201 role.setId(key.toString());
202 }
203catch(Exception e)
204 {
205thrownewRoleException("Failed to create role '" +
206 role.getName() + "'", e);
207 }
208209if (cachingEnable)
210 {
211 JetspeedSecurityCache.addRole(role);
212 }
213214try215 {
216 addDefaultRolePSML(role);
217 }
218catch (Exception e)
219 {
220try221 {
222 removeRole(role.getName());
223 }
224catch (Exception e2)
225 {
226 }
227thrownewRoleException("failed to add default PSML for Role resource", e);
228 }
229230 }
231232protectedvoid addDefaultRolePSML(Role role)
233 throws RoleException234 {
235try236 {
237JetspeedRunDataService runDataService =
238 (JetspeedRunDataService)TurbineServices.getInstance()
239 .getService(RunDataService.SERVICE_NAME);
240JetspeedRunData rundata = runDataService.getCurrentRunData();
241Profile profile = Profiler.createProfile();
242 profile.setRole(role);
243 profile.setMediaType("html");
244 Profiler.createProfile(rundata, profile);
245 }
246catch (ProfileException e)
247 {
248try249 {
250 removeRole(role.getName());
251 }
252catch(Exception e2)
253 {
254 }
255thrownewRoleException("Failed to create Role PSML", e);
256 }
257 }
258259/***260 * Saves a <code>Role</code> into permanent storage.261 *262 * The security service can throw a <code>NotUniqueEntityException</code> when the public263 * credentials fail to meet the security provider-specific unique constraints.264 * The security service may optionally check the current user context265 * to determine if the requestor has permission to perform this action.266 *267 * @exception RoleException when the security provider has a general failure.268 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege269 */270publicvoid saveRole(Role role)
271 throws JetspeedSecurityException272 {
273if(!roleExists(role.getName()))
274 {
275thrownewRoleException("The role '" +
276 role.getName() + "' doesn't exists");
277 }
278279try280 {
281if (role instanceof TurbineRole)
282 {
283 TurbineRolePeer.doUpdate((TurbineRole)role);
284 }
285else286 {
287thrownewRoleException("TurbineRoleManagment: Role is not a Turbine role, cannot update");
288 }
289290 }
291catch(Exception e)
292 {
293thrownewRoleException("Failed to create role '" +
294 role.getName() + "'", e);
295 }
296297 }
298299/***300 * Removes a <code>Role</code> from the permanent store.301 *302 * The security service may optionally check the current user context303 * to determine if the requestor has permission to perform this action.304 *305 * @param rolename the principal identity of the role to be retrieved.306 * @exception RoleException when the security provider has a general failure.307 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege308 */309publicvoid removeRole(String rolename)
310 throws JetspeedSecurityException311 {
312 Connection conn = null;
313try314 {
315 conn = Torque.getConnection();
316Role role = this.getRole(rolename);
317318 Criteria criteria = new Criteria();
319 criteria.add(TurbineRolePeer.ROLE_NAME, rolename);
320321if(cascadeDelete)
322 {
323// CASCADE TURBINE_USER_GROUP_ROLE, TURBINE_ROLE_PERMISSION324 Criteria criteria1 = new Criteria();
325 criteria1.add(TurbineUserGroupRolePeer.ROLE_ID, role.getId());
326 TurbineUserGroupRolePeer.doDelete(criteria1, conn);
327328 Criteria criteria2 = new Criteria();
329 criteria2.add(TurbineRolePermissionPeer.ROLE_ID, role.getId());
330 TurbineRolePermissionPeer.doDelete(criteria2, conn);
331 }
332333 TurbineRolePeer.doDelete(criteria, conn);
334 PsmlManager.removeRoleDocuments(role);
335336 conn.commit();
337338if (cachingEnable)
339 {
340 JetspeedSecurityCache.removeAllRoles(rolename);
341 }
342 }
343catch(Exception e)
344 {
345try346 {
347 conn.rollback();
348 }
349catch (java.sql.SQLException sqle)
350 {
351 Log.error(sqle);
352 }
353thrownewRoleException("Failed to remove role '" +
354 rolename + "'", e);
355 }
356finally357 {
358try359 {
360 Torque.closeConnection(conn);
361 }
362catch (Exception e){}
363 }
364365 }
366367/***368 * Grants a role to a user.369 *370 * The security service may optionally check the current user context371 * to determine if the requestor has permission to perform this action.372 *373 * @exception RoleException when the security provider has a general failure retrieving users.374 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege375 */376publicvoid grantRole(String username, String rolename)
377 throws JetspeedSecurityException378 {
379 grantRole(username, rolename, GroupManagement.DEFAULT_GROUP_NAME);
380 }
381publicvoid grantRole(String username, String rolename, String groupname)
382 throws JetspeedSecurityException383 {
384try385 {
386JetspeedUser user = JetspeedSecurity.getUser(username);
387Role role = this.getRole(rolename);
388Group group = JetspeedSecurity.getGroup(groupname);
389390 Criteria criteria = new Criteria();
391 criteria.add(TurbineUserGroupRolePeer.USER_ID, user.getUserId());
392 criteria.add(TurbineUserGroupRolePeer.GROUP_ID, group.getId());
393 criteria.add(TurbineUserGroupRolePeer.ROLE_ID, role.getId());
394 TurbineUserGroupRolePeer.doInsert(criteria);
395396if (cachingEnable)
397 {
398 JetspeedSecurityCache.addRole(username, role, group);
399 }
400 }
401catch(Exception e)
402 {
403thrownewRoleException("Grant role '" + rolename + "' to user '" + username + "' failed: ", e);
404 }
405 }
406407/***408 * Revokes a role from a user.409 *410 * The security service may optionally check the current user context411 * to determine if the requestor has permission to perform this action.412 *413 * @exception RoleException when the security provider has a general failure retrieving users.414 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege415 */416publicvoid revokeRole(String username, String rolename)
417 throws JetspeedSecurityException418 {
419 revokeRole(username, rolename, GroupManagement.DEFAULT_GROUP_NAME);
420 }
421422publicvoid revokeRole(String username, String rolename, String groupname)
423 throws JetspeedSecurityException424 {
425try426 {
427JetspeedUser user = JetspeedSecurity.getUser(username);
428Role role = this.getRole(rolename);
429Group group = JetspeedSecurity.getGroup(groupname);
430431 Criteria criteria = new Criteria();
432 criteria.add(TurbineUserGroupRolePeer.USER_ID, user.getUserId());
433 criteria.add(TurbineUserGroupRolePeer.GROUP_ID, group.getId());
434 criteria.add(TurbineUserGroupRolePeer.ROLE_ID, role.getId());
435 TurbineUserGroupRolePeer.doDelete(criteria);
436437if (cachingEnable)
438 {
439 JetspeedSecurityCache.removeRole(username, rolename, groupname);
440 }
441442 }
443catch(Exception e)
444 {
445thrownewRoleException("Revoke role '" + rolename + "' to user '" + username + "' failed: ", e);
446 }
447448 }
449450/***451 * Checks for the relationship of user has a role. Returns true when the user has the given role.452 *453 * The security service may optionally check the current user context454 * to determine if the requestor has permission to perform this action.455 *456 * @exception RoleException when the security provider has a general failure retrieving users.457 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege458 */459publicboolean hasRole(String username, String rolename)
460 throws JetspeedSecurityException461 {
462return hasRole(username, rolename, GroupManagement.DEFAULT_GROUP_NAME);
463 }
464465publicboolean hasRole(String username, String rolename, String groupname)
466 throws JetspeedSecurityException467 {
468 List roles;
469470try471 {
472if (cachingEnable)
473 {
474CachedAcl acl = JetspeedSecurityCache.getAcl(username);
475if (null != acl)
476 {
477return acl.hasRole(rolename, groupname);
478 }
479 }
480JetspeedUser user = JetspeedSecurity.getUser(username);
481Role role = this.getRole(rolename);
482Group group = JetspeedSecurity.getGroup(groupname);
483484 Criteria criteria = new Criteria();
485 criteria.add(TurbineUserGroupRolePeer.USER_ID, user.getUserId());
486 criteria.add(TurbineUserGroupRolePeer.GROUP_ID, group.getId());
487 criteria.add(TurbineUserGroupRolePeer.ROLE_ID, role.getId());
488 roles = TurbineUserGroupRolePeer.doSelect(criteria);
489490 }
491catch(Exception e)
492 {
493thrownewRoleException("Failed to check role '" +
494 rolename + "'", e);
495 }
496return ( roles.size() > 0 );
497 }
498499500/***501 * Retrieves a single <code>Role</code> for a given rolename principal.502 *503 * The security service may optionally check the current user context504 * to determine if the requestor has permission to perform this action.505 *506 * @param rolename a role principal identity to be retrieved.507 * @return Role the role record retrieved.508 * @exception RoleException when the security provider has a general failure.509 * @exception InsufficientPrivilegeException when the requestor is denied due to insufficient privilege510 */511publicRole getRole(String rolename)
512 throws JetspeedSecurityException513 {
514 List roles;
515try516 {
517 Criteria criteria = new Criteria();
518 criteria.add(TurbineRolePeer.ROLE_NAME, rolename);
519 roles = TurbineRolePeer.doSelect(criteria);
520 }
521catch(Exception e)
522 {
523thrownewRoleException("Failed to retrieve role '" +
524 rolename + "'", e);
525 }
526if ( roles.size() > 1 )
527 {
528thrownewRoleException(
529"Multiple Roles with same rolename '" + rolename + "'");
530 }
531if ( roles.size() == 1 )
532 {
533TurbineRole role = (TurbineRole)roles.get(0);
534return role;
535 }
536thrownewRoleException("Unknown role '" + rolename + "'");
537538 }
539540541///////////////////////////////////////////////////////////////////////////542// Internal543///////////////////////////////////////////////////////////////////////////544545protectedJetspeedRunData getRunData()
546 {
547JetspeedRunData rundata = null;
548if (this.runDataService != null)
549 {
550 rundata = this.runDataService.getCurrentRunData();
551 }
552return rundata;
553 }
554555/***556 * Check whether a specified role exists.557 *558 * The login name is used for looking up the account.559 *560 * @param roleName the name of the role to check for existence.561 * @return true if the specified account exists562 * @throws RoleException if there was a general db access error563 *564 */565protectedboolean roleExists(String roleName)
566 throws RoleException567 {
568 Criteria criteria = new Criteria();
569 criteria.add(TurbineRolePeer.ROLE_NAME, roleName);
570 List roles;
571try572 {
573 roles = TurbineRolePeer.doSelect(criteria);
574 }
575catch(Exception e)
576 {
577thrownewRoleException(
578"Failed to check account's presence", e);
579 }
580if (roles.size() < 1)
581 {
582return false;
583 }
584returntrue;
585 }
586587///////////////////////////////////////////////////////////////////////////588// Service Init589///////////////////////////////////////////////////////////////////////////590591592/***593 * This is the early initialization method called by the594 * Turbine <code>Service</code> framework595 * @param conf The <code>ServletConfig</code>596 * @exception throws a <code>InitializationException</code> if the service597 * fails to initialize598 */599publicsynchronizedvoid init(ServletConfig conf)
600 throws InitializationException
601 {
602if (getInit()) return;
603604super.init(conf);
605606// get configuration parameters from Jetspeed Resources607 ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
608 .getResources(JetspeedSecurityService.SERVICE_NAME);
609610this.runDataService =
611 (JetspeedRunDataService)TurbineServices.getInstance()
612 .getService(RunDataService.SERVICE_NAME);
613614 cascadeDelete = serviceConf.getBoolean( CASCADE_DELETE, DEFAULT_CASCADE_DELETE );
615 cachingEnable = serviceConf.getBoolean( CACHING_ENABLE, cachingEnable );
616617 setInit(true);
618 }
619620621622 }
623624