]> source.dussan.org Git - archiva.git/blob
931cab4d1fe8824431ed4ce0a012aa67ef5c068c
[archiva.git] /
1 package org.apache.archiva.web.startup;
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.common.ArchivaException;
23 import org.apache.archiva.configuration.ArchivaConfiguration;
24 import org.apache.archiva.configuration.ConfigurationNames;
25 import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
26 import org.apache.archiva.redback.components.registry.RegistryListener;
27 import org.apache.archiva.redback.rbac.RBACManager;
28 import org.apache.archiva.redback.rbac.RbacManagerException;
29 import org.apache.archiva.redback.rbac.UserAssignment;
30 import org.apache.archiva.redback.role.RoleManager;
31 import org.apache.archiva.redback.role.RoleManagerException;
32 import org.apache.archiva.redback.system.check.EnvironmentCheck;
33 import org.apache.archiva.redback.users.UserManager;
34 import org.apache.archiva.security.common.ArchivaRoleConstants;
35 import org.apache.commons.collections.CollectionUtils;
36 import org.apache.commons.lang.StringUtils;
37 import org.apache.commons.lang.time.StopWatch;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.context.ApplicationContext;
41 import org.springframework.stereotype.Service;
42
43 import javax.annotation.PostConstruct;
44 import javax.inject.Inject;
45 import javax.inject.Named;
46 import java.util.ArrayList;
47 import java.util.HashMap;
48 import java.util.List;
49 import java.util.Map;
50 import java.util.Map.Entry;
51
52 /**
53  * ConfigurationSynchronization
54  */
55 @Service
56 public class SecuritySynchronization
57     implements RegistryListener
58 {
59     private Logger log = LoggerFactory.getLogger( SecuritySynchronization.class );
60
61     @Inject
62     private RoleManager roleManager;
63
64     @Inject
65     @Named(value = "rbacManager#cached")
66     private RBACManager rbacManager;
67
68     private Map<String, EnvironmentCheck> checkers;
69
70     @Inject
71     private ArchivaConfiguration archivaConfiguration;
72
73     @Inject
74     private ApplicationContext applicationContext;
75
76     @PostConstruct
77     public void initialize()
78     {
79         checkers = getBeansOfType( EnvironmentCheck.class );
80     }
81
82     protected <T> Map<String, T> getBeansOfType( Class<T> clazz )
83     {
84         //TODO do some caching here !!!
85         // olamy : with plexus we get only roleHint
86         // as per convention we named spring bean role#hint remove role# if exists
87         Map<String, T> springBeans = applicationContext.getBeansOfType( clazz );
88
89         Map<String, T> beans = new HashMap<>( springBeans.size() );
90
91         for ( Entry<String, T> entry : springBeans.entrySet() )
92         {
93             String key = StringUtils.substringAfterLast( entry.getKey(), "#" );
94             beans.put( key, entry.getValue() );
95         }
96         return beans;
97     }
98
99     @Override
100     public void afterConfigurationChange( org.apache.archiva.redback.components.registry.Registry registry,
101                                           String propertyName, Object propertyValue )
102     {
103         if ( ConfigurationNames.isManagedRepositories( propertyName ) && propertyName.endsWith( ".id" ) )
104         {
105             if ( propertyValue != null )
106             {
107                 syncRepoConfiguration( (String) propertyValue );
108             }
109         }
110     }
111
112     @Override
113     public void beforeConfigurationChange( org.apache.archiva.redback.components.registry.Registry registry,
114                                            String propertyName, Object propertyValue )
115     {
116         /* do nothing */
117     }
118
119     private void synchConfiguration( List<ManagedRepositoryConfiguration> repos )
120     {
121         // NOTE: Remote Repositories do not have roles or security placed around them.
122
123         for ( ManagedRepositoryConfiguration repoConfig : repos )
124         {
125             syncRepoConfiguration( repoConfig.getId() );
126         }
127     }
128
129     private void syncRepoConfiguration( String id )
130     {
131         // manage roles for repositories
132         try
133         {
134             if ( !roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, id ) )
135             {
136                 roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, id );
137             }
138             else
139             {
140                 roleManager.verifyTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, id );
141             }
142
143             if ( !roleManager.templatedRoleExists( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, id ) )
144             {
145                 roleManager.createTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, id );
146             }
147             else
148             {
149                 roleManager.verifyTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, id );
150             }
151         }
152         catch ( RoleManagerException e )
153         {
154             // Log error.
155             log.error( "Unable to create roles for configured repositories: {}", e.getMessage(), e );
156         }
157     }
158
159     public void startup()
160         throws ArchivaException
161     {
162         executeEnvironmentChecks();
163
164         synchConfiguration( archivaConfiguration.getConfiguration().getManagedRepositories() );
165         archivaConfiguration.addChangeListener( this );
166
167         if ( archivaConfiguration.isDefaulted() )
168         {
169             assignRepositoryObserverToGuestUser( archivaConfiguration.getConfiguration().getManagedRepositories() );
170         }
171     }
172
173     private void executeEnvironmentChecks()
174         throws ArchivaException
175     {
176         if ( ( checkers == null ) || CollectionUtils.isEmpty( checkers.values() ) )
177         {
178             throw new ArchivaException(
179                 "Unable to initialize the Redback Security Environment, " + "no Environment Check components found." );
180         }
181
182         StopWatch stopWatch = new StopWatch();
183         stopWatch.reset();
184         stopWatch.start();
185
186         List<String> violations = new ArrayList<>();
187
188         for ( Entry<String, EnvironmentCheck> entry : checkers.entrySet() )
189         {
190             EnvironmentCheck check = entry.getValue();
191             List<String> v = new ArrayList<>();
192             check.validateEnvironment( v );
193             log.info( "Environment Check: {} -> {} violation(s)", entry.getKey(), v.size() );
194             for ( String s : v )
195             {
196                 violations.add( "[" + entry.getKey() + "] " + s );
197             }
198         }
199
200         if ( CollectionUtils.isNotEmpty( violations ) )
201         {
202             StringBuilder msg = new StringBuilder();
203             msg.append( "EnvironmentCheck Failure.\n" );
204             msg.append( "======================================================================\n" );
205             msg.append( " ENVIRONMENT FAILURE !! \n" );
206             msg.append( "\n" );
207
208             for ( String violation : violations )
209             {
210                 msg.append( violation ).append( "\n" );
211             }
212
213             msg.append( "\n" );
214             msg.append( "======================================================================" );
215             log.error( msg.toString() );
216
217             throw new ArchivaException( "Unable to initialize Redback Security Environment, [" + violations.size()
218                                             + "] violation(s) encountered, See log for details." );
219         }
220
221         stopWatch.stop();
222         log.info( "time to execute all EnvironmentCheck: {} ms", stopWatch.getTime() );
223     }
224
225
226     private void assignRepositoryObserverToGuestUser( List<ManagedRepositoryConfiguration> repos )
227     {
228         for ( ManagedRepositoryConfiguration repoConfig : repos )
229         {
230             String repoId = repoConfig.getId();
231
232             String principal = UserManager.GUEST_USERNAME;
233
234             try
235             {
236                 UserAssignment ua;
237
238                 if ( rbacManager.userAssignmentExists( principal ) )
239                 {
240                     ua = rbacManager.getUserAssignment( principal );
241                 }
242                 else
243                 {
244                     ua = rbacManager.createUserAssignment( principal );
245                 }
246
247                 ua.addRoleName( ArchivaRoleConstants.toRepositoryObserverRoleName( repoId ) );
248                 rbacManager.saveUserAssignment( ua );
249             }
250             catch ( RbacManagerException e )
251             {
252                 log.warn( "Unable to add role [{}] to {} user.", ArchivaRoleConstants.toRepositoryObserverRoleName( repoId ), principal, e );
253             }
254         }
255     }
256 }