View Javadoc

1   /*
2    * Copyright 2000-2001,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.modules.actions.portlets.security;
18  
19  // java util
20  import java.util.Iterator;
21  import java.util.List;
22  import java.util.Vector;
23  
24  import org.apache.jetspeed.modules.actions.portlets.SecureVelocityPortletAction;
25  import org.apache.jetspeed.om.profile.Portlets;
26  import org.apache.jetspeed.om.profile.Profile;
27  import org.apache.jetspeed.om.profile.ProfileLocator;
28  import org.apache.jetspeed.om.security.JetspeedUser;
29  import org.apache.jetspeed.om.security.Role;
30  import org.apache.jetspeed.portal.portlets.VelocityPortlet;
31  import org.apache.jetspeed.services.JetspeedSecurity;
32  import org.apache.jetspeed.services.Profiler;
33  import org.apache.jetspeed.services.PsmlManager;
34  import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
35  import org.apache.jetspeed.services.logging.JetspeedLogger;
36  import org.apache.jetspeed.services.resources.JetspeedResources;
37  import org.apache.jetspeed.services.rundata.JetspeedRunData;
38  import org.apache.jetspeed.util.PortletUtils;
39  import org.apache.turbine.util.DynamicURI;
40  import org.apache.turbine.util.RunData;
41  import org.apache.turbine.util.StringUtils;
42  import org.apache.velocity.context.Context;
43  
44  
45  /***
46   * This action sets up the template context for editing security roles in the Turbine database
47   * for a given user.
48   *
49   * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
50   * @version $Id: UserRoleUpdateAction.java,v 1.12 2004/03/31 04:49:10 morciuch Exp $
51   */
52  public class UserRoleUpdateAction extends SecureVelocityPortletAction
53  {
54      
55      /***
56       * Static initialization of the logger for this class
57       */    
58      private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(UserRoleUpdateAction.class.getName());     
59      
60      /***
61       * Build the maximized state content for this portlet. (Same as normal state).
62       *
63       * @param portlet The velocity-based portlet that is being built.
64       * @param context The velocity context for this request.
65       * @param rundata The turbine rundata context for this request.
66       */
67      protected void buildMaximizedContext( VelocityPortlet portlet,
68                                            Context context,
69                                            RunData rundata )
70      {
71          buildNormalContext( portlet, context, rundata);
72      }
73  
74      /***
75       * Build the configure state content for this portlet.
76       * TODO: we could configure this portlet with configurable skins, etc..
77       *
78       * @param portlet The velocity-based portlet that is being built.
79       * @param context The velocity context for this request.
80       * @param rundata The turbine rundata context for this request.
81       */
82      protected void buildConfigureContext( VelocityPortlet portlet,
83                                            Context context,
84                                            RunData rundata )
85      {
86  
87          buildNormalContext( portlet, context, rundata);
88      }
89  
90      /***
91       * Build the normal state content for this portlet.
92       *
93       * @param portlet The velocity-based portlet that is being built.
94       * @param context The velocity context for this request.
95       * @param rundata The turbine rundata context for this request.
96       */
97      protected void buildNormalContext( VelocityPortlet portlet,
98                                         Context context,
99                                         RunData rundata )
100     {
101         try
102         {
103             Role role = null;
104             /*
105              * Grab the mode for the user form.
106              */
107             String mode = rundata.getParameters().getString(SecurityConstants.PARAM_MODE);
108 
109             //
110             // check to see if we are adding a role for a single user
111             //
112             String entityid = rundata.getParameters().getString(SecurityConstants.PARAM_ENTITY_ID);
113             if (entityid == null || entityid.trim().length() == 0)
114             {
115                 return;
116             }
117 
118             buildUserRoleContext(portlet, context, rundata, entityid);
119 
120             //
121             // if there was an error, display the message
122             //
123             String msgid = rundata.getParameters().getString(SecurityConstants.PARAM_MSGID);
124             if (msgid != null)
125             {
126                 int id = Integer.parseInt(msgid);
127                 if (id < SecurityConstants.MESSAGES.length)
128                     context.put(SecurityConstants.PARAM_MSG, SecurityConstants.MESSAGES[id]);
129             }
130 
131         }
132         catch (Exception e)
133         {
134             logger.error("Error in Jetspeed User Role Security", e);
135             rundata.setMessage("Error in Jetspeed User Role Security: " + e.toString());
136             rundata.setStackTrace(StringUtils.stackTrace(e), e);
137             rundata.setScreenTemplate(JetspeedResources.getString("template.error","Error"));
138         }
139     }
140 
141 
142     /***
143      * Database Update Action for Security Roles. Performs updates into security database.
144      *
145      * @param rundata The turbine rundata context for this request.
146      * @param context The velocity context for this request.
147      */
148     public void doUpdate(RunData rundata, Context context)
149         throws Exception
150     {
151         String entityid = rundata.getParameters().getString(SecurityConstants.PARAM_ENTITY_ID);
152         if (entityid == null || entityid.trim().length() == 0)
153         {
154             logger.error("UserRoleBrowser: Failed to get entity: " + entityid );
155             DynamicURI duri = new DynamicURI (rundata);
156             duri.addPathInfo(SecurityConstants.PANE_NAME, SecurityConstants.PANEID_USERROLE_UPDATE);
157             duri.addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_MISSING_PARAMETER);
158             rundata.setRedirectURI(duri.toString());
159             return;
160         }
161 
162         JetspeedUser user = JetspeedSecurity.getUser(entityid);
163         if (null == user)
164         {
165             logger.error("UserRoleBrowser: Failed to get user: " + entityid );
166             DynamicURI duri = new DynamicURI (rundata);
167             duri.addPathInfo(SecurityConstants.PANE_NAME, SecurityConstants.PANEID_USERROLE_UPDATE);
168             duri.addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_MISSING_PARAMETER);
169             rundata.setRedirectURI(duri.toString());
170             return;
171         }
172 
173 
174         try
175         {
176             List roles = (List)rundata.getUser().getTemp(SecurityConstants.CONTEXT_ROLES);
177             List selected = (List)rundata.getUser().getTemp(SecurityConstants.CONTEXT_SELECTED);
178 
179             if (roles == null || selected == null)
180             {
181                 DynamicURI duri = new DynamicURI (rundata);
182                 duri.addPathInfo(SecurityConstants.PANE_NAME, SecurityConstants.PANEID_USERROLE_UPDATE);
183                 duri.addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_MISSING_PARAMETER);
184                 rundata.setRedirectURI(duri.toString());
185                 return;
186             }
187 
188             //
189             // walk thru all the roles, see if anything changed
190             // if changed, update the database
191             //
192             for (int ix = 0; ix < roles.size(); ix++)
193             {
194                 boolean newValue = rundata.getParameters().getBoolean("box_" + ((Role)roles.get(ix)).getName(), false);
195                 boolean oldValue = ((Boolean)selected.get(ix + 1)).booleanValue();
196                 //System.out.println("In role:"+((Role)roles.get(ix)).getName()+" newValue="+newValue+" oldValue="+oldValue);
197                 if (newValue != oldValue)
198                 {
199                     if (newValue == true)
200                     {
201                         // grant a role to a user
202                         Role newRole = (Role) roles.get(ix);
203                         JetspeedSecurity.grantRole( user.getUserName(), newRole.getName());
204 
205                         // If role profile merging is active, append profile for the new role
206                         if (Profiler.useRoleProfileMerging())
207                         {
208                             appendNewRoleProfile((JetspeedRunData) rundata, user, newRole);
209                         }
210                     }
211                     else
212                     {
213                         // revoke a role from a user
214                         JetspeedSecurity.revokeRole( user.getUserName(),
215                                                     ((Role)roles.get(ix)).getName() );
216                     }
217                 }
218             }
219 
220             // clear the temp values
221             rundata.getUser().setTemp(SecurityConstants.CONTEXT_ROLES, null);
222             rundata.getUser().setTemp(SecurityConstants.CONTEXT_SELECTED, null);
223 
224         }
225         catch (Exception e)
226         {
227            //  the error msg
228             logger.error("Failed update role+permission: ", e);
229             //
230             // error on update - display error message
231             //
232             DynamicURI duri = new DynamicURI (rundata);
233             duri.addPathInfo(SecurityConstants.PANE_NAME, SecurityConstants.PANEID_USERROLE_UPDATE);
234             duri.addPathInfo(SecurityConstants.PARAM_MSGID, SecurityConstants.MID_UPDATE_FAILED);
235             if (user != null)
236                 duri.addPathInfo(SecurityConstants.PARAM_ENTITY_ID, user.getUserName());
237             rundata.setRedirectURI(duri.toString());
238 
239         }
240     }
241 
242     /***
243      * Appends profile for specified role to the end of profile for specified user
244      * 
245      * @param user   User to append to
246      * @param role   Role to append from
247      * @exception Exception
248      */
249     private void appendNewRoleProfile(JetspeedRunData jdata, JetspeedUser user, Role role)
250     throws Exception
251     {
252         // Retrieve the role profile
253         ProfileLocator roleLocator = Profiler.createLocator();
254         roleLocator.setRole(role);
255         roleLocator.setMediaType(jdata.getCapability().getPreferredMediaType());
256         roleLocator.setName("default.psml");
257         Profile roleProfile = Profiler.getProfile(roleLocator);
258         if (roleProfile != null)
259         {
260             if (logger.isDebugEnabled())
261             {
262                 logger.debug("UserRoleUpdateAction: retrieved profile for role: " + roleProfile.getPath());
263             }
264         }
265 
266         // Retrieve the user profile
267         ProfileLocator userLocator = Profiler.createLocator();
268         userLocator.setUser(user);
269         userLocator.setMediaType(jdata.getCapability().getPreferredMediaType());
270         userLocator.setName("default.psml");
271         Profile userProfile = Profiler.getProfile(userLocator);
272         if (userProfile != null)
273         {
274             if (logger.isDebugEnabled())
275             {
276                 logger.debug("UserRoleUpdateAction: retrieved profile for user: " + userProfile.getPath());
277             }
278         }
279 
280         // Append role profile to user profile
281         if (roleProfile != null && 
282             roleProfile.getDocument() != null && 
283             userProfile != null && 
284             userProfile.getDocument() != null)
285         {
286             Profile tmpProfile = (Profile) roleProfile.clone();
287             Portlets rolePortlets = tmpProfile.getDocument().getPortlets();
288             Portlets userPortlets = userProfile.getDocument().getPortlets();
289 
290             // Handle pane based profile
291             if (rolePortlets.getPortletsCount() > 0)
292             {
293                 for (int i = 0; i < rolePortlets.getPortletsCount(); i++)
294                 {
295                     Portlets pane = rolePortlets.getPortlets(i);
296                     pane.setLayout(null);                            
297                     userPortlets.addPortlets(pane);
298                     if (logger.isDebugEnabled())
299                     {
300                         logger.debug("UserRoleUpdateAction: appended pane: " + pane.getId() + " to user: " + user.getUserName());
301                     }
302                 }
303             }
304             // Handle profile with no panes
305             else
306             {
307                 if (rolePortlets.getTitle() == null)
308                 {
309                     String title = org.apache.turbine.util.StringUtils.firstLetterCaps(roleProfile.getRoleName());
310                     rolePortlets.setTitle(title + " Home");
311                 }
312                 rolePortlets.setLayout(null);
313                 userPortlets.addPortlets(rolePortlets);
314             }
315 
316             // Regenerate ids
317             PortletUtils.regenerateIds(userPortlets);
318 
319             // Save the user profile
320             PsmlManager.store(userProfile);
321         }
322     }
323 
324     /***
325      * Build the context for a role browser for a specific user.
326      *
327      * @param portlet The velocity-based portlet that is being built.
328      * @param context The velocity context for this request.
329      * @param rundata The turbine rundata context for this request.
330      * @param userid The userid of the user that we are building a role context for.
331      */
332     private void buildUserRoleContext(VelocityPortlet portlet,
333                                        Context context,
334                                        RunData rundata,
335                                        String userid)
336         throws Exception
337     {
338         // get the user object
339         JetspeedUser user = JetspeedSecurity.getUser(userid);
340         if (null == user)
341         {
342             // no User found
343             logger.error("UserRoleBrowser: Failed to get user: " + userid );
344             return;
345         }
346         // get master list of roles
347         Iterator roles = JetspeedSecurity.getRoles();
348         Vector masterRoles = new Vector();
349         Vector selected = new Vector();
350         int ix = 0;
351         boolean sel = false;
352         selected.add(ix, new Boolean(sel));
353         while(roles.hasNext())
354         {
355             Role role = (Role)roles.next();
356             //System.out.println("In buildUserRoleContext role="+role.getName());
357             masterRoles.add(role);
358             sel = JetspeedSecurity.hasRole(user.getUserName(), role.getName());
359             //System.out.println("In buildUserRoleContext sel="+sel);
360             ix = ix + 1;
361             selected.add(ix, new Boolean(sel));
362         }
363         masterRoles.trimToSize();
364         selected.trimToSize();
365 
366         rundata.getUser().setTemp(SecurityConstants.CONTEXT_ROLES, masterRoles);
367         rundata.getUser().setTemp(SecurityConstants.CONTEXT_SELECTED, selected);
368         context.put(SecurityConstants.CONTEXT_USER, user);
369         context.put(SecurityConstants.CONTEXT_ROLES, masterRoles);
370         context.put(SecurityConstants.CONTEXT_SELECTED, selected);
371 
372     }
373 
374 
375 }