Merge from my branch september
This commit is contained in:
parent
c2428ebd94
commit
4f8b45f074
31 changed files with 1002 additions and 247 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,6 +2,7 @@
|
|||
bin/
|
||||
.project
|
||||
config.txt
|
||||
config-test.txt
|
||||
dist/
|
||||
testApi/
|
||||
.apt_generated/*
|
||||
|
|
Binary file not shown.
126
database-schem.sql
Normal file
126
database-schem.sql
Normal file
|
@ -0,0 +1,126 @@
|
|||
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;
|
||||
|
||||
|
|
@ -35,20 +35,22 @@ public class Configuration {
|
|||
private String mailUsername;
|
||||
private String mailPassword;
|
||||
private String mailSmtpHost;
|
||||
private int mailSmptPort;
|
||||
private int mailSmtpPort;
|
||||
private String mailFromAddress;
|
||||
|
||||
private File file;
|
||||
private String git_token;
|
||||
|
||||
private File _file;
|
||||
|
||||
public Configuration(String path) {
|
||||
this.file = new File(path);
|
||||
System.out.println("Config on " + file.getAbsolutePath());
|
||||
this._file = new File(path);
|
||||
System.out.println("Config on " + _file.getAbsolutePath());
|
||||
}
|
||||
|
||||
public void load() throws Exception {
|
||||
if (!this.file.exists())
|
||||
if (!this._file.exists())
|
||||
return;
|
||||
BufferedReader reader = new BufferedReader(new FileReader(this.file));
|
||||
BufferedReader reader = new BufferedReader(new FileReader(this._file));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
String[] split = line.split("=");
|
||||
|
@ -101,14 +103,13 @@ public class Configuration {
|
|||
}
|
||||
|
||||
public void save() throws Exception {
|
||||
if (!file.exists()) {
|
||||
File parent = file.getParentFile();
|
||||
if (!parent.exists())
|
||||
parent.mkdirs();
|
||||
file.createNewFile();
|
||||
if (!_file.exists()) {
|
||||
File parent = _file.getParentFile();
|
||||
if(!parent.exists()) parent.mkdirs();
|
||||
_file.createNewFile();
|
||||
}
|
||||
Field[] fields = getClass().getDeclaredFields();
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(_file));
|
||||
for (Field field : fields) {
|
||||
field.setAccessible(true);
|
||||
if (field.getName().startsWith("_"))
|
||||
|
@ -187,7 +188,11 @@ public class Configuration {
|
|||
this.mailUsername,
|
||||
this.mailPassword,
|
||||
this.mailSmtpHost,
|
||||
this.mailSmptPort,
|
||||
this.mailSmtpPort,
|
||||
this.mailFromAddress);
|
||||
}
|
||||
|
||||
public String getGitToken(){
|
||||
return this.git_token;
|
||||
}
|
||||
}
|
|
@ -16,18 +16,21 @@ 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.Login;
|
||||
import dev.peerat.backend.routes.MailConfirmation;
|
||||
import dev.peerat.backend.routes.PlayerDetails;
|
||||
import dev.peerat.backend.routes.PuzzleElement;
|
||||
import dev.peerat.backend.routes.PuzzleResponse;
|
||||
import dev.peerat.backend.routes.Register;
|
||||
import dev.peerat.backend.routes.Result;
|
||||
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.utils.Mail;
|
||||
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.framework.Context;
|
||||
import dev.peerat.framework.HttpReader;
|
||||
import dev.peerat.framework.HttpWriter;
|
||||
|
@ -47,15 +50,19 @@ public class Main{
|
|||
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));
|
||||
|
||||
router.addDefaultHeaders(RequestType.GET, "Access-Control-Allow-Origin: *");
|
||||
router.addDefaultHeaders(RequestType.POST, "Access-Control-Allow-Origin: *");
|
||||
(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);
|
||||
|
@ -65,10 +72,7 @@ public class Main{
|
|||
router.register(new Response(){
|
||||
@Route(path = "^(.*)$", type = OPTIONS)
|
||||
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
|
||||
context.response(200,
|
||||
"Access-Control-Allow-Origin: *",
|
||||
"Access-Control-Allow-Methods: *",
|
||||
"Access-Control-Allow-Headers: *");
|
||||
context.response(200);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -84,26 +88,30 @@ public class Main{
|
|||
|
||||
private static void initRoutes(Router<PeerAtUser> router, DatabaseRepository repo, Configuration config){
|
||||
Map<Player, Integer> playersWaiting = new HashMap<>();
|
||||
router.register(new Register(repo, playersWaiting));
|
||||
router.register(new MailConfirmation(repo, router, config.getUsersFiles(), config.getGitToken(), playersWaiting));
|
||||
router.register(new Login(repo, router));
|
||||
router.register(new ProfileSettings(repo));
|
||||
router.register(new ChangePassword(repo));
|
||||
router.register(new ForgotPassword());
|
||||
|
||||
router.register(new DynamicLogs(repo, router.getLogger()));
|
||||
|
||||
router.register(new ChapterElement(repo));
|
||||
router.register(new ChapterList(repo));
|
||||
router.register(new PuzzleElement(repo));
|
||||
router.register(new Register(repo, router, config.getUsersFiles(), playersWaiting));
|
||||
router.register(new MailConfirmation(repo, router, config.getUsersFiles(), playersWaiting));
|
||||
router.register(new Login(repo, router));
|
||||
router.register(new Result(repo));
|
||||
router.register(new Leaderboard(repo));
|
||||
router.register(new PlayerDetails(repo));
|
||||
router.register(new BadgeDetails(repo));
|
||||
|
||||
Locker<Group> groupLock = new Locker<>();
|
||||
router.register(new GroupCreate(repo, groupLock, config.getGroupJoinMinutes()));
|
||||
|
||||
DynamicLeaderboard dlb = new DynamicLeaderboard(repo);
|
||||
router.register(dlb);
|
||||
|
||||
Locker<Completion> leaderboard = dlb.getLocker();
|
||||
Locker<Completion> leaderboard = new Locker<>();
|
||||
|
||||
router.register(new DynamicLeaderboard(repo, leaderboard));
|
||||
router.register(new PuzzleResponse(repo, config.getUsersFiles(), leaderboard));
|
||||
|
||||
router.register(new GroupCreate(repo, groupLock, config.getGroupJoinMinutes()));
|
||||
router.register(new GroupList(repo));
|
||||
router.register(new GroupJoin(repo, config.getGroupJoinMinutes(), config.getGroupQuitMinutes(), leaderboard));
|
||||
router.register(new GroupQuit(repo, config.getGroupJoinMinutes(), leaderboard));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package dev.peerat.backend.model;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
public class Chapter {
|
||||
|
@ -34,6 +35,14 @@ public class Chapter {
|
|||
this.puzzles = puzzles;
|
||||
}
|
||||
|
||||
public boolean isInCurrentTime(){
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
boolean show = true;
|
||||
if(startDate != null) show &= now.isAfter(startDate.toLocalDateTime());
|
||||
if(endDate != null) show &= now.isBefore(endDate.toLocalDateTime());
|
||||
return show;
|
||||
}
|
||||
|
||||
public Timestamp getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,10 @@ public class Player implements Comparable<Player> {
|
|||
this.email = email;
|
||||
}
|
||||
|
||||
public void setPseudo(String pseudo){
|
||||
this.pseudo = pseudo;
|
||||
}
|
||||
|
||||
public String getPseudo() {
|
||||
return this.pseudo;
|
||||
}
|
||||
|
@ -185,8 +189,8 @@ public class Player implements Comparable<Player> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(email, pseudo);
|
||||
public int hashCode(){
|
||||
return Objects.hash(email);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -198,6 +202,6 @@ public class Player implements Comparable<Player> {
|
|||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Player other = (Player) obj;
|
||||
return Objects.equals(email, other.email) && Objects.equals(pseudo, other.pseudo);
|
||||
return Objects.equals(email, other.email);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ public enum DatabaseQuery {
|
|||
|
||||
// PLAYERS
|
||||
GET_PLAYER_SIMPLE("SELECT pseudo, email, firstname, lastname, description FROM players WHERE id_player = ?"),
|
||||
GET_PLAYER_PSEUDO("SELECT * FROM players WHERE pseudo = ?"),
|
||||
GET_PLAYER_DETAILS("SELECT p.*, g.*\r\n"
|
||||
+ "FROM players p\r\n"
|
||||
+ "LEFT OUTER JOIN containsGroups cg ON p.id_player = cg.fk_player\r\n"
|
||||
|
@ -79,6 +80,8 @@ public enum DatabaseQuery {
|
|||
GET_PLAYER_DETAILS_BY_PSEUDO(GET_PLAYER_DETAILS, "p.pseudo = ? GROUP BY g.name ORDER BY g.fk_chapter, g.fk_puzzle;"),
|
||||
GET_PLAYER_COMPLETIONS("select c.*, p.name from completions c left join puzzles p on c.fk_puzzle = p.id_puzzle where fk_player = ?;"),
|
||||
GET_PLAYER_RANK("SELECT * FROM (SELECT fk_player, RANK() OVER(ORDER BY SUM(score) DESC) rank FROM completions c LEFT JOIN players p ON p.id_player = c.fk_player 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
|
||||
GET_BADGE("SELECT * FROM badges WHERE id_badge = ?"), GET_BADGES_OF_PLAYER(
|
||||
|
|
|
@ -32,68 +32,6 @@ public class DatabaseRepository {
|
|||
public DatabaseRepository(Configuration 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 {
|
||||
if (con == null || (!con.isValid(5))) {
|
||||
|
@ -278,6 +216,50 @@ public class DatabaseRepository {
|
|||
return null;
|
||||
}
|
||||
|
||||
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) {
|
||||
return getPlayerDetails(idPlayer, null);
|
||||
}
|
||||
|
@ -520,7 +502,6 @@ public class DatabaseRepository {
|
|||
*/
|
||||
public int register(String pseudo, String email, String password, String firstname, String lastname,
|
||||
String description, String sgroup, String avatar) {
|
||||
Hash hash = Password.hash(password).withArgon2();
|
||||
try {
|
||||
ensureConnection();
|
||||
con.setAutoCommit(false);
|
||||
|
@ -528,7 +509,7 @@ public class DatabaseRepository {
|
|||
Statement.RETURN_GENERATED_KEYS)) {
|
||||
playerStatement.setString(1, pseudo);
|
||||
playerStatement.setString(2, email);
|
||||
playerStatement.setString(3, hash.getResult());
|
||||
playerStatement.setString(3, Password.hash(password).withArgon2().getResult());
|
||||
playerStatement.setString(4, firstname);
|
||||
playerStatement.setString(5, lastname);
|
||||
playerStatement.setString(6, description);
|
||||
|
|
|
@ -34,23 +34,23 @@ public class ChapterElement implements Response {
|
|||
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();
|
||||
boolean show = chapter.isInCurrentTime();
|
||||
chapterJSON.put("show", show);
|
||||
PeerAtUser user = context.getUser();
|
||||
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);
|
||||
if(show){
|
||||
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);
|
||||
}
|
||||
chapterJSON.put("puzzles", puzzles);
|
||||
context.response(200);
|
||||
writer.write(chapterJSON.toJSONString());
|
||||
} else {
|
||||
|
|
|
@ -35,10 +35,7 @@ public class ChapterList implements Response {
|
|||
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());
|
||||
chapterJSON.put("show", chapter.isInCurrentTime());
|
||||
chaptersJSON.add(chapterJSON);
|
||||
}
|
||||
context.response(200);
|
||||
|
|
|
@ -16,9 +16,9 @@ public class DynamicLeaderboard extends Leaderboard{
|
|||
|
||||
private Locker<Completion> locker;
|
||||
|
||||
public DynamicLeaderboard(DatabaseRepository databaseRepo){
|
||||
public DynamicLeaderboard(DatabaseRepository databaseRepo, Locker<Completion> locker){
|
||||
super(databaseRepo);
|
||||
this.locker = new Locker<>();
|
||||
this.locker = locker;
|
||||
}
|
||||
|
||||
public Locker<Completion> getLocker(){
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
package dev.peerat.backend.routes;
|
||||
|
||||
import static dev.peerat.framework.RequestType.POST;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
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.Router;
|
||||
|
||||
public class MailConfirmation implements Response {
|
||||
|
||||
private DatabaseRepository databaseRepo;
|
||||
private Router<PeerAtUser> router;
|
||||
private String usersFilesPath;
|
||||
private Map<Player, Integer> playersWaiting;
|
||||
|
||||
public MailConfirmation(DatabaseRepository databaseRepo, Router<PeerAtUser> router, String initUsersFilesPath,
|
||||
Map<Player, Integer> playersWaiting) {
|
||||
this.databaseRepo = databaseRepo;
|
||||
this.router = router;
|
||||
usersFilesPath = initUsersFilesPath;
|
||||
}
|
||||
|
||||
@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.getUser() != null) {
|
||||
context.response(403);
|
||||
return;
|
||||
}
|
||||
JSONObject informations = reader.readJson();
|
||||
if (informations != null) {
|
||||
boolean allNecessaryFieldsFilled = informations.containsKey("email") && informations.containsKey("code")
|
||||
&& informations.containsKey("passwd");
|
||||
if (!allNecessaryFieldsFilled) {
|
||||
context.response(400);
|
||||
return;
|
||||
}
|
||||
String email = (String) informations.get("email");
|
||||
String password = (String) informations.get("passwd");
|
||||
int code = (int) informations.get("code");
|
||||
|
||||
Player newPlayer = getPlayerFromEmail(email);
|
||||
if (newPlayer != null && code == playersWaiting.get(newPlayer)) {
|
||||
String pseudo = newPlayer.getPseudo();
|
||||
int id;
|
||||
if ((id = databaseRepo.register(pseudo, email, password, newPlayer.getFirstname(), newPlayer.getLastname(), "", "", "")) >= 0) {
|
||||
context.response(200, "Access-Control-Expose-Headers: Authorization",
|
||||
"Authorization: Bearer " + this.router.createAuthUser(new PeerAtUser(id)));
|
||||
createFolderToSaveSourceCode(pseudo);
|
||||
return;
|
||||
} else {
|
||||
context.response(400);
|
||||
JSONObject error = new JSONObject();
|
||||
error.put("username_valid", pseudo);
|
||||
error.put("email_valid", email);
|
||||
writer.write(error.toJSONString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
context.response(400);
|
||||
}
|
||||
|
||||
private void createFolderToSaveSourceCode(String pseudo) throws IOException {
|
||||
|
||||
Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo)));
|
||||
}
|
||||
|
||||
private Player getPlayerFromEmail(String email) {
|
||||
Player toMatch = new Player(email);
|
||||
for (Player p: playersWaiting.keySet()) {
|
||||
if (p.equals(toMatch)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
56
src/dev/peerat/backend/routes/admins/DynamicLogs.java
Normal file
56
src/dev/peerat/backend/routes/admins/DynamicLogs.java
Normal file
|
@ -0,0 +1,56 @@
|
|||
package dev.peerat.backend.routes.admins;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Route(path = "^/admin/logs$", needLogin = true, 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()){
|
||||
Context instance = locker.getValue(key);
|
||||
JSONObject json = new JSONObject();
|
||||
json.put("logged", instance.isLogged());
|
||||
if(instance.isLogged()) json.put("pseudo", repo.getPlayer(instance.<PeerAtUser>getUser().getId()).getPseudo());
|
||||
json.put("path", instance.getPath());
|
||||
json.put("type", instance.getType());
|
||||
json.put("code", instance.getResponseCode());
|
||||
|
||||
writer.write(json.toJSONString());
|
||||
writer.flush();
|
||||
locker.lock(key);
|
||||
}
|
||||
}catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
locker.remove(key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
36
src/dev/peerat/backend/routes/users/ChangePassword.java
Normal file
36
src/dev/peerat/backend/routes/users/ChangePassword.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
package dev.peerat.backend.routes.users;
|
||||
|
||||
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.RequestType;
|
||||
import dev.peerat.framework.Response;
|
||||
import dev.peerat.framework.Route;
|
||||
|
||||
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 = (String) reader.<JSONObject>readJson().get("password");
|
||||
|
||||
repo.updatePassword(context.<PeerAtUser>getUser().getId(), password);
|
||||
context.response(200);
|
||||
}
|
||||
|
||||
}
|
25
src/dev/peerat/backend/routes/users/ForgotPassword.java
Normal file
25
src/dev/peerat/backend/routes/users/ForgotPassword.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package dev.peerat.backend.routes.users;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
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 ForgotPassword implements Response{
|
||||
|
||||
@Route(path = "^/user/fpw$")
|
||||
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
|
||||
if(context.isLogged()){
|
||||
context.response(403);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.peerat.backend.routes;
|
||||
package dev.peerat.backend.routes.users;
|
||||
|
||||
import static dev.peerat.framework.RequestType.POST;
|
||||
|
||||
|
@ -9,19 +9,19 @@ import org.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.Response;
|
||||
import dev.peerat.framework.Route;
|
||||
import dev.peerat.framework.Router;
|
||||
|
||||
public class Login implements Response {
|
||||
public class Login extends FormResponse{
|
||||
|
||||
private DatabaseRepository databaseRepo;
|
||||
private Router<PeerAtUser> router;
|
||||
|
||||
public Login(DatabaseRepository databaseRepo, Router<PeerAtUser> router) {
|
||||
public Login(DatabaseRepository databaseRepo, Router<PeerAtUser> router){
|
||||
this.databaseRepo = databaseRepo;
|
||||
this.router = router;
|
||||
}
|
||||
|
@ -32,23 +32,23 @@ public class Login implements Response {
|
|||
|
||||
@Route(path = "^\\/login$", type = POST)
|
||||
public void exec(Matcher matcher, Context context, HttpReader reader, HttpWriter writer) throws Exception {
|
||||
if (context.getUser() != null) {
|
||||
if(context.isLogged()){
|
||||
context.response(403);
|
||||
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) {
|
||||
context.response(200,
|
||||
"Access-Control-Expose-Headers: Authorization",
|
||||
"Authorization: Bearer " + this.router.createAuthUser(new PeerAtUser(id)));
|
||||
return;
|
||||
}
|
||||
JSONObject json = json(reader);
|
||||
if(!areValids("pseudo", "passwd")){
|
||||
context.response(400);
|
||||
return;
|
||||
}
|
||||
int id;
|
||||
if((id = databaseRepo.login((String)json.get("pseudo"), (String)json.get("passwd"))) >= 0){
|
||||
context.response(200,
|
||||
"Access-Control-Expose-Headers: Authorization",
|
||||
"Authorization: Bearer " + this.router.createAuthUser(new PeerAtUser(id)));
|
||||
}else{
|
||||
context.response(400);
|
||||
}
|
||||
context.response(400);
|
||||
}
|
||||
|
||||
}
|
156
src/dev/peerat/backend/routes/users/MailConfirmation.java
Normal file
156
src/dev/peerat/backend/routes/users/MailConfirmation.java
Normal file
|
@ -0,0 +1,156 @@
|
|||
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.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
import java.util.Base64.Encoder;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
|
||||
import org.json.simple.JSONAware;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
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.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;
|
||||
|
||||
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<Player, Integer> playersWaiting;
|
||||
|
||||
public MailConfirmation(
|
||||
DatabaseRepository databaseRepo,
|
||||
Router<PeerAtUser> router,
|
||||
String initUsersFilesPath,
|
||||
String gitToken,
|
||||
Map<Player, Integer> playersWaiting){
|
||||
this.databaseRepo = databaseRepo;
|
||||
this.router = router;
|
||||
usersFilesPath = initUsersFilesPath;
|
||||
this.gitToken = gitToken;
|
||||
try {
|
||||
generator = KeyPairGenerator.getInstance("RSA");
|
||||
generator.initialize(2048); //a changer ?
|
||||
} 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;
|
||||
}
|
||||
JSONObject json = json(reader);
|
||||
if(!areValids("email","code","passwd")){
|
||||
context.response(400);
|
||||
return;
|
||||
}
|
||||
String email = (String) json.get("email");
|
||||
String password = (String) json.get("passwd");
|
||||
int code = (int) json.get("code");
|
||||
|
||||
Player newPlayer = getPlayerFromEmail(email);
|
||||
if (newPlayer != null && code == playersWaiting.get(newPlayer)){
|
||||
playersWaiting.remove(newPlayer);
|
||||
String pseudo = newPlayer.getPseudo();
|
||||
int id;
|
||||
if ((id = databaseRepo.register(pseudo, email, password, newPlayer.getFirstname(), newPlayer.getLastname(), "", "", "")) >= 0) {
|
||||
context.response(200,
|
||||
"Access-Control-Expose-Headers: Authorization",
|
||||
"Authorization: Bearer " + this.router.createAuthUser(new PeerAtUser(id)));
|
||||
createFolderToSaveSourceCode(pseudo);
|
||||
generateGitKey(email, pseudo, password);
|
||||
return;
|
||||
} else {
|
||||
context.response(400);
|
||||
JSONObject error = new JSONObject();
|
||||
error.put("username_valid", pseudo);
|
||||
error.put("email_valid", email);
|
||||
writer.write(error.toJSONString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
context.response(400);
|
||||
}
|
||||
|
||||
private void createFolderToSaveSourceCode(String pseudo) throws IOException {
|
||||
|
||||
Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo)));
|
||||
}
|
||||
|
||||
private Player getPlayerFromEmail(String email) {
|
||||
Player toMatch = new Player(email);
|
||||
for (Player p: playersWaiting.keySet()) {
|
||||
if (p.equals(toMatch)) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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();
|
||||
sendKey.put("key", new String(encoder.encode(pair.getPrivate().getEncoded()))); //add ssh-rsa au début ?
|
||||
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);
|
||||
}
|
||||
}
|
58
src/dev/peerat/backend/routes/users/ProfileSettings.java
Normal file
58
src/dev/peerat/backend/routes/users/ProfileSettings.java
Normal file
|
@ -0,0 +1,58 @@
|
|||
package dev.peerat.backend.routes.users;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
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;
|
||||
|
||||
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 {
|
||||
JSONObject json = reader.readJson();
|
||||
|
||||
String pseudo = (String) json.get("pseudo");
|
||||
String email = (String) json.get("email");
|
||||
String firstname = (String) json.get("firstname");
|
||||
String lastname = (String) 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);
|
||||
}
|
||||
|
||||
}
|
74
src/dev/peerat/backend/routes/users/Register.java
Normal file
74
src/dev/peerat/backend/routes/users/Register.java
Normal file
|
@ -0,0 +1,74 @@
|
|||
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 org.json.simple.JSONObject;
|
||||
|
||||
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.backend.utils.FormResponse;
|
||||
import dev.peerat.framework.Context;
|
||||
import dev.peerat.framework.HttpReader;
|
||||
import dev.peerat.framework.HttpWriter;
|
||||
import dev.peerat.framework.Route;
|
||||
|
||||
public class Register extends FormResponse {
|
||||
|
||||
private DatabaseRepository databaseRepo;
|
||||
private Map<Player, Integer> playersWaiting;
|
||||
|
||||
public Register(DatabaseRepository databaseRepo, Map<Player, Integer> playersWaiting){
|
||||
this.databaseRepo = databaseRepo;
|
||||
this.playersWaiting = playersWaiting;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
JSONObject json = json(reader);
|
||||
if(!areValids("pseudo","email","firstname","lastname")){
|
||||
context.response(400);
|
||||
return;
|
||||
}
|
||||
|
||||
String pseudo = (String) json.get("pseudo");
|
||||
String email = (String) json.get("email");
|
||||
String firstname = (String) json.get("firstname");
|
||||
String lastname = (String) json.get("lastname");
|
||||
|
||||
boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo);
|
||||
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
|
||||
if(pseudoAvailable && emailAvailable){
|
||||
Player player = new Player(pseudo, email, firstname, lastname);
|
||||
playersWaiting.put(player, codeGenerator());
|
||||
context.response(200);
|
||||
}else{
|
||||
context.response(400);
|
||||
JSONObject error = new JSONObject();
|
||||
error.put("username_valid", pseudoAvailable);
|
||||
error.put("email_valid", emailAvailable);
|
||||
writer.write(error.toJSONString());
|
||||
}
|
||||
}
|
||||
|
||||
private int codeGenerator() {
|
||||
int min = 1000;
|
||||
int max = 9999;
|
||||
return new Random().nextInt((max-min)) + min;
|
||||
|
||||
}
|
||||
|
||||
}
|
49
src/dev/peerat/backend/utils/FormResponse.java
Normal file
49
src/dev/peerat/backend/utils/FormResponse.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package dev.peerat.backend.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.json.simple.JSONAware;
|
||||
|
||||
import dev.peerat.framework.HttpReader;
|
||||
import dev.peerat.framework.Response;
|
||||
|
||||
public abstract class FormResponse implements Response{
|
||||
|
||||
private JSONAware 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 JSONAware> T json(HttpReader reader) throws Exception{
|
||||
return (T) (this.json = reader.readJson());
|
||||
}
|
||||
|
||||
public boolean hasFields(String... fields){
|
||||
Map<?,?> map = (Map<?,?>)json;
|
||||
for(String field : fields){
|
||||
if(!map.containsKey(field)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean areValids(String... fields){
|
||||
Map<?,?> map = (Map<?,?>)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;
|
||||
}
|
||||
}
|
|
@ -42,8 +42,8 @@ public class Mail {
|
|||
msg.addHeader("format", "flowed");
|
||||
msg.addHeader("Content-Transfer-Encoding", "8bit");
|
||||
|
||||
msg.setFrom(new InternetAddress("ping@peerat.dev", "NoReply-JD"));
|
||||
msg.setReplyTo(InternetAddress.parse("ping@peerat.dev", false));
|
||||
msg.setFrom(new InternetAddress(fromAddress, "NoReply-JD"));
|
||||
msg.setReplyTo(InternetAddress.parse(fromAddress, false));
|
||||
msg.setSubject(subject, "UTF-8");
|
||||
msg.setText(text, "UTF-8");
|
||||
msg.setSentDate(new Date());
|
||||
|
|
64
test/dev/peerat/backend/TestDatabaseRepository.java
Normal file
64
test/dev/peerat/backend/TestDatabaseRepository.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package dev.peerat.backend.webclient;
|
||||
package dev.peerat.backend;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
|
@ -9,7 +9,7 @@ import org.junit.jupiter.api.TestInstance;
|
|||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import dev.peerat.backend.Main;
|
||||
import dev.peerat.backend.webclient.WebClient;
|
||||
import dev.peerat.backend.WebClient;
|
||||
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
class PlayerDetailsTests {
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.junit.jupiter.api.TestInstance;
|
|||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import dev.peerat.backend.Main;
|
||||
import dev.peerat.backend.webclient.WebClient;
|
||||
import dev.peerat.backend.WebClient;
|
||||
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
public class ScoreTests {
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.junit.jupiter.api.TestInstance;
|
|||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import dev.peerat.backend.Main;
|
||||
import dev.peerat.backend.webclient.WebClient;
|
||||
import dev.peerat.backend.WebClient;
|
||||
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
public class TmpRoutesTests {
|
||||
|
|
|
@ -9,7 +9,7 @@ import org.junit.jupiter.api.TestInstance;
|
|||
import org.junit.jupiter.api.TestInstance.Lifecycle;
|
||||
|
||||
import dev.peerat.backend.Main;
|
||||
import dev.peerat.backend.webclient.WebClient;
|
||||
import dev.peerat.backend.WebClient;
|
||||
|
||||
@TestInstance(Lifecycle.PER_CLASS)
|
||||
public class TriggerTests {
|
||||
|
|
30
test/dev/peerat/backend/userstories/BaseUserStoriesTest.java
Normal file
30
test/dev/peerat/backend/userstories/BaseUserStoriesTest.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
79
test/dev/peerat/backend/userstories/LoginTests.java
Normal file
79
test/dev/peerat/backend/userstories/LoginTests.java
Normal 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);
|
||||
}
|
||||
}
|
90
test/dev/peerat/backend/userstories/RegisterTests.java
Normal file
90
test/dev/peerat/backend/userstories/RegisterTests.java
Normal file
|
@ -0,0 +1,90 @@
|
|||
package dev.peerat.backend.userstories;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
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", new JSONObject().toJSONString());
|
||||
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);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue