File Source: Register.java

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   *  contributor license agreements.  The ASF licenses this file to You
     4   * under the Apache License, Version 2.0 (the "License"); you may not
     5   * 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.  For additional information regarding
    15   * copyright in this work, please see the NOTICE file in the top level
    16   * directory of this distribution.
    17   */
    18  
    19  package org.apache.roller.weblogger.ui.struts2.core;
    20  
    21  import java.util.Locale;
    22  import java.util.TimeZone;
    23  import java.util.UUID;
    24  import javax.servlet.http.HttpServletRequest;
    25  import org.apache.commons.lang.CharSetUtils;
    26  import org.apache.commons.lang.StringUtils;
    27  import org.apache.commons.logging.Log;
    28  import org.apache.commons.logging.LogFactory;
    29  import org.apache.roller.weblogger.WebloggerException;
    30  import org.apache.roller.weblogger.business.WebloggerFactory;
    31  import org.apache.roller.weblogger.business.UserManager;
    32  import org.apache.roller.weblogger.config.WebloggerConfig;
    33  import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
    34  import org.apache.roller.weblogger.pojos.User;
    35  import org.apache.roller.weblogger.ui.core.security.CustomUserRegistry;
    36  import org.apache.roller.weblogger.ui.struts2.util.UIAction;
    37  import org.apache.roller.weblogger.util.MailUtil;
    38  import org.apache.struts2.interceptor.ServletRequestAware;
    39  import org.apache.struts2.interceptor.validation.SkipValidation;
    40  
    41  
    42  /**
    43   * Actions for registering a new user.
    44   */
    45  public class Register extends UIAction implements ServletRequestAware {
    46      
             /* 
    P/P       *  Method: org.apache.roller.weblogger.ui.struts2.core.Register__static_init
              * 
              *  Postconditions:
              *    DEFAULT_ALLOWED_CHARS == &"A-Za-z0-9"
              *    init'ed(log)
              */
    47      private static Log log = LogFactory.getLog(Register.class);
    48      
    49      public static String DEFAULT_ALLOWED_CHARS = "A-Za-z0-9";
    50      
    51      // this is a no-no, we should not need this
    52      private HttpServletRequest servletRequest = null;
    53      
    54      private boolean fromSS0 = false;
    55      private String activationStatus = null;
    56      
    57      private String activationCode = null;
    58      private ProfileBean bean = new ProfileBean();
    59      
    60      
             /* 
    P/P       *  Method: void org.apache.roller.weblogger.ui.struts2.core.Register()
              * 
              *  Postconditions:
              *    this.activationCode == null
              *    this.activationStatus == null
              *    this.servletRequest == null
              *    this.bean.emailAddress == null
              *    this.bean.fullName == null
              *    this.bean.id == null
              *    this.bean.locale == null
              *    this.bean.password == null
              *    this.bean.passwordConfirm == null
              *    this.bean.passwordText == null
              *    ...
              */
    61      public Register() {
    62          this.pageTitle = "newUser.addNewUser";
    63      }
    64      
    65      
    66      // override default security, we do not require an authenticated user
    67      public boolean isUserRequired() {
                 /* 
    P/P           *  Method: bool isUserRequired()
                  * 
                  *  Postconditions:
                  *    return_value == 0
                  */
    68          return false;
    69      }
    70      
    71      // override default security, we do not require an action weblog
    72      public boolean isWeblogRequired() {
                 /* 
    P/P           *  Method: bool isWeblogRequired()
                  * 
                  *  Postconditions:
                  *    return_value == 0
                  */
    73          return false;
    74      }
    75      
    76      
    77      @SkipValidation
    78      public String execute() {
    79          
                 /* 
    P/P           *  Method: String execute()
                  * 
                  *  Preconditions:
                  *    (soft) log != null
                  *    (soft) this.bean != null
                  * 
                  *  Presumptions:
                  *    java.util.Locale:getDefault(...)@85 != null
                  *    java.util.TimeZone:getDefault(...)@86 != null
                  * 
                  *  Postconditions:
                  *    java.util.Locale:toString(...)._tainted == 0
                  *    return_value in Addr_Set{&"input",&"disabled"}
                  *    possibly_updated(this.bean.emailAddress)
                  *    possibly_updated(this.bean.fullName)
                  *    possibly_updated(this.bean.id)
                  *    possibly_updated(this.bean.locale)
                  *    possibly_updated(this.bean.password)
                  *    possibly_updated(this.bean.screenName)
                  *    possibly_updated(this.bean.timeZone)
                  *    possibly_updated(this.bean.userName)
                  *    ...
                  * 
                  *  Test Vectors:
                  *    org.apache.roller.weblogger.config.WebloggerConfig:getBooleanProperty(...)@91: {0}, {1}
                  *    org.apache.roller.weblogger.config.WebloggerRuntimeConfig:getBooleanProperty(...)@80: {1}, {0}
                  *    org.apache.roller.weblogger.ui.core.security.CustomUserRegistry:getUserDetailsFromAuthentication(...)@93: Addr_Set{null}, Inverse{null}
                  */
    80          if(!WebloggerRuntimeConfig.getBooleanProperty("users.registration.enabled")) {
    81              return "disabled";
    82          }
    83          
    84          // set some defaults
    85          getBean().setLocale(Locale.getDefault().toString());
    86          getBean().setTimeZone(TimeZone.getDefault().getID());
    87              
    88          try {
    89              // Let's see if there's any user-authentication available from Acegi
    90              // and retrieve custom user data to pre-populate form.
    91              boolean usingSSO = WebloggerConfig.getBooleanProperty("users.sso.enabled");
    92              if(usingSSO) {
    93                  User fromSSO = CustomUserRegistry.getUserDetailsFromAuthentication();
    94                  if(fromSSO != null) {
    95                      getBean().copyFrom(fromSSO);
    96                      setFromSS0(true);
    97                  }
    98              }
    99              
   100          } catch (Exception ex) {
   101              log.error("Error reading SSO user data", ex);
   102              addError("error.editing.user", ex.toString());
   103          }
   104          
   105          return INPUT;
   106      }
   107      
   108      
   109      public String save() {
   110          
                 /* 
    P/P           *  Method: String save()
                  * 
                  *  Preconditions:
                  *    (soft) init'ed(DEFAULT_ALLOWED_CHARS)
                  *    (soft) log != null
                  *    (soft) init'ed(this.bean.passwordConfirm)
                  *    (soft) this.bean.passwordText != null
                  *    (soft) init'ed(this.bean.userName)
                  *    (soft) this.bean != null
                  *    (soft) init'ed(this.bean.emailAddress)
                  *    (soft) init'ed(this.bean.fullName)
                  *    (soft) init'ed(this.bean.locale)
                  *    (soft) init'ed(this.bean.screenName)
                  *    ...
                  * 
                  *  Presumptions:
                  *    init'ed(java.lang.Boolean.FALSE)
                  *    init'ed(java.lang.Boolean.TRUE)
                  *    java.util.UUID:randomUUID(...)@142 != null
                  *    java.util.UUID:randomUUID(...)@150 != null
                  *    javax.servlet.http.HttpServletRequest:getSession(...)@184 != null
                  *    ...
                  * 
                  *  Postconditions:
                  *    return_value in Addr_Set{&"success",&"input",&"disabled"}
                  *    this.activationStatus == One-of{old this.activationStatus, &"pending"}
                  *    init'ed(this.bean.passwordConfirm)
                  *    this.bean.passwordText != null
                  *    init'ed(this.bean.userName)
                  *    possibly_updated(this.fromSS0)
                  * 
                  *  Test Vectors:
                  *    org.apache.commons.lang.StringUtils:isEmpty(...)@129: {1}, {0}
                  *    org.apache.roller.weblogger.business.UserManager:getUserByActivationCode(...)@144: Addr_Set{null}, Inverse{null}
                  *    org.apache.roller.weblogger.config.WebloggerRuntimeConfig:getBooleanProperty(...)@111: {1}, {0}
                  *    org.apache.roller.weblogger.config.WebloggerRuntimeConfig:getBooleanProperty(...)@135: {0}, {1}
                  *    org.apache.roller.weblogger.pojos.User:getActivationCode(...)@170: Addr_Set{null}, Inverse{null}
                  *    org.apache.roller.weblogger.ui.struts2.core.Register:hasActionErrors(...)@117: {1}, {0}
                  */
   111          if(!WebloggerRuntimeConfig.getBooleanProperty("users.registration.enabled")) {
   112              return "disabled";
   113          }
   114          
   115          myValidate();
   116          
   117          if (!hasActionErrors()) try {
   118              
   119              UserManager mgr = WebloggerFactory.getWeblogger().getUserManager();
   120              
   121              // copy form data into new user pojo
   122              User ud = new User();
   123              getBean().copyTo(ud); // doesn't copy password
   124              ud.setUserName(getBean().getUserName());
   125              ud.setDateCreated(new java.util.Date());
   126              ud.setEnabled(Boolean.TRUE);
   127              
   128              // If user set both password and passwordConfirm then reset password
   129              if (!StringUtils.isEmpty(getBean().getPasswordText()) && 
   130                      !StringUtils.isEmpty(getBean().getPasswordConfirm())) {
   131                  ud.resetPassword(getBean().getPasswordText());
   132              }
   133              
   134              // are we using email activation?
   135              boolean activationEnabled = WebloggerRuntimeConfig.getBooleanProperty(
   136                      "user.account.activation.enabled");
   137              if (activationEnabled) {
   138                  // User account will be enabled after the activation process
   139                  ud.setEnabled(Boolean.FALSE);
   140                  
   141                  // Create & save the activation data
   142                  String activationCode = UUID.randomUUID().toString();
   143                  
   144                  if (mgr.getUserByActivationCode(activationCode) != null) {
   145                      // In the *extremely* unlikely event that we generate an
   146                      // activation code that is already use, we'll retry 3 times.
   147                      int numOfRetries = 3;
+  148                      if (numOfRetries < 1) numOfRetries = 1;
   149                      for (int i = 0; i < numOfRetries; i++) {
   150                          activationCode = UUID.randomUUID().toString();
   151                          if (mgr.getUserByActivationCode(activationCode) == null) {
   152                              break;
   153                          } else {
   154                              activationCode = null;
   155                          }
   156                      }
   157                      // In more unlikely event that three retries isn't enough
+  158                      if (activationCode == null){
   159                          throw new WebloggerException("error.add.user.activationCodeInUse");
   160                      }
   161                  }
   162                  ud.setActivationCode(activationCode);
   163              }
   164              
   165              // save new user
   166              mgr.addUser(ud);
   167              WebloggerFactory.getWeblogger().flush();
   168              
   169              // now send activation email if necessary
   170              if (activationEnabled && ud.getActivationCode() != null) {
   171                  try {
   172                      // send activation mail to the user
   173                      MailUtil.sendUserActivationEmail(ud);
   174                  } catch (WebloggerException ex) {
   175                      log.error("Error sending activation email to - "+ud.getEmailAddress(), ex);
   176                  }
   177                  
   178                  setActivationStatus("pending");
   179              }
   180               
   181              // Invalidate session, otherwise new user who was originally
   182              // authenticated via LDAP/SSO will remain logged in with
   183              // a but without a valid Roller role.
   184              getServletRequest().getSession().invalidate();
   185              
   186              // set a special page title
   187              setPageTitle("welcome.title");
   188              
   189              return SUCCESS;
   190              
   191          } catch (WebloggerException ex) {
   192              log.error("Error adding new user", ex);
   193              // TODO: i18n
   194              addError("Error adding new user");
   195          }
   196          
   197          return INPUT;
   198      }
   199      
   200      
   201      @SkipValidation
   202      public String activate() {
   203          
   204          try {
                     /* 
    P/P               *  Method: String activate()
                      * 
                      *  Preconditions:
                      *    (soft) log != null
                      *    (soft) init'ed(this.activationCode)
                      * 
                      *  Presumptions:
                      *    init'ed(java.lang.Boolean.TRUE)
                      *    org.apache.roller.weblogger.business.Weblogger:getUserManager(...)@205 != null
                      *    org.apache.roller.weblogger.business.WebloggerFactory:getWeblogger(...)@205 != null
                      *    org.apache.roller.weblogger.business.WebloggerFactory:getWeblogger(...)@217 != null
                      * 
                      *  Postconditions:
                      *    return_value == &"success"
                      *    this.activationStatus == One-of{old this.activationStatus, &"active", &"error"}
                      * 
                      *  Test Vectors:
                      *    this.activationCode: Inverse{null}, Addr_Set{null}
                      *    org.apache.roller.weblogger.business.UserManager:getUserByActivationCode(...)@210: Addr_Set{null}, Inverse{null}
                      *    org.apache.roller.weblogger.ui.struts2.core.Register:hasActionErrors(...)@231: {0}, {1}
                      */
   205              UserManager mgr = WebloggerFactory.getWeblogger().getUserManager();
   206              
   207              if (getActivationCode() == null) {
   208                  addError("error.activate.user.missingActivationCode");
   209              } else {
   210                  User user = mgr.getUserByActivationCode(getActivationCode());
   211                  
   212                  if (user != null) {
   213                      // enable user account
   214                      user.setEnabled(Boolean.TRUE);
   215                      user.setActivationCode(null);
   216                      mgr.saveUser(user);
   217                      WebloggerFactory.getWeblogger().flush();
   218                      
   219                      setActivationStatus("active");
   220                      
   221                  } else {
   222                      addError("error.activate.user.invalidActivationCode");
   223                  }
   224              }
   225              
   226          } catch (WebloggerException e) {
   227              addError(e.getMessage());
   228              log.error("ERROR in activateUser", e);
   229          }
   230          
   231          if (hasActionErrors()) {
   232              setActivationStatus("error");
   233          }
   234          
   235          // set a special page title
   236          setPageTitle("welcome.title");
   237              
   238          return SUCCESS;
   239      }
   240      
   241      
   242      public void myValidate() {
   243          
   244          // if usingSSO, we don't want to error on empty password/username from HTML form.
                 /* 
    P/P           *  Method: void myValidate()
                  * 
                  *  Preconditions:
                  *    this.bean != null
                  *    (soft) init'ed(DEFAULT_ALLOWED_CHARS)
                  *    (soft) log != null
                  *    (soft) init'ed(this.bean.passwordConfirm)
                  *    (soft) this.bean.passwordText != null
                  *    (soft) init'ed(this.bean.userName)
                  * 
                  *  Presumptions:
                  *    org.apache.commons.lang.CharSetUtils:keep(...)@268 != null
                  *    org.apache.roller.weblogger.business.Weblogger:getUserManager(...)@280 != null
                  *    org.apache.roller.weblogger.business.WebloggerFactory:getWeblogger(...)@280 != null
                  *    org.apache.roller.weblogger.config.WebloggerConfig:getProperty(...)@251 != null
                  *    org.apache.roller.weblogger.pojos.User:getPassword(...)@253 != null
                  * 
                  *  Postconditions:
                  *    init'ed(this.bean.passwordConfirm)
                  *    this.bean.passwordText != null
                  *    init'ed(this.bean.userName)
                  *    init'ed(this.fromSS0)
                  * 
                  *  Test Vectors:
                  *    java.lang.String:equals(...)@269: {1}, {0}
                  *    java.lang.String:equals(...)@274: {1}, {0}
                  *    java.lang.String:length(...)@263: {1..232-1}, {0}
                  *    org.apache.commons.lang.StringUtils:isEmpty(...)@279: {1}, {0}
                  *    org.apache.roller.weblogger.business.UserManager:getUserByUserName(...)@281: Addr_Set{null}, Inverse{null}
                  *    org.apache.roller.weblogger.config.WebloggerConfig:getBooleanProperty(...)@246: {0}, {1}
                  *    org.apache.roller.weblogger.config.WebloggerConfig:getBooleanProperty(...)@248: {0}, {1}
                  *    org.apache.roller.weblogger.config.WebloggerConfig:getProperty(...)@262: Addr_Set{null}, Inverse{null}
                  *    org.apache.roller.weblogger.ui.core.security.CustomUserRegistry:getUserDetailsFromAuthentication(...)@249: Addr_Set{null}, Inverse{null}
                  */
   245          setFromSS0(false);
   246          boolean usingSSO = WebloggerConfig.getBooleanProperty("users.sso.enabled");
   247          if(usingSSO) {
   248              boolean storePassword = WebloggerConfig.getBooleanProperty("users.sso.passwords.saveInRollerDb");
   249              User fromSSO = CustomUserRegistry.getUserDetailsFromAuthentication();
   250              if(fromSSO != null) {
   251                  String password = WebloggerConfig.getProperty("users.sso.passwords.defaultValue", "<unknown>");
   252                  if(storePassword) {
   253                      password = fromSSO.getPassword();
   254                  }
   255                  getBean().setPasswordText(password);
   256                  getBean().setPasswordConfirm(password);
   257                  getBean().setUserName(fromSSO.getUserName());
   258                  setFromSS0(true);
   259              }
   260          }
   261          
   262          String allowed = WebloggerConfig.getProperty("username.allowedChars");
   263          if(allowed == null || allowed.trim().length() == 0) {
   264              allowed = DEFAULT_ALLOWED_CHARS;
   265          }
   266          
   267          // check that username only contains safe characters
   268          String safe = CharSetUtils.keep(getBean().getUserName(), allowed);
   269          if (!safe.equals(getBean().getUserName()) ) {
   270              addError("error.add.user.badUserName");
   271          }
   272          
   273          // check that passwords match
   274          if(!getBean().getPasswordText().equals(getBean().getPasswordConfirm())) {
   275              addError("Register.error.passowordMismatch");
   276          }
   277          
   278          // check that username is not taken
   279          if(!StringUtils.isEmpty(getBean().getUserName())) try {
   280              UserManager mgr = WebloggerFactory.getWeblogger().getUserManager();
   281              if(mgr.getUserByUserName(getBean().getUserName(), null) != null) {
   282                  addError("error.add.user.userNameInUse");
   283                  // reset user name
   284                  getBean().setUserName(null);
   285              }
   286          } catch (WebloggerException ex) {
   287              log.error("error checking for user", ex);
   288              // TODO: i18n
   289              addError("unexpected error");
   290          }
   291      }
   292      
   293      
   294      public HttpServletRequest getServletRequest() {
                 /* 
    P/P           *  Method: HttpServletRequest getServletRequest()
                  * 
                  *  Preconditions:
                  *    init'ed(this.servletRequest)
                  * 
                  *  Postconditions:
                  *    return_value == this.servletRequest
                  *    init'ed(return_value)
                  */
   295          return servletRequest;
   296      }
   297  
   298      public void setServletRequest(HttpServletRequest servletRequest) {
                 /* 
    P/P           *  Method: void setServletRequest(HttpServletRequest)
                  * 
                  *  Postconditions:
                  *    this.servletRequest == servletRequest
                  *    init'ed(this.servletRequest)
                  */
   299          this.servletRequest = servletRequest;
   300      }
   301      
   302      public ProfileBean getBean() {
                 /* 
    P/P           *  Method: ProfileBean getBean()
                  * 
                  *  Preconditions:
                  *    init'ed(this.bean)
                  * 
                  *  Postconditions:
                  *    return_value == this.bean
                  *    init'ed(return_value)
                  */
   303          return bean;
   304      }
   305  
   306      public void setBean(ProfileBean bean) {
                 /* 
    P/P           *  Method: void setBean(ProfileBean)
                  * 
                  *  Postconditions:
                  *    this.bean == bean
                  *    init'ed(this.bean)
                  */
   307          this.bean = bean;
   308      }
   309  
   310      public boolean isFromSS0() {
                 /* 
    P/P           *  Method: bool isFromSS0()
                  * 
                  *  Preconditions:
                  *    init'ed(this.fromSS0)
                  * 
                  *  Postconditions:
                  *    return_value == this.fromSS0
                  *    init'ed(return_value)
                  */
   311          return fromSS0;
   312      }
   313  
   314      public void setFromSS0(boolean fromSS0) {
                 /* 
    P/P           *  Method: void setFromSS0(bool)
                  * 
                  *  Postconditions:
                  *    this.fromSS0 == fromSS0
                  *    init'ed(this.fromSS0)
                  */
   315          this.fromSS0 = fromSS0;
   316      }
   317  
   318      public String getActivationStatus() {
                 /* 
    P/P           *  Method: String getActivationStatus()
                  * 
                  *  Preconditions:
                  *    init'ed(this.activationStatus)
                  * 
                  *  Postconditions:
                  *    return_value == this.activationStatus
                  *    init'ed(return_value)
                  */
   319          return activationStatus;
   320      }
   321  
   322      public void setActivationStatus(String activationStatus) {
                 /* 
    P/P           *  Method: void setActivationStatus(String)
                  * 
                  *  Postconditions:
                  *    this.activationStatus == activationStatus
                  *    init'ed(this.activationStatus)
                  */
   323          this.activationStatus = activationStatus;
   324      }
   325  
   326      public String getActivationCode() {
                 /* 
    P/P           *  Method: String getActivationCode()
                  * 
                  *  Preconditions:
                  *    init'ed(this.activationCode)
                  * 
                  *  Postconditions:
                  *    return_value == this.activationCode
                  *    init'ed(return_value)
                  */
   327          return activationCode;
   328      }
   329  
   330      public void setActivationCode(String activationCode) {
                 /* 
    P/P           *  Method: void setActivationCode(String)
                  * 
                  *  Postconditions:
                  *    this.activationCode == activationCode
                  *    init'ed(this.activationCode)
                  */
   331          this.activationCode = activationCode;
   332      }
   333      
   334  }








SofCheck Inspector Build Version : 2.18479
Register.java 2009-Jan-02 14:25:20
Register.class 2009-Sep-04 03:12:45