new type for payer and payee

This commit is contained in:
sahama 2024-08-10 18:36:33 +03:30
parent bd47c2252d
commit 95ed3a2d93
3 changed files with 73 additions and 11 deletions

View file

@ -1,8 +1,9 @@
import logging
from django.core.exceptions import ImproperlyConfigured
from oauth2_provider.contrib.rest_framework import TokenMatchesOASRequirements, OAuth2Authentication
from rest_framework.permissions import (
IsAuthenticated
IsAuthenticated, BasePermission
)
log = logging.getLogger("oauth2_provider")
@ -17,3 +18,57 @@ class IsAuthenticatedOrTokenMatchesOASRequirements(TokenMatchesOASRequirements):
token_has_scope = TokenMatchesOASRequirements()
return (is_authenticated and not oauth2authenticated) or token_has_scope.has_permission(request, view)
class ActionMatchesOASRequirements(BasePermission):
def has_permission(self, request, view):
token = request.auth
if not token:
return False
if hasattr(token, "scope"): # OAuth 2
# {'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy', 'head': 'retrieve'}
required_action_scopes = self.get_required_action_scopes(request, view)
action = request.action.upper()
if action in required_action_scopes:
log.debug(
"Required scopes actions to access resource: {0}".format(
required_action_scopes[action]
)
)
for alt in required_action_scopes[action]:
if token.is_valid(alt):
return True
return False
else:
log.warning("no scope alternates defined for method {0}".format(m))
return False
assert False, (
"ActionMatchesOASRequirements requires the"
"`oauth2_provider.rest_framework.OAuth2Authentication` authentication "
"class to be used."
)
def get_required_action_scopes(self, request, view):
try:
return getattr(view, "required_action_scopes")
except AttributeError:
raise ImproperlyConfigured(
"ActionMatchesOASRequirements requires the view to"
" define the required_action_scopes attribute"
)
class IsAuthenticatedOrActionMatchesOASRequirements(ActionMatchesOASRequirements):
def has_permission(self, request, view):
is_authenticated = IsAuthenticated().has_permission(request, view)
oauth2authenticated = False
if is_authenticated:
oauth2authenticated = isinstance(request.successful_authenticator, OAuth2Authentication)
action_has_scope = ActionMatchesOASRequirements()
return (is_authenticated and not oauth2authenticated) or action_has_scope.has_permission(request, view)

View file

@ -10,3 +10,8 @@ class StateChoices(IntegerChoices):
SUCCESS = 5 , _('success')
FAILED = 6 , _('failed')
EXPECTED_FAILURE = 7 , _('expected_failure') # no exact data available but guessed to be failed
class TypeChoices(IntegerChoices):
USER = 1 , _('user')
APPLICATION = 2 , _('application')

View file

@ -8,7 +8,7 @@ from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import APIException, ValidationError
from django.conf import settings
from oauth2_provider import settings as oauth2_settings
from .constans import StateChoices
from .constans import StateChoices, TypeChoices
from apps.users.models import User
@ -54,16 +54,18 @@ class Transaction(models.Model):
db_index=True) # reserve_code
amount = models.IntegerField(_('amount'), blank=False)
delay = models.IntegerField(default=0, blank=True) # number of days for delayed payments
payer = models.ForeignKey(User, on_delete=models.PROTECT, related_name='payments', blank=True, null=True)
payee = models.ForeignKey(User, on_delete=models.PROTECT, related_name='receipts')
payer_id = models.UUIDField(blank=True, null=True)
payer_type = models.IntegerField(choices=TypeChoices.choices, blank=True, null=True)
payee_id = models.UUIDField()
payee_type = models.IntegerField(choices=TypeChoices.choices, blank=True, null=True)
state = models.IntegerField(choices=StateChoices.choices, default=StateChoices.CREATED)
# create = models.DateTimeField(_('create'), blank=True, null=True, auto_now=True)
created_at = models.DateTimeField(_('created_at'), blank=True, null=True, auto_now=True)
# last_update = models.DateTimeField(_('last update'), blank=True, null=True, auto_now=True)
updated_at = models.DateTimeField(_('last update'), blank=True, null=True, auto_now=True)
application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT,
related_name='transactions', null=True)
detail_id = models.IntegerField(null=True, blank=True) # TODO: or better detail url
created_at = models.DateTimeField(auto_now_add=True, null=True)
updated_at = models.DateTimeField(auto_now=True, null=True)
payer_application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT,
related_name='payer_transactions', null=True)
payee_application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT,
related_name='payee_transactions', null=True)
detail = models.JSONField(null=True, blank=True, default={})
objects = TransactionManager()