Compare commits

..

No commits in common. "fa6f0774a1794c6b1117b65b4d1aa92bfd8b2bfa" and "e119911fefd0f28fd1d28277c40f6776630912c6" have entirely different histories.

24 changed files with 127 additions and 237 deletions

View file

@ -1,7 +1,5 @@
package be.jeffcheasey88.peeratcode; package be.jeffcheasey88.peeratcode;
import static be.jeffcheasey88.peeratcode.framework.RequestType.OPTIONS;
import java.io.IOException; import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
@ -10,6 +8,9 @@ import java.util.regex.Matcher;
import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLServerSocketFactory;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jwk.RsaJwkGenerator;
import be.jeffcheasey88.peeratcode.framework.Client; import be.jeffcheasey88.peeratcode.framework.Client;
import be.jeffcheasey88.peeratcode.framework.HttpReader; import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpUtil; import be.jeffcheasey88.peeratcode.framework.HttpUtil;
@ -30,9 +31,7 @@ import be.jeffcheasey88.peeratcode.routes.PuzzleResponse;
import be.jeffcheasey88.peeratcode.routes.Register; import be.jeffcheasey88.peeratcode.routes.Register;
import be.jeffcheasey88.peeratcode.routes.Result; import be.jeffcheasey88.peeratcode.routes.Result;
import be.jeffcheasey88.peeratcode.routes.groups.CreateGroup; import be.jeffcheasey88.peeratcode.routes.groups.CreateGroup;
import be.jeffcheasey88.peeratcode.routes.groups.GroupJoin;
import be.jeffcheasey88.peeratcode.routes.groups.GroupList; import be.jeffcheasey88.peeratcode.routes.groups.GroupList;
import be.jeffcheasey88.peeratcode.routes.groups.GroupQuit;
public class Main { public class Main {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
@ -55,7 +54,7 @@ public class Main {
}); });
router.register(new Response() { router.register(new Response() {
@Route(path = "^(.*)$", type = OPTIONS) @Route(path = "^(.*)$", type = "OPTIONS")
@Override @Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *", HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *",
@ -82,8 +81,6 @@ public class Main {
router.register(new GroupList(router.getDataBase())); router.register(new GroupList(router.getDataBase()));
router.register(new CreateGroup(router.getDataBase())); router.register(new CreateGroup(router.getDataBase()));
router.register(new GroupJoin(router.getDataBase()));
router.register(new GroupQuit(router.getDataBase()));
} }
private static void startWebServer(Configuration config, Router router) throws IOException { private static void startWebServer(Configuration config, Router router) throws IOException {
@ -98,7 +95,7 @@ public class Main {
while (!server.isClosed()) { while (!server.isClosed()) {
Socket socket = server.accept(); Socket socket = server.accept();
Client client = new Client(socket, router); Client client = new Client(socket, router, RsaJwkGenerator.generateJwk(2048));
client.start(); client.start();
} }
} catch (Exception e) { } catch (Exception e) {
@ -112,7 +109,8 @@ public class Main {
try (ServerSocket server = new ServerSocket(config.getTcpPort())) { try (ServerSocket server = new ServerSocket(config.getTcpPort())) {
while (!server.isClosed()) { while (!server.isClosed()) {
Socket socket = server.accept(); Socket socket = server.accept();
Client client = new Client(socket, router); RsaJsonWebKey rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
Client client = new Client(socket, router, rsaJsonWebKey);
client.start(); client.start();
} }
} catch (Exception e) { } catch (Exception e) {

View file

@ -10,46 +10,47 @@ import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer; import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder; import org.jose4j.jwt.consumer.JwtConsumerBuilder;
public class Client extends Thread{ public class Client extends Thread {
private HttpReader reader; private HttpReader reader;
private HttpWriter writer; private HttpWriter writer;
private Router router; private Router router;
private RsaJsonWebKey key; // Really needed ?
public Client(Socket socket, Router router) throws Exception{ public Client(Socket socket, Router router, RsaJsonWebKey key) throws Exception {
this.reader = new HttpReader(socket); this.reader = new HttpReader(socket);
this.writer = new HttpWriter(socket); this.writer = new HttpWriter(socket);
this.router = router; this.router = router;
this.key = key;
} }
@Override @Override
public void run(){ public void run() {
try { try {
String[] headers = reader.readLine().split("\\s"); String[] headers = reader.readLine().split("\\s");
System.out.println(Arrays.toString(headers)); System.out.println(Arrays.toString(headers));
router.exec(RequestType.valueOf(headers[0]), headers[1], isLogin(reader), reader, writer); router.exec(headers[0], headers[1], isLogin(reader), reader, writer);
writer.flush(); writer.flush();
writer.close(); writer.close();
}catch(Exception e){ } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
private User isLogin(HttpReader reader) throws Exception{ private User isLogin(HttpReader reader) throws Exception {
String auth = HttpUtil.readAuthorization(reader); String auth = HttpUtil.readAuthorization(reader);
if(auth == null) return null; if (auth == null)
try{ return null;
JwtConsumer jwtConsumer = new JwtConsumerBuilder() try {
.setRequireExpirationTime() JwtConsumer jwtConsumer = new JwtConsumerBuilder().setRequireExpirationTime()
.setAllowedClockSkewInSeconds(30) .setAllowedClockSkewInSeconds(30).setExpectedIssuer(this.router.getTokenIssuer())
.setExpectedIssuer(this.router.getTokenIssuer())
.setVerificationKey(this.router.getWebKey().getKey()) .setVerificationKey(this.router.getWebKey().getKey())
.setJwsAlgorithmConstraints(ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256).build(); .setJwsAlgorithmConstraints(ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256).build();
JwtClaims jwtClaims = jwtConsumer.processToClaims(auth); JwtClaims jwtClaims = jwtConsumer.processToClaims(auth);
return new User(jwtClaims); return new User(jwtClaims);
}catch(Exception e){ } catch (Exception e) {
HttpUtil.responseHeaders(writer, 401, "Access-Control-Allow-Origin: *"); HttpUtil.responseHeaders(writer, 401, "Access-Control-Allow-Origin: *");
writer.flush(); writer.flush();
writer.close(); writer.close();

View file

@ -8,34 +8,37 @@ import java.util.regex.Pattern;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
public class HttpUtil{ public class HttpUtil {
private HttpUtil(){} private HttpUtil() {
}
public static void responseHeaders(HttpWriter writer, int code, String... headers) throws Exception{ public static void responseHeaders(HttpWriter writer, int code, String... headers) throws Exception {
writer.write("HTTP/1.1 " + code + " " + codeMessage(code) + "\n"); writer.write("HTTP/1.1 " + code + " " + codeMessage(code) + "\n");
for(String header : headers) writer.write(header + "\n"); for (String header : headers)
writer.write(header + "\n");
writer.write("\n"); writer.write("\n");
writer.flush(); writer.flush();
} }
public static void skipHeaders(HttpReader reader) throws Exception{ public static void skipHeaders(HttpReader reader) throws Exception {
String line; String line;
while(((line = reader.readLine()) != null) && (line.length() > 0)); while (((line = reader.readLine()) != null) && (line.length() > 0))
;
} }
public static List<String> readMultiPartData(HttpReader reader) throws Exception{ public static List<String> readMultiPartData(HttpReader reader) throws Exception {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
reader.readLine(); reader.readLine();
while(reader.ready()){ while (reader.ready()) {
String line; String line;
while (((line = reader.readLine()) != null) && (line.length() > 0)){ while (((line = reader.readLine()) != null) && (line.length() > 0)) {
} }
String buffer = ""; String buffer = "";
while (((line = reader.readLine()) != null) && (!line.startsWith("------WebKitFormBoundary"))){ while (((line = reader.readLine()) != null) && (!line.startsWith("------WebKitFormBoundary"))) {
buffer += line; buffer += line;
} }
list.add(buffer); list.add(buffer);
@ -44,9 +47,10 @@ public class HttpUtil{
return list; return list;
} }
public static void switchToWebSocket(HttpReader reader, HttpWriter writer) throws Exception{ public static void switchToWebSocket(HttpReader reader, HttpWriter writer) throws Exception {
String key = readWebSocketKey(reader); String key = readWebSocketKey(reader);
if (key == null) throw new IllegalArgumentException(); if (key == null)
throw new IllegalArgumentException();
writer.write("HTTP/1.1 101 Switching Protocols\n"); writer.write("HTTP/1.1 101 Switching Protocols\n");
writer.write("Connection: Upgrade\n"); writer.write("Connection: Upgrade\n");
@ -59,25 +63,28 @@ public class HttpUtil{
private static Pattern WEBSOCKET_KEY = Pattern.compile("Sec-WebSocket-Key: (.*)"); private static Pattern WEBSOCKET_KEY = Pattern.compile("Sec-WebSocket-Key: (.*)");
public static String readWebSocketKey(HttpReader reader) throws Exception{ public static String readWebSocketKey(HttpReader reader) throws Exception {
String line; String line;
String key = null; String key = null;
while(((line = reader.readLine()) != null) && (line.length() > 0)){ while (((line = reader.readLine()) != null) && (line.length() > 0)) {
if(key != null) continue; if (key != null) {
continue;
}
Matcher matcher = WEBSOCKET_KEY.matcher(line); Matcher matcher = WEBSOCKET_KEY.matcher(line);
if(matcher.matches()) key = matcher.group(1); if (matcher.matches())
key = matcher.group(1);
} }
return key; return key;
} }
private static Pattern AUTORIZATION = Pattern.compile("Authorization: Bearer (.*)"); private static Pattern AUTORIZATION = Pattern.compile("Authorization: Bearer (.*)");
public static String readAuthorization(HttpReader reader) throws Exception{ public static String readAuthorization(HttpReader reader) throws Exception {
String line; String line;
String key = null; String key = null;
while (((line = reader.readLine()) != null) && (line.length() > 0)){ while (((line = reader.readLine()) != null) && (line.length() > 0)) {
Matcher matcher = AUTORIZATION.matcher(line); Matcher matcher = AUTORIZATION.matcher(line);
if(matcher.matches()){ if (matcher.matches()) {
key = matcher.group(1); key = matcher.group(1);
break; break;
} }
@ -85,33 +92,34 @@ public class HttpUtil{
return key; return key;
} }
public static Object readJson(HttpReader reader) throws Exception{ public static Object readJson(HttpReader reader) throws Exception {
String line = ""; String line = "";
while (reader.ready()){ while (reader.ready()) {
char[] c = new char[1]; char[] c = new char[1];
reader.read(c); reader.read(c);
line += c[0]; line += c[0];
if (c[0] == '}'){ if (c[0] == '}') {
Object parse; Object parse;
try { try {
parse = new JSONParser().parse(line); parse = new JSONParser().parse(line);
if (parse != null) if (parse != null)
return parse; return parse;
}catch(Exception e){} } catch (Exception e) {
}
} }
} }
return null; return null;
} }
// I found this code on StackOverFlow !!!!! (and the write too) // I found this code on StackOverFlow !!!!! (and the write too)
public static String readWebSocket(HttpReader reader) throws Exception{ public static String readWebSocket(HttpReader reader) throws Exception {
int buffLenth = 1024; int buffLenth = 1024;
int len = 0; int len = 0;
byte[] b = new byte[buffLenth]; byte[] b = new byte[buffLenth];
// rawIn is a Socket.getInputStream(); // rawIn is a Socket.getInputStream();
while (true){ while (true) {
len = reader.read(b); len = reader.read(b);
if (len != -1){ if (len != -1) {
byte rLength = 0; byte rLength = 0;
int rMaskIndex = 2; int rMaskIndex = 2;
int rDataStart = 0; int rDataStart = 0;
@ -129,7 +137,7 @@ public class HttpUtil{
int j = 0; int j = 0;
int i = 0; int i = 0;
for (i = rMaskIndex; i < (rMaskIndex + 4); i++){ for (i = rMaskIndex; i < (rMaskIndex + 4); i++) {
masks[j] = b[i]; masks[j] = b[i];
j++; j++;
} }
@ -140,7 +148,7 @@ public class HttpUtil{
byte[] message = new byte[messLen]; byte[] message = new byte[messLen];
for (i = rDataStart, j = 0; i < len; i++, j++){ for (i = rDataStart, j = 0; i < len; i++, j++) {
message[j] = (byte) (b[i] ^ masks[j % 4]); message[j] = (byte) (b[i] ^ masks[j % 4]);
} }
@ -152,7 +160,7 @@ public class HttpUtil{
return null; return null;
} }
public static void sendWebSocket(HttpWriter writer, String message) throws Exception{ public static void sendWebSocket(HttpWriter writer, String message) throws Exception {
byte[] rawData = message.getBytes(); byte[] rawData = message.getBytes();
int frameCount = 0; int frameCount = 0;
@ -160,10 +168,10 @@ public class HttpUtil{
frame[0] = (byte) 129; frame[0] = (byte) 129;
if (rawData.length <= 125){ if (rawData.length <= 125) {
frame[1] = (byte) rawData.length; frame[1] = (byte) rawData.length;
frameCount = 2; frameCount = 2;
} else if (rawData.length >= 126 && rawData.length <= 65535){ } else if (rawData.length >= 126 && rawData.length <= 65535) {
frame[1] = (byte) 126; frame[1] = (byte) 126;
int len = rawData.length; int len = rawData.length;
frame[2] = (byte) ((len >> 8) & (byte) 255); frame[2] = (byte) ((len >> 8) & (byte) 255);
@ -188,11 +196,11 @@ public class HttpUtil{
byte[] reply = new byte[bLength]; byte[] reply = new byte[bLength];
int bLim = 0; int bLim = 0;
for (int i = 0; i < frameCount; i++){ for (int i = 0; i < frameCount; i++) {
reply[bLim] = frame[i]; reply[bLim] = frame[i];
bLim++; bLim++;
} }
for (int i = 0; i < rawData.length; i++){ for (int i = 0; i < rawData.length; i++) {
reply[bLim] = rawData[i]; reply[bLim] = rawData[i];
bLim++; bLim++;
} }
@ -201,8 +209,8 @@ public class HttpUtil{
writer.flush(); writer.flush();
} }
private static String codeMessage(int paramInt){ private static String codeMessage(int paramInt) {
switch (paramInt){ switch (paramInt) {
case 200: case 200:
return " OK"; return " OK";
case 100: case 100:
@ -280,7 +288,7 @@ public class HttpUtil{
} }
// From javax.xml.bind.DatatypeConverter // From javax.xml.bind.DatatypeConverter
private static String printBase64Binary(byte[] array){ private static String printBase64Binary(byte[] array) {
char[] arrayOfChar = new char[(array.length + 2) / 3 * 4]; char[] arrayOfChar = new char[(array.length + 2) / 3 * 4];
int i = _printBase64Binary(array, 0, array.length, arrayOfChar, 0); int i = _printBase64Binary(array, 0, array.length, arrayOfChar, 0);
assert i == arrayOfChar.length; assert i == arrayOfChar.length;
@ -288,10 +296,10 @@ public class HttpUtil{
} }
private static int _printBase64Binary(byte[] paramArrayOfbyte, int paramInt1, int paramInt2, private static int _printBase64Binary(byte[] paramArrayOfbyte, int paramInt1, int paramInt2,
char[] paramArrayOfchar, int paramInt3){ char[] paramArrayOfchar, int paramInt3) {
int i = paramInt2; int i = paramInt2;
int j; int j;
for (j = paramInt1; i >= 3; j += 3){ for (j = paramInt1; i >= 3; j += 3) {
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2); paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
paramArrayOfchar[paramInt3++] = encode( paramArrayOfchar[paramInt3++] = encode(
(paramArrayOfbyte[j] & 0x3) << 4 | paramArrayOfbyte[j + 1] >> 4 & 0xF); (paramArrayOfbyte[j] & 0x3) << 4 | paramArrayOfbyte[j + 1] >> 4 & 0xF);
@ -300,13 +308,13 @@ public class HttpUtil{
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j + 2] & 0x3F); paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j + 2] & 0x3F);
i -= 3; i -= 3;
} }
if (i == 1){ if (i == 1) {
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2); paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j] & 0x3) << 4); paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j] & 0x3) << 4);
paramArrayOfchar[paramInt3++] = '='; paramArrayOfchar[paramInt3++] = '=';
paramArrayOfchar[paramInt3++] = '='; paramArrayOfchar[paramInt3++] = '=';
} }
if (i == 2){ if (i == 2) {
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2); paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
paramArrayOfchar[paramInt3++] = encode( paramArrayOfchar[paramInt3++] = encode(
(paramArrayOfbyte[j] & 0x3) << 4 | paramArrayOfbyte[j + 1] >> 4 & 0xF); (paramArrayOfbyte[j] & 0x3) << 4 | paramArrayOfbyte[j + 1] >> 4 & 0xF);
@ -316,13 +324,13 @@ public class HttpUtil{
return paramInt3; return paramInt3;
} }
private static char encode(int paramInt){ private static char encode(int paramInt) {
return encodeMap[paramInt & 0x3F]; return encodeMap[paramInt & 0x3F];
} }
private static final char[] encodeMap = initEncodeMap(); private static final char[] encodeMap = initEncodeMap();
private static char[] initEncodeMap(){ private static char[] initEncodeMap() {
char[] arrayOfChar = new char[64]; char[] arrayOfChar = new char[64];
byte b; byte b;
for (b = 0; b < 26; b++) for (b = 0; b < 26; b++)

View file

@ -7,30 +7,30 @@ import java.io.OutputStreamWriter;
import java.net.Socket; import java.net.Socket;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
public class HttpWriter{ public class HttpWriter {
private OutputStream out; private OutputStream out;
private BufferedWriter writer; private BufferedWriter writer;
public HttpWriter(Socket socket) throws Exception{ public HttpWriter(Socket socket) throws Exception {
this.out = socket.getOutputStream(); this.out = socket.getOutputStream();
this.writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8)); this.writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
} }
public void write(byte[] buffer) throws IOException{ public void write(byte[] buffer) throws IOException {
this.out.write(buffer); this.out.write(buffer);
this.out.flush(); this.out.flush();
} }
public void write(String message) throws IOException{ public void write(String message) throws IOException {
this.writer.write(message); this.writer.write(message);
} }
public void flush() throws IOException{ public void flush() throws IOException {
this.writer.flush(); this.writer.flush();
} }
public void close() throws IOException{ public void close() throws IOException {
this.writer.close(); this.writer.close();
} }
} }

View file

@ -1,7 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
public enum RequestType {
GET, POST, OPTIONS;
}

View file

@ -7,11 +7,11 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
public @interface Route{ public @interface Route {
String path() default "^.*$"; String path() default "^.*$";
RequestType type() default RequestType.GET; String type() default "GET";
boolean needLogin() default false; boolean needLogin() default false;

View file

@ -16,7 +16,7 @@ import org.jose4j.lang.JoseException;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class Router{ public class Router {
private Map<Response, Route> responses; private Map<Response, Route> responses;
private Map<Response, Pattern> patterns; private Map<Response, Pattern> patterns;
@ -26,7 +26,7 @@ public class Router{
private String token_issuer; private String token_issuer;
private int token_expiration; private int token_expiration;
public Router(DatabaseRepository repo, String token_issuer, int token_expiration) throws Exception{ public Router(DatabaseRepository repo, String token_issuer, int token_expiration) throws Exception {
this.repo = repo; this.repo = repo;
this.token_issuer = token_issuer; this.token_issuer = token_issuer;
this.token_expiration = token_expiration; this.token_expiration = token_expiration;
@ -35,51 +35,52 @@ public class Router{
this.rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048); this.rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
} }
public DatabaseRepository getDataBase(){ public DatabaseRepository getDataBase() {
return this.repo; return this.repo;
} }
public void register(Response response){ public void register(Response response) {
try{ try {
Method method = response.getClass().getDeclaredMethod("exec", Method method = response.getClass().getDeclaredMethod("exec",
Response.class.getDeclaredMethods()[0].getParameterTypes()); Response.class.getDeclaredMethods()[0].getParameterTypes());
Route route = method.getAnnotation(Route.class); Route route = method.getAnnotation(Route.class);
this.responses.put(response, route); this.responses.put(response, route);
this.patterns.put(response, Pattern.compile(route.path())); this.patterns.put(response, Pattern.compile(route.path()));
}catch(Exception e){ } catch (Exception e) {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
} }
public void setDefault(Response response){ public void setDefault(Response response) {
this.noFileFound = response; this.noFileFound = response;
} }
public void exec(RequestType type, String path, User user, HttpReader reader, HttpWriter writer) throws Exception{ public void exec(String type, String path, User user, HttpReader reader, HttpWriter writer) throws Exception {
if(type == null) return; for (Entry<Response, Route> routes : this.responses.entrySet()) {
for(Entry<Response, Route> routes : this.responses.entrySet()){ if (routes.getValue().type().equals(type)) {
if(routes.getValue().type().equals(type)){
Matcher matcher = this.patterns.get(routes.getKey()).matcher(path); Matcher matcher = this.patterns.get(routes.getKey()).matcher(path);
if(matcher.matches()){ if (matcher.matches()) {
if(user == null && routes.getValue().needLogin()) return; if (user == null && routes.getValue().needLogin())
return;
routes.getKey().exec(matcher, user, reader, writer); routes.getKey().exec(matcher, user, reader, writer);
return; return;
} }
} }
} }
if(noFileFound != null) noFileFound.exec(null, user, reader, writer); if (noFileFound != null)
noFileFound.exec(null, user, reader, writer);
} }
public RsaJsonWebKey getWebKey(){ public RsaJsonWebKey getWebKey() {
return this.rsaJsonWebKey; return this.rsaJsonWebKey;
} }
public String getTokenIssuer(){ public String getTokenIssuer() {
return this.token_issuer; return this.token_issuer;
} }
public String createAuthUser(int id) throws JoseException{ public String createAuthUser(int id) throws JoseException {
JwtClaims claims = new JwtClaims(); JwtClaims claims = new JwtClaims();
claims.setIssuer(token_issuer); // who creates the token and signs it claims.setIssuer(token_issuer); // who creates the token and signs it
claims.setExpirationTimeMinutesInTheFuture(token_expiration); claims.setExpirationTimeMinutesInTheFuture(token_expiration);

View file

@ -2,15 +2,15 @@ package be.jeffcheasey88.peeratcode.framework;
import org.jose4j.jwt.JwtClaims; import org.jose4j.jwt.JwtClaims;
public class User{ public class User {
private int id; private int id;
public User(JwtClaims jwtClaims){ public User(JwtClaims jwtClaims) {
this.id = ((Long) jwtClaims.getClaimValue("id")).intValue(); this.id = ((Long) jwtClaims.getClaimValue("id")).intValue();
} }
public int getId(){ public int getId() {
return this.id; return this.id;
} }
} }

View file

@ -16,11 +16,7 @@ public enum DatabaseQuery {
ALL_CHAPTERS_QUERY("SELECT * FROM chapters WHERE id_chapter > 0"), ALL_CHAPTERS_QUERY("SELECT * FROM chapters WHERE id_chapter > 0"),
// GROUPS // GROUPS
ALL_GROUPS("SELECT * FROM groups"), ALL_GROUPS("SELCT * FROM groups"), INSERT_GROUP("INSERT INTO groups (name, fk_chapter, fk_puzzle) VALUES (?,?,?)"),
GET_GROUP_ID_BY_DATA("SELECT id_group FROM groups WHERE name = ? AND fk_chapter = ? AND fk_puzzle = ?"),
INSERT_GROUP("INSERT INTO groups (name, fk_chapter, fk_puzzle) VALUES (?,?,?)"),
INSERT_PLAYER_IN_GROUP("INSERT INTO containsGroups (fk_player, fk_group) VALUES (?,?)"),
LEAVE_GROUP("DELETE FROM containsGroups WHERE fk_player = ? AND fk_group = ?"),
// LEADERBOARD // LEADERBOARD
ALL_PLAYERS_FOR_LEADERBOARD( ALL_PLAYERS_FOR_LEADERBOARD(

View file

@ -16,7 +16,6 @@ import com.password4j.Hash;
import com.password4j.Password; import com.password4j.Password;
import be.jeffcheasey88.peeratcode.Configuration; import be.jeffcheasey88.peeratcode.Configuration;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.model.Badge; import be.jeffcheasey88.peeratcode.model.Badge;
import be.jeffcheasey88.peeratcode.model.Chapter; import be.jeffcheasey88.peeratcode.model.Chapter;
import be.jeffcheasey88.peeratcode.model.Completion; import be.jeffcheasey88.peeratcode.model.Completion;
@ -488,53 +487,16 @@ public class DatabaseRepository {
statement.executeUpdate(); statement.executeUpdate();
} }
public boolean insertGroup(Group group, User creator){ public boolean insertGroup(Group group) {
try { try {
ensureConnection(); ensureConnection();
PreparedStatement statement = DatabaseQuery.INSERT_GROUP.prepare(this.con); PreparedStatement statement = DatabaseQuery.INSERT_GROUP.prepare(this.con);
statement.setString(1, group.getName()); statement.setString(1, group.getName());
statement.setInt(2, group.getLinkToChapter()); statement.setInt(2, group.getLinkToChapter());
statement.setInt(3, group.getLinkToPuzzle()); statement.setInt(3, group.getLinkToPuzzle());
if(statement.executeUpdate() >= 0) return insertUserInGroup(group, creator); return statement.executeUpdate() >= 0;
} catch (Exception e){} } catch (Exception e) {
return false;
} }
private int getGroupId(Group group) throws Exception{
ensureConnection();
PreparedStatement stmt = DatabaseQuery.GET_GROUP_ID_BY_DATA.prepare(this.con);
stmt.setString(1, group.getName());
stmt.setInt(2, group.getLinkToChapter());
stmt.setInt(3, group.getLinkToPuzzle());
ResultSet result = stmt.executeQuery();
if(result.next()) return result.getInt("id_group");
throw new NullPointerException();
}
public boolean insertUserInGroup(Group group, User user){
try {
int id = getGroupId(group);
PreparedStatement stmt = DatabaseQuery.INSERT_PLAYER_IN_GROUP.prepare(this.con);
stmt.setInt(1, user.getId());
stmt.setInt(2, id);
return stmt.executeUpdate() >= 0;
}catch(Exception e){}
return false;
}
public boolean leaveGroup(Group group, User user){
try {
int id = getGroupId(group);
PreparedStatement stmt = DatabaseQuery.LEAVE_GROUP.prepare(this.con);
stmt.setInt(1, user.getId());
stmt.setInt(2, id);
return stmt.executeUpdate() >= 0;
}catch(Exception e){}
return false; return false;
} }

View file

@ -23,6 +23,7 @@ public class BadgeDetails implements Response {
} }
@Route(path = "^\\/badge\\/([0-9]+)$", needLogin = true) @Route(path = "^\\/badge\\/([0-9]+)$", needLogin = true)
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
if (matcher.groupCount() > 0) { if (matcher.groupCount() > 0) {
int badgeId = Integer.parseInt(matcher.group(1)); int badgeId = Integer.parseInt(matcher.group(1));

View file

@ -24,6 +24,7 @@ public class ChapterElement implements Response {
} }
@Route(path = "^\\/chapter\\/([0-9]+)$", needLogin = true) @Route(path = "^\\/chapter\\/([0-9]+)$", needLogin = true)
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
Chapter chapter = databaseRepo.getChapter(extractId(matcher)); Chapter chapter = databaseRepo.getChapter(extractId(matcher));
if (chapter != null) { if (chapter != null) {

View file

@ -24,6 +24,7 @@ public class ChapterList implements Response {
} }
@Route(path = "^\\/chapters$", needLogin = true) @Route(path = "^\\/chapters$", needLogin = true)
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
List<Chapter> allChapters = databaseRepo.getAllChapters(); List<Chapter> allChapters = databaseRepo.getAllChapters();
if (allChapters != null) { if (allChapters != null) {

View file

@ -28,6 +28,7 @@ public class Leaderboard implements Response {
} }
@Route(path = "^\\/leaderboard\\/?(\\d+)?$") @Route(path = "^\\/leaderboard\\/?(\\d+)?$")
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *"); HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *");
if (matcher.group(1) != null) { if (matcher.group(1) != null) {

View file

@ -1,7 +1,5 @@
package be.jeffcheasey88.peeratcode.routes; package be.jeffcheasey88.peeratcode.routes;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
@ -25,7 +23,8 @@ public class Login implements Response {
this.router = router; this.router = router;
} }
@Route(path = "^\\/login$", type = POST) @Route(path = "^\\/login$", type = "POST")
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
if (user != null) { if (user != null) {
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *"); HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");

View file

@ -23,6 +23,7 @@ public class PlayerDetails implements Response {
} }
@Route(path = "^\\/player\\/?(.+)?$", needLogin = true) @Route(path = "^\\/player\\/?(.+)?$", needLogin = true)
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
Player player; Player player;
if (matcher.group(1) != null) { if (matcher.group(1) != null) {

View file

@ -22,6 +22,7 @@ public class PuzzleElement implements Response {
} }
@Route(path = "^\\/puzzle\\/([0-9]+)$", needLogin = true) @Route(path = "^\\/puzzle\\/([0-9]+)$", needLogin = true)
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
Puzzle puzzle = databaseRepo.getPuzzle(extractId(matcher)); Puzzle puzzle = databaseRepo.getPuzzle(extractId(matcher));
if (puzzle != null) { if (puzzle != null) {

View file

@ -1,7 +1,5 @@
package be.jeffcheasey88.peeratcode.routes; package be.jeffcheasey88.peeratcode.routes;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -32,7 +30,8 @@ public class PuzzleResponse implements Response {
usersFilesPath = initUsersFilesPath; usersFilesPath = initUsersFilesPath;
} }
@Route(path = "^\\/puzzleResponse\\/([0-9]+)$", type = POST, needLogin = true) @Route(path = "^\\/puzzleResponse\\/([0-9]+)$", type = "POST")
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
if (user == null) { if (user == null) {
HttpUtil.responseHeaders(writer, 401, "Access-Control-Allow-Origin: *"); HttpUtil.responseHeaders(writer, 401, "Access-Control-Allow-Origin: *");

View file

@ -1,7 +1,5 @@
package be.jeffcheasey88.peeratcode.routes; package be.jeffcheasey88.peeratcode.routes;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -30,7 +28,8 @@ public class Register implements Response {
usersFilesPath = initUsersFilesPath; usersFilesPath = initUsersFilesPath;
} }
@Route(path = "^\\/register$", type = POST) @Route(path = "^\\/register$", type = "POST")
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
if (user != null) { if (user != null) {
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *"); HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");

View file

@ -19,6 +19,7 @@ public class Result implements Response {
} }
@Route(path = "^\\/result\\/(\\d+)$", needLogin = true) @Route(path = "^\\/result\\/(\\d+)$", needLogin = true)
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
int puzzle = Integer.parseInt(matcher.group(1)); int puzzle = Integer.parseInt(matcher.group(1));

View file

@ -1,7 +1,5 @@
package be.jeffcheasey88.peeratcode.routes.groups; package be.jeffcheasey88.peeratcode.routes.groups;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
@ -23,11 +21,12 @@ public class CreateGroup implements Response {
this.repo = repo; this.repo = repo;
} }
@Route(path = "^\\/groupCreate$", type = POST, needLogin = true) @Route(path = "^\\/groupCreate$", type = "POST", needLogin = true)
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
HttpUtil.skipHeaders(reader); HttpUtil.skipHeaders(reader);
if (this.repo.insertGroup(new Group((JSONObject) HttpUtil.readJson(reader)), user)) { if (this.repo.insertGroup(new Group((JSONObject) HttpUtil.readJson(reader)))) {
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *"); HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *");
} else { } else {
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *"); HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");

View file

@ -1,37 +0,0 @@
package be.jeffcheasey88.peeratcode.routes.groups;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
import java.util.regex.Matcher;
import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpUtil;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.model.Group;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class GroupJoin implements Response{
private DatabaseRepository repo;
public GroupJoin(DatabaseRepository repo){
this.repo = repo;
}
@Route(path = "^\\/groupJoin$", type = POST, needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *");
if (this.repo.insertUserInGroup(new Group((JSONObject) HttpUtil.readJson(reader)), user)) {
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *");
} else {
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");
}
}
}

View file

@ -22,10 +22,12 @@ public class GroupList implements Response {
} }
@Route(path = "^\\/groups$", needLogin = true) @Route(path = "^\\/groups$", needLogin = true)
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *"); HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *");
JSONArray result = new JSONArray(); JSONArray result = new JSONArray();
for(Group group : this.repo.getAllGroups()) result.add(group.toJson()); for (Group group : this.repo.getAllGroups())
result.add(group.toJson());
writer.write(result.toJSONString()); writer.write(result.toJSONString());
} }

View file

@ -1,37 +0,0 @@
package be.jeffcheasey88.peeratcode.routes.groups;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
import java.util.regex.Matcher;
import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpUtil;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.model.Group;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class GroupQuit implements Response{
private DatabaseRepository repo;
public GroupQuit(DatabaseRepository repo){
this.repo = repo;
}
@Route(path = "^\\/groupQuit$", type = POST, needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *");
if (this.repo.leaveGroup(new Group((JSONObject) HttpUtil.readJson(reader)), user)) {
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *");
} else {
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");
}
}
}