001package org.apache.archiva.redback.integration.checks.security;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.redback.authentication.PasswordBasedAuthenticationDataSource;
023import org.apache.archiva.redback.configuration.UserConfiguration;
024import org.apache.archiva.redback.configuration.UserConfigurationKeys;
025import org.apache.archiva.redback.rbac.RBACManager;
026import org.apache.archiva.redback.role.RoleManager;
027import org.apache.archiva.redback.role.RoleManagerException;
028import org.apache.archiva.redback.system.SecuritySession;
029import org.apache.archiva.redback.system.SecuritySystem;
030import org.apache.archiva.redback.system.check.EnvironmentCheck;
031import org.apache.archiva.redback.users.User;
032import org.apache.archiva.redback.users.UserManager;
033import org.apache.archiva.redback.users.UserManagerException;
034import org.apache.archiva.redback.users.UserNotFoundException;
035import org.apache.commons.io.IOUtils;
036import org.apache.commons.lang3.StringUtils;
037import org.slf4j.Logger;
038import org.slf4j.LoggerFactory;
039import org.springframework.stereotype.Service;
040
041import javax.inject.Inject;
042import javax.inject.Named;
043import java.io.InputStream;
044import java.nio.file.Files;
045import java.nio.file.Path;
046import java.nio.file.Paths;
047import java.util.Date;
048import java.util.List;
049import java.util.Properties;
050
051/**
052 * @author Olivier Lamy
053 * @since 2.0
054 */
055@Service("environmentCheck#adminAutoCreateCheck")
056public class AdminAutoCreateCheck
057    implements EnvironmentCheck
058{
059
060    private Logger log = LoggerFactory.getLogger( getClass() );
061
062    public static final String FORCE_ADMIN_FILE_PATH = "redback.admin.creation.file";
063
064    public static final String ADMIN_FULL_NAME_KEY = "redback.admin.fullname";
065
066    public static final String ADMIN_EMAIL_KEY = "redback.admin.email";
067
068    public static final String ADMIN_PASSWORD_KEY = "redback.admin.password";
069
070    @Inject
071    @Named(value = "userManager#default")
072    private UserManager userManager;
073
074    @Inject
075    @Named(value = "userConfiguration#default")
076    private UserConfiguration config;
077
078    @Inject
079    protected SecuritySystem securitySystem;
080
081    @Inject
082    private RoleManager roleManager;
083
084    @Inject
085    @Named(value = "rbacManager#default")
086    private RBACManager rbacManager;
087
088    public void validateEnvironment( List<String> violations )
089    {
090        try
091        {
092            User user = userManager.findUser( getAdminUid() );
093            if ( user == null )
094            {
095                useForceAdminCreationFile();
096            }
097        }
098        catch ( UserNotFoundException e )
099        {
100            useForceAdminCreationFile();
101        }
102        catch ( UserManagerException e )
103        {
104            useForceAdminCreationFile();
105        }
106    }
107
108    private void useForceAdminCreationFile()
109    {
110        try
111        {
112            String forceAdminFilePath = System.getProperty( FORCE_ADMIN_FILE_PATH );
113            if ( StringUtils.isBlank( forceAdminFilePath ) )
114            {
115                log.info( "{} system props is empty don't use an auto creation admin ", FORCE_ADMIN_FILE_PATH );
116                return;
117            }
118            Path file = Paths.get( forceAdminFilePath );
119            if ( !Files.exists(file) )
120            {
121                log.warn( "file set in sysprops {} not exists skip admin auto creation", FORCE_ADMIN_FILE_PATH );
122                return;
123            }
124            log.debug( "user {} not found try auto creation", getAdminUid() );
125            Properties properties = new Properties();
126            InputStream fis = Files.newInputStream(file);
127            try
128            {
129                properties.load( fis );
130            }
131            catch ( Exception e )
132            {
133                log.warn( "error loading properties from file {} skip admin auto creation", forceAdminFilePath );
134                return;
135            }
136            finally
137            {
138                IOUtils.closeQuietly( fis );
139            }
140
141            // ensure we have all properties
142            String password = properties.getProperty( ADMIN_PASSWORD_KEY );
143            String email = properties.getProperty( ADMIN_EMAIL_KEY );
144            String fullName = properties.getProperty( ADMIN_FULL_NAME_KEY );
145
146            if ( StringUtils.isBlank( password ) )
147            {
148                log.warn( "property {} not set skip auto admin creation", ADMIN_PASSWORD_KEY );
149                return;
150            }
151
152            if ( StringUtils.isBlank( email ) )
153            {
154                log.warn( "property not set skip auto admin creation", ADMIN_EMAIL_KEY );
155                return;
156            }
157
158            if ( StringUtils.isBlank( fullName ) )
159            {
160                log.warn( "property {} not set skip auto admin creation", ADMIN_FULL_NAME_KEY );
161                return;
162            }
163
164            User u = userManager.createUser( getAdminUid(), fullName, email );
165
166            u.setPassword( password );
167            u.setLocked( false );
168            u.setPasswordChangeRequired( false );
169            u.setPermanent( true );
170            u.setValidated( true );
171
172            u = userManager.addUser( u );
173            u.setPassword( password );
174
175            PasswordBasedAuthenticationDataSource authdatasource = new PasswordBasedAuthenticationDataSource();
176            authdatasource.setPrincipal( u.getUsername() );
177            authdatasource.setPassword( u.getPassword() );
178            SecuritySession securitySession = securitySystem.authenticate( authdatasource );
179            if ( securitySession.getAuthenticationResult().isAuthenticated() )
180            {
181                // good add various tokens.
182                u = securitySession.getUser();
183                u.setLastLoginDate( new Date() );
184                u.setPassword( null );
185                securitySystem.getUserManager().updateUser( u );
186            }
187            assignAdminRole( u );
188
189        }
190        catch ( Exception e )
191        {
192            log.warn( "failed to automatically create an admin account {}", e.getMessage(), e );
193        }
194    }
195
196    private void assignAdminRole( User user )
197        throws RoleManagerException
198    {
199        roleManager.assignRole( "system-administrator", user.getUsername() );
200    }
201
202    private String getAdminUid()
203    {
204        return config.getString( UserConfigurationKeys.DEFAULT_ADMIN );
205    }
206}