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)
|
||||
class ResourceAdmin(admin.ModelAdmin):
|
||||
list_display = ("token", "user", "expires")
|
||||
list_display = ("name", "token", "user", "expires")
|
||||
|
||||
|
||||
@admin.register(Scope)
|
||||
class ScopeAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'description', 'is_default')
|
||||
list_display = ('name', "resource", 'description', 'is_default')
|
||||
|
||||
|
||||
# admin.site.register(RestrictedApplication, RestrictedApplicationAdmin)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class Resource(AbstractAccessToken):
|
|||
application = None
|
||||
|
||||
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(
|
||||
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True,
|
||||
|
|
@ -55,6 +55,9 @@ class Resource(AbstractAccessToken):
|
|||
def allow_scopes(self, scopes):
|
||||
return scopes == [self.scope]
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class Scope(models.Model):
|
||||
"""
|
||||
|
|
@ -74,6 +77,13 @@ class Scope(models.Model):
|
|||
help_text='The application to which the scope belongs.',
|
||||
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
|
||||
name = models.CharField(
|
||||
max_length=255,
|
||||
|
|
@ -91,6 +101,23 @@ class Scope(models.Model):
|
|||
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
|
||||
def register(cls, name, description, is_default=False):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -18,16 +18,16 @@ class Scopes(BaseScopes):
|
|||
def get_queryset(self, application=None):
|
||||
queryset = Scope.objects.all()
|
||||
if application:
|
||||
queryset = queryset.filter(name__in=application.allowed_scopes)
|
||||
queryset = queryset.filter(name__in=application.allowed_scopes).order_by('resource__uuid')
|
||||
return queryset
|
||||
|
||||
|
||||
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):
|
||||
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
|
||||
|
||||
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 @@
|
|||
"""
|
||||
Django views for the gooyal-dynamic-scopes package.
|
||||
"""
|
||||
|
||||
import json
|
||||
import calendar
|
||||
import functools
|
||||
import json
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
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.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 oauth2_provider.oauth2_backends import OAuthLibCore
|
||||
from oauth2_provider.views import IntrospectTokenView
|
||||
|
||||
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):
|
||||
|
|
@ -20,7 +20,7 @@ from django.contrib.auth.views import LogoutView
|
|||
from django.urls import path, include
|
||||
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, \
|
||||
ServiceTransactionVerify, ServiceTransactionSubmit
|
||||
from apps.users.views import UserListView, UserDetailView, AccountView, RequestOTPView, ChangePasswordView, \
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue