001    package com.sptci.system;
002    
003    import java.util.HashSet;
004    
005    import nextapp.echo2.app.event.ActionListener;
006    
007    import com.sptci.echo2.Configuration;
008    import com.sptci.echo2.Controller;
009    import com.sptci.util.PasswordGenerator;
010    
011    /**
012     * The controller for the {@link PasswordPane}. Handles all actions/events
013     * triggered by the view.
014     *
015     * <p>Copyright 2007 Sans Pareil Technologies, Inc.</p>
016     * @author Rakesh Vidyadharan 2007-04-22
017     * @version $Id: PasswordController.java 3252 2007-05-12 19:12:31Z rakesh $
018     */
019    class PasswordController extends Controller<PasswordPane>
020    {
021      /**
022       * Create a new instance of the controller for {@link PasswordPane}
023       *
024       * @param view The {@link #view} controlled by this controller.
025       */
026      PasswordController( PasswordPane view )
027      {
028        super( view );
029      }
030    
031      /**
032       * Check the information in {@link #view} and ensure that the appropriate
033       * password change request can be submitted to the server.
034       *
035       * @see #checkPassword
036       * @see #checkNewPassword
037       * @see #checkConfirmPassword
038       * @see #checkPasswordQuality
039       * @throws PasswordException If the checks failed.
040       */
041      void checkView() throws PasswordException
042      {
043        checkPassword();
044        checkNewPassword();
045        checkConfirmPassword();
046        checkPasswordQuality();
047      }
048    
049      /**
050       * Check the {@link PasswordPane#password} value specified.
051       *
052       * @throws PasswordException If the check failed.
053       */
054      void checkPassword() throws PasswordException
055      {
056        if ( ! checkText( view.getPassword() ) )
057        {
058          throw new PasswordException( Configuration.getString( view,
059                "NoPassword.text" ) );
060        }
061      }
062    
063      /**
064       * Check the {@link PasswordPane#newPassword} value specified.
065       *
066       * @throws PasswordException If the check failed.
067       */
068      void checkNewPassword() throws PasswordException
069      {
070        if ( ! checkText( view.getNewPassword() ) )
071        {
072          throw new PasswordException( Configuration.getString( view,
073                "NoNewPassword.text" ) );
074        }
075      }
076    
077      /**
078       * Check the {@link PasswordPane#confirmPassword} value specified.
079       *
080       * @throws PasswordException If the check failed.
081       */
082      void checkConfirmPassword() throws PasswordException
083      {
084        if ( ! checkText( view.getConfirmPassword() ) )
085        {
086          throw new PasswordException( Configuration.getString( view,
087                "NoConfirmPassword.text" ) );
088        }
089        else if ( ! view.getNewPassword().equals( view.getConfirmPassword() ) )
090        {
091          throw new PasswordException( Configuration.getString( view,
092                "PasswordDoesNotMatch.text" ) );
093        }
094      }
095    
096      /**
097       * Chech the quality of the new password.  In addition to
098       * <code>checkSimple</code> check the following:
099       *
100       * <ol>
101       *   <li>The username is not contained in the password</li>
102       *   <li>The username reversed is not contained in the password</li>
103       * </ol>
104       *
105       * @see com.sptci.util.PasswordGenerator#checkSimple
106       * @see #checkContains
107       * @throws PasswordException If the check fails.
108       */
109      void checkPasswordQuality() throws PasswordException
110      {
111        checkContains( view.getNewPassword(),
112            ( (Application) application ).executor.getUser(),
113            "UserNameInPassword.text" );
114        checkContains(
115            view.getNewPassword(), view.getPassword(), "PasswordSimilar.text" );
116    
117        if ( ! new PasswordGenerator().checkSimple(
118              view.getNewPassword().toCharArray() ) )
119        {
120          throw new PasswordException( Configuration.getString( view,
121                "WeakPassword.text" ) );
122        }
123      }
124    
125      /**
126       * Chech to see if the username exists in the password specified.
127       *
128       * @param string The string that is to be checked for existence of
129       *   <code>substring</code>.
130       * @param substring The string that is to be checked for existence in 
131       *   <code>string</code>
132       * @param message The key to the localised message that is to be used
133       *   as the message in {@link PasswordException}.
134       * @throws PasswordException If the check fails.
135       */
136      void checkContains( String string, String substring, String message )
137        throws PasswordException
138      {
139        HashSet<Character> set = new HashSet<Character>();
140        for ( char c : substring.toLowerCase().toCharArray() )
141        {
142          set.add( c );
143        }
144    
145        for ( char c : string.toLowerCase().toCharArray() )
146        {
147          if ( set.contains( c ) ) set.remove( c );
148        }
149    
150        if ( set.size() == 0 )
151        {
152          throw new PasswordException(
153              Configuration.getString( view, message ) );
154        }
155      }
156    
157      /**
158       * Set the {@link PasswordPane#suggest} value.
159       *
160       * @param value The value that is to be displayed in the component.
161       */
162      void setSuggest( String value )
163      {
164        view.suggest.setText( value );
165      }
166    }