diff --git a/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationConstants.java b/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationConstants.java index 143b5fb9..836e7f2f 100644 --- a/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationConstants.java +++ b/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationConstants.java @@ -27,21 +27,21 @@ public class AuthenticationConstants { // for User Manager Authenticator - public static final String AUTHN_NO_SUCH_USER = "1"; + public static final int AUTHN_NO_SUCH_USER = 1; /** * @since 2.1 */ - public static final String AUTHN_RUNTIME_EXCEPTION = "2"; + public static final int AUTHN_RUNTIME_EXCEPTION = 2; /** * @since 2.1 */ - public static final String AUTHN_LOCKED_USER_EXCEPTION = "3"; + public static final int AUTHN_LOCKED_USER_EXCEPTION = 3; /** * @since 2.1 */ - public static final String AUTHN_MUST_CHANGE_PASSWORD_EXCEPTION = "4"; + public static final int AUTHN_MUST_CHANGE_PASSWORD_EXCEPTION = 4; } diff --git a/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationFailureCause.java b/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationFailureCause.java new file mode 100644 index 00000000..488e8f6a --- /dev/null +++ b/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationFailureCause.java @@ -0,0 +1,68 @@ +package org.apache.archiva.redback.authentication; +/* + * 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. + */ + +/** + * detail on possible authentication failure. + * @author Olivier Lamy + * @since 1.4-M4 + */ +public class AuthenticationFailureCause +{ + private int cause; + + private String message; + + public AuthenticationFailureCause( int cause, String message ) + { + this.cause = cause; + this.message = message; + } + + public int getCause() + { + return cause; + } + + public void setCause( int cause ) + { + this.cause = cause; + } + + public String getMessage() + { + return message; + } + + public void setMessage( String message ) + { + this.message = message; + } + + @Override + public String toString() + { + final StringBuilder sb = new StringBuilder(); + sb.append( "AuthenticationFailureCause" ); + sb.append( "{cause=" ).append( cause ); + sb.append( ", message='" ).append( message ).append( '\'' ); + sb.append( '}' ); + return sb.toString(); + } +} diff --git a/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationResult.java b/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationResult.java index 2608959a..c76ea98f 100644 --- a/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationResult.java +++ b/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/AuthenticationResult.java @@ -23,6 +23,7 @@ import org.apache.archiva.redback.users.User; import java.io.Serializable; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -50,7 +51,7 @@ public class AuthenticationResult // TODO: why aren't these just thrown from the authenticate() method? private Exception exception; - private Map exceptionsMap; + private List authenticationFailureCauses; public AuthenticationResult() { @@ -67,12 +68,12 @@ public class AuthenticationResult } public AuthenticationResult( boolean authenticated, String principal, Exception exception, - Map exceptionsMap ) + List authenticationFailureCauses ) { isAuthenticated = authenticated; this.principal = principal; this.exception = exception; - this.exceptionsMap = exceptionsMap; + this.authenticationFailureCauses = authenticationFailureCauses; } public boolean isAuthenticated() @@ -90,9 +91,9 @@ public class AuthenticationResult return exception; } - public Map getExceptionsMap() + public List getAuthenticationFailureCauses() { - return exceptionsMap; + return authenticationFailureCauses; } /** diff --git a/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/DefaultAuthenticationManager.java b/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/DefaultAuthenticationManager.java index 85c6d595..68165a77 100644 --- a/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/DefaultAuthenticationManager.java +++ b/redback-authentication/redback-authentication-api/src/main/java/org/apache/archiva/redback/authentication/DefaultAuthenticationManager.java @@ -77,29 +77,31 @@ public class DefaultAuthenticationManager } // put AuthenticationResult exceptions in a map - Map authnResultExceptionsMap = new HashMap(); + List authnResultErrors = new ArrayList(); for ( Authenticator authenticator : authenticators ) { if ( authenticator.supportsDataSource( source ) ) { AuthenticationResult authResult = authenticator.authenticate( source ); - Map exceptionsMap = authResult.getExceptionsMap(); + List authenticationFailureCauses = + authResult.getAuthenticationFailureCauses(); if ( authResult.isAuthenticated() ) { return authResult; } - if ( exceptionsMap != null ) + if ( authenticationFailureCauses != null ) { - authnResultExceptionsMap.putAll( exceptionsMap ); + authnResultErrors.addAll( authenticationFailureCauses ); } else { if ( authResult.getException() != null ) { - authnResultExceptionsMap.put( AuthenticationConstants.AUTHN_RUNTIME_EXCEPTION, - authResult.getException().getMessage() ); + authnResultErrors.add( + new AuthenticationFailureCause( AuthenticationConstants.AUTHN_RUNTIME_EXCEPTION, + authResult.getException().getMessage() ) ); } } @@ -108,7 +110,7 @@ public class DefaultAuthenticationManager } return ( new AuthenticationResult( false, null, new AuthenticationException( - "authentication failed on authenticators: " + knownAuthenticators() ), authnResultExceptionsMap ) ); + "authentication failed on authenticators: " + knownAuthenticators() ), authnResultErrors ) ); } public List getAuthenticators() diff --git a/redback-authentication/redback-authentication-providers/redback-authentication-users/src/main/java/org/apache/archiva/redback/authentication/users/UserManagerAuthenticator.java b/redback-authentication/redback-authentication-providers/redback-authentication-users/src/main/java/org/apache/archiva/redback/authentication/users/UserManagerAuthenticator.java index d62f2e77..a1da4f59 100644 --- a/redback-authentication/redback-authentication-providers/redback-authentication-users/src/main/java/org/apache/archiva/redback/authentication/users/UserManagerAuthenticator.java +++ b/redback-authentication/redback-authentication-providers/redback-authentication-users/src/main/java/org/apache/archiva/redback/authentication/users/UserManagerAuthenticator.java @@ -23,6 +23,7 @@ import org.apache.archiva.redback.authentication.AbstractAuthenticator; import org.apache.archiva.redback.authentication.AuthenticationConstants; import org.apache.archiva.redback.authentication.AuthenticationDataSource; import org.apache.archiva.redback.authentication.AuthenticationException; +import org.apache.archiva.redback.authentication.AuthenticationFailureCause; import org.apache.archiva.redback.authentication.AuthenticationResult; import org.apache.archiva.redback.authentication.Authenticator; import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource; @@ -41,7 +42,9 @@ import org.springframework.stereotype.Service; import javax.inject.Inject; import javax.inject.Named; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -84,7 +87,7 @@ public class UserManagerAuthenticator String username = null; Exception resultException = null; PasswordBasedAuthenticationDataSource source = (PasswordBasedAuthenticationDataSource) ds; - Map authnResultExceptionsMap = new HashMap(); + List authenticationFailureCauses = new ArrayList(); try { @@ -134,8 +137,9 @@ public class UserManagerAuthenticator else { log.warn( "Password is Invalid for user {}.", source.getPrincipal() ); - authnResultExceptionsMap.put( AuthenticationConstants.AUTHN_NO_SUCH_USER, - "Password is Invalid for user " + source.getPrincipal() + "." ); + authenticationFailureCauses.add( + new AuthenticationFailureCause( AuthenticationConstants.AUTHN_NO_SUCH_USER, + "Password is Invalid for user " + source.getPrincipal() + "." ) ); try { @@ -146,26 +150,29 @@ public class UserManagerAuthenticator userManager.updateUser( user ); } - return new AuthenticationResult( false, source.getPrincipal(), null, authnResultExceptionsMap ); + return new AuthenticationResult( false, source.getPrincipal(), null, authenticationFailureCauses ); } } catch ( UserNotFoundException e ) { log.warn( "Login for user {} failed. user not found.", source.getPrincipal() ); resultException = e; - authnResultExceptionsMap.put( AuthenticationConstants.AUTHN_NO_SUCH_USER, - "Login for user " + source.getPrincipal() + " failed. user not found." ); + authenticationFailureCauses.add( new AuthenticationFailureCause( AuthenticationConstants.AUTHN_NO_SUCH_USER, + "Login for user " + source.getPrincipal() + + " failed. user not found." ) ); } catch ( UserManagerException e ) { log.warn( "Login for user {} failed, message: {}", source.getPrincipal(), e.getMessage() ); resultException = e; - authnResultExceptionsMap.put( AuthenticationConstants.AUTHN_RUNTIME_EXCEPTION, - "Login for user " + source.getPrincipal() + " failed, message: " - + e.getMessage() ); + authenticationFailureCauses.add( + new AuthenticationFailureCause( AuthenticationConstants.AUTHN_RUNTIME_EXCEPTION, + "Login for user " + source.getPrincipal() + " failed, message: " + + e.getMessage() ) ); } - return new AuthenticationResult( authenticationSuccess, username, resultException, authnResultExceptionsMap ); + return new AuthenticationResult( authenticationSuccess, username, resultException, + authenticationFailureCauses ); } /** diff --git a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java index 0c1626ed..956f6e2c 100644 --- a/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java +++ b/redback-integrations/redback-rest/redback-rest-services/src/main/java/org/apache/archiva/redback/rest/services/DefaultLoginService.java @@ -19,7 +19,9 @@ package org.apache.archiva.redback.rest.services; * under the License. */ +import org.apache.archiva.redback.authentication.AuthenticationConstants; import org.apache.archiva.redback.authentication.AuthenticationException; +import org.apache.archiva.redback.authentication.AuthenticationFailureCause; import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource; import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator; import org.apache.archiva.redback.keys.AuthenticationKey; @@ -59,7 +61,7 @@ import java.util.TimeZone; * @author Olivier Lamy * @since 1.3 */ -@Service( "loginService#rest" ) +@Service("loginService#rest") public class DefaultLoginService implements LoginService { @@ -75,7 +77,7 @@ public class DefaultLoginService @Inject public DefaultLoginService( SecuritySystem securitySystem, - @Named( "httpAuthenticator#basic" ) HttpAuthenticator httpAuthenticator ) + @Named("httpAuthenticator#basic") HttpAuthenticator httpAuthenticator ) { this.securitySystem = securitySystem; this.httpAuthenticator = httpAuthenticator; @@ -152,12 +154,19 @@ public class DefaultLoginService return restUser; } if ( securitySession.getAuthenticationResult() != null - && securitySession.getAuthenticationResult().getExceptionsMap() != null ) + && securitySession.getAuthenticationResult().getAuthenticationFailureCauses() != null ) { List errorMessages = new ArrayList(); - for ( Map.Entry entry : securitySession.getAuthenticationResult().getExceptionsMap().entrySet() ) + for ( AuthenticationFailureCause authenticationFailureCause : securitySession.getAuthenticationResult().getAuthenticationFailureCauses() ) { - errorMessages.add( new ErrorMessage().message( entry.getValue() ) ); + if ( authenticationFailureCause.getCause() == AuthenticationConstants.AUTHN_NO_SUCH_USER ) + { + errorMessages.add( new ErrorMessage( "incorrect.username.password" ) ); + } + else + { + errorMessages.add( new ErrorMessage().message( authenticationFailureCause.getMessage() ) ); + } } throw new RedbackServiceException( errorMessages );