mirror of
https://github.com/barkeser2002/offline-db.git
synced 2026-09-25 01:40:07 +03:00
- Updated dependencies in `requirements.txt` to latest safe versions (Celery 5.4.0, Channels 4.2.0, Redis 5.2.0). - Hardened `billing/views.py`: `shopier_callback` now enforces presence of `SHOPIER_SECRET` even in DEBUG mode and logs requester IP. - Updated `billing/tests.py` to assert strict security behavior (400 Bad Request when secret is missing). Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
104 lines
3.7 KiB
Python
104 lines
3.7 KiB
Python
from django.test import TestCase, Client, override_settings
|
|
from django.urls import reverse
|
|
from .models import ShopierPayment
|
|
from users.models import User
|
|
import hmac
|
|
import hashlib
|
|
import base64
|
|
import os
|
|
|
|
class BillingCallbackTests(TestCase):
|
|
def setUp(self):
|
|
self.client = Client()
|
|
self.user = User.objects.create_user(username='testuser', password='password')
|
|
self.payment = ShopierPayment.objects.create(
|
|
user=self.user,
|
|
amount=10.00,
|
|
transaction_id='ORD-12345',
|
|
status='pending'
|
|
)
|
|
self.url = reverse('shopier_callback')
|
|
self.secret = 'test_secret_key'
|
|
|
|
def generate_signature(self, transaction_id, status, secret):
|
|
payload = f"{transaction_id}{status}"
|
|
return base64.b64encode(
|
|
hmac.new(
|
|
secret.encode('utf-8'),
|
|
payload.encode('utf-8'),
|
|
hashlib.sha256
|
|
).digest()
|
|
).decode('utf-8')
|
|
|
|
@override_settings(SHOPIER_SECRET='test_secret_key', DEBUG=False)
|
|
def test_callback_success_valid_signature(self):
|
|
signature = self.generate_signature('ORD-12345', 'success', self.secret)
|
|
data = {
|
|
'platform_order_id': 'ORD-12345',
|
|
'status': 'success',
|
|
'signature': signature
|
|
}
|
|
response = self.client.post(self.url, data)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.payment.refresh_from_db()
|
|
self.user.refresh_from_db()
|
|
|
|
self.assertEqual(self.payment.status, 'success')
|
|
self.assertTrue(self.user.is_premium)
|
|
|
|
@override_settings(SHOPIER_SECRET='test_secret_key', DEBUG=False)
|
|
def test_callback_failed_valid_signature(self):
|
|
signature = self.generate_signature('ORD-12345', 'failed', self.secret)
|
|
data = {
|
|
'platform_order_id': 'ORD-12345',
|
|
'status': 'failed',
|
|
'signature': signature
|
|
}
|
|
response = self.client.post(self.url, data)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.payment.refresh_from_db()
|
|
self.assertEqual(self.payment.status, 'failed')
|
|
|
|
@override_settings(SHOPIER_SECRET='test_secret_key', DEBUG=False)
|
|
def test_callback_invalid_signature(self):
|
|
data = {
|
|
'platform_order_id': 'ORD-12345',
|
|
'status': 'success',
|
|
'signature': 'invalid_signature'
|
|
}
|
|
response = self.client.post(self.url, data)
|
|
self.assertEqual(response.status_code, 400)
|
|
self.assertEqual(response.content.decode(), "Invalid signature")
|
|
|
|
@override_settings(SHOPIER_SECRET='test_secret_key', DEBUG=False)
|
|
def test_callback_missing_signature(self):
|
|
data = {
|
|
'platform_order_id': 'ORD-12345',
|
|
'status': 'success',
|
|
}
|
|
response = self.client.post(self.url, data)
|
|
self.assertEqual(response.status_code, 400)
|
|
self.assertEqual(response.content.decode(), "Invalid signature")
|
|
|
|
@override_settings(SHOPIER_SECRET=None, DEBUG=True)
|
|
def test_callback_no_secret_debug_mode(self):
|
|
# Should fail verification even in DEBUG mode if secret is missing
|
|
data = {
|
|
'platform_order_id': 'ORD-12345',
|
|
'status': 'success',
|
|
}
|
|
response = self.client.post(self.url, data)
|
|
self.assertEqual(response.status_code, 400)
|
|
|
|
@override_settings(SHOPIER_SECRET=None, DEBUG=False)
|
|
def test_callback_no_secret_production_mode(self):
|
|
# Should fail verification in Production mode if secret is missing
|
|
data = {
|
|
'platform_order_id': 'ORD-12345',
|
|
'status': 'success',
|
|
}
|
|
response = self.client.post(self.url, data)
|
|
self.assertEqual(response.status_code, 400)
|