diff --git a/accounts/settings.py b/accounts/settings.py index 82ae3ae..6d94e5a 100644 --- a/accounts/settings.py +++ b/accounts/settings.py @@ -17,7 +17,6 @@ from decouple import config # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ @@ -29,7 +28,6 @@ DEBUG = True ALLOWED_HOSTS = ['*'] - # Application definition INSTALLED_APPS = [ @@ -39,7 +37,6 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - # 'dot_restrict_scopes', 'oauth2_provider', 'rest_framework', 'corsheaders', @@ -58,16 +55,7 @@ MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', ] -# Tell Django OAuth Toolkit to use the RestrictedApplication model -# OAUTH2_PROVIDER_APPLICATION_MODEL = 'dot_restrict_scopes.RestrictedApplication' -# OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = 'oauth2_provider.AccessToken' -# OAUTH2_PROVIDER_GRANT_MODEL = 'oauth2_provider.Grant' -# OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = 'oauth2_provider.RefreshToken' - - OAUTH2_PROVIDER = { - # Tell Django OAuth Toolkit to use the scopes backend - # 'SCOPES_BACKEND_CLASS': 'dot_restrict_scopes.scopes.RestrictApplicationScopes', # this is the list of available scopes 'SCOPES': {'read': 'Read scope', 'write': 'Write scope', @@ -76,13 +64,6 @@ OAUTH2_PROVIDER = { 'OAUTH2_VALIDATOR_CLASS': 'utils.MultiGatewayOAuth2Validator' } -# Tell dot-restrict-scopes which scopes backend it is wrapping -# NOTE: oauth2_provider.scopes.SettingsScopes is the default, so this is not -# strictly necessary if you want to use scopes from settings -# DOT_RESTRICT_SCOPES = { -# 'WRAPPED_SCOPES_BACKEND_CLASS': 'oauth2_provider.scopes.SettingsScopes', -# } - REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'oauth2_provider.contrib.rest_framework.OAuth2Authentication', @@ -115,7 +96,6 @@ TEMPLATES = [ WSGI_APPLICATION = 'accounts.wsgi.application' - # Database # https://docs.djangoproject.com/en/2.2/ref/settings/#databases @@ -148,7 +128,6 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] - # Internationalization # https://docs.djangoproject.com/en/2.2/topics/i18n/ @@ -162,7 +141,6 @@ USE_L10N = True USE_TZ = True - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.2/howto/static-files/ diff --git a/dot_restrict_scopes/__init__.py b/dot_restrict_scopes/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/dot_restrict_scopes/admin.py b/dot_restrict_scopes/admin.py deleted file mode 100644 index f52fc16..0000000 --- a/dot_restrict_scopes/admin.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -Django admin configuration for the dot-restrict-scopes package. -""" - -from django.contrib import admin -from django.contrib.admin.sites import NotRegistered - -from oauth2_provider.admin import ApplicationAdmin - -from .models import RestrictedApplication -from .forms import RestrictedApplicationForm - - -# The restricted application is registered by Django OAuth Toolkit, but we want -# to provide our own admin that uses our form -try: - admin.site.unregister(RestrictedApplication) -except NotRegistered: - pass - -@admin.register(RestrictedApplication) -class RestrictedApplicationAdmin(ApplicationAdmin): - form = RestrictedApplicationForm - -# admin.site.register(RestrictedApplication, RestrictedApplicationAdmin) diff --git a/dot_restrict_scopes/apps.py b/dot_restrict_scopes/apps.py deleted file mode 100644 index 1f8ab7e..0000000 --- a/dot_restrict_scopes/apps.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.apps import AppConfig - - -class DotRestrictScopesConfig(AppConfig): - name = 'dot_restrict_scopes' diff --git a/dot_restrict_scopes/forms.py b/dot_restrict_scopes/forms.py deleted file mode 100644 index aad5687..0000000 --- a/dot_restrict_scopes/forms.py +++ /dev/null @@ -1,51 +0,0 @@ -""" -Django forms for use with the dot-restrict-scopes package. -""" - -from django import forms - -from oauth2_provider.scopes import get_scopes_backend - - -class DelimitedListField(forms.MultipleChoiceField): - """ - Django form field that allows for the use of list widgets with a text field - containing a delimited list. - """ - delimiter = ',' - - def __init__(self, delimiter = None, *args, **kwargs): - super().__init__(*args, **kwargs) - self.delimiter = delimiter or self.delimiter - - def prepare_value(self, value): - # If the value is already a list or tuple, just use it as-is - if isinstance(value, (list, tuple)): return value - # Otherwise, prepare the value by splitting on the delimiter, trimming - # leading and trailing whitespace and excluding empty values - return [p.strip() for p in value.split(self.delimiter) if p.strip()] - - def clean(self, value): - # Let the parent clean the value first, then join the result using the - # specified delimiter - return self.delimiter.join(super().clean(value)) - - -class RestrictedApplicationForm(forms.ModelForm): - """ - Form for creating or updating a restricted application. - """ - # allowed_scope is a space-delimited list, but we want to present - # a selection of valid scopes with checkboxes - allowed_scope = DelimitedListField( - label = 'Allowed scopes', - # The choices and initial values are callables, because the scopes might - # not be available at import type, e.g. if coming from the database - choices = lambda: get_scopes_backend().get_all_scopes().items(), - initial = lambda: get_scopes_backend().get_default_scopes(), - delimiter = ' ', - widget = forms.CheckboxSelectMultiple - ) - - class Meta: - exclude = () diff --git a/dot_restrict_scopes/migrations/0001_initial.py b/dot_restrict_scopes/migrations/0001_initial.py deleted file mode 100644 index 53ae132..0000000 --- a/dot_restrict_scopes/migrations/0001_initial.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.4 on 2017-09-01 15:44 -from __future__ import unicode_literals - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import oauth2_provider.generators -import oauth2_provider.validators - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='RestrictedApplication', - fields=[ - ('id', models.BigAutoField(primary_key=True, serialize=False)), - ('client_id', models.CharField(db_index=True, default=oauth2_provider.generators.generate_client_id, max_length=100, unique=True)), - ('redirect_uris', models.TextField(blank=True, help_text='Allowed URIs list, space separated')), - ('client_type', models.CharField(choices=[('confidential', 'Confidential'), ('public', 'Public')], max_length=32)), - ('authorization_grant_type', models.CharField(choices=[('authorization-code', 'Authorization code'), ('implicit', 'Implicit'), ('password', 'Resource owner password-based'), ('client-credentials', 'Client credentials')], max_length=32)), - ('client_secret', models.CharField(blank=True, db_index=True, default=oauth2_provider.generators.generate_client_secret, max_length=255)), - ('name', models.CharField(blank=True, max_length=255)), - ('skip_authorization', models.BooleanField(default=False)), - ('created', models.DateTimeField(auto_now_add=True)), - ('updated', models.DateTimeField(auto_now=True)), - ('allowed_scope', models.TextField(blank=True)), - ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dot_restrict_scopes_restrictedapplication', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'abstract': False, - }, - ), - ] diff --git a/dot_restrict_scopes/migrations/__init__.py b/dot_restrict_scopes/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/dot_restrict_scopes/models.py b/dot_restrict_scopes/models.py deleted file mode 100644 index 689d111..0000000 --- a/dot_restrict_scopes/models.py +++ /dev/null @@ -1,25 +0,0 @@ -""" -Django models for the dot-restrict-scopes package. -""" - -from django.db import models - -from oauth2_provider.models import AbstractApplication -from oauth2_provider.scopes import get_scopes_backend - - -class RestrictedApplication(AbstractApplication): - """ - Application model for use with Django OAuth Toolkit that allows the scopes - available to an application to be restricted on a per-application basis. - """ - allowed_scope = models.TextField(blank = True) - - @property - def allowed_scopes(self): - """ - Returns the set of allowed scope names for this application. - """ - all_scopes = set(get_scopes_backend().get_all_scopes().keys()) - app_scopes = set(self.allowed_scope.split()) - return app_scopes.intersection(all_scopes) diff --git a/dot_restrict_scopes/scopes.py b/dot_restrict_scopes/scopes.py deleted file mode 100644 index 53f57ac..0000000 --- a/dot_restrict_scopes/scopes.py +++ /dev/null @@ -1,43 +0,0 @@ -""" -Django OAuth Toolkit scopes backend for the dot-restrict-scopes package. -""" - -from django.conf import settings -from django.utils import module_loading - -from oauth2_provider.scopes import BaseScopes - - -class RestrictApplicationScopes(BaseScopes): - """ - Scopes backend that wraps another backend and restricts the scopes available - to an application based on the application's ``allowed_scopes``. - """ - def __init__(self): - # Initialise the wrapped backend from settings - self._wrapped = module_loading.import_string( - getattr(settings, 'DOT_RESTRICT_SCOPES', {}).get( - 'WRAPPED_SCOPES_BACKEND_CLASS', - 'oauth2_provider.scopes.SettingsScopes' - ) - )() - - def get_all_scopes(self): - # Just return all the available scopes from the wrapped backend - return self._wrapped.get_all_scopes() - - def get_available_scopes(self, application = None, request = None, *args, **kwargs): - # Get the available scopes from the wrapped backend, then filter them - # based on the allowed_scopes of the application - scopes = self._wrapped.get_available_scopes(application, request, *args, **kwargs) - if application: - scopes = [s for s in scopes if s in application.allowed_scopes] - return scopes - - def get_default_scopes(self, application = None, request = None, *args, **kwargs): - # Get the default scopes from the wrapped backend, then filter them - # based on the allowed_scopes of the application - scopes = self._wrapped.get_default_scopes(application, request, *args, **kwargs) - if application: - scopes = [s for s in scopes if s in application.allowed_scopes] - return scopes