Fixed database errors!

This commit is contained in:
Norbi Peti 2016-07-28 11:23:17 +02:00
parent 73ef29e2df
commit 2bfa4a8c50
9 changed files with 987 additions and 958 deletions

501
.gitignore vendored
View file

@ -1,250 +1,251 @@
## Ignore Visual Studio temporary files, build results, and ## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons. ## files generated by popular Visual Studio add-ons.
# User-specific files # User-specific files
*.suo *.suo
*.user *.user
*.userosscache *.userosscache
*.sln.docstates *.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio) # User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs *.userprefs
# Build results # Build results
[Dd]ebug/ [Dd]ebug/
[Dd]ebugPublic/ [Dd]ebugPublic/
[Rr]elease/ [Rr]elease/
[Rr]eleases/ [Rr]eleases/
x64/ x64/
x86/ x86/
bld/ bld/
[Bb]in/ [Bb]in/
[Oo]bj/ [Oo]bj/
[Ll]og/ [Ll]og/
# Visual Studio 2015 cache/options directory # Visual Studio 2015 cache/options directory
.vs/ .vs/
# Uncomment if you have tasks that create the project's static files in wwwroot # Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/ #wwwroot/
# MSTest test Results # MSTest test Results
[Tt]est[Rr]esult*/ [Tt]est[Rr]esult*/
[Bb]uild[Ll]og.* [Bb]uild[Ll]og.*
# NUNIT # NUNIT
*.VisualState.xml *.VisualState.xml
TestResult.xml TestResult.xml
# Build Results of an ATL Project # Build Results of an ATL Project
[Dd]ebugPS/ [Dd]ebugPS/
[Rr]eleasePS/ [Rr]eleasePS/
dlldata.c dlldata.c
# DNX # DNX
project.lock.json project.lock.json
artifacts/ artifacts/
*_i.c *_i.c
*_p.c *_p.c
*_i.h *_i.h
*.ilk *.ilk
*.meta *.meta
*.obj *.obj
*.pch *.pch
*.pdb *.pdb
*.pgc *.pgc
*.pgd *.pgd
*.rsp *.rsp
*.sbr *.sbr
*.tlb *.tlb
*.tli *.tli
*.tlh *.tlh
*.tmp *.tmp
*.tmp_proj *.tmp_proj
*.log *.log
*.vspscc *.vspscc
*.vssscc *.vssscc
.builds .builds
*.pidb *.pidb
*.svclog *.svclog
*.scc *.scc
# Chutzpah Test files # Chutzpah Test files
_Chutzpah* _Chutzpah*
# Visual C++ cache files # Visual C++ cache files
ipch/ ipch/
*.aps *.aps
*.ncb *.ncb
*.opendb *.opendb
*.opensdf *.opensdf
*.sdf *.sdf
*.cachefile *.cachefile
# Visual Studio profiler # Visual Studio profiler
*.psess *.psess
*.vsp *.vsp
*.vspx *.vspx
*.sap *.sap
# TFS 2012 Local Workspace # TFS 2012 Local Workspace
$tf/ $tf/
# Guidance Automation Toolkit # Guidance Automation Toolkit
*.gpState *.gpState
# ReSharper is a .NET coding add-in # ReSharper is a .NET coding add-in
_ReSharper*/ _ReSharper*/
*.[Rr]e[Ss]harper *.[Rr]e[Ss]harper
*.DotSettings.user *.DotSettings.user
# JustCode is a .NET coding add-in # JustCode is a .NET coding add-in
.JustCode .JustCode
# TeamCity is a build add-in # TeamCity is a build add-in
_TeamCity* _TeamCity*
# DotCover is a Code Coverage Tool # DotCover is a Code Coverage Tool
*.dotCover *.dotCover
# NCrunch # NCrunch
_NCrunch_* _NCrunch_*
.*crunch*.local.xml .*crunch*.local.xml
nCrunchTemp_* nCrunchTemp_*
# MightyMoose # MightyMoose
*.mm.* *.mm.*
AutoTest.Net/ AutoTest.Net/
# Web workbench (sass) # Web workbench (sass)
.sass-cache/ .sass-cache/
# Installshield output folder # Installshield output folder
[Ee]xpress/ [Ee]xpress/
# DocProject is a documentation generator add-in # DocProject is a documentation generator add-in
DocProject/buildhelp/ DocProject/buildhelp/
DocProject/Help/*.HxT DocProject/Help/*.HxT
DocProject/Help/*.HxC DocProject/Help/*.HxC
DocProject/Help/*.hhc DocProject/Help/*.hhc
DocProject/Help/*.hhk DocProject/Help/*.hhk
DocProject/Help/*.hhp DocProject/Help/*.hhp
DocProject/Help/Html2 DocProject/Help/Html2
DocProject/Help/html DocProject/Help/html
# Click-Once directory # Click-Once directory
publish/ publish/
# Publish Web Output # Publish Web Output
*.[Pp]ublish.xml *.[Pp]ublish.xml
*.azurePubxml *.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings # TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted # but database connection strings (with potential passwords) will be unencrypted
*.pubxml *.pubxml
*.publishproj *.publishproj
# NuGet Packages # NuGet Packages
*.nupkg *.nupkg
# The packages folder can be ignored because of Package Restore # The packages folder can be ignored because of Package Restore
**/packages/* **/packages/*
# except build/, which is used as an MSBuild target. # except build/, which is used as an MSBuild target.
!**/packages/build/ !**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed # Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config #!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files # NuGet v3's project.json files produces more ignoreable files
*.nuget.props *.nuget.props
*.nuget.targets *.nuget.targets
# Microsoft Azure Build Output # Microsoft Azure Build Output
csx/ csx/
*.build.csdef *.build.csdef
# Microsoft Azure Emulator # Microsoft Azure Emulator
ecf/ ecf/
rcf/ rcf/
# Windows Store app package directories and files # Windows Store app package directories and files
AppPackages/ AppPackages/
BundleArtifacts/ BundleArtifacts/
Package.StoreAssociation.xml Package.StoreAssociation.xml
_pkginfo.txt _pkginfo.txt
# Visual Studio cache files # Visual Studio cache files
# files ending in .cache can be ignored # files ending in .cache can be ignored
*.[Cc]ache *.[Cc]ache
# but keep track of directories ending in .cache # but keep track of directories ending in .cache
!*.[Cc]ache/ !*.[Cc]ache/
# Others # Others
ClientBin/ ClientBin/
~$* ~$*
*~ *~
*.dbmdl *.dbmdl
*.dbproj.schemaview *.dbproj.schemaview
*.pfx *.pfx
*.publishsettings *.publishsettings
node_modules/ node_modules/
orleans.codegen.cs orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components # Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/ #bower_components/
# RIA/Silverlight projects # RIA/Silverlight projects
Generated_Code/ Generated_Code/
# Backup & report files from converting an old project file # Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed, # to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-) # because we have git ;-)
_UpgradeReport_Files/ _UpgradeReport_Files/
Backup*/ Backup*/
UpgradeLog*.XML UpgradeLog*.XML
UpgradeLog*.htm UpgradeLog*.htm
# SQL Server files # SQL Server files
*.mdf *.mdf
*.ldf *.ldf
# Business Intelligence projects # Business Intelligence projects
*.rdl.data *.rdl.data
*.bim.layout *.bim.layout
*.bim_*.settings *.bim_*.settings
# Microsoft Fakes # Microsoft Fakes
FakesAssemblies/ FakesAssemblies/
# GhostDoc plugin setting file # GhostDoc plugin setting file
*.GhostDoc.xml *.GhostDoc.xml
# Node.js Tools for Visual Studio # Node.js Tools for Visual Studio
.ntvs_analysis.dat .ntvs_analysis.dat
# Visual Studio 6 build log # Visual Studio 6 build log
*.plg *.plg
# Visual Studio 6 workspace options file # Visual Studio 6 workspace options file
*.opt *.opt
# Visual Studio LightSwitch build output # Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts **/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml **/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts **/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml **/*.Server/ModelManifest.xml
_Pvt_Extensions _Pvt_Extensions
# Paket dependency manager # Paket dependency manager
.paket/paket.exe .paket/paket.exe
paket-files/ paket-files/
# FAKE - F# Make # FAKE - F# Make
.fake/ .fake/
# JetBrains Rider # JetBrains Rider
.idea/ .idea/
*.sln.imlasd *.sln.imlasd
target/classes/* target/classes/*
/target/

View file

@ -1,12 +1,27 @@
<persistence xmlns="http://java.sun.com/xml/ns/persistence" <persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0"> version="2.0">
<persistence-unit name="ChatServerPU"> <persistence-unit name="ChatServerPU">
<properties> <properties>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /> <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:chatserver;create=true" /><property <property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:chatserver;create=true" />
name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit> <!-- c3p0 config http://www.hibernate.org/214.html -->
<!-- <property name="connection.provider_class" value="org.hibernate.connection.C3P0ConnectionProvider"
/> <property name="hibernate.c3p0.acquire_increment" value="1" /> <property
name="hibernate.c3p0.idle_test_period" value="60" /> <property name="hibernate.c3p0.min_size"
value="1" /> <property name="hibernate.c3p0.max_size" value="2" /> <property
name="hibernate.c3p0.max_statements" value="50" /> <property name="hibernate.c3p0.timeout"
value="0" /> <property name="hibernate.c3p0.acquireRetryAttempts" value="1"
/> <property name="hibernate.c3p0.acquireRetryDelay" value="250" /> -->
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.use_sql_comments" value="true" />
<property name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.JDBCTransactionFactory" />
<property name="hibernate.current_session_context_class"
value="thread" />
</properties>
</persistence-unit>
</persistence> </persistence>

160
pom.xml
View file

@ -1,78 +1,84 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>ChatServer</groupId> <groupId>ChatServer</groupId>
<artifactId>ChatServer</artifactId> <artifactId>ChatServer</artifactId>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<build> <build>
<sourceDirectory>src</sourceDirectory> <sourceDirectory>src</sourceDirectory>
<plugins> <plugins>
<plugin> <plugin>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version> <version>3.5.1</version>
<configuration> <configuration>
<source>1.8</source> <source>1.8</source>
<target>1.8</target> <target>1.8</target>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.apache.derby</groupId> <groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId> <artifactId>derby</artifactId>
<version>10.12.1.1</version> <version>10.12.1.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.derby</groupId> <groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId> <artifactId>derbyclient</artifactId>
<version>10.12.1.1</version> <version>10.12.1.1</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core --> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency> <dependency>
<groupId>org.hibernate</groupId> <groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId> <artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version> <version>5.2.1.Final</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
<version>2.5</version> <version>2.5</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.reflections</groupId> <groupId>org.reflections</groupId>
<artifactId>reflections</artifactId> <artifactId>reflections</artifactId>
<version>0.9.10</version> <version>0.9.10</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<!-- jsoup HTML parser library @ http://jsoup.org/ --> <!-- jsoup HTML parser library @ http://jsoup.org/ -->
<groupId>org.jsoup</groupId> <groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId> <artifactId>jsoup</artifactId>
<version>1.9.2</version> <version>1.9.2</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core --> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <artifactId>log4j-core</artifactId>
<version>2.6.2</version> <version>2.6.2</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api --> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId> <artifactId>log4j-api</artifactId>
<version>2.6.2</version> <version>2.6.2</version>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.json/json --> <!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency> <dependency>
<groupId>org.json</groupId> <groupId>org.json</groupId>
<artifactId>json</artifactId> <artifactId>json</artifactId>
<version>20160212</version> <version>20160212</version>
</dependency> </dependency>
</dependencies> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<properties> <dependency>
<maven.compiler.source>1.8</maven.compiler.source> <groupId>org.hibernate</groupId>
<maven.compiler.target>1.8</maven.compiler.target> <artifactId>hibernate-c3p0</artifactId>
</properties> <version>5.2.1.Final</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project> </project>

View file

@ -1,178 +1,182 @@
package io.github.norbipeti.chat.server; package io.github.norbipeti.chat.server;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.time.Period; import java.time.Period;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.HashMap; import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.json.JSONObject; import org.json.JSONObject;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import io.github.norbipeti.chat.server.db.DataProvider; import io.github.norbipeti.chat.server.db.DataProvider;
import io.github.norbipeti.chat.server.db.domain.User; import io.github.norbipeti.chat.server.db.domain.User;
import io.github.norbipeti.chat.server.page.Page; import io.github.norbipeti.chat.server.page.Page;
public class IOHelper { public class IOHelper {
public static void SendResponse(int code, String content, HttpExchange exchange) throws IOException { public static void SendResponse(int code, String content, HttpExchange exchange) throws IOException {
exchange.sendResponseHeaders(code, content.length()); exchange.sendResponseHeaders(code, content.length());
IOUtils.write(content, exchange.getResponseBody(), StandardCharsets.UTF_8); IOUtils.write(content, exchange.getResponseBody(), StandardCharsets.UTF_8);
exchange.getResponseBody().close(); exchange.getResponseBody().close();
} }
public static boolean SendPage(int code, Page page, HttpExchange exchange) throws IOException { public static boolean SendPage(int code, Page page, HttpExchange exchange) throws IOException {
String content = GetPage(page, exchange); String content = GetPage(page, exchange);
SendResponse(code, content, exchange); SendResponse(code, content, exchange);
return true; return true;
} }
public static String GetPage(Page page, HttpExchange exchange) throws IOException { public static String GetPage(Page page, HttpExchange exchange) throws IOException {
File file = new File(page.GetHTMLPath()); File file = new File(page.GetHTMLPath());
if (!file.exists()) { if (!file.exists()) {
SendResponse(501, SendResponse(501,
"<h1>501 Not Implemented</h1><p>The page \"" + page.GetName() + "\" cannot be found on disk.</h1>", "<h1>501 Not Implemented</h1><p>The page \"" + page.GetName() + "\" cannot be found on disk.</h1>",
exchange); exchange);
return null; return null;
} }
return ReadFile(file); return ReadFile(file);
} }
public static String ReadFile(File file) throws FileNotFoundException, IOException { public static String ReadFile(File file) throws FileNotFoundException, IOException {
FileInputStream inputStream = new FileInputStream(file); FileInputStream inputStream = new FileInputStream(file);
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8); String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
return content; return content;
} }
@Deprecated @Deprecated
public static HashMap<String, String> GetPOST(HttpExchange exchange) throws IOException { public static HashMap<String, String> GetPOST(HttpExchange exchange) throws IOException {
if (exchange.getRequestBody().available() == 0) if (exchange.getRequestBody().available() == 0)
return new HashMap<>(); return new HashMap<>();
try { try {
String[] content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1).split("\\&"); String[] content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1).split("\\&");
HashMap<String, String> vars = new HashMap<>(); HashMap<String, String> vars = new HashMap<>();
for (String var : content) { for (String var : content) {
String[] spl = var.split("\\="); String[] spl = var.split("\\=");
if (spl.length == 1) if (spl.length == 1)
vars.put(spl[0], ""); vars.put(spl[0], "");
else else
vars.put(spl[0], spl[1]); vars.put(spl[0], spl[1]);
} }
return vars; return vars;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return new HashMap<>(); return new HashMap<>();
} }
} }
public static JSONObject GetPOSTJSON(HttpExchange exchange) throws IOException { public static JSONObject GetPOSTJSON(HttpExchange exchange) throws IOException {
if (exchange.getRequestBody().available() == 0) if (exchange.getRequestBody().available() == 0)
return null; return null;
try { try {
String content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1); String content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1);
JSONObject obj = new JSONObject(content); JSONObject obj = new JSONObject(content);
return obj; return obj;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
} }
public static boolean SendModifiedPage(int code, Page page, Function<Document, Document> modifyfunc, public static boolean SendModifiedPage(int code, Page page, Function<Document, Document> modifyfunc,
HttpExchange exchange) throws IOException { HttpExchange exchange) throws IOException {
String content = GetPage(page, exchange); String content = GetPage(page, exchange);
if (content == null) if (content == null)
return false; return false;
Document doc = Jsoup.parse(content); Document doc = Jsoup.parse(content);
doc = modifyfunc.apply(doc); doc = modifyfunc.apply(doc);
SendResponse(200, doc.html(), exchange); SendResponse(200, doc.html(), exchange);
return true; return true;
} }
public static void LoginUser(HttpExchange exchange, User user, DataProvider provider) { public static void LoginUser(HttpExchange exchange, User user, DataProvider provider) {
provider.SetValues(() -> user.setSessionid(UUID.randomUUID())); System.out.println("Logging in user: " + user);
System.out.println("Logging in user: " + user); // provider.SetValues(() ->
ZonedDateTime expiretime = ZonedDateTime.now(ZoneId.of("GMT")).plus(Period.of(2, 0, 0)); // user.setSessionid(UUID.randomUUID().toString()));
exchange.getResponseHeaders().add("Set-Cookie", user.setSessionid(UUID.randomUUID().toString());
"user_id=" + user.getId() + "; expires=" + expiretime.format(DateTimeFormatter.RFC_1123_DATE_TIME)); provider.saveUser(user);
exchange.getResponseHeaders().add("Set-Cookie", System.out.println("Session ID set to " + user.getSessionid());
"session_id=" + user.getSessionid() + "; expires=" + expiretime); ZonedDateTime expiretime = ZonedDateTime.now(ZoneId.of("GMT")).plus(Period.of(2, 0, 0));
} exchange.getResponseHeaders().add("Set-Cookie",
"user_id=" + user.getId() + "; expires=" + expiretime.format(DateTimeFormatter.RFC_1123_DATE_TIME));
public static void LogoutUser(HttpExchange exchange, User user) { exchange.getResponseHeaders().add("Set-Cookie",
user.setSessionid(new UUID(0, 0)); "session_id=" + user.getSessionid() + "; expires=" + expiretime);
SendLogoutHeaders(exchange); }
}
public static void LogoutUser(HttpExchange exchange, User user) {
private static void SendLogoutHeaders(HttpExchange exchange) { user.setSessionid(new UUID(0, 0).toString());
String expiretime = "Sat, 19 Mar 2016 23:33:00 GMT"; SendLogoutHeaders(exchange);
exchange.getResponseHeaders().add("Set-Cookie", "user_id=del; expires=" + expiretime); }
exchange.getResponseHeaders().add("Set-Cookie", "session_id=del; expires=" + expiretime);
} private static void SendLogoutHeaders(HttpExchange exchange) {
String expiretime = "Sat, 19 Mar 2016 23:33:00 GMT";
public static void Redirect(String url, HttpExchange exchange) throws IOException { exchange.getResponseHeaders().add("Set-Cookie", "user_id=del; expires=" + expiretime);
exchange.getResponseHeaders().add("Location", url); exchange.getResponseHeaders().add("Set-Cookie", "session_id=del; expires=" + expiretime);
IOHelper.SendResponse(303, "<a href=\"" + url + "\">If you can see this, click here to continue</a>", exchange); }
}
public static void Redirect(String url, HttpExchange exchange) throws IOException {
public static HashMap<String, String> GetCookies(HttpExchange exchange) { exchange.getResponseHeaders().add("Location", url);
if (!exchange.getRequestHeaders().containsKey("Cookie")) IOHelper.SendResponse(303, "<a href=\"" + url + "\">If you can see this, click here to continue</a>", exchange);
return new HashMap<>(); }
HashMap<String, String> map = new HashMap<>();
for (String cheader : exchange.getRequestHeaders().get("Cookie")) { public static HashMap<String, String> GetCookies(HttpExchange exchange) {
String[] spl = cheader.split("\\;\\s*"); if (!exchange.getRequestHeaders().containsKey("Cookie"))
for (String s : spl) { return new HashMap<>();
String[] kv = s.split("\\="); HashMap<String, String> map = new HashMap<>();
if (kv.length < 2) for (String cheader : exchange.getRequestHeaders().get("Cookie")) {
continue; String[] spl = cheader.split("\\;\\s*");
map.put(kv[0], kv[1]); for (String s : spl) {
} String[] kv = s.split("\\=");
} if (kv.length < 2)
return map; continue;
} map.put(kv[0], kv[1]);
}
/** }
* Get logged in user. It may also send logout headers if the cookies are return map;
* invalid. }
*
* @param exchange /**
* @return The logged in user or null if not logged in. * Get logged in user. It may also send logout headers if the cookies are
*/ * invalid.
public static User GetLoggedInUser(HttpExchange exchange) { *
HashMap<String, String> cookies = GetCookies(exchange); * @param exchange
System.out.println("Cookies: " + cookies); * @return The logged in user or null if not logged in.
if (!cookies.containsKey("user_id") || !cookies.containsKey("session_id")) */
return null; public static User GetLoggedInUser(HttpExchange exchange) {
System.out.println("Cookies found"); HashMap<String, String> cookies = GetCookies(exchange);
try (DataProvider provider = new DataProvider()) { System.out.println("Cookies: " + cookies);
User user = provider.getUser(Long.parseLong(cookies.get("user_id"))); if (!cookies.containsKey("user_id") || !cookies.containsKey("session_id"))
System.out.println("User: " + user); return null;
System.out.println("session_id: " + cookies.get("session_id")); System.out.println("Cookies found");
if (user != null) try (DataProvider provider = new DataProvider()) {
System.out.println("Equals: " + UUID.fromString(cookies.get("session_id")).equals(user.getSessionid())); User user = provider.getUser(Long.parseLong(cookies.get("user_id")));
if (user != null && cookies.get("session_id") != null System.out.println("User: " + user);
&& UUID.fromString(cookies.get("session_id")).equals(user.getSessionid())) System.out.println("session_id: " + cookies.get("session_id"));
return user; if (user != null)
else System.out.println("Equals: " + cookies.get("session_id").equals(user.getSessionid()));
SendLogoutHeaders(exchange); if (user != null && cookies.get("session_id") != null
} && cookies.get("session_id").equals(user.getSessionid()))
return null; return user;
} else
SendLogoutHeaders(exchange);
public static void SendResponse(int code, Function<Document, Document> action, HttpExchange exchange) }
throws IOException { return null;
Document doc = new Document(""); }
doc = action.apply(doc);
SendResponse(200, doc.html(), exchange); public static void SendResponse(int code, Function<Document, Document> action, HttpExchange exchange)
} throws IOException {
} Document doc = new Document("");
doc = action.apply(doc);
SendResponse(200, doc.html(), exchange);
}
}

View file

@ -1,109 +1,108 @@
package io.github.norbipeti.chat.server; package io.github.norbipeti.chat.server;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.ArrayList; import java.util.Date;
import java.util.Date; import java.util.List;
import java.util.List; import java.util.Set;
import java.util.Set;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Configuration; import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.config.LoggerConfig; import org.reflections.Reflections;
import org.reflections.Reflections; import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.SubTypesScanner; import org.reflections.util.ClasspathHelper;
import org.reflections.util.ClasspathHelper; import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.ConfigurationBuilder;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpServer; import io.github.norbipeti.chat.server.db.*;
import io.github.norbipeti.chat.server.db.*; import io.github.norbipeti.chat.server.db.domain.*;
import io.github.norbipeti.chat.server.db.domain.*; import io.github.norbipeti.chat.server.page.*;
import io.github.norbipeti.chat.server.page.*;
public class Main {
public class Main { // public static final HashMap<String, Page> Pages = new HashMap<String,
// public static final HashMap<String, Page> Pages = new HashMap<String, // Page>();
// Page>();
public static void main(String[] args) { // http://stackoverflow.com/questions/9266632/access-restriction-is-not-accessible-due-to-restriction-on-required-library/10642163#10642163
public static void main(String[] args) { // http://stackoverflow.com/questions/9266632/access-restriction-is-not-accessible-due-to-restriction-on-required-library/10642163#10642163 try { // rt.jar Javadoc:
try { // rt.jar Javadoc: // https://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/
// https://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/ // https://docs.oracle.com/javase/8/docs/api/
// https://docs.oracle.com/javase/8/docs/api/ System.out.println(System.getProperty("java.class.path")); // TODO:
System.out.println(System.getProperty("java.class.path")); // TODO: // log4j
// log4j LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
LoggerContext ctx = (LoggerContext) LogManager.getContext(false); Configuration config = ctx.getConfiguration();
Configuration config = ctx.getConfiguration(); LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME); loggerConfig.setLevel(Level.WARN);
loggerConfig.setLevel(Level.WARN); ctx.updateLoggers(); // This causes all Loggers to refetch
ctx.updateLoggers(); // This causes all Loggers to refetch // information from their LoggerConfig.
// information from their LoggerConfig. System.out.println("Loading database...");
System.out.println("Loading database..."); try (DataProvider provider = new DataProvider()) {
try (DataProvider provider = new DataProvider()) { User user = new User();
User user = new User(); user.setName("asd");
user.setName("asd"); user.setEmail("test@test.com");
user.setEmail("test@test.com"); User user2 = new User();
User user2 = new User(); user2.setName("Teszt");
user2.setName("Teszt"); user2.setEmail("test2@test.com");
user2.setEmail("test2@test.com"); user2.getContacts().add(user);
user2.getContacts().add(user); provider.saveUser(user);
provider.addUser(user); List<User> users = provider.getUsers();
List<User> users = provider.getUsers(); user = users.get(0);
user = users.get(0); user.getContacts().add(user2);
user.getContacts().add(user2); provider.saveUser(user2);
provider.addUser(user2); users = provider.getUsers();
users = provider.getUsers(); user2 = users.get(1);
user2 = users.get(1); System.out.println(users);
System.out.println(users); System.out.println("1st's contact: " + user.getContacts().get(0));
System.out.println("1st's contact: " + user.getContacts().get(0)); System.out.println("2nd's contact: " + user2.getContacts().get(0));
System.out.println("2nd's contact: " + user2.getContacts().get(0)); Conversation convo = new Conversation();
Conversation convo = new Conversation(); convo.getUsers().add(user);
convo.getUsers().add(user); convo.getUsers().add(user2);
convo.getUsers().add(user2); Message msg = new Message();
Message msg = new Message(); msg.setSender(user);
msg.setSender(user); msg.setTime(new Date());
msg.setTime(new Date()); msg.setMessage("Teszt 1");
msg.setMessage("Teszt 1"); convo.getMesssages().add(msg);
convo.getMesssages().add(msg); Message msg2 = new Message();
Message msg2 = new Message(); msg2.setSender(user2);
msg2.setSender(user2); msg2.setTime(new Date());
msg2.setTime(new Date()); msg2.setMessage("Teszt 2");
msg2.setMessage("Teszt 2"); convo.getMesssages().add(msg2);
convo.getMesssages().add(msg2); provider.saveConversation(convo);
provider.addConversation(convo); }
} System.out.println("Starting webserver...");
System.out.println("Starting webserver..."); HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), 8080), 10);
HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), 8080), 10); Reflections rf = new Reflections(
Reflections rf = new Reflections( new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(Page.class.getClassLoader()))
new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(Page.class.getClassLoader())) .addClassLoader(Page.class.getClassLoader()).addScanners(new SubTypesScanner())
.addClassLoader(Page.class.getClassLoader()).addScanners(new SubTypesScanner()) .filterInputsBy((String pkg) -> pkg.contains("io.github.norbipeti.chat.server.page")));
.filterInputsBy((String pkg) -> pkg.contains("io.github.norbipeti.chat.server.page"))); Set<Class<? extends Page>> pages = rf.getSubTypesOf(Page.class);
Set<Class<? extends Page>> pages = rf.getSubTypesOf(Page.class); for (Class<? extends Page> page : pages) {
for (Class<? extends Page> page : pages) { try {
try { if (Modifier.isAbstract(page.getModifiers()))
if (Modifier.isAbstract(page.getModifiers())) continue;
continue; Page p = page.newInstance();
Page p = page.newInstance(); addPage(server, p);
addPage(server, p); } catch (InstantiationException e) {
} catch (InstantiationException e) { e.printStackTrace();
e.printStackTrace(); } catch (IllegalAccessException e) {
} catch (IllegalAccessException e) { e.printStackTrace();
e.printStackTrace(); }
} }
} server.start();
server.start(); System.out.println("Ready... Press Enter to stop.");
System.out.println("Ready... Press Enter to stop."); System.in.read();
System.in.read(); System.out.println("Stopping...");
System.out.println("Stopping..."); server.stop(1);
server.stop(1); } catch (Exception e) {
} catch (Exception e) { e.printStackTrace();
e.printStackTrace(); }
} System.out.println("Stopped");
System.out.println("Stopped"); }
}
private static void addPage(HttpServer server, Page page) {
private static void addPage(HttpServer server, Page page) { server.createContext("/" + page.GetName(), page);
server.createContext("/" + page.GetName(), page); }
}
} }

View file

@ -1,87 +1,100 @@
package io.github.norbipeti.chat.server.db; package io.github.norbipeti.chat.server.db;
import java.util.List; import java.util.List;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence; import javax.persistence.Persistence;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import io.github.norbipeti.chat.server.db.domain.*; import org.hibernate.Session;
public class DataProvider implements AutoCloseable { import io.github.norbipeti.chat.server.db.domain.*;
private EntityManagerFactory emf;
public class DataProvider implements AutoCloseable {
public DataProvider() { private EntityManagerFactory emf;
emf = Persistence.createEntityManagerFactory("ChatServerPU");
} public DataProvider() {
emf = Persistence.createEntityManagerFactory("ChatServerPU");
public void addUser(User user) { }
save(user);
} public void saveUser(User user) {
save(user);
public void addConversation(Conversation convo) { }
save(convo);
} public void saveConversation(Conversation convo) {
save(convo);
private void save(Object object) { }
EntityManager em = emf.createEntityManager();
em.getTransaction().begin(); private void save(Object object) {
em.persist(object); EntityManager em = emf.createEntityManager();
em.getTransaction().commit(); em.getTransaction().begin();
em.close(); Session s = em.unwrap(Session.class);
} s.saveOrUpdate(object);
em.persist(object);
public List<User> getUsers() { em.getTransaction().commit();
return get(User.class); em.close();
} }
public List<Message> getMessages() { public List<User> getUsers() {
return get(Message.class); return get(User.class);
} }
public List<Conversation> getConversations() { public List<Message> getMessages() {
return get(Conversation.class); return get(Message.class);
} }
private <T> List<T> get(Class<T> cl) { public List<Conversation> getConversations() {
EntityManager em = emf.createEntityManager(); return get(Conversation.class);
TypedQuery<T> query = em.createQuery("SELECT x FROM " + cl.getSimpleName() + " x", cl); }
List<T> results = query.getResultList();
em.close(); private <T> List<T> get(Class<T> cl) {
return results; EntityManager em = emf.createEntityManager();
} TypedQuery<T> query = em.createQuery("SELECT x FROM " + cl.getSimpleName() + " x", cl);
List<T> results = query.getResultList();
public void removeUser(User user) { em.close();
EntityManager em = emf.createEntityManager(); return results;
em.getTransaction().begin(); }
User managedUser = em.find(User.class, user.getId());
em.remove(managedUser); public void removeUser(User user) {
em.getTransaction().commit(); EntityManager em = emf.createEntityManager();
em.close(); em.getTransaction().begin();
} User managedUser = em.find(User.class, user.getId());
em.remove(managedUser);
public User getUser(Long id) { em.getTransaction().commit();
return get(User.class, id); em.close();
} }
private <T> T get(Class<T> cl, Long id) { public User getUser(Long id) {
EntityManager em = emf.createEntityManager(); return get(User.class, id);
T result = em.find(cl, id); }
em.close();
return result; private <T> T get(Class<T> cl, Long id) {
} EntityManager em = emf.createEntityManager();
T result = em.find(cl, id);
public void SetValues(Runnable action) { em.close();
EntityManager em = emf.createEntityManager(); return result;
em.getTransaction().begin(); }
action.run();
em.getTransaction().commit(); @Deprecated
em.close(); public void SetValues(Runnable action) {
} EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
@Override action.run();
public void close() { em.flush();
if (emf != null) em.getTransaction().commit();
emf.close(); em.close();
} }
}
@Override
public void close() {
if (emf != null)
emf.close();
}
public boolean isEntityManaged(Object entity) {
EntityManager em = emf.createEntityManager();
boolean ret = em.contains(entity);
em.close();
return ret;
}
}

View file

@ -1,115 +1,113 @@
package io.github.norbipeti.chat.server.db.domain; package io.github.norbipeti.chat.server.db.domain;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import javax.persistence.*;
import javax.persistence.*; @Entity
@Table(name = "\"User\"")
@Entity public class User {
@Table(name = "\"User\"") @Id
public class User { @GeneratedValue(strategy = GenerationType.IDENTITY)
@Id @Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
@Column(name = "id", unique = true, nullable = false) private String name;
private Long id; private String email;
private String name; private String password;
private String email; @ElementCollection(fetch = FetchType.EAGER)
private String password; private List<User> contacts;
@ElementCollection(fetch = FetchType.EAGER) private String salt;
private List<User> contacts; //@Column(columnDefinition = "CHAR(16) FOR BIT DATA")
private String salt; @Column(columnDefinition="VARCHAR(64)")
@Column(columnDefinition = "CHAR(16) FOR BIT DATA") private String sessionid;
private UUID sessionid; @Version
@Version @GeneratedValue
@GeneratedValue private int Version;
private int Version; @ElementCollection(fetch = FetchType.EAGER)
@ElementCollection(fetch = FetchType.EAGER) @ManyToMany(cascade = CascadeType.ALL)
@ManyToMany(cascade = CascadeType.ALL) public List<Conversation> conversations;
public List<Conversation> conversations;
public List<User> getContacts() {
public List<User> getContacts() { if (contacts == null)
if (contacts == null) contacts = new ArrayList<>();
contacts = new ArrayList<>(); return contacts;
return contacts; }
}
public void setContacts(List<User> contacts) {
public void setContacts(List<User> contacts) { this.contacts = contacts;
this.contacts = contacts; }
}
public String getName() {
public String getName() { return name;
return name; }
}
public void setName(String name) {
public void setName(String name) { this.name = name;
this.name = name; }
}
public String getEmail() {
public String getEmail() { return email;
return email; }
}
@Override
@Override public String toString() {
public String toString() { List<String> c = null;
List<String> c = null; if (contacts != null) {
if (contacts != null) { c = new ArrayList<>();
c = new ArrayList<>(); for (User u : contacts)
for (User u : contacts) c.add(u.name);
c.add(u.name); }
} return "User [id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + ", contacts=" + c
return "User [id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + ", contacts=" + c + ", sessionid=" + sessionid + "]";
+ ", sessionid=" + sessionid + "]"; // TODO: SessionID null }
// after getting from db
} public void setEmail(String email) {
this.email = email;
public void setEmail(String email) { }
this.email = email;
} public String getPassword() {
return password;
public String getPassword() { }
return password;
} public void setPassword(String password) {
this.password = password;
public void setPassword(String password) { }
this.password = password;
} public Long getId() {
return id;
public Long getId() { }
return id;
} public void setId(Long id) {
this.id = id;
public void setId(Long id) { }
this.id = id;
} public String getSalt() {
return salt;
public String getSalt() { }
return salt;
} public void setSalt(String salt) {
this.salt = salt;
public void setSalt(String salt) { }
this.salt = salt;
} public String getSessionid() {
return sessionid;
public UUID getSessionid() { }
return sessionid;
} public void setSessionid(String sessionid) {
this.sessionid = sessionid;
public void setSessionid(UUID sessionid) { }
this.sessionid = sessionid;
} public List<Conversation> getConversations() {
if (conversations == null)
public List<Conversation> getConversations() { conversations = new ArrayList<>();
if (conversations == null) return conversations;
conversations = new ArrayList<>(); }
return conversations;
} public void setConversations(List<Conversation> conversations) {
this.conversations = conversations;
public void setConversations(List<Conversation> conversations) { }
this.conversations = conversations;
} public User() {
public User() { }
}
}
}

View file

@ -1,60 +1,53 @@
package io.github.norbipeti.chat.server.page; package io.github.norbipeti.chat.server.page;
import java.io.IOException; import java.io.IOException;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import com.sun.net.ssl.internal.ssl.Provider; import io.github.norbipeti.chat.server.IOHelper;
import io.github.norbipeti.chat.server.db.DataProvider;
import io.github.norbipeti.chat.server.IOHelper; import io.github.norbipeti.chat.server.db.domain.User;
import io.github.norbipeti.chat.server.db.DataProvider;
import io.github.norbipeti.chat.server.db.domain.Conversation; public class IndexPage extends Page {
import io.github.norbipeti.chat.server.db.domain.Message;
import io.github.norbipeti.chat.server.db.domain.User; @Override
public void handlePage(HttpExchange exchange) throws IOException {
public class IndexPage extends Page { final User user = IOHelper.GetLoggedInUser(exchange);
/*final User user = new User();
@Override user.setEmail("test@test.com");
public void handlePage(HttpExchange exchange) throws IOException { user.setName("Norbi");
// final User user = IOHelper.GetLoggedInUser(exchange); - TODO user.setId(3L);*/
final User user = new User(); if (user == null)
user.setEmail("test@test.com"); IOHelper.SendModifiedPage(200, this, (doc) -> {
user.setName("Norbi"); doc.getElementById("userbox").remove();
user.setId(3L); doc.getElementById("usercontent").remove();
if (user == null) return doc;
IOHelper.SendModifiedPage(200, this, (doc) -> { }, exchange);
doc.getElementById("userbox").remove(); else
doc.getElementById("usercontent").remove(); IOHelper.SendModifiedPage(200, this, (doc) -> {
return doc; doc.getElementById("loginbox").remove();
}, exchange); doc.getElementById("registerbox").remove();
else Element userbox = doc.getElementById("userbox");
IOHelper.SendModifiedPage(200, this, (doc) -> { userbox.html(userbox.html().replace("<username />", user.getName()));
doc.getElementById("loginbox").remove(); Element channelmessages = doc.getElementById("channelmessages");
doc.getElementById("registerbox").remove(); try (DataProvider provider = new DataProvider()) {
Element userbox = doc.getElementById("userbox"); /*Conversation convo = provider.getConversations().get(0); // TODO
userbox.html(userbox.html().replace("<username />", user.getName())); for (Message message : convo.getMesssages()) {
Element channelmessages = doc.getElementById("channelmessages"); Element msgelement = channelmessages.appendElement("div");
try (DataProvider provider = new DataProvider()) { Element header = msgelement.appendElement("p");
Conversation convo = provider.getConversations().get(0); //TODO header.text(message.getSender().getName() + " - " + message.getTime());
for (Message message : convo.getMesssages()) { Element body = msgelement.appendElement("p");
Element msgelement = channelmessages.appendElement("div"); body.text(message.getMessage());
Element header = msgelement.appendElement("p"); }*/
header.text(message.getSender().getName() + " - " + message.getTime()); }
Element body = msgelement.appendElement("p"); return doc;
body.text(message.getMessage()); }, exchange);
} } // TODO: Validation at registration (no special chars, etc.)
}
return doc; @Override
}, exchange); public String GetName() {
} // TODO: return "";
// Validation }
// at
// registration }
@Override
public String GetName() {
return "";
}
}

View file

@ -1,72 +1,72 @@
package io.github.norbipeti.chat.server.page; package io.github.norbipeti.chat.server.page;
import java.io.IOException; import java.io.IOException;
import org.json.JSONObject; import org.json.JSONObject;
import org.mindrot.jbcrypt.BCrypt; import org.mindrot.jbcrypt.BCrypt;
import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpExchange;
import io.github.norbipeti.chat.server.IOHelper; import io.github.norbipeti.chat.server.IOHelper;
import io.github.norbipeti.chat.server.db.DataProvider; import io.github.norbipeti.chat.server.db.DataProvider;
import io.github.norbipeti.chat.server.db.domain.User; import io.github.norbipeti.chat.server.db.domain.User;
public class RegisterPage extends Page { public class RegisterPage extends Page {
@Override @Override
public void handlePage(HttpExchange exchange) throws IOException { public void handlePage(HttpExchange exchange) throws IOException {
JSONObject post = IOHelper.GetPOSTJSON(exchange); JSONObject post = IOHelper.GetPOSTJSON(exchange);
if (post != null) { if (post != null) {
String errormsg = CheckValues(post, "name", "email", "pass", "pass2"); String errormsg = CheckValues(post, "name", "email", "pass", "pass2");
if (errormsg.length() > 0) { if (errormsg.length() > 0) {
final String msg = errormsg; final String msg = errormsg;
IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange); IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange);
return; // TODO: Use JavaScript too, for error checks return; // TODO: Use JavaScript too, for error checks
} }
try (DataProvider provider = new DataProvider()) { try (DataProvider provider = new DataProvider()) {
for (User user : provider.getUsers()) { for (User user : provider.getUsers()) {
if (post.get("email").equals(user.getEmail())) { if (post.get("email").equals(user.getEmail())) {
errormsg += "<p>An user with this name already exists</p>"; errormsg += "<p>An user with this name already exists</p>";
break; break;
} }
} }
if (!post.get("pass").equals(post.get("pass2"))) if (!post.get("pass").equals(post.get("pass2")))
errormsg += "<p>The passwords don't match</p>"; errormsg += "<p>The passwords don't match</p>";
if (errormsg.length() > 0) { if (errormsg.length() > 0) {
final String msg = errormsg; final String msg = errormsg;
IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange); IOHelper.SendResponse(200, (doc) -> doc.html(msg).ownerDocument(), exchange);
return; return;
} }
User user = new User(); User user = new User();
user.setName(post.getString("name")); user.setName(post.getString("name"));
user.setEmail(post.getString("email")); user.setEmail(post.getString("email"));
user.setSalt(BCrypt.gensalt()); // http://www.mindrot.org/projects/jBCrypt/ user.setSalt(BCrypt.gensalt()); // http://www.mindrot.org/projects/jBCrypt/
user.setPassword(BCrypt.hashpw(post.getString("pass"), user.getSalt())); user.setPassword(BCrypt.hashpw(post.getString("pass"), user.getSalt()));
provider.addUser(user); provider.saveUser(user);
User managedUser = provider.getUser(user.getId()); User managedUser = provider.getUser(user.getId());
IOHelper.LoginUser(exchange, managedUser, provider); IOHelper.LoginUser(exchange, managedUser, provider);
IOHelper.SendResponse(200, "Success", exchange); IOHelper.SendResponse(200, "Success", exchange);
} catch (Exception e) { } catch (Exception e) {
throw e; throw e;
} }
return; return;
} }
IOHelper.Redirect("/", exchange); IOHelper.Redirect("/", exchange);
} }
private String CheckValues(JSONObject post, String... values) { private String CheckValues(JSONObject post, String... values) {
String errormsg = ""; String errormsg = "";
for (String value : values) for (String value : values)
if (!CheckValue(post.getString(value))) if (!CheckValue(post.getString(value)))
errormsg += "<p>" + value + " can't be empty</p>"; errormsg += "<p>" + value + " can't be empty</p>";
return errormsg; return errormsg;
} }
private boolean CheckValue(String val) { private boolean CheckValue(String val) {
return val != null && val.length() > 0; return val != null && val.length() > 0;
} }
@Override @Override
public String GetName() { public String GetName() {
return "register"; return "register";
} }
} }