Skip to content

Commit

Permalink
[AdminTL#83] Profile: update page and able to update password
Browse files Browse the repository at this point in the history
- Rename connection button
  • Loading branch information
mathben committed Mar 26, 2018
1 parent 7d91560 commit 4edd58f
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 15 deletions.
84 changes: 84 additions & 0 deletions src/web/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
3 changes: 2 additions & 1 deletion src/web/partials/_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
<li><a href="/profile/">{{current_user.get("name")}}</a></li>
<li><a href="/logout">Déconnexion</a></li>
{% elif not disable_login %}
<li ng-class="{ active: isActive('/login') }"><a href="/login">Connexion ou Inscription</a></li>
<li ng-class="{ active: isActive('/login') }"><a href="/login">Connexion</a></li>
{% end %}
</ul>

Expand Down Expand Up @@ -188,6 +188,7 @@ <h1 class="detect_javascript_enable">
<script src="{{ static_url('resources/js/tl_module/page_ctrl/page_ctrl.js') }}"></script>
<script src="{{ static_url('resources/js/tl_module/manual_ctrl/manual_ctrl.js') }}"></script>
<script src="{{ static_url('resources/js/tl_module/lore_ctrl/lore_ctrl.js') }}"></script>
<script src="{{ static_url('resources/js/tl_module/profile_ctrl/profile_ctrl.js') }}"></script>

<script src="{{ static_url('bower_components/qrcode-generator/js/qrcode.js') }}"></script>
<script src="{{ static_url('bower_components/qrcode-generator/js/qrcode_UTF8.js') }}"></script>
Expand Down
2 changes: 1 addition & 1 deletion src/web/partials/admin/_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
<li><a href="/profile/">{{current_user.get("name")}}</a></li>
<li><a href="/logout">Déconnexion</a></li>
{% elif not disable_login %}
<li ng-class="{ active: isActive('/login') }"><a href="/login">Connexion ou Inscription</a></li>
<li ng-class="{ active: isActive('/login') }"><a href="/login">Connexion</a></li>
{% end %}
</ul>

Expand Down
19 changes: 15 additions & 4 deletions src/web/partials/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,22 @@
{% block content %}

{% if user %}
<div>Profil de {{user.get("name")}}. (ID: {{ user.get("user_id") }})</div>
</br>
<a href="/character?id_player={{ user.get("user_id") }}" class="btn btn-lg btn-default" role="button">Personnage</a>
<div ng-controller="profile_ctrl" ng-cloak>
<h1>Profil de {{! model_profile.info.name }}</h1>
<h2>Fiche de personnage</h2>
<a href="/character?id_player={{! model_profile.info.user_id }}" class="btn btn-lg btn-default" role="button">Accéder à sa fiche</a>

<h2>Information personnel</h2>
<p>Nom: {{! model_profile.info.name }}</p>
<p>Email: {{! model_profile.info.email }}</p>
<p>ID: {{! model_profile.info.user_id }}</p>
Modifier son mot de passe.<br/>
<input type="password" ng-model="dct_profile_password.old_password" placeholder="Vieux password." required>
<input type="password" ng-model="dct_profile_password.new_password" placeholder="Nouveau password." required>
<a ng-click="save_password()" class="btn btn-lg btn-default" role="button">Sauvegarder</a>
</div>
{% else %}
<div class="alert alert-warning">Veuillez sélectionner un profil.</div>
<div class="alert alert-warning">Profil inexistant, veuillez-vous créer un <a href="/login" class="btn btn-lg btn-default" role="button">compte</a>.</div>
{% end %}

{% end %}
24 changes: 15 additions & 9 deletions src/web/py_class/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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

Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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 (
Expand Down
47 changes: 47 additions & 0 deletions src/web/resources/js/tl_module/profile_ctrl/profile_ctrl.js
Original file line number Diff line number Diff line change
@@ -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 = "";
});
}
};
}]);
4 changes: 4 additions & 0 deletions src/web/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down

0 comments on commit 4edd58f

Please sign in to comment.