Compare commits

...

72 commits

Author SHA1 Message Date
3c423c7122 Fix du fix de multipart 2023-09-18 12:42:40 +02:00
1ac2fe4a4f Fix log & fix(?) multipart data with \n 2023-09-18 12:41:07 +02:00
f079e4e617 Imagine.... les 2023-09-18 12:30:07 +02:00
75baf14253 [tmp] fix player rank 2023-09-18 12:24:18 +02:00
c419013c40 update framework & reboot 2023-09-18 12:19:32 +02:00
081930f415 [tmp] ...tables with s 2023-09-18 12:01:26 +02:00
5b6c122178 [tmp] remove chapter 1 from leaderboard 2023-09-18 11:59:22 +02:00
cc24278a3f Change log & tmp remove git users 2023-09-18 11:47:03 +02:00
cc8ad713a7 Test & Remove debug for Theo 2023-09-18 08:47:55 +02:00
e50034dd00 little test for groups 2023-09-18 08:46:11 +02:00
cf5695e011 [tmp] and completion 2023-09-18 07:50:27 +02:00
ecea0a396c [tmp] Fix group on chapter 1 2023-09-18 07:46:47 +02:00
f92462db82 debug from front 2023-09-17 20:44:01 +02:00
018a132466 ForgotPassword -> POST 2023-09-17 11:06:01 +02:00
9e56d83343 Fix forgot password -> code data type checker 2023-09-17 11:01:07 +02:00
3da54bbe17 Merge branch 'dev' of https://git.peerat.dev/Peer-at-Code/peer-at-code-backend into dev 2023-09-16 12:17:47 +02:00
dbfd936d32 fix json strings 2023-09-16 12:17:24 +02:00
772dd2d23f Update show for puzzle and chapter 2023-09-16 09:25:38 +02:00
fe904774c0 fix lost '{' in begin of json 2023-09-15 23:07:34 +02:00
e5081f6c13 It's alreight 2023-09-14 00:13:51 +02:00
9ad98cbedf ...je...oui 2023-09-14 00:11:42 +02:00
449cb027b3 debug 2023-09-14 00:08:52 +02:00
6d017e1d5a by one ? 2023-09-14 00:07:05 +02:00
30d221e35a byte array ? 2023-09-14 00:04:11 +02:00
6c6eba29f8 length ? 2023-09-14 00:00:58 +02:00
e237be36b6 no json ? 2023-09-13 23:56:08 +02:00
e185258a54 Null ? 2023-09-13 23:52:23 +02:00
0248b7b07c New Json lib 2023-09-13 23:48:14 +02:00
c3621da722 Bakc into functional 2023-09-13 15:42:28 +02:00
5e2d84895d Test json with \n 2023-09-13 00:03:50 +02:00
18ec7fb396 Forgot Password 2023-09-11 18:18:46 +02:00
6470bd8be7 Update Framework (headers update) 2023-09-11 15:46:29 +02:00
6824ced972 add show and start_date to puzzle 2023-09-11 14:06:27 +02:00
62c2a923ae It finally works (clean code later) 2023-09-09 22:13:03 +02:00
fa09374178 Some day ? 2023-09-09 22:09:13 +02:00
2d1c67fc65 Good rsa key ? 2023-09-09 21:59:23 +02:00
3c7aa052dc wtf ? 2023-09-09 21:42:14 +02:00
735534ea2d 2048 key into 4096 2023-09-09 21:33:59 +02:00
119e789900 private...public...what the dif ? 2023-09-09 21:19:37 +02:00
514452c295 debug gitea content 2023-09-09 21:17:42 +02:00
58d890737d ssh-rsa for git key 2023-09-09 21:12:35 +02:00
75277c5b03 Email sender 2023-09-09 20:58:41 +02:00
a68bc91459 fix get player when no fetch group 2023-09-09 20:47:56 +02:00
f6560a85fd constructor INTO Object andrew ! 2023-09-09 20:36:28 +02:00
c4dcbbb977 fix 500 & fix json int 2023-09-09 20:33:52 +02:00
12e0bd7bac fix check int in form response 2023-09-09 20:11:46 +02:00
76e9c4376a Include error 500 from framework 2023-09-08 21:35:38 +02:00
dbb47bd8c5 get('firstnae') 2023-09-08 20:18:51 +02:00
a06eb168e7 Swagger 2023-09-08 14:34:44 +02:00
8dbb5e3474 Design pattern builder =D 2023-09-08 12:27:54 +02:00
262875fd62 Send mail on register 2023-09-08 12:24:03 +02:00
26eea355f1 Move register data in mail confirmation 2023-09-08 12:20:16 +02:00
e2cf4f8542 Configuration -> add default values 2023-09-08 11:32:58 +02:00
1f2e30a7d1 Forget to remove... 2023-09-08 02:26:09 +02:00
4f8b45f074 Merge from my branch september 2023-09-08 02:18:19 +02:00
c2428ebd94 au passage, je dégage l'exception quand route par défaut 2023-09-06 23:09:12 +02:00
e1fde6bd5a Merge branch 'dev' of https://git.peerat.dev/Peer-at-Code/peer-at-code-backend into dev 2023-09-06 22:58:23 +02:00
e815346b93 Fix Annotation processor problems 2023-09-06 22:58:05 +02:00
743e230f85 forget to change key value order in main map 2023-09-05 12:03:20 +02:00
bff438073a Register with email confirmation - to test w/ Theo 2023-09-05 11:44:24 +02:00
5161916f54 Mail sended ! 2023-09-04 16:22:47 +02:00
3ad9e91365 Add jakarta lib + mail test 2023-09-04 16:04:35 +02:00
ecdf99365b Push mailConfirmation route 2023-09-04 14:56:48 +02:00
c80d9ce31d Rajout route mail confirmation 2023-09-04 14:46:09 +02:00
6b652c8adf MailConfiguration to Mail from config 2023-09-04 13:12:51 +02:00
234a4a4795 from static to POO 2023-09-04 13:10:33 +02:00
bd0460e754 forget to add new file 2023-09-04 13:01:48 +02:00
eeac351b02 mail configuration 2023-09-04 12:51:14 +02:00
97d8c0b7de Update Framework dependecy 2023-09-04 09:29:59 +02:00
50dacdff15 refractor package & adapte to framework 2023-08-29 16:46:50 +02:00
5481dbd2cf Refractor back for new versions of the framework 2023-07-26 17:03:21 +02:00
f4dd642b78 Moved Framework 2023-07-05 15:03:03 +02:00
88 changed files with 2191 additions and 2444 deletions

View file

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="test"/> <classpathentry kind="src" path="test"/>
<classpathentry exported="true" kind="lib" path="json-simple-1.1.1.jar"/>
<classpathentry exported="true" kind="lib" path="mysql-connector-java-8.0.28.jar"/> <classpathentry exported="true" kind="lib" path="mysql-connector-java-8.0.28.jar"/>
<classpathentry exported="true" kind="lib" path="password4j-1.6.3.jar"/>
<classpathentry exported="true" kind="lib" path="slf4j-api-2.0.6.jar"/>
<classpathentry exported="true" kind="lib" path="jose4j-0.9.3.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/> <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
<classpathentry kind="src" path=".apt_generated"> <classpathentry kind="src" path=".apt_generated">
<attributes> <attributes>
@ -16,5 +16,9 @@
</classpathentry> </classpathentry>
<classpathentry kind="lib" path="Treasure.jar"/> <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="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.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"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

2
.gitignore vendored
View file

@ -2,6 +2,8 @@
bin/ bin/
.project .project
config.txt config.txt
config-test.txt
dist/ dist/
testApi/ testApi/
.apt_generated/* .apt_generated/*
/.apt_generated/

BIN
PeerAtCodeFramework.jar Normal file

Binary file not shown.

Binary file not shown.

BIN
angus-activation-2.0.1.jar Normal file

Binary file not shown.

127
database-schem.sql Normal file
View file

@ -0,0 +1,127 @@
DROP TABLE IF EXISTS `containsTags`;
DROP TABLE IF EXISTS `tags`;
DROP TABLE IF EXISTS `containsBadges`;
DROP TABLE IF EXISTS `badges`;
DROP TABLE IF EXISTS `containsGroups`;
DROP TABLE IF EXISTS `nextPart`;
DROP TABLE IF EXISTS `groups`;
DROP TABLE IF EXISTS `completions`;
DROP TABLE IF EXISTS `players`;
DROP TABLE IF EXISTS `puzzles`;
DROP TABLE IF EXISTS `chapters`;
CREATE TABLE `players` (
`id_player` int(11) NOT NULL AUTO_INCREMENT,
`pseudo` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`passwd` varchar(150) NOT NULL,
`firstname` varchar(100) NOT NULL,
`lastname` varchar(100) NOT NULL,
`description` varchar(200) DEFAULT NULL,
`avatar` blob DEFAULT NULL,
PRIMARY KEY (`id_player`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE badges (
id_badge int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
logo mediumblob DEFAULT NULL,
level int(11) DEFAULT 1,
PRIMARY KEY (id_badge)
);
CREATE TABLE `chapters` (
`id_chapter` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(150) NOT NULL,
`start_date` datetime DEFAULT NULL,
`end_date` datetime DEFAULT NULL,
PRIMARY KEY (`id_chapter`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE `puzzles` (
`id_puzzle` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(150) NOT NULL,
`content` text NOT NULL,
`soluce` blob NOT NULL,
`verify` text DEFAULT NULL,
`score_max` int(11) NOT NULL,
`fk_chapter` int(11) NOT NULL,
PRIMARY KEY (`id_puzzle`),
KEY `fk_chapter` (`fk_chapter`),
CONSTRAINT `puzzles_ibfk_1` FOREIGN KEY (`fk_chapter`) REFERENCES `chapters` (`id_chapter`)
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE `groups` (
`id_group` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(150) DEFAULT NULL,
`fk_chapter` int(11) DEFAULT NULL,
`fk_puzzle` int(11) DEFAULT NULL,
PRIMARY KEY (`id_group`),
KEY `fk_chapter` (`fk_chapter`),
KEY `fk_puzzle` (`fk_puzzle`),
CONSTRAINT `groups_ibfk_1` FOREIGN KEY (`fk_chapter`) REFERENCES `chapters` (`id_chapter`),
CONSTRAINT `groups_ibfk_2` FOREIGN KEY (`fk_puzzle`) REFERENCES `puzzles` (`id_puzzle`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE `nextPart` (
`origin` int(11) NOT NULL,
`next` int(11) NOT NULL,
PRIMARY KEY (`origin`,`next`),
KEY `next` (`next`),
CONSTRAINT `nextPart_ibfk_1` FOREIGN KEY (`origin`) REFERENCES `puzzles` (`id_puzzle`),
CONSTRAINT `nextPart_ibfk_2` FOREIGN KEY (`next`) REFERENCES `puzzles` (`id_puzzle`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE `completions` (
`id_completion` int(11) NOT NULL AUTO_INCREMENT,
`fk_puzzle` int(11) NOT NULL,
`fk_player` int(11) NOT NULL,
`tries` int(11) DEFAULT 0,
`code` blob DEFAULT NULL,
`score` int(11) DEFAULT 0,
`fileName` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id_completion`),
KEY `fk_puzzle` (`fk_puzzle`),
KEY `fk_player` (`fk_player`),
CONSTRAINT `completions_ibfk_1` FOREIGN KEY (`fk_puzzle`) REFERENCES `puzzles` (`id_puzzle`),
CONSTRAINT `completions_ibfk_2` FOREIGN KEY (`fk_player`) REFERENCES `players` (`id_player`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE `tags` (
`id_tag` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id_tag`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE `containsBadges` (
`fk_player` int(11) NOT NULL,
`fk_badge` int(11) NOT NULL,
PRIMARY KEY (`fk_player`,`fk_badge`),
KEY `fk_badge` (`fk_badge`),
CONSTRAINT `containsBadges_ibfk_1` FOREIGN KEY (`fk_player`) REFERENCES `players` (`id_player`),
CONSTRAINT `containsBadges_ibfk_2` FOREIGN KEY (`fk_badge`) REFERENCES `badges` (`id_badge`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE `containsGroups` (
`fk_player` int(11) NOT NULL,
`fk_group` int(11) NOT NULL,
PRIMARY KEY (`fk_player`,`fk_group`),
KEY `fk_group` (`fk_group`),
CONSTRAINT `containsGroups_ibfk_1` FOREIGN KEY (`fk_player`) REFERENCES `players` (`id_player`),
CONSTRAINT `containsGroups_ibfk_2` FOREIGN KEY (`fk_group`) REFERENCES `groups` (`id_group`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
CREATE TABLE `containsTags` (
`fk_tag` int(11) NOT NULL,
`fk_puzzle` int(11) NOT NULL,
PRIMARY KEY (`fk_tag`,`fk_puzzle`),
KEY `fk_puzzle` (`fk_puzzle`),
CONSTRAINT `containsTags_ibfk_1` FOREIGN KEY (`fk_tag`) REFERENCES `tags` (`id_tag`),
CONSTRAINT `containsTags_ibfk_2` FOREIGN KEY (`fk_puzzle`) REFERENCES `puzzles` (`id_puzzle`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
INSERT INTO chapters (id_chapter, name) VALUES (1, 'chapter 1');
INSERT INTO players (pseudo, email, passwd,firstname,lastname) VALUES ('userTest', 'test@peerat.dev', '$argon2id$v=19$m=15360,t=2,p=1$$cAQwfs30Bf2rQGj86bpz7i59TlsuOFPiXeNpLlVu4AY', 'a','b')

Binary file not shown.

BIN
jakarta.mail-2.0.2.jar Normal file

Binary file not shown.

Binary file not shown.

View file

@ -1,136 +0,0 @@
package be.jeffcheasey88.peeratcode;
import static be.jeffcheasey88.peeratcode.framework.RequestType.OPTIONS;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.regex.Matcher;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import be.jeffcheasey88.peeratcode.framework.Client;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Locker;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.Router;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.model.Completion;
import be.jeffcheasey88.peeratcode.model.Group;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.routes.BadgeDetails;
import be.jeffcheasey88.peeratcode.routes.ChapterElement;
import be.jeffcheasey88.peeratcode.routes.ChapterList;
import be.jeffcheasey88.peeratcode.routes.DynamicLeaderboard;
import be.jeffcheasey88.peeratcode.routes.Leaderboard;
import be.jeffcheasey88.peeratcode.routes.Login;
import be.jeffcheasey88.peeratcode.routes.PlayerDetails;
import be.jeffcheasey88.peeratcode.routes.PuzzleElement;
import be.jeffcheasey88.peeratcode.routes.PuzzleResponse;
import be.jeffcheasey88.peeratcode.routes.Register;
import be.jeffcheasey88.peeratcode.routes.Result;
import be.jeffcheasey88.peeratcode.routes.groups.GroupCreate;
import be.jeffcheasey88.peeratcode.routes.groups.GroupJoin;
import be.jeffcheasey88.peeratcode.routes.groups.GroupList;
import be.jeffcheasey88.peeratcode.routes.groups.GroupQuit;
public class Main{
public static void main(String[] args) throws Exception{
Configuration config = new Configuration("config.txt");
config.load();
Class.forName("com.mysql.cj.jdbc.Driver");
Router router = new Router(new DatabaseRepository(config), config.getTokenIssuer(),
config.getTokenExpiration());
router.setDefault((matcher, user, reader, writer) -> {
writer.response(404, "Access-Control-Allow-Origin: *");
writer.write("404 not Found.\n");
writer.flush();
writer.close();
});
router.register(new Response(){
@Route(path = "^(.*)$", type = OPTIONS)
@Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
writer.response(200, "Access-Control-Allow-Origin: *",
"Access-Control-Allow-Methods: *", "Access-Control-Allow-Headers: *");
}
});
initRoutes(router, config);
// RouteExtracter extracter = new RouteExtracter(router);
// extracter.extract();
startWebServer(config, router);
}
private static void initRoutes(Router router, Configuration config){
router.register(new ChapterElement(router.getDataBase()));
router.register(new ChapterList(router.getDataBase()));
router.register(new PuzzleElement(router.getDataBase()));
router.register(new Register(router.getDataBase(), router, config.getUsersFiles()));
router.register(new Login(router.getDataBase(), router));
router.register(new Result(router.getDataBase()));
router.register(new Leaderboard(router.getDataBase()));
router.register(new PlayerDetails(router.getDataBase()));
router.register(new BadgeDetails(router.getDataBase()));
Locker<Group> groupLock = new Locker<>();
router.register(new GroupCreate(router.getDataBase(), groupLock, config.getGroupJoinMinutes()));
DynamicLeaderboard dlb = new DynamicLeaderboard(router.getDataBase());
router.register(dlb);
Locker<Completion> leaderboard = dlb.getLocker();
router.register(new PuzzleResponse(router.getDataBase(), config.getUsersFiles(), leaderboard));
router.register(new GroupList(router.getDataBase()));
router.register(new GroupJoin(router.getDataBase(), config.getGroupJoinMinutes(), config.getGroupQuitMinutes(), leaderboard));
router.register(new GroupQuit(router.getDataBase(), config.getGroupJoinMinutes(), leaderboard));
// Bot bot = new Bot(config, router.getDataBase(), groupLock);
// bot.start();
}
private static void startWebServer(Configuration config, Router router) throws IOException {
if (config.useSsl()) { // Not needed with the use of a proxy
SSLServerSocket server = null;
try {
System.setProperty("javax.net.ssl.keyStore", config.getSslKeystore());
System.setProperty("javax.net.ssl.keyStorePassword", config.getSslKeystorePasswd());
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
server = (SSLServerSocket) ssf.createServerSocket(config.getTcpPort());
while (!server.isClosed()) {
Socket socket = server.accept();
Client client = new Client(socket, router);
client.start();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (server != null) {
server.close();
}
}
} else {
try (ServerSocket server = new ServerSocket(config.getTcpPort())) {
while (!server.isClosed()) {
Socket socket = server.accept();
Client client = new Client(socket, router);
client.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View file

@ -1,49 +0,0 @@
package be.jeffcheasey88.peeratcode.bonus.extract;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;
import be.jeffcheasey88.peeratcode.framework.RequestType;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.Router;
//A noter que le but est d'extraire des informations sans modifier le code source,
//comme les tests unitaire, ici je veux générer un élément textuel qui me donnera l'état des routes,
//je ne vais donc pas modifier la classe router pour donner un accès au route.
public class RouteExtracter {
private Router router;
public RouteExtracter(Router router){
this.router = router;
}
public void extract() throws Exception{
Field field = Router.class.getDeclaredField("responses");
field.setAccessible(true);
Map<RequestType, Map<Response, Route>> responses = (Map<RequestType, Map<Response, Route>>) field.get(this.router);
for(Entry<RequestType, Map<Response, Route>> types : responses.entrySet()){
for(Entry<Response, Route> routes : types.getValue().entrySet()){
System.out.println("["+types.getKey()+"] ("+routes.getValue().needLogin()+") "+routes.getValue().path());
}
}
}
public void extractDoc() throws Exception{
Field field = Router.class.getDeclaredField("responses");
field.setAccessible(true);
Map<RequestType, Map<Response, Route>> responses = (Map<RequestType, Map<Response, Route>>) field.get(this.router);
for(Map<Response, Route> route : responses.values()){
for(Response response : route.keySet()){
Method method = response.getClass().getDeclaredMethod("exec",
Response.class.getDeclaredMethods()[0].getParameterTypes());
for(RouteDoc doc : method.getDeclaredAnnotationsByType(RouteDoc.class)){
System.out.println(doc.path()+((doc.path().isEmpty() ? "":"\n"))+" ["+doc.responseCode()+"] "+doc.responseDescription());
}
}
}
}
}

View file

@ -1,60 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
import java.net.Socket;
import java.util.Arrays;
import org.jose4j.jwa.AlgorithmConstraints.ConstraintType;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
public class Client extends Thread{
private HttpReader reader;
private HttpWriter writer;
private Router router;
public Client(Socket socket, Router router) throws Exception{
this.reader = new HttpReader(socket);
this.writer = new HttpWriter(socket);
this.router = router;
}
@Override
public void run(){
try{
String[] headers = reader.readLine().split("\\s");
System.out.println(Arrays.toString(headers));
reader.readHeaders();
router.exec(RequestType.valueOf(headers[0]), headers[1], isLogin(reader), reader, writer);
writer.flush();
writer.close();
}catch(Exception e){
e.printStackTrace();
}
}
private User isLogin(HttpReader reader) throws Exception{
String auth = reader.getHeader("Authorization");
if(auth == null) return null;
auth = auth.substring(7);
try{
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime()
.setAllowedClockSkewInSeconds(30)
.setExpectedIssuer(this.router.getTokenIssuer())
.setVerificationKey(this.router.getWebKey().getKey())
.setJwsAlgorithmConstraints(ConstraintType.PERMIT, AlgorithmIdentifiers.RSA_USING_SHA256).build();
JwtClaims jwtClaims = jwtConsumer.processToClaims(auth);
return new User(jwtClaims);
}catch(Exception e){
writer.response(401, "Access-Control-Allow-Origin: *");
writer.flush();
writer.close();
throw e;
}
}
}

View file

@ -1,138 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.json.simple.parser.JSONParser;
public class HttpReader{
private static Pattern HEADER_PATTERN = Pattern.compile("^([^:]*):\\s+(.*)$");
private Socket socket;
private InputStream in;
private BufferedReader reader;
private Map<String, String> headers;
public HttpReader(Socket socket) throws Exception{
this.socket = socket;
this.in = socket.getInputStream();
this.reader = new BufferedReader(new InputStreamReader(in));
this.headers = new HashMap<>();
}
public HttpReader(HttpReader origin) throws Exception{
this.socket = origin.socket;
this.in = origin.in;
this.reader = origin.reader;
}
public boolean isClosed(){
return this.socket.isClosed();
}
public void readHeaders() throws Exception{
String line;
while(((line = reader.readLine()) != null) && (line.length() > 0)){
Matcher matcher = HEADER_PATTERN.matcher(line);
matcher.matches();
this.headers.put(matcher.group(1).toLowerCase(), matcher.group(2));
}
}
public String getHeader(String key){
return this.headers.get(key.toLowerCase());
}
public int read(byte[] buffer) throws IOException{
return this.in.read(buffer);
}
public int read(char[] buffer) throws IOException{
return this.reader.read(buffer);
}
public String readLine() throws IOException{
return this.reader.readLine();
}
public boolean ready() throws IOException{
return this.reader.ready();
}
public int readInt() throws Exception{
int result = 0;
result += this.in.read() << 24;
result += this.in.read() << 16;
result += this.in.read() << 8;
result += this.in.read();
return result;
}
public <T> T readJson() throws Exception{
String line = "";
while (ready()){
char[] c = new char[1];
read(c);
line += c[0];
if (c[0] == '}'){
Object parse;
try {
parse = new JSONParser().parse(line);
if (parse != null)
return (T) parse;
}catch(Exception e){}
}
}
return null;
}
/*
*
------WebKitFormBoundaryNUjiLBAMuX2dhxU7
Content-Disposition: form-data; name="answer"
12
------WebKitFormBoundaryNUjiLBAMuX2dhxU7
Content-Disposition: form-data; name="filename"
webpack.js
------WebKitFormBoundaryNUjiLBAMuX2dhxU7
Content-Disposition: form-data; name="code_file"; filename="webpack.js"
Content-Type: text/javascript
------WebKitFormBoundaryNUjiLBAMuX2dhxU7--
*
*/
public List<String> readMultiPartData() throws Exception{
List<String> list = new ArrayList<>();
String boundary = getHeader("content-type");
if(boundary == null) return list;
boundary = boundary.split(";")[1].split("=")[1];
readLine();
while(ready()){
String line;
while (((line = readLine()) != null) && (line.length() > 0));
String buffer = "";
while (((line = readLine()) != null) && (!line.startsWith("--"+boundary))){
buffer += line;
}
list.add(buffer);
}
return list;
}
}

View file

@ -1,101 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class HttpWriter{
private OutputStream out;
private BufferedWriter writer;
public HttpWriter(Socket socket) throws Exception{
this.out = socket.getOutputStream();
this.writer = new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
}
public HttpWriter(HttpWriter origin) throws Exception{
this.out = origin.out;
this.writer = origin.writer;
}
public void write(byte[] buffer) throws IOException{
this.out.write(buffer);
this.out.flush();
}
public void write(String message) throws IOException{
this.writer.write(message);
}
public void flush() throws IOException{
this.writer.flush();
}
public void close() throws IOException{
this.writer.close();
}
public void response(int code, String... headers) throws Exception{
write("HTTP/1.1 "+code+codeMessage(code)+"\n");
for(String header : headers) write(header+"\n");
write("\n");
flush();
StackTraceElement[] e = Thread.currentThread().getStackTrace();
System.out.println(e[2]+" -> response "+code);
}
private static String[] HEIGHTBITS = new String[7];
private static String[] NINEBITS = new String[206];
static {
HEIGHTBITS[0] = " OK";
HEIGHTBITS[1] = " Created";
HEIGHTBITS[2] = " Accepted";
HEIGHTBITS[3] = " Non-Authoritative Information";
HEIGHTBITS[4] = " No Content";
HEIGHTBITS[5] = " Reset Content";
HEIGHTBITS[6] = " Partial Content";
NINEBITS[0] = " Multiple Choices";
NINEBITS[1] = " Moved Permanently";
NINEBITS[2] = " Temporary Redirect";
NINEBITS[3] = " See Other";
NINEBITS[4] = " Not Modified";
NINEBITS[5] = " Use Proxy";
NINEBITS[100] = " Bad Request";
NINEBITS[101] = " Unauthorized";
NINEBITS[102] = " Payment Required";
NINEBITS[103] = " Forbidden";
NINEBITS[104] = " Not Found";
NINEBITS[105] = " Method Not Allowed";
NINEBITS[106] = " Not Acceptable";
NINEBITS[107] = " Proxy Authentication Required";
NINEBITS[108] = " Request Time-Out";
NINEBITS[109] = " Conflict";
NINEBITS[110] = " Gone";
NINEBITS[111] = " Length Required";
NINEBITS[112] = " Precondition Failed";
NINEBITS[113] = " Request Entity Too Large";
NINEBITS[114] = " Request-URI Too Large";
NINEBITS[115] = " Unsupported Media Type";
NINEBITS[200] = " Internal Server Error";
NINEBITS[201] = " Not Implemented";
NINEBITS[202] = " Bad Gateway";
NINEBITS[203] = " Service Unavailable";
NINEBITS[204] = " Gateway Timeout";
NINEBITS[205] = " HTTP Version Not Supported";
}
private static String codeMessage(int code){
if(code == 100) return " Continue";
if(code >> 8 == 0) return HEIGHTBITS[code-200];
return NINEBITS[code-300];
}
}

View file

@ -1,59 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class Locker<V>{
private Map<Key, BlockingQueue<V>> map;
public Locker(){
this.map = new HashMap<>();
}
public void init(Key key){
this.map.put(key, new LinkedBlockingQueue<>());
}
public void remove(Key key){
this.map.remove(key);
}
private BlockingQueue<V> get(Key key){
return this.map.get(key);
}
public void setValue(V value){
for(Entry<Key, BlockingQueue<V>> entry : this.map.entrySet()){
entry.getValue().add(value);
this.unlock(entry.getKey());
}
}
public V getValue(Key key){
BlockingQueue<V> queue = get(key);
if(queue.isEmpty()) return null;
return queue.poll();
}
public void lock(Key key) throws InterruptedException{
BlockingQueue<V> queue = get(key);
if(queue.isEmpty()){
synchronized(queue){
queue.wait();
}
}
}
public void unlock(Key key){
BlockingQueue<V> queue = get(key);
synchronized(queue){
queue.notify();
}
}
public static class Key{ public Key(){} }
}

View file

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

View file

@ -1,9 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
import java.util.regex.Matcher;
public interface Response{
void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception;
}

View file

@ -1,19 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Route{
String path() default "^.*$";
RequestType type() default RequestType.GET;
boolean needLogin() default false;
boolean websocket() default false;
}

View file

@ -1,178 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jwk.RsaJwkGenerator;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.lang.JoseException;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class Router{
private Map<RequestType, Map<Response, Route>> responses;
private Map<Response, Pattern> patterns;
private Response noFileFound;
private RsaJsonWebKey rsaJsonWebKey;
private DatabaseRepository repo;
private String token_issuer;
private int token_expiration;
public Router(DatabaseRepository repo, String token_issuer, int token_expiration) throws Exception{
this.repo = repo;
this.token_issuer = token_issuer;
this.token_expiration = token_expiration;
this.responses = new HashMap<>();
for(RequestType type : RequestType.values()) this.responses.put(type, new HashMap<>());
this.patterns = new HashMap<>();
this.rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
}
public DatabaseRepository getDataBase(){
return this.repo;
}
public void register(Response response){
try{
Method method = response.getClass().getDeclaredMethod("exec",
Response.class.getDeclaredMethods()[0].getParameterTypes());
Route route = method.getAnnotation(Route.class);
this.responses.get(route.type()).put(response, route);
this.patterns.put(response, Pattern.compile(route.path()));
}catch(Exception e){
throw new IllegalArgumentException(e);
}
}
public void setDefault(Response response){
this.noFileFound = response;
}
public void exec(RequestType type, String path, User user, HttpReader reader, HttpWriter writer) throws Exception{
if(type == null) return;
for(Entry<Response, Route> routes : this.responses.get(type).entrySet()){
Matcher matcher = this.patterns.get(routes.getKey()).matcher(path);
if(matcher.matches()){
if(user == null && routes.getValue().needLogin()){
writer.response(401, "Access-Control-Allow-Origin: *");
return;
}
if(routes.getValue().websocket()){
switchToWebSocket(reader, writer);
reader = new WebSocketReader(reader);
writer = new WebSocketWriter(writer);
}
routes.getKey().exec(matcher, user, reader, writer);
return;
}
}
if(noFileFound != null) noFileFound.exec(null, user, reader, writer);
}
public RsaJsonWebKey getWebKey(){
return this.rsaJsonWebKey;
}
public String getTokenIssuer(){
return this.token_issuer;
}
public String createAuthUser(int id) throws JoseException{
JwtClaims claims = new JwtClaims();
claims.setIssuer(token_issuer); // who creates the token and signs it
claims.setExpirationTimeMinutesInTheFuture(token_expiration);
claims.setGeneratedJwtId(); // a unique identifier for the token
claims.setIssuedAtToNow(); // when the token was issued/created (now)
claims.setNotBeforeMinutesInThePast(2); // time before which the token is not yet valid (2 minutes ago)
claims.setClaim("id", id);
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toJson());
jws.setKey(rsaJsonWebKey.getPrivateKey());
jws.setKeyIdHeaderValue(rsaJsonWebKey.getKeyId());
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
return jws.getCompactSerialization();
}
private void switchToWebSocket(HttpReader reader, HttpWriter writer) throws Exception{
String key = reader.getHeader("Sec-WebSocket-Key");
if (key == null) throw new IllegalArgumentException();
writer.write("HTTP/1.1 101 Switching Protocols\n");
writer.write("Connection: Upgrade\n");
writer.write("Upgrade: websocket\n");
writer.write("Sec-WebSocket-Accept: " + printBase64Binary(MessageDigest.getInstance("SHA-1")
.digest((key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").getBytes("UTF-8"))) + "\n");
writer.write("\n");
writer.flush();
}
// From javax.xml.bind.DatatypeConverter
private String printBase64Binary(byte[] array){
char[] arrayOfChar = new char[(array.length + 2) / 3 * 4];
int i = _printBase64Binary(array, 0, array.length, arrayOfChar, 0);
assert i == arrayOfChar.length;
return new String(arrayOfChar);
}
private int _printBase64Binary(byte[] paramArrayOfbyte, int paramInt1, int paramInt2,
char[] paramArrayOfchar, int paramInt3){
int i = paramInt2;
int j;
for (j = paramInt1; i >= 3; j += 3){
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
paramArrayOfchar[paramInt3++] = encode(
(paramArrayOfbyte[j] & 0x3) << 4 | paramArrayOfbyte[j + 1] >> 4 & 0xF);
paramArrayOfchar[paramInt3++] = encode(
(paramArrayOfbyte[j + 1] & 0xF) << 2 | paramArrayOfbyte[j + 2] >> 6 & 0x3);
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j + 2] & 0x3F);
i -= 3;
}
if (i == 1){
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j] & 0x3) << 4);
paramArrayOfchar[paramInt3++] = '=';
paramArrayOfchar[paramInt3++] = '=';
}
if (i == 2){
paramArrayOfchar[paramInt3++] = encode(paramArrayOfbyte[j] >> 2);
paramArrayOfchar[paramInt3++] = encode(
(paramArrayOfbyte[j] & 0x3) << 4 | paramArrayOfbyte[j + 1] >> 4 & 0xF);
paramArrayOfchar[paramInt3++] = encode((paramArrayOfbyte[j + 1] & 0xF) << 2);
paramArrayOfchar[paramInt3++] = '=';
}
return paramInt3;
}
private char encode(int paramInt){
return encodeMap[paramInt & 0x3F];
}
private static final char[] encodeMap = initEncodeMap();
private static char[] initEncodeMap(){
char[] arrayOfChar = new char[64];
byte b;
for (b = 0; b < 26; b++)
arrayOfChar[b] = (char) (65 + b);
for (b = 26; b < 52; b++)
arrayOfChar[b] = (char) (97 + b - 26);
for (b = 52; b < 62; b++)
arrayOfChar[b] = (char) (48 + b - 52);
arrayOfChar[62] = '+';
arrayOfChar[63] = '/';
return arrayOfChar;
}
}

View file

@ -1,27 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
import org.jose4j.jwt.JwtClaims;
import be.jeffcheasey88.peeratcode.framework.Locker.Key;
public class User{
private int id;
private Key key;
public User(JwtClaims jwtClaims){
this.id = ((Long) jwtClaims.getClaimValue("id")).intValue();
}
public void setKey(Key key){
this.key = key;
}
public Key getKey(){
return this.key;
}
public int getId(){
return this.id;
}
}

View file

@ -1,62 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
import java.io.IOException;
public class WebSocketReader extends HttpReader{
public WebSocketReader(HttpReader origin) throws Exception{
super(origin);
}
@Override
public String readLine() throws IOException{
//read websocket found on StackOverFlow
int buffLenth = 1024;
int len = 0;
byte[] b = new byte[buffLenth];
// rawIn is a Socket.getInputStream();
while (true){
len = read(b);
if (len != -1){
byte rLength = 0;
int rMaskIndex = 2;
int rDataStart = 0;
// b[0] is always text in my case so no need to check;
byte data = b[1];
byte op = (byte) 127;
rLength = (byte) (data & op);
if (rLength == (byte) 126)
rMaskIndex = 4;
if (rLength == (byte) 127)
rMaskIndex = 10;
byte[] masks = new byte[4];
int j = 0;
int i = 0;
for (i = rMaskIndex; i < (rMaskIndex + 4); i++){
masks[j] = b[i];
j++;
}
rDataStart = rMaskIndex + 4;
int messLen = len - rDataStart;
byte[] message = new byte[messLen];
for (i = rDataStart, j = 0; i < len; i++, j++){
message[j] = (byte) (b[i] ^ masks[j % 4]);
}
return new String(message);
} else
break;
}
return null;
}
}

View file

@ -1,61 +0,0 @@
package be.jeffcheasey88.peeratcode.framework;
import java.io.IOException;
public class WebSocketWriter extends HttpWriter{
public WebSocketWriter(HttpWriter origin) throws Exception{
super(origin);
}
@Override
public void write(String message) throws IOException{
//write websocket found on StackOverFlow
byte[] rawData = message.getBytes();
int frameCount = 0;
byte[] frame = new byte[10];
frame[0] = (byte) 129;
if (rawData.length <= 125){
frame[1] = (byte) rawData.length;
frameCount = 2;
} else if (rawData.length >= 126 && rawData.length <= 65535){
frame[1] = (byte) 126;
int len = rawData.length;
frame[2] = (byte) ((len >> 8) & (byte) 255);
frame[3] = (byte) (len & (byte) 255);
frameCount = 4;
} else {
frame[1] = (byte) 127;
int len = rawData.length;
frame[2] = (byte) ((len >> 56) & (byte) 255);
frame[3] = (byte) ((len >> 48) & (byte) 255);
frame[4] = (byte) ((len >> 40) & (byte) 255);
frame[5] = (byte) ((len >> 32) & (byte) 255);
frame[6] = (byte) ((len >> 24) & (byte) 255);
frame[7] = (byte) ((len >> 16) & (byte) 255);
frame[8] = (byte) ((len >> 8) & (byte) 255);
frame[9] = (byte) (len & (byte) 255);
frameCount = 10;
}
int bLength = frameCount + rawData.length;
byte[] reply = new byte[bLength];
int bLim = 0;
for (int i = 0; i < frameCount; i++){
reply[bLim] = frame[i];
bLim++;
}
for (int i = 0; i < rawData.length; i++){
reply[bLim] = rawData[i];
bLim++;
}
write(reply);
flush();
}
}

View file

@ -1,110 +0,0 @@
package be.jeffcheasey88.peeratcode.parser.java;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Class {
private static Pattern PATTERN = Pattern.compile("^(\\s*([^\\{]*)\\{(.*)\\})\\s*$");
private int modifier;
private String name;
private List<Variable> vars;
private List<Function> functions;
public Class(){}
public int parse(String content) throws Exception{
Matcher matcher = PATTERN.matcher(content);
matcher.matches();
String[] split = matcher.group(2).split("\\s+");
for(int i = 0; i < split.length-1; i++){
this.modifier+=JavaParser.getModifier(split[i]);
}
this.name = split[split.length-1];
this.vars = new ArrayList<>();
this.functions = new ArrayList<>();
content = matcher.group(3);
Pattern empty = Pattern.compile("^\\s*$");
while(!(empty.matcher(content).matches())){
int quotes = indexOf(content,";");
int braces = indexOf(content,"\\{");
int equals = indexOf(content,"=");
if(quotes < braces && quotes < equals){
boolean quote = false;
Variable last = null;
do {
Variable variable = (last == null) ? new Variable() : new Variable(last.getModifier(), last.getType());
int index = variable.parse(content);
this.vars.add(variable);
content = content.substring(index);
quote = content.startsWith(",");
if(quote) {
content = content.substring(1);
last = variable;
}
}while(quote);
}else if(equals < braces){
//variable with value
boolean quote = false;
Variable last = null;
do {
Variable variable = (last == null) ? new Variable() : new Variable(last.getModifier(), last.getType());
int index = variable.parse(content);
this.vars.add(variable);
content = content.substring(index);
quote = content.startsWith(",");
if(quote) {
content = content.substring(1);
last = variable;
}else if(indexOf(content, "=") < indexOf(content, ";")){
Operation operation = new Operation();
index = operation.parse(content);
content = content.substring(index);
break;
}
}while(quote);
}else{
System.out.println("Function "+content);
Function func = new Function();
int index = func.parse(content);
this.functions.add(func);
content = content.substring(index);
System.out.println("End "+content);
}
}
return matcher.group(1).length();
}
private int indexOf(String value, String target){
return value.split(target)[0].length();
}
public int getModifier(){
return this.modifier;
}
public String getName(){
return this.name;
}
public List<Variable> getVariables(){
return this.vars;
}
public void show(){
System.out.println(Modifier.toString(modifier)+" "+this.name+"{");
for(Variable v : this.vars) v.show(1);
System.out.println();
for(Function f : this.functions) f.show(1);
System.out.println("}");
}
}

View file

@ -1,94 +0,0 @@
package be.jeffcheasey88.peeratcode.parser.java;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public class CleanerPool {
private static String CONSTANT_REPLACER_STRING = "$STRING_STATEMENT_CONSTANT_";
private static String CONSTANT_REPLACER_CHAR = "$CHAR_STATEMENT_CONSTANT_";
private static String CONSTANT_REPLACER_GENERIC = "$GENERIC_STATEMENT_CONSTANT_";
private List<String> constants;
private CleanerPool(){
this.constants = new ArrayList<>();
}
public String clean(String statement){
char[] chars = statement.toCharArray();
StringBuilder builder = new StringBuilder();
for(int i = 0; i < chars.length; i++){
char current = chars[i];
if(current== '"'){
int constantPos = this.constants.size();
String constant = cutConstant(chars, i);
i+=constant.length()+1;
builder.append(CONSTANT_REPLACER_STRING+constantPos);
this.constants.add(constant);
}else{
builder.append(current);
}
}
for(String s : constants){
System.out.println("CONSTANT="+s);
}
return builder.toString();
}
public boolean isConstant(String region){
return region.startsWith(CONSTANT_REPLACER_STRING);
}
public String getConstant(String replacer){
if(!replacer.startsWith(CONSTANT_REPLACER_STRING)) return null;
return this.constants.get(Integer.parseInt(replacer.replace(CONSTANT_REPLACER_STRING,"")));
}
public List<String> getConstants(){
return this.constants;
}
private static Pattern parenthesisPattern = Pattern.compile("^\\$SQL_STATEMENT_PARENTHESIS_([0-9]*$)");
public boolean isParenthesis(String region){
return parenthesisPattern.matcher(region).matches();
}
private String cutConstant(char[] chars, int pos){
StringBuilder builder = new StringBuilder();
for(int i = pos+1; i < chars.length; i++){
char current = chars[i];
if(current == '"'){
if(current == '\\'){ //toChange
builder.append(current);
}else break;
}else{
builder.append(current);
}
}
return builder.toString();
}
public static interface Cutter{
String execute(String value, List<String> constants, String pattern);
default String cutOpenable(String value, List<String> constants, String pattern, char open, char close){
StringBuilder builder = new StringBuilder();
for(char c : value.toCharArray()){
if(c == open){
}else if(c == close){
}
}
return builder.toString();
}
}
}

View file

@ -1,85 +0,0 @@
package be.jeffcheasey88.peeratcode.parser.java;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Function {
private static Pattern PATTERN = Pattern.compile("^(\\s*([^(]*)\\(([^)]*)\\)\\s*([^{]*)\\{)(.*)$");
private int modifier;
private String name;
private String exceptions;
private String parameters;
private List<Function> functions;
private List<Operation> operations;
public Function(){
this.functions = new ArrayList<>();
this.operations = new ArrayList<>();
}
public int parse(String content) throws Exception{
Matcher matcher = PATTERN.matcher(content);
matcher.matches();
String[] split = matcher.group(2).split("\\s+");
for(int i = 0; i < split.length-2; i++){
this.modifier+=JavaParser.getModifier(split[i]);
}
this.name = split[split.length-1];
this.parameters = matcher.group(3);
this.exceptions = matcher.group(4);
String body = matcher.group(5);
int offset = 0;
int index = 0;
do {
int end = body.indexOf('}');
int braces = body.indexOf('{');
int quotes = body.indexOf(';');
if((end < 0) || (end < braces && end < quotes)){
if(end > 0) offset+=end;
break;
}
if(braces < 0 && quotes < 0){
if(end > 0) offset+=end;
break;
}
if(braces >= 0 && braces < quotes){
Function func = new Function();
index = func.parse(body.substring(0, end+1));
this.functions.add(func);
}else{
Operation op = new Operation();
index = op.parse(body.substring(0, end+1));
this.operations.add(op);
}
offset+=index+1;
body = body.substring(index);
}while(offset > -1);
return matcher.group(1).length()+offset;
}
public void show(int tab){
String start = "";
for(int i = 0; i < tab; i++) start+="\t";
System.out.println(start+Modifier.toString(modifier)+" "+name+"("+parameters+") "+exceptions+" {");
for(Operation o : this.operations) o.show(tab+1);
System.out.println();
for(Function f : this.functions) f.show(tab+1);
System.out.println(start+"}");
}
@Override
public String toString(){
return "Function[name="+name+",param="+parameters+",exception="+exceptions+"]";
}
}

View file

@ -1,28 +0,0 @@
package be.jeffcheasey88.peeratcode.parser.java;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Import {
private static Pattern PATTERN = Pattern.compile("^\\s*(import\\s+([^;]*);).*$");
public static boolean isImport(String content){
return PATTERN.matcher(content).matches();
}
private String name;
public Import(){}
public int parse(String content) throws Exception{
Matcher matcher = PATTERN.matcher(content);
matcher.matches();
this.name = matcher.group(2);
return matcher.group(1).length();
}
public String getName(){
return this.name;
}
}

View file

@ -1,96 +0,0 @@
package be.jeffcheasey88.peeratcode.parser.java;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
public class JavaParser {
public static void main(String[] args) throws Exception {
File file = new File("C:\\Users\\jeffc\\eclipse-workspace\\peer-at-code-backend\\src\\be\\jeffcheasey88\\peeratcode\\parser\\java\\Import.java");
BufferedReader reader = new BufferedReader(new FileReader(file));
JavaParser parser = new JavaParser(reader);
parser.parse();
System.out.println("SHOW-----------------");
parser.show();
}
private Package pack;
private List<Import> imports;
private Class clazz;
private BufferedReader reader;
public JavaParser(BufferedReader reader){
this.reader = reader;
}
public void parse() throws Exception{
String content = "";
int index;
String line;
while((line = reader.readLine()) != null) content+=line;
// content = CleanerPool.getterToDelete.clean(content);
this.pack = new Package();
index = this.pack.parse(content);
content = content.substring(index);
this.imports = new ArrayList<>();
while(Import.isImport(content)){
Import imp = new Import();
index = imp.parse(content);
this.imports.add(imp);
content = content.substring(index);
}
this.clazz = new Class();
index = this.clazz.parse(content);
content = content.substring(index);
}
public Package getPackage(){
return this.pack;
}
public List<Import> getImports(){
return this.imports;
}
public Class getClazz(){
return this.clazz;
}
public void show(){
System.out.println("package "+this.pack.getName()+";");
System.out.println();
for(Import i : this.imports) System.out.println("import "+i.getName()+";");
System.out.println();
this.clazz.show();
}
public static int getModifier(String modifier){
switch(modifier){
case "public": return Modifier.PUBLIC;
case "private": return Modifier.PRIVATE;
case "protected": return Modifier.PROTECTED;
case "static": return Modifier.STATIC;
case "final": return Modifier.FINAL;
case "synchronized": return Modifier.SYNCHRONIZED;
case "volatile": return Modifier.VOLATILE;
case "transient": return Modifier.TRANSIENT;
case "native": return Modifier.NATIVE;
case "abstract": return Modifier.ABSTRACT;
case "strictfp": return Modifier.STRICT;
default: break;
}
return 0;
}
}

View file

@ -1,29 +0,0 @@
package be.jeffcheasey88.peeratcode.parser.java;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Operation {
private static Pattern VARIABLE_PATTERN = Pattern.compile("^(\\s*([^;]*)).*$");
private String tmp;
public Operation(){}
public int parse(String content) throws Exception{
Matcher matcher = VARIABLE_PATTERN.matcher(content);
if(matcher.matches()){
this.tmp = matcher.group(2);
return matcher.group(1).length()+1;
}
return 0;
}
public void show(int tab){
String start = "";
for(int i = 0; i < tab; i++) start+="\t";
System.out.println(start+tmp+";");
}
}

View file

@ -1,24 +0,0 @@
package be.jeffcheasey88.peeratcode.parser.java;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Package {
private static Pattern PATTERN = Pattern.compile("^(\\s*package\\s+([^;]*);).*$");
private String name;
public Package(){}
public int parse(String content) throws Exception{
Matcher matcher = PATTERN.matcher(content);
matcher.matches();
this.name = matcher.group(2);
return matcher.group(1).length();
}
public String getName(){
return this.name;
}
}

View file

@ -1,127 +0,0 @@
package be.jeffcheasey88.peeratcode.parser.java;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Variable {
private static Pattern PATTERN = Pattern.compile("^(\\s*)(.*)$");
private int modifier;
private String name;
private String type;
private Variable value;
public Variable(){}
public Variable(int modifier, String type){
this.modifier = modifier;
this.type = type;
}
public int parse(String content) throws Exception{
Matcher matcher = PATTERN.matcher(content);
matcher.matches();
int offset = matcher.group(1).length();
String body = matcher.group(2);
int equals = indexOf(body, "=");
int quote = indexOf(body,",");
int quotes = indexOf(body, ";");
int min = Math.min(quote, quotes);
body = body.substring(0, min);
if(equals < quote && equals < quotes){
assigment(body);
}else{
onlyDefine(body);
}
return offset+min;
}
private void assigment(String content){
}
private void onlyDefine(String content){
content = generiqueTypes(content);
System.out.println(content);
String[] values = content.split("\\s+");
for(String value : values){
int modifier = JavaParser.getModifier(value);
if(modifier > 0){
this.modifier+=modifier;
continue;
}
if(this.type == null){
this.type = value;
continue;
}
this.name = value;
}
}
private String generiqueTypes(String content){
System.out.println(content);
String result = "";
int opened = 0;
for(char c : content.toCharArray()){
if(c == '<') opened++;
else if(c == '>') opened--;
if(opened > 0){
if(Character.isWhitespace(c)) continue;
}
result+=c;
}
result = result.replaceAll("(>\\s*)", "> ").replace("> >", ">>");
return result;
}
private int indexOf(String value, String target){
return value.split(target)[0].length();
}
public int getModifier(){
return this.modifier;
}
public String getName(){
return this.name;
}
public String getType(){
return this.type;
}
public Variable getValue(){
return this.value;
}
public void show(int tab){
String start = "";
for(int i = 0; i < tab; i++) start+="\t";
System.out.println(start+Modifier.toString(modifier)+" "+type+" "+name+(value == null ? ";":"="+value+";"));
}
public static class Value extends Variable{
private String value;
public Value(String value){
this.value = value;
}
public String value(){
return this.value;
}
@Override
public String toString(){
return this.value;
}
}
}

View file

@ -1,47 +0,0 @@
package be.jeffcheasey88.peeratcode.routes;
import java.util.Base64;
import java.util.regex.Matcher;
import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.model.Badge;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class BadgeDetails implements Response {
private final DatabaseRepository databaseRepo;
public BadgeDetails(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/badge/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du badge")
@RouteDoc(responseCode = 400, responseDescription = "Aucun id donner")
@Route(path = "^\\/badge\\/([0-9]+)$", needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
if (matcher.groupCount() > 0) {
int badgeId = Integer.parseInt(matcher.group(1));
Badge badge = databaseRepo.getBadge(badgeId);
JSONObject badgeJSON = new JSONObject();
if (badge != null) {
badgeJSON.put("name", badge.getName());
if (badge.getLogo() != null)
badgeJSON.put("logo", Base64.getEncoder().encodeToString(badge.getLogo()));
badgeJSON.put("level", badge.getLevel());
}
writer.response(200, "Access-Control-Allow-Origin: *");
writer.write(badgeJSON.toJSONString().replace("\\", ""));
} else {
writer.response(400, "Access-Control-Allow-Origin: *");
}
}
}

View file

@ -1,59 +0,0 @@
package be.jeffcheasey88.peeratcode.routes;
import java.util.regex.Matcher;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.model.Chapter;
import be.jeffcheasey88.peeratcode.model.Puzzle;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class ChapterElement implements Response {
private final DatabaseRepository databaseRepo;
public ChapterElement(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/chapter/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du chapitre demander")
@RouteDoc(responseCode = 400, responseDescription = "Aucun id donner")
@Route(path = "^\\/chapter\\/([0-9]+)$", needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{
Chapter chapter = databaseRepo.getChapter(Integer.parseInt(matcher.group(1)));
if (chapter != null){
JSONObject chapterJSON = new JSONObject();
chapterJSON.put("id", chapter.getId());
chapterJSON.put("name", chapter.getName());
if (chapter.getStartDate() != null)
chapterJSON.put("startDate", chapter.getStartDate().toString());
if (chapter.getEndDate() != null)
chapterJSON.put("endDate", chapter.getEndDate().toString());
JSONArray puzzles = new JSONArray();
for (Puzzle puzzle : chapter.getPuzzles()){
JSONObject puzzleJSON = new JSONObject();
puzzleJSON.put("id", puzzle.getId());
puzzleJSON.put("name", puzzle.getName());
puzzleJSON.put("scoreMax", puzzle.getScoreMax());
if (puzzle.getTags() != null) puzzleJSON.put("tags", puzzle.getJsonTags());
int score = this.databaseRepo.getScore(user.getId(), puzzle.getId());
if(score >= 0) puzzleJSON.put("score", score);
puzzles.add(puzzleJSON);
}
chapterJSON.put("puzzles", puzzles);
writer.response(200, "Access-Control-Allow-Origin: *");
writer.write(chapterJSON.toJSONString());
} else {
writer.response(400, "Access-Control-Allow-Origin: *");
}
}
}

View file

@ -1,51 +0,0 @@
package be.jeffcheasey88.peeratcode.routes;
import java.util.List;
import java.util.regex.Matcher;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.model.Chapter;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class ChapterList implements Response {
private final DatabaseRepository databaseRepo;
public ChapterList(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/chapters", responseCode = 200, responseDescription = "JSON contenant les informations des chapitres")
@RouteDoc(responseCode = 400, responseDescription = "Aucun chapitre trouver")
@Route(path = "^\\/chapters$", needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
List<Chapter> allChapters = databaseRepo.getAllChapters();
if (allChapters != null) {
JSONArray chaptersJSON = new JSONArray();
for (Chapter chapter : allChapters) {
JSONObject chapterJSON = new JSONObject();
chapterJSON.put("id", chapter.getId());
chapterJSON.put("name", chapter.getName());
if (chapter.getStartDate() != null)
chapterJSON.put("startDate", chapter.getStartDate().toString());
if (chapter.getEndDate() != null)
chapterJSON.put("endDate", chapter.getEndDate().toString());
chaptersJSON.add(chapterJSON);
}
writer.response(200, "Access-Control-Allow-Origin: *");
writer.write(chaptersJSON.toJSONString());
} else {
writer.response(400, "Access-Control-Allow-Origin: *");
}
}
}

View file

@ -1,53 +0,0 @@
package be.jeffcheasey88.peeratcode.routes;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
import java.util.regex.Matcher;
import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.Router;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class Login implements Response {
private DatabaseRepository databaseRepo;
private Router router;
public Login(DatabaseRepository databaseRepo, Router router) {
this.databaseRepo = databaseRepo;
this.router = router;
}
@RouteDoc(path = "/login", 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 = "^\\/login$", type = POST)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
if (user != null) {
writer.response(403, "Access-Control-Allow-Origin: *");
return;
}
JSONObject informations = reader.readJson();
if (informations != null) {
String pseudo = (String) informations.get("pseudo");
String password = (String) informations.get("passwd");
int id;
if ((id = databaseRepo.login(pseudo, password)) >= 0) {
writer.response(200, "Access-Control-Allow-Origin: *",
"Access-Control-Expose-Headers: Authorization",
"Authorization: Bearer " + this.router.createAuthUser(id));
return;
}
}
writer.response(400, "Access-Control-Allow-Origin: *");
}
}

View file

@ -1,61 +0,0 @@
package be.jeffcheasey88.peeratcode.routes;
import java.util.Base64;
import java.util.regex.Matcher;
import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.model.Player;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class PlayerDetails implements Response {
private final DatabaseRepository databaseRepo;
public PlayerDetails(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/player/{id}", responseCode = 200, responseDescription = "JSON contenant les informations de l'utilisateur")
@RouteDoc(responseCode = 400, responseDescription = "Utilisateur introuvable dans la base de donnée")
@Route(path = "^\\/player\\/?(.+)?$", needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
Player player;
if (matcher.group(1) != null) {
player = databaseRepo.getPlayerDetails(matcher.group(1));
} else {
player = databaseRepo.getPlayerDetails(user.getId());
}
JSONObject playerJSON = new JSONObject();
if (player != null) {
playerJSON.put("pseudo", player.getPseudo());
playerJSON.put("email", player.getEmail());
playerJSON.put("firstname", player.getFirstname());
playerJSON.put("lastname", player.getLastname());
playerJSON.put("description", player.getDescription());
if (player.getGroups() != null)
playerJSON.put("groups", player.getJsonGroups());
playerJSON.put("rank", player.getRank());
playerJSON.put("score", player.getTotalScore());
playerJSON.put("completions", player.getTotalCompletion());
playerJSON.put("completionsList", player.getJsonCompletions());
playerJSON.put("tries", player.getTotalTries());
if (player.getBadges() != null)
playerJSON.put("badges", player.getJsonBadges());
if (player.getAvatar() != null)
playerJSON.put("avatar", Base64.getEncoder().encodeToString(player.getAvatar()));
writer.response(200, "Access-Control-Allow-Origin: *");
writer.write(playerJSON.toJSONString().replace("\\", ""));
} else {
writer.response(400, "Access-Control-Allow-Origin: *");
}
}
}

View file

@ -1,91 +0,0 @@
package be.jeffcheasey88.peeratcode.routes;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.Router;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class Register implements Response {
private DatabaseRepository databaseRepo;
private Router router;
private String usersFilesPath;
public Register(DatabaseRepository databaseRepo, Router router, String initUsersFilesPath) {
this.databaseRepo = databaseRepo;
this.router = router;
usersFilesPath = initUsersFilesPath;
}
@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, User user, HttpReader reader, HttpWriter writer) throws Exception{
if (user != null){
writer.response(403, "Access-Control-Allow-Origin: *");
return;
}
JSONObject informations = reader.readJson();
if (informations != null) {
boolean allFieldsFilled = informations.containsKey("pseudo") && informations.containsKey("email")
&& informations.containsKey("passwd") && informations.containsKey("firstname")
&& informations.containsKey("lastname") && informations.containsKey("description")
&& informations.containsKey("sgroup") && informations.containsKey("avatar");
if (!allFieldsFilled) {
writer.response(403, "Access-Control-Allow-Origin: *");
return;
}
String pseudo = (String) informations.get("pseudo");
String email = (String) informations.get("email");
String password = (String) informations.get("passwd");
String firstname = (String) informations.get("firstname");
String lastname = (String) informations.get("lastname");
String description = (String) informations.get("description");
String group = (String) informations.get("sgroup");
String avatar = (String) informations.get("avatar");
boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo);
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
if (pseudoAvailable && emailAvailable) {
int id;
if ((id = databaseRepo.register(pseudo, email, password, firstname, lastname, description, group,
avatar)) >= 0) {
writer.response(200, "Access-Control-Allow-Origin: *",
"Access-Control-Expose-Headers: Authorization",
"Authorization: Bearer " + this.router.createAuthUser(id));
createFolderToSaveSourceCode(pseudo);
return;
}
} else {
writer.response(400, "Access-Control-Allow-Origin: *");
JSONObject error = new JSONObject();
error.put("username_valid", pseudoAvailable);
error.put("email_valid", emailAvailable);
writer.write(error.toJSONString());
return;
}
}
writer.response(400, "Access-Control-Allow-Origin: *");
}
private void createFolderToSaveSourceCode(String pseudo) throws IOException {
Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo)));
}
}

View file

@ -1,37 +0,0 @@
package be.jeffcheasey88.peeratcode.routes;
import java.util.regex.Matcher;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class Result implements Response {
private DatabaseRepository repo;
public Result(DatabaseRepository repo) {
this.repo = repo;
}
@RouteDoc(path = "/result/<id>", responseCode = 200, responseDescription = "Le score")
@RouteDoc(responseCode = 425, responseDescription = "Puzzle pas compléter")
@Route(path = "^\\/result\\/(\\d+)$", needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
int puzzle = Integer.parseInt(matcher.group(1));
int score = this.repo.getScore(user.getId(), puzzle);
if (score < 0) {
writer.response(425, "Access-Control-Allow-Origin: *");
} else {
writer.response(200, "Access-Control-Allow-Origin: *");
writer.write(score + "");
}
}
}

View file

@ -1,34 +0,0 @@
package be.jeffcheasey88.peeratcode.routes.groups;
import java.util.regex.Matcher;
import org.json.simple.JSONArray;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.Response;
import be.jeffcheasey88.peeratcode.framework.Route;
import be.jeffcheasey88.peeratcode.framework.User;
import be.jeffcheasey88.peeratcode.model.Group;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class GroupList implements Response {
private DatabaseRepository repo;
public GroupList(DatabaseRepository repo) {
this.repo = repo;
}
@RouteDoc(path = "/groups", responseCode = 200, responseDescription = "JSON avec la liste des groups")
@Route(path = "^\\/groups$", needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
writer.response(200, "Access-Control-Allow-Origin: *");
JSONArray result = new JSONArray();
for(Group group : this.repo.getAllGroups()) result.add(group.toJson());
writer.write(result.toJSONString());
}
}

View file

@ -1,4 +1,4 @@
package be.jeffcheasey88.peeratcode; package dev.peerat.backend;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.BufferedWriter; import java.io.BufferedWriter;
@ -7,6 +7,8 @@ import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import dev.peerat.backend.utils.Mail;
public class Configuration { public class Configuration {
private String db_host; private String db_host;
@ -30,23 +32,37 @@ public class Configuration {
private int groupJoinMinutes; private int groupJoinMinutes;
private String groupQuitMinutes; private String groupQuitMinutes;
private File file; private String mailUsername;
private String mailPassword;
private String mailSmtpHost;
private int mailSmtpPort;
private String mailFromAddress;
private String git_token;
private File _file;
public Configuration(String path) { public Configuration(String path) {
this.file = new File(path); this._file = new File(path);
System.out.println("Config on " + file.getAbsolutePath()); System.out.println("Config on " + _file.getAbsolutePath());
} }
public void load() throws Exception { public <T> Configuration addDefaultValue(String name, T value) throws Exception{
if (!this.file.exists()) if(value == null) throw new IllegalArgumentException("Value cannot be null");
return; Field field = getClass().getDeclaredField(name);
BufferedReader reader = new BufferedReader(new FileReader(this.file)); field.setAccessible(true);
field.set(this, value);
return this;
}
public void load() throws Exception{
if(!this._file.exists()) return;
BufferedReader reader = new BufferedReader(new FileReader(this._file));
String line; String line;
while ((line = reader.readLine()) != null) { while((line = reader.readLine()) != null){
String[] split = line.split("="); String[] split = line.split("=");
Field field = getClass().getDeclaredField(split[0]); Field field = getClass().getDeclaredField(split[0]);
if (field == null) if(field == null) continue;
continue;
field.setAccessible(true); field.setAccessible(true);
injectValue(field, split[1]); injectValue(field, split[1]);
} }
@ -93,18 +109,16 @@ public class Configuration {
} }
public void save() throws Exception { public void save() throws Exception {
if (!file.exists()) { if (!_file.exists()) {
File parent = file.getParentFile(); File parent = _file.getParentFile();
if (!parent.exists()) if(!parent.exists()) parent.mkdirs();
parent.mkdirs(); _file.createNewFile();
file.createNewFile();
} }
Field[] fields = getClass().getDeclaredFields(); Field[] fields = getClass().getDeclaredFields();
BufferedWriter writer = new BufferedWriter(new FileWriter(file)); BufferedWriter writer = new BufferedWriter(new FileWriter(_file));
for (Field field : fields) { for(Field field : fields){
field.setAccessible(true); field.setAccessible(true);
if (field.getName().startsWith("_")) if(field.getName().startsWith("_")) continue;
continue;
Object value = field.get(this); Object value = field.get(this);
writer.write(field.getName() + "=" + value); writer.write(field.getName() + "=" + value);
} }
@ -156,9 +170,7 @@ public class Configuration {
return this.use_ssl; return this.use_ssl;
} }
public String getUsersFiles() { public String getUsersFiles(){
if (users_files == null || users_files.trim().isEmpty())
users_files = "/tmp/users_files";
return users_files; return users_files;
} }
@ -173,4 +185,17 @@ public class Configuration {
public String getGroupQuitMinutes(){ public String getGroupQuitMinutes(){
return this.groupQuitMinutes; return this.groupQuitMinutes;
} }
public Mail getMail(){
return new Mail(
this.mailUsername,
this.mailPassword,
this.mailSmtpHost,
this.mailSmtpPort,
this.mailFromAddress);
}
public String getGitToken(){
return this.git_token;
}
} }

View file

@ -0,0 +1,148 @@
package dev.peerat.backend;
import static dev.peerat.framework.RequestType.OPTIONS;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteExtracter;
import dev.peerat.backend.model.Completion;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.backend.routes.BadgeDetails;
import dev.peerat.backend.routes.ChapterElement;
import dev.peerat.backend.routes.ChapterList;
import dev.peerat.backend.routes.DynamicLeaderboard;
import dev.peerat.backend.routes.Leaderboard;
import dev.peerat.backend.routes.PlayerDetails;
import dev.peerat.backend.routes.PuzzleElement;
import dev.peerat.backend.routes.PuzzleResponse;
import dev.peerat.backend.routes.Result;
import dev.peerat.backend.routes.Swagger;
import dev.peerat.backend.routes.admins.DynamicLogs;
import dev.peerat.backend.routes.groups.GroupCreate;
import dev.peerat.backend.routes.groups.GroupJoin;
import dev.peerat.backend.routes.groups.GroupList;
import dev.peerat.backend.routes.groups.GroupQuit;
import dev.peerat.backend.routes.users.ChangePassword;
import dev.peerat.backend.routes.users.ForgotPassword;
import dev.peerat.backend.routes.users.Login;
import dev.peerat.backend.routes.users.MailConfirmation;
import dev.peerat.backend.routes.users.ProfileSettings;
import dev.peerat.backend.routes.users.Register;
import dev.peerat.backend.utils.Mail;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Locker;
import dev.peerat.framework.RequestType;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.Router;
import dev.peerat.framework.Locker.Key;
import dev.peerat.framework.utils.json.JsonMap;
public class Main{
public static void main(String[] args) throws Exception{
Configuration config = new Configuration("config.txt")
.addDefaultValue("users_files", "/tmp/users_files");
config.load();
Class.forName("com.mysql.cj.jdbc.Driver");
DatabaseRepository repo = new DatabaseRepository(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: *").
addDefaultHeaders(RequestType.OPTIONS,
"Access-Control-Allow-Origin: *",
"Access-Control-Allow-Methods: *",
"Access-Control-Allow-Headers: *");
router.setDefault((matcher, context, reader, writer) -> {
context.response(404);
writer.write("404 not Found.\n");
});
router.register(new Response(){
@Route(path = "^(.*)$", type = OPTIONS)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
context.response(200);
}
});
initRoutes(router, repo, config);
new Thread(new Runnable(){
public void run(){
Key key = new Key();
Locker<Context> locker = router.getLogger();
locker.init(key);
try {
while(true){
locker.lock(key);
Context instance = locker.getValue(key);
if(instance == null) continue;
System.out.println("["+((instance.isLogged()) ? repo.getPlayer(instance.<PeerAtUser>getUser().getId()).getPseudo() : "?")+"] "+instance.getType()+" "+instance.getPath()+" -> "+instance.getResponseCode());
}
}catch(Exception e){
e.printStackTrace();
}
}
}).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){
Map<String, Integer> playersWaiting = new HashMap<>();
Mail mail = config.getMail();
Locker<Group> groupLock = new Locker<>();
Locker<Completion> leaderboard = new Locker<>();
router.
register(new Register(repo, playersWaiting, mail)).
register(new MailConfirmation(repo, router, config.getUsersFiles(), config.getGitToken(), playersWaiting)).
register(new Login(repo, router)).
register(new ProfileSettings(repo)).
register(new ChangePassword(repo)).
register(new ForgotPassword(router, repo, mail)).
register(new DynamicLogs(repo, router.getLogger())).
register(new ChapterElement(repo)).
register(new ChapterList(repo)).
register(new PuzzleElement(repo)).
register(new Result(repo)).
register(new Leaderboard(repo)).
register(new PlayerDetails(repo)).
register(new BadgeDetails(repo)).
register(new DynamicLeaderboard(repo, leaderboard)).
register(new PuzzleResponse(repo, config.getUsersFiles(), leaderboard)).
register(new GroupCreate(repo, groupLock, config.getGroupJoinMinutes())).
register(new GroupList(repo)).
register(new GroupJoin(repo, config.getGroupJoinMinutes(), config.getGroupQuitMinutes(), leaderboard)).
register(new GroupQuit(repo, config.getGroupJoinMinutes(), leaderboard))
.register(new Swagger(new RouteExtracter(router),config.getTokenIssuer()));
// Bot bot = new Bot(config, repo, groupLock);
// bot.start();
}
}

View file

@ -1,12 +1,12 @@
package be.jeffcheasey88.peeratcode.bonus.discord; package dev.peerat.backend.bonus.discord;
import java.util.List; import java.util.List;
import be.jeffcheasey88.peeratcode.Configuration; import dev.peerat.backend.Configuration;
import be.jeffcheasey88.peeratcode.framework.Locker; import dev.peerat.backend.model.Group;
import be.jeffcheasey88.peeratcode.framework.Locker.Key; import dev.peerat.backend.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.model.Group; import dev.peerat.framework.Locker;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import dev.peerat.framework.Locker.Key;
import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder; import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.entities.Guild; import net.dv8tion.jda.api.entities.Guild;

View file

@ -1,4 +1,4 @@
package be.jeffcheasey88.peeratcode.bonus.extract; package dev.peerat.backend.bonus.extract;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable; import java.lang.annotation.Repeatable;

View file

@ -1,4 +1,4 @@
package be.jeffcheasey88.peeratcode.bonus.extract; package dev.peerat.backend.bonus.extract;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View file

@ -0,0 +1,131 @@
package dev.peerat.backend.bonus.extract;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import dev.peerat.backend.model.PeerAtUser;
import dev.peerat.framework.RequestType;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.RouteMapper;
import dev.peerat.framework.Router;
import dev.peerat.framework.utils.json.JsonArray;
import dev.peerat.framework.utils.json.JsonMap;
public class RouteExtracter {
private Router<PeerAtUser> router;
public RouteExtracter(Router<PeerAtUser> router){
this.router = router;
}
public void extract() throws Exception{
RouteMapper[] mappers = getField(Router.class, router, "mappers");
for(RequestType type : RequestType.values()){
RouteMapper mapper = mappers[type.ordinal()];
Response[] responses = getField(RouteMapper.class, mapper, "responses");
Route[] routes = getField(RouteMapper.class, mapper, "routes");
synchronized (responses){
for(int i = 0; i < responses.length; i++){
Route route = routes[i];
System.out.println("["+type+"] ("+route.needLogin()+") "+route.path());
}
}
}
}
public void extractDoc() throws Exception{
RouteMapper[] mappers = getField(Router.class, router, "mappers");
for(RequestType type : RequestType.values()){
RouteMapper mapper = mappers[type.ordinal()];
Response[] responses = getField(RouteMapper.class, mapper, "responses");
synchronized (responses){
for(int i = 0; i < responses.length; i++){
Response response = responses[i];
Method method = response.getClass().getDeclaredMethod("exec",
Response.class.getDeclaredMethods()[0].getParameterTypes());
for(RouteDoc doc : method.getDeclaredAnnotationsByType(RouteDoc.class)){
System.out.println(doc.path()+((doc.path().isEmpty() ? "":"\n"))+" ["+doc.responseCode()+"] "+doc.responseDescription());
}
}
}
}
}
public JsonMap swagger(String host) throws Exception{
JsonMap result = new JsonMap();
result.set("swagger","2.0");
JsonMap info = new JsonMap();
info.set("title", "Peer-at-code backend api routes");
info.set("description", "Using Peer-at Code Framework");
result.set("info", info);
result.set("host", host);
result.set("basePath","/");
List<Response> routes = new ArrayList<>();
RouteMapper[] mappers = getField(Router.class, router, "mappers");
for(RequestType type : RequestType.values()){
RouteMapper mapper = mappers[type.ordinal()];
Response[] responses = getField(RouteMapper.class, mapper, "responses");
synchronized (responses){
routes.addAll(Arrays.asList(responses));
}
}
Set<String> packages = new HashSet<>();
for(Response response : routes){
String name = response.getClass().getPackage().getName();
name = name.substring(name.lastIndexOf('.')+1, name.length());
packages.add(name);
}
JsonArray tags = new JsonArray();
for(String tag : packages){
JsonMap current = new JsonMap();
current.set("name", tag);
tags.add(current);
}
result.set("tags", tags);
JsonArray schemes = new JsonArray();
schemes.add("https");
result.set("schemes", schemes);
JsonMap paths = new JsonMap();
for(Response response : routes){
Method method = response.getClass().getDeclaredMethod("exec",
Response.class.getDeclaredMethods()[0].getParameterTypes());
Route route = method.getDeclaredAnnotation(Route.class);
RouteDoc[] docs = method.getDeclaredAnnotationsByType(RouteDoc.class);
if(docs.length < 1) continue;
RouteDoc base = docs[0];
JsonMap current = new JsonMap();
JsonMap data = new JsonMap();
JsonArray tag = new JsonArray();
String pack = response.getClass().getPackage().getName();
pack = pack.substring(pack.lastIndexOf('.')+1, pack.length());
tag.add(pack);
data.set("tags", tag);
current.set(route.type().toString().toLowerCase(), data);
paths.set(base.path(), current);
}
result.set("paths", paths);
return result;
}
private <E> E getField(Class<?> clazz, Object instance, String name) throws Exception{
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
return (E) field.get(instance);
}
}

View file

@ -1,8 +1,5 @@
package be.jeffcheasey88.peeratcode.model; package dev.peerat.backend.model;
import be.jeffcheasey88.peeratcode.mapping.Treasure;
@Treasure
public class Badge { public class Badge {
private String name; private String name;

View file

@ -1,6 +1,7 @@
package be.jeffcheasey88.peeratcode.model; package dev.peerat.backend.model;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
public class Chapter { public class Chapter {
@ -34,6 +35,13 @@ public class Chapter {
this.puzzles = puzzles; this.puzzles = puzzles;
} }
public boolean hasStarted(){
LocalDateTime now = LocalDateTime.now();
boolean show = true;
if(startDate != null) show &= now.isAfter(startDate.toLocalDateTime());
return show;
}
public Timestamp getStartDate() { public Timestamp getStartDate() {
return startDate; return startDate;
} }

View file

@ -1,4 +1,4 @@
package be.jeffcheasey88.peeratcode.model; package dev.peerat.backend.model;
import java.util.Arrays; import java.util.Arrays;

View file

@ -1,11 +1,14 @@
package be.jeffcheasey88.peeratcode.model; package dev.peerat.backend.model;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.json.simple.JSONArray; import org.jose4j.json.internal.json_simple.JSONArray;
import org.json.simple.JSONObject; import org.jose4j.json.internal.json_simple.JSONObject;
import be.jeffcheasey88.peeratcode.mapping.SeaBottle;
import dev.peerat.framework.utils.json.JsonMap;
public class Group implements Comparable<Group> { public class Group implements Comparable<Group> {
private String name; private String name;
@ -18,11 +21,11 @@ public class Group implements Comparable<Group> {
return "Group[name="+name+", chapter="+linkToChapter+"]"; return "Group[name="+name+", chapter="+linkToChapter+"]";
} }
public Group(JSONObject json) { public Group(JsonMap json){
this.name = (String) json.get("name"); this.name = (String) json.get("name");
if (json.containsKey("chapter")) if (json.has("chapter"))
this.linkToChapter = ((Number) json.get("chapter")).intValue(); this.linkToChapter = ((Number) json.get("chapter")).intValue();
// if (json.containsKey("puzzle")) // if (json.has("puzzle"))
// this.linkToPuzzle = ((Number) json.get("puzzle")).intValue(); // this.linkToPuzzle = ((Number) json.get("puzzle")).intValue();
} }
@ -32,6 +35,11 @@ public class Group implements Comparable<Group> {
// this.linkToPuzzle = initPuzz; // this.linkToPuzzle = initPuzz;
} }
@SeaBottle
public static Group getGroup(int player){
return null;
}
public void addPlayer(Player newPlayer) { public void addPlayer(Player newPlayer) {
if (newPlayer != null) { if (newPlayer != null) {
if (players == null) if (players == null)

View file

@ -0,0 +1,28 @@
package dev.peerat.backend.model;
import org.jose4j.jwt.JwtClaims;
public class PeerAtUser extends dev.peerat.framework.User{
private int id;
public PeerAtUser(int id){
this.id = id;
}
public PeerAtUser(JwtClaims claims){
this.id = ((Long) claims.getClaimValue("id")).intValue();
}
@Override
public void write(JwtClaims claims){
claims.setClaim("id", this.id);
}
public int getId(){
return this.id;
}
}

View file

@ -1,12 +1,12 @@
package be.jeffcheasey88.peeratcode.model; package dev.peerat.backend.model;
import java.util.Base64; import java.util.Base64;
import java.util.HashSet; import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import org.json.simple.JSONArray; import dev.peerat.framework.utils.json.JsonArray;
import org.json.simple.JSONObject; import dev.peerat.framework.utils.json.JsonMap;
public class Player implements Comparable<Player> { public class Player implements Comparable<Player> {
private String pseudo; private String pseudo;
@ -22,12 +22,12 @@ public class Player implements Comparable<Player> {
private Set<Badge> badges; private Set<Badge> badges;
public Player(String pseudo, String email, String firstname, String lastname, String description) { public Player(String pseudo, String email, String firstname, String lastname) {
this.pseudo = pseudo; this.pseudo = pseudo;
this.email = email; this.email = email;
this.firstname = firstname; this.firstname = firstname;
this.lastname = lastname; this.lastname = lastname;
this.description = description; this.description = "";
} }
public Player(String pseudo, int score, int tries) { public Player(String pseudo, int score, int tries) {
@ -37,6 +37,15 @@ public class Player implements Comparable<Player> {
email = ""; // TO make compareTo and equals works as usual 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() { public String getPseudo() {
return this.pseudo; return this.pseudo;
} }
@ -61,9 +70,9 @@ public class Player implements Comparable<Player> {
return groups; return groups;
} }
public JSONArray getJsonGroups() { public JsonArray getJsonGroups() {
if (groups != null) { if (groups != null) {
JSONArray groupsJSON = new JSONArray(); JsonArray groupsJSON = new JsonArray();
for (Group group : groups) { for (Group group : groups) {
groupsJSON.add(group.toJson()); groupsJSON.add(group.toJson());
} }
@ -112,13 +121,13 @@ public class Player implements Comparable<Player> {
return completions.size(); return completions.size();
} }
public JSONArray getJsonCompletions() { public JsonArray getJsonCompletions() {
JSONArray completionsJSON = new JSONArray(); JsonArray completionsJSON = new JsonArray();
for (Completion completion : completions) { for (Completion completion : completions) {
JSONObject completionJSON = new JSONObject(); JsonMap completionJSON = new JsonMap();
completionJSON.put("puzzleName", completion.getPuzzleName()); completionJSON.set("puzzleName", completion.getPuzzleName());
completionJSON.put("tries", completion.getTries()); completionJSON.set("tries", completion.getTries());
completionJSON.put("score", completion.getScore()); completionJSON.set("score", completion.getScore());
completionsJSON.add(completionJSON); completionsJSON.add(completionJSON);
} }
return completionsJSON; return completionsJSON;
@ -136,17 +145,17 @@ public class Player implements Comparable<Player> {
return badges; return badges;
} }
public JSONArray getJsonBadges() { public JsonArray getJsonBadges() {
if (badges == null) if (badges == null)
return null; return null;
JSONArray badgesJSON = new JSONArray(); JsonArray badgesJSON = new JsonArray();
for (Badge badge : badges) { for (Badge badge : badges) {
JSONObject badgeJSON = new JSONObject(); JsonMap badgeJSON = new JsonMap();
badgeJSON.put("name", badge.getName()); badgeJSON.set("name", badge.getName());
byte[] logo = badge.getLogo(); byte[] logo = badge.getLogo();
if (logo != null) if (logo != null)
badgeJSON.put("logo", Base64.getEncoder().encodeToString(logo)); badgeJSON.set("logo", Base64.getEncoder().encodeToString(logo));
badgeJSON.put("level", badge.getLevel()); badgeJSON.set("level", badge.getLevel());
badgesJSON.add(badgeJSON); badgesJSON.add(badgeJSON);
} }
return badgesJSON; return badgesJSON;
@ -180,8 +189,8 @@ public class Player implements Comparable<Player> {
} }
@Override @Override
public int hashCode() { public int hashCode(){
return Objects.hash(email, pseudo); return Objects.hash(email);
} }
@Override @Override
@ -193,6 +202,6 @@ public class Player implements Comparable<Player> {
if (getClass() != obj.getClass()) if (getClass() != obj.getClass())
return false; return false;
Player other = (Player) obj; Player other = (Player) obj;
return Objects.equals(email, other.email) && Objects.equals(pseudo, other.pseudo); return Objects.equals(email, other.email);
} }
} }

View file

@ -1,11 +1,13 @@
package be.jeffcheasey88.peeratcode.model; package dev.peerat.backend.model;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.json.simple.JSONArray; import dev.peerat.framework.utils.json.JsonArray;
import org.json.simple.JSONObject; import dev.peerat.framework.utils.json.JsonMap;
public class Puzzle { public class Puzzle {
@ -17,9 +19,10 @@ public class Puzzle {
private int scoreMax; private int scoreMax;
private Set<String> tags; private Set<String> tags;
private int depend; private int depend;
private Timestamp startDate;
public Puzzle(int id, String name, String content, byte[] soluce, String verify, int scoreMax, String tags, public Puzzle(int id, String name, String content, byte[] soluce, String verify, int scoreMax, String tags,
int depend) { int depend, Timestamp startDate) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.content = content; this.content = content;
@ -28,6 +31,7 @@ public class Puzzle {
this.scoreMax = scoreMax; this.scoreMax = scoreMax;
setTags(tags); setTags(tags);
this.depend = depend; this.depend = depend;
this.startDate = startDate;
} }
public int getId() { public int getId() {
@ -59,13 +63,13 @@ public class Puzzle {
* *
* @return DEATH * @return DEATH
*/ */
public JSONArray getJsonTags() { public JsonArray getJsonTags() {
if (tags == null) if (tags == null)
return null; return null;
JSONArray tagsJSON = new JSONArray(); JsonArray tagsJSON = new JsonArray();
for (String tag : tags) { for (String tag : tags) {
JSONObject tagJSON = new JSONObject(); JsonMap tagJSON = new JsonMap();
tagJSON.put("name", tag); tagJSON.set("name", tag);
tagsJSON.add(tagJSON); tagsJSON.add(tagJSON);
} }
return tagsJSON; return tagsJSON;
@ -82,6 +86,13 @@ public class Puzzle {
return this.depend; return this.depend;
} }
public boolean hasStarted(){
LocalDateTime now = LocalDateTime.now();
boolean show = true;
if(startDate != null) show &= now.isAfter(startDate.toLocalDateTime());
return show;
}
@Override @Override
public boolean equals(Object object) { public boolean equals(Object object) {
if (this == object) if (this == object)

View file

@ -1,4 +1,4 @@
package be.jeffcheasey88.peeratcode.repository; package dev.peerat.backend.repository;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -29,7 +29,7 @@ public enum DatabaseQuery {
// LEADERBOARD // LEADERBOARD
ALL_PLAYERS_FOR_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 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"), "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( 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);"), "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);"),
@ -53,7 +53,8 @@ public enum DatabaseQuery {
+ "JOIN containsGroups cGs on cGs.fk_group = cG.fk_group\r\n" + "JOIN containsGroups cGs on cGs.fk_group = cG.fk_group\r\n"
+ "JOIN groups g on cG.fk_group = g.id_group\r\n" + "JOIN groups g on cG.fk_group = g.id_group\r\n"
+ "JOIN puzzles p on p.id_puzzle = c.fk_puzzle\r\n" + "JOIN puzzles p on p.id_puzzle = c.fk_puzzle\r\n"
+ "WHERE cGs.fk_player = ? AND p.id_puzzle = ?"), + "JOIN chapters ch on ch.id_chapter = p.fk_chapter\r\n"
+ "WHERE ch.id_chapter < 2 AND cGs.fk_player = ? AND p.id_puzzle = ?"),
INSERT_COMPLETION( INSERT_COMPLETION(
"INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)"), "INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)"),
UPDATE_COMPLETION( UPDATE_COMPLETION(
@ -65,10 +66,13 @@ public enum DatabaseQuery {
+ "JOIN containsGroups cGs on cGs.fk_group = cG.fk_group\r\n" + "JOIN containsGroups cGs on cGs.fk_group = cG.fk_group\r\n"
+ "JOIN groups g on cG.fk_group = g.id_group\r\n" + "JOIN groups g on cG.fk_group = g.id_group\r\n"
+ "JOIN puzzles p on p.id_puzzle = c.fk_puzzle\r\n" + "JOIN puzzles p on p.id_puzzle = c.fk_puzzle\r\n"
+ "WHERE cGs.fk_player = ? AND p.id_puzzle = ?"), + "JOIN chapters ch on ch.id_chapter = p.fk_chapter\r\n"
+ "WHERE ch.id_chapter < 2 AND cGs.fk_player = ? AND p.id_puzzle = ?"),
// PLAYERS // PLAYERS
GET_PLAYER_SIMPLE("SELECT pseudo, email, firstname, lastname, description FROM players WHERE id_player = ?"), 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" GET_PLAYER_DETAILS("SELECT p.*, g.*\r\n"
+ "FROM players p\r\n" + "FROM players p\r\n"
+ "LEFT OUTER JOIN containsGroups cg ON p.id_player = cg.fk_player\r\n" + "LEFT OUTER JOIN containsGroups cg ON p.id_player = cg.fk_player\r\n"
@ -78,7 +82,9 @@ public enum DatabaseQuery {
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_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_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_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 players p ON p.id_player = c.fk_player GROUP BY fk_player ORDER BY rank) AS ranks WHERE ranks.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 = ?, first_name = ?, last_name = ? WHERE id_player = ?"),
UPDATE_PLAYER_PASSWORD("UPDATE players SET passwd = ? WHERE id_player = ?"),
// BADGES // BADGES
GET_BADGE("SELECT * FROM badges WHERE id_badge = ?"), GET_BADGES_OF_PLAYER( GET_BADGE("SELECT * FROM badges WHERE id_badge = ?"), GET_BADGES_OF_PLAYER(

View file

@ -1,4 +1,4 @@
package be.jeffcheasey88.peeratcode.repository; package dev.peerat.backend.repository;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
@ -15,14 +15,14 @@ import java.util.TreeSet;
import com.password4j.Hash; import com.password4j.Hash;
import com.password4j.Password; import com.password4j.Password;
import be.jeffcheasey88.peeratcode.Configuration; import dev.peerat.backend.Configuration;
import be.jeffcheasey88.peeratcode.framework.User; import dev.peerat.backend.model.Badge;
import be.jeffcheasey88.peeratcode.model.Badge; import dev.peerat.backend.model.Chapter;
import be.jeffcheasey88.peeratcode.model.Chapter; import dev.peerat.backend.model.Completion;
import be.jeffcheasey88.peeratcode.model.Completion; import dev.peerat.backend.model.Group;
import be.jeffcheasey88.peeratcode.model.Group; import dev.peerat.backend.model.PeerAtUser;
import be.jeffcheasey88.peeratcode.model.Player; import dev.peerat.backend.model.Player;
import be.jeffcheasey88.peeratcode.model.Puzzle; import dev.peerat.backend.model.Puzzle;
public class DatabaseRepository { public class DatabaseRepository {
@ -32,68 +32,6 @@ public class DatabaseRepository {
public DatabaseRepository(Configuration config) { public DatabaseRepository(Configuration config) {
this.config = config; this.config = config;
} }
// testTrigger();
// }
//
// private void testTrigger(){
// try {
// ensureConnection();
// }catch(Exception e){
// e.printStackTrace();
// }
// System.out.println("connection ensured");
//
// try {
// PreparedStatement log = this.con.prepareStatement("DROP TABLE mycustomlog;");
// log.execute();
// }catch(Exception e){
// e.printStackTrace();
// }
// System.out.println("log dropped");
//
// try {
// PreparedStatement log = this.con.prepareStatement("CREATE TABLE mycustomlog(\r\n"
// + " message VARCHAR(255),\r\n"
// + " primary key (message)\r\n"
// + ");");
// log.execute();
// }catch(Exception e){
// e.printStackTrace();
// }
// System.out.println("log created");
//
// try {
// System.out.println(DatabaseQuery.FIRST_TRY.toString());
// DatabaseQuery.FIRST_TRY.prepare(this.con).execute();
// }catch(Exception e){
// e.printStackTrace();
// }
//
// System.out.println("trigger inserted");
//
// try {
// insertCompletion(new Completion(1, 1, 1, null, 1));
// } catch (SQLException e1) {
// e1.printStackTrace();
// }
//
// try {
// showLog();
// } catch (Exception e) {
// e.printStackTrace();
// }
// System.out.println("------------------------------");
// }
//
// private void showLog() throws Exception{
// ensureConnection();
//
// PreparedStatement stmt = this.con.prepareStatement("SELECT * FROM mycustomlog");
// ResultSet result = stmt.executeQuery();
// while(result.next()){
// System.out.println("[LOG] "+result.getString("message"));
// }
// }
private void ensureConnection() throws SQLException { private void ensureConnection() throws SQLException {
if (con == null || (!con.isValid(5))) { if (con == null || (!con.isValid(5))) {
@ -107,7 +45,8 @@ public class DatabaseRepository {
return new Puzzle(puzzleResult.getInt("id_puzzle"), puzzleResult.getString("name"), return new Puzzle(puzzleResult.getInt("id_puzzle"), puzzleResult.getString("name"),
puzzleResult.getString("content"), puzzleResult.getBytes("soluce"), puzzleResult.getString("verify"), puzzleResult.getString("content"), puzzleResult.getBytes("soluce"), puzzleResult.getString("verify"),
puzzleResult.getInt("score_max"), puzzleResult.getString("tags"), puzzleResult.getInt("score_max"), puzzleResult.getString("tags"),
hasColumn(puzzleResult, "origin") ? puzzleResult.getInt("origin") : -1); hasColumn(puzzleResult, "origin") ? puzzleResult.getInt("origin") : -1,
puzzleResult.getTimestamp("start_date"));
} }
private Chapter makeChapter(ResultSet chapterResult) throws SQLException { private Chapter makeChapter(ResultSet chapterResult) throws SQLException {
@ -129,8 +68,7 @@ public class DatabaseRepository {
private Player makePlayer(ResultSet playerResult, int id) throws SQLException { private Player makePlayer(ResultSet playerResult, int id) throws SQLException {
Player p = new Player(playerResult.getString("pseudo"), playerResult.getString("email"), Player p = new Player(playerResult.getString("pseudo"), playerResult.getString("email"),
playerResult.getString("firstName"), playerResult.getString("lastName"), playerResult.getString("firstName"), playerResult.getString("lastName"));
playerResult.getString("description"));
if (hasColumn(playerResult, "avatar")) { if (hasColumn(playerResult, "avatar")) {
p.setAvatar(playerResult.getBytes("avatar")); p.setAvatar(playerResult.getBytes("avatar"));
} }
@ -141,11 +79,13 @@ public class DatabaseRepository {
p.addCompletion(new Completion(0, 0)); p.addCompletion(new Completion(0, 0));
} }
} }
if (hasColumn(playerResult, "name")) {
// Manage groups // Manage groups
String groupName = playerResult.getString("name"); String groupName = playerResult.getString("name");
if (groupName != null) { if (groupName != null) {
p.addGroup(makeGroup(playerResult)); p.addGroup(makeGroup(playerResult));
} }
}
// ADD rank // ADD rank
PreparedStatement completionsStmt = DatabaseQuery.GET_PLAYER_RANK.prepare(con); PreparedStatement completionsStmt = DatabaseQuery.GET_PLAYER_RANK.prepare(con);
@ -279,6 +219,64 @@ public class DatabaseRepository {
return null; return null;
} }
public int getPlayerId(String email){
try {
PreparedStatement completionsStmt = DatabaseQuery.GET_PLAYER_EMAIL.prepare(this.con);
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 = DatabaseQuery.GET_PLAYER_PSEUDO.prepare(this.con);
statment.setString(1, pseudo);
ResultSet result = statment.executeQuery();
if(result.next()) return false;
statment = DatabaseQuery.UPDATE_PLAYER_INFO.prepare(this.con);
statment.setString(1, player.getPseudo());
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 = DatabaseQuery.UPDATE_PLAYER_INFO.prepare(this.con);
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 = DatabaseQuery.UPDATE_PLAYER_PASSWORD.prepare(this.con);
statment.setString(1, Password.hash(password).withArgon2().getResult());
statment.setInt(2, id);
statment.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}
}
public Player getPlayerDetails(int idPlayer) { public Player getPlayerDetails(int idPlayer) {
return getPlayerDetails(idPlayer, null); return getPlayerDetails(idPlayer, null);
} }
@ -521,7 +519,6 @@ public class DatabaseRepository {
*/ */
public int register(String pseudo, String email, String password, String firstname, String lastname, public int register(String pseudo, String email, String password, String firstname, String lastname,
String description, String sgroup, String avatar) { String description, String sgroup, String avatar) {
Hash hash = Password.hash(password).withArgon2();
try { try {
ensureConnection(); ensureConnection();
con.setAutoCommit(false); con.setAutoCommit(false);
@ -529,7 +526,7 @@ public class DatabaseRepository {
Statement.RETURN_GENERATED_KEYS)) { Statement.RETURN_GENERATED_KEYS)) {
playerStatement.setString(1, pseudo); playerStatement.setString(1, pseudo);
playerStatement.setString(2, email); playerStatement.setString(2, email);
playerStatement.setString(3, hash.getResult()); playerStatement.setString(3, Password.hash(password).withArgon2().getResult());
playerStatement.setString(4, firstname); playerStatement.setString(4, firstname);
playerStatement.setString(5, lastname); playerStatement.setString(5, lastname);
playerStatement.setString(6, description); playerStatement.setString(6, description);
@ -620,7 +617,7 @@ public class DatabaseRepository {
statement.executeUpdate(); statement.executeUpdate();
} }
public boolean insertGroup(Group group, User creator) throws SQLException { public boolean insertGroup(Group group, PeerAtUser creator) throws SQLException {
Integer groupId = getGroupId(group); Integer groupId = getGroupId(group);
if (groupId == null) if (groupId == null)
ensureConnection(); ensureConnection();
@ -659,7 +656,7 @@ public class DatabaseRepository {
return null; return null;
} }
public boolean insertUserInGroup(Group group, User user) throws SQLException { public boolean insertUserInGroup(Group group, PeerAtUser user) throws SQLException {
Integer id = getGroupId(group); Integer id = getGroupId(group);
Group alreadyInGroup = getPlayerGroup(user.getId(), group.getLinkToChapter()); Group alreadyInGroup = getPlayerGroup(user.getId(), group.getLinkToChapter());
if (id != null && alreadyInGroup == null) { if (id != null && alreadyInGroup == null) {
@ -673,7 +670,7 @@ public class DatabaseRepository {
return false; return false;
} }
public boolean leaveGroup(Group group, User user) throws SQLException { public boolean leaveGroup(Group group, PeerAtUser user) throws SQLException {
Integer id = getGroupId(group); Integer id = getGroupId(group);
if (id != null) { if (id != null) {
PreparedStatement stmt = DatabaseQuery.LEAVE_GROUP.prepare(this.con); PreparedStatement stmt = DatabaseQuery.LEAVE_GROUP.prepare(this.con);

View file

@ -0,0 +1,45 @@
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.Badge;
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.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonMap;
public class BadgeDetails implements Response {
private final DatabaseRepository databaseRepo;
public BadgeDetails(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/badge/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du badge")
@RouteDoc(responseCode = 400, responseDescription = "Aucun id donner")
@Route(path = "^\\/badge\\/([0-9]+)$", needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
if (matcher.groupCount() > 0) {
int badgeId = Integer.parseInt(matcher.group(1));
Badge badge = databaseRepo.getBadge(badgeId);
JsonMap badgeJSON = new JsonMap();
if(badge != null){
badgeJSON.set("name", badge.getName());
if(badge.getLogo() != null) badgeJSON.set("logo", Base64.getEncoder().encodeToString(badge.getLogo()));
badgeJSON.set("level", badge.getLevel());
}
context.response(200);
writer.write(badgeJSON.toString().replace("\\", ""));
} else {
context.response(400);
}
}
}

View file

@ -0,0 +1,61 @@
package dev.peerat.backend.routes;
import java.util.regex.Matcher;
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.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonArray;
import dev.peerat.framework.utils.json.JsonMap;
public class ChapterElement implements Response {
private final DatabaseRepository databaseRepo;
public ChapterElement(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/chapter/<id>", responseCode = 200, responseDescription = "JSON contenant les informations du chapitre demander")
@RouteDoc(responseCode = 400, responseDescription = "Aucun id donner")
@Route(path = "^\\/chapter\\/([0-9]+)$", needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
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);
PeerAtUser user = context.getUser();
if(show){
JsonArray puzzles = new JsonArray();
for (Puzzle puzzle : chapter.getPuzzles()){
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());
int score = this.databaseRepo.getScore(user.getId(), puzzle.getId());
if(score >= 0) puzzleJSON.set("score", score);
puzzleJSON.set("show", puzzle.hasStarted());
puzzles.add(puzzleJSON);
}
chapterJSON.set("puzzles", puzzles);
}
context.response(200);
writer.write(chapterJSON.toString());
} else {
context.response(400);
}
}
}

View file

@ -0,0 +1,47 @@
package dev.peerat.backend.routes;
import java.util.List;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Chapter;
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.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonArray;
import dev.peerat.framework.utils.json.JsonMap;
public class ChapterList implements Response {
private final DatabaseRepository databaseRepo;
public ChapterList(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/chapters", responseCode = 200, responseDescription = "JSON contenant les informations des chapitres")
@RouteDoc(responseCode = 400, responseDescription = "Aucun chapitre trouver")
@Route(path = "^\\/chapters$", needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
List<Chapter> allChapters = databaseRepo.getAllChapters();
if (allChapters != null) {
JsonArray chaptersJSON = new JsonArray();
for (Chapter chapter : allChapters) {
JsonMap chapterJSON = new JsonMap();
chapterJSON.set("id", chapter.getId());
chapterJSON.set("name", chapter.getName());
chapterJSON.set("show", chapter.hasStarted());
chaptersJSON.add(chapterJSON);
}
context.response(200);
writer.write(chaptersJSON.toString());
} else {
context.response(400);
}
}
}

View file

@ -1,24 +1,24 @@
package be.jeffcheasey88.peeratcode.routes; package dev.peerat.backend.routes;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc; import dev.peerat.backend.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader; import dev.peerat.backend.model.Completion;
import be.jeffcheasey88.peeratcode.framework.HttpWriter; import dev.peerat.backend.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.framework.Locker; import dev.peerat.framework.Context;
import be.jeffcheasey88.peeratcode.framework.Locker.Key; import dev.peerat.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.Route; import dev.peerat.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.User; import dev.peerat.framework.Locker;
import be.jeffcheasey88.peeratcode.model.Completion; import dev.peerat.framework.Locker.Key;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import dev.peerat.framework.Route;
public class DynamicLeaderboard extends Leaderboard{ public class DynamicLeaderboard extends Leaderboard{
private Locker<Completion> locker; private Locker<Completion> locker;
public DynamicLeaderboard(DatabaseRepository databaseRepo){ public DynamicLeaderboard(DatabaseRepository databaseRepo, Locker<Completion> locker){
super(databaseRepo); super(databaseRepo);
this.locker = new Locker<>(); this.locker = locker;
} }
public Locker<Completion> getLocker(){ public Locker<Completion> getLocker(){
@ -28,7 +28,7 @@ public class DynamicLeaderboard extends Leaderboard{
@RouteDoc(path = "/rleaderboard/{id}", responseCode = 101, responseDescription = "WebSocket") @RouteDoc(path = "/rleaderboard/{id}", responseCode = 101, responseDescription = "WebSocket")
@Route(path = "^\\/rleaderboard\\/?(\\d+)?$", websocket = true) @Route(path = "^\\/rleaderboard\\/?(\\d+)?$", websocket = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{ public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
Key key = new Key(); Key key = new Key();
locker.init(key); locker.init(key);

View file

@ -1,22 +1,21 @@
package be.jeffcheasey88.peeratcode.routes; package dev.peerat.backend.routes;
import java.io.IOException; import java.io.IOException;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import org.json.simple.JSONArray; import dev.peerat.backend.bonus.extract.RouteDoc;
import org.json.simple.JSONObject; import dev.peerat.backend.model.Chapter;
import dev.peerat.backend.model.Group;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc; import dev.peerat.backend.model.Player;
import be.jeffcheasey88.peeratcode.framework.HttpReader; import dev.peerat.backend.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.framework.HttpWriter; import dev.peerat.framework.Context;
import be.jeffcheasey88.peeratcode.framework.Response; import dev.peerat.framework.HttpReader;
import be.jeffcheasey88.peeratcode.framework.Route; import dev.peerat.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.User; import dev.peerat.framework.Response;
import be.jeffcheasey88.peeratcode.model.Chapter; import dev.peerat.framework.Route;
import be.jeffcheasey88.peeratcode.model.Group; import dev.peerat.framework.utils.json.JsonArray;
import be.jeffcheasey88.peeratcode.model.Player; import dev.peerat.framework.utils.json.JsonMap;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
public class Leaderboard implements Response { public class Leaderboard implements Response {
@ -29,8 +28,8 @@ public class Leaderboard implements Response {
@RouteDoc(path = "/leaderboard/{id}", responseCode = 200, responseDescription = "JSON contenant le leaderboard") @RouteDoc(path = "/leaderboard/{id}", responseCode = 200, responseDescription = "JSON contenant le leaderboard")
@Route(path = "^\\/leaderboard\\/?(\\d+)?$") @Route(path = "^\\/leaderboard\\/?(\\d+)?$")
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
writer.response(200, "Access-Control-Allow-Origin: *"); context.response(200);
if (matcher.group(1) != null) { if (matcher.group(1) != null) {
groupsLeaderboard(Integer.parseInt(matcher.group(1)), writer); groupsLeaderboard(Integer.parseInt(matcher.group(1)), writer);
} else { } else {
@ -42,12 +41,12 @@ public class Leaderboard implements Response {
Chapter chInfo = databaseRepo.getChapter(chapterId); Chapter chInfo = databaseRepo.getChapter(chapterId);
SortedSet<Group> allGroupsForChapter = databaseRepo.getAllGroupForChapterLeaderboard(chapterId); SortedSet<Group> allGroupsForChapter = databaseRepo.getAllGroupForChapterLeaderboard(chapterId);
JSONObject leaderboardJSON = new JSONObject(); JsonMap leaderboardJSON = new JsonMap();
if (chInfo.getStartDate() != null) if (chInfo.getStartDate() != null)
leaderboardJSON.put("start_date", chInfo.getStartDate().toString()); leaderboardJSON.set("start_date", chInfo.getStartDate().toString());
if (chInfo.getEndDate() != null) if (chInfo.getEndDate() != null)
leaderboardJSON.put("end_date", chInfo.getEndDate().toString()); leaderboardJSON.set("end_date", chInfo.getEndDate().toString());
JSONArray groupsJSON = new JSONArray(); JsonArray groupsJSON = new JsonArray();
if (allGroupsForChapter != null) { if (allGroupsForChapter != null) {
int rank = 1; int rank = 1;
int sameRankCount = 1; int sameRankCount = 1;
@ -65,28 +64,28 @@ public class Leaderboard implements Response {
previousGroup = g; previousGroup = g;
} }
} }
leaderboardJSON.put("groups", groupsJSON); leaderboardJSON.set("groups", groupsJSON);
writer.write(leaderboardJSON.toJSONString().replace("\\", "")); writer.write(leaderboardJSON.toString().replace("\\", ""));
} }
public final void playersLeaderboard(HttpWriter writer) throws IOException { public final void playersLeaderboard(HttpWriter writer) throws IOException {
SortedSet<Player> allPlayers = databaseRepo.getAllPlayerForLeaderboard(); SortedSet<Player> allPlayers = databaseRepo.getAllPlayerForLeaderboard();
JSONArray playersJSON = new JSONArray(); JsonArray playersJSON = new JsonArray();
if (allPlayers != null) { if (allPlayers != null) {
for (Player player : allPlayers) { for (Player player : allPlayers) {
JSONObject playerJSON = new JSONObject(); JsonMap playerJSON = new JsonMap();
playerJSON.put("pseudo", player.getPseudo()); playerJSON.set("pseudo", player.getPseudo());
if (player.getGroups() != null) if (player.getGroups() != null)
playerJSON.put("groups", player.getJsonGroups()); playerJSON.set("groups", player.getJsonGroups());
// if (player.getAvatar() != null) // if (player.getAvatar() != null)
// playerJSON.put("avatar", Base64.getEncoder().encodeToString(player.getAvatar())); // playerJSON.put("avatar", Base64.getEncoder().encodeToString(player.getAvatar()));
playerJSON.put("rank", player.getRank()); playerJSON.set("rank", player.getRank());
playerJSON.put("score", player.getTotalScore()); playerJSON.set("score", player.getTotalScore());
playerJSON.put("completions", player.getTotalCompletion()); playerJSON.set("completions", player.getTotalCompletion());
playerJSON.put("tries", player.getTotalTries()); playerJSON.set("tries", player.getTotalTries());
playersJSON.add(playerJSON); playersJSON.add(playerJSON);
} }
} }
writer.write(playersJSON.toJSONString().replace("\\", "")); writer.write(playersJSON.toString().replace("\\", ""));
} }
} }

View file

@ -0,0 +1,62 @@
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.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonMap;
public class PlayerDetails implements Response {
private final DatabaseRepository databaseRepo;
public PlayerDetails(DatabaseRepository databaseRepo) {
this.databaseRepo = databaseRepo;
}
@RouteDoc(path = "/player/{id}", responseCode = 200, responseDescription = "JSON contenant les informations de l'utilisateur")
@RouteDoc(responseCode = 400, responseDescription = "Utilisateur introuvable dans la base de donnée")
@Route(path = "^\\/player\\/?(.+)?$", needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
Player player;
if (matcher.group(1) != null) {
player = databaseRepo.getPlayerDetails(matcher.group(1));
} else {
PeerAtUser user = context.getUser();
player = databaseRepo.getPlayerDetails(user.getId());
}
JsonMap playerJSON = new JsonMap();
if (player != null) {
playerJSON.set("pseudo", player.getPseudo());
playerJSON.set("email", player.getEmail());
playerJSON.set("firstname", player.getFirstname());
playerJSON.set("lastname", player.getLastname());
playerJSON.set("description", player.getDescription());
if (player.getGroups() != null)
playerJSON.set("groups", player.getJsonGroups());
playerJSON.set("rank", player.getRank());
playerJSON.set("score", player.getTotalScore());
playerJSON.set("completions", player.getTotalCompletion());
playerJSON.set("completionsList", player.getJsonCompletions());
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()));
context.response(200);
writer.write(playerJSON.toString().replace("\\", ""));
} else {
context.response(400);
}
}
}

View file

@ -1,20 +1,20 @@
package be.jeffcheasey88.peeratcode.routes; package dev.peerat.backend.routes;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import org.json.simple.JSONObject; import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Chapter;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc; import dev.peerat.backend.model.Completion;
import be.jeffcheasey88.peeratcode.framework.HttpReader; import dev.peerat.backend.model.PeerAtUser;
import be.jeffcheasey88.peeratcode.framework.HttpWriter; import dev.peerat.backend.model.Puzzle;
import be.jeffcheasey88.peeratcode.framework.Response; import dev.peerat.backend.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.framework.Route; import dev.peerat.framework.Context;
import be.jeffcheasey88.peeratcode.framework.User; import dev.peerat.framework.HttpReader;
import be.jeffcheasey88.peeratcode.model.Chapter; import dev.peerat.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.model.Completion; import dev.peerat.framework.Response;
import be.jeffcheasey88.peeratcode.model.Puzzle; import dev.peerat.framework.Route;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import dev.peerat.framework.utils.json.JsonMap;
public class PuzzleElement implements Response { public class PuzzleElement implements Response {
@ -29,13 +29,13 @@ public class PuzzleElement implements Response {
@RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de voir le puzzle en dehors de l'event") @RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de voir le puzzle en dehors de l'event")
@Route(path = "^\\/puzzle\\/([0-9]+)$", needLogin = true) @Route(path = "^\\/puzzle\\/([0-9]+)$", needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
Puzzle puzzle = databaseRepo.getPuzzle(extractId(matcher)); Puzzle puzzle = databaseRepo.getPuzzle(extractId(matcher));
if (puzzle != null){ if (puzzle != null){
Chapter chapter = this.databaseRepo.getChapter(puzzle); Chapter chapter = this.databaseRepo.getChapter(puzzle);
if(chapter.getStartDate() != null){ if(chapter.getStartDate() != null){
if(LocalDateTime.now().isBefore(chapter.getStartDate().toLocalDateTime())){ if(LocalDateTime.now().isBefore(chapter.getStartDate().toLocalDateTime())){
writer.response(423, "Access-Control-Allow-Origin: *"); context.response(423);
return; return;
} }
} }
@ -46,23 +46,25 @@ public class PuzzleElement implements Response {
// } // }
// } // }
JSONObject puzzleJSON = new JSONObject(); PeerAtUser user = context.getUser();
puzzleJSON.put("id", puzzle.getId());
puzzleJSON.put("name", puzzle.getName()); JsonMap puzzleJSON = new JsonMap();
puzzleJSON.put("content", puzzle.getContent()); puzzleJSON.set("id", puzzle.getId());
puzzleJSON.put("scoreMax", puzzle.getScoreMax()); puzzleJSON.set("name", puzzle.getName());
if(puzzle.getTags() != null) puzzleJSON.put("tags", puzzle.getJsonTags()); puzzleJSON.set("content", puzzle.getContent());
puzzleJSON.set("scoreMax", puzzle.getScoreMax());
if(puzzle.getTags() != null) puzzleJSON.set("tags", puzzle.getJsonTags());
Completion completion = this.databaseRepo.getCompletionGroup(user.getId(), puzzle.getId()); Completion completion = this.databaseRepo.getCompletionGroup(user.getId(), puzzle.getId());
if(completion != null && completion.getScore() >= 0){ if(completion != null && completion.getScore() >= 0){
puzzleJSON.put("score", completion.getScore()); puzzleJSON.set("score", completion.getScore());
puzzleJSON.put("tries", completion.getTries()); puzzleJSON.set("tries", completion.getTries());
} }
if(puzzle.getDepend() > 0) puzzleJSON.put("depend", puzzle.getDepend()); if(puzzle.getDepend() > 0) puzzleJSON.set("depend", puzzle.getDepend());
writer.response(200, "Access-Control-Allow-Origin: *", "Content-Type: application/json"); context.response(200, "Content-Type: application/json");
writer.write(puzzleJSON.toJSONString()); writer.write(puzzleJSON.toString());
} }
else { else {
writer.response(400, "Access-Control-Allow-Origin: *"); context.response(400);
} }
} }

View file

@ -1,6 +1,6 @@
package be.jeffcheasey88.peeratcode.routes; package dev.peerat.backend.routes;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST; import static dev.peerat.framework.RequestType.POST;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@ -11,21 +11,21 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import org.json.simple.JSONObject; import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Chapter;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc; import dev.peerat.backend.model.Completion;
import be.jeffcheasey88.peeratcode.framework.HttpReader; import dev.peerat.backend.model.Group;
import be.jeffcheasey88.peeratcode.framework.HttpWriter; import dev.peerat.backend.model.PeerAtUser;
import be.jeffcheasey88.peeratcode.framework.Locker; import dev.peerat.backend.model.Player;
import be.jeffcheasey88.peeratcode.framework.Response; import dev.peerat.backend.model.Puzzle;
import be.jeffcheasey88.peeratcode.framework.Route; import dev.peerat.backend.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.framework.User; import dev.peerat.framework.Context;
import be.jeffcheasey88.peeratcode.model.Chapter; import dev.peerat.framework.HttpReader;
import be.jeffcheasey88.peeratcode.model.Completion; import dev.peerat.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.model.Group; import dev.peerat.framework.Locker;
import be.jeffcheasey88.peeratcode.model.Player; import dev.peerat.framework.Response;
import be.jeffcheasey88.peeratcode.model.Puzzle; import dev.peerat.framework.Route;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import dev.peerat.framework.utils.json.JsonMap;
public class PuzzleResponse implements Response { public class PuzzleResponse implements Response {
private final DatabaseRepository databaseRepo; private final DatabaseRepository databaseRepo;
@ -46,16 +46,18 @@ public class PuzzleResponse implements Response {
@RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de répondre en dehors de l'event") @RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de répondre en dehors de l'event")
@Route(path = "^\\/puzzleResponse\\/([0-9]+)$", type = POST, needLogin = true) @Route(path = "^\\/puzzleResponse\\/([0-9]+)$", type = POST, needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{ public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
ReceivedResponse received = new ReceivedResponse(matcher, reader); ReceivedResponse received = new ReceivedResponse(matcher, reader);
if (received.getResponse() == null){ if (received.getResponse() == null){
writer.response(400, "Access-Control-Allow-Origin: *"); context.response(400);
return; return;
} }
PeerAtUser user = context.getUser();
//saveSourceCode(received, databaseRepo.getPlayer(user.getId())); //saveSourceCode(received, databaseRepo.getPlayer(user.getId()));
JSONObject responseJSON = new JSONObject(); JsonMap responseJSON = new JsonMap();
if(this.databaseRepo.getScore(user.getId(), received.getPuzzleId()) > 0){ if(this.databaseRepo.getScore(user.getId(), received.getPuzzleId()) > 0){
writer.response(403, "Access-Control-Allow-Origin: *"); context.response(403);
return; return;
} }
@ -63,25 +65,25 @@ public class PuzzleResponse implements Response {
Chapter chapter = this.databaseRepo.getChapter(currentPuzzle); Chapter chapter = this.databaseRepo.getChapter(currentPuzzle);
if(chapter.getStartDate() != null){ if(chapter.getStartDate() != null){
if(LocalDateTime.now().isBefore(chapter.getStartDate().toLocalDateTime())){ if(LocalDateTime.now().isBefore(chapter.getStartDate().toLocalDateTime())){
writer.response(423, "Access-Control-Allow-Origin: *"); context.response(423);
return; return;
} }
} }
if(chapter.getEndDate() != null){ if(chapter.getEndDate() != null){
if(LocalDateTime.now().isAfter(chapter.getEndDate().toLocalDateTime())){ if(LocalDateTime.now().isAfter(chapter.getEndDate().toLocalDateTime())){
if(Arrays.equals(currentPuzzle.getSoluce(), received.getResponse())){ if(Arrays.equals(currentPuzzle.getSoluce(), received.getResponse())){
writer.response(200, "Access-Control-Allow-Origin: *", "Content-Type: application/json"); context.response(200, "Content-Type: application/json");
JSONObject theoSaisPasJusteRecevoir200 = new JSONObject(); JsonMap theoSaisPasJusteRecevoir200 = new JsonMap();
theoSaisPasJusteRecevoir200.put("success", true); theoSaisPasJusteRecevoir200.set("success", true);
writer.write(theoSaisPasJusteRecevoir200.toJSONString()); writer.write(theoSaisPasJusteRecevoir200.toString());
return; return;
} }
writer.response(423, "Access-Control-Allow-Origin: *"); context.response(423);
return; return;
} }
Group group = this.databaseRepo.getPlayerGroup(user.getId(), chapter.getId()); Group group = this.databaseRepo.getPlayerGroup(user.getId(), chapter.getId());
if(group == null){ if(group == null){
writer.response(423, "Access-Control-Allow-Origin: *"); context.response(423);
return; return;
} }
} }
@ -90,19 +92,19 @@ public class PuzzleResponse implements Response {
Completion completion = databaseRepo.insertOrUpdatePuzzleResponse(received.getPuzzleId(), user.getId(), Completion completion = databaseRepo.insertOrUpdatePuzzleResponse(received.getPuzzleId(), user.getId(),
received.getFileName(), received.getSourceCode(), received.getResponse(), currentPuzzle); received.getFileName(), received.getSourceCode(), received.getResponse(), currentPuzzle);
if(completion == null){ if(completion == null){
writer.response(400, "Access-Control-Allow-Origin: *"); context.response(400);
return; return;
} }
if(completion.getScore() > 0){ if(completion.getScore() > 0){
writer.response(200, "Access-Control-Allow-Origin: *", "Content-Type: application/json"); context.response(200, "Content-Type: application/json");
responseJSON.put("score", completion.getScore()); responseJSON.set("score", completion.getScore());
responseJSON.put("tries", completion.getTries()); responseJSON.set("tries", completion.getTries());
}else{ }else{
writer.response(406, "Access-Control-Allow-Origin: *", "Content-Type: application/json"); context.response(406, "Content-Type: application/json");
responseJSON.put("tries", completion.getTries()); responseJSON.set("tries", completion.getTries());
} }
writer.write(responseJSON.toJSONString()); writer.write(responseJSON.toString());
writer.flush(); writer.flush();
leaderboard.setValue(completion); leaderboard.setValue(completion);

View file

@ -0,0 +1,40 @@
package dev.peerat.backend.routes;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
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.Response;
import dev.peerat.framework.Route;
public class Result implements Response {
private DatabaseRepository repo;
public Result(DatabaseRepository repo) {
this.repo = repo;
}
@RouteDoc(path = "/result/<id>", responseCode = 200, responseDescription = "Le score")
@RouteDoc(responseCode = 425, responseDescription = "Puzzle pas compléter")
@Route(path = "^\\/result\\/(\\d+)$", needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
int puzzle = Integer.parseInt(matcher.group(1));
PeerAtUser user = context.getUser();
int score = this.repo.getScore(user.getId(), puzzle);
if (score < 0) {
context.response(425);
} else {
context.response(200);
writer.write(score + "");
}
}
}

View file

@ -0,0 +1,33 @@
package dev.peerat.backend.routes;
import java.util.regex.Matcher;
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.Response;
import dev.peerat.framework.Route;
public class Swagger implements Response{
private String json;
public Swagger(RouteExtracter extracter, String host){
try{
this.json = extracter.swagger(host).toString();
}catch(Exception e){
e.printStackTrace();
json = "{}";
}
}
@Route(path = "^/swagger$")
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
context.response(200);
writer.write(json);
}
}

View file

@ -0,0 +1,61 @@
package dev.peerat.backend.routes.admins;
import java.util.regex.Matcher;
import org.jose4j.json.internal.json_simple.JSONObject;
import dev.peerat.backend.bonus.extract.RouteDoc;
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(DatabaseRepository repo, Locker<Context> locker){
this.repo = repo;
this.locker = locker;
}
@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$", websocket = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
//check if admin
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){
e.printStackTrace();
}
locker.remove(key);
}
}

View file

@ -1,20 +1,21 @@
package be.jeffcheasey88.peeratcode.routes.groups; package dev.peerat.backend.routes.groups;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST; import static dev.peerat.framework.RequestType.POST;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc; import dev.peerat.backend.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader; import dev.peerat.backend.model.Chapter;
import be.jeffcheasey88.peeratcode.framework.HttpWriter; import dev.peerat.backend.model.Group;
import be.jeffcheasey88.peeratcode.framework.Locker; import dev.peerat.backend.model.PeerAtUser;
import be.jeffcheasey88.peeratcode.framework.Response; import dev.peerat.backend.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.framework.Route; import dev.peerat.framework.Context;
import be.jeffcheasey88.peeratcode.framework.User; import dev.peerat.framework.HttpReader;
import be.jeffcheasey88.peeratcode.model.Chapter; import dev.peerat.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.model.Group; import dev.peerat.framework.Locker;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
public class GroupCreate implements Response { public class GroupCreate implements Response {
@ -33,13 +34,14 @@ public class GroupCreate implements Response {
@RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de crée un groupe après le délai maximum de création de l'event") @RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de crée un groupe après le délai maximum de création de l'event")
@Route(path = "^\\/groupCreate$", type = POST, needLogin = true) @Route(path = "^\\/groupCreate$", type = POST, needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{ public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
Group newGroup = new Group(reader.readJson()); Group newGroup = new Group(reader.readJson());
PeerAtUser user = context.getUser();
if (this.repo.getPlayerGroup(user.getId(), newGroup.getLinkToChapter()) == null) { if (this.repo.getPlayerGroup(user.getId(), newGroup.getLinkToChapter()) == null) {
try { try {
if(this.repo.getGroupId(newGroup) == null) throw new NullPointerException(); if(this.repo.getGroupId(newGroup) == null) throw new NullPointerException();
writer.response(403, "Access-Control-Allow-Origin: *"); context.response(403);
return; return;
}catch(NullPointerException e){ }catch(NullPointerException e){
if(newGroup.getLinkToChapter() != null){ if(newGroup.getLinkToChapter() != null){
@ -47,21 +49,21 @@ public class GroupCreate implements Response {
if(chapter.getStartDate() != null){ if(chapter.getStartDate() != null){
LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay); LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay);
if(LocalDateTime.now().isAfter(start)){ if(LocalDateTime.now().isAfter(start)){
writer.response(423, "Access-Control-Allow-Origin: *"); context.response(423);
return; return;
} }
} }
} }
if (this.repo.insertGroup(newGroup, user)) { if (this.repo.insertGroup(newGroup, user)) {
writer.response(200, "Access-Control-Allow-Origin: *"); context.response(200);
locker.setValue(newGroup); locker.setValue(newGroup);
} else { } else {
writer.response(403, "Access-Control-Allow-Origin: *"); context.response(403);
} }
} }
}else { }else {
writer.response(403, "Access-Control-Allow-Origin: *"); context.response(403);
} }
} }
} }

View file

@ -1,21 +1,22 @@
package be.jeffcheasey88.peeratcode.routes.groups; package dev.peerat.backend.routes.groups;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST; import static dev.peerat.framework.RequestType.POST;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc; import dev.peerat.backend.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader; import dev.peerat.backend.model.Chapter;
import be.jeffcheasey88.peeratcode.framework.HttpWriter; import dev.peerat.backend.model.Completion;
import be.jeffcheasey88.peeratcode.framework.Locker; import dev.peerat.backend.model.Group;
import be.jeffcheasey88.peeratcode.framework.Response; import dev.peerat.backend.model.PeerAtUser;
import be.jeffcheasey88.peeratcode.framework.Route; import dev.peerat.backend.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.framework.User; import dev.peerat.framework.Context;
import be.jeffcheasey88.peeratcode.model.Chapter; import dev.peerat.framework.HttpReader;
import be.jeffcheasey88.peeratcode.model.Completion; import dev.peerat.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.model.Group; import dev.peerat.framework.Locker;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
public class GroupJoin implements Response{ public class GroupJoin implements Response{
@ -38,17 +39,18 @@ public class GroupJoin implements Response{
@RouteDoc(responseCode = 409, responseDescription = "L'utilisateur est un peu débile... ou pas ?") @RouteDoc(responseCode = 409, responseDescription = "L'utilisateur est un peu débile... ou pas ?")
@Route(path = "^\\/groupJoin$", type = POST, needLogin = true) @Route(path = "^\\/groupJoin$", type = POST, needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{ public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
Group group = new Group(reader.readJson()); Group group = new Group(reader.readJson());
PeerAtUser user = context.getUser();
Group userGroup = this.repo.getPlayerGroup(user.getId(), group.getLinkToChapter()); Group userGroup = this.repo.getPlayerGroup(user.getId(), group.getLinkToChapter());
if(group.equals(userGroup)){ if(group.equals(userGroup)){
writer.response(403, "Access-Control-Allow-Origin: *"); context.response(403);
return; return;
} }
if(group.getLinkToChapter() == null){ if(group.getLinkToChapter() == null){
writer.response(409, "Access-Control-Allow-Origin: *"); context.response(409);
writer.write(waitTime); writer.write(waitTime);
return; return;
} }
@ -58,18 +60,18 @@ public class GroupJoin implements Response{
if(chapter.getStartDate() != null){ if(chapter.getStartDate() != null){
LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay); LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay);
if(LocalDateTime.now().isAfter(start)){ if(LocalDateTime.now().isAfter(start)){
writer.response(423, "Access-Control-Allow-Origin: *"); context.response(423);
return; return;
} }
} }
} }
if (this.repo.insertUserInGroup(group, user)) { if (this.repo.insertUserInGroup(group, user)) {
writer.response(200, "Access-Control-Allow-Origin: *"); context.response(200);
leaderboard.setValue(new Completion(0, 0, 0, null, 0)); leaderboard.setValue(new Completion(0, 0, 0, null, 0));
} else { } else {
writer.response(403, "Access-Control-Allow-Origin: *"); context.response(403);
} }
} }

View file

@ -0,0 +1,33 @@
package dev.peerat.backend.routes.groups;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.Group;
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.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonArray;
public class GroupList implements Response {
private DatabaseRepository repo;
public GroupList(DatabaseRepository repo) {
this.repo = repo;
}
@RouteDoc(path = "/groups", responseCode = 200, responseDescription = "JSON avec la liste des groups")
@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

@ -1,21 +1,22 @@
package be.jeffcheasey88.peeratcode.routes.groups; package dev.peerat.backend.routes.groups;
import static be.jeffcheasey88.peeratcode.framework.RequestType.POST; import static dev.peerat.framework.RequestType.POST;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import be.jeffcheasey88.peeratcode.bonus.extract.RouteDoc; import dev.peerat.backend.bonus.extract.RouteDoc;
import be.jeffcheasey88.peeratcode.framework.HttpReader; import dev.peerat.backend.model.Chapter;
import be.jeffcheasey88.peeratcode.framework.HttpWriter; import dev.peerat.backend.model.Completion;
import be.jeffcheasey88.peeratcode.framework.Locker; import dev.peerat.backend.model.Group;
import be.jeffcheasey88.peeratcode.framework.Response; import dev.peerat.backend.model.PeerAtUser;
import be.jeffcheasey88.peeratcode.framework.Route; import dev.peerat.backend.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.framework.User; import dev.peerat.framework.Context;
import be.jeffcheasey88.peeratcode.model.Chapter; import dev.peerat.framework.HttpReader;
import be.jeffcheasey88.peeratcode.model.Completion; import dev.peerat.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.model.Group; import dev.peerat.framework.Locker;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
public class GroupQuit implements Response{ public class GroupQuit implements Response{
@ -36,12 +37,13 @@ public class GroupQuit implements Response{
@RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de quitter un groupe après le délai maximum de création de l'event") @RouteDoc(responseCode = 423, responseDescription = "L'utilisateur essaye de quitter un groupe après le délai maximum de création de l'event")
@Route(path = "^\\/groupQuit$", type = POST, needLogin = true) @Route(path = "^\\/groupQuit$", type = POST, needLogin = true)
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception{ public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception{
Group group = new Group(reader.readJson()); Group group = new Group(reader.readJson());
PeerAtUser user = context.getUser();
Group userGroup = this.repo.getPlayerGroup(user.getId(), group.getLinkToChapter()); Group userGroup = this.repo.getPlayerGroup(user.getId(), group.getLinkToChapter());
if(!group.equals(userGroup)){ if(!group.equals(userGroup)){
writer.response(403, "Access-Control-Allow-Origin: *"); context.response(403);
return; return;
} }
@ -50,18 +52,18 @@ public class GroupQuit implements Response{
if(chapter.getStartDate() != null){ if(chapter.getStartDate() != null){
LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay); LocalDateTime start = chapter.getStartDate().toLocalDateTime().plusMinutes(this.groupDelay);
if(LocalDateTime.now().isAfter(start)){ if(LocalDateTime.now().isAfter(start)){
writer.response(423, "Access-Control-Allow-Origin: *"); context.response(423);
return; return;
} }
} }
} }
if (this.repo.leaveGroup(group, user)) { if (this.repo.leaveGroup(group, user)) {
writer.response(200, "Access-Control-Allow-Origin: *"); context.response(200);
leaderboard.setValue(new Completion(0, 0, 0, null, 0)); leaderboard.setValue(new Completion(0, 0, 0, null, 0));
} else { } else {
writer.response(403, "Access-Control-Allow-Origin: *"); context.response(403);
} }
} }

View file

@ -0,0 +1,35 @@
package dev.peerat.backend.routes.users;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
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.RequestType;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonMap;
public class ChangePassword implements Response{
private DatabaseRepository repo;
public ChangePassword(DatabaseRepository repo){
this.repo = repo;
}
@RouteDoc(path = "/user/cpw", responseCode = 200, responseDescription = "L'utilisateur a mis à jours sont mots de passe")
@RouteDoc(responseCode = 400, responseDescription = "L'utilisateur a envoyer un mots de passe invalide")
@Route(path = "^/user/cpw$", type = RequestType.POST, needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
String password = reader.<JsonMap>readJson().get("password");
repo.updatePassword(context.<PeerAtUser>getUser().getId(), password);
context.response(200);
}
}

View file

@ -0,0 +1,92 @@
package dev.peerat.backend.routes.users;
import static dev.peerat.framework.RequestType.POST;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import dev.peerat.backend.model.PeerAtUser;
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.RequestType;
import dev.peerat.framework.Route;
import dev.peerat.framework.Router;
import dev.peerat.framework.utils.json.JsonMap;
public class ForgotPassword extends FormResponse{
private Router<PeerAtUser> router;
private DatabaseRepository repo;
private Mail mail;
private Map<String, Integer> codes;
public ForgotPassword(Router<PeerAtUser> router, DatabaseRepository repo, Mail mail){
this.router = router;
this.repo = repo;
this.mail = mail;
this.codes = new HashMap<>();
}
@Route(path = "^/user/fpw$", 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");
int player = repo.getPlayerId(email);
if(player < 0){
context.response(400);
return;
}
if(hasFields("code") && areValids("password")){
Integer checkCode = codes.get(email);
if(checkCode == null){
context.response(400);
return;
}
int code = json.<Number>get("code").intValue();
String password = json.get("password");
if(code == checkCode.intValue()){
codes.remove(email);
repo.updatePassword(player, password);
context.response(200,
"Access-Control-Expose-Headers: Authorization",
"Authorization: Bearer " + this.router.createAuthUser(new PeerAtUser(player)));
}else{
context.response(400);
}
}else{
int code = codeGenerator();
codes.put(email, code);
mail.send(email, "Forgot your Peer @ Code password ?", "Your check code is "+code+" !");
context.response(200);
}
}
private int codeGenerator(){
int min = 1000;
int max = 9999;
return new Random().nextInt((max-min)) + min;
}
}

View file

@ -0,0 +1,53 @@
package dev.peerat.backend.routes.users;
import static dev.peerat.framework.RequestType.POST;
import java.util.regex.Matcher;
import dev.peerat.backend.bonus.extract.RouteDoc;
import dev.peerat.backend.model.PeerAtUser;
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.Route;
import dev.peerat.framework.Router;
import dev.peerat.framework.utils.json.JsonMap;
public class Login extends FormResponse{
private DatabaseRepository databaseRepo;
private Router<PeerAtUser> router;
public Login(DatabaseRepository databaseRepo, Router<PeerAtUser> router){
this.databaseRepo = databaseRepo;
this.router = router;
}
@RouteDoc(path = "/login", 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 = "^\\/login$", 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("pseudo", "passwd")){
context.response(400);
return;
}
int id;
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)));
}else{
context.response(400);
}
}
}

View file

@ -0,0 +1,168 @@
package dev.peerat.backend.routes.users;
import static dev.peerat.framework.RequestType.POST;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.Map;
import java.util.regex.Matcher;
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.bonus.extract.RouteDoc;
import dev.peerat.backend.model.PeerAtUser;
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.Route;
import dev.peerat.framework.Router;
import dev.peerat.framework.utils.json.JsonMap;
public class MailConfirmation extends FormResponse {
private DatabaseRepository databaseRepo;
private Router<PeerAtUser> router;
private String usersFilesPath;
private KeyPairGenerator generator;
private Encoder encoder;
private String gitToken;
private Map<String, Integer> playersWaiting;
public MailConfirmation(
DatabaseRepository databaseRepo,
Router<PeerAtUser> router,
String initUsersFilesPath,
String gitToken,
Map<String, Integer> playersWaiting){
this.databaseRepo = databaseRepo;
this.router = router;
this.usersFilesPath = initUsersFilesPath;
this.gitToken = gitToken;
this.playersWaiting = playersWaiting;
try {
generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(4096);
} catch (NoSuchAlgorithmException e){
e.printStackTrace();
}
encoder = Base64.getEncoder();
}
@RouteDoc(path = "/confirmation", 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 = "^\\/confirmation$", 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","pseudo","firstname","lastname","passwd")) || (!hasFields("code"))){
context.response(400);
return;
}
String email = json.get("email");
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");
Integer checkCode = playersWaiting.get(email);
if(checkCode == null){
context.response(400);
return;
}
if(code == checkCode.intValue()){
playersWaiting.remove(email);
int id = databaseRepo.register(pseudo, email, password, firstname, lastname, "", "", "");
if(id >= 0){
// createFolderToSaveSourceCode(pseudo);
// generateGitKey(email, pseudo, password);
context.response(200,
"Access-Control-Expose-Headers: Authorization",
"Authorization: Bearer " + this.router.createAuthUser(new PeerAtUser(id)));
}else{
context.response(400);
JsonMap error = new JsonMap();
error.set("username_valid", pseudo);
error.set("email_valid", email);
writer.write(error.toString());
}
}else{
context.response(400);
}
}
private void createFolderToSaveSourceCode(String pseudo) throws IOException {
Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo)));
}
private static byte[] PREFIX = new byte[] {0,0,0,7,(byte)'s',(byte)'s',(byte)'h',(byte)'-',(byte)'r',(byte)'s',(byte)'a'};
private String generateGitKey(String email, String pseudo, String password) throws Exception{
KeyPair pair = generator.generateKeyPair(); //doit être unique ???
JSONObject createUser = new JSONObject();
createUser.put("email", email);
createUser.put("username", pseudo);
createUser.put("password", password);
post("https://git-users.peerat.dev/api/v1/admin/users/", createUser);
JSONObject sendKey = new JSONObject();
RSAPublicKey pub = (RSAPublicKey) pair.getPublic();
byte[] exponent = pub.getPublicExponent().toByteArray();
byte[] modulus = pub.getModulus().toByteArray();
byte[] key = new byte[19+exponent.length+modulus.length];
System.arraycopy(PREFIX, 0, key, 0, 11);
byte[] exLength = ByteBuffer.allocate(4).putInt(exponent.length).array();
byte[] modLength = ByteBuffer.allocate(4).putInt(modulus.length).array();
System.arraycopy(exLength, 0, key, 11, 4);
System.arraycopy(exponent, 0, key, 15, exponent.length);
System.arraycopy(modLength, 0, key, 15+exponent.length, 4);
System.arraycopy(modulus, 0, key, 19+exponent.length, modulus.length);
sendKey.put("key", "ssh-rsa "+new String(encoder.encode(key)));
sendKey.put("read_only", false);
sendKey.put("title", "peer_at_code_auto_push_key_"+pseudo);
post("https://git-users.peerat.dev/api/v1/admin/users/"+pseudo+"/keys", sendKey);
return new String(encoder.encode(pair.getPrivate().getEncoded()));
}
private void post(String url, JSONAware json) throws Exception{
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type","application/json");
connection.setRequestProperty("Authorization","Bearer "+this.gitToken);
connection.setDoInput(true);
connection.setDoOutput(true);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream()));
writer.write(json.toJSONString());
writer.flush();
writer.close();
int response = connection.getResponseCode();
if(response != 201) throw new Exception("Call to "+url+" failed with response code "+response);
}
}

View file

@ -0,0 +1,57 @@
package dev.peerat.backend.routes.users;
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.DatabaseRepository;
import dev.peerat.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import dev.peerat.framework.RequestType;
import dev.peerat.framework.Response;
import dev.peerat.framework.Route;
import dev.peerat.framework.utils.json.JsonMap;
public class ProfileSettings implements Response{
private DatabaseRepository repo;
public ProfileSettings(DatabaseRepository repo){
this.repo = repo;
}
@RouteDoc(path = "/user/settings", responseCode = 200, responseDescription = "L'utilisateur a mis à jours sont profile")
@RouteDoc(responseCode = 400, responseDescription = "L'utilisateur a envoyer une donnée unique, déjà utilisée")
@Route(path = "^/user/settings$", type = RequestType.POST, needLogin = true)
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
JsonMap json = reader.readJson();
String pseudo = json.get("pseudo");
String email = json.get("email");
String firstname = json.get("firstname");
String lastname = json.get("lastname");
Player player = repo.getPlayer(context.<PeerAtUser>getUser().getId());
if(!player.getPseudo().equals(pseudo)){
if(!repo.updatePseudo(context.<PeerAtUser>getUser().getId(), player, pseudo)){
context.response(400);
return;
}
player.setPseudo(pseudo);
}
if(!player.getEmail().equals(email)){
}
if((!player.getFirstname().equals(firstname)) || (!player.getLastname().equals(lastname))){
repo.updateProfile(context.<PeerAtUser>getUser().getId(), player, lastname, firstname);
}
context.response(200);
}
}

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

@ -0,0 +1,49 @@
package dev.peerat.backend.utils;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.Response;
import dev.peerat.framework.utils.json.Json;
import dev.peerat.framework.utils.json.JsonMap;
public abstract class FormResponse implements Response{
private Json json;
private Map<String, Pattern> checker;
public FormResponse(){
this.checker = new HashMap<>();
}
public void validator(String key, Pattern regex){
this.checker.put(key, regex);
}
public <T extends Json> T json(HttpReader reader) throws Exception{
return (T) (this.json = reader.readJson());
}
public boolean hasFields(String... fields){
JsonMap map = (JsonMap)json;
for(String field : fields){
if(!map.has(field)) return false;
}
return true;
}
public boolean areValids(String... fields){
JsonMap map = (JsonMap)json;
for(String field : fields){
String value = (String) map.get(field);
if(value == null) return false;
if(value.isEmpty()) return false;
Pattern pattern = checker.get(field);
if(pattern == null) continue;
if(!pattern.matcher(value).matches()) return false;
}
return true;
}
}

View file

@ -0,0 +1,57 @@
package dev.peerat.backend.utils;
import java.util.Date;
import java.util.Properties;
import jakarta.mail.Authenticator;
import jakarta.mail.Message;
import jakarta.mail.PasswordAuthentication;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
public class Mail {
private Session session;
private String fromAddress;
public Mail(String initUsername, String initPassword, String initSmtpHost, int initSmtpPort, String initFromAddress) {
System.out.println("login on "+initUsername+" into "+initSmtpHost+":"+initSmtpPort);
Properties props = new Properties();
props.put("mail.smtp.host", initSmtpHost);
props.put("mail.smtp.port", initSmtpPort);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Authenticator auth = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(initUsername, initPassword);
}
};
session = Session.getInstance(props, auth);
fromAddress = initFromAddress;
}
public void send(String toAddress, String subject, String text){
try
{
MimeMessage msg = new MimeMessage(session);
//set message headers
msg.addHeader("Content-type", "text/HTML; charset=UTF-8");
msg.addHeader("format", "flowed");
msg.addHeader("Content-Transfer-Encoding", "8bit");
msg.setFrom(new InternetAddress(fromAddress, "Peer-at Code"));
msg.setReplyTo(InternetAddress.parse(fromAddress, false));
msg.setSubject(subject, "UTF-8");
msg.setText(text, "UTF-8");
msg.setSentDate(new Date());
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toAddress, false));
Transport.send(msg);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -1,142 +0,0 @@
package be.jeffcheasey88.peeratcode.parser.java;
import static org.junit.Assert.assertNull;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.List;
import org.junit.jupiter.api.Test;
import be.jeffcheasey88.peeratcode.parser.java.Variable.Value;
class VariableTest {
//int i = 4;
//int i,j,k,l=1;
//int lm ;
//public static int l;
//Test<Test>t;
//Test<Test,K,L> j = new Test().schedule(p -> { return true;});
//int i =j=k=l=4;
@Test
void case1(){
try {
Variable variable = new Variable();
variable.parse(" int i = 4 ; ");
assertEquals(0, variable.getModifier());
assertEquals("int", variable.getType());
assertEquals("i", variable.getName());
assertEquals("4", ((Value)variable.getValue()).value());
}catch(Exception e){
fail(e);
}
}
@Test
void case2(){
try {
Variable variable = new Variable();
variable.parse("public static int l ; ");
assertEquals(JavaParser.getModifier("public")+JavaParser.getModifier("static"), variable.getModifier());
assertEquals("int", variable.getType());
assertEquals("l", variable.getName());
assertNull(variable.getValue());
}catch(Exception e){
fail(e);
}
}
@Test
void case3(){
try {
Variable variable = new Variable();
variable.parse(" int lm ; ");
assertEquals(0, variable.getModifier());
assertEquals("int", variable.getType());
assertEquals("lm", variable.getName());
assertNull(variable.getValue());
}catch(Exception e){
fail(e);
}
}
@Test
void case4(){
try {
Variable variable = new Variable();
variable.parse("Testas< List< Map< Test, List< Test >, Test>> >t; ");
assertEquals(0, variable.getModifier());
assertEquals("Testas<List<Map<Test,List<Test>,Test>>>", variable.getType());
assertEquals("t", variable.getName());
assertNull(variable.getValue());
}catch(Exception e){
fail(e);
}
}
@Test
void case5(){
try {
Variable variable = new Variable();
variable.parse(" int i,j,k,l=1; ");
assertEquals(0, variable.getModifier());
assertEquals("int", variable.getType());
assertEquals("i", variable.getName());
assertNull(variable.getValue());
}catch(Exception e){
fail(e);
}
}
@Test
void case6(){
try {
Class clazz = new Class();
clazz.parse("public class Test{ int i ,j,k,l=1; } ");
List<Variable> vars = clazz.getVariables();
assertEquals(vars.size(), 4);
for(int i = 0; i < 3; i++){
Variable v = vars.get(i);
assertEquals(0, v.getModifier());
assertEquals("int", v.getType());
assertEquals((char)('i'+i), v.getName().charAt(0));
assertNull(v.getValue());
}
Variable v = vars.get(3);
assertEquals(0, v.getModifier());
assertEquals("int", v.getType());
assertEquals('l', v.getName().charAt(0));
assertEquals("1", ((Value)v.getValue()).value());
}catch(Exception e){
fail(e);
}
}
@Test
void case7(){
try {
Class clazz = new Class();
clazz.parse("public class Test{ int i ,j,k; int l=i=k=l=4; } ");
List<Variable> vars = clazz.getVariables();
assertEquals(vars.size(), 4);
for(int i = 0; i < 4; i++){
Variable v = vars.get(i);
assertEquals(0, v.getModifier());
assertEquals("int", v.getType());
assertEquals((char)('i'+i), v.getName().charAt(0));
}
}catch(Exception e){
fail(e);
}
}
}

View file

@ -0,0 +1,64 @@
package dev.peerat.backend;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
import dev.peerat.backend.repository.DatabaseRepository;
public class TestDatabaseRepository extends DatabaseRepository{
private Connection con;
private String schem;
public TestDatabaseRepository(Configuration config, File databaseSchem){
super(config);
try{
schem = "";
BufferedReader reader = new BufferedReader(new FileReader(databaseSchem));
String line;
while((line = reader.readLine()) != null) schem+=line;
reader.close();
}catch(Exception e){
e.printStackTrace();
}
}
public void init(){
try {
Method method = DatabaseRepository.class.getDeclaredMethod("ensureConnection");
method.setAccessible(true);
method.invoke(this);
Field field = DatabaseRepository.class.getDeclaredField("con");
field.setAccessible(true);
this.con = (Connection) field.get(this);
}catch(Exception e){
e.getCause().printStackTrace();
}
}
public void close(){
try {
this.con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void reset(){
try{
String[] split = schem.split(";");
for(String statment : split){
this.con.prepareStatement(statment).execute();
}
}catch(Exception e){
e.printStackTrace();
}
}
}

View file

@ -1,4 +1,4 @@
package be.jeffcheasey88.peeratcode.webclient; package dev.peerat.backend;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
@ -9,10 +9,9 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.json.simple.JSONObject; import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
import be.jeffcheasey88.peeratcode.framework.HttpReader; import dev.peerat.framework.utils.json.JsonMap;
import be.jeffcheasey88.peeratcode.framework.HttpWriter;
public class WebClient { public class WebClient {
@ -49,10 +48,10 @@ public class WebClient {
} }
public void auth(String user, String password) throws Exception{ public void auth(String user, String password) throws Exception{
JSONObject login = new JSONObject(); JsonMap login = new JsonMap();
login.put("pseudo", user); login.set("pseudo", user);
login.put("passwd", password); login.set("passwd", password);
route("/login", "POST", login.toJSONString()); route("/login", "POST", login.toString());
System.out.println("["+host+"] /login "+login); System.out.println("["+host+"] /login "+login);
for(String line : this.headers){ for(String line : this.headers){
@ -67,17 +66,17 @@ public class WebClient {
} }
public void register(String user, String password, String email, String firstname, String lastname, String description) throws Exception{ public void register(String user, String password, String email, String firstname, String lastname, String description) throws Exception{
JSONObject register = new JSONObject(); JsonMap register = new JsonMap();
register.put("pseudo", user); register.set("pseudo", user);
register.put("passwd", password); register.set("passwd", password);
register.put("email", email); register.set("email", email);
register.put("firstname", firstname); register.set("firstname", firstname);
register.put("lastname", lastname); register.set("lastname", lastname);
register.put("description", description); register.set("description", description);
register.put("sgroup", ""); register.set("sgroup", "");
register.put("avatar", ""); register.set("avatar", "");
route("/register", "POST", register.toJSONString()); route("/register", "POST", register.toString());
System.out.println("["+host+"] /register "+register); System.out.println("["+host+"] /register "+register);
for(String line : this.headers){ for(String line : this.headers){
Matcher matcher = AUTORIZATION.matcher(line); Matcher matcher = AUTORIZATION.matcher(line);
@ -99,6 +98,10 @@ public class WebClient {
this.writer.write(type+" "+route+" HTTP/1.1\n"); this.writer.write(type+" "+route+" HTTP/1.1\n");
if(this.token != null) this.writer.write("Authorization: Bearer "+this.token+"\n"); if(this.token != null) this.writer.write("Authorization: Bearer "+this.token+"\n");
for(String send : this.sendHeaders) this.writer.write(send+"\n"); for(String send : this.sendHeaders) this.writer.write(send+"\n");
int length = 0;
for(String value : content) length+=value.length();
length+=content.length-1;
this.writer.write("Content-length: "+length+"\n");
this.writer.write("\n"); this.writer.write("\n");
for(String value : content) this.writer.write(value+"\n"); for(String value : content) this.writer.write(value+"\n");

View file

@ -1,4 +1,4 @@
package be.jeffcheasey88.peeratcode.routes; package dev.peerat.backend.routes;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
@ -8,8 +8,8 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle; import org.junit.jupiter.api.TestInstance.Lifecycle;
import be.jeffcheasey88.peeratcode.Main; import dev.peerat.backend.Main;
import be.jeffcheasey88.peeratcode.webclient.WebClient; import dev.peerat.backend.WebClient;
@TestInstance(Lifecycle.PER_CLASS) @TestInstance(Lifecycle.PER_CLASS)
class PlayerDetailsTests { class PlayerDetailsTests {

View file

@ -1,16 +1,16 @@
package be.jeffcheasey88.peeratcode.routes; package dev.peerat.backend.routes;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
import org.json.simple.JSONObject;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle; import org.junit.jupiter.api.TestInstance.Lifecycle;
import be.jeffcheasey88.peeratcode.Main; import dev.peerat.backend.Main;
import be.jeffcheasey88.peeratcode.webclient.WebClient; import dev.peerat.backend.WebClient;
import dev.peerat.framework.utils.json.JsonMap;
@TestInstance(Lifecycle.PER_CLASS) @TestInstance(Lifecycle.PER_CLASS)
public class ScoreTests { public class ScoreTests {
@ -42,14 +42,14 @@ public class ScoreTests {
@Test @Test
void testOnDeployed(){ void testOnDeployed(){
try{ try{
JSONObject group = new JSONObject(); JsonMap group = new JsonMap();
group.put("name", "GroupTest"); group.set("name", "GroupTest");
group.put("chapter", 2); group.set("chapter", 2);
client.register("Test1", "Test2", "Test3@Test7.be", "Test4", "Test5", "Test6"); client.register("Test1", "Test2", "Test3@Test7.be", "Test4", "Test5", "Test6");
client.assertResponseCode(200); client.assertResponseCode(200);
client.route("/groupCreate", "POST", group.toJSONString()); client.route("/groupCreate", "POST", group.toString());
client.assertResponseCode(200); client.assertResponseCode(200);
client.sendHeaders.add("content-type: ah;boundary=----WebKitFormBoundaryNUjiLBAMuX2dhxU7"); client.sendHeaders.add("content-type: ah;boundary=----WebKitFormBoundaryNUjiLBAMuX2dhxU7");
@ -60,7 +60,7 @@ public class ScoreTests {
client.disconnect(); client.disconnect();
client.auth("JeffCheasey88", "TheoPueDesPieds"); client.auth("JeffCheasey88", "TheoPueDesPieds");
client.route("/groupJoin", "POST", group.toJSONString()); client.route("/groupJoin", "POST", group.toString());
client.assertResponseCode(200); client.assertResponseCode(200);
client.sendHeaders.add("content-type: ah;boundary=----WebKitFormBoundaryNUjiLBAMuX2dhxU7"); client.sendHeaders.add("content-type: ah;boundary=----WebKitFormBoundaryNUjiLBAMuX2dhxU7");

View file

@ -1,16 +1,16 @@
package be.jeffcheasey88.peeratcode.routes; package dev.peerat.backend.routes;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
import org.json.simple.JSONObject;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle; import org.junit.jupiter.api.TestInstance.Lifecycle;
import be.jeffcheasey88.peeratcode.Main; import dev.peerat.backend.Main;
import be.jeffcheasey88.peeratcode.webclient.WebClient; import dev.peerat.backend.WebClient;
import dev.peerat.framework.utils.json.JsonMap;
@TestInstance(Lifecycle.PER_CLASS) @TestInstance(Lifecycle.PER_CLASS)
public class TmpRoutesTests { public class TmpRoutesTests {
@ -42,12 +42,12 @@ public class TmpRoutesTests {
@Test @Test
void testOnDeployed(){ void testOnDeployed(){
try { try {
JSONObject group = new JSONObject(); JsonMap group = new JsonMap();
group.put("name", "MyTest"); group.set("name", "MyTest");
group.put("chapter", 1); group.set("chapter", 1);
client.auth("JeffCheasey88", "TheoPueDesPieds"); client.auth("JeffCheasey88", "TheoPueDesPieds");
client.route("/groupCreate", "POST", group.toJSONString()); client.route("/groupCreate", "POST", group.toString());
client.assertResponseCode(200); client.assertResponseCode(200);
}catch(Exception e){ }catch(Exception e){

View file

@ -1,4 +1,4 @@
package be.jeffcheasey88.peeratcode.routes; package dev.peerat.backend.routes;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
@ -8,8 +8,8 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle; import org.junit.jupiter.api.TestInstance.Lifecycle;
import be.jeffcheasey88.peeratcode.Main; import dev.peerat.backend.Main;
import be.jeffcheasey88.peeratcode.webclient.WebClient; import dev.peerat.backend.WebClient;
@TestInstance(Lifecycle.PER_CLASS) @TestInstance(Lifecycle.PER_CLASS)
public class TriggerTests { public class TriggerTests {

View file

@ -0,0 +1,30 @@
package dev.peerat.backend.userstories;
import java.io.File;
import dev.peerat.backend.Configuration;
import dev.peerat.backend.TestDatabaseRepository;
public class BaseUserStoriesTest {
private Configuration config;
private TestDatabaseRepository repo;
public BaseUserStoriesTest(){}
public void init() throws Exception{
this.config = new Configuration("config-test.txt");
this.repo = new TestDatabaseRepository(config, new File("database-schem.sql"));
this.config.load();
}
public Configuration getConfig(){
return this.config;
}
public TestDatabaseRepository getRepository(){
return this.repo;
}
}

View file

@ -0,0 +1,83 @@
package dev.peerat.backend.userstories;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import dev.peerat.backend.Main;
import dev.peerat.backend.WebClient;
import dev.peerat.framework.utils.json.JsonMap;
@TestInstance(Lifecycle.PER_METHOD)
public class GroupTests extends BaseUserStoriesTest{
private Thread server;
private WebClient client;
@BeforeEach
public void init() throws Exception{
Class.forName("com.mysql.cj.jdbc.Driver");
super.init();
getRepository().init();
getRepository().reset();
server = new Thread(new Runnable(){
@Override
public void run(){
try {
Main.main(null);
} catch (Exception e){
e.printStackTrace();
};
}
});
server.start();
client = new WebClient("localhost", 80);
// System.out.println(Password.hash("password").withArgon2().getResult());
try {
client.auth("userTest", "password");
client.assertResponseCode(200);
} catch (Exception e) {
e.printStackTrace();
}
}
@AfterEach
public void stop(){
server.interrupt();
}
@Test
void createNormalGroup() throws Exception{
JsonMap json = new JsonMap();
json.set("name", "Group_test");
json.set("chapter", 1);
client.route("/groupCreate", "POST", json.toString());
client.assertResponseCode(200);
}
@Test
void leaveNormalGroup() throws Exception{
createNormalGroup();
JsonMap json = new JsonMap();
json.set("name", "Group_test");
json.set("chapter", 1);
client.route("/groupQuit", "POST", json.toString());
client.assertResponseCode(200);
}
@Test
void joinNormalGroup() throws Exception{
leaveNormalGroup();
JsonMap json = new JsonMap();
json.set("name", "Group_test");
json.set("chapter", 1);
client.route("/groupJoin", "POST", json.toString());
client.assertResponseCode(200);
}
}

View file

@ -0,0 +1,79 @@
package dev.peerat.backend.userstories;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import dev.peerat.backend.Main;
import dev.peerat.backend.WebClient;
@TestInstance(Lifecycle.PER_METHOD)
public class LoginTests extends BaseUserStoriesTest{
private Thread server;
private WebClient client;
@BeforeEach
public void init() throws Exception{
Class.forName("com.mysql.cj.jdbc.Driver");
super.init();
getRepository().init();
getRepository().reset();
server = new Thread(new Runnable(){
@Override
public void run(){
try {
Main.main(null);
} catch (Exception e){
e.printStackTrace();
};
}
});
server.start();
client = new WebClient("localhost", 80);
try {
client.register("user", "password", "mail@peerat.dev", "firstname", "lastname", "description");
client.assertResponseCode(200);
client.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
@AfterEach
public void stop(){
server.interrupt();
}
@Test
public void normalLogin() throws Exception{
client.auth("user", "password");
client.assertResponseCode(200);
}
@Test
public void wrongPassword() throws Exception{
client.auth("user", "password1");
client.assertResponseCode(400);
}
@Test
public void wrongUsername() throws Exception{
client.auth("user1", "password");
client.assertResponseCode(400);
}
@Test
public void alreadyLoggedin() throws Exception{
client.auth("user", "password");
client.assertResponseCode(200);
client.auth("user", "password");
client.assertResponseCode(403);
}
}

View file

@ -0,0 +1,89 @@
package dev.peerat.backend.userstories;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import dev.peerat.backend.Main;
import dev.peerat.backend.WebClient;
@TestInstance(Lifecycle.PER_METHOD)
public class RegisterTests extends BaseUserStoriesTest{
private Thread server;
private WebClient client;
@BeforeEach
public void init() throws Exception{
Class.forName("com.mysql.cj.jdbc.Driver");
super.init();
getRepository().init();
getRepository().reset();
server = new Thread(new Runnable(){
@Override
public void run(){
try {
Main.main(null);
} catch (Exception e){
e.printStackTrace();
};
}
});
server.start();
client = new WebClient("localhost", 80);
}
@AfterEach
public void stop(){
server.interrupt();
getRepository().close();
}
@Test
public void normalRegister() throws Exception{
client.register("test", "test", "test@peerat.dev", "te", "st", "my desc");
client.assertResponseCode(200);
}
@Test
public void pseudoAlreadyUse() throws Exception{
client.register("test", "test", "test@peerat.dev", "te", "st", "my desc");
client.assertResponseCode(200);
client.disconnect();
client.register("test", "test", "test1@peerat.dev", "te", "st", "my desc");
client.assertResponseCode(400);
}
@Test
public void emailAlreadyUse() throws Exception{
client.register("test", "test", "test@peerat.dev", "te", "st", "my desc");
client.assertResponseCode(200);
client.disconnect();
client.register("test1", "test", "test@peerat.dev", "te", "st", "my desc");
client.assertResponseCode(400);
}
@Test
public void emptyField() throws Exception{
client.register("","","",",","","");
client.assertResponseCode(400);
}
@Test
public void lostField() throws Exception{
client.route("/register", "POST", "{}");
client.assertResponseCode(400);
}
@Test
public void alreadyLoggedin() throws Exception{
client.register("test", "test", "test@peerat.dev", "te", "st", "my desc");
client.assertResponseCode(200);
client.register("test1", "test", "test@peerat.dev", "te", "st", "my desc");
client.assertResponseCode(403);
}
}