Skip to content

Commit 050b33f

Browse files
committed
SpringChat Codes Changed
1 parent de88e03 commit 050b33f

18 files changed

+1852
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package SpringChat;
2+
3+
import java.io.File;
4+
5+
import SpringChat.storages.UserStorage;
6+
import org.springframework.beans.BeansException;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.boot.SpringApplication;
9+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
10+
import org.springframework.boot.autoconfigure.SpringBootApplication;
11+
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
12+
import org.springframework.context.ApplicationContext;
13+
import org.springframework.context.ApplicationContextAware;
14+
import org.springframework.context.annotation.Bean;
15+
import org.springframework.context.annotation.Configuration;
16+
import org.springframework.scheduling.annotation.EnableScheduling;
17+
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
18+
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
19+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
20+
import SpringChat.configurations.HttpInterceptor;
21+
import SpringChat.models.UserModel;
22+
import SpringChat.utils.Utils1;
23+
24+
import javax.annotation.PostConstruct;
25+
26+
@SpringBootApplication
27+
@EnableScheduling
28+
@EnableAutoConfiguration(exclude = ErrorMvcAutoConfiguration.class)
29+
public class SpringChat implements ApplicationContextAware {
30+
31+
public static final String PAGE_RESOURCE_PATH = "res/html";
32+
public static final String STYLE_RESOURCE_PATH = "res/css";
33+
public static final String SCRIPT_RESOURCE_PATH = "res/js";
34+
public static final String IMAGE_RESOURCE_PATH = "res/img";
35+
public static final String MISC_RESOURCE_PATH = "res/misc";
36+
public static final String ADMIN_USERNAME = "admin";
37+
public static final String BROADCAST_USERNAME = "broadcast";
38+
public static final String IMG_THUMBNAIL_FORMAT = "jpg";
39+
public static final String UPLOAD_PATH = "uploads";
40+
41+
@Autowired
42+
private UserStorage userStorage;
43+
44+
@Autowired
45+
private Utils1 byteUtils;
46+
47+
private static ApplicationContext context;
48+
49+
public static void main(String[] args) {
50+
SpringApplication.run(SpringChat.class, args);
51+
}
52+
53+
@PostConstruct
54+
public void starter() {
55+
new File(UPLOAD_PATH).mkdir();
56+
if (userStorage.findByUsername(BROADCAST_USERNAME) == null) {
57+
58+
UserModel bcUSer = new UserModel();
59+
bcUSer.setUsername(BROADCAST_USERNAME);
60+
bcUSer.setPassword(byteUtils.hash("123456"));
61+
bcUSer.setFirstname("Broadcast");
62+
bcUSer.setLastname("");
63+
userStorage.save(bcUSer);
64+
}
65+
}
66+
67+
@Override
68+
public void setApplicationContext(ApplicationContext ac) throws BeansException {
69+
context = ac;
70+
}
71+
72+
public static <T> T getBean(Class<T> requiredType) {
73+
return context.getBean(requiredType);
74+
}
75+
76+
@Configuration
77+
public class InterceptorConfig extends WebMvcConfigurerAdapter {
78+
79+
@Autowired
80+
HttpInterceptor serviceInterceptor;
81+
82+
@Override
83+
public void addInterceptors(InterceptorRegistry registry) {
84+
registry.addInterceptor(serviceInterceptor);
85+
}
86+
}
87+
88+
@Bean(name = "multipartResolver")
89+
public CommonsMultipartResolver multipartResolver() {
90+
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
91+
multipartResolver.setMaxUploadSize(10000000000l);
92+
return multipartResolver;
93+
}
94+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package SpringChat.configurations;
2+
3+
import com.zaxxer.hikari.HikariConfig;
4+
import com.zaxxer.hikari.HikariDataSource;
5+
import java.net.URI;
6+
import java.net.URISyntaxException;
7+
import org.springframework.beans.factory.annotation.Value;
8+
import org.springframework.context.annotation.Bean;
9+
10+
import javax.sql.DataSource;
11+
import org.springframework.scheduling.annotation.Scheduled;
12+
import org.springframework.web.client.RestTemplate;
13+
14+
//@Configuration
15+
public class DatabaseConfig {
16+
17+
@Scheduled(fixedRate = 300000, initialDelay = 300000)
18+
public void pingEchoServiceToKeepServiceAlive() {
19+
try {
20+
RestTemplate restTemplate = new RestTemplate();
21+
URI uri = new URI("https://mtaghavian-heroku-echo.herokuapp.com/");
22+
restTemplate.getForEntity(uri, String.class);
23+
} catch (URISyntaxException ex) {
24+
ex.printStackTrace();
25+
}
26+
}
27+
28+
@Value("${spring.datasource.url}")
29+
private String dbUrl;
30+
31+
@Bean
32+
public DataSource dataSource() {
33+
HikariConfig config = new HikariConfig();
34+
config.setJdbcUrl(dbUrl);
35+
return new HikariDataSource(config);
36+
}
37+
}
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
package SpringChat.configurations;
2+
3+
import SpringChat.models.SessionModel;
4+
import SpringChat.models.UserModel;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.http.MediaType;
7+
import org.springframework.scheduling.annotation.Scheduled;
8+
import org.springframework.stereotype.Component;
9+
import org.springframework.web.servlet.HandlerInterceptor;
10+
import org.springframework.web.servlet.ModelAndView;
11+
import SpringChat.SpringChat;
12+
import SpringChat.models.FileInfoModel;
13+
import SpringChat.storages.FileInfoStorage;
14+
import SpringChat.storages.SessionStorage;
15+
import SpringChat.storages.UserStorage;
16+
import SpringChat.utils.Utils1;
17+
18+
import javax.servlet.http.Cookie;
19+
import javax.servlet.http.HttpServletRequest;
20+
import javax.servlet.http.HttpServletResponse;
21+
import javax.servlet.http.HttpSession;
22+
import java.io.File;
23+
import java.io.UnsupportedEncodingException;
24+
import java.util.*;
25+
26+
@Component
27+
public class HttpInterceptor implements HandlerInterceptor {
28+
29+
@Autowired
30+
private SessionStorage sessionStorage;
31+
32+
@Autowired
33+
private UserStorage userStorage;
34+
35+
@Autowired
36+
private Utils1 byteUtils;
37+
38+
@Autowired
39+
private FileInfoStorage fileInfoStorage;
40+
41+
private Set<String> allowedUrls = new HashSet<>();
42+
private Set<String> allowedFiles = new HashSet<>();
43+
private Set<String> htmlFiles = new HashSet<>();
44+
45+
public HttpInterceptor() {
46+
allowedUrls.add("/");
47+
allowedUrls.add("/home");
48+
allowedUrls.add("/index");
49+
allowedUrls.add("/login-helper");
50+
allowedUrls.add("/signup");
51+
allowedUrls.add("/signup-helper");
52+
53+
for (String filename : Objects.requireNonNull(new File(SpringChat.IMAGE_RESOURCE_PATH).list())) {
54+
allowedFiles.add("/" + filename);
55+
}
56+
for (String filename : Objects.requireNonNull(new File(SpringChat.STYLE_RESOURCE_PATH).list())) {
57+
allowedFiles.add("/" + filename);
58+
}
59+
for (String filename : Objects.requireNonNull(new File(SpringChat.SCRIPT_RESOURCE_PATH).list())) {
60+
allowedFiles.add("/" + filename);
61+
}
62+
for (String filename : Objects.requireNonNull(new File(SpringChat.MISC_RESOURCE_PATH).list())) {
63+
allowedFiles.add("/" + filename);
64+
}
65+
for (String filename : Objects.requireNonNull(new File(SpringChat.PAGE_RESOURCE_PATH).list())) {
66+
htmlFiles.add("/" + filename);
67+
}
68+
}
69+
70+
private void putHeaderParams(Map<String, String> params, UserModel userModel) {
71+
if (userModel != null) {
72+
params.put("headerAccountText", userModel.getFirstname() + " " + userModel.getLastname());
73+
params.put("headerAccountAction", "");
74+
params.put("headerAccountClasses", "Dropdown");
75+
params.put("HeaderUserCaretSvgDisplay", "inline-block");
76+
} else {
77+
params.put("headerAccountText", "Sign In / Sign Up");
78+
params.put("headerAccountAction", "onclick='location.href=\"/userModel\"'");
79+
params.put("headerAccountClasses", "");
80+
params.put("HeaderUserCaretSvgDisplay", "none");
81+
}
82+
}
83+
84+
private Properties getPropertiesFromCookies(Cookie cookie[]) {
85+
if (cookie == null) {
86+
return null;
87+
}
88+
Properties cookies = new Properties();
89+
for (Cookie c : cookie) {
90+
cookies.put(c.getName(), c.getValue());
91+
}
92+
return cookies;
93+
}
94+
95+
public void loginWithCookies(Properties cookies, SessionModel sessionModel) {
96+
if (cookies != null) {
97+
if (cookies.containsKey("username") && cookies.containsKey("password")) {
98+
UserModel dbUserModel = userStorage.findByUsername("" + cookies.get("username"));
99+
if ((dbUserModel != null) && dbUserModel.getPassword().equals(cookies.get("password"))) {
100+
sessionModel.setUserModel(dbUserModel);
101+
}
102+
}
103+
}
104+
}
105+
106+
private void loginWithBasicAuth(HttpServletRequest request, HttpSession httpSession, SessionModel sessionModel) throws UnsupportedEncodingException {
107+
String auth = request.getHeader("Authorization");
108+
if (auth != null) {
109+
String[] split = auth.split(" ");
110+
if ("basic".equals(split[0].toLowerCase())) {
111+
String base64 = split[1];
112+
String cred = new String(Base64.getDecoder().decode(base64), "UTF-8");
113+
String username = cred.substring(0, cred.indexOf(":"));
114+
String password = cred.substring(cred.indexOf(":") + 1, cred.length());
115+
UserModel dbUserModel = userStorage.findByUsername(username);
116+
if ((dbUserModel != null) && dbUserModel.getPassword().equals(byteUtils.hash(password))) {
117+
sessionModel.setUserModel(dbUserModel);
118+
}
119+
}
120+
}
121+
}
122+
123+
@Scheduled(fixedRate = 3600000, initialDelay = 3600000)
124+
public void clearExpiredSessions() {
125+
List<SessionModel> expired = sessionStorage.findExpired(System.currentTimeMillis() - 3600000);
126+
sessionStorage.deleteAll(expired);
127+
}
128+
129+
@Override
130+
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
131+
String uri = request.getRequestURI();
132+
HttpSession httpSession = request.getSession();
133+
134+
SessionModel sessionModel = sessionStorage.findById(httpSession.getId()).orElse(null);
135+
if (sessionModel == null) {
136+
sessionModel = new SessionModel(httpSession.getId(), null, System.currentTimeMillis());
137+
}
138+
sessionModel.setLastModified(System.currentTimeMillis());
139+
sessionStorage.save(sessionModel);
140+
141+
loginWithBasicAuth(request, httpSession, sessionModel);
142+
loginWithCookies(getPropertiesFromCookies(request.getCookies()), sessionModel);
143+
144+
if (allowedFiles.contains(uri)) {
145+
String uriLC = uri.toLowerCase();
146+
if (uriLC.endsWith(".svg")) {
147+
response.setContentType("image/svg+xml");
148+
response.getOutputStream().write(byteUtils.readBytes(new File((SpringChat.IMAGE_RESOURCE_PATH + "/" + uri)), false));
149+
} else if (uriLC.endsWith(".css")) {
150+
response.setContentType("text/css");
151+
response.getOutputStream().write(byteUtils.readBytes(new File((SpringChat.STYLE_RESOURCE_PATH + "/" + uri)), false));
152+
} else if (uriLC.endsWith(".json")) {
153+
response.setContentType("application/json");
154+
response.getOutputStream().write(byteUtils.readBytes(new File((SpringChat.MISC_RESOURCE_PATH + "/" + uri)), false));
155+
} else if (uriLC.endsWith(".js")) {
156+
response.setContentType("text/javascript");
157+
response.getOutputStream().write(byteUtils.readBytes(new File((SpringChat.SCRIPT_RESOURCE_PATH + "/" + uri)), false));
158+
} else if (uriLC.endsWith(".png")) {
159+
response.setContentType("image/png");
160+
response.getOutputStream().write(byteUtils.readBytes(new File((SpringChat.IMAGE_RESOURCE_PATH + "/" + uri)), false));
161+
} else if (uriLC.endsWith(".ico")) {
162+
response.setContentType("image/x-icon");
163+
response.getOutputStream().write(byteUtils.readBytes(new File((SpringChat.IMAGE_RESOURCE_PATH + "/" + uri)), false));
164+
}
165+
response.setStatus(HttpServletResponse.SC_OK);
166+
return false;
167+
}
168+
169+
if (uri.startsWith("/image-file-preview/")) {
170+
String fileInfoId = uri.substring(uri.indexOf('/', 1) + 1);
171+
FileInfoModel info = fileInfoStorage.findById(UUID.fromString(fileInfoId)).get();
172+
MediaType mediaType;
173+
byte fileData[];
174+
if (info.getImgPrevFileDataId() == null) {
175+
mediaType = byteUtils.getMediaType(info.getName());
176+
fileData = byteUtils.readBytes(new File(SpringChat.UPLOAD_PATH + "/" + info.getFileDataId()), true);
177+
} else {
178+
mediaType = byteUtils.getMediaType("a." + SpringChat.IMG_THUMBNAIL_FORMAT);
179+
fileData = byteUtils.readBytes(new File(SpringChat.UPLOAD_PATH + "/" + info.getImgPrevFileDataId()), true);
180+
}
181+
response.setContentType("" + mediaType);
182+
response.getOutputStream().write(fileData);
183+
return false;
184+
}
185+
186+
if (!allowedUrls.contains(uri)) {
187+
if ("/login".equals(uri)) {
188+
if (sessionModel.getUserModel() != null) {
189+
response.sendRedirect("/user");
190+
return false;
191+
}
192+
} else {
193+
if (sessionModel.getUserModel() == null) {
194+
sessionModel.setRedirectedUri(uri);
195+
response.sendRedirect("/login");
196+
return false;
197+
}
198+
}
199+
}
200+
201+
if (uri.equals("/")) {
202+
uri = "/home";
203+
}
204+
if (htmlFiles.contains(uri + ".html")) {
205+
Map<String, String> params = new HashMap<>();
206+
putHeaderParams(params, sessionModel.getUserModel());
207+
params.put("pageTitle", uri.substring(1));
208+
if (uri.equals("/user")) {
209+
params.put("optionsSvg",
210+
"<img src=\"options.svg\" "
211+
+ "id=\"OptionsSvg\" "
212+
+ "class=\"Button ButtonTransPrimary\""
213+
+ "onclick='toggleSidebarDisplay()'/>");
214+
} else {
215+
params.put("optionsSvg", "");
216+
}
217+
String html = byteUtils.readPage(uri + ".html", params);
218+
response.setContentType("text/html");
219+
response.getOutputStream().write(html.getBytes("UTF-8"));
220+
return false;
221+
}
222+
return true;
223+
}
224+
225+
@Override
226+
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
227+
}
228+
229+
@Override
230+
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception {
231+
}
232+
}

0 commit comments

Comments
 (0)