diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index 438d2258..68f80458 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -185,6 +185,15 @@ Welcome to the wiki page! subscriber.save() subscriber.view_groups=[Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first().id] subscriber.save() + # Adding user old Subscriber + old_subscriber = User(username='old_subscriber', last_name="Subscriber", first_name="Old", + email="old_subscriber@git.an", + date_of_birth="1942-06-12", + is_superuser=False, is_staff=False) + old_subscriber.set_password("plop") + old_subscriber.save() + old_subscriber.view_groups=[Group.objects.filter(name=settings.SITH_MAIN_MEMBERS_GROUP).first().id] + old_subscriber.save() # Adding user Counter admin counter = User(username='counter', last_name="Ter", first_name="Coun", email="counter@git.an", @@ -265,6 +274,14 @@ Welcome to the wiki page! duration=settings.SITH_SUBSCRIPTIONS[s.subscription_type]['duration'], start=s.subscription_start) s.save() + ## Counter admin + s = Subscription(member=User.objects.filter(pk=counter.pk).first(), subscription_type=list(settings.SITH_SUBSCRIPTIONS.keys())[0], + payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0]) + s.subscription_start = s.compute_start() + s.subscription_end = s.compute_end( + duration=settings.SITH_SUBSCRIPTIONS[s.subscription_type]['duration'], + start=s.subscription_start) + s.save() ## Comptable s = Subscription(member=User.objects.filter(pk=comptable.pk).first(), subscription_type=list(settings.SITH_SUBSCRIPTIONS.keys())[0], payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0]) @@ -289,6 +306,14 @@ Welcome to the wiki page! duration=settings.SITH_SUBSCRIPTIONS[s.subscription_type]['duration'], start=s.subscription_start) s.save() + ## Old subscriber + s = Subscription(member=User.objects.filter(pk=old_subscriber.pk).first(), subscription_type=list(settings.SITH_SUBSCRIPTIONS.keys())[0], + payment_method=settings.SITH_SUBSCRIPTION_PAYMENT_METHOD[0]) + s.subscription_start = s.compute_start(datetime(year=2012, month=9, day=4)) + s.subscription_end = s.compute_end( + duration=settings.SITH_SUBSCRIPTIONS[s.subscription_type]['duration'], + start=s.subscription_start) + s.save() # Clubs Club(name="Bibo'UT", unix_name="bibout", @@ -311,6 +336,19 @@ Welcome to the wiki page! Customer(user=r, account_id="4000", amount=0).save() p = ProductType(name="Bières bouteilles") p.save() + c = ProductType(name="Cotisations") + c.save() + r = ProductType(name="Rechargements") + r.save() + cotis = Product(name="Cotis 1 semestre", code="1SCOTIZ", product_type=c, purchase_price="15", selling_price="15", + special_selling_price="15", club=main_club) + cotis.save() + cotis2 = Product(name="Cotis 2 semestres", code="2SCOTIZ", product_type=c, purchase_price="28", selling_price="28", + special_selling_price="28", club=main_club) + cotis2.save() + refill = Product(name="Rechargement 15 €", code="15REFILL", product_type=r, purchase_price="15", selling_price="15", + special_selling_price="15", club=main_club) + refill.save() barb = Product(name="Barbar", code="BARB", product_type=p, purchase_price="1.50", selling_price="1.7", special_selling_price="1.6", club=main_club) barb.save() @@ -326,6 +364,13 @@ Welcome to the wiki page! mde.products.add(cble) mde.save() + eboutic = Counter.objects.filter(name="Eboutic").first() + eboutic.products.add(barb) + eboutic.products.add(cotis) + eboutic.products.add(cotis2) + eboutic.products.add(refill) + eboutic.save() + refound_counter = Counter(name="Carte AE", club=refound, type='OFFICE') refound_counter.save() refound_product = Product(name="remboursement", code="REMBOURS", purchase_price="0", selling_price="0", diff --git a/eboutic/tests.py b/eboutic/tests.py index b8fbbe1e..c33d4a1b 100644 --- a/eboutic/tests.py +++ b/eboutic/tests.py @@ -21,7 +21,156 @@ # Place - Suite 330, Boston, MA 02111-1307, USA. # # +from datetime import datetime + +import re +import base64 +import urllib +from OpenSSL import crypto from django.test import TestCase +from django.core.urlresolvers import reverse +from django.core.management import call_command +from django.conf import settings + +from core.models import User +from counter.models import Customer, ProductType, Product, Counter, Refilling + +class EbouticTest(TestCase): + def setUp(self): + call_command("populate") + self.skia = User.objects.filter(username="skia").first() + self.subscriber = User.objects.filter(username="subscriber").first() + self.old_subscriber = User.objects.filter(username="old_subscriber").first() + self.public = User.objects.filter(username="public").first() + self.barbar = Product.objects.filter(code="BARB").first() + self.refill = Product.objects.filter(code="15REFILL").first() + self.cotis = Product.objects.filter(code="1SCOTIZ").first() + self.eboutic = Counter.objects.filter(name="Eboutic").first() + + def generate_bank_valid_answer_from_page_content(self, content): + content = str(content) + basket_id = re.search(r"PBX_CMD\" value=\"(\d*)\"", content).group(1) + amount = re.search(r"PBX_TOTAL\" value=\"(\d*)\"", content).group(1) + query = "Amount=%s&BasketID=%s&Auto=42&Error=00000" % (amount, basket_id) + with open("./eboutic/tests/private_key.pem") as f: + PRIVKEY = f.read() + with open("./eboutic/tests/public_key.pem") as f: + settings.SITH_EBOUTIC_PUB_KEY = f.read() + privkey = crypto.load_privatekey(crypto.FILETYPE_PEM, PRIVKEY) + sig = crypto.sign(privkey, query, "sha1") + b64sig = base64.b64encode(sig).decode("ascii") + + url = reverse("eboutic:etransation_autoanswer") + "?%s&Sig=%s" % (query, urllib.parse.quote_plus(b64sig)) + response = self.client.get(url) + self.assertTrue(response.status_code == 200) + self.assertTrue(response.content.decode("utf-8") == "") + return response + + def test_buy_simple_product_with_sith_account(self): + self.client.login(username='subscriber', password='plop') + Refilling(amount=10, counter=self.eboutic, operator=self.skia, customer=self.subscriber.customer).save() + response = self.client.post(reverse("eboutic:main"), { + "action": "add_product", + "product_id": self.barbar.id}) + self.assertTrue("\\n" + " \\n" + "\\n Barbar: 1.70 \\xe2\\x82\\xac" in str(response.content)) + response = self.client.post(reverse("eboutic:command")) + self.assertTrue("\\n Barbar\\n 1\\n" + " 1.70 \\xe2\\x82\\xac\\n " in str(response.content)) + response = self.client.post(reverse("eboutic:pay_with_sith"), { + "action": "pay_with_sith_account" + }) + self.assertTrue("Le paiement a \\xc3\\xa9t\\xc3\\xa9 effectu\\xc3\\xa9\\n" in str(response.content)) + response = self.client.get(reverse("core:user_account_detail", kwargs={ + "user_id": self.subscriber.id, + "year": datetime.now().year, + "month": datetime.now().month, + })) + self.assertTrue("class=\"selected_tab\">Compte (8.30 \\xe2\\x82\\xac)" in str(response.content)) + self.assertTrue("Eboutic\\n Subscribed User\\n" + " Barbar\\n 1\\n 1.70 \\xe2\\x82\\xac\\n" + " Compte utilisateur" in str(response.content)) + + + def test_buy_simple_product_with_credit_card(self): + self.client.login(username='subscriber', password='plop') + response = self.client.post(reverse("eboutic:main"), { + "action": "add_product", + "product_id": self.barbar.id}) + self.assertTrue("\\n" + " \\n" + "\\n Barbar: 1.70 \\xe2\\x82\\xac" in str(response.content)) + response = self.client.post(reverse("eboutic:command")) + self.assertTrue("\\n Barbar\\n 1\\n" + " 1.70 \\xe2\\x82\\xac\\n " in str(response.content)) + + response = self.generate_bank_valid_answer_from_page_content(response.content) + + response = self.client.get(reverse("core:user_account_detail", kwargs={ + "user_id": self.subscriber.id, + "year": datetime.now().year, + "month": datetime.now().month, + })) + self.assertTrue("class=\"selected_tab\">Compte (0.00 \\xe2\\x82\\xac)" in str(response.content)) + self.assertTrue("Eboutic\\n Subscribed User\\n" + " Barbar\\n 1\\n 1.70 \\xe2\\x82\\xac\\n" + " Carte bancaire" in str(response.content)) + + def test_buy_refill_product_with_credit_card(self): + self.client.login(username='subscriber', password='plop') + response = self.client.post(reverse("eboutic:main"), { + "action": "add_product", + "product_id": self.refill.id}) + self.assertTrue("\\n" + " \\n" + "\\n Rechargement 15 \\xe2\\x82\\xac: 15.00 \\xe2\\x82\\xac" in str(response.content)) + response = self.client.post(reverse("eboutic:command")) + self.assertTrue("\\n Rechargement 15 \\xe2\\x82\\xac\\n 1\\n" + " 15.00 \\xe2\\x82\\xac\\n " in str(response.content)) + + response = self.generate_bank_valid_answer_from_page_content(response.content) + + response = self.client.get(reverse("core:user_account_detail", kwargs={ + "user_id": self.subscriber.id, + "year": datetime.now().year, + "month": datetime.now().month, + })) + self.assertTrue("class=\"selected_tab\">Compte (15.00 \\xe2\\x82\\xac)" in str(response.content)) + self.assertTrue("\\n \\n \\n" + " 15.00 \\xe2\\x82\\xac" in str(response.content)) + + def test_buy_subscribe_product_with_credit_card(self): + self.client.login(username='old_subscriber', password='plop') + response = self.client.get(reverse("core:user_profile", kwargs={"user_id": self.old_subscriber.id})) + self.assertTrue("Non cotisant" in str(response.content)) + response = self.client.post(reverse("eboutic:main"), { + "action": "add_product", + "product_id": self.cotis.id}) + self.assertTrue("\\n" + " \\n" + "\\n Cotis 1 semestre: 15.00 \\xe2\\x82\\xac" in str(response.content)) + response = self.client.post(reverse("eboutic:command")) + self.assertTrue("\\n Cotis 1 semestre\\n 1\\n" + " 15.00 \\xe2\\x82\\xac\\n " in str(response.content)) + + response = self.generate_bank_valid_answer_from_page_content(response.content) + + response = self.client.get(reverse("core:user_account_detail", kwargs={ + "user_id": self.old_subscriber.id, + "year": datetime.now().year, + "month": datetime.now().month, + })) + self.assertTrue("class=\"selected_tab\">Compte (0.00 \\xe2\\x82\\xac)" in str(response.content)) + self.assertTrue("\\n \\n \\n" + " 15.00 \\xe2\\x82\\xac" in str(response.content)) + response = self.client.get(reverse("core:user_profile", kwargs={"user_id": self.old_subscriber.id})) + self.assertTrue("Cotisant jusqu\\'au" in str(response.content)) + + -# Create your tests here. diff --git a/eboutic/tests/private_key.pem b/eboutic/tests/private_key.pem new file mode 100644 index 00000000..9eb479c4 --- /dev/null +++ b/eboutic/tests/private_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCzLRPk/qRi1KNR +a9+r5Mm00avv0jwawTrQ02Oq86/1GBvWWiPkme5GYx8g18TxHX/qvE7N+P/tfMYt +PaFh+5z07BAQYBehdJrZF6XxW5j9GZiCAfIG2uOZ7WwHhT/C8ksUF/rq24Yde5b9 +uZzrT3G66N019iaLHKK0fIE69T574RP0gpby9PY/13XHj+DQ3dp29+K9V4h53uQt +axrVmW8QQKvuJVD2T6DySg/l6sYYD3p5B2bbSjS/R1mALT3qFGZaB4GsUblqTMJF +wvkcxBblxuIOjbsrIViH6xSdN/LKK9fPyFkQhs1xbWlX2ZxfVHGDtYlizf7B/Ai0 +NL4zL0anAgMBAAECggEAJd71QYWBAVKoYmFGmXJ2H73hdYMeKRmGcPT9L/jpzAgY +ein7RCo07rOstKhmfAAcNWUv0uE6Vtv0l0NbhPZFqo7qpktpMzsOL6yL6oPNxlFO +psv6d/B0Aujn2H8VhwLnU4vuAQ39PuYMd/xval0UUMk/WFR6uRSIX1WhivCjEFOb +bT2ZOmw8LoTTnzScop3Q9Mte0VCNAL6sZIhBvgGJBM8bKjGg7CQ3yJsn4PM5w6fK +T7RFnHh/SeVwaBHNrWO9HnR6fmHLUHeRJ84tBKVfYK7ibTmxt1klAQ2WyDZYB96P +dwnG3m/AZtHepiT9DTN4fwaxmXre7/KzwL+ehXA5AQKBgQDu0SC011yjC0IKQWhO +7T3z1A4YYKKqhpPerBzKOTGwEhZeKW7v5Qaqe3bLl6EE6CdXlm6a/N17A36Lc1Ze +ekclvijhZWRw/6EawpLE7WlEN8NMh0TXj4/Go0nDxj45YoKgXOMBOJ+2/y37cV5n +C/AzyWTFEPjfjdfbvGX7JlHwRwKBgQDAEWZY1HPn9taU68vVLLDDeVyaJpsGSgMl +YZSTLMr4dnAWvqLOOJd4xw2Cn0B2xBirECkShtv8cWcupDIQKvO4eT5XL9tvjgbr +wZfBsqyVNetHiUdIRfw8eEh2NlEsGDfnIy62+uT3IPaDQ6H1ouyskXNHKZvlkIQ1 +er1BXg6GoQKBgQDfTA8GyG/Hy5j+OdYsJkvNFrPvOzwdsiPFCq0IsJ2zAdaESL1/ +9WdcNIEJMEfQbLmMfg4BQPpeMRA7l6ZkRHUN51YWGlXmCj865D+TfmD09ibYAYru ++z71/mvUcCJySZfWFcPzulwsIUF/X6tjMphv85kTYiEx9lClFu1L/bKTtQKBgQCh +AXUEXgRTnY5ABHI4X2BGXMQNzPMDkKOWgHhl75SuN8q6plAgAzym2GYw64LEjJoJ +PGDR0Q80TXQrmyUEfJ0WNTzXJZ0TpMGUfBLVIwydgDedHi0NHu3VWxeTUPE2v46N +SebtKOErcQx0+QsZuNwhxUQXkX/ILx9FHYDs/QW8QQKBgHq1cCQfvFB65Z+nbe8n ++E9/XuTTvVnCX5f10w99P8KAVnqH9QB17+95NqwG/fUtXTOhqhg3Powb8rezy4Ln +xCgmvJIUjiPKK8ou5FyAAiPdXw+ZNnwADgAPPldh53a6nD/EpgT1O+cmmck076jZ +sTHvcDHEmtHF+icrumA2swJu +-----END PRIVATE KEY----- diff --git a/eboutic/tests/public_key.pem b/eboutic/tests/public_key.pem new file mode 100644 index 00000000..2ef5f66c --- /dev/null +++ b/eboutic/tests/public_key.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsy0T5P6kYtSjUWvfq+TJ +tNGr79I8GsE60NNjqvOv9Rgb1loj5JnuRmMfINfE8R1/6rxOzfj/7XzGLT2hYfuc +9OwQEGAXoXSa2Rel8VuY/RmYggHyBtrjme1sB4U/wvJLFBf66tuGHXuW/bmc609x +uujdNfYmixyitHyBOvU+e+ET9IKW8vT2P9d1x4/g0N3advfivVeIed7kLWsa1Zlv +EECr7iVQ9k+g8koP5erGGA96eQdm20o0v0dZgC096hRmWgeBrFG5akzCRcL5HMQW +5cbiDo27KyFYh+sUnTfyyivXz8hZEIbNcW1pV9mcX1Rxg7WJYs3+wfwItDS+My9G +pwIDAQAB +-----END PUBLIC KEY----- diff --git a/eboutic/tests/test.py b/eboutic/tests/test.py new file mode 100755 index 00000000..38be7646 --- /dev/null +++ b/eboutic/tests/test.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 +# -*- coding:utf-8 -* +# +# Skia < skia AT libskia DOT so > +# +# Beerware licensed software - 2017 +# + +import base64 +from OpenSSL import crypto + +with open("./private_key.pem") as f: + PRVKEY = f.read() +with open("./public_key.pem") as f: + PUBKEY = f.read() + +string = "Amount=400&BasketID=4000&Auto=42&Error=00000\n" + +# Sign +prvkey = crypto.load_privatekey(crypto.FILETYPE_PEM, PRVKEY) +sig = crypto.sign(prvkey, string, "sha1") +b64sig = base64.b64encode(sig) +print(b64sig) + +# Verify +pubkey = crypto.load_publickey(crypto.FILETYPE_PEM, PUBKEY) +cert = crypto.X509() +cert.set_pubkey(pubkey) +sig = base64.b64decode(b64sig) +try: + crypto.verify(cert, sig, string, "sha1") + print("Verify OK") +except: + print("Verify failed") + + + + diff --git a/sith/et_keys/pubkey.pem b/sith/et_keys/pubkey.pem index 55dc28b5..e8c4bcd1 100644 --- a/sith/et_keys/pubkey.pem +++ b/sith/et_keys/pubkey.pem @@ -1,6 +1,6 @@ ------BEGIN PUBLIC KEY----- -MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDe+hkicNP7ROHUssGNtHwiT2Ew -HFrSk/qwrcq8v5metRtTTFPE/nmzSkRnTs3GMpi57rBdxBBJW5W9cpNyGUh0jNXc -VrOSClpD5Ri2hER/GcNrxVRP7RlWOqB1C03q4QYmwjHZ+zlM4OUhCCAtSWflB4wC -Ka1g88CjFwRw/PB9kwIDAQAB ------END PUBLIC KEY----- +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvDYKaLH2xz4goZYXZWoHo6wyM +b24A1iF7s70tB/g3XthEVS+/Wov+ZGqNTMLc0L+HZAJjcEc9h8Br5jPLR4VhaoKi ++rezDxTQweaC24ydJWFKRhyXBhm2Wfnhppgzv9EqZKOrFaTlLQHu0F+KWEd7LngP +4xcW9qjt19MfEmk0swIDAQAB +-----END PUBLIC KEY----- diff --git a/sith/settings.py b/sith/settings.py index eccb36bc..ca6a8845 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -386,12 +386,12 @@ SITH_COUNTER_BANK = [ SITH_COUNTER_CASH_SUMMARY_LENGTH = 50 # Defines which product type is the refilling type, and thus increases the account amount -SITH_COUNTER_PRODUCTTYPE_REFILLING = 11 +SITH_COUNTER_PRODUCTTYPE_REFILLING = 3 # Defines which product is the one year subscription and which one is the six month subscription -SITH_PRODUCT_SUBSCRIPTION_ONE_SEMESTER = 93 -SITH_PRODUCT_SUBSCRIPTION_TWO_SEMESTERS = 94 -SITH_PRODUCTTYPE_SUBSCRIPTION = 23 +SITH_PRODUCT_SUBSCRIPTION_ONE_SEMESTER = 1 +SITH_PRODUCT_SUBSCRIPTION_TWO_SEMESTERS = 2 +SITH_PRODUCTTYPE_SUBSCRIPTION = 2 # Subscription durations are in semestres # Be careful, modifying this parameter will need a migration to be applied