View Javadoc
1   package com;
2   
3   /*
4    * #%L
5    * Gateway
6    * %%
7    * Copyright (C) 2015 Powered by Sergey
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  
24  import com.utils.SecurityContextReader;
25  import org.springframework.beans.factory.annotation.Value;
26  import org.springframework.boot.SpringApplication;
27  import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
28  import org.springframework.boot.autoconfigure.security.SecurityProperties;
29  import org.springframework.boot.builder.SpringApplicationBuilder;
30  import org.springframework.boot.context.web.SpringBootServletInitializer;
31  import org.springframework.context.MessageSource;
32  import org.springframework.context.annotation.Bean;
33  import org.springframework.context.annotation.ComponentScan;
34  import org.springframework.context.annotation.Configuration;
35  import org.springframework.context.support.ReloadableResourceBundleMessageSource;
36  import org.springframework.core.annotation.Order;
37  import org.springframework.core.io.ClassPathResource;
38  import org.springframework.data.domain.AuditorAware;
39  import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
40  import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
41  import org.springframework.jdbc.datasource.DriverManagerDataSource;
42  import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
43  import org.springframework.mail.javamail.JavaMailSender;
44  import org.springframework.mail.javamail.JavaMailSenderImpl;
45  import org.springframework.orm.jpa.JpaVendorAdapter;
46  import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
47  import org.springframework.orm.jpa.vendor.Database;
48  import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
49  import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
50  import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
51  import org.springframework.security.config.annotation.web.builders.HttpSecurity;
52  import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
53  import org.springframework.security.crypto.password.StandardPasswordEncoder;
54  import org.springframework.transaction.annotation.EnableTransactionManagement;
55  import org.springframework.util.StringUtils;
56  import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
57  import org.springframework.web.bind.annotation.RequestMapping;
58  import org.springframework.web.bind.annotation.RestController;
59  import org.springframework.web.servlet.LocaleResolver;
60  import org.springframework.web.servlet.i18n.CookieLocaleResolver;
61  import org.thymeleaf.spring3.SpringTemplateEngine;
62  import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
63  
64  import javax.persistence.EntityManagerFactory;
65  import javax.sql.DataSource;
66  import java.security.Principal;
67  import java.util.Properties;
68  
69  @Configuration // needed to specify that the class contains global spring configurations
70  @ComponentScan
71  @EnableAutoConfiguration
72  @EnableJpaRepositories // needed to enable JPA based repositories
73  @EnableTransactionManagement
74  @RestController // needed to enable rest end points within the class
75  @EnableGlobalMethodSecurity(securedEnabled=true) // needed for method based security (@Secured("ROLE_ADMIN") annotation))
76  @EnableJpaAuditing//needed to activate auditing(automatically managed fields createdBy, createdDate, lastModifiedBy, lastModifiedDate)
77  
78  public class GatewayApplication extends SpringBootServletInitializer{
79  	@Value("${db.type}")
80  	private String dbType;
81  
82  	@Value("${db.dialect}")
83  	private String dbDialect;
84  
85  	@Value("${db.driver}")
86  	private String dbDriver;
87  
88  	@Value("${db.url}")
89      private String dbUrl;
90  
91      @Value("${db.username}")
92      private String dbUsername;
93  
94      @Value("${db.password}")
95      private String dbPassword;
96  
97      @Value("${mailserver.host}")
98      private String mailHost;
99  
100     @Value("${mailserver.port}")
101     private int mailPort;
102 
103 	@Value("${mailserver.protocol}")
104 	private String mailProtocol;
105 
106 	@Value("${mailserver.ssl.enable}")
107 	private String mailEnableSSL;
108 
109     @Value("${mailserver.username}")
110     private String mailUsername;
111 
112     @Value("${mailserver.password}")
113 	private String mailPassword;
114 
115 	@Value("${mailserver.debug}")
116 	private String mailDebug;
117 
118     private class SpringSecurityAuditorAware implements AuditorAware<String> {
119 		@Override
120 		public String getCurrentAuditor() {
121 			SecurityContextReader securityContextReader = new SecurityContextReader();
122 			return securityContextReader.getUsername();
123 		}
124 	}
125 
126     @Bean
127     public DataSource dataSource(){
128         DriverManagerDataSource ds = new DriverManagerDataSource();
129         ds.setDriverClassName(dbDriver);
130         ds.setUrl(dbUrl);
131         ds.setUsername(dbUsername);
132         ds.setPassword(dbPassword);
133 
134         return ds;
135     }
136 
137 	@Bean
138 	public AuditorAware<String> auditorProvider() {
139 		return new SpringSecurityAuditorAware();
140 	}
141 
142 	@Bean
143 	public JpaVendorAdapter jpaVendorAdapter() {
144 		HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
145 		adapter.setDatabase(Database.valueOf(dbType));
146 		adapter.setShowSql(true);
147 		adapter.setGenerateDdl(true);
148 		adapter.setDatabasePlatform(dbDialect);
149 		return adapter;
150 	}
151 
152 	@Bean
153 	public EntityManagerFactory entityManagerFactory() {
154 
155 		HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
156 		vendorAdapter.setDatabase(Database.valueOf(dbType));
157 		vendorAdapter.setShowSql(true);
158 		vendorAdapter.setGenerateDdl(false); //true value not for production !!! update db after entityManager instantiation based on entities
159 		vendorAdapter.setDatabasePlatform(dbDialect);
160 
161 		LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
162 		factory.setJpaVendorAdapter(vendorAdapter);
163 		factory.setPackagesToScan("com.entity");
164 		factory.setDataSource(dataSource());
165 		factory.afterPropertiesSet();
166 
167 		return factory.getObject();
168 	}
169 
170 	@Bean
171 	public javax.validation.Validator localValidatorFactoryBean() {
172 		LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
173 		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
174 		messageSource.setBasename("classpath:ValidatorMessages");
175 		factory.setValidationMessageSource(messageSource);
176 		return factory;
177 	}
178 
179 	@Bean
180 	public LocaleResolver localeResolver() {
181 		CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
182 		cookieLocaleResolver.setDefaultLocale(StringUtils.parseLocaleString("en"));
183 		cookieLocaleResolver.setCookieName("appLanguage");
184 		cookieLocaleResolver.setCookieMaxAge(604800);//one month
185 		return cookieLocaleResolver;
186 	}
187 
188 	@Bean
189 	public MessageSource messageSource() {
190 
191 		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
192 		messageSource.setBasenames("classpath:messages");
193 		// if true, the key of the message will be displayed if the key is not
194 		// found, instead of throwing a NoSuchMessageException
195 		messageSource.setUseCodeAsDefaultMessage(true);
196 		messageSource.setDefaultEncoding("UTF-8");
197 		// # -1 : never reload, 0 always reload
198 		messageSource.setCacheSeconds(0);
199 		return messageSource;
200 	}
201 
202 	@Bean
203 	public JavaMailSender mailSender(){
204 		JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
205 
206 		mailSender.setHost(mailHost);
207 		mailSender.setPort(mailPort);
208 		mailSender.setProtocol(mailProtocol);
209 		mailSender.setUsername(mailUsername);
210 		mailSender.setPassword(mailPassword);
211 
212 		Properties properties = new Properties();
213         properties.setProperty("mail.smtps.auth", "true");
214 		properties.setProperty("mail.smtp.ssl.enable", mailEnableSSL);
215 		properties.setProperty("mail.transport.protocol", mailProtocol);
216 		properties.setProperty("mail.debug", mailDebug);
217 		mailSender.setJavaMailProperties(properties);
218 
219 		return mailSender;
220 	}
221 
222 	@Bean
223 	public ClassLoaderTemplateResolver emailTemplateResolver() {
224 		ClassLoaderTemplateResolver resolver =
225 				new ClassLoaderTemplateResolver();
226 		resolver.setPrefix("emailTemplates/");
227 		resolver.setSuffix(".html");
228 		resolver.setTemplateMode("HTML5");
229 		resolver.setCharacterEncoding("UTF-8");
230 		return resolver;
231 	}
232 
233 	@Bean
234 	public SpringTemplateEngine templateEngine() {
235 		SpringTemplateEngine engine = new SpringTemplateEngine();
236 		return engine;
237 	}
238 
239 	@Override
240 	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
241 		return application.sources(GatewayApplication.class);
242 	}
243 
244 	public static void main(String[] args) {
245 		SpringApplication.run(GatewayApplication.class, args);
246 	}
247 
248 	@Configuration
249 	@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
250 	protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
251 		@Override
252 		protected void configure(HttpSecurity http) throws Exception {
253 			//2419200 means 4 weeks
254 			http
255 					.formLogin()
256 				.and()
257 					.rememberMe()
258 					.tokenValiditySeconds(2419200)
259 					.key("gateway")
260 					.and()
261 					.logout()
262 				.and()
263 					.authorizeRequests()
264 						.antMatchers("/#/login", "/user", "/login?logout", "/", "/index.html", "/build/**", "/views/**", "/img/**",  "/templates/**", "/fonts/**", "/gateway/createUser", "/gateway/activateUser", "/gateway/initiateResetPassword",  "/gateway/resetPassword", "/gateway/config").permitAll()
265 						.anyRequest().authenticated()
266 					.and()
267 					.csrf().disable();
268 		}
269 
270 		@Value("${db.driver}}")
271 		private String dbDriver;
272 
273         @Value("${db.url}")
274         private String dbUrl;
275 
276         @Value("${db.username}")
277         private String dbUsername;
278 
279         @Value("${db.password}")
280         private String mySqldb;
281 
282         @Bean
283         public DataSource dataSource(){
284             DriverManagerDataSource ds = new DriverManagerDataSource();
285             ds.setDriverClassName(dbDriver);
286             ds.setUrl(dbUrl);
287             ds.setUsername(dbUsername);
288             ds.setPassword(mySqldb);
289 
290             return ds;
291         }
292 
293 		@Override
294 		protected void configure(AuthenticationManagerBuilder auth)	throws Exception {
295 			auth.jdbcAuthentication().dataSource(dataSource()).passwordEncoder(new StandardPasswordEncoder("53cr3t"));
296 
297 			ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
298 			populator.setContinueOnError(true);
299 			populator.addScript(new ClassPathResource("/sql/db_initializer.sql"));
300 			populator.populate(dataSource().getConnection());
301 		}
302 	}
303 
304 	@RequestMapping("/user")
305 	public Principal user(Principal user) {
306 				return user;
307 	}
308 }