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