[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