001    package org.apache.archiva.rest.services;
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.beans.RedbackRuntimeConfiguration;
023    import org.apache.archiva.admin.model.beans.LdapConfiguration;
024    import org.apache.archiva.admin.model.runtime.RedbackRuntimeConfigurationAdmin;
025    import org.apache.archiva.redback.authentication.Authenticator;
026    import org.apache.archiva.redback.common.ldap.connection.LdapConnection;
027    import org.apache.archiva.redback.common.ldap.user.LdapUserMapper;
028    import org.apache.archiva.redback.common.ldap.connection.DefaultLdapConnection;
029    import org.apache.archiva.redback.common.ldap.connection.LdapConnectionConfiguration;
030    import org.apache.archiva.redback.common.ldap.connection.LdapConnectionFactory;
031    import org.apache.archiva.redback.common.ldap.connection.LdapException;
032    import org.apache.archiva.redback.components.cache.Cache;
033    import org.apache.archiva.redback.policy.CookieSettings;
034    import org.apache.archiva.redback.policy.PasswordRule;
035    import org.apache.archiva.redback.rbac.RBACManager;
036    import org.apache.archiva.redback.role.RoleManager;
037    import org.apache.archiva.redback.users.UserManager;
038    import org.apache.archiva.rest.api.model.RBACManagerImplementationInformation;
039    import org.apache.archiva.rest.api.model.RedbackImplementationsInformations;
040    import org.apache.archiva.rest.api.model.UserManagerImplementationInformation;
041    import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
042    import org.apache.archiva.rest.api.services.RedbackRuntimeConfigurationService;
043    
044    import org.apache.commons.lang.StringUtils;
045    import org.springframework.context.ApplicationContext;
046    import org.springframework.stereotype.Service;
047    
048    import javax.inject.Inject;
049    import javax.inject.Named;
050    import javax.naming.InvalidNameException;
051    import java.util.ArrayList;
052    import java.util.Collection;
053    import java.util.Collections;
054    import java.util.List;
055    import java.util.Map;
056    import java.util.Properties;
057    
058    /**
059     * @author Olivier Lamy
060     * @since 1.4-M4
061     */
062    @Service("redbackRuntimeConfigurationService#rest")
063    public class DefaultRedbackRuntimeConfigurationService
064        extends AbstractRestService
065        implements RedbackRuntimeConfigurationService
066    {
067        @Inject
068        private RedbackRuntimeConfigurationAdmin redbackRuntimeConfigurationAdmin;
069    
070        @Inject
071        @Named(value = "userManager#configurable")
072        private UserManager userManager;
073    
074        @Inject
075        @Named(value = "rbacManager#default")
076        private RBACManager rbacManager;
077    
078        @Inject
079        private RoleManager roleManager;
080    
081        @Inject
082        private ApplicationContext applicationContext;
083    
084        @Inject
085        @Named(value = "ldapConnectionFactory#configurable")
086        private LdapConnectionFactory ldapConnectionFactory;
087    
088        @Inject
089        @Named(value = "cache#users")
090        private Cache usersCache;
091    
092        @Inject
093        private LdapUserMapper ldapUserMapper;
094    
095    
096        public RedbackRuntimeConfiguration getRedbackRuntimeConfiguration()
097            throws ArchivaRestServiceException
098        {
099            try
100            {
101                return redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration();
102            }
103            catch ( RepositoryAdminException e )
104            {
105                throw new ArchivaRestServiceException( e.getMessage(), e );
106            }
107        }
108    
109        public Boolean updateRedbackRuntimeConfiguration( RedbackRuntimeConfiguration redbackRuntimeConfiguration )
110            throws ArchivaRestServiceException
111        {
112            try
113            {
114                // has user manager impl changed ?
115                boolean userManagerChanged = redbackRuntimeConfiguration.getUserManagerImpls().size()
116                    != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getUserManagerImpls().size();
117    
118                userManagerChanged =
119                    userManagerChanged || ( redbackRuntimeConfiguration.getUserManagerImpls().toString().hashCode()
120                        != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getUserManagerImpls().toString().hashCode() );
121    
122                boolean rbacManagerChanged = redbackRuntimeConfiguration.getRbacManagerImpls().size()
123                    != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getRbacManagerImpls().size();
124    
125                rbacManagerChanged =
126                    rbacManagerChanged || ( redbackRuntimeConfiguration.getRbacManagerImpls().toString().hashCode()
127                        != redbackRuntimeConfigurationAdmin.getRedbackRuntimeConfiguration().getRbacManagerImpls().toString().hashCode() );
128    
129                redbackRuntimeConfigurationAdmin.updateRedbackRuntimeConfiguration( redbackRuntimeConfiguration );
130    
131                if ( userManagerChanged )
132                {
133                    log.info( "user managerImpls changed to {} so reload it",
134                              redbackRuntimeConfiguration.getUserManagerImpls() );
135                    userManager.initialize();
136                }
137    
138                if ( rbacManagerChanged )
139                {
140                    log.info( "rbac manager changed to {} so reload it",
141                              redbackRuntimeConfiguration.getRbacManagerImpls() );
142                    rbacManager.initialize();
143                    roleManager.initialize();
144                }
145    
146                ldapConnectionFactory.initialize();
147    
148                Collection<PasswordRule> passwordRules = applicationContext.getBeansOfType( PasswordRule.class ).values();
149    
150                for ( PasswordRule passwordRule : passwordRules )
151                {
152                    passwordRule.initialize();
153                }
154    
155                Collection<CookieSettings> cookieSettingsList =
156                    applicationContext.getBeansOfType( CookieSettings.class ).values();
157    
158                for ( CookieSettings cookieSettings : cookieSettingsList )
159                {
160                    cookieSettings.initialize();
161                }
162    
163                Collection<Authenticator> authenticators =
164                    applicationContext.getBeansOfType( Authenticator.class ).values();
165    
166                for ( Authenticator authenticator : authenticators )
167                {
168                    authenticator.initialize();
169                }
170    
171                // users cache
172                usersCache.setTimeToIdleSeconds(
173                    redbackRuntimeConfiguration.getUsersCacheConfiguration().getTimeToIdleSeconds() );
174                usersCache.setTimeToLiveSeconds(
175                    redbackRuntimeConfiguration.getUsersCacheConfiguration().getTimeToLiveSeconds() );
176                usersCache.setMaxElementsInMemory(
177                    redbackRuntimeConfiguration.getUsersCacheConfiguration().getMaxElementsInMemory() );
178                usersCache.setMaxElementsOnDisk(
179                    redbackRuntimeConfiguration.getUsersCacheConfiguration().getMaxElementsOnDisk() );
180    
181                ldapUserMapper.initialize();
182    
183                //check repositories roles are here !!!
184    
185                return Boolean.TRUE;
186            }
187            catch ( Exception e )
188            {
189                log.error( e.getMessage(), e );
190                throw new ArchivaRestServiceException( e.getMessage(), e );
191            }
192        }
193    
194        public List<UserManagerImplementationInformation> getUserManagerImplementationInformations()
195            throws ArchivaRestServiceException
196        {
197    
198            Map<String, UserManager> beans = applicationContext.getBeansOfType( UserManager.class );
199    
200            if ( beans.isEmpty() )
201            {
202                return Collections.emptyList();
203            }
204    
205            List<UserManagerImplementationInformation> informations =
206                new ArrayList<UserManagerImplementationInformation>( beans.size() );
207    
208            for ( Map.Entry<String, UserManager> entry : beans.entrySet() )
209            {
210                UserManager userManager = applicationContext.getBean( entry.getKey(), UserManager.class );
211                if ( userManager.isFinalImplementation() )
212                {
213                    UserManagerImplementationInformation information = new UserManagerImplementationInformation();
214                    information.setBeanId( StringUtils.substringAfter( entry.getKey(), "#" ) );
215                    information.setDescriptionKey( userManager.getDescriptionKey() );
216                    information.setReadOnly( userManager.isReadOnly() );
217                    informations.add( information );
218                }
219            }
220    
221            return informations;
222        }
223    
224        public List<RBACManagerImplementationInformation> getRbacManagerImplementationInformations()
225            throws ArchivaRestServiceException
226        {
227            Map<String, RBACManager> beans = applicationContext.getBeansOfType( RBACManager.class );
228    
229            if ( beans.isEmpty() )
230            {
231                return Collections.emptyList();
232            }
233    
234            List<RBACManagerImplementationInformation> informations =
235                new ArrayList<RBACManagerImplementationInformation>( beans.size() );
236    
237            for ( Map.Entry<String, RBACManager> entry : beans.entrySet() )
238            {
239                RBACManager rbacManager = applicationContext.getBean( entry.getKey(), RBACManager.class );
240                if ( rbacManager.isFinalImplementation() )
241                {
242                    RBACManagerImplementationInformation information = new RBACManagerImplementationInformation();
243                    information.setBeanId( StringUtils.substringAfter( entry.getKey(), "#" ) );
244                    information.setDescriptionKey( rbacManager.getDescriptionKey() );
245                    information.setReadOnly( rbacManager.isReadOnly() );
246                    informations.add( information );
247                }
248            }
249    
250            return informations;
251        }
252    
253        public RedbackImplementationsInformations getRedbackImplementationsInformations()
254            throws ArchivaRestServiceException
255        {
256            return new RedbackImplementationsInformations( getUserManagerImplementationInformations(),
257                                                           getRbacManagerImplementationInformations() );
258        }
259    
260        public Boolean checkLdapConnection()
261            throws ArchivaRestServiceException
262        {
263            LdapConnection ldapConnection = null;
264            try
265            {
266                ldapConnection = ldapConnectionFactory.getConnection();
267            }
268            catch ( LdapException e )
269            {
270                log.warn( "fail to get ldapConnection: {}", e.getMessage(), e );
271                throw new ArchivaRestServiceException( e.getMessage(), e );
272            }
273            finally
274            {
275    
276                if ( ldapConnection != null )
277                {
278                    ldapConnection.close();
279                }
280            }
281    
282            return Boolean.TRUE;
283        }
284    
285        public Boolean checkLdapConnection( LdapConfiguration ldapConfiguration )
286            throws ArchivaRestServiceException
287        {
288            LdapConnection ldapConnection = null;
289            try
290            {
291                LdapConnectionConfiguration ldapConnectionConfiguration =
292                    new LdapConnectionConfiguration( ldapConfiguration.getHostName(), ldapConfiguration.getPort(),
293                                                     ldapConfiguration.getBaseDn(), ldapConfiguration.getContextFactory(),
294                                                     ldapConfiguration.getBindDn(), ldapConfiguration.getPassword(),
295                                                     ldapConfiguration.getAuthenticationMethod(),
296                                                     toProperties( ldapConfiguration.getExtraProperties() ) );
297                ldapConnectionConfiguration.setSsl( ldapConfiguration.isSsl() );
298    
299                ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration );
300    
301                ldapConnection.close();
302    
303                // verify groups dn value too
304    
305                ldapConnectionConfiguration =
306                    new LdapConnectionConfiguration( ldapConfiguration.getHostName(), ldapConfiguration.getPort(),
307                                                     ldapConfiguration.getBaseGroupsDn(),
308                                                     ldapConfiguration.getContextFactory(), ldapConfiguration.getBindDn(),
309                                                     ldapConfiguration.getPassword(),
310                                                     ldapConfiguration.getAuthenticationMethod(),
311                                                     toProperties( ldapConfiguration.getExtraProperties() ) );
312    
313                ldapConnectionConfiguration.setSsl( ldapConfiguration.isSsl() );
314    
315                ldapConnection = ldapConnectionFactory.getConnection( ldapConnectionConfiguration );
316            }
317            catch ( InvalidNameException e )
318            {
319                log.warn( "fail to get ldapConnection: {}", e.getMessage(), e);
320                throw new ArchivaRestServiceException( e.getMessage(), e );
321            }
322            catch ( LdapException e )
323            {
324                log.warn( "fail to get ldapConnection: {}", e.getMessage(), e);
325                throw new ArchivaRestServiceException( e.getMessage(), e );
326            }
327            finally
328            {
329    
330                if ( ldapConnection != null )
331                {
332                    ldapConnection.close();
333                }
334            }
335    
336            return Boolean.TRUE;
337        }
338    
339        private Properties toProperties( Map<String, String> map )
340        {
341            Properties properties = new Properties();
342            if ( map == null || map.isEmpty() )
343            {
344                return properties;
345            }
346            for ( Map.Entry<String, String> entry : map.entrySet() )
347            {
348                properties.put( entry.getKey(), entry.getValue() );
349            }
350            return properties;
351        }
352    
353    }
354    
355