add pos header validation middleware
This commit is contained in:
30
apps/pos_device/middlewares.py
Normal file
30
apps/pos_device/middlewares.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
from rest_framework.exceptions import APIException
|
||||||
|
from django.utils.timezone import now
|
||||||
|
|
||||||
|
from apps.pos_device.models import DeviceVersion, ProviderCompany, Sessions
|
||||||
|
|
||||||
|
|
||||||
|
class POSDeviceMiddleware:
|
||||||
|
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, get_response):
|
||||||
|
self.get_response = get_response
|
||||||
|
|
||||||
|
def __call__(self, request, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def is_post_request(self, request): # noqa
|
||||||
|
""" check if is pos request """
|
||||||
|
|
||||||
|
has_device_headers = request.headers.get('device-id') and request.headers.get('device-mac')
|
||||||
|
is_pos_api_path = request.path.startswith('/api/pos/')
|
||||||
|
return has_device_headers or is_pos_api_path
|
||||||
|
|
||||||
|
def validate_pos_request(self, request):
|
||||||
|
""" validate request headers from pos device """
|
||||||
|
|
||||||
|
data = {key: request.headers.get(key) for key in self.REQUIRED_HEADERS}
|
||||||
@@ -1,66 +1,74 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from django.http import JsonResponse
|
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
|
from apps.pos_device.models import Device, ProviderCompany, Sessions, DeviceVersion
|
||||||
|
|
||||||
|
|
||||||
def get_client_ip(request):
|
def get_client_ip(request):
|
||||||
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
forwarded = request.META.get('HTTP_X_FORWARDED_FOR')
|
||||||
if x_forwarded_for:
|
return forwarded.split(',')[0] if forwarded else request.META.get('REMOTE_ADDR')
|
||||||
# اگر از پروکسی استفاده میشود، IP اول را برمیگردانیم
|
|
||||||
ip = x_forwarded_for.split(',')[0]
|
|
||||||
else:
|
|
||||||
# در غیر این صورت از REMOTE_ADDR استفاده میکنیم
|
|
||||||
ip = request.META.get('REMOTE_ADDR')
|
|
||||||
return ip
|
|
||||||
|
|
||||||
|
|
||||||
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):
|
def __init__(self, request):
|
||||||
self.request = request
|
self.request = request
|
||||||
self.headers = request.headers
|
self.headers = request.headers
|
||||||
self.device_id = request.headers.get('device-id')
|
self.data = {key: self.headers.get(key) for key in self.REQUIRED_HEADERS}
|
||||||
self.device_mac = request.headers.get('device-mac')
|
self.errors = []
|
||||||
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')
|
|
||||||
|
|
||||||
def validation_version(self):
|
def validate_required_headers(self):
|
||||||
if self.device_provider == "" or self.device_provider == None:
|
missing = [key for key, value in self.data.items() if not value]
|
||||||
return JsonResponse({'result': 'پارامتر های ارسالی صحیح نمیباشد!'}, status=402)
|
if missing:
|
||||||
|
raise APIException(
|
||||||
company = ProviderCompany.objects.filter(en_name=self.device_provider).first()
|
f'پارامترهای ارسالی ناقص هستند: {", ".join(missing)}', # noqa
|
||||||
if not company:
|
code=400
|
||||||
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)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def validation_device(self):
|
def validate_version(self):
|
||||||
pos_session = Sessions.objects.filter(pos__pos_id=self.device_id, mac=self.device_mac).first()
|
provider_name = self.data['device-provider']
|
||||||
if not pos_session:
|
company = ProviderCompany.objects.filter(en_name=provider_name).first()
|
||||||
return None
|
|
||||||
else:
|
if not company:
|
||||||
pos_session.session_last_seen_date = datetime.datetime.now()
|
raise APIException('شرکت پرداخت الکترونیک پشتیبانی نمیشود!', code=402) # noqa
|
||||||
pos_session.lng = self.device_lng
|
|
||||||
pos_session.lot = self.device_lot
|
if not company.active:
|
||||||
pos_session.version = self.device_version
|
raise APIException('شرکت پرداخت الکترونیک مسدود شده است!', code=402) # noqa
|
||||||
pos_session.ip = get_client_ip(self.request)
|
|
||||||
pos_session.save()
|
versions = DeviceVersion.objects.filter(company=company)
|
||||||
return pos_session.pos.pos_id
|
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
|
||||||
|
|||||||
@@ -331,10 +331,9 @@ class QuotaViewSet(viewsets.ModelViewSet): # noqa
|
|||||||
# paginate queryset
|
# paginate queryset
|
||||||
page = self.paginate_queryset(
|
page = self.paginate_queryset(
|
||||||
self.queryset.filter(
|
self.queryset.filter(
|
||||||
Q(assigned_organizations=organization) |
|
|
||||||
Q(registerer_organization=organization),
|
Q(registerer_organization=organization),
|
||||||
Q(is_closed=True)
|
Q(is_closed=True)
|
||||||
)
|
).order_by('-modify_date')
|
||||||
)
|
)
|
||||||
if page is not None:
|
if page is not None:
|
||||||
serializer = self.get_serializer(page, many=True)
|
serializer = self.get_serializer(page, many=True)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
from apps.product.web.api.v1.serializers import quota_distribution_serializers as distribution_serializers
|
from apps.product.web.api.v1.serializers import quota_distribution_serializers as distribution_serializers
|
||||||
|
from apps.core.pagination import CustomPageNumberPagination
|
||||||
from rest_framework.exceptions import APIException
|
from rest_framework.exceptions import APIException
|
||||||
from apps.product import models as product_models
|
from apps.product import models as product_models
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
@@ -9,6 +10,8 @@ from rest_framework import viewsets, filters
|
|||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
|
||||||
|
from common.helpers import get_organization_by_user
|
||||||
|
|
||||||
|
|
||||||
def trash(queryset, pk): # noqa
|
def trash(queryset, pk): # noqa
|
||||||
""" sent object to trash """
|
""" sent object to trash """
|
||||||
@@ -30,6 +33,7 @@ class QuotaDistributionViewSet(viewsets.ModelViewSet):
|
|||||||
serializer_class = distribution_serializers.QuotaDistributionSerializer
|
serializer_class = distribution_serializers.QuotaDistributionSerializer
|
||||||
filter_backends = [filters.SearchFilter]
|
filter_backends = [filters.SearchFilter]
|
||||||
search_fields = ['']
|
search_fields = ['']
|
||||||
|
CustomPageNumberPagination.page_size = 5
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
@@ -68,17 +72,27 @@ class QuotaDistributionViewSet(viewsets.ModelViewSet):
|
|||||||
|
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
# @action(
|
@action(
|
||||||
# methods=['get'],
|
methods=['get'],
|
||||||
# url_name='my_distributions',
|
detail=False,
|
||||||
# url_path='my_distributions',
|
url_name='my_distributions',
|
||||||
# name='my_distributions'
|
url_path='my_distributions',
|
||||||
# )
|
name='my_distributions'
|
||||||
# def my_distributions(self, request):
|
)
|
||||||
#
|
def my_distributions(self, request):
|
||||||
# distributions = self.queryset.filter(
|
""" list of my distributions """
|
||||||
# Q(assigned_organization='')
|
organization = get_organization_by_user(request.user)
|
||||||
# )
|
|
||||||
|
# paginate queryset
|
||||||
|
page = self.paginate_queryset(
|
||||||
|
self.queryset.filter(
|
||||||
|
Q(assigned_organization=organization) |
|
||||||
|
Q(assigner_organization=organization)
|
||||||
|
).order_by('-modify_date')
|
||||||
|
)
|
||||||
|
if page is not None:
|
||||||
|
serializer = self.get_serializer(page, many=True)
|
||||||
|
return self.get_paginated_response(serializer.data)
|
||||||
|
|
||||||
@action(
|
@action(
|
||||||
methods=['put'],
|
methods=['put'],
|
||||||
|
|||||||
Reference in New Issue
Block a user