request without user

This commit is contained in:
sahama 2024-08-11 12:00:37 +03:30
parent 6ee333cd06
commit 345bde39a3
7 changed files with 131 additions and 78 deletions

View file

@ -150,15 +150,18 @@ class OAuth2Validator(BaseOAuth2Validator): # pylint: disable=w0223
expires, timezone=get_timezone(oauth2_settings.AUTHENTICATION_SERVER_EXP_TIME_ZONE) expires, timezone=get_timezone(oauth2_settings.AUTHENTICATION_SERVER_EXP_TIME_ZONE)
) )
# TODO: get application owner and put it here
application, _created = Application.objects.get_or_create( application, _created = Application.objects.get_or_create(
client_id=content["client_id"], client_id=content["client_id"],
uuid=application_introspection_content["uuid"] uuid=application_introspection_content["uuid"],
defaults={
"user": owner # TODO: JUST FOR WALLET
}
) )
access_token, _created = AccessToken.objects.update_or_create( access_token, _created = AccessToken.objects.update_or_create(
token=token, token=token,
defaults={ defaults={
"user": user, "user": user , # TODO: JUST FOR WALLET
"client_id": content["client_id"], "client_id": content["client_id"],
"application_owner": owner, "application_owner": owner,
"application_id": application_uuid, "application_id": application_uuid,

View file

@ -0,0 +1,74 @@
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.db.models import Q
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views.generic import DetailView, ListView, UpdateView
from oauth2_provider.contrib.rest_framework import TokenHasScope, IsAuthenticatedOrTokenHasScope
from rest_framework import generics, permissions, mixins
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements, \
IsAuthenticatedOrActionMatchesOASRequirements
from apps.wallet.models import Transaction
from apps.wallet.serializers import TransactionSerializer, DepositSerializer, WithdrawSerializer, WalletSerializer
from .constans import StateChoices
from .forms import TransactionActionForm
from django.utils.translation import gettext_lazy as _
def get_application(request):
try:
application = request.auth.application
except:
application = None
return application
class ApplicationWalletBalanceView(generics.RetrieveAPIView):
'''
API for getting authenticated user balance.
'''
permission_classes = [TokenHasScope]
serializer_class = WalletSerializer
required_scopes = ['wallet.application:get_balance']
def get_object(self):
return self.request.user
def retrieve(self, request, *args, **kwargs):
return super().retrieve(request, *args, **kwargs)
class TransactionDetail(generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticated, IsAuthenticatedOrTokenHasScope]
serializer_class = TransactionSerializer
lookup_field = 'uuid'
required_scopes = ['wallet.transaction:retrieve']
def get_queryset(self):
user = self.request.user
return Transaction.objects.filter(Q(payee=user) | Q(payer=user) | Q(payer__isnull=True)).all()
class TransactionPay(generics.RetrieveAPIView):
permission_classes = [permissions.IsAuthenticated, IsAuthenticatedOrTokenHasScope]
serializer_class = TransactionSerializer
lookup_field = 'uuid'
required_scopes = ['wallet.invoice:pay']
def get_queryset(self):
user = self.request.user
return Transaction.objects.filter(Q(payer=user) | Q(payer__isnull=True)).all()
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
instance.pay(payer=self.request.user)
serializer = self.get_serializer(instance)
return Response(serializer.data)

View file

@ -1,6 +1,7 @@
import datetime import datetime
import uuid import uuid
from django.core.validators import MinValueValidator
from django.db import models from django.db import models
from django.db import transaction from django.db import transaction
from django.db.models import F from django.db.models import F
@ -14,45 +15,40 @@ from ..gooyal_oauth2.models import Application
# TODO: move DRF functionalities to view or serializers # TODO: move DRF functionalities to view or serializers
class TransactionManager(models.Manager): # class TransactionManager(models.Manager):
def create_transaction( # def create_transaction(
self, # self,
amount, # amount,
payee, # payee_id,
payee_type, # payee_type,
payer=None, # payer_id=None,
payer_type=None, # payer_type=None,
delay=0, # delay=0,
detail=None, # detail=None,
application=None, # application=None,
uuid=None # uuid=None
): # ):
if amount <= 0: # tr = self.model(
raise ValidationError('amount should be greater than zero') # uuid=uuid,
if delay < 0: # payer_id=payer_id,
raise ValidationError('delay should be greater than equal zero') # payer_type=payer_type,
# payee_id=payee_id,
transaction = self.model( # payee_type=payee_type,
uuid=uuid, # amount=amount,
payer=payer, # delay=delay,
payer_type=payer_type, # application=application,
payee=payee, # detail=detail
payee_type=payee_type, # )
amount=amount, #
delay=delay, # tr.save()
application=application, # return tr
detail=detail
)
transaction.save()
return transaction
class Transaction(models.Model): class Transaction(models.Model):
uuid = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4, unique=True, uuid = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4, unique=True,
db_index=True) # reserve_code db_index=True) # reserve_code
amount = models.IntegerField(_('amount'), blank=False) amount = models.PositiveBigIntegerField(_('amount'), blank=False, validators=[MinValueValidator(1)])
delay = models.IntegerField(default=0, blank=True) # number of days for delayed payments delay = models.PositiveIntegerField(default=0, blank=True) # number of days for delayed payments
payer_id = models.UUIDField(blank=True, null=True) payer_id = models.UUIDField(blank=True, null=True)
payer_type = models.IntegerField(choices=TypeChoices.choices, blank=True, null=True) payer_type = models.IntegerField(choices=TypeChoices.choices, blank=True, null=True)
payee_id = models.UUIDField() payee_id = models.UUIDField()
@ -62,9 +58,9 @@ class Transaction(models.Model):
updated_at = models.DateTimeField(auto_now=True, null=True) updated_at = models.DateTimeField(auto_now=True, null=True)
application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT, application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT,
related_name='transactions', null=True) related_name='transactions', null=True)
detail = models.JSONField(null=True, blank=True, default={}) details = models.JSONField(null=True, blank=True, default=dict)
objects = TransactionManager() # objects = TransactionManager()
# class Meta: # class Meta:
# unique_together = ('application', 'detail_id',) # unique_together = ('application', 'detail_id',)

View file

@ -8,35 +8,28 @@ from ..users.models import User
class TransactionSerializer(serializers.ModelSerializer): class TransactionSerializer(serializers.ModelSerializer):
payee = serializers.UUIDField(read_only=True) payee_id = serializers.UUIDField(read_only=True)
payee_type = serializers.UUIDField(read_only=True)
class Meta: class Meta:
model = Transaction model = Transaction
fields = ('uuid', fields = ('uuid',
'payer', 'payer_id',
'payee', 'payer_type',
'payee_id',
'payee_type',
"created_at", "created_at",
"state", "state",
'amount', 'amount',
'delay', 'delay',
'updated_at', 'updated_at',
# 'detail_id', 'details',
) )
read_only_fields = ['uuid', 'updated_at', 'state', 'created_at'] # , 'detail_id'] read_only_fields = ['uuid', 'updated_at', 'state', 'created_at', 'details']
def create(self, validated_data): # def create(self, validated_data):
# payer = validated_data.get('payer') # transaction = Transaction.objects.create_transaction(**validated_data)
# request = self.context.get('request') # return transaction
# user = request.user if request else payer
# if user == payer:
# with atomic():
# transaction = Transaction.objects.create_transaction(**validated_data)
# transaction.pay()
#
# else:
transaction = Transaction.objects.create_transaction(**validated_data)
return transaction
class DepositSerializer(serializers.ModelSerializer): class DepositSerializer(serializers.ModelSerializer):

View file

@ -1,4 +1,6 @@
from django.urls import path from django.urls import path
from .application_views import ApplicationWalletBalanceView
from .views import TransactionList, TransactionDetail, TransactionPay, TransactionReceipt, \ from .views import TransactionList, TransactionDetail, TransactionPay, TransactionReceipt, \
WithdrawVerify, WithdrawSubmit, DepositSubmit, DepositVerify, TransactionListView, TransactionDetailView, \ WithdrawVerify, WithdrawSubmit, DepositSubmit, DepositVerify, TransactionListView, TransactionDetailView, \
WalletBalanceView WalletBalanceView
@ -21,4 +23,6 @@ urlpatterns = [
# #
path('api/withdraw/', WithdrawSubmit.as_view(), name='withdraw_submit_api'), path('api/withdraw/', WithdrawSubmit.as_view(), name='withdraw_submit_api'),
path('api/withdraw/<uuid>/verify', WithdrawVerify.as_view(), name='withdraw_verify_api'), path('api/withdraw/<uuid>/verify', WithdrawVerify.as_view(), name='withdraw_verify_api'),
path('api/get_balance/', ApplicationWalletBalanceView.as_view(), name='wallet_balance'),
] ]

View file

@ -7,6 +7,7 @@ from django.views.generic import DetailView, ListView, UpdateView
from oauth2_provider.contrib.rest_framework import TokenHasScope, IsAuthenticatedOrTokenHasScope from oauth2_provider.contrib.rest_framework import TokenHasScope, IsAuthenticatedOrTokenHasScope
from rest_framework import generics, permissions from rest_framework import generics, permissions
from rest_framework.permissions import AllowAny
from rest_framework.response import Response from rest_framework.response import Response
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
@ -30,32 +31,14 @@ class WalletBalanceView(generics.RetrieveAPIView):
''' '''
API for getting authenticated user balance. API for getting authenticated user balance.
''' '''
permission_classes = [permissions.IsAuthenticated, IsAuthenticatedOrTokenHasScope] permission_classes = [AllowAny, permissions.IsAuthenticated, IsAuthenticatedOrTokenHasScope]
serializer_class = WalletSerializer serializer_class = WalletSerializer
required_scopes = ['wallet.wallet:get_balance'] required_scopes = ['wallet.application:get_balance']
def get_object(self): def get_object(self):
return self.request.user return self.request.user
# TODO: this is user invoice create view
# class TransactionList(generics.ListCreateAPIView):
# permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
# serializer_class = TransactionSerializer
# required_alternate_scopes = {
# "GET": [['wallet.transaction:list']],
# "POST": [['wallet.invoice:create']],
# }
#
# def get_queryset(self):
# user = self.request.user
# return Transaction.objects.filter(Q(payee=user) | Q(payer=user)).all()
#
# def perform_create(self, serializer):
# user = self.request.user
# serializer.save(payee=user, application=get_application(self.request))
# this is application create invoice view # this is application create invoice view
class TransactionList(generics.ListCreateAPIView): class TransactionList(generics.ListCreateAPIView):
''' '''

View file

@ -144,7 +144,7 @@ TEMPLATES = [
AUTHENTICATION_BACKENDS = ( AUTHENTICATION_BACKENDS = (
'oauth2_provider.backends.OAuth2Backend', 'oauth2_provider.backends.OAuth2Backend',
'django.contrib.auth.backends.ModelBackend', # 'django.contrib.auth.backends.ModelBackend',
) )
WSGI_APPLICATION = 'wallet.wsgi.application' WSGI_APPLICATION = 'wallet.wsgi.application'