View Javadoc

1   /*
2    * Copyright 2000-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.jetspeed.portal.security.portlets;
18  
19  // Jetspeed
20  import org.apache.jetspeed.om.security.JetspeedUser;
21  import org.apache.jetspeed.portal.Portlet;
22  import org.apache.jetspeed.portal.PortletState;
23  import org.apache.jetspeed.portal.PortletConfig;
24  import org.apache.jetspeed.portal.PortletException;
25  import org.apache.jetspeed.portal.PortletInstance;
26  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
27  import org.apache.jetspeed.services.logging.JetspeedLogger;
28  import org.apache.jetspeed.services.portletcache.Cacheable;
29  import org.apache.jetspeed.services.security.PortalResource;
30  import org.apache.jetspeed.services.JetspeedSecurity;
31  import org.apache.jetspeed.util.template.JetspeedLink;
32  import org.apache.jetspeed.util.template.JetspeedLinkFactory;
33  import org.apache.jetspeed.util.MimeType;
34  import org.apache.jetspeed.services.PortletStats;
35  
36  // Turbine imports
37  import org.apache.turbine.util.RunData;
38  import org.apache.turbine.services.localization.Localization;
39  
40  // ECS
41  import org.apache.ecs.ConcreteElement;
42  import org.apache.jetspeed.util.JetspeedClearElement;
43  
44  
45  
46  /***
47  <p>
48  This object is used to wrap a Portlet, ensuring that access control rules are enforced.
49  </p>
50  
51  @author <A HREF="mailto:sgala@apache.org">Santiago Gala</A>
52  @version $Id: PortletWrapper.java,v 1.25 2004/03/29 21:38:43 taylor Exp $
53  */
54  public class PortletWrapper implements Portlet
55  {
56      /***
57       * Static initialization of the logger for this class
58       */    
59      private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(PortletWrapper.class.getName());
60      
61      /*
62       * The portlet we are wrapping
63       */
64      private Portlet wrappedPortlet = null;
65      private PortalResource portalResource = null;
66      private ConcreteElement content = null;
67  
68      public PortletWrapper(Portlet inner)
69      {
70          wrappedPortlet = inner;
71          portalResource = new PortalResource(wrappedPortlet);
72      }
73  
74      /***
75      */
76      public final String getName()
77      {
78          //This means name is accessible for every Portlet
79          return wrappedPortlet.getName();
80      }
81  
82      /***
83      */
84      public final void setName(String name)
85      {
86          //if we want to secure this, we need a context for the check
87          wrappedPortlet.setName(name);
88      }
89  
90      /***
91      */
92      public final PortletConfig getPortletConfig()
93      {
94          return wrappedPortlet.getPortletConfig();
95      }
96  
97      /***
98      */
99      public final void setPortletConfig(PortletConfig pc)
100     {
101         //if we want to secure this, we need a context for the check
102         wrappedPortlet.setPortletConfig(pc);
103     }
104     
105     /***
106     */
107     public ConcreteElement getContent(RunData rundata)
108     {
109  
110         if (checkPermission(rundata, JetspeedSecurity.PERMISSION_VIEW))
111         {
112             if (PortletStats.isEnabled())
113             {
114             	long start = System.currentTimeMillis();
115             	content = wrappedPortlet.getContent(rundata);
116             	long time = System.currentTimeMillis() - start; // time it took to get the content for this portlet
117                 PortletStats.logAccess(rundata, this, PortletStats.ACCESS_OK, time);
118             } else {
119             	content = wrappedPortlet.getContent(rundata);
120             }
121             
122             return content;
123         }
124         else 
125         {
126             if (PortletStats.isEnabled())
127             {
128                 PortletStats.logAccess(rundata, this, PortletStats.ACCESS_DENIED);
129             }
130             return new JetspeedClearElement(Localization.getString(rundata, "SECURITY_NO_ACCESS_TO_PORTLET"));
131         }
132     }
133 
134     /***
135     Provide a description within PML if the user has specified one.
136 
137     @return a null entry if the user hasn't defined anything
138     */
139     public String getDescription()
140     {
141         return wrappedPortlet.getDescription();
142     }
143 
144     public String getDescription(String instanceDescription)
145     {
146         return wrappedPortlet.getDescription(instanceDescription);
147     }
148 
149     /***
150     */
151     public void setDescription(String description)
152     {
153         wrappedPortlet.setDescription(description);
154     }
155 
156     /***
157      * @see Portlet#getImage
158      */
159     public String getImage(String instanceImage)
160     {
161         return wrappedPortlet.getImage(instanceImage);
162     }
163     
164     /***
165      * @see Portlet#setImge
166      */
167     public void setImage(String image)
168     {
169         wrappedPortlet.setImage(image);
170     }
171     /***
172      * @see Portlet#getTitle
173      */
174     public String getTitle()
175     {
176         /* FIXME, no rundata here if( !checkPermission(rundata, 
177                                          JetspeedSecurity.PERMISSION_VIEW ) )
178                                               { */
179         return wrappedPortlet.getTitle();
180         /* } */
181 
182     }
183 
184     /***
185      * @see Portlet#getImage
186      */
187     public String getTitle(String instanceTitle)
188     {
189         return wrappedPortlet.getTitle(instanceTitle);
190     }
191     
192     /***
193     Set the title for this Portlet
194     */
195     public void setTitle(String title)
196     {
197         /* FIXME, no rundata here if( !checkPermission(rundata, 
198                                               JetspeedSecurity.PERMISSION_CUSTOMIZE ) )
199                                               { */
200         wrappedPortlet.setTitle(title);
201         /* } */
202     }
203 
204 
205     /***
206     */
207     public boolean getAllowEdit(RunData rundata)
208     {
209         return checkPermission(rundata, JetspeedSecurity.PERMISSION_CUSTOMIZE);
210     }
211 
212     /***
213      */
214      public boolean getAllowView(RunData rundata)
215      {
216 
217          if (checkPermission(rundata, JetspeedSecurity.PERMISSION_VIEW))
218          {
219              return wrappedPortlet.getAllowView(rundata);
220          }
221          return false;
222      }
223     
224     /***
225     */
226     public boolean getAllowMaximize(RunData rundata)
227     {
228         return checkPermission(rundata, JetspeedSecurity.PERMISSION_MAXIMIZE);
229     }
230 
231     /***
232     By default don't provide any initialization
233     */
234     public void init() throws PortletException 
235     {
236         /* FIXME, no rundata here if( !checkPermission(rundata, 
237                                               JetspeedSecurity.PERMISSION_CUSTOMIZE) )
238                                               { */
239         wrappedPortlet.init();
240         /* } */
241     }
242 
243     /***
244     @see Portlet#getCreationTime
245     */
246     public long getCreationTime()
247     {
248         /* FIXME, no rundata here if( !checkPermission(rundata, 
249                                               JetspeedSecurity.PERMISSION_VIEW) )
250                                               { */
251         return wrappedPortlet.getCreationTime();
252         /* } */
253     }
254     
255     /***
256     @see Portlet#setCreationTime
257     */
258     public void setCreationTime(long creationTime)
259     {
260         /* FIXME, no rundata here if( !checkPermission(rundata, 
261                                               JetspeedSecurity.PERMISSION_CUSTOMIZE) )
262                                               { */
263         wrappedPortlet.setCreationTime(creationTime);
264     }
265     
266     /***
267     @see Portlet#supportsType
268     */
269     public boolean supportsType(MimeType mimeType)
270     {
271         /* FIXME, no rundata here if( !checkPermission(rundata, 
272                                               JetspeedSecurity.PERMISSION_VIEW) )
273                                               { */
274             return wrappedPortlet.supportsType(mimeType);
275             /* } */
276     }
277 
278     /***
279      * Utility method for checking Permissions on myself.
280      * @param rundata A rundata Object
281      * @param permissionName String the name of the Permission requested
282      * @return boolean is it granted?
283      */
284     protected boolean checkPermission(RunData rundata, String permissionName)
285     {
286         try
287         {
288             JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
289             portalResource.setOwner(jsLink.getUserName());
290             JetspeedLinkFactory.putInstance(jsLink);
291         }
292         catch (Exception e)
293         {
294             logger.warn(e.getMessage(), e);
295             portalResource.setOwner(null);
296         }
297         
298         if (logger.isDebugEnabled())
299         {
300             logger.debug("checking for Portlet permission: "
301                       + permissionName 
302                       + " for portlet: "
303                       + wrappedPortlet.getName() 
304                       + " Owner = " 
305                     + portalResource.getOwner());
306         }
307         
308         return JetspeedSecurity.checkPermission((JetspeedUser) rundata.getUser(),
309                                                  portalResource,
310                                                  permissionName);
311     }
312 
313     // utility methods
314 
315     /***
316     Returns TRUE if the title bar in should be displayed. The title bar includes
317     the portlet title and action buttons. 
318      
319     NOTE(FIXME) Not in Portlet interface. Called a la Bean from Velocity.
320     @param rundata A RunData object
321     */
322     public boolean isShowTitleBar(RunData rundata)
323     {
324         if (wrappedPortlet.getPortletConfig() != null) 
325         {
326             // Parameter can exist in PSML or <portlet-entry>
327             return Boolean.valueOf(wrappedPortlet.getPortletConfig().getInitParameter("_showtitlebar", "true")).booleanValue();
328         }
329         return getAttribute("_showtitlebar", "true", rundata).equals("true");
330     }
331 
332     
333     /***
334     Retrieve a portlet attribute from persistent storage
335 
336     @param attrName The attribute to retrieve
337     @parm attrDefValue The value if the attr doesn't exists
338     @param rundata A RunData object
339     @return The attribute value
340     */
341     public String getAttribute(String attrName, String attrDefValue, RunData rundata)
342     {
343         if (checkPermission(rundata, JetspeedSecurity.PERMISSION_VIEW))
344         {
345             return wrappedPortlet.getAttribute(attrName, attrDefValue, rundata);
346         }
347         else
348         {
349             //FIXME: for the moment we will allow this call to succeed...
350             //throw new TurbineRuntimeException( "Security check failed" );
351             return wrappedPortlet.getAttribute(attrName, attrDefValue, rundata);
352         }
353 
354     }
355 
356     /***
357      * Sets a portlet attribute to persistent storage
358      *
359      * @param attrName The attribute to retrieve
360      * @param attrValue The value 
361      * @param rundata A RunData object
362      */
363     public void setAttribute(String attrName, String attrValue, RunData rundata)
364     {
365         if (checkPermission(rundata, JetspeedSecurity.PERMISSION_VIEW))
366         {
367             wrappedPortlet.setAttribute(attrName, attrValue, rundata);
368         }
369         else
370         {
371             //FIXME: for the moment we will allow this call to succeed...
372             //throw new TurbineRuntimeException( "Security check failed" );
373             wrappedPortlet.setAttribute(attrName, attrValue, rundata);
374         }
375 
376     }
377 
378     /***
379      * Gets the portlet instance associated with this portlet.
380      *
381      * @param rundata A RunData object
382      * @return PortletInstance
383      */
384     public PortletInstance getInstance(RunData rundata)
385     {
386         return wrappedPortlet.getInstance(rundata);
387     }
388 
389     /***
390      * <p>Return an instance of one of the classes in this package
391      * making tests before calling the wrapped portlet</p>
392      * <p>Different wrapper classes must be used with the current API
393      * depending on the interfaces implemented by the portlet. :-(</p>
394      *
395      */
396     public static Portlet wrap(Portlet aPortlet)
397     {
398         //SGP Security test
399         if (aPortlet instanceof PortletState)
400         {
401             if (aPortlet instanceof Cacheable)
402             {
403                 return new CacheableStatefulPortletWrapper(aPortlet);
404             }
405             return new StatefulPortletWrapper(aPortlet);
406         }
407         if (aPortlet instanceof Cacheable)
408         {
409             return new CacheablePortletWrapper(aPortlet);
410         }
411         return new PortletWrapper(aPortlet);
412         
413     }
414  
415 
416     public String getID()
417     {
418         return wrappedPortlet.getID();
419     }
420 
421     public void setID(String id)
422     {
423         wrappedPortlet.setID(id);
424     }
425 
426     /***
427     * @return true if the portlet does its own customization
428     */
429     public boolean providesCustomization()
430     {
431         return wrappedPortlet.providesCustomization();
432     } 
433 
434     public Portlet getPortlet()
435     {
436         return wrappedPortlet;
437     }      
438 }