add pos header validation middleware

This commit is contained in:
2025-07-26 15:50:57 +03:30
parent 9b8d4c0353
commit b425caf22f
4 changed files with 114 additions and 63 deletions

View File

@@ -1,66 +1,74 @@
import datetime
from django.http import JsonResponse
from django.utils.timezone import now
from rest_framework.exceptions import APIException
from apps.pos_device.models import Device, ProviderCompany, Sessions, DeviceVersion
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
# اگر از پروکسی استفاده می‌شود، IP اول را برمی‌گردانیم
ip = x_forwarded_for.split(',')[0]
else:
# در غیر این صورت از REMOTE_ADDR استفاده می‌کنیم
ip = request.META.get('REMOTE_ADDR')
return ip
forwarded = request.META.get('HTTP_X_FORWARDED_FOR')
return forwarded.split(',')[0] if forwarded else request.META.get('REMOTE_ADDR')
class PosDeviceValidator:
class DeviceValidator:
REQUIRED_HEADERS = [
'device-id', 'device-mac', 'device-serial', 'device-name',
'device-sdk', 'device-provider', 'device-version',
'device-vname', 'device-lng', 'device-lot' # noqa
]
def __init__(self, request):
self.request = request
self.headers = request.headers
self.device_id = request.headers.get('device-id')
self.device_mac = request.headers.get('device-mac')
self.device_name = request.headers.get('device-name')
self.device_sdk = request.headers.get('device-sdk')
self.device_serial = request.headers.get('device-serial')
self.device_provider = request.headers.get('device-provider')
self.device_version = request.headers.get('device-version')
self.device_version_name = request.headers.get('device-vname')
self.device_lng = request.headers.get('device-lng')
self.device_lot = request.headers.get('device-lot')
self.data = {key: self.headers.get(key) for key in self.REQUIRED_HEADERS}
self.errors = []
def validation_version(self):
if self.device_provider == "" or self.device_provider == None:
return JsonResponse({'result': 'پارامتر های ارسالی صحیح نمیباشد!'}, status=402)
company = ProviderCompany.objects.filter(en_name=self.device_provider).first()
if not company:
return JsonResponse({'result': 'شرکت پرداخت الکترونیک پشتیبانی نمیشود!'}, status=402)
if not company.active:
return JsonResponse({'result': 'شرکت پرداخت الکترونیک توسط مدیریت مسدود شده است!'}, status=402)
version = DeviceVersion.objects.filter(company=company).order_by('code')
if not version:
return JsonResponse({'result': ' هیچ نسخه معتبری برای این شرکت پرداخت الکترونیک منتشر نشده است!'},
status=402)
current_version = version.filter(code=self.device_version).first()
if not current_version or current_version.remove:
return JsonResponse({'result': f'نسخه {self.device_version_name} منقضی شده است لطفا بروز رسانی کنید '},
status=402)
def validate_required_headers(self):
missing = [key for key, value in self.data.items() if not value]
if missing:
raise APIException(
f'پارامترهای ارسالی ناقص هستند: {", ".join(missing)}', # noqa
code=400
)
return None
def validation_device(self):
pos_session = Sessions.objects.filter(pos__pos_id=self.device_id, mac=self.device_mac).first()
if not pos_session:
return None
else:
pos_session.session_last_seen_date = datetime.datetime.now()
pos_session.lng = self.device_lng
pos_session.lot = self.device_lot
pos_session.version = self.device_version
pos_session.ip = get_client_ip(self.request)
pos_session.save()
return pos_session.pos.pos_id
def validate_version(self):
provider_name = self.data['device-provider']
company = ProviderCompany.objects.filter(en_name=provider_name).first()
if not company:
raise APIException('شرکت پرداخت الکترونیک پشتیبانی نمی‌شود!', code=402) # noqa
if not company.active:
raise APIException('شرکت پرداخت الکترونیک مسدود شده است!', code=402) # noqa
versions = DeviceVersion.objects.filter(company=company)
if not versions.exists():
raise APIException('هیچ نسخه‌ای برای این شرکت ثبت نشده است!', code=402) # noqa
current_version = versions.filter(code=self.data['device-version']).first()
if not current_version or current_version.remove:
raise APIException(
f'نسخه {self.data["device-vname"]} منقضی شده است. لطفا بروزرسانی کنید.', # noqa
code=402
)
return None
def validate_device_session(self):
session = Sessions.objects.filter(
pos__pos_id=self.data['device-id'],
mac=self.data['device-mac']
).first()
if session:
session.session_last_seen_date = now()
session.lng = self.data['device-lng']
session.lot = self.data['device-lot']
session.version = self.data['device-version']
session.ip = get_client_ip(self.request)
session.save()
return session.pos.pos_id
return None