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.io.StringReader;
20  import java.util.ArrayList;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.StringTokenizer;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.jetspeed.JetspeedActions;
28  import org.apache.jetspeed.ajax.AJAXException;
29  import org.apache.jetspeed.ajax.AjaxAction;
30  import org.apache.jetspeed.ajax.AjaxBuilder;
31  import org.apache.jetspeed.layout.PortletActionSecurityBehavior;
32  import org.apache.jetspeed.om.common.SecurityConstraint;
33  import org.apache.jetspeed.om.page.PageSecurity;
34  import org.apache.jetspeed.om.page.SecurityConstraintsDef;
35  import org.apache.jetspeed.page.PageManager;
36  import org.apache.jetspeed.request.RequestContext;
37  import org.jdom.Document;
38  import org.jdom.Element;
39  import org.jdom.input.SAXBuilder;
40  
41  /***
42   * Security Permission action
43   * 
44   * AJAX Parameters: 
45   *    action = constraints
46   *    method = add-def | update-def | remove-def | add-global | remove-global   
47   *    name = name of constraint definition or global definition
48   *    xml = the constraints payload, same format as PSML constraint defs
49   *    
50   * @author <a href="mailto:taylor@apache.org">David Sean Taylor </a>
51   * @version $Id: $
52   */
53  public class SecurityConstraintsAction 
54      extends BasePortletAction 
55      implements AjaxAction, AjaxBuilder, Constants
56  {
57      protected static final Log log = LogFactory.getLog(SecurityConstraintsAction.class);
58  
59      public SecurityConstraintsAction(String template, 
60                                       String errorTemplate, 
61                                       PageManager pm,
62                                       PortletActionSecurityBehavior securityBehavior)                                     
63      {
64          super(template, errorTemplate, pm, securityBehavior); 
65      }
66  
67      public SecurityConstraintsAction(String template, 
68              String errorTemplate, 
69              PageManager pm)
70      {
71          this(template, errorTemplate, pm, null); 
72      }
73      
74      public boolean run(RequestContext requestContext, Map resultMap)
75              throws AJAXException
76      {
77          boolean success = true;
78          String status = "success";
79          try
80          {
81              resultMap.put(ACTION, "constraints");
82              // Get the necessary parameters off of the request
83              String method = getActionParameter(requestContext, "method");
84              if (method == null) 
85              { 
86                  throw new RuntimeException("Method not provided"); 
87              }            
88              resultMap.put("method", method);
89              if (false == checkAccess(requestContext, JetspeedActions.EDIT))
90              {
91                  success = false;
92                  resultMap.put(REASON, "Insufficient access to administer portal permissions");                
93                  return success;
94              }           
95              int count = 0;
96              if (method.equals("add-def") || method.equals("update-def"))
97              {
98                  count = updateConstraintDefinition(requestContext, resultMap);
99              }
100             else if (method.equals("remove-def"))
101             {
102                 count = removeConstraintDefinition(requestContext, resultMap);
103             }
104             else if (method.equals("add-global"))
105             {
106                 count = addGlobal(requestContext, resultMap);
107             }
108             else if (method.equals("remove-global"))
109             {
110                 count = removeGlobal(requestContext, resultMap);
111             }
112             else
113             {
114                 success = false;
115                 resultMap.put(REASON, "Unsupported portal constraints method: " + method);                
116                 return success;                
117             }
118             resultMap.put("count", Integer.toString(count));
119             resultMap.put(STATUS, status);
120         } 
121         catch (Exception e)
122         {
123             log.error("exception administering portal permissions", e);
124             resultMap.put(REASON, e.toString());
125             success = false;
126         }
127         return success;
128     }
129     
130     protected int removeConstraintDefinition(RequestContext requestContext, Map resultMap)
131     throws AJAXException
132     {
133         String name = getActionParameter(requestContext, "name");
134         if (name == null)
135             throw new AJAXException("Missing 'name' parameter");
136         
137         try
138         {
139             PageSecurity pageSecurity = pageManager.getPageSecurity();        
140             SecurityConstraintsDef def = pageSecurity.getSecurityConstraintsDef(name);
141             if (def == null)
142             {
143                 return 0;
144             }
145             List defs = pageSecurity.getSecurityConstraintsDefs();
146             defs.remove(def);
147             pageSecurity.setSecurityConstraintsDefs(defs);
148             pageManager.updatePageSecurity(pageSecurity);
149         }
150         catch (Exception e)
151         {
152             throw new AJAXException(e);
153         }        
154         return 1;
155     }
156     
157     protected int updateConstraintDefinition(RequestContext requestContext, Map resultMap)
158     throws AJAXException
159     {
160         int count = 0;
161         boolean added = false;
162         String xml = getActionParameter(requestContext, "xml");
163         if (xml == null)
164             throw new AJAXException("Missing 'xml' parameter");
165         try
166         {
167             SAXBuilder saxBuilder = new SAXBuilder();
168             StringReader reader = new StringReader(xml);
169             Document document = saxBuilder.build(reader);
170             Element root = document.getRootElement();
171             String name = root.getAttribute("name").getValue();
172             PageSecurity pageSecurity = pageManager.getPageSecurity();
173             SecurityConstraintsDef def = pageSecurity.getSecurityConstraintsDef(name);
174             int defsSize = 0;
175             if (def == null)
176             {
177                 def = pageManager.newSecurityConstraintsDef();
178                 def.setName(name);
179                 added = true;
180             }
181             int xmlSize = root.getChildren("security-constraint").size();
182             if (added == false)
183             {
184                 defsSize = def.getSecurityConstraints().size();
185             }
186             int min = (xmlSize < defsSize) ? xmlSize : defsSize;
187             List xmlConstraints = root.getChildren("security-constraint");
188             List constraints = def.getSecurityConstraints();
189             Element owner = root.getChild("owner");
190             if (owner != null)
191             {
192             }
193             for (int ix = 0; ix < min; ix++)
194             {
195                 Element xmlConstraint = (Element)xmlConstraints.get(ix);
196                 SecurityConstraint constraint =  (SecurityConstraint)constraints.get(ix);                
197                 updateConstraintValues(xmlConstraint, constraint);
198                 count++;                
199             }
200             if (xmlSize < defsSize)
201             {
202                 // remove constraints
203                 List deletes = new ArrayList(defsSize - xmlSize);
204                 for (int ix = min; ix < defsSize; ix++)
205                 {
206                     deletes.add(constraints.get(ix));
207                 }
208                 for (int ix = 0; ix < deletes.size(); ix++)
209                 {
210                     constraints.remove(deletes.get(ix));
211                     count++;                    
212                 }                
213             }
214             else if (xmlSize > defsSize)
215             {
216                 // add new constraints
217                 for (int ix = min; ix < xmlSize; ix++)
218                 {
219                     Element xmlConstraint = (Element)xmlConstraints.get(ix);
220                     SecurityConstraint constraint =  pageManager.newPageSecuritySecurityConstraint();                    
221                     updateConstraintValues(xmlConstraint, constraint);
222                     constraints.add(constraint);                    
223                     count++;
224                 }                
225             }
226             if (added)
227             {                
228                 pageSecurity.getSecurityConstraintsDefs().add(def);
229                 pageSecurity.setSecurityConstraintsDefs(pageSecurity.getSecurityConstraintsDefs());
230             }
231             pageManager.updatePageSecurity(pageSecurity);
232         }
233         catch (Exception e)
234         {
235             throw new AJAXException(e);
236         }
237         return count;
238     }
239     
240     protected void updateConstraintValues(Element xmlConstraint, SecurityConstraint constraint)
241     {
242         constraint.setRoles(parseCSVList(xmlConstraint.getChildText("roles")));
243         constraint.setGroups(parseCSVList(xmlConstraint.getChildText("groups")));
244         constraint.setPermissions(parseCSVList(xmlConstraint.getChildText("permissions")));
245         constraint.setUsers(parseCSVList(xmlConstraint.getChildText("users")));        
246     }
247     
248     protected List parseCSVList(String csv)
249     {
250         if (csv != null)
251         {
252             List csvList = new ArrayList(4);
253             if (csv.indexOf(',') != -1)
254             {
255                 StringTokenizer csvTokens = new StringTokenizer(csv, ",");
256                 while (csvTokens.hasMoreTokens())
257                 {
258                     csvList.add(csvTokens.nextToken().trim());
259                 }
260             }
261             else
262             {
263                 csvList.add(csv);
264             }
265             return csvList;
266         }
267         return null;
268     }
269     
270     protected int removeGlobal(RequestContext requestContext, Map resultMap)
271     throws AJAXException
272     {
273         int count = 0;
274         String name = getActionParameter(requestContext, "name");
275         if (name == null)
276             throw new AJAXException("Missing 'name' parameter");
277         
278         try
279         {
280             PageSecurity pageSecurity = pageManager.getPageSecurity();        
281             List globals = pageSecurity.getGlobalSecurityConstraintsRefs();
282             if (!globals.contains(name))
283             {
284                 return 0;
285             }
286             globals.remove(name);
287             pageSecurity.setGlobalSecurityConstraintsRefs(globals);
288             pageManager.updatePageSecurity(pageSecurity);
289             count++;
290         }
291         catch (Exception e)
292         {
293             throw new AJAXException(e);
294         }        
295         return count;
296     }
297        
298     protected int addGlobal(RequestContext requestContext, Map resultMap)
299     throws AJAXException
300     {
301         int count = 0;
302         String name = getActionParameter(requestContext, "name");
303         if (name == null)
304             throw new AJAXException("Missing 'name' parameter");
305         
306         try
307         {
308             PageSecurity pageSecurity = pageManager.getPageSecurity();        
309             List globals = pageSecurity.getGlobalSecurityConstraintsRefs();
310             if (pageSecurity.getSecurityConstraintsDef(name) == null)
311             {
312                 throw new AJAXException("global name doesnt exist in definitions");
313             }
314             if (globals.contains(name))
315             {
316                 // already exist;
317                 return count;
318             }
319             globals.add(name);
320             pageSecurity.setGlobalSecurityConstraintsRefs(globals);
321             pageManager.updatePageSecurity(pageSecurity);
322             count++;
323         }
324         catch (Exception e)
325         {
326             throw new AJAXException(e);
327         }        
328         return count;
329     }
330     
331 }