001    package org.apache.archiva.web.security;
002    /*
003     * Licensed to the Apache Software Foundation (ASF) under one
004     * or more contributor license agreements.  See the NOTICE file
005     * distributed with this work for additional information
006     * regarding copyright ownership.  The ASF licenses this file
007     * to you under the Apache License, Version 2.0 (the
008     * "License"); you may not use this file except in compliance
009     * with the License.  You may obtain a copy of the License at
010     *
011     * http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing,
014     * software distributed under the License is distributed on an
015     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016     * KIND, either express or implied.  See the License for the
017     * specific language governing permissions and limitations
018     * under the License.
019     */
020    
021    import org.apache.archiva.admin.model.RepositoryAdminException;
022    import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin;
023    import org.apache.archiva.redback.integration.security.role.RedbackRoleConstants;
024    import org.apache.archiva.redback.rbac.RBACManager;
025    import org.apache.archiva.redback.rbac.RbacManagerException;
026    import org.apache.archiva.redback.rbac.UserAssignment;
027    import org.apache.archiva.redback.system.check.EnvironmentCheck;
028    import org.apache.archiva.redback.users.User;
029    import org.apache.archiva.redback.users.UserManager;
030    import org.apache.archiva.redback.users.UserManagerException;
031    import org.apache.archiva.redback.users.UserNotFoundException;
032    import org.slf4j.Logger;
033    import org.slf4j.LoggerFactory;
034    import org.springframework.context.ApplicationContext;
035    import org.springframework.stereotype.Service;
036    
037    import javax.annotation.PostConstruct;
038    import javax.inject.Inject;
039    import javax.inject.Named;
040    import java.util.ArrayList;
041    import java.util.List;
042    
043    /**
044     * @author Olivier Lamy
045     */
046    @Service( "environmentCheck#archiva-locked-admin-check" )
047    public class ArchivaLockedAdminEnvironmentCheck
048        implements EnvironmentCheck
049    {
050    
051        protected Logger log = LoggerFactory.getLogger( getClass() );
052    
053    
054        @Inject
055        @Named( value = "rbacManager#cached" )
056        private RBACManager rbacManager;
057    
058        /**
059         * boolean detailing if this environment check has been executed
060         */
061        private boolean checked = false;
062    
063        @Inject
064        private ApplicationContext applicationContext;
065    
066        @Inject
067        private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin;
068    
069        private List<UserManager> userManagers;
070    
071        @PostConstruct
072        protected void initialize()
073            throws RepositoryAdminException
074        {
075            List<String> userManagerImpls =
076                redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getUserManagerImpls();
077    
078            userManagers = new ArrayList<UserManager>( userManagerImpls.size() );
079    
080            for ( String beanId : userManagerImpls )
081            {
082                userManagers.add( applicationContext.getBean( "userManager#" + beanId, UserManager.class ) );
083            }
084        }
085    
086        /**
087         * This environment check will unlock system administrator accounts that are locked on the restart of the
088         * application when the environment checks are processed.
089         *
090         * @param violations
091         */
092        public void validateEnvironment( List<String> violations )
093        {
094            if ( !checked )
095            {
096    
097                for ( UserManager userManager : userManagers )
098                {
099                    if ( userManager.isReadOnly() )
100                    {
101                        continue;
102                    }
103                    List<String> roles = new ArrayList<String>();
104                    roles.add( RedbackRoleConstants.SYSTEM_ADMINISTRATOR_ROLE );
105    
106                    List<UserAssignment> systemAdminstrators;
107                    try
108                    {
109                        systemAdminstrators = rbacManager.getUserAssignmentsForRoles( roles );
110    
111                        for ( UserAssignment userAssignment : systemAdminstrators )
112                        {
113                            try
114                            {
115                                User admin = userManager.findUser( userAssignment.getPrincipal() );
116    
117                                if ( admin.isLocked() )
118                                {
119                                    log.info( "Unlocking system administrator: {}", admin.getUsername() );
120                                    admin.setLocked( false );
121                                    userManager.updateUser( admin );
122                                }
123                            }
124                            catch ( UserNotFoundException ne )
125                            {
126                                log.warn( "Dangling UserAssignment -> {}", userAssignment.getPrincipal() );
127                            }
128                            catch ( UserManagerException e )
129                            {
130                                log.warn( "fail to find user {} for admin unlock check: {}", userAssignment.getPrincipal(),
131                                          e.getMessage() );
132                            }
133                        }
134                    }
135                    catch ( RbacManagerException e )
136                    {
137                        log.warn( "Exception when checking for locked admin user: " + e.getMessage(), e );
138                    }
139    
140                    checked = true;
141                }
142    
143            }
144    
145        }
146    }