new type for payer and payee
This commit is contained in:
parent
bd47c2252d
commit
95ed3a2d93
3 changed files with 73 additions and 11 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue