1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.layout.impl;
18
19 import java.lang.reflect.Constructor;
20 import java.security.Permission;
21 import java.security.Principal;
22 import java.util.LinkedList;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.StringTokenizer;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.jetspeed.JetspeedActions;
30 import org.apache.jetspeed.ajax.AJAXException;
31 import org.apache.jetspeed.ajax.AjaxAction;
32 import org.apache.jetspeed.ajax.AjaxBuilder;
33 import org.apache.jetspeed.layout.PortletActionSecurityBehavior;
34 import org.apache.jetspeed.request.RequestContext;
35 import org.apache.jetspeed.security.PermissionManager;
36 import org.apache.jetspeed.security.SecurityException;
37 import org.apache.jetspeed.security.impl.RolePrincipalImpl;
38
39 /***
40 * Security Permission action
41 *
42 * AJAX Parameters:
43 * action = permission
44 * method = add | update | delete
45 * resource = name of the resource to modify
46 * type = portlet | page | folder
47 * roles = comma separated list of roles
48 * actions = comma separated list of actions
49 * oldactions = comma separated list of old actions
50 *
51 * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
52 * @version $Id: $
53 */
54 public class SecurityPermissionAction
55 extends BasePortletAction
56 implements AjaxAction, AjaxBuilder, Constants
57 {
58 protected static final Log log = LogFactory.getLog(SecurityPermissionAction.class);
59 protected PermissionManager pm = null;
60 protected Map permissionMap = null;
61
62 public SecurityPermissionAction(String template,
63 String errorTemplate,
64 PermissionManager pm,
65 PortletActionSecurityBehavior securityBehavior,
66 Map permissionMap)
67 {
68 super(template, errorTemplate, securityBehavior);
69 this.pm = pm;
70 this.permissionMap = permissionMap;
71 }
72
73 public boolean run(RequestContext requestContext, Map resultMap)
74 throws AJAXException
75 {
76 boolean success = true;
77 String status = "success";
78 try
79 {
80 resultMap.put(ACTION, "permissions");
81
82 String method = getActionParameter(requestContext, "method");
83 if (method == null)
84 {
85 throw new RuntimeException("Method not provided");
86 }
87 resultMap.put("method", method);
88 if (false == checkAccess(requestContext, JetspeedActions.EDIT))
89 {
90 success = false;
91 resultMap.put(REASON, "Insufficient access to administer portal permissions");
92 return success;
93 }
94 int count = 0;
95 if (method.equals("add"))
96 {
97 count = addPermission(requestContext, resultMap);
98 }
99 else if (method.equals("update"))
100 {
101 count = updatePermission(requestContext, resultMap);
102 }
103 else if (method.equals("remove"))
104 {
105 count = removePermission(requestContext, resultMap);
106 }
107 else
108 {
109 success = false;
110 resultMap.put(REASON, "Unsupported portal permissions method: " + method);
111 return success;
112 }
113 resultMap.put("count", Integer.toString(count));
114 resultMap.put("resource", getActionParameter(requestContext, "resource"));
115 resultMap.put("type", getActionParameter(requestContext, "type"));
116 resultMap.put("actions", getActionParameter(requestContext, "actions"));
117 resultMap.put("roles", getActionParameter(requestContext, "roles"));
118 resultMap.put(STATUS, status);
119 }
120 catch (Exception e)
121 {
122 log.error("exception administering portal permissions", e);
123 resultMap.put(REASON, e.toString());
124 success = false;
125 }
126 return success;
127 }
128
129 protected int addPermission(RequestContext requestContext, Map resultMap)
130 throws AJAXException
131 {
132 try
133 {
134 String type = getActionParameter(requestContext, "type");
135 if (type == null)
136 throw new AJAXException("Missing 'type' parameter");
137 String resource = getActionParameter(requestContext, "resource");
138 if (resource == null)
139 throw new AJAXException("Missing 'resource' parameter");
140 String actions = getActionParameter(requestContext, "actions");
141 if (actions == null)
142 throw new AJAXException("Missing 'actions' parameter");
143
144 Permission permission = createPermissionFromClass(type, resource, actions);
145 if (pm.permissionExists(permission))
146 {
147 throw new AJAXException("Permission " + resource + " already exists");
148 }
149
150 pm.addPermission(permission);
151 String roleNames = getActionParameter(requestContext, "roles");
152 return updateRoles(permission, roleNames);
153 }
154 catch (SecurityException e)
155 {
156 throw new AJAXException(e.toString(), e);
157 }
158 }
159
160 protected int updatePermission(RequestContext requestContext, Map resultMap)
161 throws AJAXException
162 {
163 try
164 {
165 String type = getActionParameter(requestContext, "type");
166 if (type == null)
167 throw new AJAXException("Missing 'type' parameter");
168 String resource = getActionParameter(requestContext, "resource");
169 if (resource == null)
170 throw new AJAXException("Missing 'resource' parameter");
171 String actions = getActionParameter(requestContext, "actions");
172 if (actions == null)
173 throw new AJAXException("Missing 'actions' parameter");
174 String oldActions = getActionParameter(requestContext, "oldactions");
175 if (oldActions == null)
176 {
177
178 oldActions = actions;
179 }
180 Permission permission = null;
181 if (!oldActions.equals(actions))
182 {
183 permission = createPermissionFromClass(type, resource, oldActions);
184 pm.removePermission(permission);
185 permission = createPermissionFromClass(type, resource, actions);
186 pm.addPermission(permission);
187 }
188 else
189 {
190 permission = createPermissionFromClass(type, resource, actions);
191 }
192 String roleNames = getActionParameter(requestContext, "roles");
193 return updateRoles(permission, roleNames);
194 }
195 catch (SecurityException e)
196 {
197 throw new AJAXException(e.toString(), e);
198 }
199 }
200
201 protected int updateRoles(Permission permission, String roleNames)
202 throws SecurityException
203 {
204 List principals = new LinkedList();
205 if (roleNames != null)
206 {
207 StringTokenizer toke = new StringTokenizer(roleNames, ",");
208 while (toke.hasMoreTokens())
209 {
210 String roleName = toke.nextToken();
211 Principal role = new RolePrincipalImpl(roleName);
212 principals.add(role);
213 }
214 }
215 return pm.updatePermission(permission, principals);
216 }
217
218 protected int removePermission(RequestContext requestContext, Map resultMap)
219 throws AJAXException
220 {
221 try
222 {
223 String type = getActionParameter(requestContext, "type");
224 if (type == null)
225 throw new AJAXException("Missing 'type' parameter");
226 String resource = getActionParameter(requestContext, "resource");
227 if (resource == null)
228 throw new AJAXException("Missing 'resource' parameter");
229 String actions = getActionParameter(requestContext, "actions");
230 if (actions == null)
231 throw new AJAXException("Missing 'actions' parameter");
232 Permission permission = createPermissionFromClass(type, resource, actions);
233 if (pm.permissionExists(permission))
234 {
235 pm.removePermission(permission);
236 return 1;
237 }
238 return 0;
239 }
240 catch (SecurityException e)
241 {
242 throw new AJAXException(e.toString(), e);
243 }
244 }
245
246 protected String mapTypeToClassname(String type)
247 throws AJAXException
248 {
249 String classname = (String)this.permissionMap.get(type);
250 if (classname != null)
251 return classname;
252 throw new AJAXException("Bad resource 'type' parameter: " + type);
253 }
254
255 protected Permission createPermissionFromClass(String type, String resource, String actions)
256 throws AJAXException
257 {
258 String classname = this.mapTypeToClassname(type);
259 try
260 {
261 Class permissionClass = Class.forName(classname);
262 Class[] parameterTypes = { String.class, String.class };
263 Constructor permissionConstructor = permissionClass.getConstructor(parameterTypes);
264 Object[] initArgs = { resource, actions };
265 return (Permission)permissionConstructor.newInstance(initArgs);
266 }
267 catch (Exception e)
268 {
269 throw new AJAXException("Failed to create permission: " + type, e);
270 }
271 }
272
273 }