Compare commits

..

2 commits

16 changed files with 203 additions and 84 deletions

Binary file not shown.

View file

@ -51,6 +51,7 @@ import dev.peerat.backend.routes.users.ProfileSettings;
import dev.peerat.backend.routes.users.Register;
import dev.peerat.backend.utils.Mail;
import dev.peerat.framework.Context;
import dev.peerat.framework.DependencyInjector;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Locker;
@ -177,44 +178,18 @@ public class Main{
}
private static void initRoutes(Router<PeerAtUser> router, DatabaseRepository repo, Configuration config) throws Exception{
Map<String, Integer> playersWaiting = new HashMap<>();
Mail mail = config.getMail();
Locker<Group> groupLock = new Locker<>();
Locker<Completion> leaderboard = new Locker<>();
if(config.isProduction())
router.
register(new Register(repo, playersWaiting, mail)).
register(new MailConfirmation(repo, router, config.getUsersFiles(), config.getGitToken(), playersWaiting, mail));
router.
register(new Login(repo, router)).
register(new ProfileSettings(repo)).
register(new ChangePassword(repo)).
// register(new ForgotPassword(router, repo, mail)).
register(new DynamicLogs(router.getLogger(), repo)).
register(new ExceptionLogs(router.getExceptionLogger())).
register(new WebHookLeaderboard(leaderboard)).
register(new ChapterElement(repo)).
register(new ChapterList(repo)).
register(new PuzzleElement(repo)).
register(new Result(repo)).
register(new Leaderboard(repo)).
register(new PlayerDetails(repo)).
register(new BadgeDetails(repo)).
register(new DynamicLeaderboard(repo, leaderboard)).
register(new PuzzleResponse(repo, config.getUsersFiles(), leaderboard)).
register(new GroupCreate(repo, groupLock, config.getGroupJoinMinutes())).
register(new GroupList(repo)).
register(new GroupJoin(repo, config.getGroupJoinMinutes(), config.getGroupQuitMinutes(), leaderboard)).
register(new GroupQuit(repo, config.getGroupJoinMinutes(), leaderboard))
.register(new Swagger(new RouteExtracter(router),config.getTokenIssuer()));
router.registerPackages(new DependencyInjector()
.of(repo, router, config.getMail(), new RouteExtracter(router))
.of("waitting", new HashMap<>())
.of("leaderboard", new Locker<>())
.of("log", router.getLogger())
.of("exception", router.getExceptionLogger())
.of("groups", new Locker<>())
.of("groupDelay", config.getGroupJoinMinutes())
.of("waitTime", config.getGroupQuitMinutes())
.of("usersFiles", config.getUsersFiles())
.of("gitToken", config.getGitToken())
.of("issuer", config.getTokenIssuer()));
// Bot bot = new Bot(config, repo, groupLock);
// bot.start();

View file

@ -8,7 +8,9 @@ import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
@ -32,6 +34,56 @@ public class DatabaseRepository {
public DatabaseRepository(Configuration config) {
this.config = config;
}
public void hotfix() throws Exception{
ensureConnection();
PreparedStatement stmt = con.prepareStatement("SELECT c.*, g.* FROM completions c JOIN puzzles p ON c.fk_puzzle = p.id_puzzle JOIN containsGroups cg ON cg.fk_player = c.fk_player JOIN groups g ON g.id_group = cg.fk_group WHERE g.fk_chapter = 12 AND p.fk_chapter = 12;");
ResultSet results = stmt.executeQuery();
List<Completionz> list = new ArrayList<>();
while(results.next()){
Completionz complete = new Completionz(results);
list.add(complete);
}
Map<Integer, Map<Integer, Completionz>> map = new HashMap<>();
for(Completionz comp : list){
Map<Integer,Completionz> puz = map.get(comp.puzzle);
if(puz == null){
puz = new HashMap<>();
map.put(comp.puzzle, puz);
}
Completionz c = puz.get(comp.groups);
if(c == null){
puz.put(comp.groups, comp);
}else{
if(comp.score >= c.score){
puz.put(comp.groups, comp);
System.out.println("remove compl "+c.id);
}
}
}
}
private static class Completionz{
public int id;
public int puzzle;
public int player;
public int tries;
public int score;
public int groups;
public Completionz(ResultSet result) throws Exception{
id = result.getInt("id_completion");
puzzle = result.getInt("fk_puzzle");
player = result.getInt("fk_player");
tries = result.getInt("tries");
score = result.getInt("score");
groups = result.getInt("id_group");
System.out.println(id);
}
}
private void ensureConnection() throws SQLException {
if (con == null || (!con.isValid(5))) {

View file

@ -8,6 +8,7 @@ import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Locker;
import dev.peerat.framework.Locker.Key;
import dev.peerat.framework.Route;
@ -16,7 +17,7 @@ public class DynamicLeaderboard extends Leaderboard{
private Locker<Completion> locker;
public DynamicLeaderboard(DatabaseRepository databaseRepo, Locker<Completion> locker){
public DynamicLeaderboard(DatabaseRepository databaseRepo, @Injection("leaderboard") Locker<Completion> locker){
super(databaseRepo);
this.locker = locker;
}

View file

@ -1,6 +1,5 @@
package dev.peerat.backend.routes;
import java.util.Base64;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;

View file

@ -22,6 +22,7 @@ import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Locker;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
@ -33,7 +34,7 @@ public class PuzzleResponse implements Response {
private final Locker<Completion> leaderboard;
public PuzzleResponse(DatabaseRepository databaseRepo, String initUsersFilesPath, Locker<Completion> locker){
public PuzzleResponse(DatabaseRepository databaseRepo, @Injection("usersFiles") String initUsersFilesPath, @Injection("leaderboard") Locker<Completion> locker){
this.databaseRepo = databaseRepo;
usersFilesPath = initUsersFilesPath;
this.leaderboard = locker;

View file

@ -6,6 +6,7 @@ import dev.peerat.backend.bonus.extract.RouteExtracter;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
@ -13,7 +14,7 @@ public class Swagger implements Response{
private String json;
public Swagger(RouteExtracter extracter, String host){
public Swagger(RouteExtracter extracter, @Injection("issuer") String host){
try{
this.json = extracter.swagger(host).toString();
}catch(Exception e){

View file

@ -9,6 +9,7 @@ import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Locker;
import dev.peerat.framework.Locker.Key;
import dev.peerat.framework.Response;
@ -20,7 +21,7 @@ public class DynamicLogs implements Response{
private Locker<Context> locker; //Context
private DatabaseRepository repo;
public DynamicLogs(Locker<Context> locker, DatabaseRepository repo){
public DynamicLogs(@Injection("log") Locker<Context> locker, DatabaseRepository repo){
this.locker = locker;
this.repo = repo;
}

View file

@ -5,6 +5,7 @@ import java.util.regex.Matcher;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Locker;
import dev.peerat.framework.Locker.Key;
import dev.peerat.framework.Response;
@ -16,7 +17,7 @@ public class ExceptionLogs implements Response{
private Locker<Exception> locker;
public ExceptionLogs(Locker<Exception> locker){
public ExceptionLogs(@Injection("exception") Locker<Exception> locker){
this.locker = locker;
}

View file

@ -6,6 +6,7 @@ import dev.peerat.backend.model.Completion;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Locker;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
@ -14,7 +15,7 @@ public class WebHookLeaderboard implements Response{
private Locker<Completion> locker;
public WebHookLeaderboard(Locker<Completion> locker){
public WebHookLeaderboard(@Injection("leaderboard") Locker<Completion> locker){
this.locker = locker;
}

View file

@ -14,6 +14,7 @@ import dev.peerat.backend.utils.FormResponse;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Locker;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
@ -25,7 +26,7 @@ public class GroupCreate extends FormResponse {
private DatabaseRepository repo;
private int groupDelay;
public GroupCreate(DatabaseRepository repo, Locker<Group> locker, int groupDelay){
public GroupCreate(DatabaseRepository repo, @Injection("groups") Locker<Group> locker, @Injection("groupDelay") int groupDelay){
this.repo = repo;
this.locker = locker;
this.groupDelay = groupDelay;

View file

@ -14,6 +14,7 @@ import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Locker;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
@ -26,7 +27,7 @@ public class GroupJoin implements Response{
private final Locker<Completion> leaderboard;
public GroupJoin(DatabaseRepository repo, int groupDelay, String waitTime, Locker<Completion> locker){
public GroupJoin(DatabaseRepository repo, @Injection("groupDelay") int groupDelay, @Injection("waitTime") String waitTime, @Injection("leaderboard") Locker<Completion> locker){
this.repo = repo;
this.groupDelay = groupDelay;
this.waitTime = waitTime;

View file

@ -14,6 +14,7 @@ import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Locker;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
@ -25,7 +26,7 @@ public class GroupQuit implements Response{
private final Locker<Completion> leaderboard;
public GroupQuit(DatabaseRepository repo, int groupDelay, Locker<Completion> locker){
public GroupQuit(DatabaseRepository repo, @Injection("groupDelay") int groupDelay, @Injection("leaderboard") Locker<Completion> locker){
this.repo = repo;
this.groupDelay = groupDelay;

View file

@ -2,9 +2,14 @@ package dev.peerat.backend.routes.users;
import static dev.peerat.framework.RequestType.POST;
import java.lang.reflect.Constructor;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import dev.peerat.backend.model.PeerAtUser;
@ -23,13 +28,28 @@ public class ForgotPassword extends FormResponse{
private Router<PeerAtUser> router;
private DatabaseRepository repo;
private Mail mail;
private Map<String, Integer> codes;
private Map<String, String> codes;
private List<Random> randoms;
public ForgotPassword(Router<PeerAtUser> router, DatabaseRepository repo, Mail mail){
this.router = router;
this.repo = repo;
this.mail = mail;
this.codes = new HashMap<>();
this.randoms = new ArrayList<>();
Random random = new Random();
int randoms = random.nextInt(10)+3;
for(int i = 0; i < randoms; i++) this.randoms.add(new SecureRandom());
try {
Constructor<?> constructor = UUID.class.getDeclaredConstructor(byte[].class);
constructor.setAccessible(true);
this.uuidBuilder = constructor;
} catch (Exception e){
e.printStackTrace();
}
}
@Route(path = "^/user/fpw$", type = POST)
@ -54,16 +74,16 @@ public class ForgotPassword extends FormResponse{
}
if(hasFields("code") && areValids("password")){
Integer checkCode = codes.get(email);
String checkCode = codes.get(email);
if(checkCode == null){
context.response(400);
return;
}
int code = json.<Number>get("code").intValue();
String code = json.<String>get("code");
String password = json.get("password");
if(code == checkCode.intValue()){
if(checkCode.equals(code)){
codes.remove(email);
repo.updatePassword(player, password);
@ -74,18 +94,25 @@ public class ForgotPassword extends FormResponse{
context.response(400);
}
}else{
int code = codeGenerator();
String code = codeGenerator();
codes.put(email, code);
mail.send(email, "Forgot your Peer @ Code password ?", "Your check code is "+code+" !");
context.response(200);
}
}
private int codeGenerator(){
int min = 1000;
int max = 9999;
return new Random().nextInt((max-min)) + min;
private Constructor<?> uuidBuilder;
private String codeGenerator() throws Exception{
Random random = new Random();
Random target = this.randoms.get(random.nextInt(this.randoms.size()));
byte[] arrayOfByte = new byte[16];
target.nextBytes(arrayOfByte);
arrayOfByte[6] = (byte)(arrayOfByte[6] & 0xF);
arrayOfByte[6] = (byte)(arrayOfByte[6] | 0x40);
arrayOfByte[8] = (byte)(arrayOfByte[8] & 0x3F);
arrayOfByte[8] = (byte)(arrayOfByte[8] | 0x80);
return uuidBuilder.newInstance(arrayOfByte).toString();
}
}

View file

@ -5,6 +5,7 @@ import static dev.peerat.framework.RequestType.POST;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.file.Files;
@ -12,11 +13,15 @@ import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import javax.net.ssl.HttpsURLConnection;
@ -32,11 +37,12 @@ import dev.peerat.backend.utils.Mail;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Route;
import dev.peerat.framework.Router;
import dev.peerat.framework.utils.json.JsonMap;
public class MailConfirmation extends FormResponse {
public class MailConfirmation extends FormResponse{
private DatabaseRepository databaseRepo;
private Router<PeerAtUser> router;
@ -44,15 +50,16 @@ public class MailConfirmation extends FormResponse {
private KeyPairGenerator generator;
private Encoder encoder;
private String gitToken;
private Map<String, Integer> playersWaiting;
private Map<String, String> playersWaiting;
private Mail mail;
private List<Random> randoms;
public MailConfirmation(
DatabaseRepository databaseRepo,
Router<PeerAtUser> router,
String initUsersFilesPath,
String gitToken,
Map<String, Integer> playersWaiting,
@Injection("usersFiles") String initUsersFilesPath,
@Injection("gitToken") String gitToken,
@Injection("waitting") Map<String, String> playersWaiting,
Mail mail) throws NoSuchAlgorithmException{
this.databaseRepo = databaseRepo;
@ -66,6 +73,20 @@ public class MailConfirmation extends FormResponse {
generator.initialize(4096);
encoder = Base64.getEncoder();
this.randoms = new ArrayList<>();
Random random = new Random();
int randoms = random.nextInt(10)+3;
for(int i = 0; i < randoms; i++) this.randoms.add(new SecureRandom());
try {
Constructor<?> constructor = UUID.class.getDeclaredConstructor(byte[].class);
constructor.setAccessible(true);
this.uuidBuilder = constructor;
} catch (Exception e){
e.printStackTrace();
}
validator("pseudo", "[a-zA-Z0-9&|!?{}\\[\\]%/*\\-+=:;,_#@ ]{3,100}");
validator("firstname", "^(?>[a-zA-Z]+ ?)+$");
validator("lastname", "^(?>[a-zA-Z]+ ?)+$");
@ -87,13 +108,13 @@ public class MailConfirmation extends FormResponse {
return;
}
String email = json.get("email");
int code = json.<Number>get("code").intValue();
String code = json.<String>get("code");
String pseudo = json.get("pseudo");
String firstname = json.get("firstname");
String lastname = json.get("lastname");
String password = json.get("passwd");
Integer checkCode = playersWaiting.get(email);
String checkCode = playersWaiting.get(email);
if(checkCode == null){
context.response(400);
return;
@ -102,7 +123,7 @@ public class MailConfirmation extends FormResponse {
boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo);
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
if(pseudoAvailable && emailAvailable){
if(code == checkCode.intValue()){
if(code.equals(checkCode)){
playersWaiting.remove(email);
int id = databaseRepo.register(pseudo, email, password, firstname, lastname, "", "", "");
if(id >= 0){
@ -117,7 +138,7 @@ public class MailConfirmation extends FormResponse {
error.set("username_valid", pseudo);
error.set("email_valid", email);
writer.write(error.toString());
int ncode = codeGenerator();
String ncode = codeGenerator()+codeGenerator();
playersWaiting.put(email, ncode);
mail.send(email, "Welcome @ Peer @ Code", "Your check code is "+ncode+" !");
}
@ -133,13 +154,20 @@ public class MailConfirmation extends FormResponse {
}
}
private int codeGenerator(){
int min = 1000;
int max = 9999;
return new Random().nextInt((max-min)) + min;
private Constructor<?> uuidBuilder;
private String codeGenerator() throws Exception{
Random random = new Random();
Random target = this.randoms.get(random.nextInt(this.randoms.size()));
byte[] arrayOfByte = new byte[16];
target.nextBytes(arrayOfByte);
arrayOfByte[6] = (byte)(arrayOfByte[6] & 0xF);
arrayOfByte[6] = (byte)(arrayOfByte[6] | 0x40);
arrayOfByte[8] = (byte)(arrayOfByte[8] & 0x3F);
arrayOfByte[8] = (byte)(arrayOfByte[8] | 0x80);
return uuidBuilder.newInstance(arrayOfByte).toString();
}
private void createFolderToSaveSourceCode(String pseudo) throws IOException {
Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo)));

View file

@ -2,8 +2,13 @@ package dev.peerat.backend.routes.users;
import static dev.peerat.framework.RequestType.POST;
import java.lang.reflect.Constructor;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
@ -13,19 +18,36 @@ import dev.peerat.backend.utils.Mail;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonMap;
public class Register extends FormResponse {
public class Register extends FormResponse{
private DatabaseRepository databaseRepo;
private Map<String, Integer> playersWaiting;
private Map<String, String> playersWaiting;
private Mail mail;
private String host;
private List<Random> randoms;
public Register(DatabaseRepository databaseRepo, Map<String, Integer> playersWaiting, Mail mail){
public Register(DatabaseRepository databaseRepo, @Injection("waitting") Map<String, String> playersWaiting, Mail mail, @Injection("issuer") String host){
this.databaseRepo = databaseRepo;
this.playersWaiting = playersWaiting;
this.mail = mail;
this.host = host;
this.randoms = new ArrayList<>();
Random random = new Random();
int randoms = random.nextInt(10)+3;
for(int i = 0; i < randoms; i++) this.randoms.add(new SecureRandom());
try {
Constructor<?> constructor = UUID.class.getDeclaredConstructor(byte[].class);
constructor.setAccessible(true);
this.uuidBuilder = constructor;
} catch (Exception e){
e.printStackTrace();
}
}
@RouteDoc(path = "/register", responseCode = 200, responseDescription = "L'utilisateur est inscrit")
@ -48,9 +70,9 @@ public class Register extends FormResponse {
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
if(emailAvailable){
int code = codeGenerator();
String code = codeGenerator()+codeGenerator();
playersWaiting.put(email, code);
mail.send(email, "Welcome @ Peer @ Code", "Your check code is "+code+" !");
mail.send(email, "Welcome @ Peer @ Code", "Please, confirm your code on "+host+"/?code="+code+" !");
context.response(200);
}else{
context.response(400);
@ -60,11 +82,18 @@ public class Register extends FormResponse {
}
}
private int codeGenerator(){
int min = 1000;
int max = 9999;
return new Random().nextInt((max-min)) + min;
private Constructor<?> uuidBuilder;
private String codeGenerator() throws Exception{
Random random = new Random();
Random target = this.randoms.get(random.nextInt(this.randoms.size()));
byte[] arrayOfByte = new byte[16];
target.nextBytes(arrayOfByte);
arrayOfByte[6] = (byte)(arrayOfByte[6] & 0xF);
arrayOfByte[6] = (byte)(arrayOfByte[6] | 0x40);
arrayOfByte[8] = (byte)(arrayOfByte[8] & 0x3F);
arrayOfByte[8] = (byte)(arrayOfByte[8] | 0x80);
return uuidBuilder.newInstance(arrayOfByte).toString();
}
}