View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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              // Get the necessary parameters off of the request
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                 // assume no change
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 }