mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-26 22:52:26 +00:00
Stockage en BDD des identifiants comnpay.
This commit is contained in:
parent
c57f155e24
commit
d694330149
7 changed files with 139 additions and 6 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,3 +5,4 @@ re2o.png
|
|||
__pycache__/*
|
||||
static_files/*
|
||||
static/logo/*
|
||||
media/*
|
||||
|
|
|
@ -11,6 +11,8 @@ from django.utils.datastructures import MultiValueDictKeyError
|
|||
from django.http import HttpResponse, HttpResponseBadRequest
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from preferences.models import AssoOption
|
||||
from .models import Facture
|
||||
from .payment_utils.comnpay import Payment as ComnpayPayment
|
||||
|
||||
|
@ -36,6 +38,7 @@ def refuse_payment(request):
|
|||
|
||||
@csrf_exempt
|
||||
def ipn(request):
|
||||
option, _created = AssoOption.objects.get_or_create()
|
||||
p = ComnpayPayment()
|
||||
order = ('idTpe', 'idTransaction', 'montant', 'result', 'sec', )
|
||||
try:
|
||||
|
@ -43,7 +46,7 @@ def ipn(request):
|
|||
except MultiValueDictKeyError:
|
||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||
|
||||
if not p.validSec(data, "DEMO"):
|
||||
if not p.validSec(data, option.payment_pass):
|
||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||
|
||||
result = True if (request.POST['result'] == 'OK') else False
|
||||
|
@ -51,7 +54,7 @@ def ipn(request):
|
|||
idTransaction = request.POST['idTransaction']
|
||||
|
||||
# On vérifie que le paiement nous est destiné
|
||||
if not idTpe == "DEMO":
|
||||
if not idTpe == option.payment_id:
|
||||
return HttpResponseBadRequest("HTTP/1.1 400 Bad Request")
|
||||
|
||||
try:
|
||||
|
@ -78,10 +81,14 @@ def ipn(request):
|
|||
|
||||
def comnpay(facture, request):
|
||||
host = request.get_host()
|
||||
option, _created = AssoOption.objects.get_or_create()
|
||||
p = ComnpayPayment(
|
||||
"DEMO",
|
||||
"DEMO",
|
||||
'https://' + host + reverse('cotisations:accept_payment', kwargs={'factureid':facture.id}),
|
||||
str(option.payment_id),
|
||||
str(option.payment_pass),
|
||||
'https://' + host + reverse(
|
||||
'cotisations:accept_payment',
|
||||
kwargs={'factureid':facture.id}
|
||||
),
|
||||
'https://' + host + reverse('cotisations:refuse_payment'),
|
||||
'https://' + host + reverse('cotisations:ipn'),
|
||||
"",
|
||||
|
@ -90,7 +97,11 @@ def comnpay(facture, request):
|
|||
r = {
|
||||
'action' : 'https://secure.homologation.comnpay.com',
|
||||
'method' : 'POST',
|
||||
'content' : p.buildSecretHTML("Rechargement du solde", facture.prix(), idTransaction=str(facture.id)),
|
||||
'content' : p.buildSecretHTML(
|
||||
"Rechargement du solde",
|
||||
facture.prix(),
|
||||
idTransaction=str(facture.id)
|
||||
),
|
||||
'amount' : facture.prix,
|
||||
}
|
||||
return r
|
||||
|
|
53
preferences/aes_field.py
Normal file
53
preferences/aes_field.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
import string
|
||||
import binascii
|
||||
from random import choice
|
||||
from Crypto.Cipher import AES
|
||||
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
|
||||
EOD = '`%EofD%`' # This should be something that will not occur in strings
|
||||
|
||||
|
||||
def genstring(length=16, chars=string.printable):
|
||||
return ''.join([choice(chars) for i in range(length)])
|
||||
|
||||
|
||||
def encrypt(key, s):
|
||||
obj = AES.new(key)
|
||||
datalength = len(s) + len(EOD)
|
||||
if datalength < 16:
|
||||
saltlength = 16 - datalength
|
||||
else:
|
||||
saltlength = 16 - datalength % 16
|
||||
ss = ''.join([s, EOD, genstring(saltlength)])
|
||||
return obj.encrypt(ss)
|
||||
|
||||
|
||||
def decrypt(key, s):
|
||||
obj = AES.new(key)
|
||||
ss = obj.decrypt(s)
|
||||
return ss.split(bytes(EOD, 'utf-8'))[0]
|
||||
|
||||
|
||||
class AESEncryptedField(models.CharField):
|
||||
def save_form_data(self, instance, data):
|
||||
setattr(instance, self.name,
|
||||
binascii.b2a_base64(encrypt(settings.AES_KEY, data)))
|
||||
|
||||
def value_from_object(self, obj):
|
||||
return decrypt(settings.AES_KEY,
|
||||
binascii.a2b_base64(getattr(obj, self.attname))).decode('utf-8')
|
||||
|
||||
def to_python(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
return decrypt(settings.AES_KEY,
|
||||
binascii.a2b_base64(value)).decode('utf-8')
|
||||
|
||||
def from_db_value(self, value, expression, connection, *args):
|
||||
|
||||
if value is None:
|
||||
return value
|
||||
return decrypt(settings.AES_KEY,
|
||||
binascii.a2b_base64(value)).decode('utf-8')
|
26
preferences/migrations/0039_auto_20180115_0003.py
Normal file
26
preferences/migrations/0039_auto_20180115_0003.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.7 on 2018-01-14 23:03
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import preferences.aes_field
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('preferences', '0038_auto_20180114_2209'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='assooption',
|
||||
name='payment_id',
|
||||
field=models.CharField(max_length=255, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='assooption',
|
||||
name='payment_pass',
|
||||
field=preferences.aes_field.AESEncryptedField(max_length=255, null=True),
|
||||
),
|
||||
]
|
26
preferences/migrations/0040_auto_20180115_0010.py
Normal file
26
preferences/migrations/0040_auto_20180115_0010.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.7 on 2018-01-14 23:10
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import preferences.aes_field
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('preferences', '0039_auto_20180115_0003'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='assooption',
|
||||
name='payment_id',
|
||||
field=models.CharField(default='', max_length=255),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='assooption',
|
||||
name='payment_pass',
|
||||
field=preferences.aes_field.AESEncryptedField(default='', max_length=255),
|
||||
),
|
||||
]
|
|
@ -28,6 +28,8 @@ from __future__ import unicode_literals
|
|||
from django.db import models
|
||||
import cotisations.models
|
||||
|
||||
from .aes_field import AESEncryptedField
|
||||
|
||||
|
||||
class OptionalUser(models.Model):
|
||||
"""Options pour l'user : obligation ou nom du telephone,
|
||||
|
@ -471,6 +473,16 @@ class AssoOption(models.Model):
|
|||
choices=PAYMENT,
|
||||
default='NONE',
|
||||
)
|
||||
payment_id = models.CharField(
|
||||
max_length=255,
|
||||
default='',
|
||||
)
|
||||
payment_pass = AESEncryptedField(
|
||||
max_length=255,
|
||||
default='',
|
||||
)
|
||||
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
("view_assooption", "Peut voir les options de l'asso"),
|
||||
|
|
|
@ -26,6 +26,10 @@ SECRET_KEY = 'SUPER_SECRET_KEY'
|
|||
|
||||
DB_PASSWORD = 'SUPER_SECRET_DB'
|
||||
|
||||
# AES key for secret key encryption
|
||||
AES_KEY = 'WHAT_A_WONDERFULL_KEY'
|
||||
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = False
|
||||
|
||||
|
|
Loading…
Reference in a new issue