1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.jetspeed.om.page.psml;
19
20 import java.security.AccessController;
21 import java.security.Principal;
22 import java.util.ArrayList;
23 import java.util.Iterator;
24 import java.util.LinkedList;
25 import java.util.List;
26
27 import javax.security.auth.Subject;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.jetspeed.JetspeedActions;
32 import org.apache.jetspeed.om.common.SecuredResource;
33 import org.apache.jetspeed.om.common.SecurityConstraint;
34 import org.apache.jetspeed.om.common.SecurityConstraints;
35 import org.apache.jetspeed.om.page.BaseElement;
36 import org.apache.jetspeed.om.page.PageSecurity;
37 import org.apache.jetspeed.om.page.SecurityConstraintImpl;
38 import org.apache.jetspeed.page.document.DocumentHandlerFactory;
39 import org.apache.jetspeed.page.document.Node;
40 import org.apache.jetspeed.page.document.NodeSet;
41 import org.apache.jetspeed.page.document.psml.NodeSetImpl;
42 import org.apache.jetspeed.security.FolderPermission;
43 import org.apache.jetspeed.security.GroupPrincipal;
44 import org.apache.jetspeed.security.JSSubject;
45 import org.apache.jetspeed.security.PagePermission;
46 import org.apache.jetspeed.security.PortalResourcePermission;
47 import org.apache.jetspeed.security.RolePrincipal;
48 import org.apache.jetspeed.security.UserPrincipal;
49
50
51 /***
52 *
53 * @version $Id: AbstractBaseElement.java 516448 2007-03-09 16:25:47Z ate $
54 */
55 public abstract class AbstractBaseElement implements java.io.Serializable, SecuredResource
56 {
57 private final static Log log = LogFactory.getLog(AbstractBaseElement.class);
58
59 private String id = null;
60
61 private String title = null;
62
63 private String shortTitle = null;
64
65 private boolean constraintsEnabled;
66
67 private SecurityConstraints constraints = null;
68
69 private boolean permissionsEnabled;
70
71 private DocumentHandlerFactory handlerFactory = null;
72
73 public String getId()
74 {
75 return this.id;
76 }
77
78 public void setId(String id)
79 {
80 this.id = id;
81 }
82
83 /***
84 * <p>
85 * getTitle
86 * </p>
87 *
88 * @see org.apache.jetspeed.om.page.BaseElement#getTitle()
89 * @return
90 */
91 public String getTitle()
92 {
93 return this.title;
94 }
95
96 /***
97 * <p>
98 * setTitle
99 * </p>
100 *
101 * @see org.apache.jetspeed.om.page.BaseElement#setTitle(java.lang.String)
102 * @param title
103 */
104 public void setTitle(String title)
105 {
106 this.title = title;
107 }
108 /***
109 * <p>
110 * getShortTitle
111 * </p>
112 *
113 * @see org.apache.jetspeed.om.page.BaseElement#getShortTitle()
114 * @return short title
115 */
116 public String getShortTitle()
117 {
118
119 String title = this.shortTitle;
120 if (title == null)
121 {
122 title = this.title;
123 }
124 return title;
125 }
126 /***
127 * <p>
128 * setShortTitle
129 * </p>
130 *
131 * @see org.apache.jetspeed.om.page.BaseElement#setShortTitle(java.lang.String)
132 * @param title
133 */
134 public void setShortTitle(String title)
135 {
136 this.shortTitle = title;
137 }
138
139 /***
140 * <p>
141 * getConstraintsEnabled
142 * </p>
143 *
144 * @see org.apache.jetspeed.om.common.SecureResource#getConstraintsEnabled()
145 * @return whether security relies on PSML constraints
146 */
147 public boolean getConstraintsEnabled()
148 {
149 return constraintsEnabled;
150 }
151
152 /***
153 * <p>
154 * setConstraintsEnabled
155 * </p>
156 *
157 * @param enabled indicator
158 */
159 public void setConstraintsEnabled(boolean enabled)
160 {
161 constraintsEnabled = enabled;
162 }
163
164 /***
165 * <p>
166 * getSecurityConstraints
167 * </p>
168 *
169 * @see org.apache.jetspeed.om.common.SecureResource#getSecurityConstraints()
170 * @return the PSML security constraints
171 */
172 public SecurityConstraints getSecurityConstraints()
173 {
174 return constraints;
175 }
176
177 /***
178 * <p>
179 * newSecurityConstraints
180 * </p>
181 *
182 * @see org.apache.jetspeed.om.common.SecureResource#newSecurityConstraints()
183 * @return a new security constraints object
184 */
185 public SecurityConstraints newSecurityConstraints()
186 {
187 return new SecurityConstraintsImpl();
188 }
189
190 /***
191 * <p>
192 * newSecurityConstraint
193 * </p>
194 *
195 * @see org.apache.jetspeed.om.common.SecureResource#newSecurityConstraint()
196 * @return security constraint
197 */
198 public SecurityConstraint newSecurityConstraint()
199 {
200 return new SecurityConstraintImpl();
201 }
202
203 /***
204 * <p>
205 * setSecurityConstraints
206 * </p>
207 *
208 * @see org.apache.jetspeed.om.common.SecureResource#setSecurityConstraints(org.apache.jetspeed.om.common.SecurityConstraints)
209 * @param constraints
210 */
211 public void setSecurityConstraints(SecurityConstraints constraints)
212 {
213 this.constraints = constraints;
214 }
215
216 /***
217 * <p>
218 * checkConstraints
219 * </p>
220 *
221 * @see org.apache.jetspeed.om.common.SecureResource#checkConstraints(java.lang.String)
222 * @param actions
223 * @throws SecurityException
224 */
225 public void checkConstraints(String actions) throws SecurityException
226 {
227
228 if (!getConstraintsEnabled())
229 {
230 return;
231 }
232
233
234 if (actions == null)
235 {
236 throw new SecurityException("AbstractBaseElement.checkConstraints(): No actions specified.");
237 }
238
239
240
241 List viewActionList = SecurityConstraintImpl.parseCSVList(actions);
242 List otherActionsList = null;
243 if (viewActionList.size() == 1)
244 {
245 if (!viewActionList.contains(JetspeedActions.VIEW))
246 {
247 otherActionsList = viewActionList;
248 viewActionList = null;
249 }
250 }
251 else
252 {
253 otherActionsList = viewActionList;
254 viewActionList = null;
255 if (otherActionsList.remove(JetspeedActions.VIEW))
256 {
257 viewActionList = new ArrayList(1);
258 viewActionList.add(JetspeedActions.VIEW);
259 }
260 }
261
262
263 Subject subject = JSSubject.getSubject(AccessController.getContext());
264 if (subject == null)
265 {
266 throw new SecurityException("AbstractBaseElement.checkConstraints(): Missing JSSubject");
267 }
268
269
270 List userPrincipals = null;
271 List rolePrincipals = null;
272 List groupPrincipals = null;
273 Iterator principals = subject.getPrincipals().iterator();
274 while (principals.hasNext())
275 {
276 Principal principal = (Principal) principals.next();
277 if (principal instanceof UserPrincipal)
278 {
279 if (userPrincipals == null)
280 {
281 userPrincipals = new LinkedList();
282 }
283 userPrincipals.add(principal.getName());
284 }
285 else if (principal instanceof RolePrincipal)
286 {
287 if (rolePrincipals == null)
288 {
289 rolePrincipals = new LinkedList();
290 }
291 rolePrincipals.add(principal.getName());
292 }
293 else if (principal instanceof GroupPrincipal)
294 {
295 if (groupPrincipals == null)
296 {
297 groupPrincipals = new LinkedList();
298 }
299 groupPrincipals.add(principal.getName());
300 }
301 }
302
303
304 if (viewActionList != null)
305 {
306 checkConstraints(viewActionList, userPrincipals, rolePrincipals, groupPrincipals, false, grantViewActionAccess());
307 }
308 if (otherActionsList != null)
309 {
310 checkConstraints(otherActionsList, userPrincipals, rolePrincipals, groupPrincipals, true, false);
311 }
312 }
313
314 /***
315 * <p>
316 * checkConstraints
317 * </p>
318 *
319 * @param actions
320 * @param userPrincipals
321 * @param rolePrincipals
322 * @param groupPrincipals
323 * @param checkNodeOnly
324 * @param checkParentsOnly
325 * @throws SecurityException
326 */
327 public void checkConstraints(List actions, List userPrincipals, List rolePrincipals, List groupPrincipals, boolean checkNodeOnly, boolean checkParentsOnly) throws SecurityException
328 {
329
330 if ((constraints != null) && !constraints.isEmpty())
331 {
332 ((SecurityConstraintsImpl)constraints).checkConstraints(actions, userPrincipals, rolePrincipals, groupPrincipals, getEffectivePageSecurity());
333 }
334 }
335
336 /***
337 * <p>
338 * getPermissionsEnabled
339 * </p>
340 *
341 * @see org.apache.jetspeed.om.common.SecureResource#getPermissionsEnabled()
342 * @return
343 */
344 public boolean getPermissionsEnabled()
345 {
346 return permissionsEnabled;
347 }
348
349 /***
350 * <p>
351 * setPermissionsEnabled
352 * </p>
353 *
354 * @param enabled indicator
355 */
356 public void setPermissionsEnabled(boolean enabled)
357 {
358 permissionsEnabled = enabled;
359 }
360
361 /***
362 * <p>
363 * checkPermissions
364 * </p>
365 *
366 * @see org.apache.jetspeed.om.common.SecuredResource#checkPermissions(int)
367 * @param mask Mask of actions requested
368 * @throws SecurityException
369 */
370 public void checkPermissions(int mask) throws SecurityException
371 {
372
373 if (!getPermissionsEnabled())
374 {
375 return;
376 }
377
378
379 boolean viewAction = (mask & JetspeedActions.MASK_VIEW) == JetspeedActions.MASK_VIEW;
380 int otherMask = mask & ~JetspeedActions.MASK_VIEW;
381
382
383 if (viewAction)
384 {
385 checkPermissions(JetspeedActions.MASK_VIEW, false, grantViewActionAccess());
386 }
387 if (otherMask != 0)
388 {
389 checkPermissions(otherMask, true, false);
390 }
391 }
392 /***
393 * <p>
394 * checkPermissions
395 * </p>
396 *
397 * @param mask of actions
398 * @param checkNodeOnly
399 * @param checkParentsOnly
400 * @throws SecurityException
401 */
402 public void checkPermissions(int mask, boolean checkNodeOnly, boolean checkParentsOnly) throws SecurityException
403 {
404
405 String physicalPermissionPath = getPhysicalPermissionPath();
406 if (physicalPermissionPath != null)
407 {
408
409 try
410 {
411 checkPermissions(physicalPermissionPath, mask, checkNodeOnly, checkParentsOnly);
412 }
413 catch (SecurityException physicalSE)
414 {
415
416 String logicalPermissionPath = getLogicalPermissionPath();
417 if ((logicalPermissionPath != null) && !logicalPermissionPath.equals(physicalPermissionPath))
418 {
419 checkPermissions(logicalPermissionPath, mask, checkNodeOnly, checkParentsOnly);
420 }
421 else
422 {
423 throw physicalSE;
424 }
425 }
426 }
427 }
428 /***
429 * <p>
430 * checkPermissions
431 * </p>
432 *
433 * @param path
434 * @param mask Mask of actions requested
435 * @param checkNodeOnly
436 * @param checkParentsOnly
437 * @throws SecurityException
438 */
439 public void checkPermissions(String path, int mask, boolean checkNodeOnly, boolean checkParentsOnly) throws SecurityException
440 {
441
442 try
443 {
444
445 PagePermission permission = new PagePermission(path, mask);
446 AccessController.checkPermission(permission);
447 }
448 catch (SecurityException se)
449 {
450
451 FolderPermission permission = new FolderPermission(path, mask);
452 AccessController.checkPermission(permission);
453 }
454 }
455
456 /***
457 * <p>
458 * getLogicalPermissionPath
459 * </p>
460 *
461 * @return path used for permissions checks
462 */
463 public String getLogicalPermissionPath()
464 {
465 return getPhysicalPermissionPath();
466 }
467
468 /***
469 * <p>
470 * getPhysicalPermissionPath
471 * </p>
472 *
473 * @return path used for permissions checks
474 */
475 public String getPhysicalPermissionPath()
476 {
477
478 log.warn("getPhysicalPermissionPath(): no permission path available for " + this + " element.");
479 return null;
480 }
481
482 /***
483 * <p>
484 * checkAccess
485 * </p>
486 *
487 * @see org.apache.jetspeed.om.common.SecureResource#checkAccess(java.lang.String)
488 * @param actions
489 * @throws SecurityException
490 */
491 public void checkAccess(String actions) throws SecurityException
492 {
493
494 if (getPermissionsEnabled())
495 {
496 int mask = PortalResourcePermission.parseActions(actions);
497 checkPermissions(mask);
498 }
499 if (getConstraintsEnabled())
500 {
501 checkConstraints(actions);
502 }
503 }
504
505 /***
506 * <p>
507 * grantViewActionAccess
508 * </p>
509 *
510 * @return granted access for view action
511 */
512 public boolean grantViewActionAccess()
513 {
514
515 return false;
516 }
517
518 /***
519 * getEffectivePageSecurity
520 *
521 * @return effective page security object
522 */
523 public PageSecurity getEffectivePageSecurity()
524 {
525
526 return null;
527 }
528
529 /***
530 * <p>
531 * getHandlerFactory
532 * </p>
533 *
534 * @return element handler factory
535 */
536 public DocumentHandlerFactory getHandlerFactory()
537 {
538 return handlerFactory;
539 }
540
541 /***
542 * <p>
543 * setHandlerFactory
544 * </p>
545 *
546 * @param factory element handler factory
547 */
548 public void setHandlerFactory(DocumentHandlerFactory factory)
549 {
550 this.handlerFactory = factory;
551 }
552
553 /***
554 * <p>
555 * equals
556 * </p>
557 *
558 * @see java.lang.Object#equals(java.lang.Object)
559 * @param obj
560 * @return whether the supplied object equals this one
561 */
562 public boolean equals( Object obj )
563 {
564 if(obj instanceof BaseElement)
565 {
566 AbstractBaseElement element = (AbstractBaseElement) obj;
567 return id != null && element.getId() != null && id.equals(element.getId());
568 }
569 else
570 {
571 return false;
572 }
573 }
574
575 /***
576 * <p>
577 * hashCode
578 * </p>
579 *
580 * @see java.lang.Object#hashCode()
581 * @return the hashcode for this object
582 */
583 public int hashCode()
584 {
585 return ((null != id) ? id.hashCode() : -1);
586 }
587
588 /***
589 * <p>
590 * toString
591 * </p>
592 *
593 * @see java.lang.Object#toString()
594 * @return the id as a string representation of this object
595 */
596 public String toString()
597 {
598 return getId();
599 }
600
601 /***
602 * <p>
603 * checkAccess returns a set of nodes we can access. It may be the passed in node set or a partial copy.
604 * </p>
605 *
606 * @param nodes
607 * @param actions
608 * @return a NodeSet containing the nodes allowing access
609 */
610 public static NodeSet checkAccess(NodeSet nodes, String actions)
611 {
612 if ((nodes != null) && !nodes.isEmpty())
613 {
614
615 NodeSetImpl filteredNodes = null;
616 Iterator checkAccessIter = nodes.iterator();
617 while (checkAccessIter.hasNext())
618 {
619 AbstractBaseElement node = (AbstractBaseElement)checkAccessIter.next();
620 try
621 {
622
623 node.checkAccess(actions);
624
625
626 if (filteredNodes != null)
627 {
628
629 filteredNodes.add((Node)node);
630 }
631 }
632 catch (SecurityException se)
633 {
634
635 if (filteredNodes == null)
636 {
637
638
639 filteredNodes = new NodeSetImpl(null, ((NodeSetImpl) nodes).getComparator());
640 Iterator copyIter = nodes.iterator();
641 while (copyIter.hasNext())
642 {
643 Node copyNode = (Node)copyIter.next();
644 if (copyNode != node)
645 {
646 filteredNodes.add(copyNode);
647 }
648 else
649 {
650 break;
651 }
652 }
653 }
654 }
655 }
656
657
658 if (filteredNodes != null)
659 {
660 return filteredNodes;
661 }
662 }
663 return nodes;
664 }
665
666 /***
667 * unmarshalled - notification that this instance has been
668 * loaded from the persistent store
669 */
670 public void unmarshalled()
671 {
672
673 }
674
675 /***
676 * marshalling - notification that this instance is to
677 * be saved to the persistent store
678 */
679 public void marshalling()
680 {
681
682 }
683 }