Authentification K-Psul

Si une (des) permission(s) sont nécessaires pour enregistrer/annuler des
opérations, une demande d'authentification apparaît où l'utilisateur
doit mettre le mot de passe d'un compte ayant la (les) permission(s)
requise(s).

Ce mot de passe est envoyé dans la requête AJAX via le header
`KFetPassword`.
Le middleware `KFetAuthenticationPassword` est appelée à chaque requête.
Il appelle lui même le backend `KFetBackend` qui est chargé de
retrouver le user dont le compte K-Fêt correspond au mot de passe défini
dans le header `KFETPASSWORD`.
Si le header n'est pas présent ou
qu'aucun utilisateur ne correspond à ce mot de passe, le middleware ne
fait... rien !
Dans le cas où un user est trouvé, il est "chargé" dans
`request.user` permettant ainsi de connecter l'utilisateur pour ce cycle
requête/réponse sans déconnecter l'utilisateur connecté de manière
normale.
This commit is contained in:
Aurélien Delobelle 2016-08-19 06:20:37 +02:00
parent 5643e0c1d9
commit 3e96932a5b
4 changed files with 83 additions and 10 deletions

View file

@ -60,6 +60,7 @@ MIDDLEWARE_CLASSES = (
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'kfet.middleware.KFetAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',

18
kfet/backends.py Normal file
View file

@ -0,0 +1,18 @@
import hashlib
from kfet.models import Account
class KFetBackend(object):
def authenticate(self, request):
password = request.META.get('HTTP_KFETPASSWORD')
if not password:
return None
try:
password_sha1 = hashlib.sha1(password.encode()).hexdigest()
account = Account.objects.get(password=password_sha1)
user = account.cofprofile.user
except Account.DoesNotExist:
return None
return user

8
kfet/middleware.py Normal file
View file

@ -0,0 +1,8 @@
from kfet.backends import KFetBackend
class KFetAuthenticationMiddleware(object):
def process_request(self, request):
kfet_backend = KFetBackend()
temp_request_user = kfet_backend.authenticate(request)
if temp_request_user:
request.user = temp_request_user

View file

@ -305,6 +305,33 @@ $(document).ready(function() {
retrieveCheckoutData(checkoutInput.val());
});
// -----
// Auth
// -----
function requestAuth(data, callback) {
$.confirm({
title: 'Authentification requise',
content: '<input type="password" name="password" autofocus>',
backgroundDismiss: true,
animation:'top',
closeAnimation:'bottom',
keyboardEnabled: true,
confirm: function() {
var password = this.$content.find('input').val();
callback(password);
},
onOpen: function() {
var that = this
this.$content.find('input').on('keypress', function(e) {
if (e.keyCode == 13)
that.$confirmButton.click();
});
},
onClose: function() { this._lastFocused = articleSelect; }
});
}
// -----
// Perform operations
// -----
@ -313,20 +340,29 @@ $(document).ready(function() {
var operationGroup = $('#operationgroup_form');
var operations = $('#operation_formset');
function performOperations() {
function performOperations(password = '') {
var data = operationGroup.serialize() + '&' + operations.serialize();
$.ajax({
dataType: "json",
url : "{% url 'kfet.kpsul.perform_operations' %}",
method : "POST",
data : data,
beforeSend: function ($xhr) {
$xhr.setRequestHeader("X-CSRFToken", csrftoken);
if (password != '')
$xhr.setRequestHeader("KFetPassword", password);
},
})
.done(function(data) {
console.log(data);
coolReset();
})
.fail(function($xhr) {
var data = $xhr.responseJSON;
console.log(data);
switch ($xhr.status) {
case 403:
requestAuth(data, performOperations);
break;
}
});
}
@ -342,21 +378,33 @@ $(document).ready(function() {
var cancelButton = $('#cancel_operations');
var cancelForm = $('#cancel_form');
function cancelOperations(opes_array) {
function cancelOperations(opes_array, password = '') {
var data = { 'operations' : opes_array }
$.ajax({
dataType: "json",
url : "{% url 'kfet.kpsul.cancel_operations' %}",
method : "POST",
data : data,
beforeSend: function ($xhr) {
$xhr.setRequestHeader("X-CSRFToken", csrftoken);
if (password != '')
$xhr.setRequestHeader("KFetPassword", password);
},
})
.done(function(data) {
console.log(data);
history_container.find('.ui-selected').removeClass('ui-selected');
coolReset();
})
.fail(function($xhr) {
var data = $xhr.responseJSON;
console.log(data);
switch ($xhr.status) {
case 403:
requestAuth(data, function(password) {
cancelOperations(opes_array, password);
});
break;
}
});
}
@ -510,10 +558,8 @@ $(document).ready(function() {
var text = articleSelect.val();
// Comportement normal pour ces touches
if (normalKeys.test(e.keyCode) || e.ctrlKey) {
if (text == '' && e.keyCode == 13) {
if (text == '' && e.keyCode == 13)
performOperations();
coolReset();
}
if (e.keyCode == 8)
updateMatchedArticles(text.substring(0,text.length-1), commit=false);
if (e.charCode == 97 && e.ctrlKey) {