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
|
import logging
|
||||||
|
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from oauth2_provider.contrib.rest_framework import TokenMatchesOASRequirements, OAuth2Authentication
|
from oauth2_provider.contrib.rest_framework import TokenMatchesOASRequirements, OAuth2Authentication
|
||||||
from rest_framework.permissions import (
|
from rest_framework.permissions import (
|
||||||
IsAuthenticated
|
IsAuthenticated, BasePermission
|
||||||
)
|
)
|
||||||
|
|
||||||
log = logging.getLogger("oauth2_provider")
|
log = logging.getLogger("oauth2_provider")
|
||||||
|
|
@ -17,3 +18,57 @@ class IsAuthenticatedOrTokenMatchesOASRequirements(TokenMatchesOASRequirements):
|
||||||
|
|
||||||
token_has_scope = TokenMatchesOASRequirements()
|
token_has_scope = TokenMatchesOASRequirements()
|
||||||
return (is_authenticated and not oauth2authenticated) or token_has_scope.has_permission(request, view)
|
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')
|
SUCCESS = 5 , _('success')
|
||||||
FAILED = 6 , _('failed')
|
FAILED = 6 , _('failed')
|
||||||
EXPECTED_FAILURE = 7 , _('expected_failure') # no exact data available but guessed to be 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 rest_framework.exceptions import APIException, ValidationError
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from oauth2_provider import settings as oauth2_settings
|
from oauth2_provider import settings as oauth2_settings
|
||||||
from .constans import StateChoices
|
from .constans import StateChoices, TypeChoices
|
||||||
from apps.users.models import User
|
from apps.users.models import User
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -54,16 +54,18 @@ class Transaction(models.Model):
|
||||||
db_index=True) # reserve_code
|
db_index=True) # reserve_code
|
||||||
amount = models.IntegerField(_('amount'), blank=False)
|
amount = models.IntegerField(_('amount'), blank=False)
|
||||||
delay = models.IntegerField(default=0, blank=True) # number of days for delayed payments
|
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)
|
payer_id = models.UUIDField(blank=True, null=True)
|
||||||
payee = models.ForeignKey(User, on_delete=models.PROTECT, related_name='receipts')
|
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)
|
state = models.IntegerField(choices=StateChoices.choices, default=StateChoices.CREATED)
|
||||||
# create = models.DateTimeField(_('create'), blank=True, null=True, auto_now=True)
|
created_at = models.DateTimeField(auto_now_add=True, null=True)
|
||||||
created_at = models.DateTimeField(_('created_at'), blank=True, null=True, auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True, null=True)
|
||||||
# last_update = models.DateTimeField(_('last update'), blank=True, null=True, auto_now=True)
|
payer_application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT,
|
||||||
updated_at = models.DateTimeField(_('last update'), blank=True, null=True, auto_now=True)
|
related_name='payer_transactions', null=True)
|
||||||
application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT,
|
payee_application = models.ForeignKey(oauth2_settings.APPLICATION_MODEL, on_delete=models.PROTECT,
|
||||||
related_name='transactions', null=True)
|
related_name='payee_transactions', null=True)
|
||||||
detail_id = models.IntegerField(null=True, blank=True) # TODO: or better detail url
|
detail = models.JSONField(null=True, blank=True, default={})
|
||||||
|
|
||||||
objects = TransactionManager()
|
objects = TransactionManager()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue