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

View file

@ -1,12 +1,27 @@
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
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"
version="2.0">
<persistence-unit name="ChatServerPU">
<properties>
<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
name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
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"
version="2.0">
<persistence-unit name="ChatServerPU">
<properties>
<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 name="hibernate.hbm2ddl.auto" value="update" />
<!-- 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>

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"
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>
<groupId>ChatServer</groupId>
<artifactId>ChatServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.12.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.12.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
<scope>runtime</scope>
</dependency>
<dependency>
<!-- jsoup HTML parser library @ http://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.6.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160212</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>ChatServer</groupId>
<artifactId>ChatServer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.12.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>10.12.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.1.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
<scope>runtime</scope>
</dependency>
<dependency>
<!-- jsoup HTML parser library @ http://jsoup.org/ -->
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.6.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160212</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<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>

View file

@ -1,178 +1,182 @@
package io.github.norbipeti.chat.server;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.UUID;
import java.util.function.Function;
import org.apache.commons.io.IOUtils;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import com.sun.net.httpserver.HttpExchange;
import io.github.norbipeti.chat.server.db.DataProvider;
import io.github.norbipeti.chat.server.db.domain.User;
import io.github.norbipeti.chat.server.page.Page;
public class IOHelper {
public static void SendResponse(int code, String content, HttpExchange exchange) throws IOException {
exchange.sendResponseHeaders(code, content.length());
IOUtils.write(content, exchange.getResponseBody(), StandardCharsets.UTF_8);
exchange.getResponseBody().close();
}
public static boolean SendPage(int code, Page page, HttpExchange exchange) throws IOException {
String content = GetPage(page, exchange);
SendResponse(code, content, exchange);
return true;
}
public static String GetPage(Page page, HttpExchange exchange) throws IOException {
File file = new File(page.GetHTMLPath());
if (!file.exists()) {
SendResponse(501,
"<h1>501 Not Implemented</h1><p>The page \"" + page.GetName() + "\" cannot be found on disk.</h1>",
exchange);
return null;
}
return ReadFile(file);
}
public static String ReadFile(File file) throws FileNotFoundException, IOException {
FileInputStream inputStream = new FileInputStream(file);
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
return content;
}
@Deprecated
public static HashMap<String, String> GetPOST(HttpExchange exchange) throws IOException {
if (exchange.getRequestBody().available() == 0)
return new HashMap<>();
try {
String[] content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1).split("\\&");
HashMap<String, String> vars = new HashMap<>();
for (String var : content) {
String[] spl = var.split("\\=");
if (spl.length == 1)
vars.put(spl[0], "");
else
vars.put(spl[0], spl[1]);
}
return vars;
} catch (Exception e) {
e.printStackTrace();
return new HashMap<>();
}
}
public static JSONObject GetPOSTJSON(HttpExchange exchange) throws IOException {
if (exchange.getRequestBody().available() == 0)
return null;
try {
String content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1);
JSONObject obj = new JSONObject(content);
return obj;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static boolean SendModifiedPage(int code, Page page, Function<Document, Document> modifyfunc,
HttpExchange exchange) throws IOException {
String content = GetPage(page, exchange);
if (content == null)
return false;
Document doc = Jsoup.parse(content);
doc = modifyfunc.apply(doc);
SendResponse(200, doc.html(), exchange);
return true;
}
public static void LoginUser(HttpExchange exchange, User user, DataProvider provider) {
provider.SetValues(() -> user.setSessionid(UUID.randomUUID()));
System.out.println("Logging in user: " + user);
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));
exchange.getResponseHeaders().add("Set-Cookie",
"session_id=" + user.getSessionid() + "; expires=" + expiretime);
}
public static void LogoutUser(HttpExchange exchange, User user) {
user.setSessionid(new UUID(0, 0));
SendLogoutHeaders(exchange);
}
private static void SendLogoutHeaders(HttpExchange exchange) {
String expiretime = "Sat, 19 Mar 2016 23:33:00 GMT";
exchange.getResponseHeaders().add("Set-Cookie", "user_id=del; expires=" + expiretime);
exchange.getResponseHeaders().add("Set-Cookie", "session_id=del; expires=" + expiretime);
}
public static void Redirect(String url, HttpExchange exchange) throws IOException {
exchange.getResponseHeaders().add("Location", url);
IOHelper.SendResponse(303, "<a href=\"" + url + "\">If you can see this, click here to continue</a>", exchange);
}
public static HashMap<String, String> GetCookies(HttpExchange exchange) {
if (!exchange.getRequestHeaders().containsKey("Cookie"))
return new HashMap<>();
HashMap<String, String> map = new HashMap<>();
for (String cheader : exchange.getRequestHeaders().get("Cookie")) {
String[] spl = cheader.split("\\;\\s*");
for (String s : spl) {
String[] kv = s.split("\\=");
if (kv.length < 2)
continue;
map.put(kv[0], kv[1]);
}
}
return map;
}
/**
* Get logged in user. It may also send logout headers if the cookies are
* invalid.
*
* @param exchange
* @return The logged in user or null if not logged in.
*/
public static User GetLoggedInUser(HttpExchange exchange) {
HashMap<String, String> cookies = GetCookies(exchange);
System.out.println("Cookies: " + cookies);
if (!cookies.containsKey("user_id") || !cookies.containsKey("session_id"))
return null;
System.out.println("Cookies found");
try (DataProvider provider = new DataProvider()) {
User user = provider.getUser(Long.parseLong(cookies.get("user_id")));
System.out.println("User: " + user);
System.out.println("session_id: " + cookies.get("session_id"));
if (user != null)
System.out.println("Equals: " + UUID.fromString(cookies.get("session_id")).equals(user.getSessionid()));
if (user != null && cookies.get("session_id") != null
&& UUID.fromString(cookies.get("session_id")).equals(user.getSessionid()))
return user;
else
SendLogoutHeaders(exchange);
}
return null;
}
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);
}
}
package io.github.norbipeti.chat.server;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.UUID;
import java.util.function.Function;
import org.apache.commons.io.IOUtils;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import com.sun.net.httpserver.HttpExchange;
import io.github.norbipeti.chat.server.db.DataProvider;
import io.github.norbipeti.chat.server.db.domain.User;
import io.github.norbipeti.chat.server.page.Page;
public class IOHelper {
public static void SendResponse(int code, String content, HttpExchange exchange) throws IOException {
exchange.sendResponseHeaders(code, content.length());
IOUtils.write(content, exchange.getResponseBody(), StandardCharsets.UTF_8);
exchange.getResponseBody().close();
}
public static boolean SendPage(int code, Page page, HttpExchange exchange) throws IOException {
String content = GetPage(page, exchange);
SendResponse(code, content, exchange);
return true;
}
public static String GetPage(Page page, HttpExchange exchange) throws IOException {
File file = new File(page.GetHTMLPath());
if (!file.exists()) {
SendResponse(501,
"<h1>501 Not Implemented</h1><p>The page \"" + page.GetName() + "\" cannot be found on disk.</h1>",
exchange);
return null;
}
return ReadFile(file);
}
public static String ReadFile(File file) throws FileNotFoundException, IOException {
FileInputStream inputStream = new FileInputStream(file);
String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
return content;
}
@Deprecated
public static HashMap<String, String> GetPOST(HttpExchange exchange) throws IOException {
if (exchange.getRequestBody().available() == 0)
return new HashMap<>();
try {
String[] content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1).split("\\&");
HashMap<String, String> vars = new HashMap<>();
for (String var : content) {
String[] spl = var.split("\\=");
if (spl.length == 1)
vars.put(spl[0], "");
else
vars.put(spl[0], spl[1]);
}
return vars;
} catch (Exception e) {
e.printStackTrace();
return new HashMap<>();
}
}
public static JSONObject GetPOSTJSON(HttpExchange exchange) throws IOException {
if (exchange.getRequestBody().available() == 0)
return null;
try {
String content = IOUtils.toString(exchange.getRequestBody(), StandardCharsets.ISO_8859_1);
JSONObject obj = new JSONObject(content);
return obj;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static boolean SendModifiedPage(int code, Page page, Function<Document, Document> modifyfunc,
HttpExchange exchange) throws IOException {
String content = GetPage(page, exchange);
if (content == null)
return false;
Document doc = Jsoup.parse(content);
doc = modifyfunc.apply(doc);
SendResponse(200, doc.html(), exchange);
return true;
}
public static void LoginUser(HttpExchange exchange, User user, DataProvider provider) {
System.out.println("Logging in user: " + user);
// provider.SetValues(() ->
// user.setSessionid(UUID.randomUUID().toString()));
user.setSessionid(UUID.randomUUID().toString());
provider.saveUser(user);
System.out.println("Session ID set to " + user.getSessionid());
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));
exchange.getResponseHeaders().add("Set-Cookie",
"session_id=" + user.getSessionid() + "; expires=" + expiretime);
}
public static void LogoutUser(HttpExchange exchange, User user) {
user.setSessionid(new UUID(0, 0).toString());
SendLogoutHeaders(exchange);
}
private static void SendLogoutHeaders(HttpExchange exchange) {
String expiretime = "Sat, 19 Mar 2016 23:33:00 GMT";
exchange.getResponseHeaders().add("Set-Cookie", "user_id=del; expires=" + expiretime);
exchange.getResponseHeaders().add("Set-Cookie", "session_id=del; expires=" + expiretime);
}
public static void Redirect(String url, HttpExchange exchange) throws IOException {
exchange.getResponseHeaders().add("Location", url);
IOHelper.SendResponse(303, "<a href=\"" + url + "\">If you can see this, click here to continue</a>", exchange);
}
public static HashMap<String, String> GetCookies(HttpExchange exchange) {
if (!exchange.getRequestHeaders().containsKey("Cookie"))
return new HashMap<>();
HashMap<String, String> map = new HashMap<>();
for (String cheader : exchange.getRequestHeaders().get("Cookie")) {
String[] spl = cheader.split("\\;\\s*");
for (String s : spl) {
String[] kv = s.split("\\=");
if (kv.length < 2)
continue;
map.put(kv[0], kv[1]);
}
}
return map;
}
/**
* Get logged in user. It may also send logout headers if the cookies are
* invalid.
*
* @param exchange
* @return The logged in user or null if not logged in.
*/
public static User GetLoggedInUser(HttpExchange exchange) {
HashMap<String, String> cookies = GetCookies(exchange);
System.out.println("Cookies: " + cookies);
if (!cookies.containsKey("user_id") || !cookies.containsKey("session_id"))
return null;
System.out.println("Cookies found");
try (DataProvider provider = new DataProvider()) {
User user = provider.getUser(Long.parseLong(cookies.get("user_id")));
System.out.println("User: " + user);
System.out.println("session_id: " + cookies.get("session_id"));
if (user != null)
System.out.println("Equals: " + cookies.get("session_id").equals(user.getSessionid()));
if (user != null && cookies.get("session_id") != null
&& cookies.get("session_id").equals(user.getSessionid()))
return user;
else
SendLogoutHeaders(exchange);
}
return null;
}
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;
import java.lang.reflect.Modifier;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import com.sun.net.httpserver.HttpServer;
import io.github.norbipeti.chat.server.db.*;
import io.github.norbipeti.chat.server.db.domain.*;
import io.github.norbipeti.chat.server.page.*;
public class Main {
// public static final HashMap<String, Page> Pages = new HashMap<String,
// 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
try { // rt.jar Javadoc:
// https://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/
// https://docs.oracle.com/javase/8/docs/api/
System.out.println(System.getProperty("java.class.path")); // TODO:
// log4j
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.setLevel(Level.WARN);
ctx.updateLoggers(); // This causes all Loggers to refetch
// information from their LoggerConfig.
System.out.println("Loading database...");
try (DataProvider provider = new DataProvider()) {
User user = new User();
user.setName("asd");
user.setEmail("test@test.com");
User user2 = new User();
user2.setName("Teszt");
user2.setEmail("test2@test.com");
user2.getContacts().add(user);
provider.addUser(user);
List<User> users = provider.getUsers();
user = users.get(0);
user.getContacts().add(user2);
provider.addUser(user2);
users = provider.getUsers();
user2 = users.get(1);
System.out.println(users);
System.out.println("1st's contact: " + user.getContacts().get(0));
System.out.println("2nd's contact: " + user2.getContacts().get(0));
Conversation convo = new Conversation();
convo.getUsers().add(user);
convo.getUsers().add(user2);
Message msg = new Message();
msg.setSender(user);
msg.setTime(new Date());
msg.setMessage("Teszt 1");
convo.getMesssages().add(msg);
Message msg2 = new Message();
msg2.setSender(user2);
msg2.setTime(new Date());
msg2.setMessage("Teszt 2");
convo.getMesssages().add(msg2);
provider.addConversation(convo);
}
System.out.println("Starting webserver...");
HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), 8080), 10);
Reflections rf = new Reflections(
new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(Page.class.getClassLoader()))
.addClassLoader(Page.class.getClassLoader()).addScanners(new SubTypesScanner())
.filterInputsBy((String pkg) -> pkg.contains("io.github.norbipeti.chat.server.page")));
Set<Class<? extends Page>> pages = rf.getSubTypesOf(Page.class);
for (Class<? extends Page> page : pages) {
try {
if (Modifier.isAbstract(page.getModifiers()))
continue;
Page p = page.newInstance();
addPage(server, p);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
server.start();
System.out.println("Ready... Press Enter to stop.");
System.in.read();
System.out.println("Stopping...");
server.stop(1);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Stopped");
}
private static void addPage(HttpServer server, Page page) {
server.createContext("/" + page.GetName(), page);
}
package io.github.norbipeti.chat.server;
import java.lang.reflect.Modifier;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Date;
import java.util.List;
import java.util.Set;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import com.sun.net.httpserver.HttpServer;
import io.github.norbipeti.chat.server.db.*;
import io.github.norbipeti.chat.server.db.domain.*;
import io.github.norbipeti.chat.server.page.*;
public class Main {
// public static final HashMap<String, Page> Pages = new HashMap<String,
// 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
try { // rt.jar Javadoc:
// https://docs.oracle.com/javase/8/docs/jre/api/net/httpserver/spec/
// https://docs.oracle.com/javase/8/docs/api/
System.out.println(System.getProperty("java.class.path")); // TODO:
// log4j
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.setLevel(Level.WARN);
ctx.updateLoggers(); // This causes all Loggers to refetch
// information from their LoggerConfig.
System.out.println("Loading database...");
try (DataProvider provider = new DataProvider()) {
User user = new User();
user.setName("asd");
user.setEmail("test@test.com");
User user2 = new User();
user2.setName("Teszt");
user2.setEmail("test2@test.com");
user2.getContacts().add(user);
provider.saveUser(user);
List<User> users = provider.getUsers();
user = users.get(0);
user.getContacts().add(user2);
provider.saveUser(user2);
users = provider.getUsers();
user2 = users.get(1);
System.out.println(users);
System.out.println("1st's contact: " + user.getContacts().get(0));
System.out.println("2nd's contact: " + user2.getContacts().get(0));
Conversation convo = new Conversation();
convo.getUsers().add(user);
convo.getUsers().add(user2);
Message msg = new Message();
msg.setSender(user);
msg.setTime(new Date());
msg.setMessage("Teszt 1");
convo.getMesssages().add(msg);
Message msg2 = new Message();
msg2.setSender(user2);
msg2.setTime(new Date());
msg2.setMessage("Teszt 2");
convo.getMesssages().add(msg2);
provider.saveConversation(convo);
}
System.out.println("Starting webserver...");
HttpServer server = HttpServer.create(new InetSocketAddress(InetAddress.getLocalHost(), 8080), 10);
Reflections rf = new Reflections(
new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(Page.class.getClassLoader()))
.addClassLoader(Page.class.getClassLoader()).addScanners(new SubTypesScanner())
.filterInputsBy((String pkg) -> pkg.contains("io.github.norbipeti.chat.server.page")));
Set<Class<? extends Page>> pages = rf.getSubTypesOf(Page.class);
for (Class<? extends Page> page : pages) {
try {
if (Modifier.isAbstract(page.getModifiers()))
continue;
Page p = page.newInstance();
addPage(server, p);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
server.start();
System.out.println("Ready... Press Enter to stop.");
System.in.read();
System.out.println("Stopping...");
server.stop(1);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Stopped");
}
private static void addPage(HttpServer server, Page page) {
server.createContext("/" + page.GetName(), page);
}
}

View file

@ -1,87 +1,100 @@
package io.github.norbipeti.chat.server.db;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import io.github.norbipeti.chat.server.db.domain.*;
public class DataProvider implements AutoCloseable {
private EntityManagerFactory emf;
public DataProvider() {
emf = Persistence.createEntityManagerFactory("ChatServerPU");
}
public void addUser(User user) {
save(user);
}
public void addConversation(Conversation convo) {
save(convo);
}
private void save(Object object) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(object);
em.getTransaction().commit();
em.close();
}
public List<User> getUsers() {
return get(User.class);
}
public List<Message> getMessages() {
return get(Message.class);
}
public List<Conversation> getConversations() {
return get(Conversation.class);
}
private <T> List<T> get(Class<T> cl) {
EntityManager em = emf.createEntityManager();
TypedQuery<T> query = em.createQuery("SELECT x FROM " + cl.getSimpleName() + " x", cl);
List<T> results = query.getResultList();
em.close();
return results;
}
public void removeUser(User user) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
User managedUser = em.find(User.class, user.getId());
em.remove(managedUser);
em.getTransaction().commit();
em.close();
}
public User getUser(Long id) {
return get(User.class, id);
}
private <T> T get(Class<T> cl, Long id) {
EntityManager em = emf.createEntityManager();
T result = em.find(cl, id);
em.close();
return result;
}
public void SetValues(Runnable action) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
action.run();
em.getTransaction().commit();
em.close();
}
@Override
public void close() {
if (emf != null)
emf.close();
}
}
package io.github.norbipeti.chat.server.db;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import org.hibernate.Session;
import io.github.norbipeti.chat.server.db.domain.*;
public class DataProvider implements AutoCloseable {
private EntityManagerFactory emf;
public DataProvider() {
emf = Persistence.createEntityManagerFactory("ChatServerPU");
}
public void saveUser(User user) {
save(user);
}
public void saveConversation(Conversation convo) {
save(convo);
}
private void save(Object object) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Session s = em.unwrap(Session.class);
s.saveOrUpdate(object);
em.persist(object);
em.getTransaction().commit();
em.close();
}
public List<User> getUsers() {
return get(User.class);
}
public List<Message> getMessages() {
return get(Message.class);
}
public List<Conversation> getConversations() {
return get(Conversation.class);
}
private <T> List<T> get(Class<T> cl) {
EntityManager em = emf.createEntityManager();
TypedQuery<T> query = em.createQuery("SELECT x FROM " + cl.getSimpleName() + " x", cl);
List<T> results = query.getResultList();
em.close();
return results;
}
public void removeUser(User user) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
User managedUser = em.find(User.class, user.getId());
em.remove(managedUser);
em.getTransaction().commit();
em.close();
}
public User getUser(Long id) {
return get(User.class, id);
}
private <T> T get(Class<T> cl, Long id) {
EntityManager em = emf.createEntityManager();
T result = em.find(cl, id);
em.close();
return result;
}
@Deprecated
public void SetValues(Runnable action) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
action.run();
em.flush();
em.getTransaction().commit();
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;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.persistence.*;
@Entity
@Table(name = "\"User\"")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Long id;
private String name;
private String email;
private String password;
@ElementCollection(fetch = FetchType.EAGER)
private List<User> contacts;
private String salt;
@Column(columnDefinition = "CHAR(16) FOR BIT DATA")
private UUID sessionid;
@Version
@GeneratedValue
private int Version;
@ElementCollection(fetch = FetchType.EAGER)
@ManyToMany(cascade = CascadeType.ALL)
public List<Conversation> conversations;
public List<User> getContacts() {
if (contacts == null)
contacts = new ArrayList<>();
return contacts;
}
public void setContacts(List<User> contacts) {
this.contacts = contacts;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
@Override
public String toString() {
List<String> c = null;
if (contacts != null) {
c = new ArrayList<>();
for (User u : contacts)
c.add(u.name);
}
return "User [id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + ", contacts=" + c
+ ", sessionid=" + sessionid + "]"; // TODO: SessionID null
// after getting from db
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public UUID getSessionid() {
return sessionid;
}
public void setSessionid(UUID sessionid) {
this.sessionid = sessionid;
}
public List<Conversation> getConversations() {
if (conversations == null)
conversations = new ArrayList<>();
return conversations;
}
public void setConversations(List<Conversation> conversations) {
this.conversations = conversations;
}
public User() {
}
}
package io.github.norbipeti.chat.server.db.domain;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
@Entity
@Table(name = "\"User\"")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Long id;
private String name;
private String email;
private String password;
@ElementCollection(fetch = FetchType.EAGER)
private List<User> contacts;
private String salt;
//@Column(columnDefinition = "CHAR(16) FOR BIT DATA")
@Column(columnDefinition="VARCHAR(64)")
private String sessionid;
@Version
@GeneratedValue
private int Version;
@ElementCollection(fetch = FetchType.EAGER)
@ManyToMany(cascade = CascadeType.ALL)
public List<Conversation> conversations;
public List<User> getContacts() {
if (contacts == null)
contacts = new ArrayList<>();
return contacts;
}
public void setContacts(List<User> contacts) {
this.contacts = contacts;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
@Override
public String toString() {
List<String> c = null;
if (contacts != null) {
c = new ArrayList<>();
for (User u : contacts)
c.add(u.name);
}
return "User [id=" + id + ", name=" + name + ", email=" + email + ", password=" + password + ", contacts=" + c
+ ", sessionid=" + sessionid + "]";
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public String getSessionid() {
return sessionid;
}
public void setSessionid(String sessionid) {
this.sessionid = sessionid;
}
public List<Conversation> getConversations() {
if (conversations == null)
conversations = new ArrayList<>();
return conversations;
}
public void setConversations(List<Conversation> conversations) {
this.conversations = conversations;
}
public User() {
}
}

View file

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

View file

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