View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.catalog.config;
18  
19  import java.io.File;
20  import java.net.URI;
21  import java.net.URISyntaxException;
22  import java.util.Collections;
23  import java.util.List;
24  
25  import com.fasterxml.jackson.databind.ObjectMapper;
26  
27  import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
28  import com.jcraft.jsch.JSch;
29  import com.jcraft.jsch.JSchException;
30  import com.jcraft.jsch.Session;
31  import com.jcraft.jsch.UserInfo;
32  import org.apache.logging.log4j.LogManager;
33  import org.apache.logging.log4j.Logger;
34  import org.apache.logging.log4j.catalog.api.dao.CatalogDao;
35  import org.apache.logging.log4j.catalog.api.util.CatalogEventFilter;
36  import org.apache.logging.log4j.catalog.git.dao.GitCatalogDao;
37  import org.apache.logging.log4j.catalog.security.LocalAuthorizationInterceptor;
38  import org.eclipse.jgit.api.TransportConfigCallback;
39  import org.eclipse.jgit.transport.JschConfigSessionFactory;
40  import org.eclipse.jgit.transport.OpenSshConfig;
41  import org.eclipse.jgit.transport.SshSessionFactory;
42  import org.eclipse.jgit.transport.SshTransport;
43  import org.eclipse.jgit.transport.Transport;
44  import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
45  import org.eclipse.jgit.util.FS;
46  import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
47  import org.springframework.beans.BeansException;
48  import org.springframework.beans.factory.annotation.Autowired;
49  import org.springframework.beans.factory.annotation.Value;
50  import org.springframework.context.ApplicationContext;
51  import org.springframework.context.ApplicationContextAware;
52  import org.springframework.context.MessageSource;
53  import org.springframework.context.annotation.Bean;
54  import org.springframework.context.annotation.ComponentScan;
55  import org.springframework.context.annotation.Configuration;
56  import org.springframework.context.annotation.PropertySource;
57  import org.springframework.context.annotation.Scope;
58  import org.springframework.context.support.ResourceBundleMessageSource;
59  import org.springframework.core.annotation.Order;
60  import org.springframework.http.converter.HttpMessageConverter;
61  import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
62  import org.springframework.scheduling.annotation.EnableScheduling;
63  import org.springframework.web.servlet.ViewResolver;
64  import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
65  import org.springframework.web.servlet.config.annotation.EnableWebMvc;
66  import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
67  import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
68  import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
69  import org.thymeleaf.spring4.SpringTemplateEngine;
70  import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
71  import org.thymeleaf.spring4.view.ThymeleafView;
72  import org.thymeleaf.spring4.view.ThymeleafViewResolver;
73  import org.thymeleaf.templatemode.TemplateMode;
74  
75  import static org.apache.commons.lang3.StringUtils.isNotBlank;
76  
77  @Configuration
78  @ComponentScan(basePackages = {"org.apache.logging.log4j.catalog"})
79  //@PropertySource(value = "classpath:catalog-${env:}config.properties", ignoreResourceNotFound = true)
80  public class WebMvcAppContext extends WebMvcConfigurerAdapter implements ApplicationContextAware {
81  
82      private static final Logger LOGGER = LogManager.getLogger(WebMvcAppContext.class);
83  
84      @Autowired
85      ConfigurationService configurationService;
86  
87      private ApplicationContext applicationContext;
88  
89      @Override
90      public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
91          this.applicationContext = applicationContext;
92      }
93  
94      @Override
95      public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
96          configurer.enable();
97      }
98  
99      @Override
100     public void addResourceHandlers(final ResourceHandlerRegistry registry) {
101         super.addResourceHandlers(registry);
102         registry.addResourceHandler("/images/**").addResourceLocations("classpath:/static/images/");
103         registry.addResourceHandler("/css/**").addResourceLocations("classpath:/static/css/");
104         registry.addResourceHandler("/js/**").addResourceLocations("classpath:/static/js/");
105         registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
106         registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
107     }
108 
109     @Override
110     public void addViewControllers(ViewControllerRegistry registry) {
111         registry.addViewController("products").setViewName("products");
112         registry.addViewController("categories").setViewName("categories");
113         registry.addViewController("events").setViewName("events");
114         registry.addViewController("attributes").setViewName("attributes");
115     }
116 
117     @Override
118     public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
119         converters.add(jsonMessageConverter());
120     }
121 
122     @Bean
123     public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
124         DefaultAdvisorAutoProxyCreator proxyCreator = new DefaultAdvisorAutoProxyCreator();
125         proxyCreator.setProxyTargetClass(true);
126         return proxyCreator;
127     }
128 
129     @Bean
130     public MessageSource messageSource() {
131         ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
132         messageSource.setBasename("messages");
133         return messageSource;
134     }
135 
136     @Bean
137     public LocalAuthorizationInterceptor localAuthorizationInterceptor() {
138 
139         return new LocalAuthorizationInterceptor(configurationService.getCatalogServiceAuthToken());
140     }
141 
142     public ObjectMapper objectMapper() {
143         LOGGER.debug("Creating custom ObjectMapper");
144         ObjectMapper mapper = JsonObjectMapperFactory.createMapper();
145         SimpleFilterProvider filterProvider = new SimpleFilterProvider();
146         filterProvider.addFilter("catalogEvent", new CatalogEventFilter());
147         mapper.setFilterProvider(filterProvider);
148         return mapper;
149     }
150 
151     public MappingJackson2HttpMessageConverter jsonMessageConverter() {
152         return new MappingJackson2HttpMessageConverter(objectMapper());
153     }
154 
155     @Value("${gitUserName")
156     private String gitUserName;
157 
158     @Value("${gitPassword:#{null}}")
159     private String gitPassword;
160 
161     @Value("${gitPassPhrase:#{null}}")
162     private String gitPassPhrase;
163 
164     @Value("${localRepoUrl:#{null}}")
165     private String localRepoUrl;
166 
167     @Value("${branch:#{null}}")
168     private String branch;
169 
170     @Value("${privateKeyPath:#{null}}")
171     private String privateKeyPath;
172 
173     @Value("${remoteRepoUrl}")
174     private String remoteRepoUrl;
175 
176     @Value("${remoteRepoCatalogPath:#{null}}")
177     private String remoteRepoCatalogPath;
178 
179     @Bean
180     public CatalogDao catalogDao() {
181         GitCatalogDao dataSource = new GitCatalogDao();
182         if (isNotBlank(gitUserName) && isNotBlank(gitPassword)) {
183             dataSource.setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUserName, gitPassword));
184         }
185         if (isNotBlank(remoteRepoUrl)) {
186             try {
187                 URI uri = new URI(remoteRepoUrl);
188                 if (uri.getScheme().equalsIgnoreCase("SSH")) {
189                     TransportConfigCallback transportConfigCallback = new TransportConfigCallback() {
190                         final SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
191                             @Override
192                             protected JSch createDefaultJSch( FS fs ) throws JSchException {
193                                 JSch defaultJSch = super.createDefaultJSch( fs );
194                                 if (isNotBlank(privateKeyPath)) {
195                                     defaultJSch.addIdentity(privateKeyPath);
196                                 }
197                                 return defaultJSch;
198                             }
199 
200                             @Override
201                             protected void configure(OpenSshConfig.Host host, Session session) {
202                                 session.setConfig("StrictHostKeyChecking", "no");
203                                 if (isNotBlank(gitPassPhrase)) {
204                                     session.setUserInfo(new UserInfo() {
205                                         @Override
206                                         public String getPassphrase() {
207                                             return gitPassPhrase;
208                                         }
209 
210                                         @Override
211                                         public String getPassword() {return null;}
212 
213                                         @Override
214                                         public boolean promptPassword(String message) {return false;}
215 
216                                         @Override
217                                         public boolean promptPassphrase(String message) {return true;}
218 
219                                         @Override
220                                         public boolean promptYesNo(String message) {return false;}
221 
222                                         @Override
223                                         public void showMessage(String message) {}
224                                     });
225 
226                                 }
227                             }
228                         };
229                         @Override
230                         public void configure(Transport transport) {
231                             SshTransport sshTransport = ( SshTransport )transport;
232                             sshTransport.setSshSessionFactory( sshSessionFactory );
233 
234                         }
235                     };
236                     dataSource.setTransportConfigCallback(transportConfigCallback);
237                 }
238             } catch (URISyntaxException ex) {
239                 LOGGER.error("Invalid URI {}:", remoteRepoUrl, ex);
240             }
241         } else {
242             LOGGER.error("No remote repo URL provided.");
243         }
244         if (isNotBlank(branch)) {
245             dataSource.setBranch(branch);
246         }
247 
248         if (isNotBlank(localRepoUrl)) {
249             dataSource.setLocalRepoPath(localRepoUrl);
250         } else {
251             String localRepoPath = System.getProperty("java.io.tmpdir") + "/audit/catalog";
252             File file = new File(localRepoPath);
253             File parent = file.getParentFile();
254             parent.mkdirs();
255             dataSource.setLocalRepoPath(localRepoPath);
256         }
257 
258         dataSource.setRemoteRepoUri(remoteRepoUrl);
259         if (isNotBlank(remoteRepoCatalogPath)) {
260             dataSource.setCatalogPath(remoteRepoCatalogPath);
261         }
262         return dataSource;
263     }
264 }