JWT refractor
This commit is contained in:
parent
c915a96535
commit
64a88f7282
9 changed files with 142 additions and 43 deletions
|
@ -48,7 +48,7 @@ public class Main {
|
||||||
|
|
||||||
Class.forName("com.mysql.cj.jdbc.Driver");
|
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||||
|
|
||||||
Router router = new Router();
|
Router router = new Router(new DatabaseRepository(config));
|
||||||
|
|
||||||
router.setDefault(new Response(){
|
router.setDefault(new Response(){
|
||||||
|
|
||||||
|
@ -66,19 +66,19 @@ public class Main {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
initRoutes(router, new DatabaseRepository(config));
|
initRoutes(router);
|
||||||
|
|
||||||
startWebServer(config, router);
|
startWebServer(config, router);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void initRoutes(Router router, DatabaseRepository repo) {
|
private static void initRoutes(Router router) {
|
||||||
router.register(new ChapterElement(repo));
|
router.register(new ChapterElement(router.getDataBase()));
|
||||||
router.register(new ChapterList(repo));
|
router.register(new ChapterList(router.getDataBase()));
|
||||||
router.register(new PuzzleElement(repo));
|
router.register(new PuzzleElement(router.getDataBase()));
|
||||||
router.register(new Register(repo));
|
router.register(new Register(router.getDataBase(), router));
|
||||||
router.register(new Login(repo));
|
router.register(new Login(router.getDataBase(), router));
|
||||||
router.register(new Result(repo));
|
router.register(new Result(router.getDataBase()));
|
||||||
router.register(new PuzzleResponse(repo));
|
router.register(new PuzzleResponse(router.getDataBase()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void startWebServer(Configuration config, Router router) throws IOException {
|
private static void startWebServer(Configuration config, Router router) throws IOException {
|
||||||
|
|
45
src/be/jeffcheasey88/peeratcode/model/Player.java
Normal file
45
src/be/jeffcheasey88/peeratcode/model/Player.java
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
package be.jeffcheasey88.peeratcode.model;
|
||||||
|
|
||||||
|
public class Player {
|
||||||
|
|
||||||
|
private String pseudo;
|
||||||
|
private String email;
|
||||||
|
private String firstname;
|
||||||
|
private String lastname;
|
||||||
|
private String description;
|
||||||
|
private String sgroup;
|
||||||
|
|
||||||
|
public Player(String pseudo, String email, String firstname, String lastname, String description, String sgroup){
|
||||||
|
this.pseudo = pseudo;
|
||||||
|
this.email = email;
|
||||||
|
this.firstname = firstname;
|
||||||
|
this.lastname = lastname;
|
||||||
|
this.description = description;
|
||||||
|
this.sgroup = sgroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPseudo(){
|
||||||
|
return this.pseudo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail(){
|
||||||
|
return this.email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstname(){
|
||||||
|
return this.firstname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastname(){
|
||||||
|
return this.lastname;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription(){
|
||||||
|
return this.description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGroup(){
|
||||||
|
return this.sgroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,19 +1,21 @@
|
||||||
package be.jeffcheasey88.peeratcode.repository;
|
package be.jeffcheasey88.peeratcode.repository;
|
||||||
|
|
||||||
import be.jeffcheasey88.peeratcode.Configuration;
|
|
||||||
import be.jeffcheasey88.peeratcode.model.Chapter;
|
|
||||||
import be.jeffcheasey88.peeratcode.model.Puzzle;
|
|
||||||
import com.password4j.Hash;
|
|
||||||
import com.password4j.Password;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.password4j.Hash;
|
||||||
|
import com.password4j.Password;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.Configuration;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Chapter;
|
||||||
|
import be.jeffcheasey88.peeratcode.model.Puzzle;
|
||||||
|
|
||||||
public class DatabaseRepository {
|
public class DatabaseRepository {
|
||||||
private static final String SPECIFIC_PUZZLE_QUERY = "SELECT * FROM puzzles WHERE id_puzzle = ?";
|
private static final String SPECIFIC_PUZZLE_QUERY = "SELECT * FROM puzzles WHERE id_puzzle = ?";
|
||||||
private static final String SPECIFIC_CHAPTER_QUERY = "SELECT * FROM chapters WHERE id_chapter = ?";
|
private static final String SPECIFIC_CHAPTER_QUERY = "SELECT * FROM chapters WHERE id_chapter = ?";
|
||||||
|
@ -22,7 +24,7 @@ public class DatabaseRepository {
|
||||||
private static final String CHECK_PSEUDO_AVAILABLE_QUERY = "SELECT * FROM players WHERE pseudo = ?";
|
private static final String CHECK_PSEUDO_AVAILABLE_QUERY = "SELECT * FROM players WHERE pseudo = ?";
|
||||||
private static final String CHECK_EMAIL_AVAILABLE_QUERY = "SELECT * FROM players WHERE email = ?";
|
private static final String CHECK_EMAIL_AVAILABLE_QUERY = "SELECT * FROM players WHERE email = ?";
|
||||||
private static final String REGISTER_QUERY = "INSERT INTO players (pseudo, email, passwd, firstname, lastname, description, sgroup, avatar) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
|
private static final String REGISTER_QUERY = "INSERT INTO players (pseudo, email, passwd, firstname, lastname, description, sgroup, avatar) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
private static final String CHECK_PASSWORD = "SELECT passwd FROM players WHERE pseudo=?";
|
private static final String CHECK_PASSWORD = "SELECT id_player, passwd FROM players WHERE pseudo=?";
|
||||||
private static final String SCORE = "SELECT score FROM completions WHERE fk_player = ? AND fk_puzzle = ?";
|
private static final String SCORE = "SELECT score FROM completions WHERE fk_player = ? AND fk_puzzle = ?";
|
||||||
private static final String GET_PUZZLE_SOLUTION = "SELECT soluce FROM puzzles WHERE id_puzzle=?";
|
private static final String GET_PUZZLE_SOLUTION = "SELECT soluce FROM puzzles WHERE id_puzzle=?";
|
||||||
private static final String GET_PUZZLE_SCORE_MAX = "SELECT score_max FROM puzzles WHERE id_puzzle=?";
|
private static final String GET_PUZZLE_SCORE_MAX = "SELECT score_max FROM puzzles WHERE id_puzzle=?";
|
||||||
|
@ -192,11 +194,11 @@ public class DatabaseRepository {
|
||||||
* @param avatar The avatar of the user
|
* @param avatar The avatar of the user
|
||||||
* @return True if the user was registered, false if an error occurred
|
* @return True if the user was registered, false if an error occurred
|
||||||
*/
|
*/
|
||||||
public boolean register(String pseudo, String email, String password, String firstname, String lastname, String description, String sgroup, String avatar) {
|
public int register(String pseudo, String email, String password, String firstname, String lastname, String description, String sgroup, String avatar) {
|
||||||
Hash hash = Password.hash(password).withArgon2();
|
Hash hash = Password.hash(password).withArgon2();
|
||||||
try {
|
try {
|
||||||
ensureConnection();
|
ensureConnection();
|
||||||
PreparedStatement statement = con.prepareStatement(REGISTER_QUERY);
|
PreparedStatement statement = con.prepareStatement(REGISTER_QUERY, Statement.RETURN_GENERATED_KEYS);
|
||||||
statement.setString(1, pseudo);
|
statement.setString(1, pseudo);
|
||||||
statement.setString(2, email);
|
statement.setString(2, email);
|
||||||
statement.setString(3, hash.getResult());
|
statement.setString(3, hash.getResult());
|
||||||
|
@ -205,11 +207,14 @@ public class DatabaseRepository {
|
||||||
statement.setString(6, description);
|
statement.setString(6, description);
|
||||||
statement.setString(7, sgroup);
|
statement.setString(7, sgroup);
|
||||||
statement.setString(8, avatar);
|
statement.setString(8, avatar);
|
||||||
return statement.executeUpdate() == 1;
|
if(statement.executeUpdate() == 1){
|
||||||
|
ResultSet inserted = statement.getGeneratedKeys();
|
||||||
|
if(inserted.next()) return inserted.getInt("id_player");
|
||||||
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -217,9 +222,9 @@ public class DatabaseRepository {
|
||||||
*
|
*
|
||||||
* @param username The username of the user
|
* @param username The username of the user
|
||||||
* @param password The password of the user
|
* @param password The password of the user
|
||||||
* @return True if the user's information are correct, false otherwise (or if an error occurred)
|
* @return id the id of the user, -1 if not login successefuly
|
||||||
*/
|
*/
|
||||||
public boolean login(String username, String password) {
|
public int login(String username, String password) {
|
||||||
try {
|
try {
|
||||||
ensureConnection();
|
ensureConnection();
|
||||||
PreparedStatement statement = con.prepareStatement(CHECK_PASSWORD);
|
PreparedStatement statement = con.prepareStatement(CHECK_PASSWORD);
|
||||||
|
@ -227,12 +232,11 @@ public class DatabaseRepository {
|
||||||
ResultSet result = statement.executeQuery();
|
ResultSet result = statement.executeQuery();
|
||||||
if (result.next()) {
|
if (result.next()) {
|
||||||
String hashedPassword = result.getString("passwd");
|
String hashedPassword = result.getString("passwd");
|
||||||
return Password.check(password, hashedPassword).withArgon2();
|
if(Password.check(password, hashedPassword).withArgon2()) return result.getInt("id_player");
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getPuzzleSolution(int puzzleId) {
|
public byte[] getPuzzleSolution(int puzzleId) {
|
||||||
|
|
|
@ -3,6 +3,10 @@ package be.jeffcheasey88.peeratcode.routes;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.jose4j.jwk.RsaJsonWebKey;
|
||||||
|
import org.jose4j.jws.AlgorithmIdentifiers;
|
||||||
|
import org.jose4j.jws.JsonWebSignature;
|
||||||
|
import org.jose4j.jwt.JwtClaims;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
|
|
||||||
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
@ -10,14 +14,17 @@ import be.jeffcheasey88.peeratcode.webserver.HttpReader;
|
||||||
import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
|
import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
|
||||||
import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
|
import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
|
||||||
import be.jeffcheasey88.peeratcode.webserver.Response;
|
import be.jeffcheasey88.peeratcode.webserver.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.webserver.Router;
|
||||||
import be.jeffcheasey88.peeratcode.webserver.User;
|
import be.jeffcheasey88.peeratcode.webserver.User;
|
||||||
|
|
||||||
public class Login implements Response {
|
public class Login implements Response {
|
||||||
|
|
||||||
private final DatabaseRepository databaseRepo;
|
private DatabaseRepository databaseRepo;
|
||||||
|
private Router router;
|
||||||
|
|
||||||
public Login(DatabaseRepository databaseRepo) {
|
public Login(DatabaseRepository databaseRepo, Router router){
|
||||||
this.databaseRepo = databaseRepo;
|
this.databaseRepo = databaseRepo;
|
||||||
|
this.router = router;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -27,8 +34,11 @@ public class Login implements Response {
|
||||||
if (informations != null) {
|
if (informations != null) {
|
||||||
String pseudo = (String) informations.get("pseudo");
|
String pseudo = (String) informations.get("pseudo");
|
||||||
String password = (String) informations.get("passwd");
|
String password = (String) informations.get("passwd");
|
||||||
if (databaseRepo.login(pseudo, password)) {
|
int id;
|
||||||
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *");
|
if ((id = databaseRepo.login(pseudo, password)) >= 0){
|
||||||
|
HttpUtil.responseHeaders(writer, 200,
|
||||||
|
"Access-Control-Allow-Origin: *",
|
||||||
|
"Authorization: Bearer "+this.router.createAuthUser(id));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,12 @@ public class PuzzleResponse implements Response {
|
||||||
|
|
||||||
@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.skipHeaders(reader);
|
if(user == null){
|
||||||
|
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpUtil.skipHeaders(reader);
|
||||||
int puzzleId = Integer.parseInt(matcher.group(1));
|
int puzzleId = Integer.parseInt(matcher.group(1));
|
||||||
byte[] response;
|
byte[] response;
|
||||||
byte[] fileName;
|
byte[] fileName;
|
||||||
|
|
|
@ -10,14 +10,17 @@ import be.jeffcheasey88.peeratcode.webserver.HttpReader;
|
||||||
import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
|
import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
|
||||||
import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
|
import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
|
||||||
import be.jeffcheasey88.peeratcode.webserver.Response;
|
import be.jeffcheasey88.peeratcode.webserver.Response;
|
||||||
|
import be.jeffcheasey88.peeratcode.webserver.Router;
|
||||||
import be.jeffcheasey88.peeratcode.webserver.User;
|
import be.jeffcheasey88.peeratcode.webserver.User;
|
||||||
|
|
||||||
public class Register implements Response {
|
public class Register implements Response {
|
||||||
|
|
||||||
private final DatabaseRepository databaseRepo;
|
private DatabaseRepository databaseRepo;
|
||||||
|
private Router router;
|
||||||
|
|
||||||
public Register(DatabaseRepository databaseRepo) {
|
public Register(DatabaseRepository databaseRepo, Router router) {
|
||||||
this.databaseRepo = databaseRepo;
|
this.databaseRepo = databaseRepo;
|
||||||
|
this.router = router;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,8 +48,11 @@ public class Register implements Response {
|
||||||
boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo);
|
boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo);
|
||||||
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
|
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
|
||||||
if (pseudoAvailable && emailAvailable) {
|
if (pseudoAvailable && emailAvailable) {
|
||||||
if (databaseRepo.register(pseudo, email, password, firstname, lastname, description, group, avatar)){
|
int id;
|
||||||
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *");
|
if ((id = databaseRepo.register(pseudo, email, password, firstname, lastname, description, group, avatar)) >= 0){
|
||||||
|
HttpUtil.responseHeaders(writer, 200,
|
||||||
|
"Access-Control-Allow-Origin: *",
|
||||||
|
"Authorization: Bearer "+this.router.createAuthUser(id));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,9 +20,14 @@ public class Result implements Response{
|
||||||
|
|
||||||
@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 {
|
||||||
|
if(user == null){
|
||||||
|
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int puzzle = Integer.parseInt(matcher.group(1));
|
int puzzle = Integer.parseInt(matcher.group(1));
|
||||||
|
|
||||||
int score = this.repo.getScore(0, puzzle);
|
int score = this.repo.getScore(user.getId(), puzzle);
|
||||||
if(score < 0) {
|
if(score < 0) {
|
||||||
HttpUtil.responseHeaders(writer, 425, "Access-Control-Allow-Origin: *");
|
HttpUtil.responseHeaders(writer, 425, "Access-Control-Allow-Origin: *");
|
||||||
}else{
|
}else{
|
||||||
|
|
|
@ -6,18 +6,30 @@ import java.util.regex.Matcher;
|
||||||
|
|
||||||
import org.jose4j.jwk.RsaJsonWebKey;
|
import org.jose4j.jwk.RsaJsonWebKey;
|
||||||
import org.jose4j.jwk.RsaJwkGenerator;
|
import org.jose4j.jwk.RsaJwkGenerator;
|
||||||
|
import org.jose4j.jws.AlgorithmIdentifiers;
|
||||||
|
import org.jose4j.jws.JsonWebSignature;
|
||||||
|
import org.jose4j.jwt.JwtClaims;
|
||||||
|
import org.jose4j.lang.JoseException;
|
||||||
|
|
||||||
|
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||||
|
|
||||||
public class Router{
|
public class Router{
|
||||||
|
|
||||||
private List<Response> responses;
|
private List<Response> responses;
|
||||||
private Response noFileFound;
|
private Response noFileFound;
|
||||||
private RsaJsonWebKey rsaJsonWebKey;
|
private RsaJsonWebKey rsaJsonWebKey;
|
||||||
|
private DatabaseRepository repo;
|
||||||
|
|
||||||
public Router() throws Exception{
|
public Router(DatabaseRepository repo) throws Exception{
|
||||||
|
this.repo = repo;
|
||||||
this.responses = new ArrayList<>();
|
this.responses = new ArrayList<>();
|
||||||
this.rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
|
this.rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DatabaseRepository getDataBase(){
|
||||||
|
return this.repo;
|
||||||
|
}
|
||||||
|
|
||||||
public void register(Response response){
|
public void register(Response response){
|
||||||
this.responses.add(response);
|
this.responses.add(response);
|
||||||
}
|
}
|
||||||
|
@ -42,4 +54,23 @@ public class Router{
|
||||||
public RsaJsonWebKey getWebKey(){
|
public RsaJsonWebKey getWebKey(){
|
||||||
return this.rsaJsonWebKey;
|
return this.rsaJsonWebKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String createAuthUser(int id) throws JoseException{
|
||||||
|
JwtClaims claims = new JwtClaims();
|
||||||
|
claims.setIssuer("Issuer"); // who creates the token and signs it
|
||||||
|
claims.setAudience("Audience"); // to whom the token is intended to be sent
|
||||||
|
claims.setExpirationTimeMinutesInTheFuture(10); // time when the token will expire (10 minutes from now)
|
||||||
|
claims.setGeneratedJwtId(); // a unique identifier for the token
|
||||||
|
claims.setIssuedAtToNow(); // when the token was issued/created (now)
|
||||||
|
claims.setNotBeforeMinutesInThePast(2); // time before which the token is not yet valid (2 minutes ago)
|
||||||
|
|
||||||
|
claims.setClaim("id", id);
|
||||||
|
|
||||||
|
JsonWebSignature jws = new JsonWebSignature();
|
||||||
|
jws.setPayload(claims.toJson());
|
||||||
|
jws.setKey(rsaJsonWebKey.getPrivateKey());
|
||||||
|
jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId());
|
||||||
|
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
|
||||||
|
return jws.getCompactSerialization();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -4,18 +4,12 @@ import org.jose4j.jwt.JwtClaims;
|
||||||
|
|
||||||
public class User {
|
public class User {
|
||||||
|
|
||||||
private String username;
|
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
public User(JwtClaims jwtClaims){
|
public User(JwtClaims jwtClaims){
|
||||||
this.username = (String) jwtClaims.getClaimValue("username");
|
|
||||||
this.id = (int) jwtClaims.getClaimValue("id");
|
this.id = (int) jwtClaims.getClaimValue("id");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername(){
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId(){
|
public int getId(){
|
||||||
return this.id;
|
return this.id;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue