]> source.dussan.org Git - archiva.git/blob
9173a1c16443c5ce70640a46b61d25b50f305dcb
[archiva.git] /
1 package org.apache.archiva.redback.struts2.action.admin;
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.AuthenticationException;
23 import org.apache.archiva.redback.configuration.UserConfiguration;
24 import org.apache.archiva.redback.policy.MustChangePasswordException;
25 import org.apache.archiva.redback.role.RoleManager;
26 import org.apache.archiva.redback.role.RoleManagerException;
27 import org.apache.archiva.redback.struts2.action.AuditEvent;
28 import org.apache.archiva.redback.users.UserManager;
29 import org.apache.struts2.ServletActionContext;
30 import org.apache.archiva.redback.authentication.AuthenticationConstants;
31 import org.apache.archiva.redback.authentication.AuthenticationDataSource;
32 import org.apache.archiva.redback.authentication.AuthenticationResult;
33 import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
34 import org.apache.archiva.redback.policy.AccountLockedException;
35 import org.apache.archiva.redback.system.SecuritySession;
36 import org.apache.archiva.redback.users.User;
37 import org.apache.archiva.redback.users.UserNotFoundException;
38 import org.apache.archiva.redback.integration.interceptor.SecureActionBundle;
39 import org.apache.archiva.redback.integration.interceptor.SecureActionException;
40 import org.apache.archiva.redback.integration.model.EditUserCredentials;
41 import org.apache.archiva.redback.integration.util.AutoLoginCookies;
42 import org.springframework.context.annotation.Scope;
43 import org.springframework.stereotype.Controller;
44
45 import javax.inject.Inject;
46 import java.util.Arrays;
47 import java.util.Date;
48
49 /**
50  * AddAdminUserAction
51  *
52  * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
53  *
54  */
55 @Controller( "redback-admin-account" )
56 @Scope( "prototype" )
57 public class AddAdminUserAction
58     extends AbstractAdminUserCredentialsAction
59 {
60     private static final String LOGIN_ERROR = "login-error";
61
62     private static final String LOGIN_SUCCESS = "security-login-success";
63
64     private static final String PASSWORD_CHANGE = "security-must-change-password";
65
66     private static final String ACCOUNT_LOCKED = "security-login-locked";
67
68     @Inject
69     private RoleManager roleManager;
70
71
72     @Inject
73     private UserConfiguration config;
74
75     private EditUserCredentials user;
76
77     @Inject
78     private AutoLoginCookies autologinCookies;
79
80     public String show()
81     {
82         if ( user == null )
83         {
84             user = new EditUserCredentials( config.getString( "redback.default.admin" ) );
85         }
86
87         return INPUT;
88     }
89
90     /**
91      * TODO this must done in a service !!
92      * @return
93      */
94     public String submit()
95     {
96         if ( user == null )
97         {
98             user = new EditUserCredentials( config.getString( "redback.default.admin" ) );
99             addActionError( getText( "invalid.admin.credentials" ) );
100             return ERROR;
101         }
102
103         log.info( "user = {}", user );
104
105         internalUser = user;
106
107         validateCredentialsStrict();
108
109         UserManager userManager = super.securitySystem.getUserManager();
110
111         if ( userManager.userExists( config.getString( "redback.default.admin" ) ) )
112         {
113             // Means that the role name exist already.
114             // We need to fail fast and return to the previous page.
115             addActionError( getText( "admin.user.already.exists" ) );
116             return ERROR;
117         }
118
119         if ( hasActionErrors() || hasFieldErrors() )
120         {
121             return ERROR;
122         }
123
124         User u =
125             userManager.createUser( config.getString( "redback.default.admin" ), user.getFullName(), user.getEmail() );
126         if ( u == null )
127         {
128             addActionError( getText( "cannot.operate.on.null.user" ) );
129             return ERROR;
130         }
131
132         u.setPassword( user.getPassword() );
133         u.setLocked( false );
134         u.setPasswordChangeRequired( false );
135         u.setPermanent( true );
136
137         userManager.addUser( u );
138
139         AuditEvent event = new AuditEvent( getText( "log.account.create" ) );
140         event.setAffectedUser( u.getUsername() );
141         event.log();
142
143         try
144         {
145             roleManager.assignRole( "system-administrator", u.getPrincipal().toString() );
146             event = new AuditEvent( getText( "log.assign.role" ) );
147             event.setAffectedUser( u.getUsername() );
148             event.setRole( "system-administrator" );
149             event.log();
150         }
151         catch ( RoleManagerException rpe )
152         {
153             addActionError( getText( "cannot.assign.admin.role" ) );
154             return ERROR;
155         }
156
157         PasswordBasedAuthenticationDataSource authdatasource = new PasswordBasedAuthenticationDataSource();
158         authdatasource.setPrincipal( user.getUsername() );
159         authdatasource.setPassword( user.getPassword() );
160
161         return webLogin( authdatasource );
162     }
163
164     public EditUserCredentials getUser()
165     {
166         return user;
167     }
168
169     public void setUser( EditUserCredentials user )
170     {
171         this.user = user;
172     }
173
174     public SecureActionBundle initSecureActionBundle()
175         throws SecureActionException
176     {
177         return SecureActionBundle.OPEN;
178     }
179
180     /**
181      * 1) attempts to authentication based on the passed in data source
182      * 2) if successful sets cookies and returns LOGIN_SUCCESS
183      * 3) if failure then check what kinda failure and return error
184      *
185      * @param authdatasource
186      * @return
187      */
188     private String webLogin( AuthenticationDataSource authdatasource )
189     {
190         // An attempt should log out your authentication tokens first!
191         setAuthTokens( null );
192
193         clearErrorsAndMessages();
194
195         String principal = authdatasource.getPrincipal();
196
197         try
198         {
199             SecuritySession securitySession = securitySystem.authenticate( authdatasource );
200
201             if ( securitySession.getAuthenticationResult().isAuthenticated() )
202             {
203                 // Success!  Create tokens.
204                 setAuthTokens( securitySession );
205
206                 setCookies( authdatasource );
207
208                 AuditEvent event = new AuditEvent( getText( "log.login.success" ) );
209                 event.setAffectedUser( principal );
210                 event.log();
211
212                 User u = securitySession.getUser();
213                 u.setLastLoginDate( new Date() );
214                 securitySystem.getUserManager().updateUser( u );
215
216                 return LOGIN_SUCCESS;
217             }
218             else
219             {
220                 log.debug( "Login Action failed against principal : {}",
221                            securitySession.getAuthenticationResult().getPrincipal(),
222                            securitySession.getAuthenticationResult().getException() );
223
224                 AuthenticationResult result = securitySession.getAuthenticationResult();
225                 if ( result.getExceptionsMap() != null && !result.getExceptionsMap().isEmpty() )
226                 {
227                     if ( result.getExceptionsMap().get( AuthenticationConstants.AUTHN_NO_SUCH_USER ) != null )
228                     {
229                         addActionError( getText( "incorrect.username.password" ) );
230                     }
231                     else
232                     {
233                         addActionError( getText( "authentication.failed" ) );
234                     }
235                 }
236                 else
237                 {
238                     addActionError( getText( "authentication.failed" ) );
239                 }
240
241                 AuditEvent event = new AuditEvent( getText( "log.login.fail" ) );
242                 event.setAffectedUser( principal );
243                 event.log();
244
245                 return LOGIN_ERROR;
246             }
247         }
248         catch ( AuthenticationException ae )
249         {
250             addActionError( getText( "authentication.exception", Arrays.asList( (Object) ae.getMessage() ) ) );
251             return LOGIN_ERROR;
252         }
253         catch ( UserNotFoundException ue )
254         {
255             addActionError(
256                 getText( "user.not.found.exception", Arrays.asList( (Object) principal, ue.getMessage() ) ) );
257
258             AuditEvent event = new AuditEvent( getText( "log.login.fail" ) );
259             event.setAffectedUser( principal );
260             event.log();
261             return LOGIN_ERROR;
262         }
263         catch ( AccountLockedException e )
264         {
265             addActionError( getText( "account.locked" ) );
266
267             AuditEvent event = new AuditEvent( getText( "log.login.fail.locked" ) );
268             event.setAffectedUser( principal );
269             event.log();
270             return ACCOUNT_LOCKED;
271         }
272         catch ( MustChangePasswordException e )
273         {
274             // TODO: preferably we would not set the cookies for this "partial" login state
275             setCookies( authdatasource );
276
277             AuditEvent event = new AuditEvent( getText( "log.login.fail.locked" ) );
278             event.setAffectedUser( principal );
279             event.log();
280             return PASSWORD_CHANGE;
281         }
282     }
283
284     private void setCookies( AuthenticationDataSource authdatasource )
285     {
286         autologinCookies.setSignonCookie( authdatasource.getPrincipal(), ServletActionContext.getResponse(),
287                                           ServletActionContext.getRequest() );
288     }
289 }