Merge remote-tracking branch 'origin/getPuzzleResponse'
This commit is contained in:
commit
688ff3cedd
4 changed files with 183 additions and 70 deletions
|
@ -10,7 +10,6 @@ import java.util.regex.Pattern;
|
|||
|
||||
import javax.net.ssl.SSLServerSocket;
|
||||
import javax.net.ssl.SSLServerSocketFactory;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
|
||||
import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
|
||||
import org.jose4j.jwk.JsonWebKey;
|
||||
|
@ -31,6 +30,7 @@ import be.jeffcheasey88.peeratcode.routes.ChapterElement;
|
|||
import be.jeffcheasey88.peeratcode.routes.ChapterList;
|
||||
import be.jeffcheasey88.peeratcode.routes.Login;
|
||||
import be.jeffcheasey88.peeratcode.routes.PuzzleElement;
|
||||
import be.jeffcheasey88.peeratcode.routes.PuzzleResponse;
|
||||
import be.jeffcheasey88.peeratcode.routes.Register;
|
||||
import be.jeffcheasey88.peeratcode.routes.Result;
|
||||
import be.jeffcheasey88.peeratcode.webserver.Client;
|
||||
|
@ -42,78 +42,10 @@ import be.jeffcheasey88.peeratcode.webserver.Router;
|
|||
import be.jeffcheasey88.peeratcode.webserver.User;
|
||||
|
||||
public class Main {
|
||||
// Define SSL Protocol parameters
|
||||
public static void main(String[] args) throws Exception {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Configuration config = new Configuration("config.txt");
|
||||
config.load();
|
||||
|
||||
/*try
|
||||
{
|
||||
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("username","USERNAME");
|
||||
|
||||
JsonWebSignature jws = new JsonWebSignature();
|
||||
|
||||
jws.setPayload(claims.toJson());
|
||||
|
||||
jws.setKey(rsaJsonWebKey.getPrivateKey());
|
||||
|
||||
jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId());
|
||||
|
||||
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
|
||||
|
||||
String jwt = jws.getCompactSerialization();
|
||||
|
||||
System.out.println("jwt token = " + jwt);
|
||||
|
||||
|
||||
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
|
||||
.setRequireExpirationTime() // the JWT must have an expiration time
|
||||
.setAllowedClockSkewInSeconds(30) // allow some leeway in validating time based claims to account for clock skew
|
||||
.setRequireSubject() // the JWT must have a subject claim
|
||||
.setExpectedIssuer("Issuer") // whom the JWT needs to have been issued by
|
||||
.setExpectedAudience("Audience") // to whom the JWT is intended for
|
||||
.setVerificationKey(rsaJsonWebKey.getKey()) // verify the signature with the public key
|
||||
.setJwsAlgorithmConstraints( // only allow the expected signature algorithm(s) in the given context
|
||||
ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256) // which is only RS256 here
|
||||
.build(); // create the JwtConsumer instance
|
||||
|
||||
// Validate the JWT and process it to the Claims
|
||||
JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);
|
||||
System.out.println("JWT validation = " + jwtClaims);
|
||||
}
|
||||
catch (InvalidJwtException e)
|
||||
{
|
||||
// InvalidJwtException will be thrown, if the JWT failed processing or validation in anyway.
|
||||
// Hopefully with meaningful explanations(s) about what went wrong.
|
||||
System.out.println("Invalid JWT! " + e);
|
||||
|
||||
// Programmatic access to (some) specific reasons for JWT invalidity is also possible
|
||||
// should you want different error handling behavior for certain conditions.
|
||||
|
||||
// Whether or not the JWT has expired being one common reason for invalidity
|
||||
if (e.hasExpired())
|
||||
{
|
||||
System.out.println("JWT expired");
|
||||
}
|
||||
|
||||
// Or maybe the audience was invalid
|
||||
if (e.hasErrorCode(ErrorCodes.AUDIENCE_INVALID))
|
||||
{
|
||||
System.out.println("JWT had wrong audience");
|
||||
}
|
||||
} catch (JoseException e) {
|
||||
e.printStackTrace();
|
||||
}*/
|
||||
|
||||
|
||||
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||
|
||||
Router router = new Router();
|
||||
|
@ -146,6 +78,7 @@ public class Main {
|
|||
router.register(new Register(repo));
|
||||
router.register(new Login(repo));
|
||||
router.register(new Result(repo));
|
||||
router.register(new PuzzleResponse(repo));
|
||||
}
|
||||
|
||||
private static void startWebServer(Configuration config, Router router) throws IOException {
|
||||
|
|
|
@ -24,6 +24,12 @@ public class DatabaseRepository {
|
|||
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 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_SCORE_MAX = "SELECT score_max FROM puzzles WHERE id_puzzle=?";
|
||||
private static final String GET_PLAYER_ID_BY_PSEUDO = "SELECT id_player FROM players WHERE pseudo=?";
|
||||
private static final String GET_PUZZLE_NB_TRIES_AND_SCORE_BY_PLAYER = "SELECT tries, score FROM completions WHERE fk_puzzle = ? AND fk_player = ?";
|
||||
private static final String INSERT_COMPLETION = "INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)";
|
||||
private static final String UPDATE_COMPLETION = "UPDATE completions SET tries = ?, code = ?, filename = ?, score = ?";
|
||||
|
||||
private Connection con;
|
||||
private Configuration config;
|
||||
|
@ -228,4 +234,91 @@ public class DatabaseRepository {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public byte[] getPuzzleSolution(int puzzleId) {
|
||||
try {
|
||||
PreparedStatement puzzleStmt = con.prepareStatement(GET_PUZZLE_SOLUTION);
|
||||
puzzleStmt.setInt(1, puzzleId);
|
||||
ResultSet result = puzzleStmt.executeQuery();
|
||||
if (result.next()) {
|
||||
return result.getBytes("soluce");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public int insertOrUpdatePuzzleResponse(int puzzleId, String pseudo, String fileName, byte[] code) {
|
||||
try {
|
||||
ensureConnection();
|
||||
int[] triesAndScore = getPuzzleNbTriesAndScore(puzzleId, pseudo);
|
||||
int playerId = getPlayerIdByPseudo(pseudo);
|
||||
int puzzleScoreMax = getPuzzleScoreMax(puzzleId);
|
||||
if (triesAndScore[0] < 0) {
|
||||
// Insert completions
|
||||
PreparedStatement statement = con.prepareStatement(INSERT_COMPLETION);
|
||||
statement.setInt(1, puzzleId);
|
||||
statement.setInt(2, playerId);
|
||||
statement.setInt(3, 0);
|
||||
statement.setBytes(4, code);
|
||||
statement.setString(5, fileName);
|
||||
statement.setInt(6, puzzleScoreMax);
|
||||
return puzzleScoreMax;
|
||||
} else {
|
||||
// Update completions
|
||||
int score = puzzleScoreMax * (((triesAndScore[0]-1)*10)/100);
|
||||
PreparedStatement statement = con.prepareStatement(UPDATE_COMPLETION);
|
||||
statement.setInt(1, triesAndScore[0]+1);
|
||||
statement.setBytes(2, code);
|
||||
statement.setString(3, fileName);
|
||||
statement.setInt(4, score);
|
||||
return score;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public int getPuzzleScoreMax(int puzzleId) {
|
||||
try {
|
||||
PreparedStatement puzzleStmt = con.prepareStatement(GET_PUZZLE_SCORE_MAX);
|
||||
puzzleStmt.setInt(1, puzzleId);
|
||||
ResultSet result = puzzleStmt.executeQuery();
|
||||
if (result.next()) {
|
||||
return result.getInt("score_max");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public int[] getPuzzleNbTriesAndScore(int puzzleId, String pseudo) {
|
||||
try {
|
||||
PreparedStatement puzzleStmt = con.prepareStatement(GET_PUZZLE_NB_TRIES_AND_SCORE_BY_PLAYER);
|
||||
puzzleStmt.setInt(1, puzzleId);
|
||||
ResultSet result = puzzleStmt.executeQuery();
|
||||
int[] res = new int[2];
|
||||
if (result.next()) {
|
||||
res[0] = result.getInt("tries");
|
||||
res[1] = result.getInt("score");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private int getPlayerIdByPseudo(String pseudo) {
|
||||
try {
|
||||
PreparedStatement puzzleStmt = con.prepareStatement(GET_PLAYER_ID_BY_PSEUDO);
|
||||
puzzleStmt.setString(1, pseudo);
|
||||
ResultSet result = puzzleStmt.executeQuery();
|
||||
if (result.next()) {
|
||||
return result.getInt("id_player");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
79
src/be/jeffcheasey88/peeratcode/routes/PuzzleResponse.java
Normal file
79
src/be/jeffcheasey88/peeratcode/routes/PuzzleResponse.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
package be.jeffcheasey88.peeratcode.routes;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
|
||||
import be.jeffcheasey88.peeratcode.webserver.HttpReader;
|
||||
import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
|
||||
import be.jeffcheasey88.peeratcode.webserver.HttpWriter;
|
||||
import be.jeffcheasey88.peeratcode.webserver.Response;
|
||||
|
||||
public class PuzzleResponse implements Response {
|
||||
private final DatabaseRepository databaseRepo;
|
||||
|
||||
public PuzzleResponse(DatabaseRepository databaseRepo) {
|
||||
this.databaseRepo = databaseRepo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exec(Matcher matcher, HttpReader reader, HttpWriter writer) throws Exception {
|
||||
HttpUtil.skipHeaders(reader);
|
||||
|
||||
int puzzleId = Integer.parseInt(matcher.group(1));
|
||||
byte[] response;
|
||||
byte[] fileName;
|
||||
byte[] sourceCode;
|
||||
|
||||
// Response
|
||||
int hSize = reader.readInt();
|
||||
response = new byte[hSize];
|
||||
if (hSize == reader.read(response)) {
|
||||
// File Name
|
||||
hSize = reader.readInt();
|
||||
fileName = new byte[hSize];
|
||||
if (hSize == reader.read(fileName)) {
|
||||
// Source Code
|
||||
hSize = reader.readInt();
|
||||
sourceCode = new byte[hSize];
|
||||
if (hSize == reader.read(sourceCode)) {
|
||||
int score = databaseRepo.insertOrUpdatePuzzleResponse(puzzleId, "Pseudo", fileName.toString(), sourceCode);
|
||||
if (Arrays.equals(response, databaseRepo.getPuzzleSolution(puzzleId))) {
|
||||
HttpUtil.responseHeaders(writer, 200,
|
||||
"Access-Control-Allow-Origin: *",
|
||||
"Content-Type: application/json");
|
||||
JSONObject responseJSON = new JSONObject();
|
||||
responseJSON.put("id", puzzleId);
|
||||
responseJSON.put("score", score);
|
||||
writer.write(responseJSON.toJSONString());
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} else {
|
||||
HttpUtil.responseHeaders(writer, 406, "Access-Control-Allow-Origin: *");
|
||||
}
|
||||
}
|
||||
else {
|
||||
HttpUtil.responseHeaders(writer, 400, "Access-Control-Allow-Origin: *");
|
||||
}
|
||||
}
|
||||
else {
|
||||
HttpUtil.responseHeaders(writer, 400, "Access-Control-Allow-Origin: *");
|
||||
}
|
||||
|
||||
}
|
||||
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pattern getPattern() {
|
||||
return Pattern.compile("^\\/puzzleResponse\\/([0-9]+)$");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "POST";
|
||||
}
|
||||
}
|
|
@ -38,4 +38,12 @@ public class HttpReader {
|
|||
return this.reader.ready();
|
||||
}
|
||||
|
||||
public int readInt() throws Exception{
|
||||
int result = 0;
|
||||
result+=this.in.read() << 24;
|
||||
result+=this.in.read() << 16;
|
||||
result+=this.in.read() << 8;
|
||||
result+=this.in.read();
|
||||
return result;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue