request without user
This commit is contained in:
parent
6ee333cd06
commit
345bde39a3
7 changed files with 131 additions and 78 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
74
apps/wallet/application_views.py
Executable file
74
apps/wallet/application_views.py
Executable 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)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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',)
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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'),
|
||||||
]
|
]
|
||||||
|
|
@ -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):
|
||||||
'''
|
'''
|
||||||
|
|
|
||||||
|
|
@ -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'
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue