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.portlets.security;
18  
19  import java.io.IOException;
20  import java.text.MessageFormat;
21  import java.util.ArrayList;
22  import java.util.ResourceBundle;
23  
24  import javax.portlet.ActionRequest;
25  import javax.portlet.ActionResponse;
26  import javax.portlet.PortletConfig;
27  import javax.portlet.PortletException;
28  import javax.portlet.PortletRequest;
29  import javax.portlet.RenderRequest;
30  import javax.portlet.RenderResponse;
31  
32  import org.apache.jetspeed.CommonPortletServices;
33  import org.apache.jetspeed.PortalReservedParameters;
34  import javax.security.auth.Subject;
35  
36  import org.apache.jetspeed.audit.AuditActivity;
37  import org.apache.jetspeed.portlets.security.users.UserDetailsPortlet;
38  import org.apache.jetspeed.request.RequestContext;
39  import org.apache.jetspeed.security.InvalidNewPasswordException;
40  import org.apache.jetspeed.security.InvalidPasswordException;
41  import org.apache.jetspeed.security.PasswordAlreadyUsedException;
42  import org.apache.jetspeed.security.PasswordCredential;
43  import org.apache.jetspeed.security.SecurityException;
44  import org.apache.jetspeed.security.UserManager;
45  import org.apache.portals.bridges.common.GenericServletPortlet;
46  
47  /***
48   * This portlet allows a logged on user to change its password.
49   *
50   * @author <a href="mailto:ate@apache.org">Ate Douma</a>
51   * @version $Id: ChangePasswordPortlet.java 348264 2005-11-22 22:06:45Z taylor $
52   */
53  public class ChangePasswordPortlet extends GenericServletPortlet
54  {
55      private UserManager manager;
56      private AuditActivity audit;
57      
58      public static final String CURRENT_PASSWORD = "currentPassword";
59      public static final String NEW_PASSWORD = "newPassword";
60      public static final String NEW_PASSWORD_AGAIN = "newPasswordAgain";
61      public static final String ERROR_MESSAGES = "errorMessages";
62      public static final String PASSWORD_CHANGED = "passwordChanged";
63      public static final String WHY = "why";
64      public static final String REQUIRED = "required";
65      public static final String CANCELLED = "cancelled";
66      
67      public void init(PortletConfig config)
68      throws PortletException 
69      {
70          super.init(config);
71          manager = (UserManager) getPortletContext().getAttribute(CommonPortletServices.CPS_USER_MANAGER_COMPONENT);
72          if (null == manager)
73          {
74              throw new PortletException("Failed to find the User Manager on portlet initialization");
75          }
76          audit = (AuditActivity)getPortletContext().getAttribute(CommonPortletServices.CPS_AUDIT_ACTIVITY);
77          if (null == audit)
78          {
79              throw new PortletException("Failed to find the Audit Activity on portlet initialization");            
80          }        
81      }
82      
83      public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException
84      {
85          response.setContentType("text/html");
86  
87          if ( request.getUserPrincipal() != null )
88          {
89              RequestContext requestContext = (RequestContext)request.getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
90              Integer passwordDaysValid = (Integer)requestContext.getAttribute(PasswordCredential.PASSWORD_CREDENTIAL_DAYS_VALID_REQUEST_ATTR_KEY);
91              
92              if ( passwordDaysValid != null )
93              {
94                  ResourceBundle bundle = ResourceBundle.getBundle("org.apache.jetspeed.portlets.security.resources.ChgPwdResources",request.getLocale());
95                  if ( passwordDaysValid.intValue() < 1 )
96                  {
97                      request.setAttribute(WHY,bundle.getString("chgpwd.message.change.required"));
98                      request.setAttribute(REQUIRED,Boolean.TRUE);
99                  }
100                 else if ( passwordDaysValid.intValue() == 1 )
101                 {
102                     request.setAttribute(WHY,bundle.getString("chgpwd.message.expires.today"));
103                     request.setAttribute(REQUIRED,Boolean.TRUE);
104                 }
105                 else
106                 {
107                     MessageFormat mf = new MessageFormat(bundle.getString("chgpwd.message.expires.in.days"));
108                     request.setAttribute(WHY,mf.format(new Integer[]{passwordDaysValid}));
109                 }
110             }
111             
112             ArrayList errorMessages = (ArrayList)request.getPortletSession().getAttribute(ERROR_MESSAGES);
113             if (errorMessages != null )
114             {
115                 request.getPortletSession().removeAttribute(ERROR_MESSAGES);
116                 request.setAttribute(ERROR_MESSAGES,errorMessages);
117             }
118             else
119             {
120                 Boolean password_changed = (Boolean)request.getPortletSession().getAttribute(PASSWORD_CHANGED);
121                 if ( password_changed != null )
122                 {
123                     request.getPortletSession().removeAttribute(PASSWORD_CHANGED);
124                     request.setAttribute(PASSWORD_CHANGED,password_changed);
125                 }
126             }        
127         }
128         super.doView(request, response);
129     }
130     
131     public void processAction(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException,
132     IOException
133     {
134         if ( actionRequest.getUserPrincipal() != null )
135         {
136             ResourceBundle bundle = ResourceBundle.getBundle("org.apache.jetspeed.portlets.security.resources.ChgPwdResources",actionRequest.getLocale());
137 
138             ArrayList errorMessages = new ArrayList();
139             
140             String cancelled = actionRequest.getParameter(CANCELLED);
141             if ( cancelled == null )
142             {
143                 String currPassword = actionRequest.getParameter(CURRENT_PASSWORD);
144                 String newPassword = actionRequest.getParameter(NEW_PASSWORD);
145                 String newPasswordAgain = actionRequest.getParameter(NEW_PASSWORD_AGAIN);
146                 String userName = actionRequest.getUserPrincipal().getName();
147             
148                 if (currPassword == null || currPassword.length() == 0)
149                 {
150                     errorMessages.add(bundle.getString("chgpwd.error.currentPasswordNull"));
151                     currPassword = null;
152                 }
153                 if (newPassword == null || newPassword.length() == 0)
154                 {
155                     errorMessages.add(bundle.getString("chgpwd.error.newPasswordNull"));
156                     newPassword = null;
157                 }
158                 if (newPassword != null && newPassword.length() == 0)
159                 {
160                     newPassword = null;
161                 }
162                 
163                 if (newPassword != null && 
164                         (newPasswordAgain == null || (newPasswordAgain != null && !newPassword.equals(newPasswordAgain))))
165                 {
166                     errorMessages.add(bundle.getString("chgpwd.error.newPasswordsDoNotMatch"));
167                 }
168                 if ( errorMessages.size() == 0 )
169                 {
170                     try
171                     {
172                         manager.setPassword(userName, currPassword, newPassword);
173                         audit.logUserActivity(userName, getIPAddress(actionRequest), AuditActivity.PASSWORD_CHANGE_SUCCESS, UserDetailsPortlet.USER_ADMINISTRATION);
174 
175                         // refresh/update Subject in session to reflect the changed PasswordCredential
176                         Subject subject = manager.getUser(userName).getSubject();
177                         RequestContext requestContext = (RequestContext)actionRequest.getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);                  
178                         requestContext.setSessionAttribute(PortalReservedParameters.SESSION_KEY_SUBJECT, subject);
179                     }
180                     catch ( InvalidPasswordException ipe )
181                     {
182                         errorMessages.add(bundle.getString("chgpwd.error.invalidPassword"));
183                     }
184                     catch ( InvalidNewPasswordException inpe )
185                     {
186                         errorMessages.add(bundle.getString("chgpwd.error.invalidNewPassword"));
187                     }
188                     catch ( PasswordAlreadyUsedException paue )
189                     {
190                         errorMessages.add(bundle.getString("chgpwd.error.passwordAlreadyUsed"));
191                     }
192                     catch ( SecurityException e)
193                     {
194                         // todo: localization of all exception messages
195                         errorMessages.add(e.getMessage());
196                     }
197                 }
198                 if ( errorMessages.size() > 0 )
199                 {
200                     actionRequest.getPortletSession().setAttribute(ERROR_MESSAGES,errorMessages);
201                     audit.logUserActivity(userName, getIPAddress(actionRequest), AuditActivity.PASSWORD_CHANGE_FAILURE, errorMessages.toString());                    
202                 }
203                 else
204                 {
205                     actionRequest.getPortletSession().setAttribute(PASSWORD_CHANGED,Boolean.TRUE);
206                 }
207             }
208         }
209     }
210 
211     protected String getIPAddress(PortletRequest request)
212     {
213         RequestContext context = (RequestContext)request.getAttribute(PortalReservedParameters.REQUEST_CONTEXT_ATTRIBUTE);
214         if (context == null)
215             return "";
216         return context.getRequest().getRemoteAddr();
217     }
218     
219 }