Compare commits

..

2 commits
main ... ORM

80 changed files with 453 additions and 3520 deletions

View file

@ -17,8 +17,8 @@
<classpathentry kind="lib" path="Treasure.jar"/>
<classpathentry exported="true" kind="lib" path="JDA-5.0.0-beta.8-withDependencies.jar"/>
<classpathentry exported="true" kind="lib" path="PeerAtCodeFramework.jar"/>
<classpathentry exported="true" kind="lib" path="angus-activation-2.0.2.jar"/>
<classpathentry exported="true" kind="lib" path="jakarta.activation-api-2.1.3.jar"/>
<classpathentry exported="true" kind="lib" path="jakarta.mail-2.0.3.jar"/>
<classpathentry exported="true" kind="lib" path="angus-activation-2.0.1.jar"/>
<classpathentry exported="true" kind="lib" path="jakarta.activation-api-2.1.2.jar"/>
<classpathentry exported="true" kind="lib" path="jakarta.mail-2.0.2.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -2,5 +2,6 @@ eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=true
org.eclipse.jdt.apt.genSrcDir=.apt_generated
org.eclipse.jdt.apt.genTestSrcDir=.apt_generated_tests
org.eclipse.jdt.apt.processorOptions/treasure.providers=dev.peerat.mapping.providers.mysql.MySQLProvider
org.eclipse.jdt.apt.processorOptions/treasure.source=%sourcepath%
org.eclipse.jdt.apt.reconcileEnabled=true

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
jose4j-0.9.3.jar Normal file

Binary file not shown.

BIN
password4j-1.6.3.jar Normal file

Binary file not shown.

View file

@ -1,6 +0,0 @@
/chapter/0
GET
Authorization: Bearer <token:test@peerat.dev>
400

View file

@ -1,8 +0,0 @@
/chapters
GET
Authorization: Bearer <token:test@peerat.dev>
200
[]

View file

@ -1,8 +0,0 @@
/leaderboard/
GET
Authorization: Bearer <token:test@peerat.dev>
200
[]

View file

@ -1,6 +0,0 @@
/puzzle/0
GET
Authorization: Bearer <token:test@peerat.dev>
400

View file

@ -1,6 +0,0 @@
/admin/chapter/0
GET
Authorization: Bearer <token:test@peerat.dev>
401

BIN
slf4j-api-2.0.6.jar Normal file

Binary file not shown.

View file

@ -7,7 +7,9 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.lang.reflect.Field;
import dev.peerat.backend.utils.Mail;
import dev.peerat.backend.last_utils.Mail;
import dev.peerat.mapping.providers.Compass;
import dev.peerat.mapping.providers.mysql.MySQLCompass;
public class Configuration {
@ -33,7 +35,6 @@ public class Configuration {
private int groupJoinMinutes;
private String groupQuitMinutes;
private int groupMaxPlayers;
private String mailUsername;
private String mailPassword;
@ -42,12 +43,6 @@ public class Configuration {
private String mailFromAddress;
private String git_token;
private String jwt_key;
private String sql_folder;
private int event_chapter;
private File _file;
@ -132,7 +127,7 @@ public class Configuration {
field.setAccessible(true);
if(field.getName().startsWith("_")) continue;
Object value = field.get(this);
writer.write(field.getName() + "=" + value+"\n");
writer.write(field.getName() + "=" + value);
}
writer.flush();
writer.close();
@ -142,47 +137,31 @@ public class Configuration {
return this.prod;
}
public String getDbHost(){
return this.db_host;
public Compass getCompass(){
return new MySQLCompass(db_host, db_port, db_database, db_user, db_password);
}
public int getDbPort(){
return this.db_port;
}
public String getDbUser(){
return this.db_user;
}
public String getDbDatabase(){
return this.db_database;
}
public String getDbPassword(){
return this.db_password;
}
public String getSslKeystore(){
public String getSslKeystore() {
return this.ssl_keystore;
}
public String getTokenIssuer(){
public String getTokenIssuer() {
return this.token_issuer;
}
public int getTokenExpiration(){
public int getTokenExpiration() {
return this.token_expiration;
}
public String getSslKeystorePasswd(){
public String getSslKeystorePasswd() {
return this.ssl_keystorePasswd;
}
public int getTcpPort(){
public int getTcpPort() {
return this.tcp_port;
}
public boolean useSsl(){
public boolean useSsl() {
return this.use_ssl;
}
@ -202,10 +181,6 @@ public class Configuration {
return this.groupQuitMinutes;
}
public int getGroupMaxPlayers(){
return this.groupMaxPlayers;
}
public Mail getMail(){
return new Mail(
this.mailUsername,
@ -218,20 +193,4 @@ public class Configuration {
public String getGitToken(){
return this.git_token;
}
public String getJwtKey(){
return this.jwt_key;
}
public void setJwtKey(String key){
this.jwt_key = key;
}
public String getSqlFolder(){
return this.sql_folder;
}
public int getEventChapter(){
return this.event_chapter;
}
}

View file

@ -2,46 +2,40 @@ package dev.peerat.backend;
import static dev.peerat.framework.RequestType.OPTIONS;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteExtracter;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.ConnectionManager;
import dev.peerat.backend.repository.DatabaseRepository;
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;
import dev.peerat.framework.Locker.Key;
import dev.peerat.framework.RequestType;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.RouteInterceptor;
import dev.peerat.framework.Router;
import dev.peerat.framework.auth.Authenticator;
import dev.peerat.framework.auth.JwtAuthenticator;
import dev.peerat.framework.utils.json.JsonMap;
import dev.peerat.framework.utils.json.JsonParser;
import dev.peerat.mapping.Ship;
import dev.peerat.mapping.providers.mysql.MySQLCompass;
import dev.peerat.mapping.providers.mysql.MySQLMap;
import dev.peerat.framework.Locker.Key;
public class Main{
private static Router<PeerAtUser> ACCESS_ROUTER;
public static void main(String[] args) throws Exception{
Configuration config = new Configuration("config.txt").addDefaultValue("users_files", "/tmp/users_files");
config.load();
Configuration config = new Configuration("config.txt")
.addDefaultValue("users_files", "/tmp/users_files")
.load();
Ship ship = new Ship("mysql", config.getCompass(), new MySQLMap());
Class.forName("com.mysql.cj.jdbc.Driver");
DatabaseRepository repo = new DatabaseRepository(new ConnectionManager(config), config);
Router<PeerAtUser> router = new Router<PeerAtUser>()
.configureJwt(
(builder) -> builder.setExpectedIssuer(config.getTokenIssuer()),
(claims) -> {
claims.setIssuer(config.getTokenIssuer()); // who creates the token and signs it
claims.setExpirationTimeMinutesInTheFuture(config.getTokenExpiration());
},
(claims) -> new PeerAtUser(claims))
.activeReOrdering().
addDefaultHeaders(RequestType.GET, "Access-Control-Allow-Origin: *").
addDefaultHeaders(RequestType.POST, "Access-Control-Allow-Origin: *").
@ -49,38 +43,6 @@ public class Main{
"Access-Control-Allow-Origin: *",
"Access-Control-Allow-Methods: *",
"Access-Control-Allow-Headers: *");
ACCESS_ROUTER = router;
Authenticator<PeerAtUser> auth;
if(config.getJwtKey() != null){
JsonParser parser = new JsonParser();
JsonMap json = parser.parse(config.getJwtKey());
Map<String, Object> params = new HashMap<>();
for(Entry<String, Object> entry : json.entries()) params.put(entry.getKey(), entry.getValue());
auth = new JwtAuthenticator<PeerAtUser>().configure(
(builder) -> builder.setExpectedIssuer(config.getTokenIssuer()),
(claims) -> {
claims.setIssuer(config.getTokenIssuer());
claims.setExpirationTimeMinutesInTheFuture(config.getTokenExpiration());
},
(claims) -> new PeerAtUser(claims),
params);
}else{
auth = new JwtAuthenticator<PeerAtUser>().configure(
(builder) -> builder.setExpectedIssuer(config.getTokenIssuer()),
(claims) -> {
claims.setIssuer(config.getTokenIssuer());
claims.setExpirationTimeMinutesInTheFuture(config.getTokenExpiration());
},
(claims) -> new PeerAtUser(claims));
JsonMap json = new JsonMap();
for(Entry<String, Object> entry : ((JwtAuthenticator<PeerAtUser>)auth).exportKey().entrySet()){
json.set(entry.getKey(), entry.getValue());
}
config.setJwtKey(json.toString());
config.save();
}
router.setAuthenticator(auth);
router.setDefault((matcher, context, reader, writer) -> {
context.response(404);
@ -94,29 +56,7 @@ public class Main{
}
});
initRoutes(router, repo, config);
router.addInterceptor(new RouteInterceptor(){
@Override
public boolean intercept(Matcher matcher, Context context, HttpReader reader, HttpWriter writer, Method method){
if(method.getDeclaringClass().getPackage().getName().contains(".admins")){
try {
Group group = repo.getGroupRepository().getPlayerGroup(context.<PeerAtUser>getUser().getId(), 1);
if(!group.getName().equalsIgnoreCase("Quarter-Master - Battles PAC x CEI")){
context.response(401);
return false;
}
}catch(Exception ex){
ex.printStackTrace();
try{
context.response(401);
}catch(Exception e){}
return false;
}
}
return true;
}
});
initRoutes(router, config);
new Thread(new Runnable(){
public void run(){
@ -130,7 +70,7 @@ public class Main{
locker.lock(key);
Context instance = locker.getValue(key);
if(instance == null) continue;
System.out.println("["+((instance.isLogged()) ? repo.getPlayerRepository().getPlayer(instance.<PeerAtUser>getUser().getId()).getPseudo() : "?")+"] "+instance.getType()+" "+instance.getPath()+" -> "+instance.getResponseCode());
System.out.println("["+((instance.isLogged()) ? instance.<PeerAtUser>getUser().getPseudo() : "?")+"] "+instance.getType()+" "+instance.getPath()+" -> "+instance.getResponseCode());
}
}catch(Exception e){
e.printStackTrace();
@ -138,45 +78,16 @@ public class Main{
locker.remove(key);
}
}).start();
new Thread(new Runnable(){
public void run(){
Key key = new Key();
Locker<Throwable> locker = router.getExceptionLogger();
locker.init(key);
try {
while(true){
locker.lock(key);
locker.getValue(key).printStackTrace();
}
}catch(Exception e){
e.printStackTrace();
}
locker.remove(key);
}
}).start();
if(config.useSsl()) router.configureSSL(config.getSslKeystore(), config.getSslKeystorePasswd());
router.listen(config.getTcpPort(), config.useSsl());
}
private static void initRoutes(Router<PeerAtUser> router, DatabaseRepository repo, Configuration config) throws Exception{
Predicate<PeerAtUser> isAdmin = (user) -> {
try {
Group group = repo.getGroupRepository().getPlayerGroup(user.getId(), 1);
return group.getName().equalsIgnoreCase("Quarter-Master - Battles PAC x CEI");
}catch(Exception ex){}
return false;
};
router.registerPackages("dev.peerat.backend.routes",new DependencyInjector()
.of(repo, router, config, new RouteExtracter(router), config.getMail(), isAdmin)
.of("waitting", new HashMap<>())
.of("leaderboard", new Locker<>())
.of("groups", new Locker<>())
.of("groupMessages", new Locker<>()));
private static void initRoutes(Router<PeerAtUser> router, Configuration config) throws Exception{
Map<String, Integer> playersWaiting = new HashMap<>();
Mail mail = config.getMail();
Locker<Group> groupLock = new Locker<>();
Locker<Completion> leaderboard = new Locker<>();
// Bot bot = new Bot(config, repo, groupLock);
// bot.start();

View file

@ -1,4 +1,4 @@
package dev.peerat.backend.bonus.discord;
package dev.peerat.backend.last_bonus.discord;
import java.util.List;
@ -38,7 +38,7 @@ public class Bot extends Thread{
locker.init(key);
List<Group> groups = this.repo.getGroupRepository().getAllGroups();
List<Group> groups = this.repo.getAllGroups();
for(Group group : groups){
Integer chapter = group.getLinkToChapter();
// Integer puzzle = group.getLinkToPuzzle();

View file

@ -5,7 +5,6 @@ import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Badge;
import dev.peerat.backend.repository.DatabaseBadgeRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
@ -16,10 +15,10 @@ import dev.peerat.framework.utils.json.JsonMap;
public class BadgeDetails implements Response {
private final DatabaseBadgeRepository databaseRepo;
private final DatabaseRepository databaseRepo;
public BadgeDetails(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo.getBadgeRepository();
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/badge/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du badge")

View file

@ -6,9 +6,6 @@ import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.model.Puzzle;
import dev.peerat.backend.repository.DatabaseChapterRepository;
import dev.peerat.backend.repository.DatabaseCompletionRepository;
import dev.peerat.backend.repository.DatabaseGroupRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
@ -20,12 +17,10 @@ import dev.peerat.framework.utils.json.JsonMap;
public class ChapterElement implements Response {
private final DatabaseChapterRepository chapterRepo;
private final DatabaseCompletionRepository completionRepo;
private final DatabaseRepository databaseRepo;
public ChapterElement(DatabaseRepository repo) {
this.chapterRepo = repo.getChapterRepository();
this.completionRepo = repo.getCompletionRepository();
public ChapterElement(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/chapter/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du chapitre demander")
@ -33,15 +28,13 @@ public class ChapterElement implements Response {
@Route(path = "^\\/chapter\\/([0-9]+)$", needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
Chapter chapter = chapterRepo.getChapter(Integer.parseInt(matcher.group(1)));
Chapter chapter = databaseRepo.getChapter(Integer.parseInt(matcher.group(1)));
if (chapter != null){
JsonMap chapterJSON = new JsonMap();
chapterJSON.set("id", chapter.getId());
chapterJSON.set("name", chapter.getName());
boolean show = chapter.hasStarted();
chapterJSON.set("show", show);
if(chapter.getStartDate() != null) chapterJSON.set("start", chapter.getStartDate().toString());
if(chapter.getEndDate() != null) chapterJSON.set("end", chapter.getEndDate().toString());
PeerAtUser user = context.getUser();
if(show){
JsonArray puzzles = new JsonArray();
@ -51,7 +44,7 @@ public class ChapterElement implements Response {
puzzleJSON.set("name", puzzle.getName());
puzzleJSON.set("scoreMax", puzzle.getScoreMax());
if (puzzle.getTags() != null) puzzleJSON.set("tags", puzzle.getJsonTags());
int score = this.completionRepo.getScore(user.getId(), puzzle.getId());
int score = this.databaseRepo.getScore(user.getId(), puzzle.getId());
if(score >= 0) puzzleJSON.set("score", score);
puzzleJSON.set("show", puzzle.hasStarted());
puzzles.add(puzzleJSON);

View file

@ -5,7 +5,6 @@ import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.repository.DatabaseChapterRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
@ -17,10 +16,10 @@ import dev.peerat.framework.utils.json.JsonMap;
public class ChapterList implements Response {
private final DatabaseChapterRepository databaseRepo;
private final DatabaseRepository databaseRepo;
public ChapterList(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo.getChapterRepository();
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/chapters", responseCode = 200, responseDescription = "JSON contenant les informations des chapitres")
@ -36,8 +35,6 @@ public class ChapterList implements Response {
chapterJSON.set("id", chapter.getId());
chapterJSON.set("name", chapter.getName());
chapterJSON.set("show", chapter.hasStarted());
if(chapter.getStartDate() != null) chapterJSON.set("start", chapter.getStartDate().toString());
if(chapter.getEndDate() != null) chapterJSON.set("end", chapter.getEndDate().toString());
chaptersJSON.add(chapterJSON);
}
context.response(200);

View file

@ -8,7 +8,6 @@ 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;
@ -17,7 +16,7 @@ public class DynamicLeaderboard extends Leaderboard{
private Locker<Completion> locker;
public DynamicLeaderboard(DatabaseRepository databaseRepo, @Injection("leaderboard") Locker<Completion> locker){
public DynamicLeaderboard(DatabaseRepository databaseRepo, Locker<Completion> locker){
super(databaseRepo);
this.locker = locker;
}

View file

@ -38,9 +38,9 @@ public class Leaderboard implements Response {
}
public final void groupsLeaderboard(int chapterId, HttpWriter writer) throws IOException {
Chapter chInfo = databaseRepo.getChapterRepository().getChapter(chapterId);
Chapter chInfo = databaseRepo.getChapter(chapterId);
SortedSet<Group> allGroupsForChapter = databaseRepo.getLeaderboardRepository().getAllGroupForChapterLeaderboard(chapterId);
SortedSet<Group> allGroupsForChapter = databaseRepo.getAllGroupForChapterLeaderboard(chapterId);
JsonMap leaderboardJSON = new JsonMap();
if (chInfo.getStartDate() != null)
leaderboardJSON.set("start_date", chInfo.getStartDate().toString());
@ -65,11 +65,11 @@ public class Leaderboard implements Response {
}
}
leaderboardJSON.set("groups", groupsJSON);
writer.write(leaderboardJSON.toString());
writer.write(leaderboardJSON.toString().replace("\\", ""));
}
public final void playersLeaderboard(HttpWriter writer) throws IOException {
SortedSet<Player> allPlayers = databaseRepo.getLeaderboardRepository().getAllPlayerForLeaderboard();
SortedSet<Player> allPlayers = databaseRepo.getAllPlayerForLeaderboard();
JsonArray playersJSON = new JsonArray();
if (allPlayers != null) {
for (Player player : allPlayers) {
@ -86,6 +86,6 @@ public class Leaderboard implements Response {
playersJSON.add(playerJSON);
}
}
writer.write(playersJSON.toString());
writer.write(playersJSON.toString().replace("\\", ""));
}
}

View file

@ -1,11 +1,11 @@
package dev.peerat.backend.routes;
import java.util.Base64;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.model.Player;
import dev.peerat.backend.repository.DatabasePlayerRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
@ -16,10 +16,10 @@ import dev.peerat.framework.utils.json.JsonMap;
public class PlayerDetails implements Response {
private final DatabasePlayerRepository databaseRepo;
private final DatabaseRepository databaseRepo;
public PlayerDetails(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo.getPlayerRepository();
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/player/{id}", responseCode = 200, responseDescription = "JSON contenant les informations de l'utilisateur")
@ -50,10 +50,10 @@ public class PlayerDetails implements Response {
playerJSON.set("tries", player.getTotalTries());
if (player.getBadges() != null)
playerJSON.set("badges", player.getJsonBadges());
// if (player.getAvatar() != null)
// playerJSON.set("avatar", Base64.getEncoder().encodeToString(player.getAvatar()));
if (player.getAvatar() != null)
playerJSON.set("avatar", Base64.getEncoder().encodeToString(player.getAvatar()));
context.response(200);
writer.write(playerJSON.toString());
writer.write(playerJSON.toString().replace("\\", ""));
} else {
context.response(400);
}

View file

@ -1,7 +1,6 @@
package dev.peerat.backend.routes;
import java.time.LocalDateTime;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
@ -20,11 +19,9 @@ import dev.peerat.framework.utils.json.JsonMap;
public class PuzzleElement implements Response {
private final DatabaseRepository databaseRepo;
private Predicate<PeerAtUser> isAdmin;
public PuzzleElement(DatabaseRepository databaseRepo, Predicate<PeerAtUser> isAdmin){
public PuzzleElement(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
this.isAdmin = isAdmin;
}
@RouteDoc(path = "/puzzle/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du puzzle")
@ -33,10 +30,10 @@ public class PuzzleElement implements Response {
@Route(path = "^\\/puzzle\\/([0-9]+)$", needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
Puzzle puzzle = databaseRepo.getPuzzleRepository().getPuzzle(extractId(matcher));
Puzzle puzzle = databaseRepo.getPuzzle(extractId(matcher));
if (puzzle != null){
Chapter chapter = this.databaseRepo.getChapterRepository().getChapter(puzzle);
if(chapter.getStartDate() != null && !isAdmin.test(context.getUser())){
Chapter chapter = this.databaseRepo.getChapter(puzzle);
if(chapter.getStartDate() != null){
if(LocalDateTime.now().isBefore(chapter.getStartDate().toLocalDateTime())){
context.response(423);
return;
@ -57,7 +54,7 @@ public class PuzzleElement implements Response {
puzzleJSON.set("content", puzzle.getContent());
puzzleJSON.set("scoreMax", puzzle.getScoreMax());
if(puzzle.getTags() != null) puzzleJSON.set("tags", puzzle.getJsonTags());
Completion completion = this.databaseRepo.getCompletionRepository().getCompletionGroup(user.getId(), puzzle.getId());
Completion completion = this.databaseRepo.getCompletionGroup(user.getId(), puzzle.getId());
if(completion != null && completion.getScore() >= 0){
puzzleJSON.set("score", completion.getScore());
puzzleJSON.set("tries", completion.getTries());

View file

@ -9,10 +9,8 @@ import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.Completion;
@ -24,7 +22,6 @@ 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;
@ -35,13 +32,11 @@ public class PuzzleResponse implements Response {
private final String usersFilesPath;
private final Locker<Completion> leaderboard;
private Predicate<PeerAtUser> isAdmin;
public PuzzleResponse(DatabaseRepository databaseRepo, Configuration config, @Injection("leaderboard") Locker<Completion> locker, Predicate<PeerAtUser> isAdmin){
public PuzzleResponse(DatabaseRepository databaseRepo, String initUsersFilesPath, Locker<Completion> locker){
this.databaseRepo = databaseRepo;
usersFilesPath = config.getUsersFiles();
usersFilesPath = initUsersFilesPath;
this.leaderboard = locker;
this.isAdmin = isAdmin;
}
@RouteDoc(path = "/puzzleResponse/<id>", responseCode = 200, responseDescription = "Bonne réponse, json contenant les points + tries")
@ -61,23 +56,23 @@ public class PuzzleResponse implements Response {
//saveSourceCode(received, databaseRepo.getPlayer(user.getId()));
JsonMap responseJSON = new JsonMap();
if(this.databaseRepo.getCompletionRepository().getScore(user.getId(), received.getPuzzleId()) > 0){
if(this.databaseRepo.getScore(user.getId(), received.getPuzzleId()) > 0){
context.response(403);
return;
}
Puzzle currentPuzzle = databaseRepo.getPuzzleRepository().getPuzzle(received.getPuzzleId());
Puzzle currentPuzzle = databaseRepo.getPuzzle(received.getPuzzleId());
if(!currentPuzzle.hasStarted()){
context.response(423);
return;
}
Chapter chapter = this.databaseRepo.getChapterRepository().getChapter(currentPuzzle);
Chapter chapter = this.databaseRepo.getChapter(currentPuzzle);
if(!chapter.hasStarted()){
context.response(423);
return;
}
if(chapter.getEndDate() != null && !isAdmin.test(context.getUser())){
if(chapter.getEndDate() != null){
if(LocalDateTime.now().isAfter(chapter.getEndDate().toLocalDateTime())){
if(Arrays.equals(currentPuzzle.getSoluce(), received.getResponse())){
context.response(200, "Content-Type: application/json");
@ -89,7 +84,7 @@ public class PuzzleResponse implements Response {
context.response(423);
return;
}
Group group = this.databaseRepo.getGroupRepository().getPlayerGroup(user.getId(), chapter.getId());
Group group = this.databaseRepo.getPlayerGroup(user.getId(), chapter.getId());
if(group == null){
context.response(423);
return;
@ -97,7 +92,7 @@ public class PuzzleResponse implements Response {
}
Completion completion = databaseRepo.getCompletionRepository().insertOrUpdatePuzzleResponse(received.getPuzzleId(), user.getId(),
Completion completion = databaseRepo.insertOrUpdatePuzzleResponse(received.getPuzzleId(), user.getId(),
received.getFileName(), received.getSourceCode(), received.getResponse(), currentPuzzle);
if(completion == null){
context.response(400);

View file

@ -4,7 +4,6 @@ import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.DatabaseCompletionRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
@ -14,10 +13,10 @@ import dev.peerat.framework.Route;
public class Result implements Response {
private DatabaseCompletionRepository repo;
private DatabaseRepository repo;
public Result(DatabaseRepository repo) {
this.repo = repo.getCompletionRepository();
this.repo = repo;
}
@RouteDoc(path = "/result/<id>", responseCode = 200, responseDescription = "Le score")

View file

@ -2,12 +2,10 @@ package dev.peerat.backend.routes;
import java.util.regex.Matcher;
import dev.peerat.backend.Configuration;
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;
@ -15,9 +13,9 @@ public class Swagger implements Response{
private String json;
public Swagger(RouteExtracter extracter, Configuration config){
public Swagger(RouteExtracter extracter, String host){
try{
// this.json = extracter.swagger(config.getTokenIssuer()).toString();
this.json = extracter.swagger(host).toString();
}catch(Exception e){
e.printStackTrace();
json = "{}";

View file

@ -0,0 +1,59 @@
package dev.peerat.backend.routes.admins;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.PeerAtUser;
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.Locker;
import dev.peerat.framework.Locker.Key;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonMap;
public class DynamicLogs implements Response{
private Locker<Context> locker; //Context
private DatabaseRepository repo;
public DynamicLogs(Locker<Context> locker, DatabaseRepository repo){
this.locker = locker;
this.repo = repo;
}
@RouteDoc(path = "/admin/logs", responseCode = 200, responseDescription = "L'utilisateur peux voir les logs en directe")
@RouteDoc(responseCode = 401, responseDescription = "L'utilisateur n'a pas accès à cette ressource")
@Route(path = "^/admin/logs$", needLogin = true, websocket = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
Group group = this.repo.getPlayerGroup(context.<PeerAtUser>getUser().getId(), 1);
if(!group.getName().equalsIgnoreCase("Quarter-Master - Battles PAC x CEI")) return;
Key key = new Key();
locker.init(key);
try {
while(!reader.isClosed()){
locker.lock(key);
Context instance = locker.getValue(key);
JsonMap json = new JsonMap();
json.set("logged", instance.isLogged());
if(instance.isLogged()) json.set("pseudo", repo.getPlayer(instance.<PeerAtUser>getUser().getId()).getPseudo());
json.set("path", instance.getPath());
json.set("type", instance.getType());
json.set("code", instance.getResponseCode());
writer.write(json.toString());
writer.flush();
}
}catch(Exception e){}
locker.remove(key);
}
}

View file

@ -5,35 +5,30 @@ import static dev.peerat.framework.RequestType.POST;
import java.time.LocalDateTime;
import java.util.regex.Matcher;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.DatabaseChapterRepository;
import dev.peerat.backend.repository.DatabaseGroupRepository;
import dev.peerat.backend.repository.DatabaseRepository;
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;
import dev.peerat.framework.utils.json.JsonMap;
public class GroupCreate extends FormResponse {
private Locker<Group> locker;
private DatabaseGroupRepository repo;
private DatabaseChapterRepository chapterRepo;
private DatabaseRepository repo;
private int groupDelay;
public GroupCreate(DatabaseRepository repo, @Injection("groups") Locker<Group> locker, Configuration config){
this.repo = repo.getGroupRepository();
this.chapterRepo = repo.getChapterRepository();
public GroupCreate(DatabaseRepository repo, Locker<Group> locker, int groupDelay){
this.repo = repo;
this.locker = locker;
this.groupDelay = config.getGroupJoinMinutes();
this.groupDelay = groupDelay;
validator("name", "[a-zA-Z0-9&|!?{}\\[\\]%/*\\-+=:;,_#@ ]{3,100}");
}
@ -59,7 +54,7 @@ public class GroupCreate extends FormResponse {
return;
}catch(NullPointerException e){
if(newGroup.getLinkToChapter() != null){
Chapter chapter = this.chapterRepo.getChapter(newGroup.getLinkToChapter());
Chapter chapter = this.repo.getChapter(newGroup.getLinkToChapter());
if(chapter.getStartDate() != null){
LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay);
if(LocalDateTime.now().isAfter(start)){

View file

@ -5,37 +5,31 @@ import static dev.peerat.framework.RequestType.POST;
import java.time.LocalDateTime;
import java.util.regex.Matcher;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.Completion;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.DatabaseChapterRepository;
import dev.peerat.backend.repository.DatabaseGroupRepository;
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;
public class GroupJoin implements Response{
private DatabaseChapterRepository chapterRepo;
private DatabaseGroupRepository groupRepo;
private DatabaseRepository repo;
private int groupDelay;
private String waitTime;
private final Locker<Completion> leaderboard;
public GroupJoin(DatabaseRepository repo, Configuration config, @Injection("leaderboard") Locker<Completion> locker){
this.chapterRepo = repo.getChapterRepository();
this.groupRepo = repo.getGroupRepository();
this.groupDelay = config.getGroupJoinMinutes();
this.waitTime = config.getGroupQuitMinutes();
public GroupJoin(DatabaseRepository repo, int groupDelay, String waitTime, Locker<Completion> locker){
this.repo = repo;
this.groupDelay = groupDelay;
this.waitTime = waitTime;
this.leaderboard = locker;
}
@ -49,7 +43,7 @@ public class GroupJoin implements Response{
Group group = new Group(reader.readJson());
PeerAtUser user = context.getUser();
Group userGroup = this.groupRepo.getPlayerGroup(user.getId(), group.getLinkToChapter());
Group userGroup = this.repo.getPlayerGroup(user.getId(), group.getLinkToChapter());
if(group.equals(userGroup)){
context.response(403);
return;
@ -62,7 +56,7 @@ public class GroupJoin implements Response{
}
if(group.getLinkToChapter() != null){
Chapter chapter = this.chapterRepo.getChapter(group.getLinkToChapter());
Chapter chapter = this.repo.getChapter(group.getLinkToChapter());
if(chapter.getStartDate() != null){
LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay);
if(LocalDateTime.now().isAfter(start)){
@ -72,7 +66,7 @@ public class GroupJoin implements Response{
}
}
if (this.groupRepo.insertUserInGroup(group, user)) {
if (this.repo.insertUserInGroup(group, user)) {
context.response(200);
leaderboard.setValue(new Completion(0, 0, 0, null, 0));

View file

@ -4,7 +4,6 @@ import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.repository.DatabaseGroupRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
@ -15,28 +14,19 @@ import dev.peerat.framework.utils.json.JsonArray;
public class GroupList implements Response {
private DatabaseGroupRepository repo;
private DatabaseRepository repo;
public GroupList(DatabaseRepository repo){
this.repo = repo.getGroupRepository();
public GroupList(DatabaseRepository repo) {
this.repo = repo;
}
@RouteDoc(path = "/groups", responseCode = 200, responseDescription = "JSON avec la liste des groups")
@Route(path = "^\\/groups\\/?(\\d+)?$", needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
String param = matcher.group(1);
if(param == null){
JsonArray result = new JsonArray();
for(Group group : this.repo.getAllGroups()) result.add(group.toJson());
context.response(200);
writer.write(result.toString());
return;
}
int chapter = Integer.parseInt(param);
JsonArray result = new JsonArray();
for(Group group : this.repo.getAllGroupsByChapter(chapter)) result.add(group.toJson());
@Route(path = "^\\/groups$", needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
context.response(200);
JsonArray result = new JsonArray();
for(Group group : this.repo.getAllGroups()) result.add(group.toJson());
writer.write(result.toString());
}

View file

@ -5,35 +5,29 @@ import static dev.peerat.framework.RequestType.POST;
import java.time.LocalDateTime;
import java.util.regex.Matcher;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.Completion;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.DatabaseChapterRepository;
import dev.peerat.backend.repository.DatabaseGroupRepository;
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;
public class GroupQuit implements Response{
private DatabaseChapterRepository chapterRepo;
private DatabaseGroupRepository groupRepo;
private DatabaseRepository repo;
private int groupDelay;
private final Locker<Completion> leaderboard;
public GroupQuit(DatabaseRepository repo, Configuration config, @Injection("leaderboard") Locker<Completion> locker){
this.chapterRepo = repo.getChapterRepository();
this.groupRepo = repo.getGroupRepository();
this.groupDelay = config.getGroupJoinMinutes();
public GroupQuit(DatabaseRepository repo, int groupDelay, Locker<Completion> locker){
this.repo = repo;
this.groupDelay = groupDelay;
this.leaderboard = locker;
}
@ -47,14 +41,14 @@ public class GroupQuit implements Response{
Group group = new Group(reader.readJson());
PeerAtUser user = context.getUser();
Group userGroup = this.groupRepo.getPlayerGroup(user.getId(), group.getLinkToChapter());
Group userGroup = this.repo.getPlayerGroup(user.getId(), group.getLinkToChapter());
if(!group.equals(userGroup)){
context.response(403);
return;
}
if(group.getLinkToChapter() != null){
Chapter chapter = this.chapterRepo.getChapter(group.getLinkToChapter());
Chapter chapter = this.repo.getChapter(group.getLinkToChapter());
if(chapter.getStartDate() != null){
LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay);
if(LocalDateTime.now().isAfter(start)){
@ -64,7 +58,7 @@ public class GroupQuit implements Response{
}
}
if (this.groupRepo.leaveGroup(group, user)) {
if (this.repo.leaveGroup(group, user)) {
context.response(200);
leaderboard.setValue(new Completion(0, 0, 0, null, 0));

View file

@ -4,7 +4,6 @@ import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.DatabasePlayerRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
@ -16,10 +15,10 @@ import dev.peerat.framework.utils.json.JsonMap;
public class ChangePassword implements Response{
private DatabasePlayerRepository repo;
private DatabaseRepository repo;
public ChangePassword(DatabaseRepository repo){
this.repo = repo.getPlayerRepository();
this.repo = repo;
}
@RouteDoc(path = "/user/cpw", responseCode = 200, responseDescription = "L'utilisateur a mis à jours sont mots de passe")

View file

@ -2,18 +2,12 @@ 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;
import dev.peerat.backend.repository.DatabasePlayerRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.backend.utils.FormResponse;
import dev.peerat.backend.utils.Mail;
@ -27,30 +21,15 @@ import dev.peerat.framework.utils.json.JsonMap;
public class ForgotPassword extends FormResponse{
private Router<PeerAtUser> router;
private DatabasePlayerRepository repo;
private DatabaseRepository repo;
private Mail mail;
private Map<String, String> codes;
private List<Random> randoms;
private Map<String, Integer> codes;
public ForgotPassword(Router<PeerAtUser> router, DatabaseRepository repo, Mail mail){
this.router = router;
this.repo = repo.getPlayerRepository();
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)
@ -75,16 +54,16 @@ public class ForgotPassword extends FormResponse{
}
if(hasFields("code") && areValids("password")){
String checkCode = codes.get(email);
Integer checkCode = codes.get(email);
if(checkCode == null){
context.response(400);
return;
}
String code = json.<String>get("code");
int code = json.<Number>get("code").intValue();
String password = json.get("password");
if(checkCode.equals(code)){
if(code == checkCode.intValue()){
codes.remove(email);
repo.updatePassword(player, password);
@ -95,30 +74,18 @@ public class ForgotPassword extends FormResponse{
context.response(400);
}
}else{
String code = codeGenerator();
int code = codeGenerator();
codes.put(email, code);
mail.send(email, "Forgot your Peer @ Code password ?", "Your check code is "+code+" !");
context.response(200);
}
}
private Constructor<?> uuidBuilder;
private int[] start = {4, 9, 14, 19};
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);
String uuid = uuidBuilder.newInstance(arrayOfByte).toString();
target = this.randoms.get(random.nextInt(this.randoms.size()));
int start = this.start[target.nextInt(this.start.length)];
return uuid.substring(start, start+9);
private int codeGenerator(){
int min = 1000;
int max = 9999;
return new Random().nextInt((max-min)) + min;
}
}

View file

@ -6,7 +6,6 @@ import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.DatabaseAuthRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.backend.utils.FormResponse;
import dev.peerat.framework.Context;
@ -18,11 +17,11 @@ import dev.peerat.framework.utils.json.JsonMap;
public class Login extends FormResponse{
private DatabaseAuthRepository repo;
private DatabaseRepository databaseRepo;
private Router<PeerAtUser> router;
public Login(DatabaseRepository databaseRepo, Router<PeerAtUser> router){
this.repo = databaseRepo.getAuthRepository();
this.databaseRepo = databaseRepo;
this.router = router;
}
@ -42,7 +41,7 @@ public class Login extends FormResponse{
return;
}
int id;
if((id = repo.login(json.get("pseudo"), json.get("passwd"))) >= 0){
if((id = databaseRepo.login(json.get("pseudo"), json.get("passwd"))) >= 0){
context.response(200,
"Access-Control-Expose-Headers: Authorization",
"Authorization: Bearer " + this.router.createAuthUser(new PeerAtUser(id)));

View file

@ -5,7 +5,6 @@ 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;
@ -13,15 +12,11 @@ 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;
@ -29,44 +24,41 @@ import javax.net.ssl.HttpsURLConnection;
import org.jose4j.json.internal.json_simple.JSONAware;
import org.jose4j.json.internal.json_simple.JSONObject;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.DatabaseAuthRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.backend.utils.FormResponse;
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 DatabaseAuthRepository databaseRepo;
private DatabaseRepository databaseRepo;
private Router<PeerAtUser> router;
private String usersFilesPath;
private KeyPairGenerator generator;
private Encoder encoder;
private String gitToken;
private Map<String, String> playersWaiting;
private Map<String, Integer> playersWaiting;
private Mail mail;
private List<Random> randoms;
public MailConfirmation(
DatabaseRepository databaseRepo,
Router<PeerAtUser> router,
Configuration config,
@Injection("waitting") Map<String, String> playersWaiting,
String initUsersFilesPath,
String gitToken,
Map<String, Integer> playersWaiting,
Mail mail) throws NoSuchAlgorithmException{
this.databaseRepo = databaseRepo.getAuthRepository();
this.databaseRepo = databaseRepo;
this.router = router;
this.usersFilesPath = config.getUsersFiles();
this.gitToken = config.getGitToken();
this.usersFilesPath = initUsersFilesPath;
this.gitToken = gitToken;
this.playersWaiting = playersWaiting;
this.mail = mail;
@ -74,23 +66,9 @@ 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À-ÖØ-öø-ÿ]+ ?)+$");
validator("firstname", "^(?>[a-zA-Z]+ ?)+$");
validator("lastname", "^(?>[a-zA-Z]+ ?)+$");
}
@RouteDoc(path = "/confirmation", responseCode = 200, responseDescription = "L'utilisateur est inscrit")
@ -109,13 +87,13 @@ public class MailConfirmation extends FormResponse{
return;
}
String email = json.get("email");
String code = json.<String>get("code");
int code = json.<Number>get("code").intValue();
String pseudo = json.get("pseudo");
String firstname = json.get("firstname");
String lastname = json.get("lastname");
String password = json.get("passwd");
String checkCode = playersWaiting.get(email);
Integer checkCode = playersWaiting.get(email);
if(checkCode == null){
context.response(400);
return;
@ -124,7 +102,7 @@ public class MailConfirmation extends FormResponse{
boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo);
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
if(pseudoAvailable && emailAvailable){
if(code.equals(checkCode)){
if(code == checkCode.intValue()){
playersWaiting.remove(email);
int id = databaseRepo.register(pseudo, email, password, firstname, lastname, "", "", "");
if(id >= 0){
@ -139,7 +117,7 @@ public class MailConfirmation extends FormResponse{
error.set("username_valid", pseudo);
error.set("email_valid", email);
writer.write(error.toString());
String ncode = codeGenerator();
int ncode = codeGenerator();
playersWaiting.put(email, ncode);
mail.send(email, "Welcome @ Peer @ Code", "Your check code is "+ncode+" !");
}
@ -155,25 +133,13 @@ public class MailConfirmation extends FormResponse{
}
}
private Constructor<?> uuidBuilder;
private int[] start = {4, 9, 14, 19};
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);
String uuid = uuidBuilder.newInstance(arrayOfByte).toString();
target = this.randoms.get(random.nextInt(this.randoms.size()));
int start = this.start[target.nextInt(this.start.length)];
return uuid.substring(start, start+9);
private int codeGenerator(){
int min = 1000;
int max = 9999;
return new Random().nextInt((max-min)) + min;
}
private void createFolderToSaveSourceCode(String pseudo) throws IOException {
Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo)));

View file

@ -5,7 +5,6 @@ import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.model.Player;
import dev.peerat.backend.repository.DatabasePlayerRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.backend.utils.FormResponse;
import dev.peerat.framework.Context;
@ -17,10 +16,10 @@ import dev.peerat.framework.utils.json.JsonMap;
public class ProfileSettings extends FormResponse{
private DatabasePlayerRepository repo;
private DatabaseRepository repo;
public ProfileSettings(DatabaseRepository repo){
this.repo = repo.getPlayerRepository();
this.repo = repo;
validator("pseudo", "[a-zA-Z0-9&|!?{}\\[\\]%/*\\-+=:;,_#@ ]{3,100}");
}

View file

@ -0,0 +1,70 @@
package dev.peerat.backend.routes.users;
import static dev.peerat.framework.RequestType.POST;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.backend.utils.FormResponse;
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.Route;
import dev.peerat.framework.utils.json.JsonMap;
public class Register extends FormResponse {
private DatabaseRepository databaseRepo;
private Map<String, Integer> playersWaiting;
private Mail mail;
public Register(DatabaseRepository databaseRepo, Map<String, Integer> playersWaiting, Mail mail){
this.databaseRepo = databaseRepo;
this.playersWaiting = playersWaiting;
this.mail = mail;
}
@RouteDoc(path = "/register", responseCode = 200, responseDescription = "L'utilisateur est inscrit")
@RouteDoc(responseCode = 403, responseDescription = "L'utilisateur est connecté")
@RouteDoc(responseCode = 400, responseDescription = "Aucune données fournie / données invalide")
@Route(path = "^\\/register$", type = POST)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
if (context.isLogged()){
context.response(403);
return;
}
JsonMap json = json(reader);
if(!areValids("email")){
context.response(400);
return;
}
String email = json.get("email");
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
if(emailAvailable){
int code = codeGenerator();
playersWaiting.put(email, code);
mail.send(email, "Welcome @ Peer @ Code", "Your check code is "+code+" !");
context.response(200);
}else{
context.response(400);
JsonMap error = new JsonMap();
error.set("email_valid", emailAvailable);
writer.write(error.toString());
}
}
private int codeGenerator(){
int min = 1000;
int max = 9999;
return new Random().nextInt((max-min)) + min;
}
}

View file

@ -1,26 +0,0 @@
package dev.peerat.backend.model;
public class Badge {
private String name;
private byte[] logo;
private int level;
public Badge(String name, byte[] logo, int level) {
this.name = name;
this.logo = logo;
this.level = level;
}
public String getName(){
return name;
}
public byte[] getLogo() {
return logo;
}
public int getLevel() {
return level;
}
}

View file

@ -1,66 +1,26 @@
package dev.peerat.backend.model;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List;
import dev.peerat.mapping.Treasure;
@Treasure
public class Chapter {
private int id;
private String name;
private List<Puzzle> puzzles;
private Timestamp startDate;
private Timestamp endDate;
public Chapter(int id, String name, Timestamp startDate, Timestamp endDate) {
this.id = id;
this.name = name;
this.startDate = startDate;
this.endDate = endDate;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public List<Puzzle> getPuzzles() {
return puzzles;
}
public void setPuzzles(List<Puzzle> puzzles) {
this.puzzles = puzzles;
private int participantCount;
private LocalDateTime start;
private LocalDateTime end;
public int getParticipantCount(){
return this.participantCount;
}
public boolean hasStarted(){
LocalDateTime now = LocalDateTime.now();
boolean show = true;
if(startDate != null) show &= now.isAfter(startDate.toLocalDateTime());
return show;
public LocalDateTime getStartTime(){
return this.start;
}
public Timestamp getStartDate() {
return startDate;
}
public Timestamp getEndDate() {
return endDate;
}
@Override
public boolean equals(Object object) {
if (this == object)
return true;
if (!(object instanceof Chapter))
return false;
return this.id == (((Chapter) object).id);
}
@Override
public int hashCode() {
return id;
public LocalDateTime getEndTime(){
return this.end;
}
}

View file

@ -1,103 +1,51 @@
package dev.peerat.backend.model;
import java.util.Arrays;
import dev.peerat.mapping.Treasure;
@Treasure
public class Completion{
private int puzzleId;
private int playerId;
private PeerAtUser player;
private int tries;
private String fileName;
private byte[] code;
private String file;
private int score;
private String puzzleName;
private int scoreTime;
private int scoreRespect;
private Solution solution;
public Completion(int playerId, int puzzleId, int tries, String fileName, int score){
this(playerId, puzzleId, tries, score, fileName, null, null, null, null);
}
public Completion(int playerId, int puzzleId, int tries, String fileName, int score, String puzzleName) {
this(playerId, puzzleId, tries, score, fileName, null, null, null, puzzleName);
}
public Completion(int playerId, int puzzleId, String fileName, byte[] file, byte[] response, Puzzle currentPuzzle) {
this(playerId, puzzleId, 0, 0, fileName, file, response, currentPuzzle, null);
public Completion(){}
public Completion(PeerAtUser player, String file){
this.player = player;
this.tries = 1;
this.file = file;
}
public Completion(int initTries, int initScore){
// For group leaderboard
this(-1, -1, initTries, initScore, null, null, null, null, null);
}
public Completion(int playerId, int puzzleId, int tries, int score, String fileName, byte[] file, byte[] response,
Puzzle currentPuzzle, String initPuzzleName){
this.playerId = playerId;
this.puzzleId = puzzleId;
this.fileName = fileName;
if (code != null)
this.code = Arrays.copyOf(file, file.length);
// Updated with addTry
this.tries = tries;
this.score = score;
if (currentPuzzle != null)
addTry(currentPuzzle, response, 0);
puzzleName = initPuzzleName;
}
@Override
public String toString(){
return "Completion[puzzleId="+puzzleId+", userId="+playerId+",tries="+tries+",score="+score+"]";
}
public int getPuzzleId() {
return puzzleId;
}
public int getPlayerId() {
return playerId;
}
public int getTries() {
return tries;
}
public void addTry(Puzzle currentPuzzle, byte[] response, int chapter){
if (score <= 0){
tries++;
if (response != null && Arrays.equals(currentPuzzle.getSoluce(), response)){
if (tries > 1) { // Loose 5% each try with a minimum of 1 for score
if(chapter < 4){
score = currentPuzzle.getScoreMax();
}else{
score = (int) Math.ceil(currentPuzzle.getScoreMax() * (1 - ((tries - 1) / 20.)));
}
// score = currentPuzzle.getScoreMax();
if (score < 1)
score = 1;
} else
score = currentPuzzle.getScoreMax();
}
}
public PeerAtUser getPlayer(){
return this.player;
}
public void updatePlayer(int playerId){
this.playerId = playerId;
}
public String getFileName() {
return fileName;
public int getTries(){
return this.tries;
}
public String getPuzzleName() {
return puzzleName;
public String getFileName(){
return this.file;
}
public byte[] getCode() {
return code;
public int getScore(){
return this.score;
}
public int getScore() {
return score;
public int getScoreTime(){
return this.scoreTime;
}
public int getScoreRespect(){
return this.scoreRespect;
}
public Solution getSolution(){
return this.solution;
}
}

View file

@ -1,159 +1,32 @@
package dev.peerat.backend.model;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.jose4j.json.internal.json_simple.JSONArray;
import org.jose4j.json.internal.json_simple.JSONObject;
import dev.peerat.mapping.Treasure;
import be.jeffcheasey88.peeratcode.mapping.SeaBottle;
import dev.peerat.framework.utils.json.JsonMap;
@Treasure
public class Group {
public class Group implements Comparable<Group> {
private String name;
private Integer linkToChapter;
// private Integer linkToPuzzle;
private List<Player> players;
private int playerCount;
private List<PeerAtUser> players;
private Puzzle puzzle;
private Chapter chapter;
@Override
public String toString(){
return "Group[name="+name+", chapter="+linkToChapter+"]";
}
public Group(JsonMap json){
this.name = (String) json.get("name");
if (json.has("chapter"))
this.linkToChapter = ((Number) json.get("chapter")).intValue();
// if (json.has("puzzle"))
// this.linkToPuzzle = ((Number) json.get("puzzle")).intValue();
}
public Group(String name, Integer initChap, Integer initPuzz, int playerCount) {
this.name = name;
this.linkToChapter = initChap;
// this.linkToPuzzle = initPuzz;
this.playerCount = playerCount;
public Group(){}
public String getName(){
return this.name;
}
public int getPlayerCount(){
return this.playerCount;
public List<PeerAtUser> getPlayers(){
return this.players;
}
@SeaBottle
public static Group getGroup(int player){
return null;
public Puzzle getPuzzle(){
return this.puzzle;
}
public void addPlayer(Player newPlayer) {
if (newPlayer != null) {
if (players == null)
players = new ArrayList<Player>();
int pPosition = players.indexOf(newPlayer);
if (pPosition < 0) {
players.add(newPlayer);
} else {
players.get(pPosition).addCompletion(new Completion(newPlayer.getTotalTries(), newPlayer.getTotalScore()));
}
}
}
public int getScore() {
int score = 0;
if (players != null) {
for (Player p : players) {
score = score + p.getTotalScore();
}
}
return score;
}
public int getTries() {
int tries = 0;
if (players != null) {
for (Player p : players) {
tries = tries + p.getTotalTries();
}
}
return tries;
}
public String getName() {
return name;
}
public Integer getLinkToChapter() {
return linkToChapter;
}
// public Integer getLinkToPuzzle() {
// return linkToPuzzle;
// }
public JSONObject toJson() {
return this.toJson(null);
}
public JSONObject toJson(Integer rank) {
JSONObject groupJSON = new JSONObject();
groupJSON.put("name", name);
if (rank != null)
groupJSON.put("rank", rank);
else if (linkToChapter != null)
groupJSON.put("chapter", linkToChapter);
// else if (linkToPuzzle != null)
// groupJSON.put("puzzle", linkToPuzzle);
if (players != null) {
JSONArray groupsPlayerJSON = new JSONArray();
for (Player p : players) {
JSONObject playerJSON = new JSONObject();
playerJSON.put("pseudo", p.getPseudo());
playerJSON.put("score", p.getTotalScore());
playerJSON.put("completion", p.getTotalCompletion());
playerJSON.put("tries", p.getTotalTries());
groupsPlayerJSON.add(playerJSON);
}
groupJSON.put("players", groupsPlayerJSON);
}
groupJSON.put("playerCount", this.playerCount);
return groupJSON;
}
@Override
public int compareTo(Group arg0) {
int comparo = arg0.getScore() - getScore();
if (comparo == 0) {
comparo = players.size() - arg0.players.size();
if (comparo == 0) {
comparo = getTries() - arg0.getTries();
if (comparo == 0) {
comparo = name.compareTo(arg0.name);
}
}
}
return comparo;
}
@Override
public int hashCode(){
return Objects.hash(name);
}
@Override
public boolean equals(Object obj){
if(obj == this) return true;
if(obj == null) return false;
if(!(obj instanceof Group)) return false;
Group other = (Group) obj;
return this.name.equals(other.name) && integerEquals(this.linkToChapter, other.linkToChapter); // && integerEquals(this.linkToPuzzle, other.linkToPuzzle);
}
private boolean integerEquals(Integer a, Integer b){
if(a == null) return b == null;
return a.equals(b);
public Chapter getChapter(){
return this.chapter;
}
}

View file

@ -2,9 +2,17 @@ package dev.peerat.backend.model;
import org.jose4j.jwt.JwtClaims;
public class PeerAtUser extends dev.peerat.framework.User{
import dev.peerat.mapping.Treasure;
@Treasure
public class PeerAtUser extends dev.peerat.framework.User{
private int id;
private String pseudo;
private String email;
private String fistName;
private String lastName;
private School school;
public PeerAtUser(int id){
this.id = id;
@ -23,6 +31,23 @@ public class PeerAtUser extends dev.peerat.framework.User{
return this.id;
}
public String getPseudo(){
return this.pseudo;
}
public String getEmail(){
return this.email;
}
public String getFirstName(){
return this.fistName;
}
public String getLastName(){
return this.lastName;
}
public School getSchool(){
return this.school;
}
}

View file

@ -1,207 +0,0 @@
package dev.peerat.backend.model;
import java.util.Base64;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import dev.peerat.framework.utils.json.JsonArray;
import dev.peerat.framework.utils.json.JsonMap;
public class Player implements Comparable<Player> {
private String pseudo;
private String email;
private String firstname;
private String lastname;
private String description;
private Set<Group> groups;
private Set<Completion> completions = new HashSet<Completion>();
private byte[] avatar;
private int rank;
private Set<Badge> badges;
public Player(String pseudo, String email, String firstname, String lastname) {
this.pseudo = pseudo;
this.email = email;
this.firstname = firstname;
this.lastname = lastname;
this.description = "";
}
public Player(String pseudo, int score, int tries) {
// For groups leaderboard
this.pseudo = pseudo;
this.completions.add(new Completion(tries, score));
email = ""; // TO make compareTo and equals works as usual
}
public Player(String email) {
// For player find in Map during register process
this.email = email;
}
public void setPseudo(String pseudo){
this.pseudo = pseudo;
}
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 Set<Group> getGroups() {
return groups;
}
public JsonArray getJsonGroups() {
if (groups != null) {
JsonArray groupsJSON = new JsonArray();
for (Group group : groups) {
groupsJSON.add(group.toJson());
}
return groupsJSON;
}
return null;
}
public void addGroup(Group newGroup) {
if (newGroup != null) {
if (this.groups == null)
this.groups = new HashSet<Group>();
this.groups.add(newGroup);
}
}
public byte[] getAvatar() {
return this.avatar;
}
public void setAvatar(byte[] newAvatar) {
avatar = newAvatar;
}
public int getRank() {
return rank;
}
public void setRank(int newRank) {
rank = newRank;
}
public void addCompletion(Completion makeCompletion) {
completions.add(makeCompletion);
}
public int getTotalScore() {
int totalScore = 0;
for (Completion c: completions) {
totalScore = totalScore + c.getScore();
}
return totalScore;
}
public int getTotalCompletion() {
return completions.size();
}
public JsonArray getJsonCompletions() {
JsonArray completionsJSON = new JsonArray();
for (Completion completion : completions) {
JsonMap completionJSON = new JsonMap();
completionJSON.set("puzzleName", completion.getPuzzleName());
completionJSON.set("tries", completion.getTries());
completionJSON.set("score", completion.getScore());
completionsJSON.add(completionJSON);
}
return completionsJSON;
}
public int getTotalTries() {
int totalTries = 0;
for (Completion c: completions) {
totalTries = totalTries + c.getTries();
}
return totalTries;
}
public Set<Badge> getBadges() {
return badges;
}
public JsonArray getJsonBadges() {
if (badges == null)
return null;
JsonArray badgesJSON = new JsonArray();
for (Badge badge : badges) {
JsonMap badgeJSON = new JsonMap();
badgeJSON.set("name", badge.getName());
byte[] logo = badge.getLogo();
if (logo != null)
badgeJSON.set("logo", Base64.getEncoder().encodeToString(logo));
badgeJSON.set("level", badge.getLevel());
badgesJSON.add(badgeJSON);
}
return badgesJSON;
}
public void addBadge(Badge newBadge) {
if (newBadge != null) {
if (badges == null)
badges = new HashSet<Badge>();
badges.add(newBadge);
}
}
@Override
public int compareTo(Player other) {
if (this == other)
return 0;
if (other == null)
return -1;
int compare = Integer.compare(other.getTotalScore(), getTotalScore());
if (compare == 0) {
compare = Integer.compare(other.getTotalCompletion(), getTotalCompletion());
if (compare == 0) {
compare = Integer.compare(getTotalTries(), other.getTotalTries());
if (compare == 0)
compare = other.getPseudo().compareTo(pseudo);
}
}
return compare;
}
@Override
public int hashCode(){
return Objects.hash(email, pseudo);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Player other = (Player) obj;
return Objects.equals(email, other.email) && Objects.equals(pseudo, other.pseudo);
}
}

View file

@ -1,109 +1,30 @@
package dev.peerat.backend.model;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import dev.peerat.framework.utils.json.JsonArray;
import dev.peerat.framework.utils.json.JsonMap;
import dev.peerat.mapping.Treasure;
public class Puzzle {
@Treasure
public class Puzzle{
private int id;
private String name;
private String content;
private byte[] soluce;
private String verify;
private int scoreMax;
private Set<String> tags;
private int depend;
private Timestamp startDate;
public Puzzle(int id, String name, String content, byte[] soluce, String verify, int scoreMax, String tags,
int depend, Timestamp startDate) {
this.id = id;
this.name = name;
this.content = content;
this.soluce = soluce;
this.verify = verify;
this.scoreMax = scoreMax;
setTags(tags);
this.depend = depend;
this.startDate = startDate;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public String getContent() {
return content;
}
public byte[] getSoluce() {
return this.soluce;
}
public int getScoreMax() {
return this.scoreMax;
}
public Set<String> getTags() {
return this.tags;
}
/**
* DO NOT EVER EVER SHOW TO MISTER LUDWIG XD
*
* @return DEATH
*/
public JsonArray getJsonTags() {
if (tags == null)
return null;
JsonArray tagsJSON = new JsonArray();
for (String tag : tags) {
JsonMap tagJSON = new JsonMap();
tagJSON.set("name", tag);
tagsJSON.add(tagJSON);
}
return tagsJSON;
}
public void setTags(String tags) {
if (tags == null || tags.isEmpty())
this.tags = null;
else
this.tags = new HashSet<String>(Arrays.asList(tags.split(",")));
}
public int getDepend() {
return this.depend;
private int participantCount;
private LocalDateTime start;
private LocalDateTime end;
private Chapter chapter;
public int getParticipantCount(){
return this.participantCount;
}
public boolean hasStarted(){
LocalDateTime now = LocalDateTime.now();
boolean show = true;
if(startDate != null) show &= now.isAfter(startDate.toLocalDateTime());
return show;
public LocalDateTime getStartTime(){
return this.start;
}
@Override
public boolean equals(Object object) {
if (this == object)
return true;
if (!(object instanceof Puzzle))
return false;
return this.id == (((Puzzle) object).id);
public LocalDateTime getEndTime(){
return this.end;
}
@Override
public int hashCode() {
return id;
public Chapter getChapter(){
return this.chapter;
}
}

View file

@ -0,0 +1,17 @@
package dev.peerat.backend.model;
import dev.peerat.mapping.Treasure;
@Treasure
public class School{
private String name;
public School(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}

View file

@ -0,0 +1,39 @@
package dev.peerat.backend.model;
import dev.peerat.mapping.Treasure;
@Treasure
public class Solution{
private Puzzle puzzle;
private byte[] answer;
private String verify;
private int scoreMax;
private int scoreMaxTime;
private int ScoreMaxRespect;
public Puzzle getPuzzle(){
return this.puzzle;
}
public byte[] getAnswer(){
return answer;
}
public String getVerify(){
return verify;
}
public int getScoreMax(){
return scoreMax;
}
public int getScoreMaxTime(){
return scoreMaxTime;
}
public int getScoreMaxRespect(){
return ScoreMaxRespect;
}
}

View file

@ -1,30 +0,0 @@
package dev.peerat.backend.model;
import dev.peerat.framework.utils.json.JsonMap;
public class Tag{
private int id;
private String name;
public Tag(int id, String name){
this.id = id;
this.name = name;
}
public int getId(){
return this.id;
}
public String getName(){
return this.name;
}
public JsonMap toJson(){
JsonMap result = new JsonMap();
result.set("id", id);
result.set("name", name);
return result;
}
}

View file

@ -1,114 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.model.Badge;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.Completion;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.Player;
import dev.peerat.backend.model.Puzzle;
public class BaseDatabaseQuery{
private ConnectionManager con;
private Configuration config;
public BaseDatabaseQuery(ConnectionManager con){
this.con = con;
}
public Connection ensureConnection() throws SQLException{
return this.con.ensureConnection();
}
public PreparedStatement prepare(String request) throws SQLException{
return this.con.ensureConnection().prepareStatement(request);
}
public Puzzle makePuzzle(ResultSet puzzleResult) throws SQLException {
return new Puzzle(puzzleResult.getInt("id_puzzle"), puzzleResult.getString("name"),
puzzleResult.getString("content"), puzzleResult.getBytes("soluce"), puzzleResult.getString("verify"),
puzzleResult.getInt("score_max"), puzzleResult.getString("tags"),
hasColumn(puzzleResult, "origin") ? puzzleResult.getInt("origin") : -1,
puzzleResult.getTimestamp("start_date"));
}
public Chapter makeChapter(ResultSet chapterResult) throws SQLException {
return new Chapter(chapterResult.getInt("id_chapter"), chapterResult.getString("name"),
chapterResult.getTimestamp("start_date"), chapterResult.getTimestamp("end_date"));
}
public Completion makeCompletion(ResultSet completionResult) throws SQLException {
String fileName = null;
if (hasColumn(completionResult, "fileName"))
fileName = completionResult.getString("fileName");
String puzzleName = null;
if (hasColumn(completionResult, "name"))
puzzleName = completionResult.getString("name");
return new Completion(completionResult.getInt("fk_player"), completionResult.getInt("fk_puzzle"), completionResult.getInt("tries"),
fileName, completionResult.getInt("score"), puzzleName);
}
public Player makePlayer(ResultSet playerResult, int id) throws SQLException {
Player p = new Player(playerResult.getString("pseudo"), playerResult.getString("email"),
playerResult.getString("firstName"), playerResult.getString("lastName"));
if (hasColumn(playerResult, "avatar")) {
p.setAvatar(playerResult.getBytes("avatar"));
}
if (hasColumn(playerResult, "score")) {
p.addCompletion(new Completion(playerResult.getInt("tries"), playerResult.getInt("score")));
for (int ct = 1; ct < playerResult.getInt("completions"); ct++)
{ // TODO refactor for V3
p.addCompletion(new Completion(0, 0));
}
}
if (hasColumn(playerResult, "name")) {
// Manage groups
String groupName = playerResult.getString("name");
if (groupName != null) {
p.addGroup(makeGroup(playerResult));
}
}
// ADD rank
PreparedStatement completionsStmt = con.ensureConnection().prepareStatement(DatabasePlayerRepository.GET_PLAYER_RANK());
completionsStmt.setInt(1, id);
ResultSet result = completionsStmt.executeQuery();
while (result.next()) {
p.setRank(result.getInt("rank"));
}
return p;
}
public Group makeGroup(ResultSet result) throws SQLException {
return new Group(result.getString("name"), result.getInt("fk_chapter"), result.getInt("fk_puzzle"), ((hasColumn(result, "countPlayer")) ? result.getInt("countPlayer") : 0));
}
public Player makeGroupPlayer(ResultSet result) throws SQLException {
return new Player(result.getString("pseudo"), result.getInt("score"), result.getInt("tries"));
}
public Badge makeBadge(ResultSet rs) throws SQLException {
return new Badge(rs.getString("name"), rs.getBytes("logo"), rs.getInt("level"));
}
public boolean hasColumn(ResultSet rs, String columnName) throws SQLException {
// Found on StackOverflow
ResultSetMetaData rsmd = rs.getMetaData();
int columns = rsmd.getColumnCount();
for (int x = 1; x <= columns; x++) {
if (columnName.equals(rsmd.getColumnName(x)))
return true;
}
return false;
}
}

View file

@ -1,26 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import dev.peerat.backend.Configuration;
public class ConnectionManager {
private Connection con;
private Configuration config;
public ConnectionManager(Configuration config){
this.config = config;
}
public Connection ensureConnection() throws SQLException {
if (con == null || (!con.isValid(5))) {
this.con = DriverManager.getConnection(
"jdbc:mysql://" + config.getDbHost() + ":" + config.getDbPort() + "/" + config.getDbDatabase() + "",
config.getDbUser(), config.getDbPassword());
}
return this.con;
}
}

View file

@ -1,194 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.Puzzle;
import dev.peerat.backend.model.Tag;
public class DatabaseAdminRepository extends BaseDatabaseQuery{
private static enum Query{
//ADMIN
ADD_CHAPTER("INSERT INTO chapters (name, start_date, end_date) VALUES (?,?,?)"),
DELETE_CHAPTER("DELETE FROM chapters WHERE id_chapter = ?"),
EDIT_CHAPTER("UPDATE chapters SET name = ?, start_date = ?, end_date = ? WHERE id_chapter = ?"),
GET_CHAPTER("SELECT * FROM chapters WHERE id_chapter = ?"),
ADD_PUZZLE("INSERT INTO puzzles (name, content, soluce, verify, score_max, fk_chapter) VALUES (?,?,?,?,?,?)"),
DELETE_PUZZLE("DELETE FROM puzzles WHERE id_puzzle = ?"),
EDIT_PUZZLE("UPDATE puzzles SET name = ?, content = ?, soluce = ?, verify = ?, score_max = ?, fk_chapter = ? WHERE id_puzzle = ?"),
GET_PUZZLE("SELECT p.*, GROUP_CONCAT(t.name) AS tags FROM puzzles p LEFT JOIN containsTags ct ON ct.fk_puzzle = p.id_puzzle LEFT JOIN tags t ON t.id_tag = ct.fk_tag WHERE p.id_puzzle = ? GROUP BY p.id_puzzle"),
GET_PUZZLES("SELECT p.*, GROUP_CONCAT(t.name) AS tags FROM puzzles p LEFT JOIN containsTags ct ON ct.fk_puzzle = p.id_puzzle LEFT JOIN tags t ON t.id_tag = ct.fk_tag GROUP BY p.id_puzzle"),
ADD_TAG("INSERT INTO tags (name) VALUES (?)"),
DELETE_TAG("DELETE FROM tags WHERE id_tag = ?"),
EDIT_TAG("UPDATE tags SET name = ? WHERE id_tag = ?"),
GET_TAGS("SELECT * FROM tags");
private String request;
Query(Query parent, String request) {
this.request = parent.request + request;
}
Query(String request) {
this.request = request;
}
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
return base.prepare(this.request);
}
@Override
public String toString() {
return this.request;
}
}
private Configuration config;
public DatabaseAdminRepository(ConnectionManager con, Configuration config){
super(con);
this.config = config;
}
//ADMIN
public Chapter getAdminChapter(int id){
try {
PreparedStatement chapterStmt = Query.GET_CHAPTER.prepare(this);
chapterStmt.setInt(1, id);
ResultSet chapterResult = chapterStmt.executeQuery();
if (chapterResult.next()) {
Chapter chapter = makeChapter(chapterResult);
return chapter;
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public Puzzle getAdminPuzzle(int id){
try {
PreparedStatement chapterStmt = Query.GET_PUZZLE.prepare(this);
chapterStmt.setInt(1, id);
ResultSet chapterResult = chapterStmt.executeQuery();
if (chapterResult.next()) {
return makePuzzle(chapterResult);
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public List<Puzzle> getAdminPuzzles(){
try {
PreparedStatement chapterStmt = Query.GET_PUZZLES.prepare(this);
ResultSet chapterResult = chapterStmt.executeQuery();
List<Puzzle> list = new ArrayList<>();
while(chapterResult.next()){
list.add(makePuzzle(chapterResult));
}
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public List<Tag> getAdminTags(){
try {
PreparedStatement chapterStmt = Query.GET_TAGS.prepare(this);
ResultSet chapterResult = chapterStmt.executeQuery();
List<Tag> list = new ArrayList<>();
while(chapterResult.next()){
list.add(new Tag(chapterResult.getInt("id_tag"), chapterResult.getString("name")));
}
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public boolean adminAddChapter(Chapter chapter) throws SQLException {
PreparedStatement statement = Query.ADD_CHAPTER.prepare(this);
statement.setString(1, chapter.getName());
statement.setTimestamp(2, chapter.getStartDate());
statement.setTimestamp(3, chapter.getEndDate());
return (statement.executeUpdate() >= 0);
}
public boolean adminAddPuzzle(Puzzle puzzle, int chapter) throws SQLException {
PreparedStatement statement = Query.ADD_PUZZLE.prepare(this);
statement.setString(1, puzzle.getName());
statement.setString(2, puzzle.getContent());
statement.setBytes(3, puzzle.getSoluce());
statement.setString(4, "");
statement.setInt(5, puzzle.getScoreMax());
statement.setInt(6, chapter);
return (statement.executeUpdate() >= 0);
}
public boolean adminAddTag(String name) throws SQLException {
PreparedStatement statement = Query.ADD_TAG.prepare(this);
statement.setString(1, name);
return (statement.executeUpdate() >= 0);
}
public boolean adminUpdateChapter(int id, Chapter chapter) throws SQLException {
PreparedStatement statement = Query.EDIT_CHAPTER.prepare(this);
statement.setString(1, chapter.getName());
statement.setTimestamp(2, chapter.getStartDate());
statement.setTimestamp(3, chapter.getEndDate());
statement.setInt(4, id);
return (statement.executeUpdate() >= 0);
}
public boolean adminUpdatePuzzle(int id, Puzzle puzzle, int chapter) throws SQLException {
PreparedStatement statement = Query.EDIT_PUZZLE.prepare(this);
statement.setString(1, puzzle.getName());
statement.setString(2, puzzle.getContent());
statement.setBytes(3, puzzle.getSoluce());
statement.setString(4, "");
statement.setInt(5, puzzle.getScoreMax());
statement.setInt(6, chapter);
statement.setInt(7, id);
return (statement.executeUpdate() >= 0);
}
public boolean adminUpdateTag(Tag tag) throws SQLException {
PreparedStatement statement = Query.EDIT_TAG.prepare(this);
statement.setString(1, tag.getName());
statement.setInt(2, tag.getId());
return (statement.executeUpdate() >= 0);
}
public boolean adminDeleteChapter(int id) throws SQLException {
PreparedStatement statement = Query.DELETE_CHAPTER.prepare(this);
statement.setInt(1, id);
return (statement.executeUpdate() >= 0);
}
public boolean adminDeletePuzzle(int id) throws SQLException {
PreparedStatement statement = Query.DELETE_PUZZLE.prepare(this);
statement.setInt(1, id);
return (statement.executeUpdate() >= 0);
}
public boolean adminDeleteTag(int id) throws SQLException {
PreparedStatement statement = Query.DELETE_TAG.prepare(this);
statement.setInt(1, id);
return (statement.executeUpdate() >= 0);
}
}

View file

@ -1,167 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.password4j.Password;
import dev.peerat.backend.Configuration;
public class DatabaseAuthRepository extends BaseDatabaseQuery{
private static enum Query{
// REGISTER
CHECK_PSEUDO_AVAILABLE_QUERY("SELECT * FROM players WHERE pseudo = ?"),
CHECK_EMAIL_AVAILABLE_QUERY("SELECT * FROM players WHERE email = ?"),
REGISTER_QUERY(
"INSERT INTO players (pseudo, email, passwd, firstname, lastname, description, avatar) VALUES (?, ?, ?, ?, ?, ?, ?)"),
REGISTER_PLAYER_IN_EXISTING_GROUP(
"INSERT INTO containsGroups (fk_player, fk_group) VALUES (?, (SELECT id_group FROM groups WHERE name = ?));"),
// LOGIN
CHECK_PASSWORD("SELECT id_player, passwd FROM players WHERE pseudo=?");
private String request;
Query(Query parent, String request) {
this.request = parent.request + request;
}
Query(String request) {
this.request = request;
}
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
return base.prepare(this.request);
}
@Override
public String toString() {
return this.request;
}
}
private Configuration config;
public DatabaseAuthRepository(ConnectionManager con, Configuration config){
super(con);
this.config = config;
}
/**
* Check if a pseudo is available
*
* @param pseudo The pseudo to check
* @return True if the pseudo is available, false if it's already taken
*/
public boolean checkPseudoAvailability(String pseudo) {
return checkAvailability(pseudo, Query.CHECK_PSEUDO_AVAILABLE_QUERY.toString());
}
/**
* Check if an email is available
*
* @param email The email to check
* @return True if the email is available, false if it's already taken
*/
public boolean checkEmailAvailability(String email) {
return checkAvailability(email, Query.CHECK_EMAIL_AVAILABLE_QUERY.toString());
}
private boolean checkAvailability(String queriedString, String correspondingQuery) {
try {
PreparedStatement statement = prepare(correspondingQuery);
statement.setString(1, queriedString);
ResultSet result = statement.executeQuery();
return !result.next();
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
/**
* Register a new user
*
* @param pseudo The pseudo of the user
* @param email The email of the user
* @param password The password of the user
* @param firstname The firstname of the user
* @param lastname The lastname of the user
* @param description The description of the user
* @param sgroup The group of the user
* @param avatar The avatar of the user
* @return True if the user was registered, false if an error occurred
*/
public int register(String pseudo, String email, String password, String firstname, String lastname,
String description, String sgroup, String avatar) {
try {
String pass = Password.hash(password).withArgon2().getResult();
System.out.println("pass("+pass.length()+") "+pass);
Connection con = ensureConnection();
con.setAutoCommit(false);
try (PreparedStatement playerStatement = con.prepareStatement(Query.REGISTER_QUERY.toString(),
Statement.RETURN_GENERATED_KEYS)) {
playerStatement.setString(1, pseudo);
playerStatement.setString(2, email);
playerStatement.setString(3, Password.hash(password).withArgon2().getResult());
playerStatement.setString(4, firstname);
playerStatement.setString(5, lastname);
playerStatement.setString(6, description);
playerStatement.setString(7, avatar);
if (playerStatement.executeUpdate() == 1) {
ResultSet inserted = playerStatement.getGeneratedKeys();
if (inserted.next()) {
int newPlayerId = inserted.getInt(1);
if (!sgroup.isEmpty()) {
try (PreparedStatement containsGroupsStatement = con
.prepareStatement(Query.REGISTER_PLAYER_IN_EXISTING_GROUP.toString())) {
containsGroupsStatement.setInt(1, newPlayerId);
containsGroupsStatement.setString(2, sgroup);
containsGroupsStatement.executeUpdate();
}
}
con.commit();
con.setAutoCommit(true);
return newPlayerId;
}
}
} catch (SQLException e) {
con.rollback();
con.setAutoCommit(true);
e.printStackTrace();
}
} catch (SQLException e) {
e.printStackTrace();
}
return -1;
}
/**
* Login a user
*
* @param username The username of the user
* @param password The password of the user
* @return id the id of the user, -1 if not login successefuly
*/
public int login(String username, String password) {
try {
ensureConnection();
PreparedStatement statement = prepare(Query.CHECK_PASSWORD.toString());
statement.setString(1, username);
ResultSet result = statement.executeQuery();
if (result.next()) {
String hashedPassword = result.getString("passwd");
if (Password.check(password, hashedPassword).withArgon2())
return result.getInt("id_player");
}
} catch (SQLException e) {
}
return -1;
}
}

View file

@ -1,69 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.model.Badge;
import dev.peerat.backend.model.Puzzle;
public class DatabaseBadgeRepository extends BaseDatabaseQuery{
public static String GET_BADGES_OF_PLAYER(){
return Query.GET_BADGES_OF_PLAYER.request;
}
private static enum Query{
// BADGES
GET_BADGE("SELECT * FROM badges WHERE id_badge = ?"),
GET_BADGES_OF_PLAYER(
"SELECT * FROM badges b LEFT JOIN containsBadges cb ON cb.fk_badge = b.id_badge WHERE cb.fk_player = ?");
private String request;
Query(Query parent, String request) {
this.request = parent.request + request;
}
Query(String request) {
this.request = request;
}
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
return base.prepare(this.request);
}
@Override
public String toString() {
return this.request;
}
}
private Configuration config;
public DatabaseBadgeRepository(ConnectionManager con, Configuration config){
super(con);
this.config = config;
}
public Badge getBadge(int badgeId) {
try {
ensureConnection();
PreparedStatement completionsStmt = Query.GET_BADGE.prepare(this);
completionsStmt.setInt(1, badgeId);
ResultSet result = completionsStmt.executeQuery();
if (result.next()) {
return makeBadge(result);
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}

View file

@ -1,122 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.Puzzle;
public class DatabaseChapterRepository extends BaseDatabaseQuery{
private static enum Query{
// CHAPTERS
SPECIFIC_CHAPTER_QUERY("SELECT * FROM chapters WHERE id_chapter = ?"),
CHAPTER_FROM_PUZZLE("SELECT c.*\r\n"
+ "FROM chapters c\r\n"
+ "JOIN puzzles p ON p.fk_chapter = c.id_chapter\r\n"
+ "WHERE p.id_puzzle = ?"),
ALL_CHAPTERS_QUERY("SELECT * FROM chapters WHERE id_chapter > 0");
private String request;
Query(Query parent, String request) {
this.request = parent.request + request;
}
Query(String request) {
this.request = request;
}
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
return base.prepare(this.request);
}
@Override
public String toString() {
return this.request;
}
}
private Configuration config;
private DatabasePuzzleRepository puzzleRepo;
public DatabaseChapterRepository(ConnectionManager con, Configuration config, DatabasePuzzleRepository puzzleRepo){
super(con);
this.config = config;
this.puzzleRepo = puzzleRepo;
}
/**
* Get a specific chapter
*
* @param id The id of the chapter
* @return The chapter or null if an error occurred
*/
public Chapter getChapter(int id) {
try {
ensureConnection();
PreparedStatement chapterStmt = Query.SPECIFIC_CHAPTER_QUERY.prepare(this);
chapterStmt.setInt(1, id);
ResultSet chapterResult = chapterStmt.executeQuery();
if (chapterResult.next()) {
Chapter chapter = makeChapter(chapterResult);
List<Puzzle> puzzles = puzzleRepo.getPuzzlesInChapter(id);
chapter.setPuzzles(puzzles);
return chapter;
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public Chapter getChapter(Puzzle puzzle){
try {
ensureConnection();
PreparedStatement chapterStmt = Query.CHAPTER_FROM_PUZZLE.prepare(this);
chapterStmt.setInt(1, puzzle.getId());
ResultSet chapterResult = chapterStmt.executeQuery();
if (chapterResult.next()) {
Chapter chapter = makeChapter(chapterResult);
List<Puzzle> puzzles = puzzleRepo.getPuzzlesInChapter(chapter.getId());
chapter.setPuzzles(puzzles);
return chapter;
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* Get all chapters in the database
*
* @return List of all chapters or null if an error occurred
*/
public List<Chapter> getAllChapters() {
try {
List<Chapter> chapterList = new ArrayList<>();
ensureConnection();
PreparedStatement chapterStmt = Query.ALL_CHAPTERS_QUERY.prepare(this);
ResultSet chapterResult = chapterStmt.executeQuery();
while (chapterResult.next()) {
Chapter chapter = makeChapter(chapterResult);
chapter.setPuzzles(puzzleRepo.getPuzzlesInChapter(chapter.getId()));
chapterList.add(chapter);
}
return chapterList;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}

View file

@ -1,162 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.model.Completion;
import dev.peerat.backend.model.Puzzle;
public class DatabaseCompletionRepository extends BaseDatabaseQuery{
private static enum Query{
// COMPLETIONS
GET_COMPLETION(
"SELECT * FROM completions WHERE fk_puzzle = ? AND fk_player = ?"),
GET_COMPLETION_GROUP("SELECT c.*\r\n"
+ "FROM completions c\r\n"
+ "WHERE c.fk_puzzle = ? AND c.fk_player IN\r\n"
+ "(select f.fk_player FROM containsGroups cgs JOIN containsGroups f ON f.fk_group = cgs.fk_group JOIN groups g ON g.id_group = cgs.fk_group WHERE g.fk_chapter = 12 AND cgs.fk_player = ?)"),
INSERT_COMPLETION(
"INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)"),
UPDATE_COMPLETION(
"UPDATE completions SET tries = ?, score = ?, fk_player = ? WHERE fk_puzzle = ? AND fk_player = ?"),
SCORE("SELECT score FROM completions WHERE fk_player = ? AND fk_puzzle = ?"),
SCORE_GROUP("SELECT c.score\r\n"
+ "FROM completions c\r\n"
+ "WHERE c.fk_puzzle = ? AND c.fk_player IN\r\n"
+ "(select f.fk_player FROM containsGroups cgs JOIN containsGroups f ON f.fk_group = cgs.fk_group JOIN groups g ON g.id_group = cgs.fk_group WHERE g.fk_chapter = 12 AND cgs.fk_player = ?)");
private String request;
Query(Query parent, String request) {
this.request = parent.request + request;
}
Query(String request) {
this.request = request;
}
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
return base.prepare(this.request);
}
@Override
public String toString() {
return this.request;
}
}
private Configuration config;
private DatabaseChapterRepository chapterRepo;
public DatabaseCompletionRepository(ConnectionManager con, Configuration config, DatabaseChapterRepository chapterRepo){
super(con);
this.config = config;
this.chapterRepo = chapterRepo;
}
public Completion getCompletionGroup(int user, int puzzle) {
try {
PreparedStatement stmt = Query.GET_COMPLETION_GROUP.prepare(this);
stmt.setInt(1, puzzle);
stmt.setInt(2, user);
ResultSet result = stmt.executeQuery();
if (result.next())
return makeCompletion(result);
} catch (SQLException e) {
e.printStackTrace();
}
return getCompletion(user, puzzle);
}
public Completion getCompletion(int playerId, int puzzleId) {
try {
PreparedStatement completionsStmt = Query.GET_COMPLETION.prepare(this);
completionsStmt.setInt(1, puzzleId);
completionsStmt.setInt(2, playerId);
ResultSet result = completionsStmt.executeQuery();
if (result.next()) {
return makeCompletion(result);
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public Completion insertOrUpdatePuzzleResponse(int puzzleId, int userId, String fileName, byte[] code,
byte[] response, Puzzle currentPuzzle){
try {
ensureConnection();
Completion completion = getCompletionGroup(userId, puzzleId);
if (completion == null){
System.out.println("Completion is null");
completion = new Completion(userId, puzzleId, fileName, code, response, currentPuzzle);
insertCompletion(completion);
} else {
System.out.println(completion);
completion.addTry(currentPuzzle, response, chapterRepo.getChapter(currentPuzzle).getId());
int lastUserId = completion.getPlayerId();
completion.updatePlayer(userId);
updateCompletion(completion, lastUserId);
}
return completion;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
private void insertCompletion(Completion newCompletion) throws SQLException {
PreparedStatement statement = Query.INSERT_COMPLETION.prepare(this);
statement.setInt(1, newCompletion.getPuzzleId());
statement.setInt(2, newCompletion.getPlayerId());
statement.setInt(3, newCompletion.getTries());
statement.setBytes(4, newCompletion.getCode());
statement.setString(5, newCompletion.getFileName());
statement.setInt(6, newCompletion.getScore());
statement.executeUpdate();
}
private void updateCompletion(Completion completionToUpdate, int user) throws SQLException{
System.out.println("update "+completionToUpdate);
PreparedStatement statement = Query.UPDATE_COMPLETION.prepare(this);
statement.setInt(1, completionToUpdate.getTries());
statement.setInt(2, completionToUpdate.getScore());
statement.setInt(3, completionToUpdate.getPlayerId());
statement.setInt(4, completionToUpdate.getPuzzleId());
statement.setInt(5, user);
statement.executeUpdate();
}
public int getScore(int user, int puzzle) {
try {
ensureConnection();
PreparedStatement stmt = Query.SCORE_GROUP.prepare(this);
stmt.setInt(1, puzzle);
stmt.setInt(2, user);
ResultSet result = stmt.executeQuery();
if (result.next())
return result.getInt("score");
stmt = Query.SCORE.prepare(this);
stmt.setInt(1, user);
stmt.setInt(2, puzzle);
result = stmt.executeQuery();
if (result.next())
return result.getInt("score");
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
}

View file

@ -1,166 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.PeerAtUser;
public class DatabaseGroupRepository extends BaseDatabaseQuery{
private static enum Query{
// GROUPS
ALL_GROUPS("SELECT * FROM groups"),
ALL_GROUPS_BY_CHAPTER("select g.*, count(cg.fk_player) as countPlayer from groups g left join containsGroups cg on cg.fk_group = g.id_group where g.fk_chapter = ? group by g.id_group"),
GET_GROUP_FOR_PLAYER("SELECT g.* FROM groups g JOIN containsGroups cg ON cg.fk_group = g.id_group WHERE cg.fk_player = ? AND g.fk_chapter = ?"), // AND g.fk_puzzle = ?
GET_GROUP_ID_BY_DATA("SELECT id_group FROM groups WHERE name = ? AND (fk_chapter = ?)"), // OR fk_puzzle = ?
GET_GROUP_USERS_COUNT("SELECT count(*) as howmany FROM containsGroups WHERE fk_group = ?"),
INSERT_GROUP("INSERT INTO groups (name, fk_chapter) VALUES (?,?)"),
INSERT_PLAYER_IN_GROUP("INSERT INTO containsGroups (fk_player, fk_group) VALUES (?,?)"),
LEAVE_GROUP("DELETE FROM containsGroups WHERE fk_player = ? AND fk_group = ?");
private String request;
Query(Query parent, String request) {
this.request = parent.request + request;
}
Query(String request) {
this.request = request;
}
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
return base.prepare(this.request);
}
@Override
public String toString() {
return this.request;
}
}
private Configuration config;
public DatabaseGroupRepository(ConnectionManager con, Configuration config){
super(con);
this.config = config;
}
public List<Group> getAllGroups() {
try {
ensureConnection();
List<Group> list = new ArrayList<>();
PreparedStatement stmt = Query.ALL_GROUPS.prepare(this);
ResultSet groupResult = stmt.executeQuery();
while (groupResult.next())
list.add(makeGroup(groupResult));
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public List<Group> getAllGroupsByChapter(int chapter){
try {
ensureConnection();
List<Group> list = new ArrayList<>();
PreparedStatement stmt = Query.ALL_GROUPS_BY_CHAPTER.prepare(this);
stmt.setInt(1, chapter);
ResultSet groupResult = stmt.executeQuery();
while (groupResult.next())
list.add(makeGroup(groupResult));
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public boolean insertGroup(Group group, PeerAtUser creator) throws SQLException {
Integer groupId = getGroupId(group);
if (groupId == null)
ensureConnection();
PreparedStatement statement = Query.INSERT_GROUP.prepare(this);
statement.setString(1, group.getName());
statement.setObject(2, group.getLinkToChapter());
// statement.setObject(3, group.getLinkToPuzzle());
if (statement.executeUpdate() >= 0)
return insertUserInGroup(group, creator);
return false;
}
public Group getPlayerGroup(int user, Integer chapter) throws SQLException {
ensureConnection();
PreparedStatement stmt = Query.GET_GROUP_FOR_PLAYER.prepare(this);
stmt.setInt(1, user);
stmt.setObject(2, chapter);
// stmt.setObject(3, puzzle);
ResultSet result = stmt.executeQuery();
if (result.next())
return makeGroup(result);
return null;
}
public Integer getGroupId(Group group) throws SQLException {
ensureConnection();
PreparedStatement stmt = Query.GET_GROUP_ID_BY_DATA.prepare(this);
stmt.setString(1, group.getName());
stmt.setObject(2, group.getLinkToChapter());
// stmt.setObject(3, group.getLinkToPuzzle());
ResultSet result = stmt.executeQuery();
if (result.next())
return result.getInt("id_group");
return null;
}
public boolean insertUserInGroup(Group group, PeerAtUser user) throws SQLException{
Integer id = getGroupId(group);
if(id != null){
int howmany = numberInGroup(id);
System.out.println("join group, already have "+howmany);
if(howmany > config.getGroupMaxPlayers()) return false;
}
Group alreadyInGroup = getPlayerGroup(user.getId(), group.getLinkToChapter());
if (id != null && alreadyInGroup == null) {
PreparedStatement stmt = Query.INSERT_PLAYER_IN_GROUP.prepare(this);
stmt.setInt(1, user.getId());
stmt.setInt(2, id);
return stmt.executeUpdate() >= 0;
}
return false;
}
public int numberInGroup(int group) throws SQLException{
PreparedStatement stmt = Query.GET_GROUP_USERS_COUNT.prepare(this);
stmt.setInt(1, group);
ResultSet result = stmt.executeQuery();
if(result.next()) return result.getInt("howmany");
return 0;
}
public boolean leaveGroup(Group group, PeerAtUser user) throws SQLException {
Integer id = getGroupId(group);
if (id != null) {
PreparedStatement stmt = Query.LEAVE_GROUP.prepare(this);
stmt.setInt(1, user.getId());
stmt.setInt(2, id);
return stmt.executeUpdate() >= 0;
}
return false;
}
}

View file

@ -1,102 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.Player;
public class DatabaseLeaderboardRepository extends BaseDatabaseQuery{
private static enum Query{
// LEADERBOARD
ALL_PLAYERS_FOR_LEADERBOARD(
"select p.*, scores.*, g.* from players p ,(SELECT fk_player, SUM(c.score) AS score, COUNT(c.id_completion) AS completions, SUM(c.tries) AS tries, rank() over(ORDER BY score DESC) AS rank FROM completions c LEFT JOIN puzzles puzz on puzz.id_puzzle = c.fk_puzzle LEFT JOIN chapters chap on chap.id_chapter = puzz.fk_chapter WHERE chap.id_chapter > 1 GROUP BY c.fk_player) AS scores LEFT JOIN containsGroups cg ON scores.fk_player = cg.fk_player LEFT JOIN groups g ON cg.fk_group = g.id_group WHERE p.id_player = scores.fk_player ORDER BY g.fk_chapter"),
ALL_GROUP_FOR_CHAPTER_LEADERBOARD(
"SELECT g.*, pl.pseudo, co.score, co.tries FROM groups g LEFT JOIN containsGroups cg ON g.id_group = cg.fk_group LEFT JOIN players pl ON cg.fk_player = pl.id_player LEFT JOIN completions co ON pl.id_player = co.fk_player WHERE cg.fk_player IS NOT NULL AND fk_chapter = ? AND (co.fk_puzzle IN (SELECT id_puzzle FROM puzzles puz WHERE puz.fk_chapter = g.fk_chapter) OR co.score IS NULL);");
private String request;
Query(Query parent, String request) {
this.request = parent.request + request;
}
Query(String request) {
this.request = request;
}
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
return base.prepare(this.request);
}
@Override
public String toString() {
return this.request;
}
}
private Configuration config;
public DatabaseLeaderboardRepository(ConnectionManager con, Configuration config){
super(con);
this.config = config;
}
public SortedSet<Player> getAllPlayerForLeaderboard() {
try {
ensureConnection();
PreparedStatement playersStmt = Query.ALL_PLAYERS_FOR_LEADERBOARD.prepare(this);
ResultSet result = playersStmt.executeQuery();
ArrayList<Player> players = new ArrayList<Player>();
Player tmpPlayer;
while (result.next()) {
tmpPlayer = makePlayer(result, result.getInt("id_player"));
if (!players.contains(tmpPlayer)) {
players.add(tmpPlayer);
} else {
players.get(players.indexOf(tmpPlayer)).addGroup(makeGroup(result));
}
}
return new TreeSet<Player>(players);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public SortedSet<Group> getAllGroupForChapterLeaderboard(int chapterId){
try{
ensureConnection();
PreparedStatement groupsStmt = Query.ALL_GROUP_FOR_CHAPTER_LEADERBOARD.prepare(this);
groupsStmt.setInt(1, chapterId);
ResultSet result = groupsStmt.executeQuery();
List<Group> groups = new ArrayList<Group>();
Group tmpGroup;
while (result.next()) {
tmpGroup = makeGroup(result);
if (tmpGroup != null) {
int gPosition = groups.indexOf(tmpGroup);
if (gPosition < 0) {
tmpGroup.addPlayer(makeGroupPlayer(result));
groups.add(tmpGroup);
} else {
groups.get(gPosition).addPlayer(makeGroupPlayer(result));
}
}
}
return new TreeSet<Group>(groups);
}catch(SQLException e){
e.printStackTrace();
}
return null;
}
}

View file

@ -1,191 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.password4j.Password;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.model.Player;
import dev.peerat.backend.model.Puzzle;
public class DatabasePlayerRepository extends BaseDatabaseQuery{
public static String GET_PLAYER_RANK(){
return Query.GET_PLAYER_RANK.request;
}
private static enum Query{
// PLAYERS
GET_PLAYER_SIMPLE("SELECT pseudo, email, firstname, lastname, description FROM players WHERE id_player = ?"),
GET_PLAYER_EMAIL("SELECT id_player FROM players WHERE email = ?"),
GET_PLAYER_PSEUDO("SELECT * FROM players WHERE pseudo = ?"),
GET_PLAYER_DETAILS("SELECT p.*, g.*\r\n"
+ "FROM players p\r\n"
+ "LEFT OUTER JOIN containsGroups cg ON p.id_player = cg.fk_player\r\n"
+ "LEFT OUTER JOIN groups g ON cg.fk_group = g.id_group\r\n"
+ "LEFT OUTER JOIN completions c on p.id_player = c.fk_player\r\n"
+ "WHERE "),
GET_PLAYER_DETAILS_BY_ID(GET_PLAYER_DETAILS, " p.id_player = ? GROUP BY g.name ORDER BY g.fk_chapter, g.fk_puzzle;"),
GET_PLAYER_DETAILS_BY_PSEUDO(GET_PLAYER_DETAILS, "p.pseudo = ? GROUP BY g.name ORDER BY g.fk_chapter, g.fk_puzzle;"),
GET_PLAYER_COMPLETIONS("select c.*, p.name from completions c left join puzzles p on c.fk_puzzle = p.id_puzzle where fk_player = ?;"),
GET_PLAYER_RANK("SELECT * FROM (SELECT fk_player, RANK() OVER(ORDER BY SUM(score) DESC) rank FROM completions c LEFT JOIN puzzles puzz on puzz.id_puzzle = c.fk_puzzle LEFT JOIN chapters chap on chap.id_chapter = puzz.fk_chapter LEFT JOIN players p ON p.id_player = c.fk_player WHERE chap.id_chapter > 1 GROUP BY fk_player ORDER BY rank) AS ranks WHERE ranks.fk_player = ?;"),
UPDATE_PLAYER_INFO("UPDATE players SET pseudo = ?, email = ?, firstname = ?, lastname = ? WHERE id_player = ?"),
UPDATE_PLAYER_PASSWORD("UPDATE players SET passwd = ? WHERE id_player = ?");
private String request;
Query(Query parent, String request) {
this.request = parent.request + request;
}
Query(String request) {
this.request = request;
}
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
return base.prepare(this.request);
}
@Override
public String toString() {
return this.request;
}
}
private Configuration config;
public DatabasePlayerRepository(ConnectionManager con, Configuration config){
super(con);
this.config = config;
}
public Player getPlayer(int idPlayer) {
try {
PreparedStatement completionsStmt = Query.GET_PLAYER_SIMPLE.prepare(this);
completionsStmt.setInt(1, idPlayer);
ResultSet result = completionsStmt.executeQuery();
if (result.next()) {
return makePlayer(result, idPlayer);
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public int getPlayerId(String email){
try {
ensureConnection();
PreparedStatement completionsStmt = Query.GET_PLAYER_EMAIL.prepare(this);
completionsStmt.setString(1, email);
ResultSet result = completionsStmt.executeQuery();
if (result.next()) {
return result.getInt("id_player");
}
} catch (SQLException e) {
e.printStackTrace();
}
return -1;
}
public boolean updatePseudo(int id, Player player, String pseudo){
try{
PreparedStatement statment = Query.GET_PLAYER_PSEUDO.prepare(this);
statment.setString(1, pseudo);
ResultSet result = statment.executeQuery();
if(result.next()) return false;
statment = Query.UPDATE_PLAYER_INFO.prepare(this);
statment.setString(1, pseudo);
statment.setString(2, player.getEmail());
statment.setString(3, player.getFirstname());
statment.setString(4, player.getLastname());
statment.setInt(5, id);
return statment.executeUpdate() > 0;
}catch(Exception e){
e.printStackTrace();
}
return false;
}
public void updateProfile(int id, Player player, String lastname, String firstname){
try{
PreparedStatement statment = Query.UPDATE_PLAYER_INFO.prepare(this);
statment.setString(1, player.getPseudo());
statment.setString(2, player.getEmail());
statment.setString(3, firstname);
statment.setString(4, lastname);
statment.setInt(5, id);
statment.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}
}
public void updatePassword(int id, String password){
try{
PreparedStatement statment = Query.UPDATE_PLAYER_PASSWORD.prepare(this);
statment.setString(1, Password.hash(password).withArgon2().getResult());
statment.setInt(2, id);
statment.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}
}
public Player getPlayerDetails(int idPlayer) {
return getPlayerDetails(idPlayer, null);
}
public Player getPlayerDetails(String pseudoPlayer) {
return getPlayerDetails(-1, pseudoPlayer);
}
private Player getPlayerDetails(int id, String pseudo) {
try {
ensureConnection();
PreparedStatement completionsStmt;
if (pseudo != null) {
completionsStmt = Query.GET_PLAYER_DETAILS_BY_PSEUDO.prepare(this);
completionsStmt.setString(1, pseudo);
} else {
completionsStmt = Query.GET_PLAYER_DETAILS_BY_ID.prepare(this);
completionsStmt.setInt(1, id);
}
ResultSet result = completionsStmt.executeQuery();
Player player = null;
while (result.next()) {
if (player == null) {
id = result.getInt("id_player");
player = makePlayer(result, id);
completionsStmt = prepare(DatabaseBadgeRepository.GET_BADGES_OF_PLAYER());
completionsStmt.setInt(1, id);
ResultSet resultBadges = completionsStmt.executeQuery();
while (resultBadges.next()) {
player.addBadge(makeBadge(resultBadges));
}
} else {
player.addGroup(makeGroup(result));
}
}
// ADD completions
completionsStmt = Query.GET_PLAYER_COMPLETIONS.prepare(this);
completionsStmt.setInt(1, id);
result = completionsStmt.executeQuery();
while (result.next()) {
player.addCompletion(makeCompletion(result));
}
return player;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}

View file

@ -1,78 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.model.Puzzle;
public class DatabasePuzzleRepository extends BaseDatabaseQuery{
private static enum Query{
SPECIFIC_PUZZLE_QUERY(
"SELECT p.*, np.origin, GROUP_CONCAT(t.name) AS tags FROM puzzles p LEFT JOIN nextPart np ON p.id_puzzle = np.next LEFT JOIN containsTags ct ON ct.fk_puzzle = p.id_puzzle LEFT JOIN tags t ON t.id_tag = ct.fk_tag WHERE p.id_puzzle = ? GROUP BY p.id_puzzle"),
PUZZLES_IN_CHAPTER_QUERY(
"SELECT p.*, GROUP_CONCAT(t.name) AS tags FROM puzzles p LEFT JOIN containsTags ct ON ct.fk_puzzle = p.id_puzzle LEFT JOIN tags t ON t.id_tag = ct.fk_tag WHERE fk_chapter = ? GROUP BY p.id_puzzle");
private String request;
Query(Query parent, String request) {
this.request = parent.request + request;
}
Query(String request) {
this.request = request;
}
public PreparedStatement prepare(BaseDatabaseQuery base) throws SQLException {
return base.prepare(this.request);
}
@Override
public String toString() {
return this.request;
}
}
private Configuration config;
public DatabasePuzzleRepository(ConnectionManager con, Configuration config){
super(con);
this.config = config;
}
public List<Puzzle> getPuzzlesInChapter(int id) throws SQLException {
List<Puzzle> puzzles = new ArrayList<>();
ensureConnection();
PreparedStatement puzzleStmt = Query.PUZZLES_IN_CHAPTER_QUERY.prepare(this);
puzzleStmt.setInt(1, id);
ResultSet puzzleResult = puzzleStmt.executeQuery();
while (puzzleResult.next()) {
puzzles.add(makePuzzle(puzzleResult));
}
return puzzles;
}
/**
* Get a specific puzzle
*
* @param id The id of the puzzle
* @return The puzzle or null if an error occurred
*/
public Puzzle getPuzzle(int id) throws SQLException {
ensureConnection();
PreparedStatement puzzleStmt = Query.SPECIFIC_PUZZLE_QUERY.prepare(this);
puzzleStmt.setInt(1, id);
ResultSet puzzleResult = puzzleStmt.executeQuery();
if (puzzleResult.next()) {
return makePuzzle(puzzleResult);
}
return null;
}
}

View file

@ -1,181 +0,0 @@
package dev.peerat.backend.repository;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public enum DatabaseQuery {
//TRIGGER
FIRST_TRY("CREATE OR REPLACE TRIGGER FirstTry\r\n"
+ "AFTER INSERT\r\n"
+ " ON completions FOR EACH ROW\r\n"
+ "BEGIN\r\n"
+ " DECLARE badge INT;\r\n"
+ " DECLARE contain INT;\r\n"
+ " \r\n"
+ " SELECT id_badge\r\n"
+ " INTO @badge\r\n"
+ " FROM badges\r\n"
+ " WHERE name = 'FirstTry';\r\n"
+ " \r\n"
+ " IF @badge is not null THEN\r\n"
+ " \r\n"
+ " SELECT count(*)\r\n"
+ " INTO @contain\r\n"
+ " FROM containsBadges\r\n"
+ " WHERE fk_badge = @badge AND fk_player = NEW.fk_player;\r\n"
+ " \r\n"
+ " IF (@contain = 0) THEN\r\n"
+ " INSERT INTO containsBadges(fk_player, fk_badge) VALUES (NEW.fk_player, @badge);\r\n"
+ " END IF;\r\n"
+ " END IF;\r\n"
+ "END;"),
EventParticipation("CREATE OR REPLACE TRIGGER EventParticipation\r\n"
+ "AFTER INSERT\r\n"
+ " ON completions FOR EACH ROW\r\n"
+ "BEGIN\r\n"
+ " DECLARE badge INT;\r\n"
+ " DECLARE endDate datetime;\r\n"
+ " DECLARE player INT;\r\n"
+ " DECLARE contain INT;\r\n"
+ "\r\n"
+ " SELECT id_badge\r\n"
+ " INTO badge\r\n"
+ " FROM badges\r\n"
+ " WHERE name = 'EventParticipation';\r\n"
+ "\r\n"
+ " IF @badge is not null THEN\r\n"
+ "\r\n"
+ " SELECT c.end_date, i.fk_player\r\n"
+ " INTO endDate, player\r\n"
+ " FROM inserted i\r\n"
+ " JOIN puzzles p ON i.fk_puzzle = p.id_puzzle\r\n"
+ " JOIN chapters c on p.fk_chapter = c.id_chapter;\r\n"
+ "\r\n"
+ " IF @endDate is not null THEN\r\n"
+ "\r\n"
+ " SELECT count(*)\r\n"
+ " INTO contain\r\n"
+ " FROM containsBadges\r\n"
+ " WHERE fk_badge = badge AND fk_player = player;\r\n"
+ "\r\n"
+ " IF (@contain = 0) THEN\r\n"
+ " INSERT INTO containsBadges(fk_player, fk_badge) VALUES (@player, @badge);\r\n"
+ " END IF;\r\n"
+ " END IF;\r\n"
+ " END IF;\r\n"
+ "END;");
private String request;
DatabaseQuery(DatabaseQuery parent, String request) {
this.request = parent.request + request;
}
DatabaseQuery(String request) {
this.request = request;
}
public PreparedStatement prepare(Connection con) throws SQLException {
return con.prepareStatement(this.request);
}
@Override
public String toString() {
return this.request;
}
}
/*
*
SELECT p.*, scores.score, scores.completions, scores.tries, scores.rank, g.*
FROM players p,
(SELECT fk_player, SUM(c.score) AS score,
COUNT(c.id_completion) AS completions,
SUM(c.tries) AS tries,
rank() over(ORDER BY score DESC) AS rank
FROM completions c GROUP BY c.fk_player)
AS scores
LEFT OUTER JOIN containsGroups cg ON scores.fk_player = cg.fk_player
LEFT OUTER JOIN groups g ON cg.fk_group = g.id_group
WHERE p.id_player = scores.fk_player AND "),
*
*/
/* TRIGGER PLACE
*
CREATE OR REPLACE TRIGGER FirstTry
AFTER INSERT
ON completions FOR EACH ROW
BEGIN
DECLARE badge INT;
DECLARE contain INT;
SELECT id_badge
INTO @badge
FROM badges
WHERE name = 'FirstTry';
IF @badge is not null THEN
SELECT count(*)
INTO @contain
FROM containsBadges
WHERE fk_badge = @badge AND fk_player = NEW.fk_player;
IF (@contain = 0) THEN
IF (NEW.score >= 0 AND NEW.tries < 2) THEN
INSERT INTO containsBadges(fk_player, fk_badge) VALUES (NEW.fk_player, @badge);
END IF;
END IF;
END IF;
END;
CREATE OR REPLACE TRIGGER EventParticipation
AFTER INSERT
ON completions FOR EACH ROW
BEGIN
DECLARE badge INT;
DECLARE endDate datetime;
DECLARE player INT;
DECLARE contain INT;
SELECT id_badge
INTO badge
FROM badges
WHERE name = 'EventParticipation';
IF @badge is not null THEN
SELECT c.end_date, i.fk_player
INTO endDate, player
FROM inserted i
JOIN puzzles p ON i.fk_puzzle = p.id_puzzle
JOIN chapters c on p.fk_chapter = c.id_chapter;
IF @endDate is not null THEN
SELECT count(*)
INTO contain
FROM containsBadges
WHERE fk_badge = badge AND fk_player = player;
IF (@contain = 0) THEN
INSERT INTO containsBadges(fk_player, fk_badge) VALUES (@player, @badge);
END IF;
END IF;
END IF;
END;
*
*/

View file

@ -1,239 +0,0 @@
package dev.peerat.backend.repository;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import dev.peerat.backend.Configuration;
public class DatabaseRepository extends BaseDatabaseQuery{
private Connection con; //refractor chain
private Configuration config;
private DatabasePuzzleRepository puzzleRepo;
private DatabaseChapterRepository chapterRepo;
private DatabaseAdminRepository adminRepo;
private DatabaseAuthRepository authRepo;
private DatabaseBadgeRepository badgeRepo;
private DatabaseCompletionRepository completionRepo;
private DatabaseGroupRepository groupRepo;
private DatabaseLeaderboardRepository leaderboardRepo;
private DatabasePlayerRepository playerRepo;
public DatabaseRepository(ConnectionManager con, Configuration config) throws Exception {
super(con);
this.config = config;
this.puzzleRepo = new DatabasePuzzleRepository(con, config);
this.chapterRepo = new DatabaseChapterRepository(con, config, puzzleRepo);
this.adminRepo = new DatabaseAdminRepository(con, config);
this.authRepo = new DatabaseAuthRepository(con, config);
this.badgeRepo = new DatabaseBadgeRepository(con, config);
this.completionRepo = new DatabaseCompletionRepository(con, config, chapterRepo);
this.groupRepo = new DatabaseGroupRepository(con, config);
this.leaderboardRepo = new DatabaseLeaderboardRepository(con, config);
this.playerRepo = new DatabasePlayerRepository(con, config);
loadConfig(config);
}
private void loadConfig(Configuration config) throws Exception{
String name = DatabaseRepository.class.getPackage().getName();
InputStream stream = ClassLoader.getSystemClassLoader().getResourceAsStream(name.replace(".", "/"));
File folder = new File(config.getSqlFolder());
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
while((line = reader.readLine()) != null){
if(line.endsWith(".class")){
Class<?> clazz = Class.forName(name+"."+line.substring(0, line.length()-6));
if(BaseDatabaseQuery.class.isAssignableFrom(clazz)){
for(Class<?> subClazz : clazz.getDeclaredClasses()){
if(subClazz.isEnum()){
configure(subClazz, folder);
}
}
}
continue;
}
}
reader.close();
}catch(Exception e){
System.err.println("Failed to read "+name);
e.printStackTrace();
}
new Thread(() -> {
try{
WatchService watchService = FileSystems.getDefault().newWatchService();
Path path = folder.toPath();
path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);
while (true) {
WatchKey key = watchService.take();
for(WatchEvent<?> event : key.pollEvents()){
Path edited = (Path) event.context();
String targetClazz = edited.toFile().getName().split("\\.")[0];
Class<?> clazz = Class.forName(name+"."+targetClazz);
if(BaseDatabaseQuery.class.isAssignableFrom(clazz)){
for(Class<?> subClazz : clazz.getDeclaredClasses()){
if(subClazz.isEnum()){
bind(subClazz, new File(folder, edited.toFile().getName()));
}
}
}
}
key.reset();
}
}catch(Exception ex){
ex.printStackTrace();
}
}).start();
}
private void configure(Class<?> clazz, File folder) throws Exception{
String name = clazz.getName().split("\\$")[0];
String[] split = name.split("\\.");
File file = new File(folder, split[split.length-1]+".txt");
if(file.exists()){
bind(clazz, file);
}else{
File parent = file.getParentFile();
if(!parent.exists()) parent.mkdirs();
file.createNewFile();
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
for(Object obj : clazz.getEnumConstants()){
Enum instance = (Enum) obj;
writer.write(instance.name()+"="+instance.toString().replace("\n", " ").replace("\r", " ")+"\n");
}
writer.flush();
writer.close();
}
}
private void bind(Class<?> clazz, File file) throws Exception{
Map<String, String> map = new HashMap<>();
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
while((line = reader.readLine()) != null){
int index = line.indexOf('=');
String key = line.substring(0, index);
String value = line.substring(index+1);
map.put(key, value);
}
reader.close();
for(Object obj : clazz.getEnumConstants()){
Enum instance = (Enum) obj;
String value = map.get(instance.name());
Field field = obj.getClass().getDeclaredField("request");
field.setAccessible(true);
field.set(instance, value);
}
}
public DatabasePuzzleRepository getPuzzleRepository(){
return this.puzzleRepo;
}
public DatabaseChapterRepository getChapterRepository(){
return this.chapterRepo;
}
public DatabaseAdminRepository getAdminRepository(){
return this.adminRepo;
}
public DatabaseAuthRepository getAuthRepository(){
return this.authRepo;
}
public DatabaseBadgeRepository getBadgeRepository(){
return this.badgeRepo;
}
public DatabaseCompletionRepository getCompletionRepository(){
return this.completionRepo;
}
public DatabaseGroupRepository getGroupRepository(){
return this.groupRepo;
}
public DatabaseLeaderboardRepository getLeaderboardRepository(){
return this.leaderboardRepo;
}
public DatabasePlayerRepository getPlayerRepository(){
return this.playerRepo;
}
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);
}
}
}

View file

@ -1,65 +0,0 @@
package dev.peerat.backend.routes;
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.Route;
import dev.peerat.framework.utils.json.JsonMap;
public class EventSSE{
private Locker<GroupMessage> locker;
public EventSSE(@Injection("groupMessages") Locker<GroupMessage> locker){
this.locker = locker;
}
@Route(path = "^/group/event/$", websocket = true)
public void connect(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
String group = reader.<JsonMap>readJson().get("group");
Key key = new Key();
locker.init(key);
try {
while(true){
locker.lock(key);
GroupMessage message = locker.getValue(key);
if(message.getGroup() == null || message.getGroup().equals(group)){
JsonMap send = new JsonMap();
send.set("message", message.getMessage());
writer.write(send.toString()+"\n");
writer.flush();
}
}
}catch(Exception e){
e.printStackTrace();
}
locker.remove(key);
}
public static class GroupMessage{
private String group;
private String message;
public GroupMessage(String group, String message){
this.group = group;
this.message = message;
}
public String getGroup(){
return this.group;
}
public String getMessage(){
return this.message;
}
}
}

View file

@ -1,70 +0,0 @@
package dev.peerat.backend.routes.admins;
import static dev.peerat.framework.RequestType.DELETE;
import static dev.peerat.framework.RequestType.POST;
import static dev.peerat.framework.RequestType.PUT;
import java.sql.Timestamp;
import java.util.regex.Matcher;
import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.repository.DatabaseAdminRepository;
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.Route;
import dev.peerat.framework.utils.json.JsonMap;
public class ChapterController{
private DatabaseAdminRepository repo;
public ChapterController(DatabaseRepository repo){
this.repo = repo.getAdminRepository();
}
@Route(path = "^/admin/chapter/$", type = POST, needLogin = true)
public void add(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
JsonMap json = reader.readJson();
Chapter chapter = new Chapter(-1, json.get("name"), Timestamp.valueOf(json.<String>get("start")), Timestamp.valueOf(json.<String>get("end")));
if(repo.adminAddChapter(chapter)){
context.response(200);
}else{
context.response(501);
}
}
@Route(path = "^/admin/chapter/(\\d+)$", type = DELETE, needLogin = true)
public void delte(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
if(this.repo.adminDeleteChapter(Integer.parseInt(matcher.group(1)))){
context.response(200);
}else{
context.response(501);
}
}
@Route(path = "^/admin/chapter/(\\d+)$", type = PUT, needLogin = true)
public void edit(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
JsonMap json = reader.readJson();
Chapter chapter = new Chapter(-1, json.get("name"), Timestamp.valueOf(json.<String>get("start")), Timestamp.valueOf(json.<String>get("end")));
if(repo.adminUpdateChapter(Integer.parseInt(matcher.group(1)), chapter)){
context.response(200);
}else{
context.response(501);
}
}
@Route(path = "^/admin/chapter/(\\d+)$", needLogin = true)
public void get(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
Chapter chapter = this.repo.getAdminChapter(Integer.parseInt(matcher.group(1)));
JsonMap json = new JsonMap();
json.set("name", chapter.getName());
json.set("start", chapter.getStartDate());
json.set("end", chapter.getEndDate());
context.response(200);
writer.write(json.toString()+"\n");
}
}

View file

@ -1,32 +0,0 @@
package dev.peerat.backend.routes.admins;
import dev.peerat.backend.routes.EventSSE.GroupMessage;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.Injection;
import dev.peerat.framework.Locker;
import dev.peerat.framework.RequestType;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonMap;
public class GroupController {
private Locker<GroupMessage> locker;
public GroupController(@Injection("groupMessages") Locker<GroupMessage> locker){
this.locker = locker;
}
@Route(path = "^/admin/event/$", type = RequestType.POST ,needLogin = true)
public void send(Context context, HttpReader reader) throws Exception{
JsonMap json = reader.readJson();
if(!json.has("message")){
context.response(400);
return;
}
locker.setValue(new GroupMessage(json.get("group"), json.get("message")));
context.response(200);
}
}

View file

@ -1,78 +0,0 @@
package dev.peerat.backend.routes.admins;
import java.util.function.BiConsumer;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.DatabaseAdminRepository;
import dev.peerat.backend.repository.DatabasePlayerRepository;
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.Locker;
import dev.peerat.framework.Locker.Key;
import dev.peerat.framework.Route;
import dev.peerat.framework.Router;
import dev.peerat.framework.utils.json.JsonArray;
import dev.peerat.framework.utils.json.JsonMap;
public class LogController {
private Locker<Context> contextLocker;
private Locker<Throwable> exceptionLocker;
private DatabaseAdminRepository repo;
private DatabasePlayerRepository playerRepo;
public LogController(Router<PeerAtUser> router, DatabaseRepository repo){
this.contextLocker = router.getLogger();
this.exceptionLocker = router.getExceptionLogger();
this.repo = repo.getAdminRepository();
this.playerRepo = repo.getPlayerRepository();
}
@RouteDoc(path = "/admin/logs", responseCode = 200, responseDescription = "L'utilisateur peux voir les logs en directe")
@RouteDoc(responseCode = 401, responseDescription = "L'utilisateur n'a pas accès à cette ressource")
@Route(path = "^/admin/logs$", needLogin = true, websocket = true)
public void logs(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
log(reader, writer, this.contextLocker, (json, instance) -> {
json.set("logged", instance.isLogged());
if(instance.isLogged()) json.set("pseudo", playerRepo.getPlayer(instance.<PeerAtUser>getUser().getId()).getPseudo());
json.set("path", instance.getPath());
json.set("type", instance.getType().toString());
json.set("code", instance.getResponseCode());
});
}
@Route(path = "^/admin/exceptions$", needLogin = true, websocket = true)
public void exceptions(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
log(reader, writer, this.exceptionLocker, (json, exception) -> {
json.set("type", exception.getClass().getSimpleName());
json.set("message", exception.getMessage());
JsonArray trace = new JsonArray();
for(StackTraceElement element : exception.getStackTrace()) trace.add(element.toString());
json.set("trace", trace);
});
}
public <T> void log(HttpReader reader, HttpWriter writer, Locker<T> locker, BiConsumer<JsonMap, T> consumer){
Key key = new Key();
locker.init(key);
try {
while(!reader.isClosed()){
locker.lock(key);
T instance = locker.getValue(key);
JsonMap json = new JsonMap();
consumer.accept(json, instance);
writer.write(json.toString());
writer.flush();
}
}catch(Exception e){}
locker.remove(key);
}
}

View file

@ -1,89 +0,0 @@
package dev.peerat.backend.routes.admins;
import static dev.peerat.framework.RequestType.DELETE;
import static dev.peerat.framework.RequestType.POST;
import static dev.peerat.framework.RequestType.PUT;
import java.util.List;
import java.util.regex.Matcher;
import dev.peerat.backend.model.Puzzle;
import dev.peerat.backend.repository.DatabaseAdminRepository;
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.Route;
import dev.peerat.framework.utils.json.JsonArray;
import dev.peerat.framework.utils.json.JsonMap;
public class PuzzleController {
private DatabaseAdminRepository repo;
public PuzzleController(DatabaseRepository repo){
this.repo = repo.getAdminRepository();
}
@Route(path = "^/admin/puzzle/$", type = POST, needLogin = true)
public void add(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
JsonMap json = reader.readJson();
Puzzle puzzle = new Puzzle(-1, json.get("name"), json.get("content"), json.<String>get("soluce").getBytes(), null, json.<Long>get("scoreMax").intValue(), null, -1, null);
if(repo.adminAddPuzzle(puzzle, json.<Long>get("chapter").intValue())){
context.response(200);
}else{
context.response(501);
}
}
@Route(path = "^/admin/puzzle/(\\d+)$", type = DELETE, needLogin = true)
public void delete(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
if(this.repo.adminDeletePuzzle(Integer.parseInt(matcher.group(1)))){
context.response(200);
}else{
context.response(501);
}
}
@Route(path = "^/admin/puzzle/(\\d+)$", type = PUT, needLogin = true)
public void edit(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
JsonMap json = reader.readJson();
Puzzle puzzle = new Puzzle(-1, json.get("name"), json.get("content"), json.<String>get("soluce").getBytes(), null, json.<Long>get("scoreMax").intValue(), null, -1, null);
if(repo.adminUpdatePuzzle(Integer.parseInt(matcher.group(1)), puzzle, json.<Long>get("chapter").intValue())){
context.response(200);
}else{
context.response(501);
}
}
@Route(path = "^/admin/puzzle/(\\d+)$", needLogin = true)
public void get(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
Puzzle puzzle = this.repo.getAdminPuzzle(Integer.parseInt(matcher.group(1)));
JsonMap json = new JsonMap();
json.set("name", puzzle.getName());
json.set("content", puzzle.getContent());
json.set("soluce", new String(puzzle.getSoluce()));
json.set("score_max", puzzle.getScoreMax());
context.response(200);
writer.write(json.toString()+"\n");
}
@Route(path = "^/admin/puzzles/$", needLogin = true)
public void getAll(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
List<Puzzle> puzzles = repo.getAdminPuzzles();
JsonArray array = new JsonArray();
for (Puzzle puzzle : puzzles){
JsonMap puzzleJSON = new JsonMap();
puzzleJSON.set("id", puzzle.getId());
puzzleJSON.set("name", puzzle.getName());
puzzleJSON.set("scoreMax", puzzle.getScoreMax());
if(puzzle.getTags() != null) puzzleJSON.set("tags", puzzle.getJsonTags());
puzzleJSON.set("show", puzzle.hasStarted());
array.add(puzzleJSON);
}
context.response(200);
writer.write(array.toString());
}
}

View file

@ -1,68 +0,0 @@
package dev.peerat.backend.routes.admins;
import static dev.peerat.framework.RequestType.DELETE;
import static dev.peerat.framework.RequestType.POST;
import static dev.peerat.framework.RequestType.PUT;
import java.util.List;
import java.util.regex.Matcher;
import dev.peerat.backend.model.Tag;
import dev.peerat.backend.repository.DatabaseAdminRepository;
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.Route;
import dev.peerat.framework.utils.json.JsonArray;
import dev.peerat.framework.utils.json.JsonMap;
public class TagController {
private DatabaseAdminRepository repo;
public TagController(DatabaseRepository repo){
this.repo = repo.getAdminRepository();
}
@Route(path = "^/admin/tag/$", type = POST, needLogin = true)
public void add(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
JsonMap json = reader.readJson();
if(repo.adminAddTag(json.get("name"))){
context.response(200);
}else{
context.response(501);
}
}
@Route(path = "^/admin/tag/(\\d+)$", type = DELETE, needLogin = true)
public void delete(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
if(this.repo.adminDeleteTag(Integer.parseInt(matcher.group(1)))){
context.response(200);
}else{
context.response(501);
}
}
@Route(path = "^/admin/tag/(\\d+)$", type = PUT, needLogin = true)
public void edit(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
JsonMap json = reader.readJson();
if(repo.adminUpdateTag(new Tag(Integer.parseInt(matcher.group(1)), json.get("name")))){
context.response(200);
}else{
context.response(501);
}
}
@Route(path = "^/admin/tag/$", needLogin = true)
public void get(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
List<Tag> list = repo.getAdminTags();
JsonArray json = new JsonArray();
for(Tag tag : list) json.add(tag.toJson());
context.response(200);
writer.write(json.toString());
writer.flush();
}
}

View file

@ -1,28 +0,0 @@
package dev.peerat.backend.routes.admins;
import java.util.regex.Matcher;
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;
public class WebHookLeaderboard implements Response{
private Locker<Completion> locker;
public WebHookLeaderboard(@Injection("leaderboard") Locker<Completion> locker){
this.locker = locker;
}
@Route(path = "^/admin/webhook/leaderboard/$", needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
locker.setValue(new Completion(0, 0));
context.response(200);
}
}

View file

@ -1,106 +0,0 @@
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.Configuration;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.repository.DatabaseAuthRepository;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.backend.utils.FormResponse;
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{
private DatabaseAuthRepository databaseRepo;
private Map<String, String> playersWaiting;
private Mail mail;
private String host;
private List<Random> randoms;
public Register(DatabaseRepository databaseRepo, @Injection("waitting") Map<String, String> playersWaiting, Mail mail, Configuration config){
this.databaseRepo = databaseRepo.getAuthRepository();
this.playersWaiting = playersWaiting;
this.mail = mail;
this.host = config.getTokenIssuer();
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")
@RouteDoc(responseCode = 403, responseDescription = "L'utilisateur est connecté")
@RouteDoc(responseCode = 400, responseDescription = "Aucune données fournie / données invalide")
@Route(path = "^\\/register$", type = POST)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
if (context.isLogged()){
context.response(403);
return;
}
JsonMap json = json(reader);
if(!areValids("email")){
context.response(400);
return;
}
String email = json.get("email");
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
if(emailAvailable){
String code = codeGenerator();
playersWaiting.put(email, code);
mail.send(email, "Welcome @ Peer @ Code", "Your check code is "+code+" !");
context.response(200);
}else{
context.response(400);
JsonMap error = new JsonMap();
error.set("email_valid", emailAvailable);
writer.write(error.toString());
}
}
private Constructor<?> uuidBuilder;
private int[] start = {4, 9, 14, 19};
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);
String uuid = uuidBuilder.newInstance(arrayOfByte).toString();
target = this.randoms.get(random.nextInt(this.randoms.size()));
int start = this.start[target.nextInt(this.start.length)];
return uuid.substring(start, start+9);
}
}

View file

@ -1,7 +0,0 @@
package dev.peerat.backend.routes;
public interface DatabaseSeeder{
void setup() throws Exception;
}

View file

@ -6,69 +6,20 @@ import java.io.File;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.lang.reflect.Field;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.jupiter.api.Test;
import org.opentest4j.AssertionFailedError;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.Main;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.framework.Locker;
import dev.peerat.framework.Locker.Key;
import dev.peerat.framework.RequestType;
import dev.peerat.framework.Router;
public class StateTestCase{
@Test
void main() throws Exception{
Locker<Boolean> locker = new Locker<>();
Thread server = new Thread(new Runnable(){
@Override
public void run(){
try {
locker.setValue(true);
Main.main(null);
} catch (Exception e){
e.printStackTrace();
};
}
});
Key key = new Key();
locker.init(key);
server.start();
Thread.sleep(3000);
locker.lock(key);
locker.unlock(key);
Configuration config = new Configuration("config.txt");
config.load();
DatabaseRepository repo = new DatabaseRepository(config);
Field field = Main.class.getDeclaredField("ACCESS_ROUTER");
field.setAccessible(true);
Router<PeerAtUser> router = (Router<PeerAtUser>) field.get(null);
Function<String, String> tokenProvider = (email) -> {
try{
return router.createAuthUser(new PeerAtUser(repo.getPlayerId(email)));
}catch(Exception ex){
ex.printStackTrace();
return null;
}
};
String host = "127.0.0.1";
int port = 80;
File dir = new File("./route-test/");
for(File cases : dir.listFiles()){
@ -79,19 +30,16 @@ public class StateTestCase{
if(file.getName().endsWith(".class")) dbsetup = file; else responses.add(file);
}
// Class<?> clazz = new URLClassLoader(new URL[]{cases.toURI().toURL()}).loadClass(dbsetup.getAbsolutePath().substring(cases.getAbsolutePath().length()+1).replace("/", ".").replace("\\", ".").replace(".class", ""));
// DatabaseSeeder seeder = (DatabaseSeeder) clazz.newInstance();
// seeder.setup();
//setup database with clazz
for(File file : responses){
StateCase state = new StateCase(file, tokenProvider);
state.execute("127.0.0.1", config.getTcpPort());
StateCase state = new StateCase(file);
state.execute(host, port);
}
}
}
public static class StateCase{
private static final Pattern TOKEN_PATTERN = Pattern.compile("^(.*)<token:(.*)>(.*)$");
private String path;
private RequestType type;
private List<String> headers;
@ -101,7 +49,7 @@ public class StateTestCase{
private List<String> responseHeaders;
private String responsePayload;
public StateCase(File file, Function<String, String> tokenProvider) throws Exception{
public StateCase(File file) throws Exception{
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
String payloadBuffer;
@ -123,13 +71,6 @@ public class StateTestCase{
payloadBuffer = "";
while(((line = reader.readLine() )!= null) && (!line.isEmpty())) payloadBuffer+=line;
this.responsePayload = payloadBuffer;
reader.close();
this.headers = Arrays.asList(this.headers.stream().<String>map((header) -> {
Matcher matcher = TOKEN_PATTERN.matcher(header);
return matcher.matches() ? matcher.group(1)+tokenProvider.apply(matcher.group(2))+matcher.group(3) : header;
}).toArray((size) -> new String[size]));
}
public void execute(String host, int port) throws Exception{
@ -142,21 +83,11 @@ public class StateTestCase{
writer.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
int responseCode;
Set<String> responseHeaders = new HashSet<>();
String responseBody = "";
String line;
responseCode = Integer.parseInt(reader.readLine().split("\\s+")[1]);
while(((line = reader.readLine() )!= null) && (!line.isEmpty())) responseHeaders.add(line);
while(((line = reader.readLine() )!= null) && (!line.isEmpty())) responseBody+=line;
while((line = reader.readLine()) != null) System.out.println(line);
socket.close();
if(this.responseCode != responseCode) throw new AssertionFailedError("Excepted "+this.responseCode+" but have "+responseCode);
}
}
}
}

View file

@ -1,10 +0,0 @@
package dev.peerat.backend.routes.states;
import dev.peerat.backend.routes.DatabaseSeeder;
public class AllEmptyTests implements DatabaseSeeder{
@Override
public void setup() throws Exception{}
}