You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ca...@apache.org on 2006/08/30 01:57:40 UTC
svn commit: r438300 - in /maven/shared/trunk/maven-user/maven-user-model/src:
main/java/org/apache/maven/user/model/
main/java/org/apache/maven/user/model/impl/
main/java/org/apache/maven/user/model/rules/
main/java/org/apache/maven/user/model/store/im...
Author: carlos
Date: Tue Aug 29 16:57:39 2006
New Revision: 438300
URL: http://svn.apache.org/viewvc?rev=438300&view=rev
Log:
[CONTINUUM-793, CONTINUUM-795, CONTINUUM-796] Password validation
Submitted By: Joakime Erdfelt
Added:
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserSecurityPolicy.java (with props)
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserSecurityPolicy.java (with props)
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/AlphaPasswordRule.java (with props)
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/CharacterLengthPasswordRule.java (with props)
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/MustHavePasswordRule.java (with props)
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/NumericalPasswordRule.java (with props)
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/ReusePasswordRule.java (with props)
Removed:
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/MustHavePasswordRule.java
Modified:
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/PasswordRule.java
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/PasswordRuleViolations.java
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserManager.java
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserManager.java
maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/store/impl/DefaultUserStore.java
maven/shared/trunk/maven-user/maven-user-model/src/main/mdo/user.xml
maven/shared/trunk/maven-user/maven-user-model/src/main/resources/org/apache/maven/user/model/messages.properties
maven/shared/trunk/maven-user/maven-user-model/src/test/java/org/apache/maven/user/model/impl/DefaultUserManagerTest.java
Modified: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/PasswordRule.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/PasswordRule.java?rev=438300&r1=438299&r2=438300&view=diff
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/PasswordRule.java (original)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/PasswordRule.java Tue Aug 29 16:57:39 2006
@@ -16,12 +16,9 @@
* limitations under the License.
*/
-
/**
* A Password Rule
*
- * @TODO don't rely too much into this until we leverage commons-validation.
- *
* @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
* @version $Id$
*/
@@ -31,9 +28,9 @@
* Provide the Plexus Component Role.
*/
public static final String ROLE = PasswordRule.class.getName();
-
+
/**
* Tests the {@link User#getPassword()} for a valid password, based on rule.
*/
- void testPassword(PasswordRuleViolations violations, User user);
+ void testPassword( PasswordRuleViolations violations, User user, UserSecurityPolicy securityPolicy );
}
Modified: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/PasswordRuleViolations.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/PasswordRuleViolations.java?rev=438300&r1=438299&r2=438300&view=diff
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/PasswordRuleViolations.java (original)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/PasswordRuleViolations.java Tue Aug 29 16:57:39 2006
@@ -34,7 +34,7 @@
{
String key;
- String args[];
+ Object args[];
}
/**
@@ -60,12 +60,23 @@
*/
public void addViolation( String key )
{
+ addViolation(key, null);
+ }
+
+ /**
+ * Add a violation to the underlying list.
+ *
+ * @param key the bundle/localization key for the message.
+ * @param args the arguments for the message.
+ */
+ public void addViolation( String key, Object args[] )
+ {
MessageReference mesgref = new MessageReference();
mesgref.key = key;
- mesgref.args = null;
+ mesgref.args = args;
violations.add( mesgref );
}
-
+
/**
* Get the List of Violations as localized and post-processed {@link String}s.
*
Modified: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserManager.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserManager.java?rev=438300&r1=438299&r2=438300&view=diff
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserManager.java (original)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserManager.java Tue Aug 29 16:57:39 2006
@@ -36,8 +36,7 @@
// ----------------------------------------------------------------------
/**
- * Add a new user. User password will be encoded using the {@link #getPasswordEncoder()}
- * before storing it.
+ * Add a new user. User password may be encoded before storing it.
*
* @param user
*/
@@ -45,8 +44,7 @@
throws PasswordRuleViolationException;
/**
- * Update user data. User password will be encoded using the {@link #getPasswordEncoder()}
- * before storing it.
+ * Update user data. User password may be encoded before storing it.
*
* @param user
*/
@@ -129,45 +127,6 @@
*/
boolean login(String username, String rawpassword);
- // ----------------------------------------------------------------------
- // Passwords
- // ----------------------------------------------------------------------
-
- /**
- * Set the password encoder to be used for password operations
- *
- * @param passwordEncoder
- */
- void setPasswordEncoder( PasswordEncoder passwordEncoder );
-
- /**
- * Get the password encoder to be used for password operations
- *
- * @return the encoder
- */
- PasswordEncoder getPasswordEncoder();
-
- /**
- * Set the Password Rules List.
- *
- * @param rules the list of {@link PasswordRule} objects.
- */
- void setPasswordRules( List rules );
-
- /**
- * Get the Password Rules List.
- *
- * @return the list of {@link PasswordRule} objects.
- */
- List getPasswordRules();
-
- /**
- * Add a Specific Rule to the Password Rules List.
- *
- * @param rule the rule to add.
- */
- void addPasswordRule( PasswordRule rule );
-
// ----------------------------------------------------------------------
// User Group
// ----------------------------------------------------------------------
Added: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserSecurityPolicy.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserSecurityPolicy.java?rev=438300&view=auto
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserSecurityPolicy.java (added)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserSecurityPolicy.java Tue Aug 29 16:57:39 2006
@@ -0,0 +1,36 @@
+package org.apache.maven.user.model;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * User Security Policy Settings.
+ */
+public interface UserSecurityPolicy
+{
+ public static final String ROLE = UserSecurityPolicy.class.getName();
+
+ public int getAllowedLoginAttempts();
+
+ public int getPreviousPasswordsCount();
+
+ /**
+ * Salt to be used in addiotion to the algorithm when encoding a password
+ *
+ * @return the salt
+ */
+ public String getSalt();
+}
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserSecurityPolicy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/UserSecurityPolicy.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Modified: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserManager.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserManager.java?rev=438300&r1=438299&r2=438300&view=diff
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserManager.java (original)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserManager.java Tue Aug 29 16:57:39 2006
@@ -30,6 +30,8 @@
import org.apache.maven.user.model.User;
import org.apache.maven.user.model.UserGroup;
import org.apache.maven.user.model.UserManager;
+import org.apache.maven.user.model.UserSecurityPolicy;
+import org.apache.maven.user.model.rules.MustHavePasswordRule;
import org.apache.maven.user.model.store.UserStore;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
@@ -57,10 +59,10 @@
private PasswordEncoder passwordEncoder;
/**
- * @plexus.configuration default-value="Step doog ekam Skravdraa"
+ * @plexus.requirement
*/
- private String salt;
-
+ private UserSecurityPolicy securityPolicy;
+
/**
* The List of {@link PasswordRule} objects.
*/
@@ -86,8 +88,63 @@
{
return false;
}
+
+ if ( user.isLocked() )
+ {
+ return false;
+ }
- return this.passwordEncoder.isPasswordValid( user.getEncodedPassword(), rawPassword, salt );
+ // Ensure that user cannot set password during login.
+ user.setPassword( null );
+
+ boolean validPassword = this.passwordEncoder.isPasswordValid( user.getEncodedPassword(), rawPassword,
+ securityPolicy.getSalt() );
+
+ if ( validPassword )
+ {
+ // successful login. reset any failed login attempts counter.
+ user.setFailedLoginAttempts( 0 );
+ }
+ else
+ {
+ // failed login. increment and test.
+ if ( user.incrementFailedLoginAttempts() >= securityPolicy.getAllowedLoginAttempts() )
+ {
+ user.setLocked( true );
+ }
+
+ try
+ {
+ this.updateUser( user );
+ }
+ catch ( PasswordRuleViolationException e )
+ {
+ // not possible here.
+ throw new RuntimeException( e );
+ }
+ }
+
+ return validPassword;
+ }
+
+ /**
+ * Sets the Security Policy to use.
+ *
+ * @param policy the policy to use.
+ */
+ public void setSecurityPolicy( UserSecurityPolicy policy )
+ {
+ this.securityPolicy = policy;
+ }
+
+ /**
+ * Gets the Security Policy to use.
+ *
+ * @return the security policy.
+ */
+ public UserSecurityPolicy getSecurityPolicy()
+ {
+ return securityPolicy;
}
public User addUser( User user )
@@ -106,17 +163,30 @@
private void processPasswordChange( User user )
throws PasswordRuleViolationException
{
- validatePassword( user );
-
if ( user.isGuest() )
{
- //TODO we shouldn't allow password changes for guest users, throw exception before getting here
user.setEncodedPassword( null );
+ //TODO we shouldn't allow password changes for guest users, throw exception before getting here
+ return;
}
- else
+
+ validatePassword( user );
+
+ // remember the previous password.
+ List previousPasswords = new ArrayList();
+ previousPasswords.add( user.getEncodedPassword() );
+
+ if ( ( user.getPreviousEncodedPasswords() != null ) && !user.getPreviousEncodedPasswords().isEmpty() )
{
- user.setEncodedPassword( this.passwordEncoder.encodePassword( user.getPassword(), salt ) );
+ int oldCount = Math.min( securityPolicy.getPreviousPasswordsCount() - 1,
+ user.getPreviousEncodedPasswords().size() );
+ List sublist = user.getPreviousEncodedPasswords().subList( 1, oldCount );
+ previousPasswords.addAll( sublist );
}
+ user.setPreviousEncodedPasswords( previousPasswords );
+
+ // set the current encoded password.
+ user.setEncodedPassword( encodePassword( user.getPassword() ) );
user.setPassword( null );
user.setLastPasswordChange( new Date() ); // update timestamp to now.
@@ -125,13 +195,16 @@
private void validatePassword( User user )
throws PasswordRuleViolationException
{
+ // Trim password.
+ user.setPassword( StringUtils.trim( user.getPassword() ) );
+
PasswordRuleViolations violations = new PasswordRuleViolations();
Iterator it = this.rules.iterator();
while ( it.hasNext() )
{
PasswordRule rule = (PasswordRule) it.next();
- rule.testPassword( violations, user );
+ rule.testPassword( violations, user, securityPolicy );
}
if ( violations.hasViolations() )
@@ -152,11 +225,6 @@
return userStore.addUserGroup( userGroup );
}
- public PasswordEncoder getPasswordEncoder()
- {
- return passwordEncoder;
- }
-
public User getUser( int accountId )
{
return userStore.getUser( accountId );
@@ -224,23 +292,64 @@
userStore.removeUserGroup( userGroupName );
}
+ /**
+ * Set the password encoder to be used for password operations
+ *
+ * @param passwordEncoder
+ */
public void setPasswordEncoder( PasswordEncoder passwordEncoder )
{
this.passwordEncoder = passwordEncoder;
}
+ /**
+ * Get the password encoder to be used for password operations
+ *
+ * @return the encoder
+ */
+ public PasswordEncoder getPasswordEncoder()
+ {
+ return passwordEncoder;
+ }
+
+ /**
+ * Encode arbitrary password using configured encoder and salt.
+ *
+ * @param rawpassword the raw password to encode.
+ * @return the encoded form of the password.
+ */
+ public String encodePassword( String rawpassword )
+ {
+ return this.passwordEncoder.encodePassword( rawpassword, securityPolicy.getSalt() );
+ }
+
+ /**
+ * Add a Specific Rule to the Password Rules List.
+ *
+ * @param rule the rule to add.
+ */
public void addPasswordRule( PasswordRule rule )
{
- // TODO: check for duplicates?
+ // TODO: check for duplicates? if so, check should only be based on Rule class name.
this.rules.add( rule );
}
+ /**
+ * Get the Password Rules List.
+ *
+ * @return the list of {@link PasswordRule} objects.
+ */
public List getPasswordRules()
{
return this.rules;
}
+ /**
+ * Set the Password Rules List.
+ *
+ * @param rules the list of {@link PasswordRule} objects.
+ */
public void setPasswordRules( List rules )
{
this.rules = rules;
Added: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserSecurityPolicy.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserSecurityPolicy.java?rev=438300&view=auto
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserSecurityPolicy.java (added)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserSecurityPolicy.java Tue Aug 29 16:57:39 2006
@@ -0,0 +1,76 @@
+package org.apache.maven.user.model.impl;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.maven.user.model.UserSecurityPolicy;
+
+/**
+ * User Security Policy.
+ *
+ * @plexus.component role="org.apache.maven.user.model.UserSecurityPolicy"
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class DefaultUserSecurityPolicy
+ implements UserSecurityPolicy
+{
+ /**
+ * @plexus.configuration default-value="3"
+ */
+ private int allowedLoginAttempts;
+
+ /**
+ * @plexus.configuration default-value="6"
+ */
+ private int previousPasswordsCount;
+
+ /**
+ * @plexus.configuration default-value="Step doog ekam Skravdraa"
+ */
+ private String salt;
+
+ public int getAllowedLoginAttempts()
+ {
+ return allowedLoginAttempts;
+ }
+
+ public int getPreviousPasswordsCount()
+ {
+ return previousPasswordsCount;
+ }
+
+ public void setAllowedLoginAttempts( int allowedLoginAttempts )
+ {
+ this.allowedLoginAttempts = allowedLoginAttempts;
+ }
+
+ public void setPreviousPasswordsCount( int previousPasswordsCount )
+ {
+ this.previousPasswordsCount = previousPasswordsCount;
+ }
+
+ public void setSalt( String salt )
+ {
+ this.salt = salt;
+ }
+
+ public String getSalt()
+ {
+ return salt;
+ }
+}
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserSecurityPolicy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/impl/DefaultUserSecurityPolicy.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/AlphaPasswordRule.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/AlphaPasswordRule.java?rev=438300&view=auto
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/AlphaPasswordRule.java (added)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/AlphaPasswordRule.java Tue Aug 29 16:57:39 2006
@@ -0,0 +1,84 @@
+package org.apache.maven.user.model.rules;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.maven.user.model.PasswordRule;
+import org.apache.maven.user.model.PasswordRuleViolations;
+import org.apache.maven.user.model.User;
+import org.apache.maven.user.model.UserSecurityPolicy;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Basic Password Rule, Checks for non-empty passwords that have at least {@link #setMinimumCount(int)} of
+ * alpha characters contained within.
+ *
+ * @plexus.component role="org.apache.maven.user.model.PasswordRule" role-hint="alpha-count"
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class AlphaPasswordRule
+ implements PasswordRule
+{
+ private int minimumCount;
+
+ public AlphaPasswordRule()
+ {
+ minimumCount = 1;
+ }
+
+ public int getMinimumCount()
+ {
+ return minimumCount;
+ }
+
+ public void setMinimumCount( int minimumCount )
+ {
+ this.minimumCount = minimumCount;
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user, UserSecurityPolicy securityPolicy )
+ {
+ if ( countAlphaCharacters( user.getPassword() ) < this.minimumCount )
+ {
+ violations.addViolation( "user.password.violation.alpha", new Object[] { new Integer( minimumCount ) } ); //$NON-NLS-1$
+ }
+ }
+
+ private int countAlphaCharacters( String password )
+ {
+ int count = 0;
+
+ if ( StringUtils.isEmpty( password ) )
+ {
+ return count;
+ }
+
+ // Doing this via iteration of code points to take in account localized passwords.
+ for ( int i = 0; i < password.length(); i++ )
+ {
+ int codepoint = password.codePointAt( i );
+ if ( Character.isLetter( codepoint ) )
+ {
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+}
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/AlphaPasswordRule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/AlphaPasswordRule.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/CharacterLengthPasswordRule.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/CharacterLengthPasswordRule.java?rev=438300&view=auto
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/CharacterLengthPasswordRule.java (added)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/CharacterLengthPasswordRule.java Tue Aug 29 16:57:39 2006
@@ -0,0 +1,88 @@
+package org.apache.maven.user.model.rules;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.maven.user.model.PasswordRule;
+import org.apache.maven.user.model.PasswordRuleViolations;
+import org.apache.maven.user.model.User;
+import org.apache.maven.user.model.UserSecurityPolicy;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Basic Password Rule, Checks for non-empty passwords that have between {@link #setMinimumCharacters(int)} and
+ * {@link #setMaximumCharacters(int)} characters in length.
+ *
+ * @plexus.component role="org.apache.maven.user.model.PasswordRule" role-hint="character-length"
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class CharacterLengthPasswordRule
+ implements PasswordRule
+{
+ private int minimumCharacters;
+ private int maximumCharacters;
+
+ public CharacterLengthPasswordRule()
+ {
+ minimumCharacters = 1;
+ maximumCharacters = 8;
+ }
+
+ public int getMaximumCharacters()
+ {
+ return maximumCharacters;
+ }
+
+ public int getMinimumCharacters()
+ {
+ return minimumCharacters;
+ }
+
+ public void setMaximumCharacters( int maximumCharacters )
+ {
+ this.maximumCharacters = maximumCharacters;
+ }
+
+ public void setMinimumCharacters( int minimumCharacters )
+ {
+ this.minimumCharacters = minimumCharacters;
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user, UserSecurityPolicy securityPolicy )
+ {
+ if(minimumCharacters > maximumCharacters)
+ {
+ /* this should caught up front during the configuration of the component */
+ // TODO: Throw runtime exception instead?
+ violations.addViolation( "user.password.violation.length.misconfigured", new Object[] {
+ new Integer( minimumCharacters ),
+ new Integer( maximumCharacters ) } ); //$NON-NLS-1$
+ }
+
+ String password = user.getPassword();
+
+ if ( StringUtils.isEmpty( password )
+ || password.length() < minimumCharacters
+ || password.length() > maximumCharacters )
+ {
+ violations.addViolation( "user.password.violation.length", new Object[] {
+ new Integer( minimumCharacters ),
+ new Integer( maximumCharacters ) } ); //$NON-NLS-1$
+ }
+ }
+}
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/CharacterLengthPasswordRule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/CharacterLengthPasswordRule.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/MustHavePasswordRule.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/MustHavePasswordRule.java?rev=438300&view=auto
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/MustHavePasswordRule.java (added)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/MustHavePasswordRule.java Tue Aug 29 16:57:39 2006
@@ -0,0 +1,44 @@
+package org.apache.maven.user.model.rules;
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.maven.user.model.PasswordRule;
+import org.apache.maven.user.model.PasswordRuleViolations;
+import org.apache.maven.user.model.User;
+import org.apache.maven.user.model.UserSecurityPolicy;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Basic Password Rule, Checks for non-empty Passwords in non guest users.
+ *
+ * @plexus.component role="org.apache.maven.user.model.PasswordRule" role-hint="must-have"
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class MustHavePasswordRule
+ implements PasswordRule
+{
+ public void testPassword( PasswordRuleViolations violations, User user, UserSecurityPolicy securityPolicy )
+ {
+ if ( StringUtils.isEmpty( user.getPassword() ) )
+ {
+ violations.addViolation( "user.password.violation.missing" ); //$NON-NLS-1$
+ }
+ }
+
+}
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/MustHavePasswordRule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/MustHavePasswordRule.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/NumericalPasswordRule.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/NumericalPasswordRule.java?rev=438300&view=auto
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/NumericalPasswordRule.java (added)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/NumericalPasswordRule.java Tue Aug 29 16:57:39 2006
@@ -0,0 +1,84 @@
+package org.apache.maven.user.model.rules;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.maven.user.model.PasswordRule;
+import org.apache.maven.user.model.PasswordRuleViolations;
+import org.apache.maven.user.model.User;
+import org.apache.maven.user.model.UserSecurityPolicy;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Basic Password Rule, Checks for non-empty passwords that have at least {@link #setMinimumCount(int)} of
+ * numerical characters contained within.
+ *
+ * @plexus.component role="org.apache.maven.user.model.PasswordRule" role-hint="numerical-count"
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class NumericalPasswordRule
+ implements PasswordRule
+{
+ private int minimumCount;
+
+ public NumericalPasswordRule()
+ {
+ this.minimumCount = 1;
+ }
+
+ public int getMinimumCount()
+ {
+ return minimumCount;
+ }
+
+ public void setMinimumCount( int minimumCount )
+ {
+ this.minimumCount = minimumCount;
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user, UserSecurityPolicy securityPolicy )
+ {
+ if ( countDigitCharacters( user.getPassword() ) < this.minimumCount )
+ {
+ violations.addViolation( "user.password.violation.digit", new Object[] { new Integer( minimumCount ) } ); //$NON-NLS-1$
+ }
+ }
+
+ private int countDigitCharacters( String password )
+ {
+ int count = 0;
+
+ if ( StringUtils.isEmpty( password ) )
+ {
+ return count;
+ }
+
+ // Doing this via iteration of code points to take in account localized passwords.
+ for ( int i = 0; i < password.length(); i++ )
+ {
+ int codepoint = password.codePointAt( i );
+ if ( Character.isDigit( codepoint ) )
+ {
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+}
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/NumericalPasswordRule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/NumericalPasswordRule.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/ReusePasswordRule.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/ReusePasswordRule.java?rev=438300&view=auto
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/ReusePasswordRule.java (added)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/ReusePasswordRule.java Tue Aug 29 16:57:39 2006
@@ -0,0 +1,102 @@
+package org.apache.maven.user.model.rules;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Iterator;
+
+import org.apache.maven.user.model.PasswordEncoder;
+import org.apache.maven.user.model.PasswordRule;
+import org.apache.maven.user.model.PasswordRuleViolations;
+import org.apache.maven.user.model.User;
+import org.apache.maven.user.model.UserSecurityPolicy;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Password Rule, Checks supplied password found at {@link User#getPassword()} against
+ * the {@link User#getPreviousEncodedPasswords()} to ensure that a password is not reused.
+ *
+ * @plexus.component role="org.apache.maven.user.model.PasswordRule" role-hint="reuse"
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class ReusePasswordRule
+ implements PasswordRule
+{
+ /**
+ * @plexus.requirement
+ */
+ private PasswordEncoder passwordEncoder;
+
+ private int previousPasswordCount;
+
+ /**
+ * Create a rule that will check last 3 passwords
+ */
+ public ReusePasswordRule()
+ {
+ this.previousPasswordCount = 3;
+ }
+
+ public int getPreviousPasswordCount()
+ {
+ return previousPasswordCount;
+ }
+
+ public void setPreviousPasswordCount( int previousPasswordCount )
+ {
+ this.previousPasswordCount = previousPasswordCount;
+ }
+
+ private boolean hasReusedPassword( User user, String password, String salt )
+ {
+ if ( StringUtils.isEmpty( password ) )
+ {
+ return false;
+ }
+
+ String encodedPassword = passwordEncoder.encodePassword( password, salt );
+
+ int checkCount = previousPasswordCount;
+
+ Iterator it = user.getPreviousEncodedPasswords().iterator();
+
+ while ( it.hasNext() && ( checkCount >= 0 ) )
+ {
+ String prevEncodedPassword = (String) it.next();
+ if ( encodedPassword.equals( prevEncodedPassword ) )
+ {
+ return true;
+ }
+ checkCount--;
+ }
+
+ return false;
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user, UserSecurityPolicy securityPolicy )
+ {
+ String password = user.getPassword();
+
+ if ( hasReusedPassword( user, password, securityPolicy.getSalt() ) )
+ {
+ violations
+ .addViolation( "user.password.violation.reuse", new Object[] { new Integer( previousPasswordCount ) } ); //$NON-NLS-1$
+ }
+ }
+
+}
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/ReusePasswordRule.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/rules/ReusePasswordRule.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Modified: maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/store/impl/DefaultUserStore.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/store/impl/DefaultUserStore.java?rev=438300&r1=438299&r2=438300&view=diff
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/store/impl/DefaultUserStore.java (original)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/java/org/apache/maven/user/model/store/impl/DefaultUserStore.java Tue Aug 29 16:57:39 2006
@@ -283,6 +283,7 @@
catch ( PlexusStoreException pse )
{
//TODO log exception
+ throw new RuntimeException( pse.getMessage(), pse );
}
}
@@ -295,6 +296,7 @@
catch ( PlexusStoreException pse )
{
//TODO log exception
+ throw new RuntimeException( pse.getMessage(), pse );
}
}
Modified: maven/shared/trunk/maven-user/maven-user-model/src/main/mdo/user.xml
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/mdo/user.xml?rev=438300&r1=438299&r2=438300&view=diff
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/mdo/user.xml (original)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/mdo/user.xml Tue Aug 29 16:57:39 2006
@@ -114,6 +114,25 @@
<type>Date</type>
</field>
<field>
+ <name>failedLoginAttempts</name>
+ <version>1.0.0+</version>
+ <type>int</type>
+ </field>
+ <field>
+ <name>locked</name>
+ <version>1.0.0+</version>
+ <type>boolean</type>
+ <defaultValue>false</defaultValue>
+ </field>
+ <field>
+ <name>previousEncodedPasswords</name>
+ <version>1.0.0+</version>
+ <association stash.part="true">
+ <type>String</type>
+ <multiplicity>*</multiplicity>
+ </association>
+ </field>
+ <field>
<name>group</name>
<version>1.0.0+</version>
<association stash.part="true">
@@ -121,6 +140,17 @@
</association>
</field>
</fields>
+ <codeSegments>
+ <codeSegment>
+ <version>1.0.0+</version>
+ <code><![CDATA[
+ public int incrementFailedLoginAttempts()
+ {
+ return failedLoginAttempts++;
+ }
+ ]]></code>
+ </codeSegment>
+ </codeSegments>
</class>
<class stash.storable="true">
Modified: maven/shared/trunk/maven-user/maven-user-model/src/main/resources/org/apache/maven/user/model/messages.properties
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/main/resources/org/apache/maven/user/model/messages.properties?rev=438300&r1=438299&r2=438300&view=diff
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/main/resources/org/apache/maven/user/model/messages.properties (original)
+++ maven/shared/trunk/maven-user/maven-user-model/src/main/resources/org/apache/maven/user/model/messages.properties Tue Aug 29 16:57:39 2006
@@ -5,3 +5,8 @@
password.encoder.no.such.algoritm=The specified algorithm {1} is not available in the JAAS Implementation of this JVM.
password.encoder.unsupported.encoding=The UTF-8 Encoding is not available in the JAAS Implementation of this JVM.
user.password.violation.missing=You must provide a password.
+user.password.violation.length=You must provide a password between {1} and {2} characters in length.
+user.password.violation.length.misconfigured=Password Length Rule is misconfigured. Specified minimum of ({1}) is larger than specified maximum of ({2}). Rule disabled.
+user.password.violation.alpha=You must provide a password containing at least {1} alphabetic character(s).
+user.password.violation.numeric=You must provide a password containing at least {1} numeric character(s).
+user.password.violation.reuse=Your password cannot match any of your previous {1} password(s).
Modified: maven/shared/trunk/maven-user/maven-user-model/src/test/java/org/apache/maven/user/model/impl/DefaultUserManagerTest.java
URL: http://svn.apache.org/viewvc/maven/shared/trunk/maven-user/maven-user-model/src/test/java/org/apache/maven/user/model/impl/DefaultUserManagerTest.java?rev=438300&r1=438299&r2=438300&view=diff
==============================================================================
--- maven/shared/trunk/maven-user/maven-user-model/src/test/java/org/apache/maven/user/model/impl/DefaultUserManagerTest.java (original)
+++ maven/shared/trunk/maven-user/maven-user-model/src/test/java/org/apache/maven/user/model/impl/DefaultUserManagerTest.java Tue Aug 29 16:57:39 2006
@@ -16,6 +16,15 @@
* limitations under the License.
*/
+import java.net.URL;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+
import org.apache.maven.user.model.Permission;
import org.apache.maven.user.model.User;
import org.apache.maven.user.model.UserGroup;
@@ -26,15 +35,6 @@
import org.codehaus.plexus.jdo.JdoFactory;
import org.jpox.SchemaTool;
-import java.net.URL;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.jdo.PersistenceManager;
-import javax.jdo.PersistenceManagerFactory;
-
/**
* Test Cases for the Default User Manager.
*
@@ -44,7 +44,7 @@
public class DefaultUserManagerTest
extends PlexusTestCase
{
- UserManager usermanager = null;
+ private DefaultUserManager usermanager = null;
/**
* Creates a new UserManager which contains no data.
@@ -92,7 +92,7 @@
pm.close();
- usermanager = (UserManager) lookup( UserManager.ROLE );
+ usermanager = (DefaultUserManager) lookup( UserManager.ROLE );
}
public void testAddGetUserById()
@@ -154,12 +154,17 @@
User fetched = usermanager.getUser( "jgarner" ); //$NON-NLS-1$
assertNotNull( "User should not be null.", fetched ); //$NON-NLS-1$
+ assertEquals( "James Garner", fetched.getFullName() ); //$NON-NLS-1$
+
+ // Change the full name, and update the user.
fetched.setFullName( "Flight Lt. Hendley" ); //$NON-NLS-1$
-
usermanager.updateUser( fetched );
+
+ // Should not change number of users being tracked.
+ assertEquals( 1, usermanager.getUsers().size() );
+ // Fetch the user and test for updated Full Name.
User actual = usermanager.getUser( "jgarner" ); //$NON-NLS-1$
-
assertEquals( "Flight Lt. Hendley", actual.getFullName() ); //$NON-NLS-1$
}
@@ -455,5 +460,35 @@
assertNotNull( actual );
assertNotNull( actual.getPermissions() );
assertEquals( 2, actual.getPermissions().size() );
+ }
+
+ public void testPolicyLoginFailureLock() throws Exception
+ {
+ assertNotNull( usermanager );
+
+ assertEquals( "New UserManager should contain no users.", 0, usermanager.getUsers().size() ); //$NON-NLS-1$
+ assertEquals( "New UserManager should contain no groups.", 0, usermanager.getUserGroups().size() ); //$NON-NLS-1$
+ assertNotNull( "New UserManager should have a Security Policy", usermanager.getSecurityPolicy() ); //$NON-NLS-1$
+
+ User rattenborough = new User();
+ rattenborough.setUsername( "rattenborough" ); //$NON-NLS-1$
+ rattenborough.setFullName( "Richard Attenborough" ); //$NON-NLS-1$
+ rattenborough.setPassword( "the big x" ); //$NON-NLS-1$
+
+ usermanager.addUser( rattenborough );
+
+ assertEquals( 1, usermanager.getUsers().size() );
+
+ // Setup the policy.
+ ( (DefaultUserSecurityPolicy) usermanager.getSecurityPolicy() ).setAllowedLoginAttempts( 3 );
+
+ assertFalse( usermanager.login( "rattenborough", "the big lebowski" ) );
+ assertFalse( usermanager.getUser( "rattenborough" ).isLocked() );
+
+ assertFalse( usermanager.login( "rattenborough", "the big cheese" ) );
+ assertFalse( usermanager.getUser( "rattenborough" ).isLocked() );
+
+ assertFalse( usermanager.login( "rattenborough", "big x" ) );
+ assertTrue( usermanager.getUser( "rattenborough" ).isLocked() );
}
}