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      	System.out.println( "SecurityConstraintsAction run" );
78          boolean success = true;
79          String status = "success";
80          try
81          {
82              resultMap.put(ACTION, "constraints");
83              // Get the necessary parameters off of the request
84              String method = getActionParameter(requestContext, "method");
85              if (method == null) 
86              { 
87                  throw new RuntimeException("Method not provided"); 
88              }            
89              resultMap.put("method", method);
90              if (false == checkAccess(requestContext, JetspeedActions.EDIT))
91              {
92                  success = false;
93                  resultMap.put(REASON, "Insufficient access to administer portal permissions");                
94                  return success;
95              }           
96              int count = 0;
97              if (method.equals("add-def") || method.equals("update-def"))
98              {
99                  count = updateConstraintDefinition(requestContext, resultMap);
100             }
101             else if (method.equals("remove-def"))
102             {
103                 count = removeConstraintDefinition(requestContext, resultMap);
104             }
105             else if (method.equals("add-global"))
106             {
107                 count = addGlobal(requestContext, resultMap);
108             }
109             else if (method.equals("remove-global"))
110             {
111                 count = removeGlobal(requestContext, resultMap);
112             }
113             else
114             {
115                 success = false;
116                 resultMap.put(REASON, "Unsupported portal constraints method: " + method);                
117                 return success;                
118             }
119             resultMap.put("count", Integer.toString(count));
120             resultMap.put(STATUS, status);
121         } 
122         catch (Exception e)
123         {
124         	System.out.println( "SecurityConstraintsAction run failure caused by " + e.getClass().getName() + " " + e.getMessage() );
125         	e.printStackTrace();
126             log.error("exception administering portal permissions", e);
127             resultMap.put(REASON, e.toString());
128             success = false;
129         }
130         System.out.println( "SecurityConstraintsAction complete " + resultMap.toString() );
131         return success;
132     }
133     
134     protected int removeConstraintDefinition(RequestContext requestContext, Map resultMap)
135     throws AJAXException
136     {
137         String name = getActionParameter(requestContext, "name");
138         if (name == null)
139             throw new AJAXException("Missing 'name' parameter");
140         
141         try
142         {
143             PageSecurity pageSecurity = pageManager.getPageSecurity();        
144             SecurityConstraintsDef def = pageSecurity.getSecurityConstraintsDef(name);
145             if (def == null)
146             {
147                 return 0;
148             }
149             List defs = pageSecurity.getSecurityConstraintsDefs();
150             defs.remove(def);
151             pageSecurity.setSecurityConstraintsDefs(defs);
152             pageManager.updatePageSecurity(pageSecurity);
153         }
154         catch (Exception e)
155         {
156             throw new AJAXException(e);
157         }        
158         return 1;
159     }
160     
161     protected int updateConstraintDefinition(RequestContext requestContext, Map resultMap)
162     throws AJAXException
163     {
164     	System.out.println( "SecurityConstraintsAction updateConstraintDefinition started" );
165         	
166         int count = 0;
167         boolean added = false;
168         String xml = getActionParameter(requestContext, "xml");
169         if (xml == null)
170             throw new AJAXException("Missing 'xml' parameter");
171         try
172         {
173             SAXBuilder saxBuilder = new SAXBuilder();
174             StringReader reader = new StringReader(xml);
175             Document document = saxBuilder.build(reader);
176             Element root = document.getRootElement();
177             String name = root.getAttribute("name").getValue();
178             PageSecurity pageSecurity = pageManager.getPageSecurity();
179             SecurityConstraintsDef def = pageSecurity.getSecurityConstraintsDef(name);
180             int defsSize = 0;
181             if (def == null)
182             {
183                 def = pageManager.newSecurityConstraintsDef();
184                 def.setName(name);
185                 added = true;
186             }
187             int xmlSize = root.getChildren("security-constraint").size();
188             if (added == false)
189             {
190                 defsSize = def.getSecurityConstraints().size();
191             }
192             int min = (xmlSize < defsSize) ? xmlSize : defsSize;
193             List xmlConstraints = root.getChildren("security-constraint");
194             List constraints = def.getSecurityConstraints();
195             Element owner = root.getChild("owner");
196             if (owner != null)
197             {
198             }
199             for (int ix = 0; ix < min; ix++)
200             {
201                 Element xmlConstraint = (Element)xmlConstraints.get(ix);
202                 SecurityConstraint constraint =  (SecurityConstraint)constraints.get(ix);                
203                 updateConstraintValues(xmlConstraint, constraint);
204                 count++;                
205             }
206             if (xmlSize < defsSize)
207             {
208                 // remove constraints
209                 List deletes = new ArrayList(defsSize - xmlSize);
210                 for (int ix = min; ix < defsSize; ix++)
211                 {
212                     deletes.add(constraints.get(ix));
213                 }
214                 for (int ix = 0; ix < deletes.size(); ix++)
215                 {
216                     constraints.remove(deletes.get(ix));
217                     count++;                    
218                 }                
219             }
220             else if (xmlSize > defsSize)
221             {
222                 // add new constraints
223                 for (int ix = min; ix < xmlSize; ix++)
224                 {
225                     Element xmlConstraint = (Element)xmlConstraints.get(ix);
226                     SecurityConstraint constraint =  pageManager.newPageSecuritySecurityConstraint();                    
227                     updateConstraintValues(xmlConstraint, constraint);
228                     constraints.add(constraint);                    
229                     count++;
230                 }                
231             }
232             if (added)
233             {                
234                 pageSecurity.getSecurityConstraintsDefs().add(def);
235                 pageSecurity.setSecurityConstraintsDefs(pageSecurity.getSecurityConstraintsDefs());
236             }
237             pageManager.updatePageSecurity(pageSecurity);
238         }
239         catch (Exception e)
240         {
241         	System.out.println( "SecurityConstraintsAction updateConstraintDefinition failure caused by " + e.getClass().getName() + " " + e.getMessage() );
242         	e.printStackTrace();
243         	log.error( "SecurityConstraintsAction updateConstraintDefinition failure caused by " + e.getClass().getName() + " " + e.getMessage(), e );
244             throw new AJAXException(e);
245         }
246         return count;
247     }
248     
249     protected void updateConstraintValues(Element xmlConstraint, SecurityConstraint constraint)
250     {
251         constraint.setRoles(parseCSVList(xmlConstraint.getChildText("roles")));
252         constraint.setGroups(parseCSVList(xmlConstraint.getChildText("groups")));
253         constraint.setPermissions(parseCSVList(xmlConstraint.getChildText("permissions")));
254         constraint.setUsers(parseCSVList(xmlConstraint.getChildText("users")));        
255     }
256     
257     protected List parseCSVList(String csv)
258     {
259         if (csv != null)
260         {
261             List csvList = new ArrayList(4);
262             if (csv.indexOf(',') != -1)
263             {
264                 StringTokenizer csvTokens = new StringTokenizer(csv, ",");
265                 while (csvTokens.hasMoreTokens())
266                 {
267                     csvList.add(csvTokens.nextToken().trim());
268                 }
269             }
270             else
271             {
272                 csvList.add(csv);
273             }
274             return csvList;
275         }
276         return null;
277     }
278     
279     protected int removeGlobal(RequestContext requestContext, Map resultMap)
280     throws AJAXException
281     {
282         int count = 0;
283         String name = getActionParameter(requestContext, "name");
284         if (name == null)
285             throw new AJAXException("Missing 'name' parameter");
286         
287         try
288         {
289             PageSecurity pageSecurity = pageManager.getPageSecurity();        
290             List globals = pageSecurity.getGlobalSecurityConstraintsRefs();
291             if (!globals.contains(name))
292             {
293                 return 0;
294             }
295             globals.remove(name);
296             pageSecurity.setGlobalSecurityConstraintsRefs(globals);
297             pageManager.updatePageSecurity(pageSecurity);
298             count++;
299         }
300         catch (Exception e)
301         {
302             throw new AJAXException(e);
303         }        
304         return count;
305     }
306        
307     protected int addGlobal(RequestContext requestContext, Map resultMap)
308     throws AJAXException
309     {
310         int count = 0;
311         String name = getActionParameter(requestContext, "name");
312         if (name == null)
313             throw new AJAXException("Missing 'name' parameter");
314         
315         try
316         {
317             PageSecurity pageSecurity = pageManager.getPageSecurity();        
318             List globals = pageSecurity.getGlobalSecurityConstraintsRefs();
319             if (pageSecurity.getSecurityConstraintsDef(name) == null)
320             {
321                 throw new AJAXException("global name doesnt exist in definitions");
322             }
323             if (globals.contains(name))
324             {
325                 // already exist;
326                 return count;
327             }
328             globals.add(name);
329             pageSecurity.setGlobalSecurityConstraintsRefs(globals);
330             pageManager.updatePageSecurity(pageSecurity);
331             count++;
332         }
333         catch (Exception e)
334         {
335             throw new AJAXException(e);
336         }        
337         return count;
338     }
339     
340 }