1 package org.apache.archiva.redback.struts2.action.admin;
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
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;
45 import javax.inject.Inject;
46 import java.util.Arrays;
47 import java.util.Date;
52 * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
55 @Controller( "redback-admin-account" )
57 public class AddAdminUserAction
58 extends AbstractAdminUserCredentialsAction
60 private static final String LOGIN_ERROR = "login-error";
62 private static final String LOGIN_SUCCESS = "security-login-success";
64 private static final String PASSWORD_CHANGE = "security-must-change-password";
66 private static final String ACCOUNT_LOCKED = "security-login-locked";
69 private RoleManager roleManager;
73 private UserConfiguration config;
75 private EditUserCredentials user;
78 private AutoLoginCookies autologinCookies;
84 user = new EditUserCredentials( config.getString( "redback.default.admin" ) );
91 * TODO this must done in a service !!
94 public String submit()
98 user = new EditUserCredentials( config.getString( "redback.default.admin" ) );
99 addActionError( getText( "invalid.admin.credentials" ) );
103 log.info( "user = {}", user );
107 validateCredentialsStrict();
109 UserManager userManager = super.securitySystem.getUserManager();
111 if ( userManager.userExists( config.getString( "redback.default.admin" ) ) )
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" ) );
119 if ( hasActionErrors() || hasFieldErrors() )
125 userManager.createUser( config.getString( "redback.default.admin" ), user.getFullName(), user.getEmail() );
128 addActionError( getText( "cannot.operate.on.null.user" ) );
132 u.setPassword( user.getPassword() );
133 u.setLocked( false );
134 u.setPasswordChangeRequired( false );
135 u.setPermanent( true );
137 userManager.addUser( u );
139 AuditEvent event = new AuditEvent( getText( "log.account.create" ) );
140 event.setAffectedUser( u.getUsername() );
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" );
151 catch ( RoleManagerException rpe )
153 addActionError( getText( "cannot.assign.admin.role" ) );
157 PasswordBasedAuthenticationDataSource authdatasource = new PasswordBasedAuthenticationDataSource();
158 authdatasource.setPrincipal( user.getUsername() );
159 authdatasource.setPassword( user.getPassword() );
161 return webLogin( authdatasource );
164 public EditUserCredentials getUser()
169 public void setUser( EditUserCredentials user )
174 public SecureActionBundle initSecureActionBundle()
175 throws SecureActionException
177 return SecureActionBundle.OPEN;
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
185 * @param authdatasource
188 private String webLogin( AuthenticationDataSource authdatasource )
190 // An attempt should log out your authentication tokens first!
191 setAuthTokens( null );
193 clearErrorsAndMessages();
195 String principal = authdatasource.getPrincipal();
199 SecuritySession securitySession = securitySystem.authenticate( authdatasource );
201 if ( securitySession.getAuthenticationResult().isAuthenticated() )
203 // Success! Create tokens.
204 setAuthTokens( securitySession );
206 setCookies( authdatasource );
208 AuditEvent event = new AuditEvent( getText( "log.login.success" ) );
209 event.setAffectedUser( principal );
212 User u = securitySession.getUser();
213 u.setLastLoginDate( new Date() );
214 securitySystem.getUserManager().updateUser( u );
216 return LOGIN_SUCCESS;
220 log.debug( "Login Action failed against principal : {}",
221 securitySession.getAuthenticationResult().getPrincipal(),
222 securitySession.getAuthenticationResult().getException() );
224 AuthenticationResult result = securitySession.getAuthenticationResult();
225 if ( result.getExceptionsMap() != null && !result.getExceptionsMap().isEmpty() )
227 if ( result.getExceptionsMap().get( AuthenticationConstants.AUTHN_NO_SUCH_USER ) != null )
229 addActionError( getText( "incorrect.username.password" ) );
233 addActionError( getText( "authentication.failed" ) );
238 addActionError( getText( "authentication.failed" ) );
241 AuditEvent event = new AuditEvent( getText( "log.login.fail" ) );
242 event.setAffectedUser( principal );
248 catch ( AuthenticationException ae )
250 addActionError( getText( "authentication.exception", Arrays.asList( (Object) ae.getMessage() ) ) );
253 catch ( UserNotFoundException ue )
256 getText( "user.not.found.exception", Arrays.asList( (Object) principal, ue.getMessage() ) ) );
258 AuditEvent event = new AuditEvent( getText( "log.login.fail" ) );
259 event.setAffectedUser( principal );
263 catch ( AccountLockedException e )
265 addActionError( getText( "account.locked" ) );
267 AuditEvent event = new AuditEvent( getText( "log.login.fail.locked" ) );
268 event.setAffectedUser( principal );
270 return ACCOUNT_LOCKED;
272 catch ( MustChangePasswordException e )
274 // TODO: preferably we would not set the cookies for this "partial" login state
275 setCookies( authdatasource );
277 AuditEvent event = new AuditEvent( getText( "log.login.fail.locked" ) );
278 event.setAffectedUser( principal );
280 return PASSWORD_CHANGE;
284 private void setCookies( AuthenticationDataSource authdatasource )
286 autologinCookies.setSignonCookie( authdatasource.getPrincipal(), ServletActionContext.getResponse(),
287 ServletActionContext.getRequest() );