* under the License.
*/
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import java.util.List;
* under the License.
*/
-import org.apache.archiva.redback.authentication.AuthenticationDataSource;
-import org.apache.archiva.redback.authentication.AuthenticationException;
-import org.apache.archiva.redback.authentication.AuthenticationResult;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
/**
* Authenticator:
* under the License.
*/
-import org.apache.archiva.redback.authentication.AuthenticationDataSource;
-import org.apache.archiva.redback.authentication.AuthenticationException;
-import org.apache.archiva.redback.authentication.AuthenticationManager;
-import org.apache.archiva.redback.authentication.AuthenticationResult;
-import org.apache.archiva.redback.authentication.Authenticator;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import junit.framework.TestCase;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
-import org.apache.archiva.redback.authentication.ldap.LdapBindAuthenticator;
-import org.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.codehaus.plexus.redback.policy.encoders.SHA1PasswordEncoder;
+import org.apache.archiva.redback.policy.PasswordEncoder;
+import org.apache.archiva.redback.policy.encoders.SHA1PasswordEncoder;
import org.apache.archiva.redback.users.ldap.service.LdapCacheService;
import org.codehaus.redback.components.apacheds.ApacheDs;
import org.junit.After;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authentication.Authenticator;
import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.AccountLockedException;
import org.springframework.stereotype.Service;
/**
* under the License.
*/
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserNotFoundException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
import org.codehaus.plexus.redback.role.RoleManager;
import org.codehaus.plexus.redback.role.RoleManagerException;
import org.codehaus.plexus.redback.system.SecuritySystem;
*/
import org.apache.archiva.redback.authentication.AuthenticationException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.authentication.AuthenticationDataSource;
import org.apache.archiva.redback.authentication.AuthenticationResult;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.AccountLockedException;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.codehaus.plexus.redback.system.SecuritySystemConstants;
import javax.servlet.http.HttpSession;
import org.apache.archiva.redback.authentication.AuthenticationException;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.commons.codec.binary.Base64;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.redback.integration.filter.authentication.HttpAuthenticator;
*/
import org.apache.archiva.redback.authentication.AuthenticationException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.users.User;
import org.apache.commons.codec.binary.Base64;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authentication.TokenBasedAuthenticationDataSource;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.AccountLockedException;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.codehaus.plexus.util.StringUtils;
import org.apache.archiva.redback.configuration.UserConfiguration;
import org.apache.archiva.redback.keys.AuthenticationKey;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
-import org.codehaus.plexus.redback.policy.UserValidationSettings;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.policy.UserValidationSettings;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.codehaus.plexus.util.StringUtils;
import org.slf4j.Logger;
import org.apache.archiva.redback.keys.KeyManager;
import org.apache.archiva.redback.keys.KeyManagerException;
import org.apache.archiva.redback.keys.KeyNotFoundException;
-import org.codehaus.plexus.redback.policy.CookieSettings;
+import org.apache.archiva.redback.policy.CookieSettings;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.codehaus.plexus.util.StringUtils;
import org.slf4j.Logger;
import net.sf.ehcache.CacheManager;
import org.apache.archiva.redback.keys.AuthenticationKey;
import org.apache.archiva.redback.keys.KeyManager;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.codehaus.plexus.jdo.DefaultConfigurableJdoFactory;
import org.apache.archiva.redback.keys.KeyManagerException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
import org.jpox.SchemaTool;
import org.junit.Before;
import org.junit.Test;
import java.util.Iterator;
import java.util.Set;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserNotFoundException;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
import org.codehaus.plexus.redback.rbac.Permission;
import org.codehaus.plexus.redback.rbac.RBACManager;
import org.codehaus.plexus.redback.rbac.RbacManagerException;
*/
import junit.framework.TestCase;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.User;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
import org.codehaus.plexus.redback.rbac.Operation;
import org.codehaus.plexus.redback.rbac.Permission;
import org.codehaus.plexus.redback.rbac.RBACManager;
*/
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.keys.KeyManager;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
import org.apache.archiva.redback.keys.AuthenticationKey;
import org.codehaus.plexus.redback.keys.jdo.JdoAuthenticationKey;
import org.apache.archiva.redback.keys.memory.MemoryAuthenticationKey;
import org.apache.archiva.redback.keys.memory.MemoryKeyManager;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.codehaus.redback.integration.filter.authentication.HttpAuthenticator;
* under the License.
*/
+import org.apache.archiva.redback.policy.PasswordEncoder;
+import org.apache.archiva.redback.policy.PasswordRuleViolationException;
+import org.apache.archiva.redback.policy.PasswordRuleViolations;
import org.apache.archiva.redback.users.User;
import org.apache.commons.lang.StringUtils;
import org.apache.archiva.redback.keys.AuthenticationKey;
import org.apache.archiva.redback.keys.KeyManagerException;
-import org.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolationException;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolations;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.codehaus.redback.integration.filter.authentication.HttpAuthenticator;
import net.sf.ehcache.CacheManager;
import org.apache.archiva.redback.configuration.UserConfiguration;
import org.apache.archiva.redback.keys.AuthenticationKey;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.commons.lang.StringUtils;
import org.apache.archiva.redback.keys.KeyManager;
import org.apache.archiva.redback.keys.KeyManagerException;
import org.apache.archiva.redback.keys.KeyNotFoundException;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
-import org.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.policy.PasswordEncoder;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.codehaus.plexus.redback.rbac.RBACManager;
import org.codehaus.plexus.redback.rbac.RbacManagerException;
import org.codehaus.plexus.redback.rbac.RbacObjectNotFoundException;
*/
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManager;
import org.apache.cxf.jaxrs.ext.RequestHandler;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authorization.RedbackAuthorization;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.AccountLockedException;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.codehaus.redback.integration.filter.authentication.HttpAuthenticationException;
* under the License.
*/
-import org.codehaus.plexus.redback.policy.PasswordRuleViolationException;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.PasswordRuleViolationException;
+import org.apache.archiva.redback.policy.PasswordRuleViolations;
import org.codehaus.redback.rest.api.model.ErrorMessage;
import org.codehaus.redback.rest.api.model.RedbackRestError;
import org.springframework.stereotype.Service;
* under the License.
*/
+import org.apache.archiva.redback.policy.PasswordRuleViolations;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserNotFoundException;
-import org.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolationException;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.PasswordEncoder;
+import org.apache.archiva.redback.policy.PasswordRuleViolationException;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.codehaus.redback.rest.api.model.ErrorMessage;
import org.codehaus.redback.rest.api.services.RedbackServiceException;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolationException;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.PasswordRuleViolationException;
+import org.apache.archiva.redback.policy.PasswordRuleViolations;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.redback.system.SecuritySystemConstants;
import org.codehaus.redback.integration.interceptor.SecureAction;
*/
import org.apache.archiva.redback.users.User;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolationException;
+import org.apache.archiva.redback.policy.PasswordRuleViolationException;
import org.codehaus.plexus.redback.rbac.Permission;
import org.codehaus.plexus.redback.rbac.RBACManager;
import org.codehaus.plexus.redback.rbac.RbacManagerException;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserNotFoundException;
-import org.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolationException;
+import org.apache.archiva.redback.policy.PasswordEncoder;
+import org.apache.archiva.redback.policy.PasswordRuleViolationException;
import org.codehaus.plexus.redback.system.DefaultSecuritySession;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.redback.system.SecuritySystemConstants;
*/
import org.apache.archiva.redback.keys.AuthenticationKey;
+import org.apache.archiva.redback.policy.AccountLockedException;
import org.apache.archiva.redback.users.User;
import org.apache.struts2.ServletActionContext;
import org.apache.archiva.redback.authentication.AuthenticationConstants;
import org.apache.archiva.redback.configuration.UserConfiguration;
import org.apache.archiva.redback.keys.KeyManagerException;
import org.apache.archiva.redback.keys.KeyNotFoundException;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.apache.archiva.redback.users.UserNotFoundException;
* under the License.
*/
+import org.apache.archiva.redback.policy.PasswordEncoder;
+import org.apache.archiva.redback.policy.PasswordRuleViolations;
import org.apache.archiva.redback.users.User;
-import org.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolationException;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.PasswordRuleViolationException;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.apache.archiva.redback.users.UserNotFoundException;
*/
import org.apache.archiva.redback.keys.KeyManager;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.keys.AuthenticationKey;
import org.apache.archiva.redback.keys.KeyManagerException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.apache.archiva.redback.users.User;
import org.codehaus.plexus.util.StringUtils;
*/
import org.apache.archiva.redback.keys.AuthenticationKey;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.keys.KeyManagerException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
import org.codehaus.plexus.redback.role.RoleManager;
import org.codehaus.plexus.redback.role.RoleManagerException;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.configuration.UserConfiguration;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.users.UserManager;
import org.apache.struts2.ServletActionContext;
import org.apache.archiva.redback.authentication.AuthenticationConstants;
import org.apache.archiva.redback.authentication.AuthenticationDataSource;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.AccountLockedException;
import org.codehaus.plexus.redback.role.RoleManager;
import org.codehaus.plexus.redback.role.RoleManagerException;
import org.codehaus.plexus.redback.struts2.action.AuditEvent;
import java.util.Arrays;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.codehaus.plexus.redback.rbac.Resource;
import org.codehaus.plexus.redback.struts2.action.AbstractUserCredentialsAction;
import org.codehaus.plexus.redback.struts2.action.AuditEvent;
* under the License.
*/
+import org.apache.archiva.redback.policy.PasswordEncoder;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.commons.lang.StringEscapeUtils;
-import org.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolationException;
+import org.apache.archiva.redback.policy.PasswordRuleViolationException;
import org.codehaus.plexus.redback.rbac.RBACManager;
import org.codehaus.plexus.redback.rbac.RbacManagerException;
import org.codehaus.plexus.redback.rbac.Resource;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import org.apache.archiva.redback.keys.AuthenticationKey;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.struts2.ServletActionContext;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authentication.TokenBasedAuthenticationDataSource;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.redback.system.SecuritySystem;
import org.codehaus.plexus.redback.system.SecuritySystemConstants;
import org.apache.archiva.redback.configuration.UserConfiguration;
import org.apache.archiva.redback.users.UserManager;
import org.apache.struts2.ServletActionContext;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.codehaus.plexus.redback.system.DefaultSecuritySession;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.redback.system.SecuritySystem;
import java.util.HashMap;
+import org.apache.archiva.redback.policy.DefaultUserSecurityPolicy;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.policy.UserValidationSettings;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.authentication.AuthenticationDataSource;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.authentication.AuthenticationResult;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.DefaultUserSecurityPolicy;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
-import org.codehaus.plexus.redback.policy.UserValidationSettings;
+import org.apache.archiva.redback.policy.AccountLockedException;
import org.codehaus.plexus.redback.system.DefaultSecuritySession;
import org.codehaus.plexus.redback.system.SecuritySession;
import org.codehaus.plexus.redback.system.SecuritySystem;
*/
import net.sf.ehcache.CacheManager;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.users.UserManager;
import org.apache.struts2.StrutsSpringTestCase;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
import org.codehaus.plexus.redback.rbac.RBACManager;
import org.codehaus.plexus.redback.rbac.RbacManagerException;
import org.codehaus.plexus.redback.rbac.RbacObjectInvalidException;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.authorization.AuthorizationResult;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.AccountLockedException;
import org.codehaus.plexus.redback.rbac.RbacManagerException;
import org.codehaus.plexus.redback.rbac.RbacObjectInvalidException;
import org.codehaus.plexus.redback.rbac.Role;
* Check security - show should succeed and display all roles, even without 'user-management-role-grant' or
* 'user-management-user-role' for the user administrators.
*
- * @throws MustChangePasswordException
+ * @throws org.apache.archiva.redback.policy.MustChangePasswordException
*/
@Test
public void testSystemAdminCanShowRoles()
import com.opensymphony.xwork2.Action;
import org.apache.archiva.redback.authentication.AuthenticationException;
+import org.apache.archiva.redback.policy.AccountLockedException;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.authentication.AuthenticationResult;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.codehaus.plexus.redback.rbac.RbacManagerException;
import org.codehaus.plexus.redback.rbac.RbacObjectInvalidException;
import org.codehaus.plexus.redback.rbac.RbacObjectNotFoundException;
import org.apache.archiva.redback.keys.KeyManager;
import org.apache.archiva.redback.keys.KeyManagerException;
import org.apache.archiva.redback.keys.KeyNotFoundException;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserNotFoundException;
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.archiva.redback.configuration.UserConfiguration;
+
+/**
+ * Base class for cookie settings. These will only differ by their configuration keys.
+ *
+ * @todo not sure if having the domain and path in the general configuration is a good idea - this is probably something
+ * customised once for all cookies and applications. Should it be in a sharead configuration file, under a sharead key,
+ * or perhaps even configured at the application server level? (ie, in Naming).
+ */
+public abstract class AbstractCookieSettings
+ implements CookieSettings
+{
+ @Inject @Named(value="userConfiguration")
+ protected UserConfiguration config;
+
+ /**
+ * Timeout (in minutes) for the sign on cookie.
+ */
+ protected int cookieTimeout;
+
+ /**
+ * The domain for the cookie.
+ */
+ protected String domain;
+
+ /**
+ * The path for the cookie.
+ */
+ protected String path;
+
+ public int getCookieTimeout()
+ {
+ return cookieTimeout;
+ }
+
+ public String getDomain()
+ {
+ return domain;
+ }
+
+ public String getPath()
+ {
+ return path;
+ }
+
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * 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.archiva.redback.users.User;
+
+/**
+ * AccountLockedException
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class AccountLockedException
+ extends PolicyViolationException
+{
+ private User user;
+
+ public AccountLockedException( String message, User user )
+ {
+ super( message );
+ this.user = user;
+ }
+
+ public User getUser()
+ {
+ return user;
+ }
+}
+
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * CookieSettings
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface CookieSettings
+{
+ /**
+ * Gets the Cookie timeout (in minutes) for the signon cookie.
+ *
+ * @return the timeout in minutes
+ */
+ int getCookieTimeout();
+
+ /**
+ * Gets the domain to use for the signon cookie.
+ *
+ * @return the domain
+ */
+ String getDomain();
+
+ /**
+ * Gets the path to use for the signon cookie.
+ *
+ * @return the path
+ */
+ String getPath();
+
+ /**
+ * Enable or disables the remember me features of the application.
+ *
+ * @return true if remember me settings are enabled.
+ */
+ boolean isEnabled();
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.archiva.redback.configuration.UserConfiguration;
+import org.apache.archiva.redback.users.User;
+import org.apache.archiva.redback.policy.rules.MustHavePasswordRule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * User Security Policy.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service( "userSecurityPolicy" )
+public class DefaultUserSecurityPolicy
+ implements UserSecurityPolicy
+{
+ private static final String ENABLEMENT_KEY = "UserSecurityPolicy" + ":ENABLED";
+
+ public static final String PASSWORD_RETENTION_COUNT = "security.policy.password.previous.count";
+
+ public static final String LOGIN_ATTEMPT_COUNT = "security.policy.allowed.login.attempt";
+
+ public static final String PASSWORD_EXPIRATION_ENABLED = "security.policy.password.expiration.enabled";
+
+ public static final String PASSWORD_EXPIRATION = "security.policy.password.expiration.days";
+
+ public static final String PASSWORD_ENCODER = "security.policy.password.encoder";
+
+ public static final String UNLOCKABLE_ACCOUNTS = "security.policy.unlockable.accounts";
+
+ private static final Logger log = LoggerFactory.getLogger( DefaultUserSecurityPolicy.class );
+
+ private PasswordRule defaultPasswordRule = new MustHavePasswordRule();
+
+ @Inject
+ @Named( value = "userConfiguration" )
+ private UserConfiguration config;
+
+ @Inject
+ @Named( value = "passwordEncoder#sha256" )
+ private PasswordEncoder passwordEncoder;
+
+ @Inject
+ @Named( value = "userValidationSettings" )
+ private UserValidationSettings userValidationSettings;
+
+ @Inject
+ @Named( value = "cookieSettings#rememberMe" )
+ private CookieSettings rememberMeCookieSettings;
+
+ @Inject
+ @Named( value = "cookieSettings#signon" )
+ private CookieSettings signonCookieSettings;
+
+ // TODO use something more generic to be able to do change about container
+ @Inject
+ private ApplicationContext applicationContext;
+
+ /**
+ * The List of {@link PasswordRule} objects.
+ */
+ @Inject
+ private List<PasswordRule> rules = new ArrayList<PasswordRule>( 0 );
+
+ private int previousPasswordsCount;
+
+ private int loginAttemptCount;
+
+ private int passwordExpirationDays;
+
+ private boolean passwordExpirationEnabled;
+
+ private List<String> unlockableAccounts;
+
+
+ // ---------------------------------------
+ // Component lifecycle
+ // ---------------------------------------
+ // TODO move this to constructor
+ @SuppressWarnings( "unchecked" )
+ @PostConstruct
+ public void initialize()
+ {
+ configurePolicy();
+
+ configureEncoder();
+
+ // In some configurations, rules can be unset.
+ if ( rules == null )
+ {
+ // Set rules to prevent downstream NPE.
+ rules = new ArrayList<PasswordRule>( 1 );
+ }
+
+ if ( rules.isEmpty() )
+ {
+ // there should be at least one rule
+ addPasswordRule( defaultPasswordRule );
+ }
+ }
+
+ private void configureEncoder()
+ {
+ String encoder = config.getString( PASSWORD_ENCODER );
+
+ if ( encoder != null )
+ {
+ this.passwordEncoder = applicationContext.getBean( "passwordEncoder#" + encoder, PasswordEncoder.class );
+ }
+ }
+
+ private void configurePolicy()
+ {
+ this.previousPasswordsCount = config.getInt( PASSWORD_RETENTION_COUNT );
+ this.loginAttemptCount = config.getInt( LOGIN_ATTEMPT_COUNT );
+ this.passwordExpirationEnabled = config.getBoolean( PASSWORD_EXPIRATION_ENABLED );
+ this.passwordExpirationDays = config.getInt( PASSWORD_EXPIRATION );
+ this.unlockableAccounts = config.getList( UNLOCKABLE_ACCOUNTS );
+ }
+
+
+ public String getId()
+ {
+ return "Default User Security Policy";
+ }
+
+ public int getPreviousPasswordsCount()
+ {
+ return previousPasswordsCount;
+ }
+
+ public List<String> getUnlockableAccounts()
+ {
+ if ( unlockableAccounts == null )
+ {
+ unlockableAccounts = new ArrayList<String>( 0 );
+ }
+ return unlockableAccounts;
+ }
+
+ /**
+ * Sets a list of accounts which should never be locked by security policy
+ *
+ * @param unlockableAccounts
+ */
+ public void setUnlockableAccounts( List<String> unlockableAccounts )
+ {
+ this.unlockableAccounts = unlockableAccounts;
+ }
+
+ /**
+ * Sets the count of previous passwords that should be tracked.
+ *
+ * @param count the count of previous passwords to track.
+ */
+ public void setPreviousPasswordsCount( int count )
+ {
+ this.previousPasswordsCount = count;
+ }
+
+ public int getLoginAttemptCount()
+ {
+ return loginAttemptCount;
+ }
+
+ public void setLoginAttemptCount( int count )
+ {
+ this.loginAttemptCount = count;
+ }
+
+ /**
+ * Get the password encoder to be used for password operations
+ *
+ * @return the encoder
+ */
+ public PasswordEncoder getPasswordEncoder()
+ {
+ return passwordEncoder;
+ }
+
+ public boolean isEnabled()
+ {
+ Boolean bool = (Boolean) PolicyContext.getContext().get( ENABLEMENT_KEY );
+ return bool == null || bool.booleanValue();
+ }
+
+ public void setEnabled( boolean enabled )
+ {
+ PolicyContext.getContext().put( ENABLEMENT_KEY, Boolean.valueOf( enabled ) );
+ }
+
+ /**
+ * Add a Specific Rule to the Password Rules List.
+ *
+ * @param rule the rule to add.
+ */
+ public void addPasswordRule( PasswordRule rule )
+ {
+ // TODO: check for duplicates? if so, check should only be based on Rule class name.
+
+ rule.setUserSecurityPolicy( this );
+ this.rules.add( rule );
+ }
+
+ /**
+ * Get the Password Rules List.
+ *
+ * @return the list of {@link PasswordRule} objects.
+ */
+ public List<PasswordRule> getPasswordRules()
+ {
+ return this.rules;
+ }
+
+ /**
+ * Set the Password Rules List.
+ *
+ * @param rules the list of {@link PasswordRule} objects.
+ */
+ public void setPasswordRules( List<PasswordRule> rules )
+ {
+ this.rules.clear();
+
+ if ( rules == null )
+ {
+ return;
+ }
+
+ // Intentionally iterating to ensure policy settings in provided rules.
+
+ for ( PasswordRule rule : rules )
+ {
+ addPasswordRule( rule );
+ }
+ }
+
+ public void extensionPasswordExpiration( User user )
+ throws MustChangePasswordException
+ {
+ if ( passwordExpirationEnabled && !getUnlockableAccounts().contains( user.getUsername() ) )
+ {
+ Calendar expirationDate = Calendar.getInstance();
+ expirationDate.setTime( user.getLastPasswordChange() );
+ expirationDate.add( Calendar.DAY_OF_MONTH, passwordExpirationDays );
+ Calendar now = Calendar.getInstance();
+
+ if ( now.after( expirationDate ) )
+ {
+ log.info( "User '{}' flagged for password expiry (expired on: {})", user.getUsername(),
+ expirationDate );
+ user.setPasswordChangeRequired( true );
+ throw new MustChangePasswordException( "Password Expired, You must change your password.", user );
+ }
+ }
+ }
+
+ public void extensionExcessiveLoginAttempts( User user )
+ throws AccountLockedException
+ {
+ if ( !getUnlockableAccounts().contains( user.getUsername() ) )
+ {
+ int attempt = user.getCountFailedLoginAttempts();
+ attempt++;
+ user.setCountFailedLoginAttempts( attempt );
+
+ if ( attempt >= loginAttemptCount )
+ {
+ log.info( "User '{}' locked due to excessive login attempts: {}", user.getUsername(), attempt );
+ user.setLocked( true );
+ throw new AccountLockedException( "Account " + user.getUsername() + " is locked.", user );
+ }
+ }
+ }
+
+ public void extensionChangePassword( User user )
+ throws PasswordRuleViolationException
+ {
+ extensionChangePassword( user, false );
+ }
+
+ public void extensionChangePassword( User user, boolean passwordChangeRequired )
+ throws PasswordRuleViolationException
+ {
+ validatePassword( user );
+
+ // set the current encoded password.
+ user.setEncodedPassword( passwordEncoder.encodePassword( user.getPassword() ) );
+ user.setPassword( null );
+
+ // push new password onto list of previous password.
+ List<String> previousPasswords = new ArrayList<String>( 1 );
+ previousPasswords.add( user.getEncodedPassword() );
+
+ if ( !user.getPreviousEncodedPasswords().isEmpty() )
+ {
+ int oldCount = Math.min( previousPasswordsCount - 1, user.getPreviousEncodedPasswords().size() );
+ //modified sublist start index as the previous value results to nothing being added to the list.
+ List<String> sublist = user.getPreviousEncodedPasswords().subList( 0, oldCount );
+ previousPasswords.addAll( sublist );
+ }
+
+ user.setPreviousEncodedPasswords( previousPasswords );
+ user.setPasswordChangeRequired( passwordChangeRequired );
+
+ // Update timestamp for password change.
+ user.setLastPasswordChange( new Date() );
+ }
+
+ public void validatePassword( User user )
+ throws PasswordRuleViolationException
+ {
+ if ( isEnabled() )
+ {
+ PasswordRuleViolations violations = new PasswordRuleViolations();
+
+ for ( PasswordRule rule : this.rules )
+ {
+ if ( rule.isEnabled() )
+ {
+ if ( rule.requiresSecurityPolicy() )
+ {
+ rule.setUserSecurityPolicy( this );
+ }
+
+ rule.testPassword( violations, user );
+ }
+ }
+
+ if ( violations.hasViolations() )
+ {
+ PasswordRuleViolationException exception = new PasswordRuleViolationException();
+ exception.setViolations( violations );
+ throw exception;
+ }
+ }
+
+ // If you got this far, then ensure that the password is never null.
+ if ( user.getPassword() == null )
+ {
+ user.setPassword( "" );
+ }
+ }
+
+ public int getPasswordExpirationDays()
+ {
+ return passwordExpirationDays;
+ }
+
+ public void setPasswordExpirationDays( int passwordExpiry )
+ {
+ this.passwordExpirationDays = passwordExpiry;
+ }
+
+ public UserValidationSettings getUserValidationSettings()
+ {
+ return userValidationSettings;
+ }
+
+ public void setUserValidationSettings( UserValidationSettings settings )
+ {
+ this.userValidationSettings = settings;
+ }
+
+ public CookieSettings getRememberMeCookieSettings()
+ {
+ return rememberMeCookieSettings;
+ }
+
+ public CookieSettings getSignonCookieSettings()
+ {
+ return signonCookieSettings;
+ }
+
+ public UserConfiguration getConfig()
+ {
+ return config;
+ }
+
+ public void setConfig( UserConfiguration config )
+ {
+ this.config = config;
+ }
+
+
+ public void setPasswordEncoder( PasswordEncoder passwordEncoder )
+ {
+ this.passwordEncoder = passwordEncoder;
+ }
+
+ public void setRememberMeCookieSettings( CookieSettings rememberMeCookieSettings )
+ {
+ this.rememberMeCookieSettings = rememberMeCookieSettings;
+ }
+
+ public void setSignonCookieSettings( CookieSettings signonCookieSettings )
+ {
+ this.signonCookieSettings = signonCookieSettings;
+ }
+
+ public void setRules( List<PasswordRule> rules )
+ {
+ this.rules = rules;
+ }
+
+ public void setDefaultPasswordRule( PasswordRule defaultPasswordRule )
+ {
+ this.defaultPasswordRule = defaultPasswordRule;
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.archiva.redback.configuration.UserConfiguration;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+
+/**
+ * DefaultUserValidationSettings
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("userValidationSettings")
+public class DefaultUserValidationSettings
+ implements UserValidationSettings
+{
+ @Resource (name="userConfiguration")
+ private UserConfiguration config;
+
+ private boolean emailValidationRequired;
+
+ private int emailValidationTimeout;
+
+ private String emailSubject;
+
+ public boolean isEmailValidationRequired()
+ {
+ return emailValidationRequired;
+ }
+
+ public int getEmailValidationTimeout()
+ {
+ return emailValidationTimeout;
+ }
+
+ public String getEmailSubject()
+ {
+ return emailSubject;
+ }
+
+ @PostConstruct
+ public void initialize()
+ {
+ this.emailValidationRequired = config.getBoolean( "email.validation.required" );
+ this.emailValidationTimeout = config.getInt( "email.validation.timeout" );
+ this.emailSubject = config.getString( "email.validation.subject" );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+import org.apache.archiva.redback.users.User;
+
+/*
+ * 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.
+ */
+
+/**
+ * MustChangePasswordException
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class MustChangePasswordException
+ extends PolicyViolationException
+{
+ private final User user;
+
+ public MustChangePasswordException( String message, User user )
+ {
+ super( message );
+ this.user = user;
+ }
+
+ public User getUser()
+ {
+ return user;
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * 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.
+ */
+
+/**
+ * <p>
+ * Interface for performing authentication operations on a password.
+ * </p>
+ *
+ * <p>Javadoc about encoding and salts copied from Acegi Security.</p>
+ *
+ * @author colin sampaleanu
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface PasswordEncoder
+{
+
+ /**
+ * <p>
+ * Sets the system wide salt to use in the encoder.
+ * </p>
+ *
+ * <p>
+ * The specified salt will potentially be used by the implementation to "salt" the initial value before
+ * encoding. A salt is usually a user-specific value which is added to the password before the digest is computed.
+ * This means that computation of digests for common dictionary words will be different than those in the backend
+ * store, because the dictionary word digests will not reflect the addition of the salt. If a per-user salt is
+ * used (rather than a system-wide salt), it also means users with the same password will have different digest
+ * encoded passwords in the backend store.
+ * </p>
+ *
+ * @param salt the salt to use as a default for the encoder.
+ */
+ void setSystemSalt( Object salt );
+
+ /**
+ * <p>
+ * Encodes the specified raw password with an implementation specific algorithm, using the system wide salt.
+ * </p>
+ *
+ * <p>
+ * This will generally be a one-way message digest such as MD5 or SHA, but may also be a plaintext
+ * variant which does no encoding at all, but rather returns the same password it was fed. The latter is useful to
+ * plug in when the original password must be stored as-is.
+ * </p>
+ *
+ * @param rawPass the password to encode
+ *
+ * @return encoded password
+ */
+ String encodePassword( String rawPass );
+
+ /**
+ * <p>
+ * Encodes the specified raw password with an implementation specific algorithm, using user specific salt.
+ * </p>
+ *
+ * <p>
+ * This will generally be a one-way message digest such as MD5 or SHA, but may also be a plaintext
+ * variant which does no encoding at all, but rather returns the same password it was fed. The latter is useful to
+ * plug in when the original password must be stored as-is.
+ * </p>
+ *
+ * <p>
+ * The specified salt will potentially be used by the implementation to "salt" the initial value before
+ * encoding. A salt is usually a user-specific value which is added to the password before the digest is computed.
+ * This means that computation of digests for common dictionary words will be different than those in the backend
+ * store, because the dictionary word digests will not reflect the addition of the salt. If a per-user salt is
+ * used (rather than a system-wide salt), it also means users with the same password will have different digest
+ * encoded passwords in the backend store.
+ * </p>
+ *
+ * @param rawPass the password to encode
+ * @param salt optionally used by the implementation to "salt" the raw password before encoding.
+ * A <code>null</code> value is legal.
+ * @return encoded password
+ */
+ String encodePassword( String rawPass, Object salt );
+
+
+ /**
+ * <p>
+ * Validates a specified "raw" password against an encoded password, using the system wide salt.
+ * </p>
+ *
+ * <p>
+ * The encoded password should have previously been generated by {@link #encodePassword(String)}.
+ * This method will encode the <code>rawPass</code> (using the system wide <code>salt</code>), and then
+ * compared it with the presented <code>encPass</code>.
+ * </p>
+ *
+ * <p>
+ * For an explanation of salts, please refer to {@link #setSystemSalt(Object)}.
+ * </p>
+ *
+ * @param encPass a pre-encoded password
+ * @param rawPass a raw password to encode and compare against the pre-encoded password
+ *
+ * @return true if the password is valid , false otherwise
+ */
+ boolean isPasswordValid( String encPass, String rawPass );
+
+ /**
+ * <p>
+ * Validates a specified "raw" password against an encoded password, using a user specific salt.
+ * </p>
+ *
+ * <p>
+ * The encoded password should have previously been generated by {@link #encodePassword(String,
+ * Object)}. This method will encode the <code>rawPass</code> (using the optional <code>salt</code>), and then
+ * compared it with the presented <code>encPass</code>.
+ * </p>
+ *
+ * <p>
+ * For a discussion of salts, please refer to {@link #encodePassword(String, Object)}.
+ * </p>
+ *
+ * @param encPass a pre-encoded password
+ * @param rawPass a raw password to encode and compare against the pre-encoded password
+ * @param salt optionally used by the implementation to "salt" the raw password before encoding. A
+ * <code>null</code> value is legal.
+ *
+ * @return true if the password is valid , false otherwise
+ */
+ boolean isPasswordValid( String encPass, String rawPass, Object salt );
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * 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.
+ */
+
+/**
+ * Password Encoding Exception.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class PasswordEncodingException
+ extends RuntimeException
+{
+ public PasswordEncodingException()
+ {
+ super();
+ }
+
+ public PasswordEncodingException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public PasswordEncodingException( String message )
+ {
+ super( message );
+ }
+
+ public PasswordEncodingException( Throwable cause )
+ {
+ super( cause );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * 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.archiva.redback.users.User;
+
+/**
+ * A Password Rule
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface PasswordRule
+{
+
+ /**
+ * Tests if rule is enabled (or not)
+ */
+ boolean isEnabled();
+
+ /**
+ * Sets the User Security Policy to use.
+ *
+ * The policy is set once per instance of a PasswordRule object.
+ *
+ * @param policy the policy to use.
+ */
+ void setUserSecurityPolicy(UserSecurityPolicy policy);
+
+
+ /**
+ * true if the security policy has been set on the rule
+ *
+ * @return boolean
+ */
+ boolean requiresSecurityPolicy();
+
+ /**
+ * Tests the {@link User#getPassword()} for a valid password, based on rule.
+ *
+ * @param violations the place to add any password rule violations that this rule has discovered.
+ * @param user the User to test.
+ */
+ void testPassword( PasswordRuleViolations violations, User user );
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * 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.
+ */
+
+/**
+ * Password Rule Violations Exception
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class PasswordRuleViolationException
+ extends RuntimeException
+{
+ private static final long serialVersionUID = -4686338829234880328L;
+
+ private PasswordRuleViolations violations;
+
+ public PasswordRuleViolationException()
+ {
+ }
+
+ public PasswordRuleViolationException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public PasswordRuleViolationException( String message )
+ {
+ super( message );
+ }
+
+ public PasswordRuleViolationException( Throwable cause )
+ {
+ super( cause );
+ }
+
+ public PasswordRuleViolations getViolations()
+ {
+ return violations;
+ }
+
+ public void setViolations( PasswordRuleViolations violations )
+ {
+ this.violations = violations;
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * 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.archiva.redback.users.Messages;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Password Rule Violations
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class PasswordRuleViolations
+{
+ private List<MessageReference> violations;
+
+ public class MessageReference
+ {
+ String key;
+
+ String[] args;
+
+ public String getKey()
+ {
+ return key;
+ }
+
+ public String[] getArgs()
+ {
+ return args;
+ }
+ }
+
+ /**
+ * Construct a Password Rule Violations object.
+ */
+ public PasswordRuleViolations()
+ {
+ violations = new ArrayList<MessageReference>( 0 );
+ }
+
+ /**
+ * Empty out the list of violations.
+ */
+ public void reset()
+ {
+ violations.clear();
+ }
+
+ /**
+ * Add a violation to the underlying list.
+ *
+ * @param key the bundle/localization key for the message.
+ */
+ 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, String[] args )
+ {
+ MessageReference mesgref = new MessageReference();
+ mesgref.key = key;
+ mesgref.args = args;
+ violations.add( mesgref );
+ }
+
+ /**
+ * Get the List of Violations as localized and post-processed {@link String}s.
+ *
+ * @return the List of {@link String} objects.
+ */
+ public List<String> getLocalizedViolations()
+ {
+ List<String> msgs = new ArrayList<String>( violations.size() );
+
+ for ( MessageReference msgref : violations )
+ {
+ msgs.add( Messages.getString( msgref.key, msgref.args ) );
+ }
+
+ return msgs;
+ }
+
+ /**
+ * Simple test to see if there are any violations.
+ *
+ * @return true if there are any violations.
+ */
+ public boolean hasViolations()
+ {
+ return !violations.isEmpty();
+ }
+
+ public List<MessageReference> getViolations()
+ {
+ return violations;
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * 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.HashMap;
+import java.util.Map;
+
+/**
+ * PolicyContext - A Thread Local Context.
+ * Useful for managing policy operations on a thread local point of view.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class PolicyContext
+{
+ static ThreadLocal<PolicyContext> policyContext = new PolicyContextThreadLocal();
+
+ Map<Object, Object> context;
+
+ public PolicyContext( Map<Object, Object> map )
+ {
+ context = map;
+ }
+
+ public static void setContext( PolicyContext context )
+ {
+ policyContext.set( context );
+ }
+
+ public static PolicyContext getContext()
+ {
+ PolicyContext ctx = (PolicyContext) policyContext.get();
+ if ( ctx == null )
+ {
+ ctx = new PolicyContext( new HashMap<Object, Object>() );
+ setContext( ctx );
+ }
+
+ return ctx;
+ }
+
+ public Object get( Object key )
+ {
+ return context.get( key );
+ }
+
+ public void put( Object key, Object value )
+ {
+ context.put( key, value );
+ }
+
+ private static class PolicyContextThreadLocal
+ extends ThreadLocal<PolicyContext>
+ {
+ protected PolicyContext initialValue()
+ {
+ return new PolicyContext( new HashMap<Object, Object>() );
+ }
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * 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.
+ */
+
+/**
+ * PolicyViolationException
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class PolicyViolationException
+ extends Exception
+{
+
+ public PolicyViolationException()
+ {
+ super();
+ }
+
+ public PolicyViolationException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public PolicyViolationException( String message )
+ {
+ super( message );
+ }
+
+ public PolicyViolationException( Throwable cause )
+ {
+ super( cause );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.archiva.redback.policy.AbstractCookieSettings;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * RememberMeCookieSettings
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("cookieSettings#rememberMe")
+public class RememberMeCookieSettings
+ extends AbstractCookieSettings
+{
+ private boolean enabled;
+
+ public boolean isEnabled()
+ {
+ return enabled;
+ }
+
+ @PostConstruct
+ public void initialize()
+ {
+ this.cookieTimeout = config.getInt( "security.rememberme.timeout" );
+ this.domain = config.getString( "security.rememberme.domain" );
+ this.path = config.getString( "security.rememberme.path" );
+ this.enabled = config.getBoolean( "security.rememberme.enabled" );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.archiva.redback.policy.AbstractCookieSettings;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * SignonCookieSettings
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("cookieSettings#signon")
+public class SignonCookieSettings
+ extends AbstractCookieSettings
+{
+ @PostConstruct
+ public void initialize()
+ {
+ // cookie timeouts in the configuration settings is labeled to be in minutes, so adjust to minutes
+ cookieTimeout = config.getInt( "security.signon.timeout" ) * 60;
+ domain = config.getString( "security.signon.domain" );
+ path = config.getString( "security.signon.path" );
+ }
+
+ public boolean isEnabled()
+ {
+ return true;
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * 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.archiva.redback.users.User;
+
+import java.util.List;
+
+/**
+ * User Security Policy Settings.
+ *
+ * @version $Id$
+ * @todo roll password management into it's own object.
+ */
+public interface UserSecurityPolicy
+{
+ /**
+ * Get identifying string for the User Security Policy implementation.
+ *
+ * @return the id for the security policy implementation.
+ */
+ String getId();
+
+ // ----------------------------------------------------------------------
+ // Password Management
+ // ----------------------------------------------------------------------
+
+ /**
+ * Gets the password encoder to use.
+ *
+ * @return the PasswordEncoder implementation to use.
+ */
+ PasswordEncoder getPasswordEncoder();
+
+ /**
+ * Add a Specific Rule to the Password Rules List.
+ *
+ * @param rule the rule to add.
+ */
+ void addPasswordRule( PasswordRule rule );
+
+ /**
+ * Get the Password Rules List.
+ *
+ * @return the list of {@link PasswordRule} objects.
+ */
+ List<PasswordRule> getPasswordRules();
+
+ /**
+ * Set the Password Rules List.
+ *
+ * @param rules the list of {@link PasswordRule} objects.
+ */
+ void setPasswordRules( List<PasswordRule> rules );
+
+ /**
+ * Gets the count of Previous Passwords that should be tracked.
+ *
+ * @return the count of previous passwords to track.
+ */
+ int getPreviousPasswordsCount();
+
+ /**
+ * Sets the count of previous passwords that should be tracked.
+ *
+ * @param count the count of previous passwords to track.
+ */
+ void setPreviousPasswordsCount( int count );
+
+ /**
+ * Gets the count of login attempts to allow.
+ *
+ * @return the count of login attempts to allow.
+ */
+ int getLoginAttemptCount();
+
+ /**
+ * Sets the count of login attempts to allow.
+ *
+ * @param count the count of login attempts to allow.
+ */
+ void setLoginAttemptCount( int count );
+
+ /**
+ * Get the Validation Settings.
+ *
+ * @return the validation settings.
+ */
+ UserValidationSettings getUserValidationSettings();
+
+ /**
+ * Set the Validation Settings.
+ *
+ * @param settings the settings.
+ */
+ void setUserValidationSettings( UserValidationSettings settings );
+
+ /**
+ * Get the Single Sign On Settings.
+ *
+ * @return the single sign on settings.
+ */
+ CookieSettings getSignonCookieSettings();
+
+ /**
+ * Get the Remember Me Settings.
+ *
+ * @return the remember me settings.
+ */
+ CookieSettings getRememberMeCookieSettings();
+
+ /**
+ * Enable the policies or not.
+ * <p/>
+ * Useful in code when application startup or application init is being performed.
+ *
+ * @param enabled true if enabled.
+ */
+ void setEnabled( boolean enabled );
+
+ /**
+ * Determines if the policies are enabled or not.
+ *
+ * @return true if enabled.
+ */
+ boolean isEnabled();
+
+ /**
+ * Sets the policy of how long a password will be valid until it expires.
+ *
+ * @param passwordExpiry the number of days until a password expires. (or -1 to disable)
+ */
+ void setPasswordExpirationDays( int passwordExpiry );
+
+ /**
+ * Gets the policy of how long a password will be valid until it expires.
+ *
+ * @return the number of days until a password expires. (or -1 for disabled)
+ */
+ int getPasswordExpirationDays();
+
+ /**
+ * Gets a list of accounts which should never be locked by security policy
+ * @return accounts that should never be locked
+ */
+ List<String> getUnlockableAccounts();
+
+ /**
+ * Sets a list of accounts which should never be locked by security policy
+ * @param unlockableAccounts
+ */
+ void setUnlockableAccounts(List<String> unlockableAccounts);
+
+ /**
+ * Extension Point - Change the password of a user.
+ * <p/>
+ * This method does not check if a user is allowed to change his/her password.
+ * Any kind of authorization checks for password change allowed on guest or
+ * anonymous users needs to occur before calling this method.
+ * <p/>
+ * This method does not persist the newly changed user password.
+ * That will require a call to {@link org.apache.archiva.redback.users.UserManager#updateUser(User)}.
+ *
+ * @param user the user password to validate, remember, and encode.
+ * @throws PasswordRuleViolationException if the new password violates the password rules
+ */
+ void extensionChangePassword( User user )
+ throws PasswordRuleViolationException;
+
+ void extensionChangePassword( User user, boolean passwordChangeRequired )
+ throws PasswordRuleViolationException;
+
+ /**
+ * Extension Point - Test User for Password Expiration.
+ *
+ * @param user the user to test password expiration against.
+ * @throws MustChangePasswordException if the password has expired
+ */
+ void extensionPasswordExpiration( User user )
+ throws MustChangePasswordException;
+
+ /**
+ * Extension Point - Test if user has excessive logins
+ *
+ * @param user the user to test excessive logins against.
+ * @throws org.apache.archiva.redback.policy.AccountLockedException if the number of logins was exceeded
+ */
+ void extensionExcessiveLoginAttempts( User user )
+ throws AccountLockedException;
+
+ /**
+ * Validate the incoming {@link User#getPassword()} against the specified
+ * PasswordRules.
+ *
+ * @param user the user to validate.
+ * @throws PasswordRuleViolationException if the password is not valid
+ */
+ void validatePassword( User user )
+ throws PasswordRuleViolationException;
+}
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * UserValidationSettings
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface UserValidationSettings
+{
+ /**
+ * Get the flag indicating if a new users require email validation or not.
+ *
+ * @return
+ */
+ boolean isEmailValidationRequired();
+
+ /**
+ * Gets the number of minutes until the email validation message key
+ * should expire.
+ *
+ * @return the email validation timeout (in minutes).
+ */
+ int getEmailValidationTimeout();
+
+ /**
+ * Get the subject line for the validation email.
+ *
+ * @return the subject line for the validation email.
+ */
+ String getEmailSubject();
+}
--- /dev/null
+package org.apache.archiva.redback.policy.encoders;
+
+/*
+ * 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.archiva.redback.policy.PasswordEncoder;
+import org.apache.archiva.redback.policy.PasswordEncodingException;
+import org.apache.archiva.redback.users.Messages;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang.StringUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Abstract Password Encoder that uses the {@link MessageDigest} from JAAS.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class AbstractJAASPasswordEncoder
+ implements PasswordEncoder
+{
+ private String algorithm;
+
+ private Object systemSalt;
+
+ public AbstractJAASPasswordEncoder( String algorithm )
+ {
+ this.algorithm = algorithm;
+ }
+
+ public void setSystemSalt( Object salt )
+ {
+ this.systemSalt = salt;
+ }
+
+ public String encodePassword( String rawPass, Object salt )
+ {
+ if ( rawPass == null )
+ {
+ throw new IllegalArgumentException( "rawPass parameter cannot be null." );
+ }
+
+ MessageDigest md = null;
+ try
+ {
+ md = MessageDigest.getInstance( this.algorithm );
+ String precode = rawPass;
+
+ // Only checking for null, not using StringUtils.isNotEmpty() as
+ // whitespace can make up a valid salt.
+ if ( salt != null )
+ {
+ // Conforming to acegi password encoding standards for compatibility
+ precode += "{" + salt + "}";
+ }
+ md.update( precode.getBytes( "UTF-8" ) ); //$NON-NLS-1$
+
+ byte raw[] = md.digest();
+ Base64 base64 = new Base64( 0, new byte[0] );
+ return ( base64.encodeToString( raw ) );
+ }
+ catch ( NoSuchAlgorithmException e )
+ {
+ throw new PasswordEncodingException(
+ Messages.getString( "password.encoder.no.such.algoritm", this.algorithm ), e ); //$NON-NLS-1$
+ }
+ catch ( UnsupportedEncodingException e )
+ {
+ throw new PasswordEncodingException( Messages.getString( "password.encoder.unsupported.encoding" ),
+ e ); //$NON-NLS-1$
+ }
+ }
+
+ public boolean isPasswordValid( String encPass, String rawPass, Object salt )
+ {
+ if ( StringUtils.isEmpty( encPass ) )
+ {
+ // TODO: Throw exception?
+ return false;
+ }
+
+ // PLXREDBACK-36 Commented out because a user with an empty password can't login due to the checking.
+ // Empty password checking can also be achieve by turning on MustHavePasswordRule.
+ //if ( StringUtils.isEmpty( rawPass ) )
+ //{
+ // TODO: Throw exception?
+ // return false;
+ //}
+
+ String testPass = encodePassword( rawPass, salt );
+ return ( encPass.equals( testPass ) );
+ }
+
+ public String encodePassword( String rawPass )
+ {
+ return encodePassword( rawPass, this.systemSalt );
+ }
+
+ public boolean isPasswordValid( String encPass, String rawPass )
+ {
+ return isPasswordValid( encPass, rawPass, this.systemSalt );
+ }
+
+}
--- /dev/null
+package org.apache.archiva.redback.policy.encoders;
+
+/*
+ * 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.archiva.redback.policy.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+/**
+ * PlainText PasswordEncoder for use in situtations where the password needs to be saved as-is.
+ * See {@link PasswordEncoder#encodePassword(String)} for details.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("passwordEncoder#plaintext")
+public class PlainTextPasswordEncoder
+ implements PasswordEncoder
+{
+
+ public String encodePassword( String rawPass )
+ {
+ return rawPass;
+ }
+
+ public String encodePassword( String rawPass, Object salt )
+ {
+ return rawPass;
+ }
+
+ public boolean isPasswordValid( String encPass, String rawPass )
+ {
+ if ( encPass == null && rawPass != null )
+ {
+ return false;
+ }
+
+ return encPass.equals( rawPass );
+ }
+
+ public boolean isPasswordValid( String encPass, String rawPass, Object salt )
+ {
+ return isPasswordValid( encPass, rawPass );
+ }
+
+ public void setSystemSalt( Object salt )
+ {
+ // Ignore, not used in this plaintext encoder.
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy.encoders;
+
+/*
+ * 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.archiva.redback.policy.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+/**
+ * SHA-1 Password Encoder.
+ *
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("passwordEncoder#sha1")
+public class SHA1PasswordEncoder
+ extends AbstractJAASPasswordEncoder
+ implements PasswordEncoder
+{
+ public SHA1PasswordEncoder()
+ {
+ super( "SHA-1" ); //$NON-NLS-1$
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy.encoders;
+
+/*
+ * 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.archiva.redback.policy.PasswordEncoder;
+import org.springframework.stereotype.Service;
+
+/**
+ * SHA-256 Password Encoder.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("passwordEncoder#sha256")
+public class SHA256PasswordEncoder
+ extends AbstractJAASPasswordEncoder
+ implements PasswordEncoder
+{
+ public SHA256PasswordEncoder()
+ {
+ super( "SHA-256" );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy.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.archiva.redback.configuration.UserConfiguration;
+import org.apache.archiva.redback.policy.PasswordRule;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * AbstractPasswordRule
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public abstract class AbstractPasswordRule
+ implements PasswordRule
+{
+ protected boolean enabled = true;
+
+ @Inject @Named (value="userConfiguration")
+ protected UserConfiguration config;
+
+ public boolean isEnabled()
+ {
+ return enabled;
+ }
+
+ /**
+ * true if the security policy is required for the rule to execute
+ *
+ * @return boolean
+ */
+ public boolean requiresSecurityPolicy()
+ {
+ return false;
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy.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.archiva.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.users.User;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * Basic Password Rule. Checks that password only contains alpha-numeric characters.
+ *
+ * $Id$
+ */
+@Service("passwordRule#alpha-numeric")
+public class AlphaNumericPasswordRule
+ extends AbstractPasswordRule
+{
+ public static final String ALPHANUM_VIOLATION = "user.password.violation.alphanum.only";
+
+ public void setUserSecurityPolicy( UserSecurityPolicy policy )
+ {
+ // Ignore, policy not needed in this rule.
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user )
+ {
+ char[] password = user.getPassword().toCharArray();
+
+ for ( int i = 0; i < password.length; i++ )
+ {
+ if ( !Character.isLetterOrDigit( password[i] ) )
+ {
+ violations.addViolation( ALPHANUM_VIOLATION );
+ return;
+ }
+ }
+ }
+
+ // FIXME to constructor
+ @PostConstruct
+ public void initialize()
+ {
+ enabled = config.getBoolean( "security.policy.password.rule.alphanumeric.enabled" );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy.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.archiva.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.users.User;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * Basic Password Rule, Checks for non-empty passwords that have at least {@link #setMinimumCount(int)} of
+ * alpha characters contained within.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("passwordRule#alpha-count")
+public class AlphaPasswordRule
+ extends AbstractPasswordRule
+{
+ public static final String ALPHA_COUNT_MIN = "security.policy.password.rule.alphacount.minimum";
+
+ public static final String ALPHA_COUNT_VIOLATION = "user.password.violation.alpha";
+
+ private int minimumCount;
+
+ private int countAlphaCharacters( String password )
+ {
+ int count = 0;
+
+ if ( StringUtils.isEmpty( password ) )
+ {
+ return count;
+ }
+
+ /* TODO: Eventually upgrade to the JDK 1.5 Technique
+ *
+ * // 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++;
+ * }
+ * }
+ */
+
+ // JDK 1.4 Technique - NOT LOCALIZED.
+ for ( int i = 0; i < password.length(); i++ )
+ {
+ char c = password.charAt( i );
+ if ( Character.isLetter( c ) )
+ {
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+ public int getMinimumCount()
+ {
+ return minimumCount;
+ }
+
+ public void setMinimumCount( int minimumCount )
+ {
+ this.minimumCount = minimumCount;
+ }
+
+ public void setUserSecurityPolicy( UserSecurityPolicy policy )
+ {
+ // Ignore, policy not needed in this rule.
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user )
+ {
+ if ( countAlphaCharacters( user.getPassword() ) < this.minimumCount )
+ {
+ violations.addViolation( ALPHA_COUNT_VIOLATION,
+ new String[]{String.valueOf( minimumCount )} ); //$NON-NLS-1$
+ }
+ }
+
+ @PostConstruct
+ public void initialize()
+ {
+ enabled = config.getBoolean( "security.policy.password.rule.alphacount.enabled" );
+ this.minimumCount = config.getInt( ALPHA_COUNT_MIN );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy.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.archiva.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.users.User;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * Basic Password Rule, Checks for non-empty passwords that have between {@link #setMinimumCharacters(int)} and
+ * {@link #setMaximumCharacters(int)} characters in length.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("passwordRule#character-length")
+public class CharacterLengthPasswordRule
+ extends AbstractPasswordRule
+{
+ public static final String CHARACTER_LENGTH_MIN = "security.policy.password.rule.characterlength.minimum";
+
+ public static final String CHARACTER_LENGTH_MAX = "security.policy.password.rule.characterlength.maximum";
+
+ public static final String CHARACTER_LENGTH_MISCONFIGURED_VIOLATION =
+ "user.password.violation.length.misconfigured";
+
+ public static final String CHARACTER_LENGTH_VIOLATION = "user.password.violation.length";
+
+ public static final int DEFAULT_CHARACTER_LENGTH_MAX = 8;
+
+ private int minimumCharacters;
+
+ private int maximumCharacters;
+
+ 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 setUserSecurityPolicy( UserSecurityPolicy policy )
+ {
+ // Ignore, policy not needed in this rule.
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user )
+ {
+ if ( minimumCharacters > maximumCharacters )
+ {
+ /* this should caught up front during the configuration of the component */
+ // TODO: Throw runtime exception instead?
+ violations.addViolation( CHARACTER_LENGTH_MISCONFIGURED_VIOLATION, new String[]{
+ String.valueOf( minimumCharacters ), String.valueOf( maximumCharacters )} ); //$NON-NLS-1$
+ }
+
+ String password = user.getPassword();
+
+ if ( StringUtils.isEmpty( password ) || password.length() < minimumCharacters ||
+ password.length() > maximumCharacters )
+ {
+ violations.addViolation( CHARACTER_LENGTH_VIOLATION, new String[]{String.valueOf( minimumCharacters ),
+ String.valueOf( maximumCharacters )} ); //$NON-NLS-1$
+ }
+ }
+
+ @PostConstruct
+ public void initialize()
+ {
+ enabled = config.getBoolean( "security.policy.password.rule.characterlength.enabled" );
+ this.minimumCharacters = config.getInt( CHARACTER_LENGTH_MIN );
+ this.maximumCharacters = config.getInt( CHARACTER_LENGTH_MAX );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy.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.archiva.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.users.User;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * Basic Password Rule, Checks for non-empty Passwords in non guest users.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("passwordRule#must-have")
+public class MustHavePasswordRule
+ extends AbstractPasswordRule
+{
+ public static final String MISSING_PASSWORD_VIOLATION = "user.password.violation.missing";
+
+ public void setUserSecurityPolicy( UserSecurityPolicy policy )
+ {
+ // Ignore, policy not needed in this rule.
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user )
+ {
+ if ( StringUtils.isEmpty( user.getPassword() ) )
+ {
+ violations.addViolation( MISSING_PASSWORD_VIOLATION ); //$NON-NLS-1$
+ }
+ }
+
+ @PostConstruct
+ public void initialize()
+ {
+ enabled = config.getBoolean( "security.policy.password.rule.musthave.enabled" );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy.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.archiva.redback.users.User;
+import org.apache.archiva.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * Basic Password Rule, Checks for non-empty passwords that have at least {@link #setMinimumCount(int)} of
+ * numerical characters contained within.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("passwordRule#numerical-count")
+public class NumericalPasswordRule
+ extends AbstractPasswordRule
+{
+ public static final String MINIMUM = "security.policy.password.rule.numericalcount.minimum";
+
+ public static final String NUMERICAL_COUNT_VIOLATION = "user.password.violation.numeric";
+
+ private int minimumCount;
+
+ private int countDigitCharacters( String password )
+ {
+ int count = 0;
+
+ if ( StringUtils.isEmpty( password ) )
+ {
+ return count;
+ }
+
+ /* TODO: Eventually upgrade to the JDK 1.5 Technique
+ *
+ * // Doing this via iteration of code points to take in account localized numbers.
+ * for ( int i = 0; i < password.length(); i++ )
+ * {
+ * int codepoint = password.codePointAt( i );
+ * if ( Character.isDigit( codepoint ) )
+ * {
+ * count++;
+ * }
+ * }
+ */
+
+ // JDK 1.4 Technique - NOT LOCALIZED.
+ for ( int i = 0; i < password.length(); i++ )
+ {
+ char c = password.charAt( i );
+ if ( Character.isDigit( c ) )
+ {
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+ public int getMinimumCount()
+ {
+ return minimumCount;
+ }
+
+ public void setMinimumCount( int minimumCount )
+ {
+ this.minimumCount = minimumCount;
+ }
+
+ public void setUserSecurityPolicy( UserSecurityPolicy policy )
+ {
+ // Ignore, policy not needed in this rule.
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user )
+ {
+ if ( countDigitCharacters( user.getPassword() ) < this.minimumCount )
+ {
+ violations.addViolation( NUMERICAL_COUNT_VIOLATION,
+ new String[]{String.valueOf( minimumCount )} ); //$NON-NLS-1$
+ }
+ }
+
+ @PostConstruct
+ public void initialize()
+ {
+ enabled = config.getBoolean( "security.policy.password.rule.numericalcount.enabled" );
+ this.minimumCount = config.getInt( MINIMUM );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy.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.archiva.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.users.User;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import java.util.Iterator;
+
+/**
+ * Password Rule, Checks supplied password found at {@link User#getPassword()} against
+ * the {@link User#getPreviousEncodedPasswords()} to ensure that a password is not reused.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("passwordRule#reuse")
+public class ReusePasswordRule
+ extends AbstractPasswordRule
+{
+ public static final String REUSE_VIOLATION = "user.password.violation.reuse";
+
+ private UserSecurityPolicy securityPolicy;
+
+ public void setUserSecurityPolicy( UserSecurityPolicy policy )
+ {
+ this.securityPolicy = policy;
+ }
+
+ /**
+ * true if the security policy is required for this rule
+ *
+ * @return boolean
+ */
+ public boolean requiresSecurityPolicy()
+ {
+ return true;
+ }
+
+ public int getPreviousPasswordCount()
+ {
+ if ( securityPolicy == null )
+ {
+ throw new IllegalStateException( "The security policy has not yet been set." );
+ }
+
+ return securityPolicy.getPreviousPasswordsCount();
+ }
+
+ private boolean hasReusedPassword( User user, String password )
+ {
+ if ( securityPolicy == null )
+ {
+ throw new IllegalStateException( "The security policy has not yet been set." );
+ }
+
+ if ( StringUtils.isEmpty( password ) )
+ {
+ return false;
+ }
+
+ String encodedPassword = securityPolicy.getPasswordEncoder().encodePassword( password );
+
+ int checkCount = getPreviousPasswordCount();
+
+ Iterator<String> it = user.getPreviousEncodedPasswords().iterator();
+
+ while ( it.hasNext() && checkCount >= 0 )
+ {
+ String prevEncodedPassword = it.next();
+ if ( encodedPassword.equals( prevEncodedPassword ) )
+ {
+ return true;
+ }
+ checkCount--;
+ }
+
+ return false;
+ }
+
+ public void setPreviousPasswordCount( int previousPasswordCount )
+ {
+ securityPolicy.setPreviousPasswordsCount( previousPasswordCount );
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user )
+ {
+ String password = user.getPassword();
+
+ if ( hasReusedPassword( user, password ) )
+ {
+ violations.addViolation( REUSE_VIOLATION,
+ new String[]{String.valueOf( getPreviousPasswordCount() )} ); //$NON-NLS-1$
+ }
+ }
+
+ @PostConstruct
+ public void initialize()
+ {
+ enabled = config.getBoolean( "security.policy.password.rule.reuse.enabled" );
+ }
+}
--- /dev/null
+package org.apache.archiva.redback.policy.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.archiva.redback.policy.PasswordRuleViolations;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.users.User;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * Basic Password Rule. Checks that password does not have whitespaces in it.
+ *
+ * $Id$
+ */
+@Service("passwordRule#no-whitespaces")
+public class WhitespacePasswordRule
+ extends AbstractPasswordRule
+{
+ public static final String NO_WHITE_SPACE_VIOLATION = "user.password.violation.whitespace.detected";
+
+ public void setUserSecurityPolicy( UserSecurityPolicy policy )
+ {
+ // Ignore, policy not needed in this rule.
+ }
+
+ public void testPassword( PasswordRuleViolations violations, User user )
+ {
+ if ( user.getPassword() != null )
+ {
+ char[] password = user.getPassword().toCharArray();
+
+ for ( int i = 0; i < password.length; i++ )
+ {
+ if ( Character.isWhitespace( password[i] ) )
+ {
+ violations.addViolation( NO_WHITE_SPACE_VIOLATION );
+ return;
+ }
+ }
+ }
+ }
+
+ @PostConstruct
+ public void initialize()
+ {
+ enabled = config.getBoolean( "security.policy.password.rule.nowhitespace.enabled" );
+ }
+}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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 javax.inject.Inject;
-import javax.inject.Named;
-
-import org.apache.archiva.redback.configuration.UserConfiguration;
-
-/**
- * Base class for cookie settings. These will only differ by their configuration keys.
- *
- * @todo not sure if having the domain and path in the general configuration is a good idea - this is probably something
- * customised once for all cookies and applications. Should it be in a sharead configuration file, under a sharead key,
- * or perhaps even configured at the application server level? (ie, in Naming).
- */
-public abstract class AbstractCookieSettings
- implements CookieSettings
-{
- @Inject @Named(value="userConfiguration")
- protected UserConfiguration config;
-
- /**
- * Timeout (in minutes) for the sign on cookie.
- */
- protected int cookieTimeout;
-
- /**
- * The domain for the cookie.
- */
- protected String domain;
-
- /**
- * The path for the cookie.
- */
- protected String path;
-
- public int getCookieTimeout()
- {
- return cookieTimeout;
- }
-
- public String getDomain()
- {
- return domain;
- }
-
- public String getPath()
- {
- return path;
- }
-
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * 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.archiva.redback.users.User;
-
-/**
- * AccountLockedException
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class AccountLockedException
- extends PolicyViolationException
-{
- private User user;
-
- public AccountLockedException( String message, User user )
- {
- super( message );
- this.user = user;
- }
-
- public User getUser()
- {
- return user;
- }
-}
-
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-/**
- * CookieSettings
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public interface CookieSettings
-{
- /**
- * Gets the Cookie timeout (in minutes) for the signon cookie.
- *
- * @return the timeout in minutes
- */
- int getCookieTimeout();
-
- /**
- * Gets the domain to use for the signon cookie.
- *
- * @return the domain
- */
- String getDomain();
-
- /**
- * Gets the path to use for the signon cookie.
- *
- * @return the path
- */
- String getPath();
-
- /**
- * Enable or disables the remember me features of the application.
- *
- * @return true if remember me settings are enabled.
- */
- boolean isEnabled();
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.archiva.redback.configuration.UserConfiguration;
-import org.apache.archiva.redback.users.User;
-import org.codehaus.plexus.redback.policy.rules.MustHavePasswordRule;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-import javax.inject.Inject;
-import javax.inject.Named;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-/**
- * User Security Policy.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service( "userSecurityPolicy" )
-public class DefaultUserSecurityPolicy
- implements UserSecurityPolicy
-{
- private static final String ENABLEMENT_KEY = "UserSecurityPolicy" + ":ENABLED";
-
- public static final String PASSWORD_RETENTION_COUNT = "security.policy.password.previous.count";
-
- public static final String LOGIN_ATTEMPT_COUNT = "security.policy.allowed.login.attempt";
-
- public static final String PASSWORD_EXPIRATION_ENABLED = "security.policy.password.expiration.enabled";
-
- public static final String PASSWORD_EXPIRATION = "security.policy.password.expiration.days";
-
- public static final String PASSWORD_ENCODER = "security.policy.password.encoder";
-
- public static final String UNLOCKABLE_ACCOUNTS = "security.policy.unlockable.accounts";
-
- private static final Logger log = LoggerFactory.getLogger( DefaultUserSecurityPolicy.class );
-
- private PasswordRule defaultPasswordRule = new MustHavePasswordRule();
-
- @Inject
- @Named( value = "userConfiguration" )
- private UserConfiguration config;
-
- @Inject
- @Named( value = "passwordEncoder#sha256" )
- private PasswordEncoder passwordEncoder;
-
- @Inject
- @Named( value = "userValidationSettings" )
- private UserValidationSettings userValidationSettings;
-
- @Inject
- @Named( value = "cookieSettings#rememberMe" )
- private CookieSettings rememberMeCookieSettings;
-
- @Inject
- @Named( value = "cookieSettings#signon" )
- private CookieSettings signonCookieSettings;
-
- // TODO use something more generic to be able to do change about container
- @Inject
- private ApplicationContext applicationContext;
-
- /**
- * The List of {@link PasswordRule} objects.
- */
- @Inject
- private List<PasswordRule> rules = new ArrayList<PasswordRule>( 0 );
-
- private int previousPasswordsCount;
-
- private int loginAttemptCount;
-
- private int passwordExpirationDays;
-
- private boolean passwordExpirationEnabled;
-
- private List<String> unlockableAccounts;
-
-
- // ---------------------------------------
- // Component lifecycle
- // ---------------------------------------
- // TODO move this to constructor
- @SuppressWarnings( "unchecked" )
- @PostConstruct
- public void initialize()
- {
- configurePolicy();
-
- configureEncoder();
-
- // In some configurations, rules can be unset.
- if ( rules == null )
- {
- // Set rules to prevent downstream NPE.
- rules = new ArrayList<PasswordRule>( 1 );
- }
-
- if ( rules.isEmpty() )
- {
- // there should be at least one rule
- addPasswordRule( defaultPasswordRule );
- }
- }
-
- private void configureEncoder()
- {
- String encoder = config.getString( PASSWORD_ENCODER );
-
- if ( encoder != null )
- {
- this.passwordEncoder = applicationContext.getBean( "passwordEncoder#" + encoder, PasswordEncoder.class );
- }
- }
-
- private void configurePolicy()
- {
- this.previousPasswordsCount = config.getInt( PASSWORD_RETENTION_COUNT );
- this.loginAttemptCount = config.getInt( LOGIN_ATTEMPT_COUNT );
- this.passwordExpirationEnabled = config.getBoolean( PASSWORD_EXPIRATION_ENABLED );
- this.passwordExpirationDays = config.getInt( PASSWORD_EXPIRATION );
- this.unlockableAccounts = config.getList( UNLOCKABLE_ACCOUNTS );
- }
-
-
- public String getId()
- {
- return "Default User Security Policy";
- }
-
- public int getPreviousPasswordsCount()
- {
- return previousPasswordsCount;
- }
-
- public List<String> getUnlockableAccounts()
- {
- if ( unlockableAccounts == null )
- {
- unlockableAccounts = new ArrayList<String>( 0 );
- }
- return unlockableAccounts;
- }
-
- /**
- * Sets a list of accounts which should never be locked by security policy
- *
- * @param unlockableAccounts
- */
- public void setUnlockableAccounts( List<String> unlockableAccounts )
- {
- this.unlockableAccounts = unlockableAccounts;
- }
-
- /**
- * Sets the count of previous passwords that should be tracked.
- *
- * @param count the count of previous passwords to track.
- */
- public void setPreviousPasswordsCount( int count )
- {
- this.previousPasswordsCount = count;
- }
-
- public int getLoginAttemptCount()
- {
- return loginAttemptCount;
- }
-
- public void setLoginAttemptCount( int count )
- {
- this.loginAttemptCount = count;
- }
-
- /**
- * Get the password encoder to be used for password operations
- *
- * @return the encoder
- */
- public PasswordEncoder getPasswordEncoder()
- {
- return passwordEncoder;
- }
-
- public boolean isEnabled()
- {
- Boolean bool = (Boolean) PolicyContext.getContext().get( ENABLEMENT_KEY );
- return bool == null || bool.booleanValue();
- }
-
- public void setEnabled( boolean enabled )
- {
- PolicyContext.getContext().put( ENABLEMENT_KEY, Boolean.valueOf( enabled ) );
- }
-
- /**
- * Add a Specific Rule to the Password Rules List.
- *
- * @param rule the rule to add.
- */
- public void addPasswordRule( PasswordRule rule )
- {
- // TODO: check for duplicates? if so, check should only be based on Rule class name.
-
- rule.setUserSecurityPolicy( this );
- this.rules.add( rule );
- }
-
- /**
- * Get the Password Rules List.
- *
- * @return the list of {@link PasswordRule} objects.
- */
- public List<PasswordRule> getPasswordRules()
- {
- return this.rules;
- }
-
- /**
- * Set the Password Rules List.
- *
- * @param rules the list of {@link PasswordRule} objects.
- */
- public void setPasswordRules( List<PasswordRule> rules )
- {
- this.rules.clear();
-
- if ( rules == null )
- {
- return;
- }
-
- // Intentionally iterating to ensure policy settings in provided rules.
-
- for ( PasswordRule rule : rules )
- {
- addPasswordRule( rule );
- }
- }
-
- public void extensionPasswordExpiration( User user )
- throws MustChangePasswordException
- {
- if ( passwordExpirationEnabled && !getUnlockableAccounts().contains( user.getUsername() ) )
- {
- Calendar expirationDate = Calendar.getInstance();
- expirationDate.setTime( user.getLastPasswordChange() );
- expirationDate.add( Calendar.DAY_OF_MONTH, passwordExpirationDays );
- Calendar now = Calendar.getInstance();
-
- if ( now.after( expirationDate ) )
- {
- log.info( "User '{}' flagged for password expiry (expired on: {})", user.getUsername(),
- expirationDate );
- user.setPasswordChangeRequired( true );
- throw new MustChangePasswordException( "Password Expired, You must change your password.", user );
- }
- }
- }
-
- public void extensionExcessiveLoginAttempts( User user )
- throws AccountLockedException
- {
- if ( !getUnlockableAccounts().contains( user.getUsername() ) )
- {
- int attempt = user.getCountFailedLoginAttempts();
- attempt++;
- user.setCountFailedLoginAttempts( attempt );
-
- if ( attempt >= loginAttemptCount )
- {
- log.info( "User '{}' locked due to excessive login attempts: {}", user.getUsername(), attempt );
- user.setLocked( true );
- throw new AccountLockedException( "Account " + user.getUsername() + " is locked.", user );
- }
- }
- }
-
- public void extensionChangePassword( User user )
- throws PasswordRuleViolationException
- {
- extensionChangePassword( user, false );
- }
-
- public void extensionChangePassword( User user, boolean passwordChangeRequired )
- throws PasswordRuleViolationException
- {
- validatePassword( user );
-
- // set the current encoded password.
- user.setEncodedPassword( passwordEncoder.encodePassword( user.getPassword() ) );
- user.setPassword( null );
-
- // push new password onto list of previous password.
- List<String> previousPasswords = new ArrayList<String>( 1 );
- previousPasswords.add( user.getEncodedPassword() );
-
- if ( !user.getPreviousEncodedPasswords().isEmpty() )
- {
- int oldCount = Math.min( previousPasswordsCount - 1, user.getPreviousEncodedPasswords().size() );
- //modified sublist start index as the previous value results to nothing being added to the list.
- List<String> sublist = user.getPreviousEncodedPasswords().subList( 0, oldCount );
- previousPasswords.addAll( sublist );
- }
-
- user.setPreviousEncodedPasswords( previousPasswords );
- user.setPasswordChangeRequired( passwordChangeRequired );
-
- // Update timestamp for password change.
- user.setLastPasswordChange( new Date() );
- }
-
- public void validatePassword( User user )
- throws PasswordRuleViolationException
- {
- if ( isEnabled() )
- {
- PasswordRuleViolations violations = new PasswordRuleViolations();
-
- for ( PasswordRule rule : this.rules )
- {
- if ( rule.isEnabled() )
- {
- if ( rule.requiresSecurityPolicy() )
- {
- rule.setUserSecurityPolicy( this );
- }
-
- rule.testPassword( violations, user );
- }
- }
-
- if ( violations.hasViolations() )
- {
- PasswordRuleViolationException exception = new PasswordRuleViolationException();
- exception.setViolations( violations );
- throw exception;
- }
- }
-
- // If you got this far, then ensure that the password is never null.
- if ( user.getPassword() == null )
- {
- user.setPassword( "" );
- }
- }
-
- public int getPasswordExpirationDays()
- {
- return passwordExpirationDays;
- }
-
- public void setPasswordExpirationDays( int passwordExpiry )
- {
- this.passwordExpirationDays = passwordExpiry;
- }
-
- public UserValidationSettings getUserValidationSettings()
- {
- return userValidationSettings;
- }
-
- public void setUserValidationSettings( UserValidationSettings settings )
- {
- this.userValidationSettings = settings;
- }
-
- public CookieSettings getRememberMeCookieSettings()
- {
- return rememberMeCookieSettings;
- }
-
- public CookieSettings getSignonCookieSettings()
- {
- return signonCookieSettings;
- }
-
- public UserConfiguration getConfig()
- {
- return config;
- }
-
- public void setConfig( UserConfiguration config )
- {
- this.config = config;
- }
-
-
- public void setPasswordEncoder( PasswordEncoder passwordEncoder )
- {
- this.passwordEncoder = passwordEncoder;
- }
-
- public void setRememberMeCookieSettings( CookieSettings rememberMeCookieSettings )
- {
- this.rememberMeCookieSettings = rememberMeCookieSettings;
- }
-
- public void setSignonCookieSettings( CookieSettings signonCookieSettings )
- {
- this.signonCookieSettings = signonCookieSettings;
- }
-
- public void setRules( List<PasswordRule> rules )
- {
- this.rules = rules;
- }
-
- public void setDefaultPasswordRule( PasswordRule defaultPasswordRule )
- {
- this.defaultPasswordRule = defaultPasswordRule;
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.archiva.redback.configuration.UserConfiguration;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-import javax.annotation.Resource;
-
-/**
- * DefaultUserValidationSettings
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("userValidationSettings")
-public class DefaultUserValidationSettings
- implements UserValidationSettings
-{
- @Resource (name="userConfiguration")
- private UserConfiguration config;
-
- private boolean emailValidationRequired;
-
- private int emailValidationTimeout;
-
- private String emailSubject;
-
- public boolean isEmailValidationRequired()
- {
- return emailValidationRequired;
- }
-
- public int getEmailValidationTimeout()
- {
- return emailValidationTimeout;
- }
-
- public String getEmailSubject()
- {
- return emailSubject;
- }
-
- @PostConstruct
- public void initialize()
- {
- this.emailValidationRequired = config.getBoolean( "email.validation.required" );
- this.emailValidationTimeout = config.getInt( "email.validation.timeout" );
- this.emailSubject = config.getString( "email.validation.subject" );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-import org.apache.archiva.redback.users.User;
-
-/*
- * 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.
- */
-
-/**
- * MustChangePasswordException
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class MustChangePasswordException
- extends PolicyViolationException
-{
- private final User user;
-
- public MustChangePasswordException( String message, User user )
- {
- super( message );
- this.user = user;
- }
-
- public User getUser()
- {
- return user;
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * 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.
- */
-
-/**
- * <p>
- * Interface for performing authentication operations on a password.
- * </p>
- *
- * <p>Javadoc about encoding and salts copied from Acegi Security.</p>
- *
- * @author colin sampaleanu
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public interface PasswordEncoder
-{
-
- /**
- * <p>
- * Sets the system wide salt to use in the encoder.
- * </p>
- *
- * <p>
- * The specified salt will potentially be used by the implementation to "salt" the initial value before
- * encoding. A salt is usually a user-specific value which is added to the password before the digest is computed.
- * This means that computation of digests for common dictionary words will be different than those in the backend
- * store, because the dictionary word digests will not reflect the addition of the salt. If a per-user salt is
- * used (rather than a system-wide salt), it also means users with the same password will have different digest
- * encoded passwords in the backend store.
- * </p>
- *
- * @param salt the salt to use as a default for the encoder.
- */
- void setSystemSalt( Object salt );
-
- /**
- * <p>
- * Encodes the specified raw password with an implementation specific algorithm, using the system wide salt.
- * </p>
- *
- * <p>
- * This will generally be a one-way message digest such as MD5 or SHA, but may also be a plaintext
- * variant which does no encoding at all, but rather returns the same password it was fed. The latter is useful to
- * plug in when the original password must be stored as-is.
- * </p>
- *
- * @param rawPass the password to encode
- *
- * @return encoded password
- */
- String encodePassword( String rawPass );
-
- /**
- * <p>
- * Encodes the specified raw password with an implementation specific algorithm, using user specific salt.
- * </p>
- *
- * <p>
- * This will generally be a one-way message digest such as MD5 or SHA, but may also be a plaintext
- * variant which does no encoding at all, but rather returns the same password it was fed. The latter is useful to
- * plug in when the original password must be stored as-is.
- * </p>
- *
- * <p>
- * The specified salt will potentially be used by the implementation to "salt" the initial value before
- * encoding. A salt is usually a user-specific value which is added to the password before the digest is computed.
- * This means that computation of digests for common dictionary words will be different than those in the backend
- * store, because the dictionary word digests will not reflect the addition of the salt. If a per-user salt is
- * used (rather than a system-wide salt), it also means users with the same password will have different digest
- * encoded passwords in the backend store.
- * </p>
- *
- * @param rawPass the password to encode
- * @param salt optionally used by the implementation to "salt" the raw password before encoding.
- * A <code>null</code> value is legal.
- * @return encoded password
- */
- String encodePassword( String rawPass, Object salt );
-
-
- /**
- * <p>
- * Validates a specified "raw" password against an encoded password, using the system wide salt.
- * </p>
- *
- * <p>
- * The encoded password should have previously been generated by {@link #encodePassword(String)}.
- * This method will encode the <code>rawPass</code> (using the system wide <code>salt</code>), and then
- * compared it with the presented <code>encPass</code>.
- * </p>
- *
- * <p>
- * For an explanation of salts, please refer to {@link #setSystemSalt(Object)}.
- * </p>
- *
- * @param encPass a pre-encoded password
- * @param rawPass a raw password to encode and compare against the pre-encoded password
- *
- * @return true if the password is valid , false otherwise
- */
- boolean isPasswordValid( String encPass, String rawPass );
-
- /**
- * <p>
- * Validates a specified "raw" password against an encoded password, using a user specific salt.
- * </p>
- *
- * <p>
- * The encoded password should have previously been generated by {@link #encodePassword(String,
- * Object)}. This method will encode the <code>rawPass</code> (using the optional <code>salt</code>), and then
- * compared it with the presented <code>encPass</code>.
- * </p>
- *
- * <p>
- * For a discussion of salts, please refer to {@link #encodePassword(String, Object)}.
- * </p>
- *
- * @param encPass a pre-encoded password
- * @param rawPass a raw password to encode and compare against the pre-encoded password
- * @param salt optionally used by the implementation to "salt" the raw password before encoding. A
- * <code>null</code> value is legal.
- *
- * @return true if the password is valid , false otherwise
- */
- boolean isPasswordValid( String encPass, String rawPass, Object salt );
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * 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.
- */
-
-/**
- * Password Encoding Exception.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class PasswordEncodingException
- extends RuntimeException
-{
- public PasswordEncodingException()
- {
- super();
- }
-
- public PasswordEncodingException( String message, Throwable cause )
- {
- super( message, cause );
- }
-
- public PasswordEncodingException( String message )
- {
- super( message );
- }
-
- public PasswordEncodingException( Throwable cause )
- {
- super( cause );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * 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.archiva.redback.users.User;
-
-/**
- * A Password Rule
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public interface PasswordRule
-{
-
- /**
- * Tests if rule is enabled (or not)
- */
- boolean isEnabled();
-
- /**
- * Sets the User Security Policy to use.
- *
- * The policy is set once per instance of a PasswordRule object.
- *
- * @param policy the policy to use.
- */
- void setUserSecurityPolicy(UserSecurityPolicy policy);
-
-
- /**
- * true if the security policy has been set on the rule
- *
- * @return boolean
- */
- boolean requiresSecurityPolicy();
-
- /**
- * Tests the {@link User#getPassword()} for a valid password, based on rule.
- *
- * @param violations the place to add any password rule violations that this rule has discovered.
- * @param user the User to test.
- */
- void testPassword( PasswordRuleViolations violations, User user );
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * 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.
- */
-
-/**
- * Password Rule Violations Exception
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class PasswordRuleViolationException
- extends RuntimeException
-{
- private static final long serialVersionUID = -4686338829234880328L;
-
- private PasswordRuleViolations violations;
-
- public PasswordRuleViolationException()
- {
- }
-
- public PasswordRuleViolationException( String message, Throwable cause )
- {
- super( message, cause );
- }
-
- public PasswordRuleViolationException( String message )
- {
- super( message );
- }
-
- public PasswordRuleViolationException( Throwable cause )
- {
- super( cause );
- }
-
- public PasswordRuleViolations getViolations()
- {
- return violations;
- }
-
- public void setViolations( PasswordRuleViolations violations )
- {
- this.violations = violations;
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * 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.archiva.redback.users.Messages;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Password Rule Violations
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class PasswordRuleViolations
-{
- private List<MessageReference> violations;
-
- public class MessageReference
- {
- String key;
-
- String[] args;
-
- public String getKey()
- {
- return key;
- }
-
- public String[] getArgs()
- {
- return args;
- }
- }
-
- /**
- * Construct a Password Rule Violations object.
- */
- public PasswordRuleViolations()
- {
- violations = new ArrayList<MessageReference>( 0 );
- }
-
- /**
- * Empty out the list of violations.
- */
- public void reset()
- {
- violations.clear();
- }
-
- /**
- * Add a violation to the underlying list.
- *
- * @param key the bundle/localization key for the message.
- */
- 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, String[] args )
- {
- MessageReference mesgref = new MessageReference();
- mesgref.key = key;
- mesgref.args = args;
- violations.add( mesgref );
- }
-
- /**
- * Get the List of Violations as localized and post-processed {@link String}s.
- *
- * @return the List of {@link String} objects.
- */
- public List<String> getLocalizedViolations()
- {
- List<String> msgs = new ArrayList<String>( violations.size() );
-
- for ( MessageReference msgref : violations )
- {
- msgs.add( Messages.getString( msgref.key, msgref.args ) );
- }
-
- return msgs;
- }
-
- /**
- * Simple test to see if there are any violations.
- *
- * @return true if there are any violations.
- */
- public boolean hasViolations()
- {
- return !violations.isEmpty();
- }
-
- public List<MessageReference> getViolations()
- {
- return violations;
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * 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.HashMap;
-import java.util.Map;
-
-/**
- * PolicyContext - A Thread Local Context.
- * Useful for managing policy operations on a thread local point of view.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class PolicyContext
-{
- static ThreadLocal<PolicyContext> policyContext = new PolicyContextThreadLocal();
-
- Map<Object, Object> context;
-
- public PolicyContext( Map<Object, Object> map )
- {
- context = map;
- }
-
- public static void setContext( PolicyContext context )
- {
- policyContext.set( context );
- }
-
- public static PolicyContext getContext()
- {
- PolicyContext ctx = (PolicyContext) policyContext.get();
- if ( ctx == null )
- {
- ctx = new PolicyContext( new HashMap<Object, Object>() );
- setContext( ctx );
- }
-
- return ctx;
- }
-
- public Object get( Object key )
- {
- return context.get( key );
- }
-
- public void put( Object key, Object value )
- {
- context.put( key, value );
- }
-
- private static class PolicyContextThreadLocal
- extends ThreadLocal<PolicyContext>
- {
- protected PolicyContext initialValue()
- {
- return new PolicyContext( new HashMap<Object, Object>() );
- }
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * 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.
- */
-
-/**
- * PolicyViolationException
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class PolicyViolationException
- extends Exception
-{
-
- public PolicyViolationException()
- {
- super();
- }
-
- public PolicyViolationException( String message, Throwable cause )
- {
- super( message, cause );
- }
-
- public PolicyViolationException( String message )
- {
- super( message );
- }
-
- public PolicyViolationException( Throwable cause )
- {
- super( cause );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-
-/**
- * RememberMeCookieSettings
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("cookieSettings#rememberMe")
-public class RememberMeCookieSettings
- extends AbstractCookieSettings
-{
- private boolean enabled;
-
- public boolean isEnabled()
- {
- return enabled;
- }
-
- @PostConstruct
- public void initialize()
- {
- this.cookieTimeout = config.getInt( "security.rememberme.timeout" );
- this.domain = config.getString( "security.rememberme.domain" );
- this.path = config.getString( "security.rememberme.path" );
- this.enabled = config.getBoolean( "security.rememberme.enabled" );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-
-/**
- * SignonCookieSettings
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("cookieSettings#signon")
-public class SignonCookieSettings
- extends AbstractCookieSettings
-{
- @PostConstruct
- public void initialize()
- {
- // cookie timeouts in the configuration settings is labeled to be in minutes, so adjust to minutes
- cookieTimeout = config.getInt( "security.signon.timeout" ) * 60;
- domain = config.getString( "security.signon.domain" );
- path = config.getString( "security.signon.path" );
- }
-
- public boolean isEnabled()
- {
- return true;
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * 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.archiva.redback.users.User;
-
-import java.util.List;
-
-/**
- * User Security Policy Settings.
- *
- * @version $Id$
- * @todo roll password management into it's own object.
- */
-public interface UserSecurityPolicy
-{
- /**
- * Get identifying string for the User Security Policy implementation.
- *
- * @return the id for the security policy implementation.
- */
- String getId();
-
- // ----------------------------------------------------------------------
- // Password Management
- // ----------------------------------------------------------------------
-
- /**
- * Gets the password encoder to use.
- *
- * @return the PasswordEncoder implementation to use.
- */
- PasswordEncoder getPasswordEncoder();
-
- /**
- * Add a Specific Rule to the Password Rules List.
- *
- * @param rule the rule to add.
- */
- void addPasswordRule( PasswordRule rule );
-
- /**
- * Get the Password Rules List.
- *
- * @return the list of {@link PasswordRule} objects.
- */
- List<PasswordRule> getPasswordRules();
-
- /**
- * Set the Password Rules List.
- *
- * @param rules the list of {@link PasswordRule} objects.
- */
- void setPasswordRules( List<PasswordRule> rules );
-
- /**
- * Gets the count of Previous Passwords that should be tracked.
- *
- * @return the count of previous passwords to track.
- */
- int getPreviousPasswordsCount();
-
- /**
- * Sets the count of previous passwords that should be tracked.
- *
- * @param count the count of previous passwords to track.
- */
- void setPreviousPasswordsCount( int count );
-
- /**
- * Gets the count of login attempts to allow.
- *
- * @return the count of login attempts to allow.
- */
- int getLoginAttemptCount();
-
- /**
- * Sets the count of login attempts to allow.
- *
- * @param count the count of login attempts to allow.
- */
- void setLoginAttemptCount( int count );
-
- /**
- * Get the Validation Settings.
- *
- * @return the validation settings.
- */
- UserValidationSettings getUserValidationSettings();
-
- /**
- * Set the Validation Settings.
- *
- * @param settings the settings.
- */
- void setUserValidationSettings( UserValidationSettings settings );
-
- /**
- * Get the Single Sign On Settings.
- *
- * @return the single sign on settings.
- */
- CookieSettings getSignonCookieSettings();
-
- /**
- * Get the Remember Me Settings.
- *
- * @return the remember me settings.
- */
- CookieSettings getRememberMeCookieSettings();
-
- /**
- * Enable the policies or not.
- * <p/>
- * Useful in code when application startup or application init is being performed.
- *
- * @param enabled true if enabled.
- */
- void setEnabled( boolean enabled );
-
- /**
- * Determines if the policies are enabled or not.
- *
- * @return true if enabled.
- */
- boolean isEnabled();
-
- /**
- * Sets the policy of how long a password will be valid until it expires.
- *
- * @param passwordExpiry the number of days until a password expires. (or -1 to disable)
- */
- void setPasswordExpirationDays( int passwordExpiry );
-
- /**
- * Gets the policy of how long a password will be valid until it expires.
- *
- * @return the number of days until a password expires. (or -1 for disabled)
- */
- int getPasswordExpirationDays();
-
- /**
- * Gets a list of accounts which should never be locked by security policy
- * @return accounts that should never be locked
- */
- List<String> getUnlockableAccounts();
-
- /**
- * Sets a list of accounts which should never be locked by security policy
- * @param unlockableAccounts
- */
- void setUnlockableAccounts(List<String> unlockableAccounts);
-
- /**
- * Extension Point - Change the password of a user.
- * <p/>
- * This method does not check if a user is allowed to change his/her password.
- * Any kind of authorization checks for password change allowed on guest or
- * anonymous users needs to occur before calling this method.
- * <p/>
- * This method does not persist the newly changed user password.
- * That will require a call to {@link org.apache.archiva.redback.users.UserManager#updateUser(User)}.
- *
- * @param user the user password to validate, remember, and encode.
- * @throws PasswordRuleViolationException if the new password violates the password rules
- */
- void extensionChangePassword( User user )
- throws PasswordRuleViolationException;
-
- void extensionChangePassword( User user, boolean passwordChangeRequired )
- throws PasswordRuleViolationException;
-
- /**
- * Extension Point - Test User for Password Expiration.
- *
- * @param user the user to test password expiration against.
- * @throws MustChangePasswordException if the password has expired
- */
- void extensionPasswordExpiration( User user )
- throws MustChangePasswordException;
-
- /**
- * Extension Point - Test if user has excessive logins
- *
- * @param user the user to test excessive logins against.
- * @throws AccountLockedException if the number of logins was exceeded
- */
- void extensionExcessiveLoginAttempts( User user )
- throws AccountLockedException;
-
- /**
- * Validate the incoming {@link User#getPassword()} against the specified
- * PasswordRules.
- *
- * @param user the user to validate.
- * @throws PasswordRuleViolationException if the password is not valid
- */
- void validatePassword( User user )
- throws PasswordRuleViolationException;
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you 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.
- */
-
-/**
- * UserValidationSettings
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public interface UserValidationSettings
-{
- /**
- * Get the flag indicating if a new users require email validation or not.
- *
- * @return
- */
- boolean isEmailValidationRequired();
-
- /**
- * Gets the number of minutes until the email validation message key
- * should expire.
- *
- * @return the email validation timeout (in minutes).
- */
- int getEmailValidationTimeout();
-
- /**
- * Get the subject line for the validation email.
- *
- * @return the subject line for the validation email.
- */
- String getEmailSubject();
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.encoders;
-
-/*
- * 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.archiva.redback.users.Messages;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.lang.StringUtils;
-import org.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.codehaus.plexus.redback.policy.PasswordEncodingException;
-
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/**
- * Abstract Password Encoder that uses the {@link MessageDigest} from JAAS.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public class AbstractJAASPasswordEncoder
- implements PasswordEncoder
-{
- private String algorithm;
-
- private Object systemSalt;
-
- public AbstractJAASPasswordEncoder( String algorithm )
- {
- this.algorithm = algorithm;
- }
-
- public void setSystemSalt( Object salt )
- {
- this.systemSalt = salt;
- }
-
- public String encodePassword( String rawPass, Object salt )
- {
- if ( rawPass == null )
- {
- throw new IllegalArgumentException( "rawPass parameter cannot be null." );
- }
-
- MessageDigest md = null;
- try
- {
- md = MessageDigest.getInstance( this.algorithm );
- String precode = rawPass;
-
- // Only checking for null, not using StringUtils.isNotEmpty() as
- // whitespace can make up a valid salt.
- if ( salt != null )
- {
- // Conforming to acegi password encoding standards for compatibility
- precode += "{" + salt + "}";
- }
- md.update( precode.getBytes( "UTF-8" ) ); //$NON-NLS-1$
-
- byte raw[] = md.digest();
- Base64 base64 = new Base64( 0, new byte[0] );
- return ( base64.encodeToString( raw ) );
- }
- catch ( NoSuchAlgorithmException e )
- {
- throw new PasswordEncodingException(
- Messages.getString( "password.encoder.no.such.algoritm", this.algorithm ), e ); //$NON-NLS-1$
- }
- catch ( UnsupportedEncodingException e )
- {
- throw new PasswordEncodingException( Messages.getString( "password.encoder.unsupported.encoding" ),
- e ); //$NON-NLS-1$
- }
- }
-
- public boolean isPasswordValid( String encPass, String rawPass, Object salt )
- {
- if ( StringUtils.isEmpty( encPass ) )
- {
- // TODO: Throw exception?
- return false;
- }
-
- // PLXREDBACK-36 Commented out because a user with an empty password can't login due to the checking.
- // Empty password checking can also be achieve by turning on MustHavePasswordRule.
- //if ( StringUtils.isEmpty( rawPass ) )
- //{
- // TODO: Throw exception?
- // return false;
- //}
-
- String testPass = encodePassword( rawPass, salt );
- return ( encPass.equals( testPass ) );
- }
-
- public String encodePassword( String rawPass )
- {
- return encodePassword( rawPass, this.systemSalt );
- }
-
- public boolean isPasswordValid( String encPass, String rawPass )
- {
- return isPasswordValid( encPass, rawPass, this.systemSalt );
- }
-
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.encoders;
-
-/*
- * 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.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.springframework.stereotype.Service;
-
-/**
- * PlainText PasswordEncoder for use in situtations where the password needs to be saved as-is.
- * See {@link PasswordEncoder#encodePassword(String)} for details.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("passwordEncoder#plaintext")
-public class PlainTextPasswordEncoder
- implements PasswordEncoder
-{
-
- public String encodePassword( String rawPass )
- {
- return rawPass;
- }
-
- public String encodePassword( String rawPass, Object salt )
- {
- return rawPass;
- }
-
- public boolean isPasswordValid( String encPass, String rawPass )
- {
- if ( encPass == null && rawPass != null )
- {
- return false;
- }
-
- return encPass.equals( rawPass );
- }
-
- public boolean isPasswordValid( String encPass, String rawPass, Object salt )
- {
- return isPasswordValid( encPass, rawPass );
- }
-
- public void setSystemSalt( Object salt )
- {
- // Ignore, not used in this plaintext encoder.
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.encoders;
-
-/*
- * 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.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.springframework.stereotype.Service;
-
-/**
- * SHA-1 Password Encoder.
- *
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("passwordEncoder#sha1")
-public class SHA1PasswordEncoder
- extends AbstractJAASPasswordEncoder
- implements PasswordEncoder
-{
- public SHA1PasswordEncoder()
- {
- super( "SHA-1" ); //$NON-NLS-1$
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.encoders;
-
-/*
- * 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.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.springframework.stereotype.Service;
-
-/**
- * SHA-256 Password Encoder.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("passwordEncoder#sha256")
-public class SHA256PasswordEncoder
- extends AbstractJAASPasswordEncoder
- implements PasswordEncoder
-{
- public SHA256PasswordEncoder()
- {
- super( "SHA-256" );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.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.archiva.redback.configuration.UserConfiguration;
-import org.codehaus.plexus.redback.policy.PasswordRule;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-/**
- * AbstractPasswordRule
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-public abstract class AbstractPasswordRule
- implements PasswordRule
-{
- protected boolean enabled = true;
-
- @Inject @Named (value="userConfiguration")
- protected UserConfiguration config;
-
- public boolean isEnabled()
- {
- return enabled;
- }
-
- /**
- * true if the security policy is required for the rule to execute
- *
- * @return boolean
- */
- public boolean requiresSecurityPolicy()
- {
- return false;
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.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.archiva.redback.users.User;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolations;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-
-/**
- * Basic Password Rule. Checks that password only contains alpha-numeric characters.
- *
- * $Id$
- */
-@Service("passwordRule#alpha-numeric")
-public class AlphaNumericPasswordRule
- extends AbstractPasswordRule
-{
- public static final String ALPHANUM_VIOLATION = "user.password.violation.alphanum.only";
-
- public void setUserSecurityPolicy( UserSecurityPolicy policy )
- {
- // Ignore, policy not needed in this rule.
- }
-
- public void testPassword( PasswordRuleViolations violations, User user )
- {
- char[] password = user.getPassword().toCharArray();
-
- for ( int i = 0; i < password.length; i++ )
- {
- if ( !Character.isLetterOrDigit( password[i] ) )
- {
- violations.addViolation( ALPHANUM_VIOLATION );
- return;
- }
- }
- }
-
- // FIXME to constructor
- @PostConstruct
- public void initialize()
- {
- enabled = config.getBoolean( "security.policy.password.rule.alphanumeric.enabled" );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.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.codehaus.plexus.redback.policy.PasswordRuleViolations;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
-import org.apache.archiva.redback.users.User;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-
-/**
- * Basic Password Rule, Checks for non-empty passwords that have at least {@link #setMinimumCount(int)} of
- * alpha characters contained within.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("passwordRule#alpha-count")
-public class AlphaPasswordRule
- extends AbstractPasswordRule
-{
- public static final String ALPHA_COUNT_MIN = "security.policy.password.rule.alphacount.minimum";
-
- public static final String ALPHA_COUNT_VIOLATION = "user.password.violation.alpha";
-
- private int minimumCount;
-
- private int countAlphaCharacters( String password )
- {
- int count = 0;
-
- if ( StringUtils.isEmpty( password ) )
- {
- return count;
- }
-
- /* TODO: Eventually upgrade to the JDK 1.5 Technique
- *
- * // 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++;
- * }
- * }
- */
-
- // JDK 1.4 Technique - NOT LOCALIZED.
- for ( int i = 0; i < password.length(); i++ )
- {
- char c = password.charAt( i );
- if ( Character.isLetter( c ) )
- {
- count++;
- }
- }
-
- return count;
- }
-
- public int getMinimumCount()
- {
- return minimumCount;
- }
-
- public void setMinimumCount( int minimumCount )
- {
- this.minimumCount = minimumCount;
- }
-
- public void setUserSecurityPolicy( UserSecurityPolicy policy )
- {
- // Ignore, policy not needed in this rule.
- }
-
- public void testPassword( PasswordRuleViolations violations, User user )
- {
- if ( countAlphaCharacters( user.getPassword() ) < this.minimumCount )
- {
- violations.addViolation( ALPHA_COUNT_VIOLATION,
- new String[]{String.valueOf( minimumCount )} ); //$NON-NLS-1$
- }
- }
-
- @PostConstruct
- public void initialize()
- {
- enabled = config.getBoolean( "security.policy.password.rule.alphacount.enabled" );
- this.minimumCount = config.getInt( ALPHA_COUNT_MIN );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.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.archiva.redback.users.User;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolations;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-
-/**
- * Basic Password Rule, Checks for non-empty passwords that have between {@link #setMinimumCharacters(int)} and
- * {@link #setMaximumCharacters(int)} characters in length.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("passwordRule#character-length")
-public class CharacterLengthPasswordRule
- extends AbstractPasswordRule
-{
- public static final String CHARACTER_LENGTH_MIN = "security.policy.password.rule.characterlength.minimum";
-
- public static final String CHARACTER_LENGTH_MAX = "security.policy.password.rule.characterlength.maximum";
-
- public static final String CHARACTER_LENGTH_MISCONFIGURED_VIOLATION =
- "user.password.violation.length.misconfigured";
-
- public static final String CHARACTER_LENGTH_VIOLATION = "user.password.violation.length";
-
- public static final int DEFAULT_CHARACTER_LENGTH_MAX = 8;
-
- private int minimumCharacters;
-
- private int maximumCharacters;
-
- 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 setUserSecurityPolicy( UserSecurityPolicy policy )
- {
- // Ignore, policy not needed in this rule.
- }
-
- public void testPassword( PasswordRuleViolations violations, User user )
- {
- if ( minimumCharacters > maximumCharacters )
- {
- /* this should caught up front during the configuration of the component */
- // TODO: Throw runtime exception instead?
- violations.addViolation( CHARACTER_LENGTH_MISCONFIGURED_VIOLATION, new String[]{
- String.valueOf( minimumCharacters ), String.valueOf( maximumCharacters )} ); //$NON-NLS-1$
- }
-
- String password = user.getPassword();
-
- if ( StringUtils.isEmpty( password ) || password.length() < minimumCharacters ||
- password.length() > maximumCharacters )
- {
- violations.addViolation( CHARACTER_LENGTH_VIOLATION, new String[]{String.valueOf( minimumCharacters ),
- String.valueOf( maximumCharacters )} ); //$NON-NLS-1$
- }
- }
-
- @PostConstruct
- public void initialize()
- {
- enabled = config.getBoolean( "security.policy.password.rule.characterlength.enabled" );
- this.minimumCharacters = config.getInt( CHARACTER_LENGTH_MIN );
- this.maximumCharacters = config.getInt( CHARACTER_LENGTH_MAX );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.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.codehaus.plexus.redback.policy.PasswordRuleViolations;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
-import org.apache.archiva.redback.users.User;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-
-/**
- * Basic Password Rule, Checks for non-empty Passwords in non guest users.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("passwordRule#must-have")
-public class MustHavePasswordRule
- extends AbstractPasswordRule
-{
- public static final String MISSING_PASSWORD_VIOLATION = "user.password.violation.missing";
-
- public void setUserSecurityPolicy( UserSecurityPolicy policy )
- {
- // Ignore, policy not needed in this rule.
- }
-
- public void testPassword( PasswordRuleViolations violations, User user )
- {
- if ( StringUtils.isEmpty( user.getPassword() ) )
- {
- violations.addViolation( MISSING_PASSWORD_VIOLATION ); //$NON-NLS-1$
- }
- }
-
- @PostConstruct
- public void initialize()
- {
- enabled = config.getBoolean( "security.policy.password.rule.musthave.enabled" );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.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.archiva.redback.users.User;
-import org.codehaus.plexus.redback.policy.PasswordRuleViolations;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-
-/**
- * Basic Password Rule, Checks for non-empty passwords that have at least {@link #setMinimumCount(int)} of
- * numerical characters contained within.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("passwordRule#numerical-count")
-public class NumericalPasswordRule
- extends AbstractPasswordRule
-{
- public static final String MINIMUM = "security.policy.password.rule.numericalcount.minimum";
-
- public static final String NUMERICAL_COUNT_VIOLATION = "user.password.violation.numeric";
-
- private int minimumCount;
-
- private int countDigitCharacters( String password )
- {
- int count = 0;
-
- if ( StringUtils.isEmpty( password ) )
- {
- return count;
- }
-
- /* TODO: Eventually upgrade to the JDK 1.5 Technique
- *
- * // Doing this via iteration of code points to take in account localized numbers.
- * for ( int i = 0; i < password.length(); i++ )
- * {
- * int codepoint = password.codePointAt( i );
- * if ( Character.isDigit( codepoint ) )
- * {
- * count++;
- * }
- * }
- */
-
- // JDK 1.4 Technique - NOT LOCALIZED.
- for ( int i = 0; i < password.length(); i++ )
- {
- char c = password.charAt( i );
- if ( Character.isDigit( c ) )
- {
- count++;
- }
- }
-
- return count;
- }
-
- public int getMinimumCount()
- {
- return minimumCount;
- }
-
- public void setMinimumCount( int minimumCount )
- {
- this.minimumCount = minimumCount;
- }
-
- public void setUserSecurityPolicy( UserSecurityPolicy policy )
- {
- // Ignore, policy not needed in this rule.
- }
-
- public void testPassword( PasswordRuleViolations violations, User user )
- {
- if ( countDigitCharacters( user.getPassword() ) < this.minimumCount )
- {
- violations.addViolation( NUMERICAL_COUNT_VIOLATION,
- new String[]{String.valueOf( minimumCount )} ); //$NON-NLS-1$
- }
- }
-
- @PostConstruct
- public void initialize()
- {
- enabled = config.getBoolean( "security.policy.password.rule.numericalcount.enabled" );
- this.minimumCount = config.getInt( MINIMUM );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.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.codehaus.plexus.redback.policy.PasswordRuleViolations;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
-import org.apache.archiva.redback.users.User;
-import org.apache.commons.lang.StringUtils;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-import java.util.Iterator;
-
-/**
- * Password Rule, Checks supplied password found at {@link User#getPassword()} against
- * the {@link User#getPreviousEncodedPasswords()} to ensure that a password is not reused.
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@Service("passwordRule#reuse")
-public class ReusePasswordRule
- extends AbstractPasswordRule
-{
- public static final String REUSE_VIOLATION = "user.password.violation.reuse";
-
- private UserSecurityPolicy securityPolicy;
-
- public void setUserSecurityPolicy( UserSecurityPolicy policy )
- {
- this.securityPolicy = policy;
- }
-
- /**
- * true if the security policy is required for this rule
- *
- * @return boolean
- */
- public boolean requiresSecurityPolicy()
- {
- return true;
- }
-
- public int getPreviousPasswordCount()
- {
- if ( securityPolicy == null )
- {
- throw new IllegalStateException( "The security policy has not yet been set." );
- }
-
- return securityPolicy.getPreviousPasswordsCount();
- }
-
- private boolean hasReusedPassword( User user, String password )
- {
- if ( securityPolicy == null )
- {
- throw new IllegalStateException( "The security policy has not yet been set." );
- }
-
- if ( StringUtils.isEmpty( password ) )
- {
- return false;
- }
-
- String encodedPassword = securityPolicy.getPasswordEncoder().encodePassword( password );
-
- int checkCount = getPreviousPasswordCount();
-
- Iterator<String> it = user.getPreviousEncodedPasswords().iterator();
-
- while ( it.hasNext() && checkCount >= 0 )
- {
- String prevEncodedPassword = it.next();
- if ( encodedPassword.equals( prevEncodedPassword ) )
- {
- return true;
- }
- checkCount--;
- }
-
- return false;
- }
-
- public void setPreviousPasswordCount( int previousPasswordCount )
- {
- securityPolicy.setPreviousPasswordsCount( previousPasswordCount );
- }
-
- public void testPassword( PasswordRuleViolations violations, User user )
- {
- String password = user.getPassword();
-
- if ( hasReusedPassword( user, password ) )
- {
- violations.addViolation( REUSE_VIOLATION,
- new String[]{String.valueOf( getPreviousPasswordCount() )} ); //$NON-NLS-1$
- }
- }
-
- @PostConstruct
- public void initialize()
- {
- enabled = config.getBoolean( "security.policy.password.rule.reuse.enabled" );
- }
-}
+++ /dev/null
-package org.codehaus.plexus.redback.policy.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.codehaus.plexus.redback.policy.PasswordRuleViolations;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
-import org.apache.archiva.redback.users.User;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.PostConstruct;
-
-/**
- * Basic Password Rule. Checks that password does not have whitespaces in it.
- *
- * $Id$
- */
-@Service("passwordRule#no-whitespaces")
-public class WhitespacePasswordRule
- extends AbstractPasswordRule
-{
- public static final String NO_WHITE_SPACE_VIOLATION = "user.password.violation.whitespace.detected";
-
- public void setUserSecurityPolicy( UserSecurityPolicy policy )
- {
- // Ignore, policy not needed in this rule.
- }
-
- public void testPassword( PasswordRuleViolations violations, User user )
- {
- if ( user.getPassword() != null )
- {
- char[] password = user.getPassword().toCharArray();
-
- for ( int i = 0; i < password.length; i++ )
- {
- if ( Character.isWhitespace( password[i] ) )
- {
- violations.addViolation( NO_WHITE_SPACE_VIOLATION );
- return;
- }
- }
- }
- }
-
- @PostConstruct
- public void initialize()
- {
- enabled = config.getBoolean( "security.policy.password.rule.nowhitespace.enabled" );
- }
-}
default-lazy-init="true">
<context:annotation-config />
- <context:component-scan base-package="org.codehaus.plexus.redback.policy"/>
+ <context:component-scan base-package="org.apache.archiva.redback.policy"/>
</beans>
\ No newline at end of file
--- /dev/null
+package org.apache.archiva.redback.policy;
+
+/*
+ * 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 junit.framework.TestCase;
+import org.apache.archiva.redback.policy.PasswordEncoder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * PasswordEncoderTest
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@RunWith( SpringJUnit4ClassRunner.class )
+@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
+public class PasswordEncoderTest
+ extends TestCase
+{
+ private static final String PASSWORD = "s3cret";
+ private static final String ENCODED_SHA1 = "/vNB+F2HQ559kaLUZbmHHvZrXpg=";
+ private static final String ENCODED_SHA256 = "HsHCa1DV08WNlYMYGvgHZlX+AHVr9yhZQLo2cPmfy6A=";
+
+ @Inject @Named(value = "passwordEncoder#sha1")
+ PasswordEncoder passwordEncoderSha1;
+
+ @Inject @Named(value = "passwordEncoder#sha256")
+ PasswordEncoder passwordEncoderSha256;
+
+ @Test
+ public void testSHA1Encoding() throws Exception
+ {
+ PasswordEncoder encoder = passwordEncoderSha1;
+
+ assertNotNull(encoder);
+
+ String encoded = encoder.encodePassword( PASSWORD );
+
+ assertEquals( ENCODED_SHA1, encoded );
+ }
+
+ @Test
+ public void testSHA256Encoding() throws Exception
+ {
+ PasswordEncoder encoder = passwordEncoderSha256;
+
+ assertNotNull(encoder);
+
+ String encoded = encoder.encodePassword( PASSWORD );
+
+ assertEquals( ENCODED_SHA256, encoded );
+ }
+
+ @Test
+ public void testSHA1IsPasswordValid() throws Exception
+ {
+ PasswordEncoder encoder = passwordEncoderSha1;
+
+ assertNotNull(encoder);
+
+ assertTrue( encoder.isPasswordValid( ENCODED_SHA1, PASSWORD ) );
+ }
+
+ @Test
+ public void testSHA256IsPasswordValid() throws Exception
+ {
+ PasswordEncoder encoder = passwordEncoderSha256;
+
+ assertNotNull(encoder);
+
+ assertTrue( encoder.isPasswordValid( ENCODED_SHA256, PASSWORD ) );
+ }
+
+}
+++ /dev/null
-package org.codehaus.plexus.redback.policy;
-
-/*
- * 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 junit.framework.TestCase;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-
-/**
- * PasswordEncoderTest
- *
- * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
- * @version $Id$
- */
-@RunWith( SpringJUnit4ClassRunner.class )
-@ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
-public class PasswordEncoderTest
- extends TestCase
-{
- private static final String PASSWORD = "s3cret";
- private static final String ENCODED_SHA1 = "/vNB+F2HQ559kaLUZbmHHvZrXpg=";
- private static final String ENCODED_SHA256 = "HsHCa1DV08WNlYMYGvgHZlX+AHVr9yhZQLo2cPmfy6A=";
-
- @Inject @Named(value = "passwordEncoder#sha1")
- PasswordEncoder passwordEncoderSha1;
-
- @Inject @Named(value = "passwordEncoder#sha256")
- PasswordEncoder passwordEncoderSha256;
-
- @Test
- public void testSHA1Encoding() throws Exception
- {
- PasswordEncoder encoder = passwordEncoderSha1;
-
- assertNotNull(encoder);
-
- String encoded = encoder.encodePassword( PASSWORD );
-
- assertEquals( ENCODED_SHA1, encoded );
- }
-
- @Test
- public void testSHA256Encoding() throws Exception
- {
- PasswordEncoder encoder = passwordEncoderSha256;
-
- assertNotNull(encoder);
-
- String encoded = encoder.encodePassword( PASSWORD );
-
- assertEquals( ENCODED_SHA256, encoded );
- }
-
- @Test
- public void testSHA1IsPasswordValid() throws Exception
- {
- PasswordEncoder encoder = passwordEncoderSha1;
-
- assertNotNull(encoder);
-
- assertTrue( encoder.isPasswordValid( ENCODED_SHA1, PASSWORD ) );
- }
-
- @Test
- public void testSHA256IsPasswordValid() throws Exception
- {
- PasswordEncoder encoder = passwordEncoderSha256;
-
- assertNotNull(encoder);
-
- assertTrue( encoder.isPasswordValid( ENCODED_SHA256, PASSWORD ) );
- }
-
-}
*/
import org.apache.archiva.redback.keys.KeyManager;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.authorization.AuthorizationException;
import org.apache.archiva.redback.authorization.AuthorizationResult;
import org.apache.archiva.redback.authorization.Authorizer;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
* @throws AuthenticationException
* @throws UserNotFoundException
* @throws MustChangePasswordException
- * @throws AccountLockedException
+ * @throws org.apache.archiva.redback.policy.AccountLockedException
* @throws MustChangePasswordException
*/
public SecuritySession authenticate( AuthenticationDataSource source )
* under the License.
*/
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.authentication.AuthenticationDataSource;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.authorization.AuthorizationException;
import org.apache.archiva.redback.authorization.AuthorizationResult;
import org.apache.archiva.redback.keys.KeyManager;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.UserManager;
/**
*/
import org.apache.archiva.redback.authentication.Authenticator;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.PasswordEncoder;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.authentication.AuthenticationConstants;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
-import org.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.codehaus.plexus.redback.policy.PolicyViolationException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
+import org.apache.archiva.redback.policy.PolicyViolationException;
import org.apache.archiva.redback.users.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
}
/**
- * @throws org.codehaus.plexus.redback.policy.AccountLockedException
+ * @throws org.apache.archiva.redback.policy.AccountLockedException
*
* @throws MustChangePasswordException
* @throws MustChangePasswordException
import junit.framework.TestCase;
import org.apache.archiva.redback.authentication.Authenticator;
+import org.apache.archiva.redback.policy.MustChangePasswordException;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.authentication.AuthenticationException;
import org.apache.archiva.redback.authentication.AuthenticationResult;
import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
-import org.codehaus.plexus.redback.policy.AccountLockedException;
-import org.codehaus.plexus.redback.policy.MustChangePasswordException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.policy.AccountLockedException;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
* under the License.
*/
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.AbstractUserManager;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManagerException;
import org.codehaus.plexus.jdo.PlexusJdoUtils;
import org.codehaus.plexus.jdo.PlexusObjectNotFoundException;
import org.codehaus.plexus.jdo.PlexusStoreException;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.PermanentUserException;
import org.apache.archiva.redback.users.UserQuery;
import org.codehaus.plexus.redback.users.jdo.JdoUser;
*/
import junit.framework.TestCase;
+import org.apache.archiva.redback.policy.PasswordEncoder;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
-import org.codehaus.plexus.redback.policy.PasswordEncoder;
-import org.codehaus.plexus.redback.policy.encoders.SHA1PasswordEncoder;
+import org.apache.archiva.redback.policy.encoders.SHA1PasswordEncoder;
import org.apache.archiva.redback.users.UserManager;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.users.ldap.service.LdapCacheService;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserManager;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.AbstractUserManager;
import org.apache.archiva.redback.users.PermanentUserException;
import org.apache.archiva.redback.users.UserQuery;
*/
import junit.framework.TestCase;
+import org.apache.archiva.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.User;
import org.apache.archiva.redback.users.UserNotFoundException;
import org.apache.archiva.redback.users.UserQuery;
-import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
import org.apache.archiva.redback.users.PermanentUserException;
import org.apache.archiva.redback.users.UserManager;
import org.junit.Test;