This project has retired. For details please refer to its Attic page.
SecuritySynchronization xref
View Javadoc
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.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.collections4.CollectionUtils;
36  import org.apache.commons.lang3.StringUtils;
37  import org.apache.commons.lang3.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.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.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 }