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.spi.impl;
018:
019: import java.security.Principal;
020: import java.util.Collection;
021: import java.util.HashSet;
022: import java.util.Iterator;
023: import java.util.Set;
024: import java.util.prefs.Preferences;
025:
026: import org.apache.jetspeed.security.HierarchyResolver;
027: import org.apache.jetspeed.security.SecurityException;
028: import org.apache.jetspeed.security.impl.GeneralizationHierarchyResolver;
029: import org.apache.jetspeed.security.impl.GroupPrincipalImpl;
030: import org.apache.jetspeed.security.impl.RolePrincipalImpl;
031: import org.apache.jetspeed.security.impl.UserPrincipalImpl;
032: import org.apache.jetspeed.security.om.InternalGroupPrincipal;
033: import org.apache.jetspeed.security.om.InternalRolePrincipal;
034: import org.apache.jetspeed.security.om.InternalUserPrincipal;
035: import org.apache.jetspeed.security.om.impl.InternalGroupPrincipalImpl;
036: import org.apache.jetspeed.security.om.impl.InternalUserPrincipalImpl;
037: import org.apache.jetspeed.security.spi.SecurityAccess;
038: import org.apache.jetspeed.security.spi.SecurityMappingHandler;
039:
040: /**
041: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler
042: * @author <a href="mailto:dlestrat@apache.org">David Le Strat </a>
043: */
044: public class DefaultSecurityMappingHandler implements
045: SecurityMappingHandler {
046:
047: /** The role hierarchy resolver. */
048: HierarchyResolver roleHierarchyResolver = new GeneralizationHierarchyResolver();
049:
050: /** The group hierarchy resolver. */
051: HierarchyResolver groupHierarchyResolver = new GeneralizationHierarchyResolver();
052:
053: /** Common queries. */
054: private SecurityAccess commonQueries = null;
055:
056: /**
057: * <p>
058: * Constructor providing access to the common queries.
059: * </p>
060: */
061: public DefaultSecurityMappingHandler(SecurityAccess commonQueries) {
062: this .commonQueries = commonQueries;
063: }
064:
065: /**
066: * <p>
067: * Constructor providing access to the common queries and hierarchy
068: * resolvers.
069: * </p>
070: */
071: public DefaultSecurityMappingHandler(SecurityAccess commonQueries,
072: HierarchyResolver roleHierarchyResolver,
073: HierarchyResolver groupHierarchyResolver) {
074: this .commonQueries = commonQueries;
075: if (null != roleHierarchyResolver) {
076: this .roleHierarchyResolver = roleHierarchyResolver;
077: }
078: if (null != groupHierarchyResolver) {
079: this .groupHierarchyResolver = groupHierarchyResolver;
080: }
081: }
082:
083: /**
084: * @return Returns the roleHierarchyResolver.
085: */
086: public HierarchyResolver getRoleHierarchyResolver() {
087: return roleHierarchyResolver;
088: }
089:
090: /**
091: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#setRoleHierarchyResolver(org.apache.jetspeed.security.HierarchyResolver)
092: */
093: public void setRoleHierarchyResolver(
094: HierarchyResolver roleHierarchyResolver) {
095: this .roleHierarchyResolver = roleHierarchyResolver;
096: }
097:
098: /**
099: * @return Returns the groupHierarchyResolver.
100: */
101: public HierarchyResolver getGroupHierarchyResolver() {
102: return groupHierarchyResolver;
103: }
104:
105: /**
106: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#setGroupHierarchyResolver(org.apache.jetspeed.security.HierarchyResolver)
107: */
108: public void setGroupHierarchyResolver(
109: HierarchyResolver groupHierarchyResolver) {
110: this .groupHierarchyResolver = groupHierarchyResolver;
111: }
112:
113: /**
114: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getRolePrincipals(java.lang.String)
115: */
116: public Set getRolePrincipals(String username) {
117: Set rolePrincipals = new HashSet();
118: InternalUserPrincipal internalUser = commonQueries
119: .getInternalUserPrincipal(username);
120: if (null != internalUser) {
121: Collection internalRoles = internalUser.getRolePrincipals();
122: if (null != internalRoles) {
123: Iterator internalRolesIter = internalRoles.iterator();
124: while (internalRolesIter.hasNext()) {
125: InternalRolePrincipal internalRole = (InternalRolePrincipal) internalRolesIter
126: .next();
127: Preferences preferences = Preferences.userRoot()
128: .node(internalRole.getFullPath());
129: String[] fullPaths = roleHierarchyResolver
130: .resolve(preferences);
131: for (int i = 0; i < fullPaths.length; i++) {
132: Principal rolePrincipal = new RolePrincipalImpl(
133: RolePrincipalImpl
134: .getPrincipalNameFromFullPath(fullPaths[i]));
135: if (!rolePrincipals.contains(rolePrincipal)) {
136: rolePrincipals.add(rolePrincipal);
137: }
138: }
139: }
140: }
141: }
142: return rolePrincipals;
143: }
144:
145: /**
146: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#setUserPrincipalInRole(java.lang.String,
147: * java.lang.String)
148: */
149: public void setUserPrincipalInRole(String username,
150: String roleFullPathName) throws SecurityException {
151: InternalUserPrincipal internalUser = commonQueries
152: .getInternalUserPrincipal(username);
153: boolean isMappingOnly = false;
154: if (null == internalUser) {
155: // This is a record for mapping only.
156: isMappingOnly = true;
157: internalUser = new InternalUserPrincipalImpl(
158: UserPrincipalImpl
159: .getFullPathFromPrincipalName(username));
160: }
161: Collection internalRoles = internalUser.getRolePrincipals();
162: // This should not be null. Check for null should be made by the caller.
163: InternalRolePrincipal internalRole = commonQueries
164: .getInternalRolePrincipal(RolePrincipalImpl
165: .getFullPathFromPrincipalName(roleFullPathName));
166: // Check anyway.
167: if (null == internalRole) {
168: throw new SecurityException(
169: SecurityException.ROLE_DOES_NOT_EXIST
170: .create(roleFullPathName));
171: }
172: internalRoles.add(internalRole);
173: internalUser.setRolePrincipals(internalRoles);
174: commonQueries.setInternalUserPrincipal(internalUser,
175: isMappingOnly);
176: }
177:
178: /**
179: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#removeUserPrincipalInRole(java.lang.String,
180: * java.lang.String)
181: */
182: public void removeUserPrincipalInRole(String username,
183: String roleFullPathName) throws SecurityException {
184: boolean isMappingOnly = false;
185: // Check is the record is used for mapping only.
186: InternalUserPrincipal internalUser = commonQueries
187: .getInternalUserPrincipal(username, false);
188: if (null == internalUser) {
189: internalUser = commonQueries.getInternalUserPrincipal(
190: username, true);
191: isMappingOnly = true;
192: }
193: if (null != internalUser) {
194: Collection internalRoles = internalUser.getRolePrincipals();
195: // This should not be null. Check for null should be made by the caller.
196: InternalRolePrincipal internalRole = commonQueries
197: .getInternalRolePrincipal(RolePrincipalImpl
198: .getFullPathFromPrincipalName(roleFullPathName));
199: // Check anyway.
200: if (null == internalRole) {
201: throw new SecurityException(
202: SecurityException.ROLE_DOES_NOT_EXIST
203: .create(roleFullPathName));
204: }
205: internalRoles.remove(internalRole);
206: // Remove dead mapping records. I.e. No mapping is associated with the specific record.
207: if (isMappingOnly && internalRoles.isEmpty()
208: && internalUser.getGroupPrincipals().isEmpty()
209: && internalUser.getPermissions().isEmpty()) {
210: commonQueries.removeInternalUserPrincipal(internalUser);
211: } else {
212: internalUser.setRolePrincipals(internalRoles);
213: commonQueries.setInternalUserPrincipal(internalUser,
214: isMappingOnly);
215: }
216: } else {
217: throw new SecurityException(
218: SecurityException.USER_DOES_NOT_EXIST
219: .create(username));
220: }
221: }
222:
223: /**
224: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getRolePrincipalsInGroup(java.lang.String)
225: */
226: public Set getRolePrincipalsInGroup(String groupFullPathName) {
227: Set rolePrincipals = new HashSet();
228:
229: Preferences preferences = Preferences
230: .userRoot()
231: .node(
232: GroupPrincipalImpl
233: .getFullPathFromPrincipalName(groupFullPathName));
234: String[] fullPaths = groupHierarchyResolver
235: .resolve(preferences);
236: for (int i = 0; i < fullPaths.length; i++) {
237: InternalGroupPrincipal internalGroup = commonQueries
238: .getInternalGroupPrincipal(fullPaths[i]);
239: if (null != internalGroup) {
240: Collection internalRoles = internalGroup
241: .getRolePrincipals();
242: if (null != internalRoles) {
243: Iterator internalRolesIter = internalRoles
244: .iterator();
245: while (internalRolesIter.hasNext()) {
246: InternalRolePrincipal internalRole = (InternalRolePrincipal) internalRolesIter
247: .next();
248: Principal rolePrincipal = new RolePrincipalImpl(
249: UserPrincipalImpl
250: .getPrincipalNameFromFullPath(internalRole
251: .getFullPath()));
252: if (!rolePrincipals.contains(rolePrincipal)) {
253: rolePrincipals.add(rolePrincipal);
254: }
255: }
256: }
257: }
258: }
259: return rolePrincipals;
260: }
261:
262: /**
263: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#setRolePrincipalInGroup(java.lang.String,
264: * java.lang.String)
265: */
266: public void setRolePrincipalInGroup(String groupFullPathName,
267: String roleFullPathName) throws SecurityException {
268: InternalGroupPrincipal internalGroup = commonQueries
269: .getInternalGroupPrincipal(GroupPrincipalImpl
270: .getFullPathFromPrincipalName(groupFullPathName));
271: boolean isMappingOnly = false;
272: if (null == internalGroup) {
273: // This is a record for mapping only.
274: isMappingOnly = true;
275: internalGroup = new InternalGroupPrincipalImpl(
276: groupFullPathName);
277: }
278: Collection internalRoles = internalGroup.getRolePrincipals();
279: InternalRolePrincipal internalRole = commonQueries
280: .getInternalRolePrincipal(RolePrincipalImpl
281: .getFullPathFromPrincipalName(roleFullPathName));
282: internalRoles.add(internalRole);
283: internalGroup.setRolePrincipals(internalRoles);
284: commonQueries.setInternalGroupPrincipal(internalGroup,
285: isMappingOnly);
286: }
287:
288: /**
289: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#removeRolePrincipalInGroup(java.lang.String,
290: * java.lang.String)
291: */
292: public void removeRolePrincipalInGroup(String groupFullPathName,
293: String roleFullPathName) throws SecurityException {
294: InternalGroupPrincipal internalGroup = commonQueries
295: .getInternalGroupPrincipal(GroupPrincipalImpl
296: .getFullPathFromPrincipalName(groupFullPathName));
297: boolean isMappingOnly = false;
298: if (null == internalGroup) {
299: // This is a record for mapping only.
300: isMappingOnly = true;
301: internalGroup = new InternalGroupPrincipalImpl(
302: groupFullPathName);
303: }
304: if (null == internalGroup) {
305: throw new SecurityException(
306: SecurityException.GROUP_DOES_NOT_EXIST
307: .create(internalGroup));
308: }
309: Collection internalRoles = internalGroup.getRolePrincipals();
310: InternalRolePrincipal internalRole = commonQueries
311: .getInternalRolePrincipal(RolePrincipalImpl
312: .getFullPathFromPrincipalName(roleFullPathName));
313: internalRoles.remove(internalRole);
314: internalGroup.setRolePrincipals(internalRoles);
315: commonQueries.setInternalGroupPrincipal(internalGroup,
316: isMappingOnly);
317: }
318:
319: /**
320: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getGroupPrincipals(java.lang.String)
321: */
322: public Set getGroupPrincipals(String username) {
323: Set groupPrincipals = new HashSet();
324: InternalUserPrincipal internalUser = commonQueries
325: .getInternalUserPrincipal(username);
326: if (null != internalUser) {
327: Collection internalGroups = internalUser
328: .getGroupPrincipals();
329: if (null != internalGroups) {
330: Iterator internalGroupsIter = internalGroups.iterator();
331: while (internalGroupsIter.hasNext()) {
332: InternalGroupPrincipal internalGroup = (InternalGroupPrincipal) internalGroupsIter
333: .next();
334: Preferences preferences = Preferences.userRoot()
335: .node(internalGroup.getFullPath());
336: String[] fullPaths = groupHierarchyResolver
337: .resolve(preferences);
338: for (int i = 0; i < fullPaths.length; i++) {
339: groupPrincipals
340: .add(new GroupPrincipalImpl(
341: GroupPrincipalImpl
342: .getPrincipalNameFromFullPath(fullPaths[i])));
343: }
344: }
345: }
346: }
347: return groupPrincipals;
348: }
349:
350: /**
351: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getGroupPrincipalsInRole(java.lang.String)
352: */
353: public Set getGroupPrincipalsInRole(String roleFullPathName) {
354: Set groupPrincipals = new HashSet();
355:
356: Preferences preferences = Preferences
357: .userRoot()
358: .node(
359: RolePrincipalImpl
360: .getFullPathFromPrincipalName(roleFullPathName));
361: String[] fullPaths = roleHierarchyResolver.resolve(preferences);
362: for (int i = 0; i < fullPaths.length; i++) {
363: InternalRolePrincipal internalRole = commonQueries
364: .getInternalRolePrincipal(fullPaths[i]);
365: if (null != internalRole) {
366: Collection internalGroups = internalRole
367: .getGroupPrincipals();
368: if (null != internalGroups) {
369: Iterator internalGroupsIter = internalGroups
370: .iterator();
371: while (internalGroupsIter.hasNext()) {
372: InternalGroupPrincipal internalGroup = (InternalGroupPrincipal) internalGroupsIter
373: .next();
374: Principal groupPrincipal = new GroupPrincipalImpl(
375: GroupPrincipalImpl
376: .getPrincipalNameFromFullPath(internalGroup
377: .getFullPath()));
378: if (!groupPrincipals.contains(groupPrincipal)) {
379: groupPrincipals.add(groupPrincipal);
380: }
381: }
382: }
383: }
384: }
385: return groupPrincipals;
386: }
387:
388: /**
389: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getUserPrincipalsInRole(java.lang.String)
390: */
391: public Set getUserPrincipalsInRole(String roleFullPathName) {
392: Set userPrincipals = new HashSet();
393:
394: Preferences preferences = Preferences
395: .userRoot()
396: .node(
397: RolePrincipalImpl
398: .getFullPathFromPrincipalName(roleFullPathName));
399: String[] fullPaths = roleHierarchyResolver.resolve(preferences);
400: for (int i = 0; i < fullPaths.length; i++) {
401: InternalRolePrincipal internalRole = commonQueries
402: .getInternalRolePrincipal(fullPaths[i]);
403: if (null != internalRole) {
404: Collection internalUsers = internalRole
405: .getUserPrincipals();
406: if (null != internalUsers) {
407: Iterator internalUsersIter = internalUsers
408: .iterator();
409: while (internalUsersIter.hasNext()) {
410: InternalUserPrincipal internalUser = (InternalUserPrincipal) internalUsersIter
411: .next();
412: Principal userPrincipal = new UserPrincipalImpl(
413: UserPrincipalImpl
414: .getPrincipalNameFromFullPath(internalUser
415: .getFullPath()));
416: if (!userPrincipals.contains(userPrincipal)) {
417: userPrincipals.add(userPrincipal);
418: }
419: }
420: }
421: }
422: }
423: return userPrincipals;
424: }
425:
426: /**
427: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#getUserPrincipalsInGroup(java.lang.String)
428: */
429: public Set getUserPrincipalsInGroup(String groupFullPathName) {
430: Set userPrincipals = new HashSet();
431:
432: Preferences preferences = Preferences
433: .userRoot()
434: .node(
435: GroupPrincipalImpl
436: .getFullPathFromPrincipalName(groupFullPathName));
437: String[] fullPaths = groupHierarchyResolver
438: .resolve(preferences);
439: for (int i = 0; i < fullPaths.length; i++) {
440: InternalGroupPrincipal internalGroup = commonQueries
441: .getInternalGroupPrincipal(fullPaths[i]);
442: if (null != internalGroup) {
443: Collection internalUsers = internalGroup
444: .getUserPrincipals();
445: if (null != internalUsers) {
446: Iterator internalUsersIter = internalUsers
447: .iterator();
448: while (internalUsersIter.hasNext()) {
449: InternalUserPrincipal internalUser = (InternalUserPrincipal) internalUsersIter
450: .next();
451: Principal userPrincipal = new UserPrincipalImpl(
452: UserPrincipalImpl
453: .getPrincipalNameFromFullPath(internalUser
454: .getFullPath()));
455: if (!userPrincipals.contains(userPrincipal)) {
456: userPrincipals.add(userPrincipal);
457: }
458: }
459: }
460: }
461: }
462: return userPrincipals;
463: }
464:
465: /**
466: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#setUserPrincipalInGroup(java.lang.String,
467: * java.lang.String)
468: */
469: public void setUserPrincipalInGroup(String username,
470: String groupFullPathName) throws SecurityException {
471: InternalUserPrincipal internalUser = commonQueries
472: .getInternalUserPrincipal(username);
473: boolean isMappingOnly = false;
474: if (null == internalUser) {
475: // This is a record for mapping only.
476: isMappingOnly = true;
477: internalUser = new InternalUserPrincipalImpl(
478: UserPrincipalImpl
479: .getFullPathFromPrincipalName(username));
480: }
481: Collection internalGroups = internalUser.getGroupPrincipals();
482: // This should not be null. Check for null should be made by the caller.
483: InternalGroupPrincipal internalGroup = commonQueries
484: .getInternalGroupPrincipal(GroupPrincipalImpl
485: .getFullPathFromPrincipalName(groupFullPathName));
486: // Check anyway.
487: if (null == internalGroup) {
488: throw new SecurityException(
489: SecurityException.GROUP_DOES_NOT_EXIST
490: .create(groupFullPathName));
491: }
492: internalGroups.add(internalGroup);
493: internalUser.setGroupPrincipals(internalGroups);
494: commonQueries.setInternalUserPrincipal(internalUser,
495: isMappingOnly);
496: }
497:
498: /**
499: * @see org.apache.jetspeed.security.spi.SecurityMappingHandler#removeUserPrincipalInGroup(java.lang.String,
500: * java.lang.String)
501: */
502: public void removeUserPrincipalInGroup(String username,
503: String groupFullPathName) throws SecurityException {
504: boolean isMappingOnly = false;
505: // Check is the record is used for mapping only.
506: InternalUserPrincipal internalUser = commonQueries
507: .getInternalUserPrincipal(username, false);
508: if (null == internalUser) {
509: internalUser = commonQueries.getInternalUserPrincipal(
510: username, true);
511: isMappingOnly = true;
512: }
513: if (null != internalUser) {
514: Collection internalGroups = internalUser
515: .getGroupPrincipals();
516: // This should not be null. Check for null should be made by the caller.
517: InternalGroupPrincipal internalGroup = commonQueries
518: .getInternalGroupPrincipal(GroupPrincipalImpl
519: .getFullPathFromPrincipalName(groupFullPathName));
520: // Check anyway.
521: if (null == internalGroup) {
522: throw new SecurityException(
523: SecurityException.GROUP_DOES_NOT_EXIST
524: .create(groupFullPathName));
525: }
526: internalGroups.remove(internalGroup);
527: // Remove dead mapping records. I.e. No mapping is associated with the specific record.
528: if (isMappingOnly && internalGroups.isEmpty()
529: && internalUser.getRolePrincipals().isEmpty()
530: && internalUser.getPermissions().isEmpty()) {
531: commonQueries.removeInternalUserPrincipal(internalUser);
532: } else {
533: internalUser.setGroupPrincipals(internalGroups);
534: commonQueries.setInternalUserPrincipal(internalUser,
535: isMappingOnly);
536: }
537: } else {
538: throw new SecurityException(
539: SecurityException.USER_DOES_NOT_EXIST
540: .create(username));
541: }
542: }
543:
544: }
|