clean up
This commit is contained in:
parent
94a8e3f25f
commit
46230c3cfe
6 changed files with 106 additions and 20 deletions
|
|
@ -25,12 +25,12 @@ class ApplicationAdmin(ApplicationAdmin):
|
||||||
|
|
||||||
@admin.register(Resource)
|
@admin.register(Resource)
|
||||||
class ResourceAdmin(admin.ModelAdmin):
|
class ResourceAdmin(admin.ModelAdmin):
|
||||||
list_display = ("token", "user", "expires")
|
list_display = ("name", "token", "user", "expires")
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Scope)
|
@admin.register(Scope)
|
||||||
class ScopeAdmin(admin.ModelAdmin):
|
class ScopeAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name', 'description', 'is_default')
|
list_display = ('name', "resource", 'description', 'is_default')
|
||||||
|
|
||||||
|
|
||||||
# admin.site.register(RestrictedApplication, RestrictedApplicationAdmin)
|
# admin.site.register(RestrictedApplication, RestrictedApplicationAdmin)
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ class Resource(AbstractAccessToken):
|
||||||
application = None
|
application = None
|
||||||
|
|
||||||
uuid = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4, unique=True, db_index=True)
|
uuid = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4, unique=True, db_index=True)
|
||||||
name = models.CharField(max_length=255, blank=True)
|
name = models.CharField(max_length=255)
|
||||||
|
|
||||||
user = models.ForeignKey(
|
user = models.ForeignKey(
|
||||||
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True,
|
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True,
|
||||||
|
|
@ -55,6 +55,9 @@ class Resource(AbstractAccessToken):
|
||||||
def allow_scopes(self, scopes):
|
def allow_scopes(self, scopes):
|
||||||
return scopes == [self.scope]
|
return scopes == [self.scope]
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
class Scope(models.Model):
|
class Scope(models.Model):
|
||||||
"""
|
"""
|
||||||
|
|
@ -74,6 +77,13 @@ class Scope(models.Model):
|
||||||
help_text='The application to which the scope belongs.',
|
help_text='The application to which the scope belongs.',
|
||||||
related_name='scopes'
|
related_name='scopes'
|
||||||
)
|
)
|
||||||
|
resource = models.ForeignKey(
|
||||||
|
Resource,
|
||||||
|
models.PROTECT,
|
||||||
|
blank=True, null=True,
|
||||||
|
help_text='The resource of scope.',
|
||||||
|
related_name='scopes'
|
||||||
|
)
|
||||||
#: The name of the scope
|
#: The name of the scope
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
|
|
@ -91,6 +101,23 @@ class Scope(models.Model):
|
||||||
help_text='Indicates if this scope should be included in the default scopes.'
|
help_text='Indicates if this scope should be included in the default scopes.'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def final_name(self):
|
||||||
|
args = []
|
||||||
|
if self.resource:
|
||||||
|
args.append(self.resource.name)
|
||||||
|
|
||||||
|
args.append(self.name)
|
||||||
|
return '.'.join(args)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def final_description(self):
|
||||||
|
resource_name = self.resource and self.resource.name
|
||||||
|
|
||||||
|
if resource_name:
|
||||||
|
return f"{resource_name} -> {self.description}"
|
||||||
|
return self.description
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def register(cls, name, description, is_default=False):
|
def register(cls, name, description, is_default=False):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,16 @@ class Scopes(BaseScopes):
|
||||||
def get_queryset(self, application=None):
|
def get_queryset(self, application=None):
|
||||||
queryset = Scope.objects.all()
|
queryset = Scope.objects.all()
|
||||||
if application:
|
if application:
|
||||||
queryset = queryset.filter(name__in=application.allowed_scopes)
|
queryset = queryset.filter(name__in=application.allowed_scopes).order_by('resource__uuid')
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
def get_all_scopes(self):
|
def get_all_scopes(self):
|
||||||
return {scope.name: scope.description for scope in self.get_queryset().all()}
|
return {scope.final_name: scope.final_description for scope in self.get_queryset().all()}
|
||||||
|
|
||||||
def get_available_scopes(self, application=None, request=None, *args, **kwargs):
|
def get_available_scopes(self, application=None, request=None, *args, **kwargs):
|
||||||
scopes = [scope.name for scope in self.get_queryset(application).all()]
|
scopes = [scope.final_name for scope in self.get_queryset(application).all()]
|
||||||
return scopes
|
return scopes
|
||||||
|
|
||||||
def get_default_scopes(self, application=None, request=None, *args, **kwargs):
|
def get_default_scopes(self, application=None, request=None, *args, **kwargs):
|
||||||
return [scope.name for scope in self.get_queryset(application).filter(is_default=True).all()]
|
return [scope.final_name for scope in self.get_queryset(application).filter(is_default=True).all()]
|
||||||
|
|
|
||||||
0
apps/gooyal_oauth2/views/__init__.py
Normal file
0
apps/gooyal_oauth2/views/__init__.py
Normal file
|
|
@ -1,22 +1,81 @@
|
||||||
"""
|
import calendar
|
||||||
Django views for the gooyal-dynamic-scopes package.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import functools
|
import functools
|
||||||
|
import json
|
||||||
|
|
||||||
from django.conf import settings
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.http import HttpResponse, HttpResponseForbidden
|
from django.http import HttpResponse, HttpResponseForbidden
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.views.decorators.http import require_http_methods, require_POST
|
from django.views.decorators.http import require_http_methods
|
||||||
|
from oauth2_provider.models import get_access_token_model
|
||||||
|
from oauth2_provider.oauth2_backends import OAuthLibCore
|
||||||
|
from oauth2_provider.views import ClientProtectedScopedResourceView
|
||||||
from oauthlib.oauth2 import Server
|
from oauthlib.oauth2 import Server
|
||||||
|
|
||||||
from oauth2_provider.oauth2_backends import OAuthLibCore
|
|
||||||
from oauth2_provider.views import IntrospectTokenView
|
|
||||||
|
|
||||||
from apps.gooyal_oauth2.validators import IntrospectOAuth2Validator
|
from apps.gooyal_oauth2.validators import IntrospectOAuth2Validator
|
||||||
from .models import Scope
|
|
||||||
|
|
||||||
|
@method_decorator(csrf_exempt, name="dispatch")
|
||||||
|
class IntrospectTokenView(ClientProtectedScopedResourceView):
|
||||||
|
"""
|
||||||
|
Implements an endpoint for token introspection based
|
||||||
|
on RFC 7662 https://tools.ietf.org/html/rfc7662
|
||||||
|
|
||||||
|
To access this view the request must pass a OAuth2 Bearer Token
|
||||||
|
which is allowed to access the scope `introspection`.
|
||||||
|
"""
|
||||||
|
required_scopes = ["introspection"]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_token_response(token_value=None):
|
||||||
|
try:
|
||||||
|
token = get_access_token_model().objects.get(token=token_value)
|
||||||
|
except ObjectDoesNotExist:
|
||||||
|
return HttpResponse(
|
||||||
|
content=json.dumps({"active": False}),
|
||||||
|
status=401,
|
||||||
|
content_type="application/json"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if token.is_valid():
|
||||||
|
data = {
|
||||||
|
"active": True,
|
||||||
|
"scope": token.scope,
|
||||||
|
"exp": int(calendar.timegm(token.expires.timetuple())),
|
||||||
|
}
|
||||||
|
if token.application:
|
||||||
|
data["client_id"] = token.application.client_id
|
||||||
|
if token.user:
|
||||||
|
data["username"] = token.user.get_username()
|
||||||
|
return HttpResponse(content=json.dumps(data), status=200, content_type="application/json")
|
||||||
|
else:
|
||||||
|
return HttpResponse(content=json.dumps({
|
||||||
|
"active": False,
|
||||||
|
}), status=200, content_type="application/json")
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Get the token from the URL parameters.
|
||||||
|
URL: https://example.com/introspect?token=mF_9.B5f-4.1JqM
|
||||||
|
|
||||||
|
:param request:
|
||||||
|
:param args:
|
||||||
|
:param kwargs:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return self.get_token_response(request.GET.get("token", None))
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Get the token from the body form parameters.
|
||||||
|
Body: token=mF_9.B5f-4.1JqM
|
||||||
|
|
||||||
|
:param request:
|
||||||
|
:param args:
|
||||||
|
:param kwargs:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
return self.get_token_response(request.POST.get("token", None))
|
||||||
|
|
||||||
|
|
||||||
def protected_resource(scopes=None):
|
def protected_resource(scopes=None):
|
||||||
|
|
@ -20,7 +20,7 @@ from django.contrib.auth.views import LogoutView
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from apps.gooyal_oauth2.views import introspect_token
|
from apps.gooyal_oauth2.views.introspect import introspect_token
|
||||||
from apps.transactions.views import TransactionList, TransactionDetail, TransactionPay, TransactionReceipt, \
|
from apps.transactions.views import TransactionList, TransactionDetail, TransactionPay, TransactionReceipt, \
|
||||||
ServiceTransactionVerify, ServiceTransactionSubmit
|
ServiceTransactionVerify, ServiceTransactionSubmit
|
||||||
from apps.users.views import UserListView, UserDetailView, AccountView, RequestOTPView, ChangePasswordView, \
|
from apps.users.views import UserListView, UserDetailView, AccountView, RequestOTPView, ChangePasswordView, \
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue