aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--juick-server/src/main/resources/juick.conf.example7
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/configuration/WebSecurityConfig.java85
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/configuration/WwwInitializer.java26
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/configuration/WwwServletConfiguration.java18
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/controllers/HelpController.java12
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/controllers/IndexController.java24
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/controllers/SettingsController.java16
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/controllers/ShowMessageController.java52
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/controllers/TagController.java37
-rw-r--r--juick-spring-www/src/main/java/com/juick/www/entity/JuickUser.java62
-rw-r--r--juick-spring-www/src/main/resources/messages_en.properties0
-rw-r--r--juick-spring-www/src/main/webapp/WEB-INF/templates/index.html10
-rw-r--r--juick-spring-www/src/main/webapp/WEB-INF/templates/layout/footer.html0
-rw-r--r--juick-spring-www/src/main/webapp/WEB-INF/templates/layout/mainLayout.html12
14 files changed, 341 insertions, 20 deletions
diff --git a/juick-server/src/main/resources/juick.conf.example b/juick-server/src/main/resources/juick.conf.example
index 945bfae4..284d86a5 100644
--- a/juick-server/src/main/resources/juick.conf.example
+++ b/juick-server/src/main/resources/juick.conf.example
@@ -26,6 +26,13 @@ sphinx_user=
# Sphinx search JDBC password
sphinx_password=
+# The domain name for Web (default value - "juick.com")
+web_domain=juick.com
+
+# Authority cookie name (default value - "hash")
+auth_cookie_name=hash
+
+
twitter_consumer_key=
twitter_consumer_secret=
diff --git a/juick-spring-www/src/main/java/com/juick/www/configuration/WebSecurityConfig.java b/juick-spring-www/src/main/java/com/juick/www/configuration/WebSecurityConfig.java
new file mode 100644
index 00000000..65d07dba
--- /dev/null
+++ b/juick-spring-www/src/main/java/com/juick/www/configuration/WebSecurityConfig.java
@@ -0,0 +1,85 @@
+package com.juick.www.configuration;
+
+import com.juick.service.UserService;
+import com.juick.www.entity.JuickUser;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+
+import javax.annotation.Resource;
+
+/**
+ * Created by aalexeev on 11/21/16.
+ */
+@EnableWebSecurity
+@PropertySource("classpath:juick.conf")
+public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
+ @Resource
+ private Environment env;
+ @Resource
+ private UserService userService;
+
+ protected WebSecurityConfig() {
+ super(true);
+ }
+
+ @Bean("authManager")
+ @Override
+ public AuthenticationManager authenticationManagerBean() throws Exception {
+ return super.authenticationManagerBean();
+ }
+
+ @Bean("userDetailsService")
+ @Override
+ public UserDetailsService userDetailsServiceBean() throws Exception {
+ return username -> {
+ if (StringUtils.isBlank(username))
+ throw new UsernameNotFoundException("Invalid user name " + username);
+
+ com.juick.User user = userService.getUserByName(username);
+
+ if (user != null)
+ return new JuickUser(user);
+
+ throw new UsernameNotFoundException("The username " + username + " is not found");
+ };
+ }
+
+ @Override
+ protected void configure(HttpSecurity http) throws Exception {
+ http
+ .authorizeRequests()
+ .antMatchers("/settings", "/pm/**").authenticated()
+ .anyRequest().authenticated()
+ .and()
+ .anonymous()
+ .authorities("ROLE_ANONYM")
+ .and()
+ .logout()
+ .invalidateHttpSession(true)
+ .logoutUrl("/logout")
+ .logoutSuccessUrl("/")
+ .and()
+ .formLogin()
+ .loginPage("/login")
+ .permitAll()
+ .defaultSuccessUrl("/")
+ .failureForwardUrl("/login")
+ .and()
+ .rememberMe()
+ .tokenValiditySeconds(6 * 30 * 24 * 3600)
+ .alwaysRemember(true)
+ .useSecureCookie(true)
+ .rememberMeCookieName(env.getProperty("auth_cookie_name", "hash"))
+ .rememberMeCookieDomain(env.getProperty("web_domain", "juick.com"))
+ .and()
+ .csrf().disable();
+ }
+}
diff --git a/juick-spring-www/src/main/java/com/juick/www/configuration/WwwInitializer.java b/juick-spring-www/src/main/java/com/juick/www/configuration/WwwInitializer.java
index 852ec554..6b7b4ebc 100644
--- a/juick-spring-www/src/main/java/com/juick/www/configuration/WwwInitializer.java
+++ b/juick-spring-www/src/main/java/com/juick/www/configuration/WwwInitializer.java
@@ -6,6 +6,9 @@ import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
/**
* Created by aalexeev on 11/20/16.
@@ -14,7 +17,7 @@ public class WwwInitializer extends AbstractAnnotationConfigDispatcherServletIni
@Override
protected Class<?>[] getRootConfigClasses() {
- return new Class<?>[]{DataConfiguration.class, SearchConfiguration.class};
+ return new Class<?>[]{DataConfiguration.class, SearchConfiguration.class, WebSecurityConfig.class};
}
@Override
@@ -28,16 +31,23 @@ public class WwwInitializer extends AbstractAnnotationConfigDispatcherServletIni
}
@Override
- protected Filter[] getServletFilters() {
- CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
- characterEncodingFilter.setEncoding("UTF-8");
-
- return new Filter[]{characterEncodingFilter};
+ protected String getServletName() {
+ return "WWW-spring dispatcher servlet";
}
@Override
- protected String getServletName() {
- return "WWW-spring dispatcher servlet";
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ super.onStartup(servletContext);
+
+ CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
+
+ encodingFilter.setEncoding("UTF-8");
+ encodingFilter.setForceEncoding(true);
+
+ FilterRegistration.Dynamic registration = servletContext.addFilter(
+ "encodingFilter", new CharacterEncodingFilter());
+
+ registration.addMappingForUrlPatterns(null, true, "/*");
}
}
diff --git a/juick-spring-www/src/main/java/com/juick/www/configuration/WwwServletConfiguration.java b/juick-spring-www/src/main/java/com/juick/www/configuration/WwwServletConfiguration.java
index 8edc1b6c..01cee39f 100644
--- a/juick-spring-www/src/main/java/com/juick/www/configuration/WwwServletConfiguration.java
+++ b/juick-spring-www/src/main/java/com/juick/www/configuration/WwwServletConfiguration.java
@@ -6,14 +6,13 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
-import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
-import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
@@ -64,20 +63,10 @@ public class WwwServletConfiguration extends WebMvcConfigurationSupport {
public ThymeleafViewResolver viewResolver() {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine());
- // NOTE 'order' and 'viewNames' are optional
- viewResolver.setOrder(1);
- viewResolver.setViewNames(new String[]{".html", ".xhtml"});
return viewResolver;
}
@Override
- public RequestMappingHandlerMapping requestMappingHandlerMapping() {
- RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping();
- mapping.setUseSuffixPatternMatch(false);
- return mapping;
- }
-
- @Override
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
.serializationInclusion(JsonInclude.Include.NON_DEFAULT)
@@ -97,6 +86,7 @@ public class WwwServletConfiguration extends WebMvcConfigurationSupport {
registry.setOrder(0);
registry.addResourceHandler("/scripts.js").addResourceLocations("/");
registry.addResourceHandler("/style.css").addResourceLocations("/");
+ registry.addResourceHandler("/favicon.ico").addResourceLocations("/static/favicon.ico");
}
@Bean
@@ -109,4 +99,8 @@ public class WwwServletConfiguration extends WebMvcConfigurationSupport {
return messageSource;
}
+
+ @Override
+ protected void addViewControllers(ViewControllerRegistry registry) {
+ }
}
diff --git a/juick-spring-www/src/main/java/com/juick/www/controllers/HelpController.java b/juick-spring-www/src/main/java/com/juick/www/controllers/HelpController.java
new file mode 100644
index 00000000..dad3ff9f
--- /dev/null
+++ b/juick-spring-www/src/main/java/com/juick/www/controllers/HelpController.java
@@ -0,0 +1,12 @@
+package com.juick.www.controllers;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * Created by aalexeev on 11/21/16.
+ */
+@Controller
+@RequestMapping("/help")
+public class HelpController {
+}
diff --git a/juick-spring-www/src/main/java/com/juick/www/controllers/IndexController.java b/juick-spring-www/src/main/java/com/juick/www/controllers/IndexController.java
new file mode 100644
index 00000000..2973bf30
--- /dev/null
+++ b/juick-spring-www/src/main/java/com/juick/www/controllers/IndexController.java
@@ -0,0 +1,24 @@
+package com.juick.www.controllers;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * Created by aalexeev on 11/21/16.
+ */
+@Controller
+public class IndexController {
+
+ @RequestMapping("/")
+ public String index(
+ java.security.Principal userPrincipal,
+ @RequestParam(required = false, defaultValue = "0") int before,
+ Model model) {
+
+ model.addAttribute("currentUser", userPrincipal);
+
+ return "index";
+ }
+}
diff --git a/juick-spring-www/src/main/java/com/juick/www/controllers/SettingsController.java b/juick-spring-www/src/main/java/com/juick/www/controllers/SettingsController.java
new file mode 100644
index 00000000..eef41c38
--- /dev/null
+++ b/juick-spring-www/src/main/java/com/juick/www/controllers/SettingsController.java
@@ -0,0 +1,16 @@
+package com.juick.www.controllers;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+/**
+ * Created by aalexeev on 11/21/16.
+ */
+@Controller
+public class SettingsController {
+
+ @RequestMapping("/settings")
+ public String showSettings() {
+ return "index";
+ }
+}
diff --git a/juick-spring-www/src/main/java/com/juick/www/controllers/ShowMessageController.java b/juick-spring-www/src/main/java/com/juick/www/controllers/ShowMessageController.java
new file mode 100644
index 00000000..338dc9be
--- /dev/null
+++ b/juick-spring-www/src/main/java/com/juick/www/controllers/ShowMessageController.java
@@ -0,0 +1,52 @@
+package com.juick.www.controllers;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.regex.Pattern;
+
+/**
+ * Created by aalexeev on 11/21/16.
+ */
+@Controller
+public class ShowMessageController {
+ private static final Pattern USER_NAME_PATTERN = Pattern.compile("[a-zA-Z-_\\d]{2,16}");
+
+ private static final Pattern POST_NUMBER_PATTERN = Pattern.compile("\\d+");
+
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
+
+ @RequestMapping("/{anything}")
+ public String parseAnything(
+ @PathVariable String anything,
+ @RequestParam(required = false, defaultValue = "0") int before,
+ Model model) {
+
+ boolean isUsername = USER_NAME_PATTERN.matcher(anything).matches();
+ boolean isPostNumber = POST_NUMBER_PATTERN.matcher(anything).matches();
+
+ return "redirect:/";
+ }
+
+ @RequestMapping("/{userName}/{postNumber}")
+ public String checkShowPost(
+ @PathVariable String userName,
+ @PathVariable String postNumber,
+ @RequestParam(required = false, defaultValue = "0") int before,
+ Model model) {
+
+ if (!USER_NAME_PATTERN.matcher(userName).matches() ||
+ !POST_NUMBER_PATTERN.matcher(postNumber).matches()) {
+ logger.warn("Invalid user name or post number, user name \"{}\", post number \"{}\"", userName, postNumber);
+ return "redirect:/";
+ }
+
+ return "index";
+ }
+}
diff --git a/juick-spring-www/src/main/java/com/juick/www/controllers/TagController.java b/juick-spring-www/src/main/java/com/juick/www/controllers/TagController.java
new file mode 100644
index 00000000..5c3b6287
--- /dev/null
+++ b/juick-spring-www/src/main/java/com/juick/www/controllers/TagController.java
@@ -0,0 +1,37 @@
+package com.juick.www.controllers;
+
+import com.juick.service.MessagesService;
+import com.juick.service.TagService;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.inject.Inject;
+
+/**
+ * Created by aalexeev on 11/21/16.
+ */
+@Controller
+public class TagController {
+ @Inject
+ private TagService tagService;
+ @Inject
+ private MessagesService messagesService;
+
+
+ @RequestMapping("/tag/{tagName}")
+ public String showTags(
+ @PathVariable String tagName,
+ @RequestParam(required = false, defaultValue = "0") int before,
+ Model model) {
+
+ return "index";
+ }
+
+ @RequestMapping("/tag")
+ public String redirectToMain() {
+ return "redirect:/";
+ }
+}
diff --git a/juick-spring-www/src/main/java/com/juick/www/entity/JuickUser.java b/juick-spring-www/src/main/java/com/juick/www/entity/JuickUser.java
new file mode 100644
index 00000000..20d7889d
--- /dev/null
+++ b/juick-spring-www/src/main/java/com/juick/www/entity/JuickUser.java
@@ -0,0 +1,62 @@
+package com.juick.www.entity;
+
+import com.juick.User;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Created by aalexeev on 11/21/16.
+ */
+public class JuickUser implements UserDetails {
+ private static final GrantedAuthority ROLE_USER = new SimpleGrantedAuthority("ROLE_USER");
+
+ private final com.juick.User user;
+
+
+ public JuickUser(com.juick.User user) {
+ this.user = user;
+ }
+
+ @Override
+ public Collection<? extends GrantedAuthority> getAuthorities() {
+ return Collections.singletonList(ROLE_USER);
+ }
+
+ @Override
+ public String getPassword() {
+ return null;
+ }
+
+ @Override
+ public String getUsername() {
+ return user.getName();
+ }
+
+ @Override
+ public boolean isAccountNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isAccountNonLocked() {
+ return false;
+ }
+
+ @Override
+ public boolean isCredentialsNonExpired() {
+ return true;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return !user.isBanned();
+ }
+
+ public User getUser() {
+ return user;
+ }
+}
diff --git a/juick-spring-www/src/main/resources/messages_en.properties b/juick-spring-www/src/main/resources/messages_en.properties
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/juick-spring-www/src/main/resources/messages_en.properties
diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/index.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/index.html
new file mode 100644
index 00000000..566549bd
--- /dev/null
+++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/index.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Title</title>
+</head>
+<body>
+
+</body>
+</html> \ No newline at end of file
diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/layout/footer.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/layout/footer.html
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/layout/footer.html
diff --git a/juick-spring-www/src/main/webapp/WEB-INF/templates/layout/mainLayout.html b/juick-spring-www/src/main/webapp/WEB-INF/templates/layout/mainLayout.html
new file mode 100644
index 00000000..91a76f72
--- /dev/null
+++ b/juick-spring-www/src/main/webapp/WEB-INF/templates/layout/mainLayout.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+ <script type="text/javascript" src="/scripts.js"></script>
+ <link rel="stylesheet" type="text/css" href="/style.css" />
+</head>
+<body>
+
+</body>
+</html> \ No newline at end of file