package cpe.hapa;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.simple.JSONObject;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.taskqueue.Queue;
import com.google.appengine.api.taskqueue.QueueFactory;
import com.google.appengine.api.taskqueue.TaskOptions;
import com.google.appengine.api.taskqueue.TaskOptions.Method;
import com.google.appengine.labs.repackaged.org.json.JSONArray;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import cpe.hapa.authentication.Authenticate;
import cpe.hapa.authentication.SessionHandler;
import cpe.hapa.dao.RoleDAO;
import cpe.hapa.dao.UserDAO;
import cpe.hapa.model.User;
/**
* Servlet implementation class InscriptionServlet
* TODO CRON QUI CHECK LES SESSIONS
*/
public class UserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public UserServlet() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
switch(request.getParameter("cmd")) {
case "listeUser":
listUser(request,response);
break;
case "userDetails":
userDetails(request,response);
break;
case "authenticationInfos":
authenticationInfos(request,response);
break;
case "checkAllSessions":
try {
SessionHandler.checkAllSessions();
} catch (NumberFormatException | ParseException | EntityNotFoundException e) {
throw new ServletException(e);
}
break;
default:
throw new ServletException("Cette commande n'existe pas");
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
switch(request.getParameter("cmd")) {
case "register" :
register(request, response);
response.getWriter().print("{\"success\":\"Utilisateur ajouté\"}");
break;
case "addUser" :
adminRegister(request, response);
break;
case "addUserQueue" :
addUserQueue(request, response);
response.getWriter().print("{\"redirect\":\"userAdministration.html\"}");
break;
case "login":
// voir les redirections dans la méthode login
login(request, response);
break;
case "changePassword":
changePassword(request, response);
break;
case "disconnect":
try {
Authenticate.disconnect(request);
} catch (NumberFormatException | ParseException | EntityNotFoundException e) {
throw new ServletException("La déconnexion a échoué", e);
}
response.getWriter().print("{\"redirect\":\"index.html\"}");
break;
default:
throw new ServletException("Cette commande n'existe pas");
}
}
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException
{
switch(req.getParameter("cmd")) {
case "deleteUser" :
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
String test = req.getParameter("id");
Key deleteKey = KeyFactory.stringToKey(test);
datastore.delete(deleteKey);
break;
case "deleteUserQueue" :
Queue queue = QueueFactory.getDefaultQueue();
TaskOptions task = TaskOptions.Builder.withUrl("/user?cmd=deleteUser&id=" + req.getParameter("id")).method(Method.DELETE);
queue.add(task);
break;
default:
throw new ServletException("Cette commande n'existe pas");
}
}
/* *******************************
* =============================
* COMMANDES ET SOUS-METHODES
* =============================
* ********************************/
private void changePassword(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
User user = null;
try {
user = Authenticate.getConnectedUser(request);
} catch(Exception e) {
throw new ServletException(e);
}
if(user == null) {
response.getWriter().print("{\"redirect\":\"index.html\"}");
} else {
String oldPassword = request.getParameter("oldPassword");
String newPassword = request.getParameter("newPassword");
String newPassword2 = request.getParameter("newPassword2");
if(user.getPassword().equals(oldPassword)) {
if(newPassword != null && !newPassword.isEmpty() && newPassword.equals(newPassword2)) {
try {
user.setPassword(newPassword);
user.setIsPasswordChanged(true);
UserDAO.update(user);
} catch (Exception e) {
throw new ServletException(e);
}
response.getWriter().print("{\"redirect\":\"home.html\"}");
} else {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,"Pas de nouveau mot de passe ou la confirmation du nouveau mot de passe n'est pas correcte");
}
} else {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,"Le mot de passe actuel ne correspond pas");
}
}
}
private void authenticationInfos(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {
Boolean connected = false;
String authInfos = "";
try {
User user = Authenticate.getConnectedUser(request);
if(user != null) {
connected = true;
String redirect = null;
if(user.isPasswordChanged()) {
redirect = "userDetails.html";
} else {
redirect = "changePassword.html";
}
authInfos = ","
+ "\"redirect\":\"" + redirect + "\","
+ "\"duration\":" + (int) (user.getDureeConnexion()/60) + ","
+ "\"role\":\"" + user.getRole() + "\","
+ "\"username\":\"" + user.getPrenom() + " " + user.getNom() + "\","
+ "\"lastConnection\":\"" + new SimpleDateFormat("dd/MM/yyyy hh:mm").format(user.getDateConnexion()) + "\"";
}
response.getWriter().print("{"+
"\"connected\":" + connected + ","
+ "\"nbUserConnected\":" + SessionHandler.getTotalActiveSession()
+ authInfos + "}"
);
} catch(Exception e) {
throw new ServletException(e);
}
}
protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {
// TODO : vérifier que login est unique
String nom = request.getParameter("nom");
String prenom = request.getParameter("prenom");
String dateNaissance = request.getParameter("dateNaissance");
String email = request.getParameter("email");
String login = request.getParameter("login");
String role = RoleDAO.getUserRole();
String isPasswordChanged = "false";
String creationDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
User user = null;
String password = UUID.randomUUID().toString().substring(0, 9);
try {
if(UserDAO.count()==0) {
role = RoleDAO.getAdminRole();
}
user = this.checkAndInstantiateUserModel(nom, prenom, dateNaissance, email, login, password, role, isPasswordChanged, null, null, creationDate);
} catch(ParseException e) {
throw new ServletException(e);
}
if (user != null) {
UserDAO.addUser(user);
sendMailForAuth(user);
} else {
throw new ServletException("Données du formulaire incorrectes");
}
}
private void adminRegister(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
// TODO : vérifier que login est unique
String nom = request.getParameter("nom");
String prenom = request.getParameter("prenom");
String dateNaissance = request.getParameter("dateNaissance");
String email = request.getParameter("email");
String login = request.getParameter("login");
String role = request.getParameter("role");
String isPasswordChanged = "false";
String creationDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
User user = null;
String password = request.getParameter("password");
String rePassword = request.getParameter("password2");
if(password == null || !password.equals(rePassword)) {
throw new ServletException("Les mots de passe ne sont pas corrects");
}
try {
user = this.checkAndInstantiateUserModel(nom, prenom, dateNaissance, email, login, password, role, isPasswordChanged, null, null, creationDate);
} catch (ParseException e) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,e.getMessage());
}
if (user != null) {
UserDAO.addUser(user);
sendMailForAuth(user);
} else {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,"Données du formulaire incorrectes");
}
}
private void addUserQueue(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
User connectedUser = null;
try {
connectedUser = Authenticate.getConnectedUser(request);
} catch (NumberFormatException | ParseException e) {
throw new ServletException(e);
}
if( !(connectedUser != null && connectedUser.isInRole(RoleDAO.getAdminRole())) ) {
throw new ServletException("Vous n'êtes pas administrateur, vous ne pouvez pas ajouter d'utilisateur");
}
String nom = request.getParameter("nom");
String prenom = request.getParameter("prenom");
String dateNaissance = request.getParameter("dateNaissance");
String email = request.getParameter("email");
String login = request.getParameter("login");
String role = request.getParameter("role");
String password = request.getParameter("password");
String rePassword = request.getParameter("password2");
try {
checkAndInstantiateUserModel(nom, prenom, dateNaissance, email, login, password, role, "false", null, null,"01-01-2013");
if(password == null || password.trim().isEmpty() || !password.equals(rePassword)) {
throw new ParseException("Les mots de passe ne sont pas corrects", 0);
}
} catch (ParseException e) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST,e.getMessage());
}
Queue queue = QueueFactory.getDefaultQueue();
TaskOptions task=TaskOptions.Builder.withUrl("/user")
.param("cmd", "addUser")
.param("nom", request.getParameter("nom"))
.param("prenom", request.getParameter("prenom"))
.param("dateNaissance", request.getParameter("dateNaissance"))
.param("email", request.getParameter("email"))
.param("login", request.getParameter("login"))
.param("password", request.getParameter("password"))
.param("password2", request.getParameter("password2"))
.param("role", request.getParameter("role"));
queue.add(task);
}
protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException {
String login = request.getParameter("login");
String password = request.getParameter("password");
User user = null;
try {
if(!Authenticate.authenticate(request, login, password)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN,"Mauvais login et/ou mot de passe");
} else {
user = Authenticate.getConnectedUser(request);
if(!user.isPasswordChanged()) {
response.getWriter().print("{\"redirect\":\"changePassword.html\"}");
} else {
response.getWriter().print("{\"redirect\":\"userDetails.html\"}");
}
}
} catch(Exception e) {
throw new ServletException("Échec de l'authentification pour une raison inconnue : " + e.getMessage(),e);
}
}
protected void listUser(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
JSONArray userList = new JSONArray();
for(User result : UserDAO.getAll())
{
JSONObject user = new JSONObject();
user.put("id", KeyFactory.keyToString(result.getKey()));
user.put("nom", result.getNom());
user.put("prenom", result.getPrenom());
user.put("dateNaissance", result.getDateNaissance());
user.put("email", result.getEmail());
user.put("login", result.getLogin());
user.put("role", result.getRole());
user.put("dateCreation", result.getDateCreation());
user.put("lastConnection", result.getDateConnexion());
user.put("duration", result.getDureeConnexion());
userList.put(user);
}
response.getWriter().print(userList);
} catch (NumberFormatException | ParseException e) {
e.printStackTrace();
}
}
private void userDetails(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
User user = null;
try {
user = Authenticate.getConnectedUser(request);
} catch (NumberFormatException | ParseException e) {
throw new ServletException(e);
}
if(user == null) {
throw new ServletException("Vous n'êtes pas/plus connecté");
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");
JSONObject jsonUser = new JSONObject();
jsonUser.put("id", KeyFactory.keyToString(user.getKey()));
jsonUser.put("nom", user.getNom());
jsonUser.put("prenom", user.getPrenom());
jsonUser.put("dateNaissance", simpleDateFormat.format(user.getDateNaissance()));
jsonUser.put("email", user.getEmail());
jsonUser.put("login", user.getLogin());
jsonUser.put("dateCreation", simpleDateFormat.format(user.getDateCreation()));
if(user.getDateConnexion() != null) {
jsonUser.put("lastConnection", simpleDateFormat.format(user.getDateConnexion()));
}
jsonUser.put("duration", user.getDureeConnexion());
response.getWriter().print(jsonUser);
}
protected User checkAndInstantiateUserModel(String nom,String prenom,String dateNaissance,String email,String login,String password,String role,String isPasswordChanged,String dateConnexion,String dureeConnexion,String dateCreation) throws ParseException, ServletException {
User user = null;
if ( nom != null &&
prenom != null &&
dateNaissance != null &&
email != null &&
login != null &&
password != null &&
role != null &&
isPasswordChanged != null &&
!nom.isEmpty() &&
!prenom.isEmpty() &&
!dateNaissance.isEmpty() &&
!email.isEmpty() &&
!login.isEmpty() &&
!password.isEmpty() &&
!role.isEmpty() &&
!isPasswordChanged.isEmpty())
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
user = new User(
null,
nom,
prenom,
sdf.parse(dateNaissance),
email,
login,
password,
role,
Boolean.valueOf(isPasswordChanged),
(dateConnexion != null ? new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").parse(dateConnexion) : null),
(dureeConnexion != null ? Long.valueOf(dureeConnexion) : null),
sdf.parse(dateCreation)
);
} else {
throw new ServletException("Données fournies incorrectes");
}
return user;
}
private void sendMailForAuth(User user) throws ServletException {
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
String msgBody = "Bonjour,"
+ "\n\nJe te fais part de tes informations d'authentification suite à ta demande de création de compte sur VolsCPE:"
+ "\n\nlogin: " + user.getLogin() + ""
+ "\nMot de passe: " + user.getPassword() + ""
+ "\n\nA bientôt sur VolsCPE!" + ""
+ "\nhttp://reservation-vole-cpe.appspot.com/";
try {
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("donotreply@reservation-vole-cpe.appspotmail.com", "reservation-vole-cpe.appspotmail.com Admin"));
msg.addRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail(), user.getPrenom() + " " + user.getNom()));
msg.setSubject("VoyageCPE - Ton compte peut décoller!");
msg.setText(msgBody);
Transport.send(msg);
} catch (AddressException e) {
throw new ServletException(e);
} catch (MessagingException | UnsupportedEncodingException e) {
throw new ServletException(e);
}
}
}