]> source.dussan.org Git - archiva.git/blob
865b226fe23e3b87cdbea9f7190e1cec7d680ffc
[archiva.git] /
1 package org.apache.archiva.redback.authentication.users;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import org.apache.archiva.redback.authentication.Authenticator;
23 import org.apache.archiva.redback.policy.AccountLockedException;
24 import org.apache.archiva.redback.policy.PasswordEncoder;
25 import org.apache.archiva.redback.policy.UserSecurityPolicy;
26 import org.apache.archiva.redback.users.UserManager;
27 import org.apache.archiva.redback.users.UserNotFoundException;
28 import org.apache.archiva.redback.authentication.AuthenticationConstants;
29 import org.apache.archiva.redback.authentication.AuthenticationDataSource;
30 import org.apache.archiva.redback.authentication.AuthenticationException;
31 import org.apache.archiva.redback.authentication.AuthenticationResult;
32 import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
33 import org.apache.archiva.redback.policy.MustChangePasswordException;
34 import org.apache.archiva.redback.policy.PolicyViolationException;
35 import org.apache.archiva.redback.users.User;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38 import org.springframework.stereotype.Service;
39
40 import javax.inject.Inject;
41 import javax.inject.Named;
42 import java.util.HashMap;
43 import java.util.Map;
44
45 /**
46  * {@link Authenticator} implementation that uses a wrapped {@link UserManager} to authenticate.
47  *
48  * @author <a href='mailto:rahul.thakur.xdev@gmail.com'>Rahul Thakur</a>
49  *
50  */
51 @Service( "authenticator#user-manager" )
52 public class UserManagerAuthenticator
53     implements Authenticator
54 {
55     private Logger log = LoggerFactory.getLogger( UserManagerAuthenticator.class );
56
57     @Inject
58     @Named( value = "userManager#jdo" )
59     private UserManager userManager;
60
61     @Inject
62     private UserSecurityPolicy securityPolicy;
63
64     public String getId()
65     {
66         return "UserManagerAuthenticator";
67     }
68
69     /**
70      * @throws org.apache.archiva.redback.policy.AccountLockedException
71      *
72      * @throws MustChangePasswordException
73      * @throws MustChangePasswordException
74      * @throws PolicyViolationException
75      * @see org.apache.archiva.redback.authentication.Authenticator#authenticate(org.apache.archiva.redback.authentication.AuthenticationDataSource)
76      */
77     public AuthenticationResult authenticate( AuthenticationDataSource ds )
78         throws AuthenticationException, AccountLockedException, MustChangePasswordException
79     {
80         boolean authenticationSuccess = false;
81         String username = null;
82         Exception resultException = null;
83         PasswordBasedAuthenticationDataSource source = (PasswordBasedAuthenticationDataSource) ds;
84         Map<String, String> authnResultExceptionsMap = new HashMap<String, String>();
85
86         try
87         {
88             log.debug( "Authenticate: {}", source );
89             User user = userManager.findUser( source.getPrincipal() );
90             username = user.getUsername();
91
92             if ( user.isLocked() )
93             {
94                 throw new AccountLockedException( "Account " + source.getPrincipal() + " is locked.", user );
95             }
96
97             if ( user.isPasswordChangeRequired() && source.isEnforcePasswordChange() )
98             {
99                 throw new MustChangePasswordException( "Password expired.", user );
100             }
101
102             PasswordEncoder encoder = securityPolicy.getPasswordEncoder();
103             log.debug( "PasswordEncoder: {}", encoder.getClass().getName() );
104
105             boolean isPasswordValid = encoder.isPasswordValid( user.getEncodedPassword(), source.getPassword() );
106             if ( isPasswordValid )
107             {
108                 log.debug( "User {} provided a valid password", source.getPrincipal() );
109
110                 try
111                 {
112                     securityPolicy.extensionPasswordExpiration( user );
113                 }
114                 catch ( MustChangePasswordException e )
115                 {
116                     user.setPasswordChangeRequired( true );
117                     throw e;
118                 }
119
120                 authenticationSuccess = true;
121
122                 //REDBACK-151 do not make unnessesary updates to the user object
123                 if ( user.getCountFailedLoginAttempts() > 0 )
124                 {
125                     user.setCountFailedLoginAttempts( 0 );
126                     userManager.updateUser( user );
127                 }
128
129                 return new AuthenticationResult( true, source.getPrincipal(), null );
130             }
131             else
132             {
133                 log.warn( "Password is Invalid for user " + source.getPrincipal() + "." );
134                 authnResultExceptionsMap.put( AuthenticationConstants.AUTHN_NO_SUCH_USER,
135                                               "Password is Invalid for user " + source.getPrincipal() + "." );
136
137                 try
138                 {
139                     securityPolicy.extensionExcessiveLoginAttempts( user );
140                 }
141                 finally
142                 {
143                     userManager.updateUser( user );
144                 }
145
146                 return new AuthenticationResult( false, source.getPrincipal(), null, authnResultExceptionsMap );
147             }
148         }
149         catch ( UserNotFoundException e )
150         {
151             log.warn( "Login for user " + source.getPrincipal() + " failed. user not found." );
152             resultException = e;
153             authnResultExceptionsMap.put( AuthenticationConstants.AUTHN_NO_SUCH_USER,
154                                           "Login for user \" + source.getPrincipal() + \" failed. user not found." );
155         }
156
157         return new AuthenticationResult( authenticationSuccess, username, resultException, authnResultExceptionsMap );
158     }
159
160     /**
161      * Returns the wrapped {@link UserManager} used by this {@link org.apache.archiva.redback.authentication.Authenticator}
162      * implementation for authentication.
163      *
164      * @return the userManager
165      */
166     public UserManager getUserManager()
167     {
168         return userManager;
169     }
170
171     /**
172      * Sets a {@link UserManager} to be used by this {@link Authenticator}
173      * implementation for authentication.
174      *
175      * @param userManager the userManager to set
176      */
177     public void setUserManager( UserManager userManager )
178     {
179         this.userManager = userManager;
180     }
181
182     public boolean supportsDataSource( AuthenticationDataSource source )
183     {
184         return ( source instanceof PasswordBasedAuthenticationDataSource );
185     }
186
187     public UserSecurityPolicy getSecurityPolicy()
188     {
189         return securityPolicy;
190     }
191
192     public void setSecurityPolicy( UserSecurityPolicy securityPolicy )
193     {
194         this.securityPolicy = securityPolicy;
195     }
196 }