diff --git a/.classpath b/.classpath
index 8eb78c7..dc62fe9 100644
--- a/.classpath
+++ b/.classpath
@@ -1,6 +1,10 @@
-
+
+
+
+
+
@@ -13,5 +17,8 @@
+
+
+
diff --git a/.gitignore b/.gitignore
index c5a661b..38fb1c2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ config.txt
dist/
testApi/
.apt_generated/*
+/.apt_generated/
diff --git a/angus-activation-2.0.1.jar b/angus-activation-2.0.1.jar
new file mode 100644
index 0000000..9d56221
Binary files /dev/null and b/angus-activation-2.0.1.jar differ
diff --git a/jakarta.activation-api-2.1.2.jar b/jakarta.activation-api-2.1.2.jar
new file mode 100644
index 0000000..ea57b3e
Binary files /dev/null and b/jakarta.activation-api-2.1.2.jar differ
diff --git a/jakarta.mail-2.0.2.jar b/jakarta.mail-2.0.2.jar
new file mode 100644
index 0000000..7192cb2
Binary files /dev/null and b/jakarta.mail-2.0.2.jar differ
diff --git a/src/dev/peerat/backend/Configuration.java b/src/dev/peerat/backend/Configuration.java
index 41c3bf9..8e05047 100644
--- a/src/dev/peerat/backend/Configuration.java
+++ b/src/dev/peerat/backend/Configuration.java
@@ -7,6 +7,8 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.lang.reflect.Field;
+import dev.peerat.backend.utils.Mail;
+
public class Configuration {
private String db_host;
@@ -29,6 +31,12 @@ public class Configuration {
private int groupJoinMinutes;
private String groupQuitMinutes;
+
+ private String mailUsername;
+ private String mailPassword;
+ private String mailSmtpHost;
+ private int mailSmptPort;
+ private String mailFromAddress;
private File file;
@@ -173,4 +181,13 @@ public class Configuration {
public String getGroupQuitMinutes(){
return this.groupQuitMinutes;
}
+
+ public Mail getMail(){
+ return new Mail(
+ this.mailUsername,
+ this.mailPassword,
+ this.mailSmtpHost,
+ this.mailSmptPort,
+ this.mailFromAddress);
+ }
}
\ No newline at end of file
diff --git a/src/dev/peerat/backend/Main.java b/src/dev/peerat/backend/Main.java
index 37f4d46..03e1806 100644
--- a/src/dev/peerat/backend/Main.java
+++ b/src/dev/peerat/backend/Main.java
@@ -2,11 +2,14 @@ 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.model.Completion;
import dev.peerat.backend.model.Group;
import dev.peerat.backend.model.PeerAtUser;
+import dev.peerat.backend.model.Player;
import dev.peerat.backend.repository.DatabaseRepository;
import dev.peerat.backend.routes.BadgeDetails;
import dev.peerat.backend.routes.ChapterElement;
@@ -14,6 +17,7 @@ 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;
@@ -23,6 +27,7 @@ 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.framework.Context;
import dev.peerat.framework.HttpReader;
import dev.peerat.framework.HttpWriter;
@@ -80,10 +85,12 @@ public class Main{
}
private static void initRoutes(Router router, DatabaseRepository repo, Configuration config){
+ Map playersWaiting = new HashMap<>();
router.register(new ChapterElement(repo));
router.register(new ChapterList(repo));
router.register(new PuzzleElement(repo));
- router.register(new Register(repo, router, config.getUsersFiles()));
+ 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));
diff --git a/src/dev/peerat/backend/model/Player.java b/src/dev/peerat/backend/model/Player.java
index 1793077..53d5575 100644
--- a/src/dev/peerat/backend/model/Player.java
+++ b/src/dev/peerat/backend/model/Player.java
@@ -22,12 +22,12 @@ public class Player implements Comparable {
private Set 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.email = email;
this.firstname = firstname;
this.lastname = lastname;
- this.description = description;
+ this.description = "";
}
public Player(String pseudo, int score, int tries) {
@@ -36,6 +36,11 @@ public class Player implements Comparable {
this.completions.add(new Completion(tries, score));
email = ""; // TO make compareTo and equals works as usual
}
+
+ public Player(String email) {
+ // For player find in Map during register process
+ this.email = email;
+ }
public String getPseudo() {
return this.pseudo;
diff --git a/src/dev/peerat/backend/repository/DatabaseRepository.java b/src/dev/peerat/backend/repository/DatabaseRepository.java
index 6c51183..259fa88 100644
--- a/src/dev/peerat/backend/repository/DatabaseRepository.java
+++ b/src/dev/peerat/backend/repository/DatabaseRepository.java
@@ -129,8 +129,7 @@ public class DatabaseRepository {
private Player makePlayer(ResultSet playerResult, int id) throws SQLException {
Player p = new Player(playerResult.getString("pseudo"), playerResult.getString("email"),
- playerResult.getString("firstName"), playerResult.getString("lastName"),
- playerResult.getString("description"));
+ playerResult.getString("firstName"), playerResult.getString("lastName"));
if (hasColumn(playerResult, "avatar")) {
p.setAvatar(playerResult.getBytes("avatar"));
}
diff --git a/src/dev/peerat/backend/routes/MailConfirmation.java b/src/dev/peerat/backend/routes/MailConfirmation.java
new file mode 100644
index 0000000..62ca4a3
--- /dev/null
+++ b/src/dev/peerat/backend/routes/MailConfirmation.java
@@ -0,0 +1,96 @@
+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 router;
+ private String usersFilesPath;
+ private Map playersWaiting;
+
+ public MailConfirmation(DatabaseRepository databaseRepo, Router router, String initUsersFilesPath,
+ Map 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;
+ }
+}
diff --git a/src/dev/peerat/backend/routes/Register.java b/src/dev/peerat/backend/routes/Register.java
index f8968e6..782a9a2 100644
--- a/src/dev/peerat/backend/routes/Register.java
+++ b/src/dev/peerat/backend/routes/Register.java
@@ -5,12 +5,16 @@ import static dev.peerat.framework.RequestType.POST;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
+import java.util.HashMap;
+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.framework.Context;
import dev.peerat.framework.HttpReader;
@@ -24,69 +28,62 @@ public class Register implements Response {
private DatabaseRepository databaseRepo;
private Router router;
private String usersFilesPath;
+ private Map playersWaiting;
- public Register(DatabaseRepository databaseRepo, Router router, String initUsersFilesPath) {
+ public Register(DatabaseRepository databaseRepo, Router router, String initUsersFilesPath,
+ Map playersWaiting) {
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, Context context, HttpReader reader, HttpWriter writer) throws Exception{
- if (context.getUser() != null){
+ 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 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) {
- context.response(403);
+ boolean allNecessaryFieldsFilled = informations.containsKey("pseudo") && informations.containsKey("email")
+ && informations.containsKey("firstname") && informations.containsKey("lastname");
+ if (!allNecessaryFieldsFilled) {
+ context.response(400);
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) {
- context.response(200,
- "Access-Control-Expose-Headers: Authorization",
- "Authorization: Bearer " + this.router.createAuthUser(new PeerAtUser(id)));
- createFolderToSaveSourceCode(pseudo);
- return;
- }
+ 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());
- return;
+
}
+ return;
}
context.response(400);
}
- private void createFolderToSaveSourceCode(String pseudo) throws IOException {
+ private int codeGenerator() {
+ int min = 1000;
+ int max = 9999;
+ return new Random().nextInt((max-min)) + min;
- Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo)));
}
}
diff --git a/src/dev/peerat/backend/utils/Mail.java b/src/dev/peerat/backend/utils/Mail.java
new file mode 100644
index 0000000..b6e1137
--- /dev/null
+++ b/src/dev/peerat/backend/utils/Mail.java
@@ -0,0 +1,58 @@
+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() {
+ //override the getPasswordAuthentication method
+ 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("ping@peerat.dev", "NoReply-JD"));
+ msg.setReplyTo(InternetAddress.parse("ping@peerat.dev", 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();
+ }
+ }
+}