diff --git a/src/web/handlers.py b/src/web/handlers.py
index b3259fdb..80c4884a 100644
--- a/src/web/handlers.py
+++ b/src/web/handlers.py
@@ -489,6 +489,90 @@ def get(self):
self.finish()
+class ProfileCmdPasswordHandler(jsonhandler.JsonHandler):
+ @tornado.web.asynchronous
+ def post(self):
+ if self._global_arg["disable_login"]:
+ # Not Found
+ self.set_status(404)
+ self.send_error(404)
+ raise tornado.web.Finish()
+
+ # Be sure the user is connected
+ current_user = self.get_current_user()
+ if not current_user:
+ print("Cannot send user command if not connect. %s" % self.request.remote_ip, file=sys.stderr)
+ # Forbidden
+ self.set_status(403)
+ self.send_error(403)
+ raise tornado.web.Finish()
+ self.prepare_json()
+
+ # Validate password is not empty
+ old_password_name = self.get_argument("old_password_name")
+ old_password_email = self.get_argument("old_password_email")
+ new_password_name = self.get_argument("new_password_name")
+ new_password_email = self.get_argument("new_password_email")
+ if not (old_password_email and old_password_name) or not (new_password_email and new_password_name):
+ print("Password is empty from %s" % self.request.remote_ip, file=sys.stderr)
+ data = {"error": "Password is empty."}
+ self.write(data)
+ self.finish()
+ return
+
+ # Validate old_password is good before update with the new_password
+ success_password_name = self._db.compare_password(old_password_name, self.current_user.get("password_name"))
+ success_password_email = self._db.compare_password(old_password_email, self.current_user.get("password_email"))
+ if not (success_password_name or success_password_email):
+ print("Wrong password from ip %s." % self.request.remote_ip)
+ data = {"error": "Wrong password."}
+ self.write(data)
+ self.finish()
+ return
+
+ # Validate the password is a new one
+ success_password_name = self._db.compare_password(new_password_name, self.current_user.get("password_name"))
+ success_password_email = self._db.compare_password(new_password_email, self.current_user.get("password_email"))
+ if success_password_name or success_password_email:
+ print("Same password from ip %s." % self.request.remote_ip)
+ data = {"status": "Same password."}
+ self.write(data)
+ self.finish()
+ return
+
+ # Update password
+ print("Good password")
+ current_user["password_name"] = self._db.generate_password(new_password_name)
+ current_user["password_email"] = self._db.generate_password(new_password_email)
+ self._db.update_user(current_user)
+
+ # TODO Need to validate insertion
+ data = {"status": "Password updated."}
+ self.write(data)
+ self.finish()
+
+
+class ProfileCmdInfoHandler(jsonhandler.JsonHandler):
+ @tornado.web.asynchronous
+ @tornado.web.authenticated
+ def get(self):
+ # TODO not sure it's secure
+ user = self.current_user
+ return_user = {
+ "email": user.get("email"),
+ "name": user.get("name"),
+ "password_name": user.get("password_name"),
+ "password_email": user.get("password_email"),
+ "user_id": user.get("user_id"),
+ "google_id": user.get("google_id"),
+ "facebook_id": user.get("facebook_id"),
+ "twitter_id": user.get("twitter_id"),
+ "permission": user.get("permission"),
+ }
+ self.write(return_user)
+ self.finish()
+
+
class StatSeasonPass(jsonhandler.JsonHandler):
@tornado.web.asynchronous
def get(self):
diff --git a/src/web/partials/_base.html b/src/web/partials/_base.html
index 254a751d..b7eea911 100644
--- a/src/web/partials/_base.html
+++ b/src/web/partials/_base.html
@@ -95,7 +95,7 @@
{{current_user.get("name")}}
Déconnexion
{% elif not disable_login %}
- Connexion ou Inscription
+ Connexion
{% end %}
@@ -188,6 +188,7 @@
+
diff --git a/src/web/partials/admin/_base.html b/src/web/partials/admin/_base.html
index 0dfa0d7c..a0ee2d01 100644
--- a/src/web/partials/admin/_base.html
+++ b/src/web/partials/admin/_base.html
@@ -91,7 +91,7 @@
{{current_user.get("name")}}
Déconnexion
{% elif not disable_login %}
- Connexion ou Inscription
+ Connexion
{% end %}
diff --git a/src/web/partials/profile.html b/src/web/partials/profile.html
index bff45953..d964acba 100644
--- a/src/web/partials/profile.html
+++ b/src/web/partials/profile.html
@@ -3,11 +3,22 @@
{% block content %}
{% if user %}
-Profil de {{user.get("name")}}. (ID: {{ user.get("user_id") }})
-
-Personnage
+
+
Profil de {{! model_profile.info.name }}
+
Fiche de personnage
+
Accéder à sa fiche
+
+
Information personnel
+
Nom: {{! model_profile.info.name }}
+
Email: {{! model_profile.info.email }}
+
ID: {{! model_profile.info.user_id }}
+ Modifier son mot de passe.
+
+
+
Sauvegarder
+
{% else %}
-Veuillez sélectionner un profil.
+Profil inexistant, veuillez-vous créer un
compte.
{% end %}
{% end %}
\ No newline at end of file
diff --git a/src/web/py_class/db.py b/src/web/py_class/db.py
index 84613bed..a2d3d19a 100644
--- a/src/web/py_class/db.py
+++ b/src/web/py_class/db.py
@@ -24,6 +24,16 @@ def __init__(self, parser):
self._query_user = tinydb.Query()
+ @staticmethod
+ def generate_password(password):
+ return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
+
+ @staticmethod
+ def compare_password(user_password, hash_password):
+ if not user_password or not hash_password:
+ return False
+ return bcrypt.checkpw(user_password.encode('utf-8'), hash_password.encode('utf-8'))
+
def create_user(self, name, email=None, password_name=None, password_mail=None, google_id=None, facebook_id=None,
twitter_id=None, permission="Joueur"):
if self._db_user.contains(self._query_user.name == name):
@@ -39,11 +49,12 @@ def create_user(self, name, email=None, password_name=None, password_mail=None,
user_id = uuid.uuid4().hex
if password_name:
- secure_pass_name = bcrypt.hashpw(password_name.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
+ secure_pass_name = self.generate_password(password_name)
else:
secure_pass_name = None
+
if password_mail:
- secure_pass_mail = bcrypt.hashpw(password_mail.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
+ secure_pass_mail = self.generate_password(password_mail)
else:
secure_pass_mail = None
@@ -68,7 +79,7 @@ def get_user(self, name=None, email=None, password=None, id_type="user", user_id
if _user:
# Validate password
ddb_password = _user.get("password_name")
- if password and ddb_password and bcrypt.checkpw(password.encode('utf-8'), ddb_password.encode('utf-8')):
+ if password and ddb_password and self.compare_password(password, ddb_password):
return _user
# If no name provided, lookup user by email
@@ -78,8 +89,7 @@ def get_user(self, name=None, email=None, password=None, id_type="user", user_id
if not force_email_no_password:
# Validate password
ddb_password = _user.get("password_mail")
- if password and ddb_password and bcrypt.checkpw(password.encode('utf-8'),
- ddb_password.encode('utf-8')):
+ if password and ddb_password and self.compare_password(password, ddb_password):
return _user
else:
return _user
@@ -107,10 +117,6 @@ def get_user(self, name=None, email=None, password=None, id_type="user", user_id
# print("Missing user name, email or id to get user.", file=sys.stderr)
return
- if not _user:
- # print("User not found", file=sys.stderr)
- return
-
def user_exist(self, email=None, user_id=None, name=None):
"""Returns True if all the arguments given are found"""
return not (email and not self._db_user.get(self._query_user.email == email)) and not (
diff --git a/src/web/resources/js/tl_module/profile_ctrl/profile_ctrl.js b/src/web/resources/js/tl_module/profile_ctrl/profile_ctrl.js
new file mode 100644
index 00000000..88027221
--- /dev/null
+++ b/src/web/resources/js/tl_module/profile_ctrl/profile_ctrl.js
@@ -0,0 +1,47 @@
+// Formulaire de Traitre-Lame
+"use strict";
+
+characterApp.controller("profile_ctrl", ["$scope", "$q", "$http", "$window", /*"$timeout",*/ function ($scope, $q, $http, $window) {
+ $scope.model_profile = {
+ info: {}
+ };
+
+ $scope.dct_profile_password = {
+ "old_password": "",
+ "new_password": ""
+ };
+
+ // Get profile info
+ $http({
+ method: "get",
+ url: "/cmd/profile/get_info",
+ headers: {"Content-Type": "application/json; charset=UTF-8"},
+ timeout: 5000
+ }).then(function (response/*, status, headers, config*/) {
+ $scope.model_profile.info = response.data;
+ });
+
+
+ $scope.save_password = function (e) {
+ if ($scope.dct_profile_password.old_password != "" && $scope.dct_profile_password.new_password) {
+ var data = {
+ "old_password_name": hashSha256($scope.dct_profile_password.old_password, $scope.model_profile.info.name),
+ "old_password_email": hashSha256($scope.dct_profile_password.old_password, $scope.model_profile.info.email),
+ "new_password_name": hashSha256($scope.dct_profile_password.new_password, $scope.model_profile.info.name),
+ "new_password_email": hashSha256($scope.dct_profile_password.new_password, $scope.model_profile.info.email)
+ };
+ // send command to server
+ $http({
+ method: "post",
+ url: "/cmd/profile/update_password",
+ headers: {"Content-Type": "application/json; charset=UTF-8"},
+ data: data,
+ timeout: 5000
+ }).then(function (response/*, status, headers, config*/) {
+ console.info(response.data);
+ $scope.dct_profile_password.old_password = "";
+ $scope.dct_profile_password.new_password = "";
+ });
+ }
+ };
+}]);
diff --git a/src/web/web.py b/src/web/web.py
index 47c9d68c..6017d214 100644
--- a/src/web/web.py
+++ b/src/web/web.py
@@ -119,6 +119,10 @@ def main(parse_arg):
tornado.web.url(r"/cmd/lore/?", handlers.LoreHandler, name='cmd_lore', kwargs=settings),
tornado.web.url(r"/cmd/stat/total_season_pass/?", handlers.StatSeasonPass, name='cmd_stat_total_season_pass',
kwargs=settings),
+ tornado.web.url(r"/cmd/profile/update_password/?", handlers.ProfileCmdPasswordHandler,
+ name='cmd_profile_update_password', kwargs=settings),
+ tornado.web.url(r"/cmd/profile/get_info/?", handlers.ProfileCmdInfoHandler,
+ name='cmd_profile_get_info', kwargs=settings),
# auto ssl
tornado.web.url(r"/.well-known/acme-challenge.*", handlers.AutoSSLHandler, name="auto_ssl")