[Python-modules-commits] [django-oauth-toolkit] 01/01: Import django-oauth-toolkit_1.0.0.orig.tar.gz

Michael Fladischer fladi at moszumanska.debian.org
Thu Nov 2 16:08:19 UTC 2017


This is an automated email from the git hooks/post-receive script.

fladi pushed a commit to branch upstream
in repository django-oauth-toolkit.

commit 733e73785e1308e6544647a6aaef529395b58394
Author: Michael Fladischer <FladischerMichael at fladi.at>
Date:   Tue Jun 20 09:45:39 2017 +0200

    Import django-oauth-toolkit_1.0.0.orig.tar.gz
---
 .coveragerc                                        |    3 -
 .travis.yml                                        |   13 +-
 AUTHORS                                            |   22 +-
 CHANGELOG.md                                       |   16 +
 CONTRIBUTING.md                                    |    6 +
 CONTRIBUTING.rst                                   |    5 -
 README.rst                                         |    2 +-
 docs/conf.py                                       |   12 +-
 docs/index.rst                                     |    1 +
 docs/install.rst                                   |    2 +-
 docs/resource_server.rst                           |   68 ++
 docs/rest-framework/getting_started.rst            |    6 +-
 docs/rfc.py                                        |    6 +-
 docs/settings.rst                                  |   38 +-
 oauth2_provider/__init__.py                        |    7 +-
 oauth2_provider/admin.py                           |   10 +-
 oauth2_provider/apps.py                            |    2 +-
 oauth2_provider/compat.py                          |   14 +-
 oauth2_provider/{ext => contrib}/__init__.py       |    0
 .../{ext => contrib}/rest_framework/__init__.py    |    0
 .../rest_framework/authentication.py               |    2 +-
 .../{ext => contrib}/rest_framework/permissions.py |   22 +-
 oauth2_provider/decorators.py                      |    8 +-
 oauth2_provider/management/commands/cleartokens.py |    1 +
 oauth2_provider/middleware.py                      |   11 +-
 oauth2_provider/migrations/0001_initial.py         |   17 +-
 .../migrations/0005_auto_20170514_1141.py          |  102 ++
 oauth2_provider/models.py                          |  201 ++--
 oauth2_provider/oauth2_backends.py                 |   30 +-
 oauth2_provider/oauth2_validators.py               |  197 +++-
 oauth2_provider/settings.py                        |  119 ++-
 oauth2_provider/tests/models.py                    |    6 -
 oauth2_provider/tests/settings.py                  |  128 ---
 oauth2_provider/tests/test_application_views.py    |  100 --
 oauth2_provider/tests/test_authorization_code.py   | 1059 -------------------
 oauth2_provider/tests/test_models.py               |  179 ----
 oauth2_provider/tests/test_token_revocation.py     |  169 ---
 oauth2_provider/tests/test_token_view.py           |  179 ----
 oauth2_provider/tests/test_utils.py                |   17 -
 oauth2_provider/tests/urls.py                      |   16 -
 oauth2_provider/urls.py                            |   24 +-
 oauth2_provider/validators.py                      |   35 +-
 oauth2_provider/views/__init__.py                  |    1 +
 oauth2_provider/views/application.py               |   31 +-
 oauth2_provider/views/base.py                      |   92 +-
 oauth2_provider/views/generic.py                   |    2 +-
 oauth2_provider/views/introspect.py                |   75 ++
 oauth2_provider/views/mixins.py                    |   23 +-
 oauth2_provider/views/token.py                     |   24 +-
 requirements/base.txt                              |    4 -
 requirements/optional.txt                          |    2 -
 requirements/project.txt                           |    2 -
 requirements/testing.txt                           |    7 -
 runtests.py                                        |    8 -
 setup.cfg                                          |   37 +
 setup.py                                           |   56 +-
 {oauth2_provider/tests => tests}/__init__.py       |    0
 tests/models.py                                    |   22 +
 tests/settings.py                                  |  126 +++
 tests/test_application_views.py                    |  104 ++
 .../tests => tests}/test_auth_backends.py          |   70 +-
 tests/test_authorization_code.py                   | 1071 ++++++++++++++++++++
 .../tests => tests}/test_client_credential.py      |   93 +-
 .../tests => tests}/test_decorators.py             |   45 +-
 {oauth2_provider/tests => tests}/test_generator.py |    8 +-
 {oauth2_provider/tests => tests}/test_implicit.py  |  181 ++--
 tests/test_introspection_auth.py                   |  195 ++++
 tests/test_introspection_view.py                   |  260 +++++
 {oauth2_provider/tests => tests}/test_mixins.py    |   17 +-
 tests/test_models.py                               |  294 ++++++
 .../tests => tests}/test_oauth2_backends.py        |   18 +-
 .../tests => tests}/test_oauth2_validators.py      |  106 +-
 {oauth2_provider/tests => tests}/test_password.py  |   62 +-
 .../tests => tests}/test_rest_framework.py         |  116 ++-
 {oauth2_provider/tests => tests}/test_scopes.py    |  272 ++---
 .../tests => tests}/test_scopes_backend.py         |    0
 tests/test_token_revocation.py                     |  181 ++++
 tests/test_token_view.py                           |  206 ++++
 .../tests => tests}/test_validators.py             |   26 +-
 tests/urls.py                                      |   12 +
 tests/utils.py                                     |   16 +
 tox.ini                                            |   69 +-
 82 files changed, 3970 insertions(+), 2819 deletions(-)

diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index d1e8992..0000000
--- a/.coveragerc
+++ /dev/null
@@ -1,3 +0,0 @@
-[run]
-source = oauth2_provider
-omit = */migrations/*
diff --git a/.travis.yml b/.travis.yml
index c9f1a6a..8e09ce6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,16 +5,10 @@ python:
 sudo: false
 
 env:
-  - TOXENV=py27-django18
-  - TOXENV=py27-django19
   - TOXENV=py27-django110
   - TOXENV=py27-django111
-  - TOXENV=py34-django18
-  - TOXENV=py34-django19
   - TOXENV=py34-django110
   - TOXENV=py34-django111
-  - TOXENV=py35-django18
-  - TOXENV=py35-django19
   - TOXENV=py35-django110
   - TOXENV=py35-django111
   - TOXENV=py35-djangomaster
@@ -39,8 +33,13 @@ matrix:
     - env: TOXENV=py35-djangomaster
     - env: TOXENV=py36-djangomaster
 
+cache:
+  directories:
+    - $HOME/.cache/pip
+    - $TRAVIS_BUILD_DIR/.tox
+
 install:
-  - pip install coveralls tox "virtualenv<14"
+  - pip install coveralls tox
 
 script:
   - tox
diff --git a/AUTHORS b/AUTHORS
index 3600835..88dabd0 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -7,19 +7,21 @@ Federico Frenguelli
 Contributors
 ============
 
-Stéphane Raimbault
-Emanuele Palazzetti
-David Fischer
+Alessandro De Angelis
 Ash Christopher
-Rodney Richardson
-Hiroki Kiyohara
-Diego Garcia
-Bas van Oostveen
+Aristóbulo Meneses
 Bart Merenda
-Paul Oswald
+Bas van Oostveen
+David Fischer
+Diego Garcia
+Emanuele Palazzetti
+Federico Dolce
+Hiroki Kiyohara
 Jens Timmerman
+Jerome Leclanche
 Jim Graham
+Paul Oswald
 pySilver
+Rodney Richardson
 Silvano Cerza
-Federico Dolce
-Alessandro De Angelis
+Stéphane Raimbault
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 46d3746..4611e0d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+### 1.0.0 [2017-06-07]
+
+* **New feature**: AccessToken, RefreshToken and Grant models are now swappable.
+* #477: **New feature**: Add support for RFC 7662 (IntrospectTokenView, introspect scope)
+* **Compatibility**: Django 1.10 is the new minimum required version
+* **Compatibility**: Django 1.11 is now supported
+* **Backwards-incompatible**: The `oauth2_provider.ext.rest_framework` module
+  has been moved to `oauth2_provider.contrib.rest_framework`
+* #177: Changed `id` field on Application, AccessToken, RefreshToken and Grant to BigAutoField (bigint/bigserial)
+* #321: Added `created` and `updated` auto fields to Application, AccessToken, RefreshToken and Grant
+* #476: Disallow empty redirect URIs
+* Fixed bad `url` parameter in some error responses.
+* Django 2.0 compatibility fixes.
+* The dependency on django-braces has been dropped.
+* The oauthlib dependency is no longer pinned.
+
 ### 0.12.0 [2017-02-24]
 
 * **New feature**: Class-based scopes backends. Listing scopes, available scopes and default scopes
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..f1703ac
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,6 @@
+# Contribute to Django OAuth Toolkit
+
+Thanks for your interest, we love contributions!
+
+Please [follow these guidelines](https://django-oauth-toolkit.readthedocs.io/en/latest/contributing.html)
+when submitting pull requests.
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
deleted file mode 100644
index 61d1327..0000000
--- a/CONTRIBUTING.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-Contributing
-============
-
-Thanks for your interest! We love contributions, so please feel free to fix bugs, improve things, provide documentation. Just `follow the
-guidelines <https://django-oauth-toolkit.readthedocs.io/en/latest/contributing.html>`_ and submit a PR.
diff --git a/README.rst b/README.rst
index a2eb108..4592aa3 100644
--- a/README.rst
+++ b/README.rst
@@ -48,7 +48,7 @@ Requirements
 ------------
 
 * Python 2.7, 3.4, 3.5, 3.6
-* Django 1.8, 1.9, 1.10, 1.11
+* Django 1.10, 1.11
 
 Installation
 ------------
diff --git a/docs/conf.py b/docs/conf.py
index 2fdfe97..321887d 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -20,7 +20,7 @@ here = os.path.abspath(os.path.dirname(__file__))
 sys.path.insert(0, here)
 sys.path.insert(0, os.path.dirname(here))
 
-os.environ['DJANGO_SETTINGS_MODULE'] = 'oauth2_provider.tests.settings'
+os.environ["DJANGO_SETTINGS_MODULE"] = "tests.settings"
 
 import django
 django.setup()
@@ -53,20 +53,12 @@ project = u'Django OAuth Toolkit'
 copyright = u'2013, Evonove'
 
 
-def get_version(package):
-    """
-    Return package version as listed in `__version__` in `init.py`.
-    """
-    init_py = open(os.path.join(package, '__init__.py')).read()
-    return re.match("__version__ = ['\"]([^'\"]+)['\"]", init_py).group(1)
-
-
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
 # The short X.Y version.
-version = get_version(os.path.join("..", "oauth2_provider"))
+version = oauth2_provider.__version__
 # The full version, including alpha/beta/rc tags.
 release = version
 
diff --git a/docs/index.rst b/docs/index.rst
index 9a79b6d..4b1c13a 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -39,6 +39,7 @@ Index
    models
    advanced_topics
    settings
+   resource_server
    management_commands
    glossary
 
diff --git a/docs/install.rst b/docs/install.rst
index 60e9d8f..462e2d5 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -2,7 +2,7 @@ Installation
 ============
 
 Install with pip
-
+::
     pip install django-oauth-toolkit
 
 Add `oauth2_provider` to your `INSTALLED_APPS`
diff --git a/docs/resource_server.rst b/docs/resource_server.rst
new file mode 100644
index 0000000..d0d5d23
--- /dev/null
+++ b/docs/resource_server.rst
@@ -0,0 +1,68 @@
+Separate Resource Server
+========================
+Django OAuth Toolkit allows to separate the :term:`Authentication Server` and the :term:`Resource Server.`
+Based one the `RFC 7662 <https://tools.ietf.org/html/rfc7662>`_ Django OAuth Toolkit provides
+a rfc-compliant introspection endpoint.
+As well the Django OAuth Toolkit allows to verify access tokens by the use of an introspection endpoint.
+
+
+Setup the Authentication Server
+-------------------------------
+Setup the :term:`Authentication Server` as described in the :ref:`tutorial`.
+Create a OAuth2 access token for the :term:`Resource Server` and add the
+``introspection``-Scope to the settings.
+
+.. code-block:: python
+
+    'SCOPES': {
+        'read': 'Read scope',
+        'write': 'Write scope',
+        'introspection': 'Introspect token scope',
+        ...
+    },
+
+The :term:`Authentication Server` will listen for introspection requests.
+The endpoint is located within the ``oauth2_provider.urls`` as ``/introspect/``.
+
+Example Request::
+
+    POST /o/introspect/ HTTP/1.1
+    Host: server.example.com
+    Accept: application/json
+    Content-Type: application/x-www-form-urlencoded
+    Authorization: Bearer 3yUqsWtwKYKHnfivFcJu
+
+    token=uH3Po4KXWP4dsY4zgyxH
+
+Example Response::
+
+    HTTP/1.1 200 OK
+    Content-Type: application/json
+
+    {
+      "active": true,
+      "client_id": "oUdofn7rfhRtKWbmhyVk",
+      "username": "jdoe",
+      "scope": "read write dolphin",
+      "exp": 1419356238
+    }
+
+Setup the Resource Server
+-------------------------
+Setup the :term:`Resource Server` like the :term:`Authentication Server` as described in the :ref:`tutorial`.
+Add ``RESOURCE_SERVER_INTROSPECTION_URL`` and ``RESOURCE_SERVER_AUTH_TOKEN`` to your settings.
+The :term:`Resource Server` will try to verify its requests on the :term:`Authentication Server`.
+
+.. code-block:: python
+
+    OAUTH2_PROVIDER = {
+        ...
+        'RESOURCE_SERVER_INTROSPECTION_URL': 'https://example.org/o/introspect/',
+        'RESOURCE_SERVER_AUTH_TOKEN': '3yUqsWtwKYKHnfivFcJu',
+        ...
+    }
+
+``RESOURCE_SERVER_INTROSPECTION_URL`` defines the introspection endpoint and
+``RESOURCE_SERVER_AUTH_TOKEN`` an authentication token to authenticate against the
+:term:`Authentication Server`.
+
diff --git a/docs/rest-framework/getting_started.rst b/docs/rest-framework/getting_started.rst
index 3d5388f..e929b23 100644
--- a/docs/rest-framework/getting_started.rst
+++ b/docs/rest-framework/getting_started.rst
@@ -35,7 +35,7 @@ To do so add the following lines at the end of your `settings.py` module:
 
     REST_FRAMEWORK = {
         'DEFAULT_AUTHENTICATION_CLASSES': (
-            'oauth2_provider.ext.rest_framework.OAuth2Authentication',
+            'oauth2_provider.contrib.rest_framework.OAuth2Authentication',
         )
     }
 
@@ -55,18 +55,20 @@ Here's our project's root `urls.py` module:
 
     from rest_framework import permissions, routers, serializers, viewsets
 
-    from oauth2_provider.ext.rest_framework import TokenHasReadWriteScope, TokenHasScope
+    from oauth2_provider.contrib.rest_framework import TokenHasReadWriteScope, TokenHasScope
 
 
     # first we define the serializers
     class UserSerializer(serializers.ModelSerializer):
         class Meta:
             model = User
+            fields = ("username", "email", "first_name", "last_name", )
 
 
     class GroupSerializer(serializers.ModelSerializer):
         class Meta:
             model = Group
+            fields = ("name", )
 
 
     # ViewSets define the view behavior.
diff --git a/docs/rfc.py b/docs/rfc.py
index e6a8fb9..e5af5f4 100644
--- a/docs/rfc.py
+++ b/docs/rfc.py
@@ -1,7 +1,8 @@
 """
 Custom Sphinx documentation module to link to parts of the OAuth2 RFC.
 """
-from docutils import nodes, utils
+from docutils import nodes
+
 
 base_url = "http://tools.ietf.org/html/rfc6749"
 
@@ -33,5 +34,4 @@ def setup(app):
 
     :param app: Sphinx application context.
     """
-    app.add_role('rfc', rfclink)
-    return
+    app.add_role("rfc", rfclink)
diff --git a/docs/settings.rst b/docs/settings.rst
index c93f1dd..9ac4b9a 100644
--- a/docs/settings.rst
+++ b/docs/settings.rst
@@ -1,8 +1,9 @@
 Settings
 ========
 
-Our configurations are all namespaced under the `OAUTH2_PROVIDER` settings with the solely exception of
-`OAUTH2_PROVIDER_APPLICATION_MODEL`: this is because of the way Django currently implements
+Our configurations are all namespaced under the `OAUTH2_PROVIDER` settings with the exception of
+`OAUTH2_PROVIDER_APPLICATION_MODEL, OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL, OAUTH2_PROVIDER_GRANT_MODEL,
+OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL`: this is because of the way Django currently implements
 swappable models. See issue #90 (https://github.com/evonove/django-oauth-toolkit/issues/90) for details.
 
 For example:
@@ -32,6 +33,12 @@ The number of seconds an access token remains valid. Requesting a protected
 resource after this duration will fail. Keep this value high enough so clients
 can cache the token for a reasonable amount of time.
 
+ACCESS_TOKEN_MODEL
+~~~~~~~~~~~~~~~~~~
+The import string of the class (model) representing your access tokens. Overwrite
+this value if you wrote your own implementation (subclass of
+``oauth2_provider.models.AccessToken``).
+
 ALLOWED_REDIRECT_URI_SCHEMES
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -67,6 +74,12 @@ CLIENT_SECRET_GENERATOR_LENGTH
 The length of the generated secrets, in characters. If this value is too low,
 secrets may become subject to bruteforce guessing.
 
+GRANT_MODEL
+~~~~~~~~~~~~~~~~~
+The import string of the class (model) representing your grants. Overwrite
+this value if you wrote your own implementation (subclass of
+``oauth2_provider.models.Grant``).
+
 OAUTH2_SERVER_CLASS
 ~~~~~~~~~~~~~~~~~~~
 The import string for the ``server_class`` (or ``oauthlib.oauth2.Server`` subclass)
@@ -87,6 +100,12 @@ REFRESH_TOKEN_EXPIRE_SECONDS
 The number of seconds before a refresh token gets removed from the database by
 the ``cleartokens`` management command. Check :ref:`cleartokens` management command for further info.
 
+REFRESH_TOKEN_MODEL
+~~~~~~~~~~~~~~~~~~~
+The import string of the class (model) representing your refresh tokens. Overwrite
+this value if you wrote your own implementation (subclass of
+``oauth2_provider.models.RefreshToken``).
+
 ROTATE_REFRESH_TOKEN
 ~~~~~~~~~~~~~~~~~~~~
 When is set to `True` (default) a new refresh token is issued to the client when the client refreshes an access token.
@@ -132,3 +151,18 @@ WRITE_SCOPE
 .. note:: (0.12.0+) Only used if `SCOPES_BACKEND_CLASS` is set to the SettingsScopes default.
 
 The name of the *write* scope.
+
+RESOURCE_SERVER_INTROSPECTION_URL
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The introspection endpoint for validating token remotely (RFC7662).
+
+RESOURCE_SERVER_AUTH_TOKEN
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+The bearer token to authenticate the introspection request towards the introspection endpoint (RFC7662).
+
+
+RESOURCE_SERVER_TOKEN_CACHING_SECONDS
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The number of seconds an authorization token received from the introspection endpoint remains valid.
+If the expire time of the received token is less than ``RESOURCE_SERVER_TOKEN_CACHING_SECONDS`` the expire time
+will be used.
diff --git a/oauth2_provider/__init__.py b/oauth2_provider/__init__.py
index 1bf8358..c4e8c4e 100644
--- a/oauth2_provider/__init__.py
+++ b/oauth2_provider/__init__.py
@@ -1,7 +1,6 @@
-__version__ = '0.12.0'
+import pkg_resources
 
-__author__ = "Massimiliano Pippi & Federico Frenguelli"
 
-default_app_config = 'oauth2_provider.apps.DOTConfig'
+__version__ = pkg_resources.require("django-oauth-toolkit")[0].version
 
-VERSION = __version__  # synonym
+default_app_config = "oauth2_provider.apps.DOTConfig"
diff --git a/oauth2_provider/admin.py b/oauth2_provider/admin.py
index cbb0c2c..1f8312f 100644
--- a/oauth2_provider/admin.py
+++ b/oauth2_provider/admin.py
@@ -1,6 +1,11 @@
 from django.contrib import admin
 
-from .models import Grant, AccessToken, RefreshToken, get_application_model
+from .models import (
+    get_access_token_model,
+    get_application_model,
+    get_grant_model,
+    get_refresh_token_model,
+)
 
 
 class ApplicationAdmin(admin.ModelAdmin):
@@ -29,6 +34,9 @@ class RefreshTokenAdmin(admin.ModelAdmin):
 
 
 Application = get_application_model()
+Grant = get_grant_model()
+AccessToken = get_access_token_model()
+RefreshToken = get_refresh_token_model()
 
 admin.site.register(Application, ApplicationAdmin)
 admin.site.register(Grant, GrantAdmin)
diff --git a/oauth2_provider/apps.py b/oauth2_provider/apps.py
index 6f67f38..887e4e3 100644
--- a/oauth2_provider/apps.py
+++ b/oauth2_provider/apps.py
@@ -2,5 +2,5 @@ from django.apps import AppConfig
 
 
 class DOTConfig(AppConfig):
-    name = 'oauth2_provider'
+    name = "oauth2_provider"
     verbose_name = "Django OAuth Toolkit"
diff --git a/oauth2_provider/compat.py b/oauth2_provider/compat.py
index 3ef0b37..4e8be22 100644
--- a/oauth2_provider/compat.py
+++ b/oauth2_provider/compat.py
@@ -7,20 +7,14 @@ from __future__ import unicode_literals
 
 # urlparse in python3 has been renamed to urllib.parse
 try:
-    from urlparse import urlparse, parse_qs, parse_qsl, urlunparse
+    from urlparse import parse_qs, parse_qsl, urlparse, urlsplit, urlunparse, urlunsplit
 except ImportError:
-    from urllib.parse import urlparse, parse_qs, parse_qsl, urlunparse
+    from urllib.parse import parse_qs, parse_qsl, urlparse, urlsplit, urlunsplit, urlunparse
 
 try:
-    from urllib import urlencode, unquote_plus
+    from urllib import urlencode, quote_plus, unquote_plus
 except ImportError:
-    from urllib.parse import urlencode, unquote_plus
-
-# changed in Django 1.10 (broken in Django 2.0)
-try:
-    from django.urls import reverse, reverse_lazy
-except ImportError:
-    from django.core.urlresolvers import reverse, reverse_lazy
+    from urllib.parse import urlencode, quote_plus, unquote_plus
 
 # bastb Django 1.10 has updated Middleware. This code imports the Mixin required to get old-style
 # middleware working again
diff --git a/oauth2_provider/ext/__init__.py b/oauth2_provider/contrib/__init__.py
similarity index 100%
rename from oauth2_provider/ext/__init__.py
rename to oauth2_provider/contrib/__init__.py
diff --git a/oauth2_provider/ext/rest_framework/__init__.py b/oauth2_provider/contrib/rest_framework/__init__.py
similarity index 100%
rename from oauth2_provider/ext/rest_framework/__init__.py
rename to oauth2_provider/contrib/rest_framework/__init__.py
diff --git a/oauth2_provider/ext/rest_framework/authentication.py b/oauth2_provider/contrib/rest_framework/authentication.py
similarity index 95%
rename from oauth2_provider/ext/rest_framework/authentication.py
rename to oauth2_provider/contrib/rest_framework/authentication.py
index 35c7439..2383078 100644
--- a/oauth2_provider/ext/rest_framework/authentication.py
+++ b/oauth2_provider/contrib/rest_framework/authentication.py
@@ -7,7 +7,7 @@ class OAuth2Authentication(BaseAuthentication):
     """
     OAuth 2 authentication backend using `django-oauth-toolkit`
     """
-    www_authenticate_realm = 'api'
+    www_authenticate_realm = "api"
 
     def authenticate(self, request):
         """
diff --git a/oauth2_provider/ext/rest_framework/permissions.py b/oauth2_provider/contrib/rest_framework/permissions.py
similarity index 84%
rename from oauth2_provider/ext/rest_framework/permissions.py
rename to oauth2_provider/contrib/rest_framework/permissions.py
index 9971065..cce946a 100644
--- a/oauth2_provider/ext/rest_framework/permissions.py
+++ b/oauth2_provider/contrib/rest_framework/permissions.py
@@ -1,16 +1,15 @@
 import logging
 
 from django.core.exceptions import ImproperlyConfigured
-
 from rest_framework.permissions import BasePermission, IsAuthenticated
-from .authentication import OAuth2Authentication
 
+from .authentication import OAuth2Authentication
 from ...settings import oauth2_settings
 
 
-log = logging.getLogger('oauth2_provider')
+log = logging.getLogger("oauth2_provider")
 
-SAFE_HTTP_METHODS = ['GET', 'HEAD', 'OPTIONS']
+SAFE_HTTP_METHODS = ["GET", "HEAD", "OPTIONS"]
 
 
 class TokenHasScope(BasePermission):
@@ -24,22 +23,23 @@ class TokenHasScope(BasePermission):
         if not token:
             return False
 
-        if hasattr(token, 'scope'):  # OAuth 2
+        if hasattr(token, "scope"):  # OAuth 2
             required_scopes = self.get_scopes(request, view)
             log.debug("Required scopes to access resource: {0}".format(required_scopes))
 
             return token.is_valid(required_scopes)
 
-        assert False, ('TokenHasScope requires the'
-                       '`oauth2_provider.rest_framework.OAuth2Authentication` authentication '
-                       'class to be used.')
+        assert False, ("TokenHasScope requires the"
+                       "`oauth2_provider.rest_framework.OAuth2Authentication` authentication "
+                       "class to be used.")
 
     def get_scopes(self, request, view):
         try:
-            return getattr(view, 'required_scopes')
+            return getattr(view, "required_scopes")
         except AttributeError:
             raise ImproperlyConfigured(
-                'TokenHasScope requires the view to define the required_scopes attribute')
+                "TokenHasScope requires the view to define the required_scopes attribute"
+            )
 
 
 class TokenHasReadWriteScope(TokenHasScope):
@@ -81,7 +81,7 @@ class TokenHasResourceScope(TokenHasScope):
             scope_type = oauth2_settings.WRITE_SCOPE
 
         required_scopes = [
-            '{0}:{1}'.format(scope, scope_type) for scope in view_scopes
+            "{}:{}".format(scope, scope_type) for scope in view_scopes
         ]
 
         return required_scopes
diff --git a/oauth2_provider/decorators.py b/oauth2_provider/decorators.py
index 8887175..d4b7085 100644
--- a/oauth2_provider/decorators.py
+++ b/oauth2_provider/decorators.py
@@ -1,11 +1,11 @@
 from functools import wraps
 
-from oauthlib.oauth2 import Server
-from django.http import HttpResponseForbidden
 from django.core.exceptions import ImproperlyConfigured
+from django.http import HttpResponseForbidden
+from oauthlib.oauth2 import Server
 
-from .oauth2_validators import OAuth2Validator
 from .oauth2_backends import OAuthLibCore
+from .oauth2_validators import OAuth2Validator
 from .scopes import get_scopes_backend
 from .settings import oauth2_settings
 
@@ -67,7 +67,7 @@ def rw_protected_resource(scopes=None, validator_cls=OAuth2Validator, server_cls
                 )
 
             # Check if method is safe
-            if request.method.upper() in ['GET', 'HEAD', 'OPTIONS']:
+            if request.method.upper() in ["GET", "HEAD", "OPTIONS"]:
                 _scopes.append(oauth2_settings.READ_SCOPE)
             else:
                 _scopes.append(oauth2_settings.WRITE_SCOPE)
diff --git a/oauth2_provider/management/commands/cleartokens.py b/oauth2_provider/management/commands/cleartokens.py
index 48f70b8..3fb1827 100644
--- a/oauth2_provider/management/commands/cleartokens.py
+++ b/oauth2_provider/management/commands/cleartokens.py
@@ -1,4 +1,5 @@
 from django.core.management.base import BaseCommand
+
 from ...models import clear_expired
 
 
diff --git a/oauth2_provider/middleware.py b/oauth2_provider/middleware.py
index 02f722a..f41f3f3 100644
--- a/oauth2_provider/middleware.py
+++ b/oauth2_provider/middleware.py
@@ -1,5 +1,6 @@
 from django.contrib.auth import authenticate
 from django.utils.cache import patch_vary_headers
+
 from .compat import MiddlewareMixin
 
 
@@ -19,17 +20,17 @@ class OAuth2TokenMiddleware(MiddlewareMixin):
     also request._cached_user field makes AuthenticationMiddleware use that instead of the one from
     the session.
 
-    It also adds 'Authorization' to the 'Vary' header. So that django's cache middleware or a
-    reverse proxy can create proper cache keys
+    It also adds "Authorization" to the "Vary" header, so that django's cache middleware or a
+    reverse proxy can create proper cache keys.
     """
     def process_request(self, request):
         # do something only if request contains a Bearer token
-        if request.META.get('HTTP_AUTHORIZATION', '').startswith('Bearer'):
-            if not hasattr(request, 'user') or request.user.is_anonymous():
+        if request.META.get("HTTP_AUTHORIZATION", "").startswith("Bearer"):
+            if not hasattr(request, "user") or request.user.is_anonymous:
                 user = authenticate(request=request)
                 if user:
                     request.user = request._cached_user = user
 
     def process_response(self, request, response):
-        patch_vary_headers(response, ('Authorization',))
+        patch_vary_headers(response, ("Authorization",))
         return response
diff --git a/oauth2_provider/migrations/0001_initial.py b/oauth2_provider/migrations/0001_initial.py
index d896a83..4b56010 100644
--- a/oauth2_provider/migrations/0001_initial.py
+++ b/oauth2_provider/migrations/0001_initial.py
@@ -13,6 +13,9 @@ class Migration(migrations.Migration):
     dependencies = [
         migrations.swappable_dependency(settings.AUTH_USER_MODEL),
         migrations.swappable_dependency(oauth2_settings.APPLICATION_MODEL),
+        migrations.swappable_dependency(oauth2_settings.ACCESS_TOKEN_MODEL),
+        migrations.swappable_dependency(oauth2_settings.REFRESH_TOKEN_MODEL),
+        migrations.swappable_dependency(oauth2_settings.GRANT_MODEL),
     ]
 
     operations = [
@@ -43,6 +46,10 @@ class Migration(migrations.Migration):
                 ('application', models.ForeignKey(to=oauth2_settings.APPLICATION_MODEL, on_delete=models.CASCADE)),
                 ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
             ],
+            options={
+                'abstract': False,
+                'swappable': 'OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL',
+            },
         ),
         migrations.CreateModel(
             name='Grant',
@@ -55,15 +62,23 @@ class Migration(migrations.Migration):
                 ('application', models.ForeignKey(to=oauth2_settings.APPLICATION_MODEL, on_delete=models.CASCADE)),
                 ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
             ],
+            options={
+                'abstract': False,
+                'swappable': 'OAUTH2_PROVIDER_GRANT_MODEL',
+            },
         ),
         migrations.CreateModel(
             name='RefreshToken',
             fields=[
                 ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                 ('token', models.CharField(max_length=255, db_index=True)),
-                ('access_token', models.OneToOneField(related_name='refresh_token', to='oauth2_provider.AccessToken', on_delete=models.CASCADE)),
+                ('access_token', models.OneToOneField(related_name='refresh_token', to=oauth2_settings.ACCESS_TOKEN_MODEL, on_delete=models.CASCADE)),
                 ('application', models.ForeignKey(to=oauth2_settings.APPLICATION_MODEL, on_delete=models.CASCADE)),
                 ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
             ],
+            options={
+                'abstract': False,
+                'swappable': 'OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL',
+            },
         ),
     ]
diff --git a/oauth2_provider/migrations/0005_auto_20170514_1141.py b/oauth2_provider/migrations/0005_auto_20170514_1141.py
new file mode 100644
index 0000000..4eca6c8
--- /dev/null
+++ b/oauth2_provider/migrations/0005_auto_20170514_1141.py
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.1 on 2017-05-14 11:41
+from __future__ import unicode_literals
+
+from oauth2_provider.settings import oauth2_settings
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('oauth2_provider', '0004_auto_20160525_1623'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='accesstoken',
+            name='application',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=oauth2_settings.APPLICATION_MODEL),
+        ),
+        migrations.AlterField(
+            model_name='accesstoken',
+            name='id',
+            field=models.BigAutoField(primary_key=True, serialize=False),
+        ),
+        migrations.AlterField(
+            model_name='accesstoken',
+            name='user',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='oauth2_provider_accesstoken', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AlterField(
+            model_name='application',
+            name='id',
+            field=models.BigAutoField(primary_key=True, serialize=False),
+        ),
+        migrations.AlterField(
+            model_name='grant',
+            name='id',
+            field=models.BigAutoField(primary_key=True, serialize=False),
+        ),
+        migrations.AlterField(
+            model_name='grant',
+            name='user',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='oauth2_provider_grant', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AlterField(
+            model_name='refreshtoken',
+            name='id',
+            field=models.BigAutoField(primary_key=True, serialize=False),
+        ),
+        migrations.AlterField(
+            model_name='refreshtoken',
+            name='user',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='oauth2_provider_refreshtoken', to=settings.AUTH_USER_MODEL),
+        ),
+        migrations.AddField(
+            model_name='accesstoken',
+            name='created',
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='accesstoken',
+            name='updated',
+            field=models.DateTimeField(auto_now=True),
+        ),
+        migrations.AddField(
+            model_name='application',
+            name='created',
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='application',
+            name='updated',
+            field=models.DateTimeField(auto_now=True),
+        ),
+        migrations.AddField(
+            model_name='grant',
+            name='created',
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='grant',
+            name='updated',
+            field=models.DateTimeField(auto_now=True),
+        ),
+        migrations.AddField(
+            model_name='refreshtoken',
+            name='created',
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='refreshtoken',
+            name='updated',
+            field=models.DateTimeField(auto_now=True),
+        ),
+    ]
diff --git a/oauth2_provider/models.py b/oauth2_provider/models.py
index 6a0103c..b2967c7 100644
--- a/oauth2_provider/models.py
+++ b/oauth2_provider/models.py
@@ -4,17 +4,17 @@ from datetime import timedelta
 
 from django.apps import apps
 from django.conf import settings
+from django.core.exceptions import ImproperlyConfigured
 from django.db import models, transaction
+from django.urls import reverse
 from django.utils import timezone
-
-from django.utils.translation import ugettext_lazy as _
 from django.utils.encoding import python_2_unicode_compatible
-from django.core.exceptions import ImproperlyConfigured
+from django.utils.translation import ugettext_lazy as _
 
+from .compat import parse_qsl, urlparse
+from .generators import generate_client_id, generate_client_secret
 from .scopes import get_scopes_backend
 from .settings import oauth2_settings
-from .compat import parse_qsl, reverse, urlparse
-from .generators import generate_client_secret, generate_client_id
 from .validators import validate_uris
 
 
@@ -39,40 +39,51 @@ class AbstractApplication(models.Model):
                             the registration process as described in :rfc:`2.2`
     * :attr:`name` Friendly name for the Application
     """
-    CLIENT_CONFIDENTIAL = 'confidential'
-    CLIENT_PUBLIC = 'public'
+    CLIENT_CONFIDENTIAL = "confidential"
+    CLIENT_PUBLIC = "public"
     CLIENT_TYPES = (
-        (CLIENT_CONFIDENTIAL, _('Confidential')),
-        (CLIENT_PUBLIC, _('Public')),
+        (CLIENT_CONFIDENTIAL, _("Confidential")),
+        (CLIENT_PUBLIC, _("Public")),
     )
 
-    GRANT_AUTHORIZATION_CODE = 'authorization-code'
-    GRANT_IMPLICIT = 'implicit'
-    GRANT_PASSWORD = 'password'
-    GRANT_CLIENT_CREDENTIALS = 'client-credentials'
+    GRANT_AUTHORIZATION_CODE = "authorization-code"
+    GRANT_IMPLICIT = "implicit"
+    GRANT_PASSWORD = "password"
+    GRANT_CLIENT_CREDENTIALS = "client-credentials"
     GRANT_TYPES = (
-        (GRANT_AUTHORIZATION_CODE, _('Authorization code')),
-        (GRANT_IMPLICIT, _('Implicit')),
-        (GRANT_PASSWORD, _('Resource owner password-based')),
-        (GRANT_CLIENT_CREDENTIALS, _('Client credentials')),
+        (GRANT_AUTHORIZATION_CODE, _("Authorization code")),
+        (GRANT_IMPLICIT, _("Implicit")),
+        (GRANT_PASSWORD, _("Resource owner password-based")),
+        (GRANT_CLIENT_CREDENTIALS, _("Client credentials")),
     )
 
-    client_id = models.CharField(max_length=100, unique=True,
-                                 default=generate_client_id, db_index=True)
-    user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="%(app_label)s_%(class)s",
-                             null=True, blank=True, on_delete=models.CASCADE)
+    id = models.BigAutoField(primary_key=True)
+    client_id = models.CharField(
+        max_length=100, unique=True, default=generate_client_id, db_index=True
+    )
+    user = models.ForeignKey(
+        settings.AUTH_USER_MODEL,
+        related_name="%(app_label)s_%(class)s",
+        null=True, blank=True, on_delete=models.CASCADE
+    )
 
     help_text = _("Allowed URIs list, space separated")
-    redirect_uris = models.TextField(help_text=help_text,
-                                     validators=[validate_uris], blank=True)
+    redirect_uris = models.TextField(
+        blank=True, help_text=help_text, validators=[validate_uris]
+    )
     client_type = models.CharField(max_length=32, choices=CLIENT_TYPES)
-    authorization_grant_type = models.CharField(max_length=32,
-                                                choices=GRANT_TYPES)
-    client_secret = models.CharField(max_length=255, blank=True,
-                                     default=generate_client_secret, db_index=True)
+    authorization_grant_type = models.CharField(
+        max_length=32, choices=GRANT_TYPES
+    )
+    client_secret = models.CharField(
+        max_length=255, blank=True, default=generate_client_secret, db_index=True
+    )
     name = models.CharField(max_length=255, blank=True)
     skip_authorization = models.BooleanField(default=False)
 
+    created = models.DateTimeField(auto_now_add=True)
+    updated = models.DateTimeField(auto_now=True)
+
     class Meta:
         abstract = True
 
@@ -85,9 +96,11 @@ class AbstractApplication(models.Model):
         if self.redirect_uris:
... 8357 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/django-oauth-toolkit.git



More information about the Python-modules-commits mailing list