From 7ed3795da542bab397ee7ed8978bde896abf5cf4 Mon Sep 17 00:00:00 2001
From: Vitaly Takmazov
Date: Tue, 6 Feb 2018 17:54:49 +0300
Subject: server: merge api and ws
---
.../api/configuration/ApiAppConfiguration.java | 135 +++++++++++++++++++++
.../juick/api/configuration/ApiInitializer.java | 65 ++++++++++
.../juick/api/configuration/ApiSecurityConfig.java | 128 +++++++++++++++++++
.../api/configuration/ApiSecurityInitializer.java | 37 ++++++
4 files changed, 365 insertions(+)
create mode 100644 juick-server/src/main/java/com/juick/api/configuration/ApiAppConfiguration.java
create mode 100644 juick-server/src/main/java/com/juick/api/configuration/ApiInitializer.java
create mode 100644 juick-server/src/main/java/com/juick/api/configuration/ApiSecurityConfig.java
create mode 100644 juick-server/src/main/java/com/juick/api/configuration/ApiSecurityInitializer.java
(limited to 'juick-server/src/main/java/com/juick/api/configuration')
diff --git a/juick-server/src/main/java/com/juick/api/configuration/ApiAppConfiguration.java b/juick-server/src/main/java/com/juick/api/configuration/ApiAppConfiguration.java
new file mode 100644
index 00000000..ea59ac52
--- /dev/null
+++ b/juick-server/src/main/java/com/juick/api/configuration/ApiAppConfiguration.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2008-2017, Juick
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.juick.api.configuration;
+
+import com.juick.api.ApiServer;
+import com.juick.api.WebsocketManager;
+import com.juick.server.component.JuickServerComponent;
+import com.juick.server.component.JuickServerReconnectManager;
+import com.juick.server.configuration.BaseWebConfiguration;
+import com.juick.service.UserService;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.*;
+import org.springframework.core.Ordered;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.socket.client.WebSocketConnectionManager;
+import org.springframework.web.socket.client.standard.StandardWebSocketClient;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.ServletWebSocketHandlerRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
+import org.springframework.web.util.UriComponentsBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+import javax.annotation.Nonnull;
+import javax.inject.Inject;
+import java.util.Collections;
+
+/**
+ * Created by aalexeev on 11/12/16.
+ */
+@Configuration
+@EnableAsync
+@EnableWebMvc
+@EnableSwagger2
+@EnableScheduling
+@EnableWebSocket
+@PropertySource("classpath:juick.conf")
+@ComponentScan(basePackages = "com.juick")
+public class ApiAppConfiguration extends BaseWebConfiguration implements WebSocketConfigurer {
+ @Inject
+ UserService userService;
+ @Value("${api_user:juick}")
+ private String serviceUser;
+ @Value("${websocket_url:ws://localhost:8080/ws/}")
+ private String baseUri;
+ @Lazy
+ @Bean
+ public JuickServerComponent juickServerComponent() {
+ return new JuickServerComponent();
+ }
+ @Lazy
+ @Bean
+ public JuickServerReconnectManager juickServerReconnectManager() {
+ return new JuickServerReconnectManager();
+ }
+ @Bean
+ public WebSocketConnectionManager connectionManager() {
+ String websocketURI = UriComponentsBuilder.fromUriString(baseUri)
+ .queryParam("hash", userService.getHashByUID(userService.getUIDbyName(serviceUser))).build().toUriString();
+ return new WebSocketConnectionManager(client(), juickServerComponent(), websocketURI);
+ }
+ @Bean
+ public StandardWebSocketClient client() {
+ return new StandardWebSocketClient();
+ }
+ @Bean
+ public ApiServer apiServer() {
+ return new ApiServer();
+ }
+ @Bean
+ public Docket api() {
+ return new Docket(DocumentationType.SWAGGER_2)
+ .select()
+ .apis(RequestHandlerSelectors.any())
+ .paths(PathSelectors.any()).build().apiInfo(new ApiInfo("Juick API", "Juick REST API Documentation",
+ "2.0", "https://juick.com/help/tos", null,
+ "AGPLv3", "https://www.gnu.org/licenses/agpl-3.0.html", Collections.emptyList()));
+ }
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.addResourceHandler("/swagger-ui.html")
+ .addResourceLocations("classpath:/META-INF/resources/");
+
+ registry.addResourceHandler("/webjars/**")
+ .addResourceLocations("classpath:/META-INF/resources/webjars/");
+ }
+ @Bean
+ public WebsocketManager wsHandler() {
+ return new WebsocketManager();
+ }
+
+ @Override
+ public void registerWebSocketHandlers(@Nonnull WebSocketHandlerRegistry registry) {
+ //((ServletWebSocketHandlerRegistry) registry).setOrder(Ordered.LOWEST_PRECEDENCE);
+ registry.addHandler(wsHandler(), "/ws/**").setAllowedOrigins("*");
+ }
+
+ @Bean
+ public ServletServerContainerFactoryBean createWebSocketContainer() {
+ ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
+ container.setMaxTextMessageBufferSize(8192);
+ container.setMaxBinaryMessageBufferSize(8192);
+ return container;
+ }
+ @Override
+ public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
+ configurer.enable();
+ }
+
+}
diff --git a/juick-server/src/main/java/com/juick/api/configuration/ApiInitializer.java b/juick-server/src/main/java/com/juick/api/configuration/ApiInitializer.java
new file mode 100644
index 00000000..8f35e3f7
--- /dev/null
+++ b/juick-server/src/main/java/com/juick/api/configuration/ApiInitializer.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008-2017, Juick
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.juick.api.configuration;
+
+import com.juick.configuration.DataConfiguration;
+import com.juick.server.configuration.JuickServerWebsocketConfiguration;
+import com.juick.server.configuration.StorageConfiguration;
+import org.apache.commons.codec.CharEncoding;
+import org.springframework.web.filter.CharacterEncodingFilter;
+import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
+
+import javax.annotation.Nonnull;
+import javax.servlet.Filter;
+
+/**
+ * Created by vt on 09/02/16.
+ */
+public class ApiInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
+ @Override
+ protected Class>[] getRootConfigClasses() {
+ return new Class>[]{
+ ApiSecurityConfig.class,
+ DataConfiguration.class,
+ StorageConfiguration.class
+ };
+ }
+
+ @Override
+ protected Class>[] getServletConfigClasses() {
+ return null;
+ }
+
+ @Override
+ @Nonnull
+ protected String[] getServletMappings() {
+ return new String[]{"/"};
+ }
+
+ @Override
+ protected Filter[] getServletFilters() {
+ return new Filter[]{new CharacterEncodingFilter(CharEncoding.UTF_8)};
+ }
+
+ @Override
+ @Nonnull
+ protected String getServletName() {
+ return "API dispatcher servlet";
+ }
+}
diff --git a/juick-server/src/main/java/com/juick/api/configuration/ApiSecurityConfig.java b/juick-server/src/main/java/com/juick/api/configuration/ApiSecurityConfig.java
new file mode 100644
index 00000000..2ae1d9e5
--- /dev/null
+++ b/juick-server/src/main/java/com/juick/api/configuration/ApiSecurityConfig.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008-2017, Juick
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.juick.api.configuration;
+
+import com.juick.service.UserService;
+import com.juick.service.security.JuickUserDetailsService;
+import com.juick.service.security.NotAuthorizedAuthenticationEntryPoint;
+import com.juick.service.security.deprecated.RequestParamHashRememberMeServices;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.builders.WebSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.authentication.RememberMeServices;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.CorsConfigurationSource;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+
+import javax.inject.Inject;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by aalexeev on 11/21/16.
+ */
+@Configuration
+@EnableWebSecurity
+@PropertySource("classpath:juick.conf")
+@Import(ApiAppConfiguration.class)
+public class ApiSecurityConfig extends WebSecurityConfigurerAdapter {
+ @Value("${auth_remember_me_key}")
+ private String rememberMeKey;
+ @Inject
+ private UserService userService;
+
+ ApiSecurityConfig() {
+ super(true);
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http.authorizeRequests()
+ .antMatchers(HttpMethod.OPTIONS).permitAll()
+ .antMatchers("/messages", "/users", "/thread", "/tags", "/tlgmbtwbhk", "/fbwbhk",
+ "/skypebotendpoint").permitAll()
+ .anyRequest().hasRole("USER")
+ .and().httpBasic().authenticationEntryPoint(getJuickAuthenticationEntryPoint())
+ .and().anonymous()
+ .and().cors().configurationSource(corsConfigurationSource())
+ .and().servletApi()
+ .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
+ .and().exceptionHandling().authenticationEntryPoint(getJuickAuthenticationEntryPoint())
+ .and()
+ .rememberMe()
+ .alwaysRemember(true)
+ .tokenValiditySeconds((int) TimeUnit.DAYS.toSeconds(6 * 30))
+ .rememberMeServices(rememberMeServices())
+ .key(rememberMeKey)
+ .and().authenticationProvider(authenticationProvider())
+ .headers().defaultsDisabled().cacheControl();
+ }
+
+ @Bean
+ public DaoAuthenticationProvider authenticationProvider() {
+ DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
+
+ authenticationProvider.setUserDetailsService(userDetailsService());
+
+ return authenticationProvider;
+ }
+
+ @Bean
+ public JuickUserDetailsService userDetailsService() {
+ return new JuickUserDetailsService(userService);
+ }
+
+ @Bean
+ public RememberMeServices rememberMeServices() throws Exception {
+ return new RequestParamHashRememberMeServices(rememberMeKey, userService);
+ }
+
+ @Bean
+ public NotAuthorizedAuthenticationEntryPoint getJuickAuthenticationEntryPoint() {
+ return new NotAuthorizedAuthenticationEntryPoint();
+ }
+
+ @Bean
+ public CorsConfigurationSource corsConfigurationSource() {
+ CorsConfiguration configuration = new CorsConfiguration();
+
+ configuration.setAllowedOrigins(Collections.singletonList("*"));
+ configuration.setAllowedMethods(Arrays.asList("POST", "GET", "PUT", "OPTIONS", "DELETE"));
+ configuration.setAllowedHeaders(Collections.singletonList("*"));
+
+ UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+ source.registerCorsConfiguration("/**", configuration);
+
+ return source;
+ }
+ @Override
+ public void configure(WebSecurity web) throws Exception {
+ web.ignoring().antMatchers("/v2/api-docs", "/configuration/ui", "/swagger-resources/**",
+ "/configuration/**", "/swagger-ui.html", "/webjars/**", "/ws/**");
+ }
+}
diff --git a/juick-server/src/main/java/com/juick/api/configuration/ApiSecurityInitializer.java b/juick-server/src/main/java/com/juick/api/configuration/ApiSecurityInitializer.java
new file mode 100644
index 00000000..259315fb
--- /dev/null
+++ b/juick-server/src/main/java/com/juick/api/configuration/ApiSecurityInitializer.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008-2017, Juick
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package com.juick.api.configuration;
+
+/**
+ * Created by vitalyster on 25.11.2016.
+ */
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
+
+import javax.servlet.ServletContext;
+
+public class ApiSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
+ @Override
+ protected void afterSpringSecurityFilterChain(ServletContext servletContext) {
+ logger.info("SpringSecurityFilterChain initialized");
+ }
+}
--
cgit v1.2.3