194 lines
6.8 KiB
Java
194 lines
6.8 KiB
Java
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.Random;
|
|
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.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.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;
|
|
private Mail mail;
|
|
|
|
public MailConfirmation(
|
|
DatabaseRepository databaseRepo,
|
|
Router<PeerAtUser> router,
|
|
String initUsersFilesPath,
|
|
String gitToken,
|
|
Map<String, Integer> playersWaiting,
|
|
Mail mail){
|
|
this.databaseRepo = databaseRepo;
|
|
this.router = router;
|
|
this.usersFilesPath = initUsersFilesPath;
|
|
this.gitToken = gitToken;
|
|
this.playersWaiting = playersWaiting;
|
|
this.mail = mail;
|
|
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;
|
|
}
|
|
|
|
boolean pseudoAvailable = databaseRepo.checkPseudoAvailability(pseudo);
|
|
boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
|
|
if(pseudoAvailable && emailAvailable){
|
|
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());
|
|
int ncode = codeGenerator();
|
|
playersWaiting.put(email, ncode);
|
|
mail.send(email, "Welcome @ Peer @ Code", "Your check code is "+ncode+" !");
|
|
}
|
|
}else{
|
|
context.response(400);
|
|
}
|
|
}else{
|
|
context.response(400);
|
|
JsonMap error = new JsonMap();
|
|
error.set("username_valid", pseudo);
|
|
error.set("email_valid", email);
|
|
writer.write(error.toString());
|
|
}
|
|
}
|
|
|
|
private int codeGenerator(){
|
|
int min = 1000;
|
|
int max = 9999;
|
|
return new Random().nextInt((max-min)) + min;
|
|
|
|
}
|
|
|
|
private void createFolderToSaveSourceCode(String pseudo) throws IOException {
|
|
|
|
Files.createDirectories(Paths.get(String.format("%s/%s", usersFilesPath, pseudo)));
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|