1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.taglibs.authz;
17
18 import org.acegisecurity.Authentication;
19
20 import org.acegisecurity.acl.AclEntry;
21 import org.acegisecurity.acl.AclManager;
22 import org.acegisecurity.acl.basic.BasicAclEntry;
23
24 import org.acegisecurity.context.SecurityContextHolder;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 import org.springframework.beans.factory.BeanFactoryUtils;
30
31 import org.springframework.context.ApplicationContext;
32
33 import org.springframework.web.context.support.WebApplicationContextUtils;
34 import org.springframework.web.util.ExpressionEvaluationUtils;
35
36 import java.util.HashSet;
37 import java.util.Set;
38 import java.util.StringTokenizer;
39
40 import javax.servlet.ServletContext;
41 import javax.servlet.jsp.JspException;
42 import javax.servlet.jsp.PageContext;
43 import javax.servlet.jsp.tagext.Tag;
44 import javax.servlet.jsp.tagext.TagSupport;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 public class AclTag extends TagSupport {
64
65
66 protected static final Log logger = LogFactory.getLog(AclTag.class);
67
68
69
70 private Object domainObject;
71 private String hasPermission = "";
72
73
74
75 public int doStartTag() throws JspException {
76 if ((null == hasPermission) || "".equals(hasPermission)) {
77 return Tag.SKIP_BODY;
78 }
79
80 final String evaledPermissionsString = ExpressionEvaluationUtils.evaluateString("hasPermission", hasPermission,
81 pageContext);
82
83 Integer[] requiredIntegers = null;
84
85 try {
86 requiredIntegers = parseIntegersString(evaledPermissionsString);
87 } catch (NumberFormatException nfe) {
88 throw new JspException(nfe);
89 }
90
91 Object resolvedDomainObject = null;
92
93 if (domainObject instanceof String) {
94 resolvedDomainObject = ExpressionEvaluationUtils.evaluate("domainObject", (String) domainObject,
95 Object.class, pageContext);
96 } else {
97 resolvedDomainObject = domainObject;
98 }
99
100 if (resolvedDomainObject == null) {
101 if (logger.isDebugEnabled()) {
102 logger.debug("domainObject resolved to null, so including tag body");
103 }
104
105
106 return Tag.EVAL_BODY_INCLUDE;
107 }
108
109 if (SecurityContextHolder.getContext().getAuthentication() == null) {
110 if (logger.isDebugEnabled()) {
111 logger.debug(
112 "SecurityContextHolder did not return a non-null Authentication object, so skipping tag body");
113 }
114
115 return Tag.SKIP_BODY;
116 }
117
118 Authentication auth = SecurityContextHolder.getContext().getAuthentication();
119
120 ApplicationContext context = getContext(pageContext);
121 String[] beans = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, AclManager.class, false, false);
122
123 if (beans.length == 0) {
124 throw new JspException("No AclManager would found the application context: " + context.toString());
125 }
126
127 AclManager aclManager = (AclManager) context.getBean(beans[0]);
128
129
130 AclEntry[] acls = aclManager.getAcls(resolvedDomainObject, auth);
131
132 if (logger.isDebugEnabled()) {
133 logger.debug("Authentication: '" + auth + "' has: " + ((acls == null) ? 0 : acls.length)
134 + " AclEntrys for domain object: '" + resolvedDomainObject + "' from AclManager: '"
135 + aclManager.toString() + "'");
136 }
137
138 if ((acls == null) || (acls.length == 0)) {
139 return Tag.SKIP_BODY;
140 }
141
142 for (int i = 0; i < acls.length; i++) {
143
144 if (acls[i] instanceof BasicAclEntry) {
145 BasicAclEntry processableAcl = (BasicAclEntry) acls[i];
146
147
148 for (int y = 0; y < requiredIntegers.length; y++) {
149 if (processableAcl.isPermitted(requiredIntegers[y].intValue())) {
150 if (logger.isDebugEnabled()) {
151 logger.debug("Including tag body as found permission: " + requiredIntegers[y]
152 + " due to AclEntry: '" + processableAcl + "'");
153 }
154
155 return Tag.EVAL_BODY_INCLUDE;
156 }
157 }
158 }
159 }
160
161 if (logger.isDebugEnabled()) {
162 logger.debug("No permission, so skipping tag body");
163 }
164
165 return Tag.SKIP_BODY;
166 }
167
168
169
170
171
172
173
174
175
176 protected ApplicationContext getContext(PageContext pageContext) {
177 ServletContext servletContext = pageContext.getServletContext();
178
179 return WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
180 }
181
182 public Object getDomainObject() {
183 return domainObject;
184 }
185
186 public String getHasPermission() {
187 return hasPermission;
188 }
189
190 private Integer[] parseIntegersString(String integersString)
191 throws NumberFormatException {
192 final Set integers = new HashSet();
193 final StringTokenizer tokenizer;
194 tokenizer = new StringTokenizer(integersString, ",", false);
195
196 while (tokenizer.hasMoreTokens()) {
197 String integer = tokenizer.nextToken();
198 integers.add(new Integer(integer));
199 }
200
201 return (Integer[]) integers.toArray(new Integer[] {});
202 }
203
204 public void setDomainObject(Object domainObject) {
205 this.domainObject = domainObject;
206 }
207
208 public void setHasPermission(String hasPermission) {
209 this.hasPermission = hasPermission;
210 }
211 }