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.Group;
034: import org.apache.jetspeed.security.GroupManager;
035: import org.apache.jetspeed.security.GroupPrincipal;
036: import org.apache.jetspeed.security.SecurityException;
037: import org.apache.jetspeed.security.SecurityProvider;
038: import org.apache.jetspeed.security.spi.GroupSecurityHandler;
039: import org.apache.jetspeed.security.spi.SecurityMappingHandler;
040: import org.apache.jetspeed.util.ArgUtil;
041:
042: /**
043: * <p>
044: * Describes the service interface for managing groups.
045: * </p>
046: * <p>
047: * Group hierarchy elements are being returned as a {@link Group}collection.
048: * The backing implementation must appropriately map the group hierarchy to a
049: * preferences sub-tree.
050: * </p>
051: * <p>
052: * The convention {principal}.{subprincipal} has been chosen to name groups
053: * hierachies. Implementation follow the conventions enforced by the
054: * {@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 GroupManagerImpl implements GroupManager {
061:
062: /** The logger. */
063: private static final Log log = LogFactory
064: .getLog(GroupManagerImpl.class);
065:
066: /** The authentication provider proxy. */
067: private AuthenticationProviderProxy atnProviderProxy = null;
068:
069: /** The group security handler. */
070: private GroupSecurityHandler groupSecurityHandler = null;
071:
072: /** The security mapping handler. */
073: private SecurityMappingHandler securityMappingHandler = null;
074:
075: /**
076: * @param securityProvider
077: * The security provider.
078: */
079: public GroupManagerImpl(SecurityProvider securityProvider) {
080: this .atnProviderProxy = securityProvider
081: .getAuthenticationProviderProxy();
082: this .groupSecurityHandler = securityProvider
083: .getGroupSecurityHandler();
084: this .securityMappingHandler = securityProvider
085: .getSecurityMappingHandler();
086: }
087:
088: /**
089: * @see org.apache.jetspeed.security.GroupManager#addGroup(java.lang.String)
090: */
091: public void addGroup(String groupFullPathName)
092: throws SecurityException {
093: ArgUtil.notNull(new Object[] { groupFullPathName },
094: new String[] { "groupFullPathName" },
095: "addGroup(java.lang.String)");
096:
097: // Check if group already exists.
098: if (groupExists(groupFullPathName)) {
099: throw new SecurityException(
100: SecurityException.GROUP_ALREADY_EXISTS
101: .create(groupFullPathName));
102: }
103:
104: GroupPrincipal groupPrincipal = new GroupPrincipalImpl(
105: groupFullPathName);
106: String fullPath = groupPrincipal.getFullPath();
107: // Add the preferences.
108: Preferences preferences = Preferences.userRoot().node(fullPath);
109: if (log.isDebugEnabled()) {
110: log.debug("Added group preferences node: " + fullPath);
111: }
112: try {
113: if ((null != preferences)
114: && preferences.absolutePath().equals(fullPath)) {
115: // Add role principal.
116: groupSecurityHandler.setGroupPrincipal(groupPrincipal);
117: if (log.isDebugEnabled()) {
118: log.debug("Added group: " + fullPath);
119: }
120: }
121: } catch (SecurityException se) {
122: String msg = "Unable to create the role.";
123: log.error(msg, se);
124:
125: // Remove the preferences node.
126: try {
127: preferences.removeNode();
128: } catch (BackingStoreException bse) {
129: bse.printStackTrace();
130: }
131: throw se;
132: }
133: }
134:
135: /**
136: * @see org.apache.jetspeed.security.GroupManager#removeGroup(java.lang.String)
137: */
138: public void removeGroup(String groupFullPathName)
139: throws SecurityException {
140: ArgUtil.notNull(new Object[] { groupFullPathName },
141: new String[] { "groupFullPathName" },
142: "removeGroup(java.lang.String)");
143:
144: // Resolve the group hierarchy.
145: Preferences prefs = Preferences
146: .userRoot()
147: .node(
148: GroupPrincipalImpl
149: .getFullPathFromPrincipalName(groupFullPathName));
150: String[] groups = securityMappingHandler
151: .getGroupHierarchyResolver().resolveChildren(prefs);
152: for (int i = 0; i < groups.length; i++) {
153: try {
154: groupSecurityHandler
155: .removeGroupPrincipal(new GroupPrincipalImpl(
156: GroupPrincipalImpl
157: .getPrincipalNameFromFullPath(groups[i])));
158: } catch (SecurityException se) {
159: throw se;
160: } catch (Exception e) {
161: KeyedMessage msg = SecurityException.UNEXPECTED
162: .create(
163: "GroupManager.removeGroup",
164: "GroupSecurityHandler.removeGroupPrincipal("
165: + GroupPrincipalImpl
166: .getPrincipalNameFromFullPath(groups[i])
167: + ")", e.getMessage());
168: log.error(msg, e);
169: throw new SecurityException(msg, e);
170: }
171: // Remove preferences
172: Preferences groupPref = Preferences.userRoot().node(
173: groups[i]);
174: try {
175: groupPref.removeNode();
176: } catch (BackingStoreException bse) {
177: KeyedMessage msg = SecurityException.UNEXPECTED.create(
178: "Preferences.removeNode(" + groups[i] + ")",
179: bse.getMessage());
180: log.error(msg, bse);
181: throw new SecurityException(msg, bse);
182: }
183: }
184: }
185:
186: /**
187: * @see org.apache.jetspeed.security.GroupManager#groupExists(java.lang.String)
188: */
189: public boolean groupExists(String groupFullPathName) {
190: ArgUtil.notNull(new Object[] { groupFullPathName },
191: new String[] { "groupFullPathName" },
192: "groupExists(java.lang.String)");
193:
194: Principal principal = groupSecurityHandler
195: .getGroupPrincipal(groupFullPathName);
196: boolean groupExists = (null != principal);
197: if (log.isDebugEnabled()) {
198: log.debug("Role exists: " + groupExists);
199: log.debug("Role: " + groupFullPathName);
200: }
201: return groupExists;
202: }
203:
204: /**
205: * @see org.apache.jetspeed.security.GroupManager#getGroup(java.lang.String)
206: */
207: public Group getGroup(String groupFullPathName)
208: throws SecurityException {
209: ArgUtil.notNull(new Object[] { groupFullPathName },
210: new String[] { "groupFullPathName" },
211: "getGroup(java.lang.String)");
212:
213: String fullPath = GroupPrincipalImpl
214: .getFullPathFromPrincipalName(groupFullPathName);
215:
216: Principal groupPrincipal = groupSecurityHandler
217: .getGroupPrincipal(groupFullPathName);
218: if (null == groupPrincipal) {
219: throw new SecurityException(
220: SecurityException.GROUP_DOES_NOT_EXIST
221: .create(groupFullPathName));
222: }
223: Preferences preferences = Preferences.userRoot().node(fullPath);
224: Group group = new GroupImpl(groupPrincipal, preferences);
225: return group;
226: }
227:
228: /**
229: * @see org.apache.jetspeed.security.GroupManager#getGroupsForUser(java.lang.String)
230: */
231: public Collection getGroupsForUser(String username)
232: throws SecurityException {
233: ArgUtil.notNull(new Object[] { username },
234: new String[] { "username" },
235: "getGroupsForUser(java.lang.String)");
236:
237: Collection groups = new ArrayList();
238:
239: Set groupPrincipals = securityMappingHandler
240: .getGroupPrincipals(username);
241: Iterator groupPrincipalsIter = groupPrincipals.iterator();
242: while (groupPrincipalsIter.hasNext()) {
243: Principal groupPrincipal = (Principal) groupPrincipalsIter
244: .next();
245: Preferences preferences = Preferences
246: .userRoot()
247: .node(
248: GroupPrincipalImpl
249: .getFullPathFromPrincipalName(groupPrincipal
250: .getName()));
251: groups.add(new GroupImpl(groupPrincipal, preferences));
252: }
253: return groups;
254: }
255:
256: /**
257: * @see org.apache.jetspeed.security.GroupManager#getGroupsInRole(java.lang.String)
258: */
259: public Collection getGroupsInRole(String roleFullPathName)
260: throws SecurityException {
261: ArgUtil.notNull(new Object[] { roleFullPathName },
262: new String[] { "roleFullPathName" },
263: "getGroupsInRole(java.lang.String)");
264:
265: Collection groups = new ArrayList();
266:
267: Set groupPrincipals = securityMappingHandler
268: .getGroupPrincipalsInRole(roleFullPathName);
269: Iterator groupPrincipalsIter = groupPrincipals.iterator();
270: while (groupPrincipalsIter.hasNext()) {
271: Principal groupPrincipal = (Principal) groupPrincipalsIter
272: .next();
273: Preferences preferences = Preferences
274: .userRoot()
275: .node(
276: GroupPrincipalImpl
277: .getFullPathFromPrincipalName(groupPrincipal
278: .getName()));
279: groups.add(new GroupImpl(groupPrincipal, preferences));
280: }
281: return groups;
282: }
283:
284: /**
285: * @see org.apache.jetspeed.security.GroupManager#addUserToGroup(java.lang.String,
286: * java.lang.String)
287: */
288: public void addUserToGroup(String username, String groupFullPathName)
289: throws SecurityException {
290: ArgUtil.notNull(new Object[] { username, groupFullPathName },
291: new String[] { "username", "groupFullPathName" },
292: "addUserToGroup(java.lang.String, java.lang.String)");
293:
294: // Get the group principal to add to user.
295: GroupPrincipal groupPrincipal = groupSecurityHandler
296: .getGroupPrincipal(groupFullPathName);
297: if (null == groupPrincipal) {
298: throw new SecurityException(
299: SecurityException.GROUP_DOES_NOT_EXIST
300: .create(groupFullPathName));
301: }
302: // Check that user exists.
303: Principal userPrincipal = atnProviderProxy
304: .getUserPrincipal(username);
305: if (null == userPrincipal) {
306: throw new SecurityException(
307: SecurityException.USER_DOES_NOT_EXIST
308: .create(username));
309: }
310: // Get the user groups.
311: Set groupPrincipals = securityMappingHandler
312: .getGroupPrincipals(username);
313: // Add group to user.
314: if (!groupPrincipals.contains(groupPrincipal)) {
315: securityMappingHandler.setUserPrincipalInGroup(username,
316: groupFullPathName);
317: }
318: }
319:
320: /**
321: * @see org.apache.jetspeed.security.GroupManager#removeUserFromGroup(java.lang.String,
322: * java.lang.String)
323: */
324: public void removeUserFromGroup(String username,
325: String groupFullPathName) throws SecurityException {
326: ArgUtil
327: .notNull(
328: new Object[] { username, groupFullPathName },
329: new String[] { "username", "groupFullPathName" },
330: "removeUserFromGroup(java.lang.String, java.lang.String)");
331:
332: // Check that user exists.
333: Principal userPrincipal = atnProviderProxy
334: .getUserPrincipal(username);
335: if (null == userPrincipal) {
336: throw new SecurityException(
337: SecurityException.USER_DOES_NOT_EXIST
338: .create(username));
339: }
340: // Get the group principal to remove.
341: Principal groupPrincipal = groupSecurityHandler
342: .getGroupPrincipal(groupFullPathName);
343: if (null != groupPrincipal) {
344: securityMappingHandler.removeUserPrincipalInGroup(username,
345: groupFullPathName);
346: }
347: }
348:
349: /**
350: * @see org.apache.jetspeed.security.GroupManager#isUserInGroup(java.lang.String,
351: * java.lang.String)
352: */
353: public boolean isUserInGroup(String username,
354: String groupFullPathName) throws SecurityException {
355: ArgUtil.notNull(new Object[] { username, groupFullPathName },
356: new String[] { "username", "groupFullPathName" },
357: "isUserInGroup(java.lang.String, java.lang.String)");
358:
359: boolean isUserInGroup = false;
360:
361: Set groupPrincipals = securityMappingHandler
362: .getGroupPrincipals(username);
363: Principal groupPrincipal = new GroupPrincipalImpl(
364: groupFullPathName);
365: if (groupPrincipals.contains(groupPrincipal)) {
366: isUserInGroup = true;
367: }
368: return isUserInGroup;
369: }
370:
371: /**
372: * @see org.apache.jetspeed.security.GroupManager#getGroups(java.lang.String)
373: */
374: public Iterator getGroups(String filter) throws SecurityException {
375: List groups = new LinkedList();
376: Iterator groupPrincipals = groupSecurityHandler
377: .getGroupPrincipals(filter).iterator();
378: while (groupPrincipals.hasNext()) {
379: String groupName = ((Principal) groupPrincipals.next())
380: .getName();
381: Group group = getGroup(groupName);
382: groups.add(group);
383: }
384: return groups.iterator();
385: }
386:
387: /**
388: * @see org.apache.jetspeed.security.GroupManager#setGroupEnabled(java.lang.String, boolean)
389: */
390: public void setGroupEnabled(String groupFullPathName,
391: boolean enabled) throws SecurityException {
392: ArgUtil.notNull(new Object[] { groupFullPathName },
393: new String[] { "groupFullPathName" },
394: "setGroupEnabled(java.lang.String,boolean)");
395:
396: GroupPrincipalImpl groupPrincipal = (GroupPrincipalImpl) groupSecurityHandler
397: .getGroupPrincipal(groupFullPathName);
398: if (null == groupPrincipal) {
399: throw new SecurityException(
400: SecurityException.GROUP_DOES_NOT_EXIST
401: .create(groupFullPathName));
402: }
403: if (enabled != groupPrincipal.isEnabled()) {
404: groupPrincipal.setEnabled(enabled);
405: groupSecurityHandler.setGroupPrincipal(groupPrincipal);
406: }
407: }
408: }
|