001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jetspeed.security.impl;
018:
019: import java.security.Principal;
020: import java.util.ArrayList;
021: import java.util.Collection;
022: import java.util.Iterator;
023: import java.util.LinkedList;
024: import java.util.List;
025: import java.util.Set;
026: import java.util.prefs.BackingStoreException;
027: import java.util.prefs.Preferences;
028:
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031: import org.apache.jetspeed.i18n.KeyedMessage;
032: import org.apache.jetspeed.security.AuthenticationProviderProxy;
033: import org.apache.jetspeed.security.Role;
034: import org.apache.jetspeed.security.RoleManager;
035: import org.apache.jetspeed.security.RolePrincipal;
036: import org.apache.jetspeed.security.SecurityException;
037: import org.apache.jetspeed.security.SecurityProvider;
038: import org.apache.jetspeed.security.spi.RoleSecurityHandler;
039: import org.apache.jetspeed.security.spi.SecurityMappingHandler;
040: import org.apache.jetspeed.util.ArgUtil;
041:
042: /**
043: * <p>
044: * Implementation for managing roles.
045: * </p>
046: * <p>
047: * Role hierarchy elements are being returned as a {@link Role}collection. The
048: * backing implementation must appropriately map the role hierarchy to a
049: * preferences sub-tree.
050: * </p>
051: * <p>
052: * The convention {principal}.{subprincipal} has been chosen to name roles
053: * hierachies in order to support declarative security. Implementation follow
054: * the conventions enforced by the {@link Preferences}API.
055: * </p>
056: *
057: * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
058: * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
059: */
060: public class RoleManagerImpl implements RoleManager {
061: /** The logger. */
062: private static final Log log = LogFactory
063: .getLog(RoleManagerImpl.class);
064:
065: /** The authentication provider proxy. */
066: private AuthenticationProviderProxy atnProviderProxy = null;
067:
068: /** The role security handler. */
069: private RoleSecurityHandler roleSecurityHandler = null;
070:
071: /** The security mapping handler. */
072: private SecurityMappingHandler securityMappingHandler = null;
073:
074: /**
075: * @param securityProvider The security provider.
076: */
077: public RoleManagerImpl(SecurityProvider securityProvider) {
078: this .atnProviderProxy = securityProvider
079: .getAuthenticationProviderProxy();
080: this .roleSecurityHandler = securityProvider
081: .getRoleSecurityHandler();
082: this .securityMappingHandler = securityProvider
083: .getSecurityMappingHandler();
084: }
085:
086: /**
087: * @see org.apache.jetspeed.security.RoleManager#addRole(java.lang.String)
088: */
089: public void addRole(String roleFullPathName)
090: throws SecurityException {
091: ArgUtil.notNull(new Object[] { roleFullPathName },
092: new String[] { "roleFullPathName" },
093: "addRole(java.lang.String)");
094:
095: // Check if role already exists.
096: if (roleExists(roleFullPathName)) {
097: throw new SecurityException(
098: SecurityException.ROLE_ALREADY_EXISTS
099: .create(roleFullPathName));
100: }
101:
102: RolePrincipal rolePrincipal = new RolePrincipalImpl(
103: roleFullPathName);
104: String fullPath = rolePrincipal.getFullPath();
105: // Add the preferences.
106: Preferences preferences = Preferences.userRoot().node(fullPath);
107: if (log.isDebugEnabled()) {
108: log.debug("Added role preferences node: " + fullPath);
109: }
110: try {
111: if ((null != preferences)
112: && preferences.absolutePath().equals(fullPath)) {
113: // Add role principal.
114: roleSecurityHandler.setRolePrincipal(rolePrincipal);
115: if (log.isDebugEnabled()) {
116: log.debug("Added role: " + fullPath);
117: }
118: }
119: } catch (SecurityException se) {
120: KeyedMessage msg = SecurityException.UNEXPECTED.create(
121: "RoleManager.addRole",
122: "RoleSecurityHandler.setRolePrincipal("
123: + rolePrincipal.getName() + ")", se
124: .getMessage());
125: log.error(msg, se);
126:
127: // Remove the preferences node.
128: try {
129: preferences.removeNode();
130: } catch (BackingStoreException bse) {
131: bse.printStackTrace();
132: }
133: throw new SecurityException(msg, se);
134: }
135: }
136:
137: /**
138: * @see org.apache.jetspeed.security.RoleManager#removeRole(java.lang.String)
139: */
140: public void removeRole(String roleFullPathName)
141: throws SecurityException {
142: ArgUtil.notNull(new Object[] { roleFullPathName },
143: new String[] { "roleFullPathName" },
144: "removeRole(java.lang.String)");
145:
146: // Resolve the role hierarchy.
147: Preferences prefs = Preferences
148: .userRoot()
149: .node(
150: RolePrincipalImpl
151: .getFullPathFromPrincipalName(roleFullPathName));
152: String[] roles = securityMappingHandler
153: .getRoleHierarchyResolver().resolveChildren(prefs);
154: for (int i = 0; i < roles.length; i++) {
155: try {
156: roleSecurityHandler
157: .removeRolePrincipal(new RolePrincipalImpl(
158: RolePrincipalImpl
159: .getPrincipalNameFromFullPath(roles[i])));
160: } catch (Exception e) {
161: KeyedMessage msg = SecurityException.UNEXPECTED
162: .create(
163: "RoleManager.removeRole",
164: "RoleSecurityHandler.removeRolePrincipal("
165: + RolePrincipalImpl
166: .getPrincipalNameFromFullPath(roles[i])
167: + ")", e.getMessage());
168: log.error(msg, e);
169: throw new SecurityException(msg, e);
170: }
171: // Remove preferences
172: Preferences rolePref = Preferences.userRoot()
173: .node(roles[i]);
174: try {
175: rolePref.removeNode();
176: } catch (BackingStoreException bse) {
177: KeyedMessage msg = SecurityException.UNEXPECTED.create(
178: "RoleManager.removeRole",
179: "Preferences.removeNode(" + roles[i] + ")", bse
180: .getMessage());
181: log.error(msg, bse);
182: throw new SecurityException(msg, bse);
183: }
184: }
185: }
186:
187: /**
188: * @see org.apache.jetspeed.security.RoleManager#roleExists(java.lang.String)
189: */
190: public boolean roleExists(String roleFullPathName) {
191: ArgUtil.notNull(new Object[] { roleFullPathName },
192: new String[] { "roleFullPathName" },
193: "roleExists(java.lang.String)");
194:
195: Principal principal = roleSecurityHandler
196: .getRolePrincipal(roleFullPathName);
197: boolean roleExists = (null != principal);
198: if (log.isDebugEnabled()) {
199: log.debug("Role exists: " + roleExists);
200: log.debug("Role: " + roleFullPathName);
201: }
202: return roleExists;
203: }
204:
205: /**
206: * @see org.apache.jetspeed.security.RoleManager#getRole(java.lang.String)
207: */
208: public Role getRole(String roleFullPathName)
209: throws SecurityException {
210: ArgUtil.notNull(new Object[] { roleFullPathName },
211: new String[] { "roleFullPathName" },
212: "getRole(java.lang.String)");
213:
214: String fullPath = RolePrincipalImpl
215: .getFullPathFromPrincipalName(roleFullPathName);
216:
217: Principal rolePrincipal = roleSecurityHandler
218: .getRolePrincipal(roleFullPathName);
219: if (null == rolePrincipal) {
220: throw new SecurityException(
221: SecurityException.ROLE_DOES_NOT_EXIST
222: .create(roleFullPathName));
223: }
224: Preferences preferences = Preferences.userRoot().node(fullPath);
225: Role role = new RoleImpl(rolePrincipal, preferences);
226: return role;
227: }
228:
229: /**
230: * @see org.apache.jetspeed.security.RoleManager#getRolesForUser(java.lang.String)
231: */
232: public Collection getRolesForUser(String username)
233: throws SecurityException {
234: ArgUtil.notNull(new Object[] { username },
235: new String[] { "username" },
236: "getRolesForUser(java.lang.String)");
237:
238: Collection roles = new ArrayList();
239:
240: Set rolePrincipals = securityMappingHandler
241: .getRolePrincipals(username);
242: Iterator rolePrincipalsIter = rolePrincipals.iterator();
243: while (rolePrincipalsIter.hasNext()) {
244: Principal rolePrincipal = (Principal) rolePrincipalsIter
245: .next();
246: Preferences preferences = Preferences.userRoot().node(
247: RolePrincipalImpl
248: .getFullPathFromPrincipalName(rolePrincipal
249: .getName()));
250: roles.add(new RoleImpl(rolePrincipal, preferences));
251: }
252: return roles;
253: }
254:
255: /**
256: * @see org.apache.jetspeed.security.RoleManager#getRolesInGroup(java.lang.String)
257: */
258: public Collection getRolesInGroup(String groupFullPathName)
259: throws SecurityException {
260: ArgUtil.notNull(new Object[] { groupFullPathName },
261: new String[] { "groupFullPathName" },
262: "getRolesInGroup(java.lang.String)");
263:
264: Collection roles = new ArrayList();
265:
266: Set rolePrincipals = securityMappingHandler
267: .getRolePrincipalsInGroup(groupFullPathName);
268: Iterator rolePrincipalsIter = rolePrincipals.iterator();
269: while (rolePrincipalsIter.hasNext()) {
270: Principal rolePrincipal = (Principal) rolePrincipalsIter
271: .next();
272: Preferences preferences = Preferences.userRoot().node(
273: RolePrincipalImpl
274: .getFullPathFromPrincipalName(rolePrincipal
275: .getName()));
276: roles.add(new RoleImpl(rolePrincipal, preferences));
277: }
278: return roles;
279: }
280:
281: /**
282: * @see org.apache.jetspeed.security.RoleManager#addRoleToUser(java.lang.String,
283: * java.lang.String)
284: */
285: public void addRoleToUser(String username, String roleFullPathName)
286: throws SecurityException {
287: ArgUtil.notNull(new Object[] { username, roleFullPathName },
288: new String[] { "username", "roleFullPathName" },
289: "addUserToRole(java.lang.String, java.lang.String)");
290:
291: // Get the role principal to add to user.
292: Principal rolePrincipal = roleSecurityHandler
293: .getRolePrincipal(roleFullPathName);
294: if (null == rolePrincipal) {
295: throw new SecurityException(
296: SecurityException.ROLE_DOES_NOT_EXIST
297: .create(roleFullPathName));
298: }
299: // Check that user exists.
300: Principal userPrincipal = atnProviderProxy
301: .getUserPrincipal(username);
302: if (null == userPrincipal) {
303: throw new SecurityException(
304: SecurityException.USER_DOES_NOT_EXIST
305: .create(username));
306: }
307: // Get the user roles.
308: Set rolePrincipals = securityMappingHandler
309: .getRolePrincipals(username);
310: // Add role to user.
311: if (!rolePrincipals.contains(rolePrincipal)) {
312: securityMappingHandler.setUserPrincipalInRole(username,
313: roleFullPathName);
314: }
315: }
316:
317: /**
318: * @see org.apache.jetspeed.security.RoleManager#removeRoleFromUser(java.lang.String,
319: * java.lang.String)
320: */
321: public void removeRoleFromUser(String username,
322: String roleFullPathName) throws SecurityException {
323: ArgUtil
324: .notNull(
325: new Object[] { username, roleFullPathName },
326: new String[] { "username", "roleFullPathName" },
327: "removeRoleFromUser(java.lang.String, java.lang.String)");
328:
329: // Check that user exists.
330: Principal userPrincipal = atnProviderProxy
331: .getUserPrincipal(username);
332: if (null == userPrincipal) {
333: throw new SecurityException(
334: SecurityException.USER_DOES_NOT_EXIST
335: .create(username));
336: }
337: // Get the role principal to remove.
338: Principal rolePrincipal = roleSecurityHandler
339: .getRolePrincipal(roleFullPathName);
340: if (null != rolePrincipal) {
341: securityMappingHandler.removeUserPrincipalInRole(username,
342: roleFullPathName);
343: }
344: }
345:
346: /**
347: * @see org.apache.jetspeed.security.RoleManager#isUserInRole(java.lang.String,
348: * java.lang.String)
349: */
350: public boolean isUserInRole(String username, String roleFullPathName)
351: throws SecurityException {
352: ArgUtil.notNull(new Object[] { username, roleFullPathName },
353: new String[] { "username", "roleFullPathName" },
354: "isUserInRole(java.lang.String, java.lang.String)");
355:
356: boolean isUserInRole = false;
357:
358: Set rolePrincipals = securityMappingHandler
359: .getRolePrincipals(username);
360: Principal rolePrincipal = new RolePrincipalImpl(
361: roleFullPathName);
362: if (rolePrincipals.contains(rolePrincipal)) {
363: isUserInRole = true;
364: }
365: return isUserInRole;
366: }
367:
368: /**
369: * @see org.apache.jetspeed.security.RoleManager#addRoleToGroup(java.lang.String,
370: * java.lang.String)
371: */
372: public void addRoleToGroup(String roleFullPathName,
373: String groupFullPathName) throws SecurityException {
374: ArgUtil.notNull(new Object[] { roleFullPathName,
375: groupFullPathName }, new String[] { "roleFullPathName",
376: "groupFullPathName" },
377: "addRoleToGroup(java.lang.String, java.lang.String)");
378:
379: // Get the role principal to add to group.
380: Principal rolePrincipal = roleSecurityHandler
381: .getRolePrincipal(roleFullPathName);
382: if (null == rolePrincipal) {
383: throw new SecurityException(
384: SecurityException.ROLE_DOES_NOT_EXIST
385: .create(roleFullPathName));
386: }
387: securityMappingHandler.setRolePrincipalInGroup(
388: groupFullPathName, roleFullPathName);
389: }
390:
391: /**
392: * @see org.apache.jetspeed.security.RoleManager#removeRoleFromGroup(java.lang.String,
393: * java.lang.String)
394: */
395: public void removeRoleFromGroup(String roleFullPathName,
396: String groupFullPathName) throws SecurityException {
397: ArgUtil
398: .notNull(new Object[] { roleFullPathName,
399: groupFullPathName }, new String[] {
400: "roleFullPathName", "groupFullPathName" },
401: "removeRoleFromGroup(java.lang.String, java.lang.String)");
402:
403: // Get the role principal to remove.
404: Principal rolePrincipal = roleSecurityHandler
405: .getRolePrincipal(roleFullPathName);
406: if (null != rolePrincipal) {
407: securityMappingHandler.removeRolePrincipalInGroup(
408: groupFullPathName, roleFullPathName);
409: }
410: }
411:
412: /**
413: * @see org.apache.jetspeed.security.RoleManager#isGroupInRole(java.lang.String,
414: * java.lang.String)
415: */
416: public boolean isGroupInRole(String groupFullPathName,
417: String roleFullPathName) throws SecurityException {
418: ArgUtil.notNull(new Object[] { roleFullPathName,
419: groupFullPathName }, new String[] { "roleFullPathName",
420: "groupFullPathName" },
421: "isGroupInRole(java.lang.String, java.lang.String)");
422:
423: boolean isGroupInRole = false;
424:
425: Set rolePrincipals = securityMappingHandler
426: .getRolePrincipalsInGroup(groupFullPathName);
427: Principal rolePrincipal = new RolePrincipalImpl(
428: roleFullPathName);
429: if (rolePrincipals.contains(rolePrincipal)) {
430: isGroupInRole = true;
431: }
432:
433: return isGroupInRole;
434: }
435:
436: /**
437: * @see org.apache.jetspeed.security.RoleManager#getRoles(java.lang.String)
438: */
439: public Iterator getRoles(String filter) throws SecurityException {
440: List roles = new LinkedList();
441: Iterator rolePrincipals = roleSecurityHandler
442: .getRolePrincipals(filter).iterator();
443: while (rolePrincipals.hasNext()) {
444: String roleName = ((Principal) rolePrincipals.next())
445: .getName();
446: Role role = getRole(roleName);
447: roles.add(role);
448: }
449: return roles.iterator();
450: }
451:
452: /**
453: * @see org.apache.jetspeed.security.RoleManager#setRoleEnabled(java.lang.String, boolean)
454: */
455: public void setRoleEnabled(String roleFullPathName, boolean enabled)
456: throws SecurityException {
457: ArgUtil.notNull(new Object[] { roleFullPathName },
458: new String[] { "roleFullPathName" },
459: "setRoleEnabled(java.lang.String,boolean)");
460:
461: RolePrincipalImpl rolePrincipal = (RolePrincipalImpl) roleSecurityHandler
462: .getRolePrincipal(roleFullPathName);
463: if (null == rolePrincipal) {
464: throw new SecurityException(
465: SecurityException.ROLE_DOES_NOT_EXIST
466: .create(roleFullPathName));
467: }
468: if (enabled != rolePrincipal.isEnabled()) {
469: rolePrincipal.setEnabled(enabled);
470: roleSecurityHandler.setRolePrincipal(rolePrincipal);
471: }
472: }
473: }
|