File django4.patch of Package failed_python-django-oidc-provider
From 7d17d720e1fe180e78b4084efc9b9e6fa9bc7550 Mon Sep 17 00:00:00 2001
From: "Peter (dkdndes)" <dkdndes@gmail.com>
Date: Thu, 3 Feb 2022 13:41:38 +0100
Subject: [PATCH 01/13] feat: django 4.*
---
README.md | 2
docs/conf.py | 59
example/app/settings.py | 78 -
example/app/templates/base.html | 2
example/app/templates/home.html | 2
example/app/templates/login.html | 29
example/app/urls.py | 17
example/app/wsgi.py | 3
example/manage.py | 4
example/templates/registration/login.html | 13
oidc_provider/__init__.py | 3
oidc_provider/admin.py | 96 -
oidc_provider/apps.py | 4
oidc_provider/lib/claims.py | 165 +-
oidc_provider/lib/endpoints/authorize.py | 281 ++-
oidc_provider/lib/endpoints/introspection.py | 88 -
oidc_provider/lib/endpoints/token.py | 229 +--
oidc_provider/lib/errors.py | 170 +-
oidc_provider/lib/utils/authorize.py | 17
oidc_provider/lib/utils/common.py | 62
oidc_provider/lib/utils/oauth2.py | 52
oidc_provider/lib/utils/token.py | 43
oidc_provider/management/commands/creatersakey.py | 11
oidc_provider/middleware.py | 6
oidc_provider/migrations/0001_initial.py | 209 ++
oidc_provider/migrations/0002_userconsent.py | 36
oidc_provider/migrations/0003_code_nonce.py | 10
oidc_provider/migrations/0004_remove_userinfo.py | 8
oidc_provider/migrations/0005_token_refresh_token.py | 8
oidc_provider/migrations/0006_unique_user_client.py | 6
oidc_provider/migrations/0007_auto_20160111_1844.py | 36
oidc_provider/migrations/0008_rsakey.py | 16
oidc_provider/migrations/0009_auto_20160202_1945.py | 12
oidc_provider/migrations/0010_code_is_authentication.py | 6
oidc_provider/migrations/0011_client_client_type.py | 17
oidc_provider/migrations/0012_auto_20160405_2041.py | 8
oidc_provider/migrations/0013_auto_20160407_1912.py | 10
oidc_provider/migrations/0014_client_jwt_alg.py | 13
oidc_provider/migrations/0015_change_client_code.py | 91 -
oidc_provider/migrations/0016_userconsent_and_verbosenames.py | 234 +--
oidc_provider/migrations/0017_auto_20160811_1954.py | 80 -
oidc_provider/migrations/0018_hybridflow_and_clientattrs.py | 70
oidc_provider/migrations/0019_auto_20161005_1552.py | 10
oidc_provider/migrations/0020_client__post_logout_redirect_uris.py | 13
oidc_provider/migrations/0021_refresh_token_not_unique.py | 10
oidc_provider/migrations/0022_auto_20170331_1626.py | 20
oidc_provider/migrations/0023_client_owner.py | 18
oidc_provider/migrations/0024_auto_20180327_1959.py | 12
oidc_provider/migrations/0025_user_field_codetoken.py | 26
oidc_provider/migrations/0026_client_multiple_response_types.py | 62
oidc_provider/migrations/0027_alter_client_id_alter_code_id_alter_responsetype_id_and_more.py | 43
oidc_provider/models.py | 239 ++-
oidc_provider/settings.py | 42
oidc_provider/signals.py | 5
oidc_provider/templates/registration/login.html | 13
oidc_provider/tests/app/urls.py | 25
oidc_provider/tests/app/utils.py | 75 -
oidc_provider/tests/cases/test_authorize_endpoint.py | 721 +++++-----
oidc_provider/tests/cases/test_claims.py | 93 -
oidc_provider/tests/cases/test_commands.py | 11
oidc_provider/tests/cases/test_end_session_endpoint.py | 58
oidc_provider/tests/cases/test_introspection_endpoint.py | 93 -
oidc_provider/tests/cases/test_middleware.py | 41
oidc_provider/tests/cases/test_provider_info_endpoint.py | 9
oidc_provider/tests/cases/test_settings.py | 18
oidc_provider/tests/cases/test_token_endpoint.py | 593 ++++----
oidc_provider/tests/cases/test_userinfo_endpoint.py | 78 -
oidc_provider/tests/cases/test_utils.py | 77 -
oidc_provider/tests/settings.py | 78 -
oidc_provider/urls.py | 42
oidc_provider/version.py | 2
oidc_provider/views.py | 274 ++-
setup.py | 61
tox-django4-devtests.ini | 45
74 files changed, 2959 insertions(+), 2254 deletions(-)
Index: django-oidc-provider-0.7.0/README.md
===================================================================
--- django-oidc-provider-0.7.0.orig/README.md
+++ django-oidc-provider-0.7.0/README.md
@@ -13,7 +13,7 @@ OpenID Connect is a simple identity laye
`django-oidc-provider` can help you providing out of the box all the endpoints, data and logic needed to add OpenID Connect (and OAuth2) capabilities to your Django projects.
-Support for Python 3 and 2. Also latest versions of django.
+Support for Python 3.2, also latest 4.* versions of django.
[Read documentation for more info.](http://django-oidc-provider.readthedocs.org/)
Index: django-oidc-provider-0.7.0/docs/conf.py
===================================================================
--- django-oidc-provider-0.7.0.orig/docs/conf.py
+++ django-oidc-provider-0.7.0/docs/conf.py
@@ -31,7 +31,7 @@
extensions = []
# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
@@ -41,21 +41,21 @@ templates_path = ['_templates']
# source_encoding = 'utf-8-sig'
# The master toctree document.
-master_doc = 'index'
+master_doc = "index"
# General information about the project.
-project = u'django-oidc-provider'
-copyright = u'2016, Juan Ignacio Fiorentino'
-author = u'Juan Ignacio Fiorentino'
+project = "django-oidc-provider"
+copyright = "2016, Juan Ignacio Fiorentino"
+author = "Juan Ignacio Fiorentino"
# 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 = u'0.5'
+version = "0.5"
# The full version, including alpha/beta/rc tags.
-release = u'0.5.x'
+release = "0.5.x"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -72,7 +72,7 @@ language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
+exclude_patterns = ["_build"]
# The reST default role (used for this markup: `text`) to use for all
# documents.
@@ -90,7 +90,7 @@ exclude_patterns = ['_build']
# show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
@@ -106,7 +106,7 @@ todo_include_todos = False
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
-html_theme = 'sphinx_rtd_theme'
+html_theme = "sphinx_rtd_theme"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
@@ -135,7 +135,7 @@ html_theme = 'sphinx_rtd_theme'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = ["_static"]
# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
@@ -198,20 +198,17 @@ html_static_path = ['_static']
# html_search_scorer = 'scorer.js'
# Output file base name for HTML help builder.
-htmlhelp_basename = 'django-oidc-providerdoc'
+htmlhelp_basename = "django-oidc-providerdoc"
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
# 'papersize': 'letterpaper',
-
# The font size ('10pt', '11pt' or '12pt').
# 'pointsize': '10pt',
-
# Additional stuff for the LaTeX preamble.
# 'preamble': '',
-
# Latex figure (float) alignment
# 'figure_align': 'htbp',
}
@@ -220,8 +217,13 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
- (master_doc, 'django-oidc-provider.tex', u'django-oidc-provider Documentation',
- u'Juan Ignacio Fiorentino', 'manual'),
+ (
+ master_doc,
+ "django-oidc-provider.tex",
+ "django-oidc-provider Documentation",
+ "Juan Ignacio Fiorentino",
+ "manual",
+ ),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -250,8 +252,13 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
- (master_doc, 'django-oidc-provider', u'django-oidc-provider Documentation',
- [author], 1)
+ (
+ master_doc,
+ "django-oidc-provider",
+ "django-oidc-provider Documentation",
+ [author],
+ 1,
+ )
]
# If true, show URL addresses after external links.
@@ -264,9 +271,15 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
- (master_doc, 'django-oidc-provider', u'django-oidc-provider Documentation',
- author, 'django-oidc-provider', 'One line description of project.',
- 'Miscellaneous'),
+ (
+ master_doc,
+ "django-oidc-provider",
+ "django-oidc-provider Documentation",
+ author,
+ "django-oidc-provider",
+ "One line description of project.",
+ "Miscellaneous",
+ ),
]
# Documents to append as an appendix to all manuals.
@@ -328,7 +341,7 @@ epub_copyright = copyright
# epub_post_files = []
# A list of files that should not be packed into the epub file.
-epub_exclude_files = ['search.html']
+epub_exclude_files = ["search.html"]
# The depth of the table of contents in toc.ncx.
# epub_tocdepth = 3
Index: django-oidc-provider-0.7.0/example/app/settings.py
===================================================================
--- django-oidc-provider-0.7.0.orig/example/app/settings.py
+++ django-oidc-provider-0.7.0/example/app/settings.py
@@ -1,74 +1,77 @@
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
+
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
-SECRET_KEY = 'c14d549c574e4d8cf162404ef0b04598'
+SECRET_KEY = "c14d549c574e4d8cf162404ef0b04598"
DEBUG = True
TEMPLATE_DEBUG = False
-ALLOWED_HOSTS = ['*']
+ALLOWED_HOSTS = ["*"]
+
+DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# Application definition
INSTALLED_APPS = [
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- 'app',
- 'oidc_provider',
+ "django.contrib.admin",
+ "django.contrib.auth",
+ "django.contrib.contenttypes",
+ "django.contrib.sessions",
+ "django.contrib.messages",
+ "django.contrib.staticfiles",
+ "app",
+ "oidc_provider",
]
MIDDLEWARE_CLASSES = [
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.common.CommonMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- 'django.middleware.clickjacking.XFrameOptionsMiddleware',
- 'oidc_provider.middleware.SessionManagementMiddleware',
+ "django.contrib.sessions.middleware.SessionMiddleware",
+ "django.middleware.common.CommonMiddleware",
+ "django.middleware.csrf.CsrfViewMiddleware",
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
+ "django.contrib.messages.middleware.MessageMiddleware",
+ "django.middleware.clickjacking.XFrameOptionsMiddleware",
+ "oidc_provider.middleware.SessionManagementMiddleware",
]
MIDDLEWARE = MIDDLEWARE_CLASSES
TEMPLATES = [
{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [],
- 'APP_DIRS': True,
- 'OPTIONS': {
- 'context_processors': [
- 'django.template.context_processors.debug',
- 'django.template.context_processors.request',
- 'django.contrib.auth.context_processors.auth',
- 'django.contrib.messages.context_processors.messages',
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": ["templates"],
+ "APP_DIRS": True,
+ "OPTIONS": {
+ "context_processors": [
+ "django.template.context_processors.debug",
+ "django.template.context_processors.request",
+ "django.contrib.auth.context_processors.auth",
+ "django.contrib.messages.context_processors.messages",
],
},
},
]
-ROOT_URLCONF = 'app.urls'
+ROOT_URLCONF = "app.urls"
-WSGI_APPLICATION = 'app.wsgi.application'
+WSGI_APPLICATION = "app.wsgi.application"
# Database
DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': os.path.join(BASE_DIR, 'DATABASE.sqlite3'),
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ "NAME": os.path.join(BASE_DIR, "DATABASE.sqlite3"),
}
}
# Internationalization
-LANGUAGE_CODE = 'en-us'
+LANGUAGE_CODE = "en-us"
-TIME_ZONE = 'UTC'
+TIME_ZONE = "UTC"
USE_I18N = True
@@ -78,14 +81,15 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images)
-STATIC_URL = '/static/'
-STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
+STATIC_URL = "/static/"
+STATIC_ROOT = os.path.join(BASE_DIR, "static/")
# Custom settings
-LOGIN_REDIRECT_URL = '/'
+LOGIN_REDIRECT_URL = "home"
+LOGOUT_REDIRECT_URL = "home"
# OIDC Provider settings
-SITE_URL = 'http://localhost:8000'
+SITE_URL = "http://localhost:8000"
OIDC_SESSION_MANAGEMENT_ENABLE = True
Index: django-oidc-provider-0.7.0/example/app/templates/base.html
===================================================================
--- django-oidc-provider-0.7.0.orig/example/app/templates/base.html
+++ django-oidc-provider-0.7.0/example/app/templates/base.html
@@ -1,4 +1,4 @@
-{% load i18n staticfiles %}
+{% load i18n static %}
<!DOCTYPE html>
<html lang="en">
Index: django-oidc-provider-0.7.0/example/app/templates/home.html
===================================================================
--- django-oidc-provider-0.7.0.orig/example/app/templates/home.html
+++ django-oidc-provider-0.7.0/example/app/templates/home.html
@@ -1,5 +1,5 @@
{% extends "base.html" %}
-{% load i18n staticfiles %}
+{% load i18n static %}
{% block content %}
Index: django-oidc-provider-0.7.0/example/app/templates/login.html
===================================================================
--- django-oidc-provider-0.7.0.orig/example/app/templates/login.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{% extends 'base.html' %}
-{% load i18n %}
-
-{% block content %}
-
-<div class="row">
- <div class="col-md-6 col-md-offset-3">
- <form method="post" action="{% url 'login' %}">
- {% csrf_token %}
- <input type="hidden" name="next" value="{{ next }}">
- {% if form.errors %}
- <div class="alert alert-danger" role="alert">
- {% trans 'Your username and password didn\'t match. Please try again.' %}
- </div>
- {% endif %}
- <fieldset class="form-group">
- <input class="form-control form-control-lg" type="text" name="username" placeholder="{% trans 'Username' %}">
- </fieldset>
- <fieldset class="form-group">
- <input class="form-control form-control-lg" type="password" name="password" placeholder="{% trans 'Password' %}">
- </fieldset>
- <fieldset class="form-group">
- <input class="btn btn-primary btn-lg btn-block" type="submit" value="{% trans 'Enter' %}" />
- </fieldset>
- </form>
- </div>
-</div>
-
-{% endblock %}
Index: django-oidc-provider-0.7.0/example/app/urls.py
===================================================================
--- django-oidc-provider-0.7.0.orig/example/app/urls.py
+++ django-oidc-provider-0.7.0/example/app/urls.py
@@ -1,16 +1,17 @@
-from django.contrib.auth import views as auth_views
try:
from django.urls import include, url
except ImportError:
- from django.conf.urls import include, url
+ from django.urls import include, path
+
+from django.contrib.auth.views import LoginView, LogoutView
+
from django.contrib import admin
from django.views.generic import TemplateView
-
urlpatterns = [
- url(r'^$', TemplateView.as_view(template_name='home.html'), name='home'),
- url(r'^accounts/login/$', auth_views.login, {'template_name': 'login.html'}, name='login'),
- url(r'^accounts/logout/$', auth_views.logout, {'next_page': '/'}, name='logout'),
- url(r'^', include('oidc_provider.urls', namespace='oidc_provider')),
- url(r'^admin/', admin.site.urls),
+ path("", TemplateView.as_view(template_name="home.html"), name="home"),
+ path("accounts/login/", LoginView.as_view(), name="login"),
+ path("accounts/logout/", LogoutView.as_view(), name="logout"),
+ path("", include("oidc_provider.urls", namespace="oidc_provider")),
+ path("admin/", admin.site.urls),
]
Index: django-oidc-provider-0.7.0/example/app/wsgi.py
===================================================================
--- django-oidc-provider-0.7.0.orig/example/app/wsgi.py
+++ django-oidc-provider-0.7.0/example/app/wsgi.py
@@ -2,7 +2,6 @@ import os
from django.core.wsgi import get_wsgi_application
-
-os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
application = get_wsgi_application()
Index: django-oidc-provider-0.7.0/example/manage.py
===================================================================
--- django-oidc-provider-0.7.0.orig/example/manage.py
+++ django-oidc-provider-0.7.0/example/manage.py
@@ -2,8 +2,8 @@
import os
import sys
-if __name__ == '__main__':
- os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings')
+if __name__ == "__main__":
+ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")
from django.core.management import execute_from_command_line
Index: django-oidc-provider-0.7.0/example/templates/registration/login.html
===================================================================
--- /dev/null
+++ django-oidc-provider-0.7.0/example/templates/registration/login.html
@@ -0,0 +1,13 @@
+<!-- templates/registration/login.html -->
+{% extends 'base.html' %}
+
+{% block title %}Login{% endblock %}
+
+{% block content %}
+<h2>Log In</h2>
+<form method="post">
+ {% csrf_token %}
+ {{ form.as_p }}
+ <button type="submit" class="btn btn-primary btn-lg">Log In</button>
+</form>
+{% endblock %}
Index: django-oidc-provider-0.7.0/oidc_provider/__init__.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/__init__.py
+++ django-oidc-provider-0.7.0/oidc_provider/__init__.py
@@ -1,2 +1 @@
-
-default_app_config = 'oidc_provider.apps.OIDCProviderConfig'
+default_app_config = "oidc_provider.apps.OIDCProviderConfig"
Index: django-oidc-provider-0.7.0/oidc_provider/admin.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/admin.py
+++ django-oidc-provider-0.7.0/oidc_provider/admin.py
@@ -2,45 +2,48 @@ from hashlib import sha224
from random import randint
from uuid import uuid4
-from django.forms import ModelForm
from django.contrib import admin
-from django.utils.translation import ugettext_lazy as _
+from django.forms import ModelForm
+from django.utils.translation import gettext_lazy as _
-from oidc_provider.models import Client, Code, Token, RSAKey
+from oidc_provider.models import Client, Code, RSAKey, Token
class ClientForm(ModelForm):
-
class Meta:
model = Client
exclude = []
def __init__(self, *args, **kwargs):
super(ClientForm, self).__init__(*args, **kwargs)
- self.fields['client_id'].required = False
- self.fields['client_id'].widget.attrs['disabled'] = 'true'
- self.fields['client_secret'].required = False
- self.fields['client_secret'].widget.attrs['disabled'] = 'true'
+ self.fields["client_id"].required = False
+ self.fields["client_id"].widget.attrs["disabled"] = "true"
+ self.fields["client_secret"].required = False
+ self.fields["client_secret"].widget.attrs["disabled"] = "true"
def clean_client_id(self):
- instance = getattr(self, 'instance', None)
+ instance = getattr(self, "instance", None)
if instance and instance.pk:
return instance.client_id
else:
return str(randint(1, 999999)).zfill(6)
def clean_client_secret(self):
- instance = getattr(self, 'instance', None)
+ instance = getattr(self, "instance", None)
- secret = ''
+ secret = ""
if instance and instance.pk:
- if (self.cleaned_data['client_type'] == 'confidential') and not instance.client_secret:
+ if (
+ self.cleaned_data["client_type"] == "confidential"
+ ) and not instance.client_secret:
secret = sha224(uuid4().hex.encode()).hexdigest()
- elif (self.cleaned_data['client_type'] == 'confidential') and instance.client_secret:
+ elif (
+ self.cleaned_data["client_type"] == "confidential"
+ ) and instance.client_secret:
secret = instance.client_secret
else:
- if (self.cleaned_data['client_type'] == 'confidential'):
+ if self.cleaned_data["client_type"] == "confidential":
secret = sha224(uuid4().hex.encode()).hexdigest()
return secret
@@ -50,38 +53,61 @@ class ClientForm(ModelForm):
class ClientAdmin(admin.ModelAdmin):
fieldsets = [
- [_(u''), {
- 'fields': (
- 'name', 'owner', 'client_type', 'response_types', '_redirect_uris', 'jwt_alg',
- 'require_consent', 'reuse_consent'),
- }],
- [_(u'Credentials'), {
- 'fields': ('client_id', 'client_secret', '_scope'),
- }],
- [_(u'Information'), {
- 'fields': ('contact_email', 'website_url', 'terms_url', 'logo', 'date_created'),
- }],
- [_(u'Session Management'), {
- 'fields': ('_post_logout_redirect_uris',),
- }],
+ [
+ _(""),
+ {
+ "fields": (
+ "name",
+ "owner",
+ "client_type",
+ "response_types",
+ "_redirect_uris",
+ "jwt_alg",
+ "require_consent",
+ "reuse_consent",
+ ),
+ },
+ ],
+ [
+ _("Credentials"),
+ {
+ "fields": ("client_id", "client_secret", "_scope"),
+ },
+ ],
+ [
+ _("Information"),
+ {
+ "fields": (
+ "contact_email",
+ "website_url",
+ "terms_url",
+ "logo",
+ "date_created",
+ ),
+ },
+ ],
+ [
+ _("Session Management"),
+ {
+ "fields": ("_post_logout_redirect_uris",),
+ },
+ ],
]
form = ClientForm
- list_display = ['name', 'client_id', 'response_type_descriptions', 'date_created']
- readonly_fields = ['date_created']
- search_fields = ['name']
- raw_id_fields = ['owner']
+ list_display = ["name", "client_id", "response_type_descriptions", "date_created"]
+ readonly_fields = ["date_created"]
+ search_fields = ["name"]
+ raw_id_fields = ["owner"]
@admin.register(Code)
class CodeAdmin(admin.ModelAdmin):
-
def has_add_permission(self, request):
return False
@admin.register(Token)
class TokenAdmin(admin.ModelAdmin):
-
def has_add_permission(self, request):
return False
@@ -89,4 +115,4 @@ class TokenAdmin(admin.ModelAdmin):
@admin.register(RSAKey)
class RSAKeyAdmin(admin.ModelAdmin):
- readonly_fields = ['kid']
+ readonly_fields = ["kid"]
Index: django-oidc-provider-0.7.0/oidc_provider/apps.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/apps.py
+++ django-oidc-provider-0.7.0/oidc_provider/apps.py
@@ -3,5 +3,5 @@ from django.apps import AppConfig
class OIDCProviderConfig(AppConfig):
- name = 'oidc_provider'
- verbose_name = u'OpenID Connect Provider'
+ name = "oidc_provider"
+ verbose_name = "OpenID Connect Provider"
Index: django-oidc-provider-0.7.0/oidc_provider/lib/claims.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/lib/claims.py
+++ django-oidc-provider-0.7.0/oidc_provider/lib/claims.py
@@ -1,46 +1,46 @@
import copy
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import gettext_lazy as _
from oidc_provider import settings
-
STANDARD_CLAIMS = {
- 'name': '',
- 'given_name': '',
- 'family_name': '',
- 'middle_name': '',
- 'nickname': '',
- 'preferred_username': '',
- 'profile': '',
- 'picture': '',
- 'website': '',
- 'gender': '',
- 'birthdate': '',
- 'zoneinfo': '',
- 'locale': '',
- 'updated_at': '',
- 'email': '',
- 'email_verified': '',
- 'phone_number': '',
- 'phone_number_verified': '',
- 'address': {
- 'formatted': '',
- 'street_address': '',
- 'locality': '',
- 'region': '',
- 'postal_code': '',
- 'country': '',
+ "name": "",
+ "given_name": "",
+ "family_name": "",
+ "middle_name": "",
+ "nickname": "",
+ "preferred_username": "",
+ "profile": "",
+ "picture": "",
+ "website": "",
+ "gender": "",
+ "birthdate": "",
+ "zoneinfo": "",
+ "locale": "",
+ "updated_at": "",
+ "email": "",
+ "email_verified": "",
+ "phone_number": "",
+ "phone_number_verified": "",
+ "address": {
+ "formatted": "",
+ "street_address": "",
+ "locality": "",
+ "region": "",
+ "postal_code": "",
+ "country": "",
},
}
class ScopeClaims(object):
-
def __init__(self, token):
self.user = token.user
claims = copy.deepcopy(STANDARD_CLAIMS)
- self.userinfo = settings.get('OIDC_USERINFO', import_str=True)(claims, self.user)
+ self.userinfo = settings.get("OIDC_USERINFO", import_str=True)(
+ claims, self.user
+ )
self.scopes = token.scope
self.client = token.client
@@ -55,7 +55,7 @@ class ScopeClaims(object):
for scope in self.scopes:
if scope in self._scopes_registered():
- dic.update(getattr(self, 'scope_' + scope)())
+ dic.update(getattr(self, "scope_" + scope)())
dic = self._clean_dic(dic)
@@ -69,8 +69,8 @@ class ScopeClaims(object):
scopes = []
for name in dir(self.__class__):
- if name.startswith('scope_'):
- scope = name.split('scope_')[1]
+ if name.startswith("scope_"):
+ scope = name.split("scope_")[1]
scopes.append(scope)
return scopes
@@ -82,7 +82,7 @@ class ScopeClaims(object):
aux_dic = dic.copy()
for key, value in iter(dic.items()):
- if value is None or value == '':
+ if value is None or value == "":
del aux_dic[key]
elif type(value) is dict:
cleaned_dict = self._clean_dic(value)
@@ -99,15 +99,17 @@ class ScopeClaims(object):
scopes_info = []
for name in dir(cls):
- if name.startswith('info_'):
- scope_name = name.split('info_')[1]
+ if name.startswith("info_"):
+ scope_name = name.split("info_")[1]
if scope_name in scopes:
touple_info = getattr(cls, name)
- scopes_info.append({
- 'scope': scope_name,
- 'name': touple_info[0],
- 'description': touple_info[1],
- })
+ scopes_info.append(
+ {
+ "scope": scope_name,
+ "name": touple_info[0],
+ "description": touple_info[1],
+ }
+ )
return scopes_info
@@ -119,73 +121,84 @@ class StandardScopeClaims(ScopeClaims):
"""
info_profile = (
- _(u'Basic profile'),
- _(u'Access to your basic information. Includes names, gender, birthdate '
- 'and other information.'),
+ _("Basic profile"),
+ _(
+ "Access to your basic information. Includes names, gender, birthdate "
+ "and other information."
+ ),
)
def scope_profile(self):
dic = {
- 'name': self.userinfo.get('name'),
- 'given_name': (self.userinfo.get('given_name') or
- getattr(self.user, 'first_name', None)),
- 'family_name': (self.userinfo.get('family_name') or
- getattr(self.user, 'last_name', None)),
- 'middle_name': self.userinfo.get('middle_name'),
- 'nickname': self.userinfo.get('nickname') or getattr(self.user, 'username', None),
- 'preferred_username': self.userinfo.get('preferred_username'),
- 'profile': self.userinfo.get('profile'),
- 'picture': self.userinfo.get('picture'),
- 'website': self.userinfo.get('website'),
- 'gender': self.userinfo.get('gender'),
- 'birthdate': self.userinfo.get('birthdate'),
- 'zoneinfo': self.userinfo.get('zoneinfo'),
- 'locale': self.userinfo.get('locale'),
- 'updated_at': self.userinfo.get('updated_at'),
+ "name": self.userinfo.get("name"),
+ "given_name": (
+ self.userinfo.get("given_name")
+ or getattr(self.user, "first_name", None)
+ ),
+ "family_name": (
+ self.userinfo.get("family_name")
+ or getattr(self.user, "last_name", None)
+ ),
+ "middle_name": self.userinfo.get("middle_name"),
+ "nickname": self.userinfo.get("nickname")
+ or getattr(self.user, "username", None),
+ "preferred_username": self.userinfo.get("preferred_username"),
+ "profile": self.userinfo.get("profile"),
+ "picture": self.userinfo.get("picture"),
+ "website": self.userinfo.get("website"),
+ "gender": self.userinfo.get("gender"),
+ "birthdate": self.userinfo.get("birthdate"),
+ "zoneinfo": self.userinfo.get("zoneinfo"),
+ "locale": self.userinfo.get("locale"),
+ "updated_at": self.userinfo.get("updated_at"),
}
return dic
info_email = (
- _(u'Email'),
- _(u'Access to your email address.'),
+ _("Email"),
+ _("Access to your email address."),
)
def scope_email(self):
dic = {
- 'email': self.userinfo.get('email') or getattr(self.user, 'email', None),
- 'email_verified': self.userinfo.get('email_verified'),
+ "email": self.userinfo.get("email") or getattr(self.user, "email", None),
+ "email_verified": self.userinfo.get("email_verified"),
}
return dic
info_phone = (
- _(u'Phone number'),
- _(u'Access to your phone number.'),
+ _("Phone number"),
+ _("Access to your phone number."),
)
def scope_phone(self):
dic = {
- 'phone_number': self.userinfo.get('phone_number'),
- 'phone_number_verified': self.userinfo.get('phone_number_verified'),
+ "phone_number": self.userinfo.get("phone_number"),
+ "phone_number_verified": self.userinfo.get("phone_number_verified"),
}
return dic
info_address = (
- _(u'Address information'),
- _(u'Access to your address. Includes country, locality, street and other information.'),
+ _("Address information"),
+ _(
+ "Access to your address. Includes country, locality, street and other information."
+ ),
)
def scope_address(self):
dic = {
- 'address': {
- 'formatted': self.userinfo.get('address', {}).get('formatted'),
- 'street_address': self.userinfo.get('address', {}).get('street_address'),
- 'locality': self.userinfo.get('address', {}).get('locality'),
- 'region': self.userinfo.get('address', {}).get('region'),
- 'postal_code': self.userinfo.get('address', {}).get('postal_code'),
- 'country': self.userinfo.get('address', {}).get('country'),
+ "address": {
+ "formatted": self.userinfo.get("address", {}).get("formatted"),
+ "street_address": self.userinfo.get("address", {}).get(
+ "street_address"
+ ),
+ "locality": self.userinfo.get("address", {}).get("locality"),
+ "region": self.userinfo.get("address", {}).get("region"),
+ "postal_code": self.userinfo.get("address", {}).get("postal_code"),
+ "country": self.userinfo.get("address", {}).get("country"),
}
}
Index: django-oidc-provider-0.7.0/oidc_provider/lib/endpoints/authorize.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/lib/endpoints/authorize.py
+++ django-oidc-provider-0.7.0/oidc_provider/lib/endpoints/authorize.py
@@ -1,42 +1,35 @@
-from datetime import timedelta
-from hashlib import (
- md5,
- sha256,
-)
import logging
+from datetime import timedelta
+from hashlib import md5, sha256
+
try:
from urllib import urlencode
- from urlparse import urlsplit, parse_qs, urlunsplit
+
+ from urlparse import parse_qs, urlsplit, urlunsplit
except ImportError:
from urllib.parse import urlsplit, parse_qs, urlunsplit, urlencode
+
from uuid import uuid4
from django.utils import timezone
+from oidc_provider import settings
from oidc_provider.lib.claims import StandardScopeClaims
-from oidc_provider.lib.errors import (
- AuthorizeError,
- ClientIdError,
- RedirectUriError,
-)
+from oidc_provider.lib.errors import AuthorizeError, ClientIdError, RedirectUriError
+from oidc_provider.lib.utils.common import get_browser_state_or_default
from oidc_provider.lib.utils.token import (
create_code,
create_id_token,
create_token,
encode_id_token,
)
-from oidc_provider.models import (
- Client,
- UserConsent,
-)
-from oidc_provider import settings
-from oidc_provider.lib.utils.common import get_browser_state_or_default
+from oidc_provider.models import Client, UserConsent
logger = logging.getLogger(__name__)
class AuthorizeEndpoint(object):
- _allowed_prompt_params = {'none', 'login', 'consent', 'select_account'}
+ _allowed_prompt_params = {"none", "login", "consent", "select_account"}
client_class = Client
def __init__(self, request):
@@ -46,18 +39,21 @@ class AuthorizeEndpoint(object):
self._extract_params()
# Determine which flow to use.
- if self.params['response_type'] in ['code']:
- self.grant_type = 'authorization_code'
- elif self.params['response_type'] in ['id_token', 'id_token token', 'token']:
- self.grant_type = 'implicit'
- elif self.params['response_type'] in [
- 'code token', 'code id_token', 'code id_token token']:
- self.grant_type = 'hybrid'
+ if self.params["response_type"] in ["code"]:
+ self.grant_type = "authorization_code"
+ elif self.params["response_type"] in ["id_token", "id_token token", "token"]:
+ self.grant_type = "implicit"
+ elif self.params["response_type"] in [
+ "code token",
+ "code id_token",
+ "code id_token token",
+ ]:
+ self.grant_type = "hybrid"
else:
self.grant_type = None
# Determine if it's an OpenID Authentication request (or OAuth2).
- self.is_authentication = 'openid' in self.params['scope']
+ self.is_authentication = "openid" in self.params["scope"]
def _extract_params(self):
"""
@@ -68,114 +64,158 @@ class AuthorizeEndpoint(object):
"""
# Because in this endpoint we handle both GET
# and POST request.
- query_dict = (self.request.POST if self.request.method == 'POST'
- else self.request.GET)
+ query_dict = (
+ self.request.POST if self.request.method == "POST" else self.request.GET
+ )
- self.params['client_id'] = query_dict.get('client_id', '')
- self.params['redirect_uri'] = query_dict.get('redirect_uri', '')
- self.params['response_type'] = query_dict.get('response_type', '')
- self.params['scope'] = query_dict.get('scope', '').split()
- self.params['state'] = query_dict.get('state', '')
- self.params['nonce'] = query_dict.get('nonce', '')
+ self.params["client_id"] = query_dict.get("client_id", "")
+ self.params["redirect_uri"] = query_dict.get("redirect_uri", "")
+ self.params["response_type"] = query_dict.get("response_type", "")
+ self.params["scope"] = query_dict.get("scope", "").split()
+ self.params["state"] = query_dict.get("state", "")
+ self.params["nonce"] = query_dict.get("nonce", "")
- self.params['prompt'] = self._allowed_prompt_params.intersection(
- set(query_dict.get('prompt', '').split()))
+ self.params["prompt"] = self._allowed_prompt_params.intersection(
+ set(query_dict.get("prompt", "").split())
+ )
- self.params['code_challenge'] = query_dict.get('code_challenge', '')
- self.params['code_challenge_method'] = query_dict.get('code_challenge_method', '')
+ self.params["code_challenge"] = query_dict.get("code_challenge", "")
+ self.params["code_challenge_method"] = query_dict.get(
+ "code_challenge_method", ""
+ )
def validate_params(self):
# Client validation.
try:
- self.client = self.client_class.objects.get(client_id=self.params['client_id'])
+ self.client = self.client_class.objects.get(
+ client_id=self.params["client_id"]
+ )
except Client.DoesNotExist:
- logger.debug('[Authorize] Invalid client identifier: %s', self.params['client_id'])
+ logger.debug(
+ "[Authorize] Invalid client identifier: %s", self.params["client_id"]
+ )
raise ClientIdError()
# Redirect URI validation.
- if self.is_authentication and not self.params['redirect_uri']:
- logger.debug('[Authorize] Missing redirect uri.')
+ if self.is_authentication and not self.params["redirect_uri"]:
+ logger.debug("[Authorize] Missing redirect uri.")
raise RedirectUriError()
- if not (self.params['redirect_uri'] in self.client.redirect_uris):
- logger.debug('[Authorize] Invalid redirect uri: %s', self.params['redirect_uri'])
+ if not (self.params["redirect_uri"] in self.client.redirect_uris):
+ logger.debug(
+ "[Authorize] Invalid redirect uri: %s", self.params["redirect_uri"]
+ )
raise RedirectUriError()
# Grant type validation.
if not self.grant_type:
- logger.debug('[Authorize] Invalid response type: %s', self.params['response_type'])
+ logger.debug(
+ "[Authorize] Invalid response type: %s", self.params["response_type"]
+ )
raise AuthorizeError(
- self.params['redirect_uri'], 'unsupported_response_type', self.grant_type)
-
- if (not self.is_authentication and (self.grant_type == 'hybrid' or
- self.params['response_type'] in ['id_token', 'id_token token'])):
- logger.debug('[Authorize] Missing openid scope.')
- raise AuthorizeError(self.params['redirect_uri'], 'invalid_scope', self.grant_type)
+ self.params["redirect_uri"],
+ "unsupported_response_type",
+ self.grant_type,
+ )
+
+ if not self.is_authentication and (
+ self.grant_type == "hybrid"
+ or self.params["response_type"] in ["id_token", "id_token token"]
+ ):
+ logger.debug("[Authorize] Missing openid scope.")
+ raise AuthorizeError(
+ self.params["redirect_uri"], "invalid_scope", self.grant_type
+ )
# Nonce parameter validation.
- if self.is_authentication and self.grant_type == 'implicit' and not self.params['nonce']:
- raise AuthorizeError(self.params['redirect_uri'], 'invalid_request', self.grant_type)
+ if (
+ self.is_authentication
+ and self.grant_type == "implicit"
+ and not self.params["nonce"]
+ ):
+ raise AuthorizeError(
+ self.params["redirect_uri"], "invalid_request", self.grant_type
+ )
# Response type parameter validation.
- if self.is_authentication \
- and self.params['response_type'] not in self.client.response_type_values():
- raise AuthorizeError(self.params['redirect_uri'], 'invalid_request', self.grant_type)
+ if (
+ self.is_authentication
+ and self.params["response_type"] not in self.client.response_type_values()
+ ):
+ raise AuthorizeError(
+ self.params["redirect_uri"], "invalid_request", self.grant_type
+ )
# PKCE validation of the transformation method.
- if self.params['code_challenge']:
- if not (self.params['code_challenge_method'] in ['plain', 'S256']):
+ if self.params["code_challenge"]:
+ if not (self.params["code_challenge_method"] in ["plain", "S256"]):
raise AuthorizeError(
- self.params['redirect_uri'], 'invalid_request', self.grant_type)
+ self.params["redirect_uri"], "invalid_request", self.grant_type
+ )
def create_response_uri(self):
- uri = urlsplit(self.params['redirect_uri'])
+ uri = urlsplit(self.params["redirect_uri"])
query_params = parse_qs(uri.query)
query_fragment = {}
try:
- if self.grant_type in ['authorization_code', 'hybrid']:
+ if self.grant_type in ["authorization_code", "hybrid"]:
code = create_code(
user=self.request.user,
client=self.client,
- scope=self.params['scope'],
- nonce=self.params['nonce'],
+ scope=self.params["scope"],
+ nonce=self.params["nonce"],
is_authentication=self.is_authentication,
- code_challenge=self.params['code_challenge'],
- code_challenge_method=self.params['code_challenge_method'])
+ code_challenge=self.params["code_challenge"],
+ code_challenge_method=self.params["code_challenge_method"],
+ )
code.save()
- if self.grant_type == 'authorization_code':
- query_params['code'] = code.code
- query_params['state'] = self.params['state'] if self.params['state'] else ''
- elif self.grant_type in ['implicit', 'hybrid']:
+ if self.grant_type == "authorization_code":
+ query_params["code"] = code.code
+ query_params["state"] = (
+ self.params["state"] if self.params["state"] else ""
+ )
+ elif self.grant_type in ["implicit", "hybrid"]:
token = create_token(
user=self.request.user,
client=self.client,
- scope=self.params['scope'])
+ scope=self.params["scope"],
+ )
# Check if response_type must include access_token in the response.
- if (self.params['response_type'] in
- ['id_token token', 'token', 'code token', 'code id_token token']):
- query_fragment['access_token'] = token.access_token
+ if self.params["response_type"] in [
+ "id_token token",
+ "token",
+ "code token",
+ "code id_token token",
+ ]:
+ query_fragment["access_token"] = token.access_token
# We don't need id_token if it's an OAuth2 request.
if self.is_authentication:
kwargs = {
- 'token': token,
- 'user': self.request.user,
- 'aud': self.client.client_id,
- 'nonce': self.params['nonce'],
- 'request': self.request,
- 'scope': self.params['scope'],
+ "token": token,
+ "user": self.request.user,
+ "aud": self.client.client_id,
+ "nonce": self.params["nonce"],
+ "request": self.request,
+ "scope": self.params["scope"],
}
# Include at_hash when access_token is being returned.
- if 'access_token' in query_fragment:
- kwargs['at_hash'] = token.at_hash
+ if "access_token" in query_fragment:
+ kwargs["at_hash"] = token.at_hash
id_token_dic = create_id_token(**kwargs)
# Check if response_type must include id_token in the response.
- if self.params['response_type'] in [
- 'id_token', 'id_token token', 'code id_token', 'code id_token token']:
- query_fragment['id_token'] = encode_id_token(id_token_dic, self.client)
+ if self.params["response_type"] in [
+ "id_token",
+ "id_token token",
+ "code id_token",
+ "code id_token token",
+ ]:
+ query_fragment["id_token"] = encode_id_token(
+ id_token_dic, self.client
+ )
else:
id_token_dic = {}
@@ -184,20 +224,23 @@ class AuthorizeEndpoint(object):
token.save()
# Code parameter must be present if it's Hybrid Flow.
- if self.grant_type == 'hybrid':
- query_fragment['code'] = code.code
+ if self.grant_type == "hybrid":
+ query_fragment["code"] = code.code
- query_fragment['token_type'] = 'bearer'
+ query_fragment["token_type"] = "bearer"
- query_fragment['expires_in'] = settings.get('OIDC_TOKEN_EXPIRE')
+ query_fragment["expires_in"] = settings.get("OIDC_TOKEN_EXPIRE")
- query_fragment['state'] = self.params['state'] if self.params['state'] else ''
+ query_fragment["state"] = (
+ self.params["state"] if self.params["state"] else ""
+ )
- if settings.get('OIDC_SESSION_MANAGEMENT_ENABLE'):
+ if settings.get("OIDC_SESSION_MANAGEMENT_ENABLE"):
# Generate client origin URI from the redirect_uri param.
- redirect_uri_parsed = urlsplit(self.params['redirect_uri'])
- client_origin = '{0}://{1}'.format(
- redirect_uri_parsed.scheme, redirect_uri_parsed.netloc)
+ redirect_uri_parsed = urlsplit(self.params["redirect_uri"])
+ client_origin = "{0}://{1}".format(
+ redirect_uri_parsed.scheme, redirect_uri_parsed.netloc
+ )
# Create random salt.
salt = md5(uuid4().hex.encode()).hexdigest()
@@ -205,25 +248,31 @@ class AuthorizeEndpoint(object):
# The generation of suitable Session State values is based
# on a salted cryptographic hash of Client ID, origin URL,
# and OP browser state.
- session_state = '{client_id} {origin} {browser_state} {salt}'.format(
+ session_state = "{client_id} {origin} {browser_state} {salt}".format(
client_id=self.client.client_id,
origin=client_origin,
browser_state=get_browser_state_or_default(self.request),
- salt=salt)
- session_state = sha256(session_state.encode('utf-8')).hexdigest()
- session_state += '.' + salt
- if self.grant_type == 'authorization_code':
- query_params['session_state'] = session_state
- elif self.grant_type in ['implicit', 'hybrid']:
- query_fragment['session_state'] = session_state
+ salt=salt,
+ )
+ session_state = sha256(session_state.encode("utf-8")).hexdigest()
+ session_state += "." + salt
+ if self.grant_type == "authorization_code":
+ query_params["session_state"] = session_state
+ elif self.grant_type in ["implicit", "hybrid"]:
+ query_fragment["session_state"] = session_state
except Exception as error:
- logger.exception('[Authorize] Error when trying to create response uri: %s', error)
- raise AuthorizeError(self.params['redirect_uri'], 'server_error', self.grant_type)
+ logger.exception(
+ "[Authorize] Error when trying to create response uri: %s", error
+ )
+ raise AuthorizeError(
+ self.params["redirect_uri"], "server_error", self.grant_type
+ )
uri = uri._replace(
query=urlencode(query_params, doseq=True),
- fragment=uri.fragment + urlencode(query_fragment, doseq=True))
+ fragment=uri.fragment + urlencode(query_fragment, doseq=True),
+ )
return urlunsplit(uri)
@@ -235,17 +284,18 @@ class AuthorizeEndpoint(object):
"""
date_given = timezone.now()
expires_at = date_given + timedelta(
- days=settings.get('OIDC_SKIP_CONSENT_EXPIRE'))
+ days=settings.get("OIDC_SKIP_CONSENT_EXPIRE")
+ )
uc, created = UserConsent.objects.get_or_create(
user=self.request.user,
client=self.client,
defaults={
- 'expires_at': expires_at,
- 'date_given': date_given,
- }
+ "expires_at": expires_at,
+ "date_given": date_given,
+ },
)
- uc.scope = self.params['scope']
+ uc.scope = self.params["scope"]
# Rewrite expires_at and date_given if object already exists.
if not created:
@@ -263,7 +313,9 @@ class AuthorizeEndpoint(object):
value = False
try:
uc = UserConsent.objects.get(user=self.request.user, client=self.client)
- if (set(self.params['scope']).issubset(uc.scope)) and not (uc.has_expired()):
+ if (set(self.params["scope"]).issubset(uc.scope)) and not (
+ uc.has_expired()
+ ):
value = True
except UserConsent.DoesNotExist:
pass
@@ -274,13 +326,14 @@ class AuthorizeEndpoint(object):
"""
Return a list with the description of all the scopes requested.
"""
- scopes = StandardScopeClaims.get_scopes_info(self.params['scope'])
- if settings.get('OIDC_EXTRA_SCOPE_CLAIMS'):
+ scopes = StandardScopeClaims.get_scopes_info(self.params["scope"])
+ if settings.get("OIDC_EXTRA_SCOPE_CLAIMS"):
scopes_extra = settings.get(
- 'OIDC_EXTRA_SCOPE_CLAIMS', import_str=True).get_scopes_info(self.params['scope'])
+ "OIDC_EXTRA_SCOPE_CLAIMS", import_str=True
+ ).get_scopes_info(self.params["scope"])
for index_extra, scope_extra in enumerate(scopes_extra):
for index, scope in enumerate(scopes[:]):
- if scope_extra['scope'] == scope['scope']:
+ if scope_extra["scope"] == scope["scope"]:
del scopes[index]
else:
scopes_extra = []
Index: django-oidc-provider-0.7.0/oidc_provider/lib/endpoints/introspection.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/lib/endpoints/introspection.py
+++ django-oidc-provider-0.7.0/oidc_provider/lib/endpoints/introspection.py
@@ -2,19 +2,18 @@ import logging
from django.http import JsonResponse
+from oidc_provider import settings
from oidc_provider.lib.errors import TokenIntrospectionError
from oidc_provider.lib.utils.common import run_processing_hook
from oidc_provider.lib.utils.oauth2 import extract_client_auth
-from oidc_provider.models import Token, Client
-from oidc_provider import settings
+from oidc_provider.models import Client, Token
logger = logging.getLogger(__name__)
-INTROSPECTION_SCOPE = 'token_introspection'
+INTROSPECTION_SCOPE = "token_introspection"
class TokenIntrospectionEndpoint(object):
-
def __init__(self, request):
self.request = request
self.params = {}
@@ -25,71 +24,86 @@ class TokenIntrospectionEndpoint(object)
def _extract_params(self):
# Introspection only supports POST requests
- self.params['token'] = self.request.POST.get('token')
+ self.params["token"] = self.request.POST.get("token")
client_id, client_secret = extract_client_auth(self.request)
- self.params['client_id'] = client_id
- self.params['client_secret'] = client_secret
+ self.params["client_id"] = client_id
+ self.params["client_secret"] = client_secret
def validate_params(self):
- if not (self.params['client_id'] and self.params['client_secret']):
- logger.debug('[Introspection] No client credentials provided')
+ if not (self.params["client_id"] and self.params["client_secret"]):
+ logger.debug("[Introspection] No client credentials provided")
raise TokenIntrospectionError()
- if not self.params['token']:
- logger.debug('[Introspection] No token provided')
+ if not self.params["token"]:
+ logger.debug("[Introspection] No token provided")
raise TokenIntrospectionError()
try:
- self.token = Token.objects.get(access_token=self.params['token'])
+ self.token = Token.objects.get(access_token=self.params["token"])
except Token.DoesNotExist:
- logger.debug('[Introspection] Token does not exist: %s', self.params['token'])
+ logger.debug(
+ "[Introspection] Token does not exist: %s", self.params["token"]
+ )
raise TokenIntrospectionError()
if self.token.has_expired():
- logger.debug('[Introspection] Token is not valid: %s', self.params['token'])
+ logger.debug("[Introspection] Token is not valid: %s", self.params["token"])
raise TokenIntrospectionError()
try:
self.client = Client.objects.get(
- client_id=self.params['client_id'],
- client_secret=self.params['client_secret'])
+ client_id=self.params["client_id"],
+ client_secret=self.params["client_secret"],
+ )
except Client.DoesNotExist:
- logger.debug('[Introspection] No valid client for id: %s',
- self.params['client_id'])
+ logger.debug(
+ "[Introspection] No valid client for id: %s", self.params["client_id"]
+ )
raise TokenIntrospectionError()
if INTROSPECTION_SCOPE not in self.client.scope:
- logger.debug('[Introspection] Client %s does not have introspection scope',
- self.params['client_id'])
+ logger.debug(
+ "[Introspection] Client %s does not have introspection scope",
+ self.params["client_id"],
+ )
raise TokenIntrospectionError()
self.id_token = self.token.id_token
- if settings.get('OIDC_INTROSPECTION_VALIDATE_AUDIENCE_SCOPE'):
+ if settings.get("OIDC_INTROSPECTION_VALIDATE_AUDIENCE_SCOPE"):
if not self.token.id_token:
- logger.debug('[Introspection] Token not an authentication token: %s',
- self.params['token'])
+ logger.debug(
+ "[Introspection] Token not an authentication token: %s",
+ self.params["token"],
+ )
raise TokenIntrospectionError()
- audience = self.token.id_token.get('aud')
+ audience = self.token.id_token.get("aud")
if not audience:
- logger.debug('[Introspection] No audience found for token: %s',
- self.params['token'])
+ logger.debug(
+ "[Introspection] No audience found for token: %s",
+ self.params["token"],
+ )
raise TokenIntrospectionError()
if audience not in self.client.scope:
- logger.debug('[Introspection] Client %s does not audience scope %s',
- self.params['client_id'], audience)
+ logger.debug(
+ "[Introspection] Client %s does not audience scope %s",
+ self.params["client_id"],
+ audience,
+ )
raise TokenIntrospectionError()
def create_response_dic(self):
response_dic = {}
if self.id_token:
- for k in ('aud', 'sub', 'exp', 'iat', 'iss'):
+ for k in ("aud", "sub", "exp", "iat", "iss"):
response_dic[k] = self.id_token[k]
- response_dic['active'] = True
- response_dic['client_id'] = self.token.client.client_id
+ response_dic["active"] = True
+ response_dic["client_id"] = self.token.client.client_id
- response_dic = run_processing_hook(response_dic,
- 'OIDC_INTROSPECTION_PROCESSING_HOOK',
- client=self.client,
- id_token=self.id_token)
+ response_dic = run_processing_hook(
+ response_dic,
+ "OIDC_INTROSPECTION_PROCESSING_HOOK",
+ client=self.client,
+ id_token=self.id_token,
+ )
return response_dic
@@ -99,7 +113,7 @@ class TokenIntrospectionEndpoint(object)
Create and return a response object.
"""
response = JsonResponse(dic, status=status)
- response['Cache-Control'] = 'no-store'
- response['Pragma'] = 'no-cache'
+ response["Cache-Control"] = "no-store"
+ response["Pragma"] = "no-cache"
return response
Index: django-oidc-provider-0.7.0/oidc_provider/lib/endpoints/token.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/lib/endpoints/token.py
+++ django-oidc-provider-0.7.0/oidc_provider/lib/endpoints/token.py
@@ -1,33 +1,21 @@
-import inspect
-from base64 import urlsafe_b64encode
import hashlib
+import inspect
import logging
-from django.contrib.auth import authenticate
+from base64 import urlsafe_b64encode
+from django.contrib.auth import authenticate
from django.http import JsonResponse
-from oidc_provider.lib.errors import (
- TokenError,
- UserAuthError,
-)
-from oidc_provider.lib.utils.oauth2 import extract_client_auth
-from oidc_provider.lib.utils.token import (
- create_id_token,
- create_token,
- encode_id_token,
-)
-from oidc_provider.models import (
- Client,
- Code,
- Token,
-)
from oidc_provider import settings
+from oidc_provider.lib.errors import TokenError, UserAuthError
+from oidc_provider.lib.utils.oauth2 import extract_client_auth
+from oidc_provider.lib.utils.token import create_id_token, create_token, encode_id_token
+from oidc_provider.models import Client, Code, Token
logger = logging.getLogger(__name__)
class TokenEndpoint(object):
-
def __init__(self, request):
self.request = request
self.params = {}
@@ -37,65 +25,75 @@ class TokenEndpoint(object):
def _extract_params(self):
client_id, client_secret = extract_client_auth(self.request)
- self.params['client_id'] = client_id
- self.params['client_secret'] = client_secret
- self.params['redirect_uri'] = self.request.POST.get('redirect_uri', '')
- self.params['grant_type'] = self.request.POST.get('grant_type', '')
- self.params['code'] = self.request.POST.get('code', '')
- self.params['state'] = self.request.POST.get('state', '')
- self.params['scope'] = self.request.POST.get('scope', '')
- self.params['refresh_token'] = self.request.POST.get('refresh_token', '')
+ self.params["client_id"] = client_id
+ self.params["client_secret"] = client_secret
+ self.params["redirect_uri"] = self.request.POST.get("redirect_uri", "")
+ self.params["grant_type"] = self.request.POST.get("grant_type", "")
+ self.params["code"] = self.request.POST.get("code", "")
+ self.params["state"] = self.request.POST.get("state", "")
+ self.params["scope"] = self.request.POST.get("scope", "")
+ self.params["refresh_token"] = self.request.POST.get("refresh_token", "")
# PKCE parameter.
- self.params['code_verifier'] = self.request.POST.get('code_verifier')
+ self.params["code_verifier"] = self.request.POST.get("code_verifier")
- self.params['username'] = self.request.POST.get('username', '')
- self.params['password'] = self.request.POST.get('password', '')
+ self.params["username"] = self.request.POST.get("username", "")
+ self.params["password"] = self.request.POST.get("password", "")
def validate_params(self):
try:
- self.client = Client.objects.get(client_id=self.params['client_id'])
+ self.client = Client.objects.get(client_id=self.params["client_id"])
except Client.DoesNotExist:
- logger.debug('[Token] Client does not exist: %s', self.params['client_id'])
- raise TokenError('invalid_client')
+ logger.debug("[Token] Client does not exist: %s", self.params["client_id"])
+ raise TokenError("invalid_client")
+
+ if self.client.client_type == "confidential":
+ if not (self.client.client_secret == self.params["client_secret"]):
+ logger.debug(
+ "[Token] Invalid client secret: client %s do not have secret %s",
+ self.client.client_id,
+ self.client.client_secret,
+ )
+ raise TokenError("invalid_client")
- if self.client.client_type == 'confidential':
- if not (self.client.client_secret == self.params['client_secret']):
- logger.debug('[Token] Invalid client secret: client %s do not have secret %s',
- self.client.client_id, self.client.client_secret)
- raise TokenError('invalid_client')
-
- if self.params['grant_type'] == 'authorization_code':
- if not (self.params['redirect_uri'] in self.client.redirect_uris):
- logger.debug('[Token] Invalid redirect uri: %s', self.params['redirect_uri'])
- raise TokenError('invalid_client')
+ if self.params["grant_type"] == "authorization_code":
+ if not (self.params["redirect_uri"] in self.client.redirect_uris):
+ logger.debug(
+ "[Token] Invalid redirect uri: %s", self.params["redirect_uri"]
+ )
+ raise TokenError("invalid_client")
try:
- self.code = Code.objects.get(code=self.params['code'])
+ self.code = Code.objects.get(code=self.params["code"])
except Code.DoesNotExist:
- logger.debug('[Token] Code does not exist: %s', self.params['code'])
- raise TokenError('invalid_grant')
+ logger.debug("[Token] Code does not exist: %s", self.params["code"])
+ raise TokenError("invalid_grant")
- if not (self.code.client == self.client) \
- or self.code.has_expired():
- logger.debug('[Token] Invalid code: invalid client or code has expired')
- raise TokenError('invalid_grant')
+ if not (self.code.client == self.client) or self.code.has_expired():
+ logger.debug("[Token] Invalid code: invalid client or code has expired")
+ raise TokenError("invalid_grant")
# Validate PKCE parameters.
- if self.params['code_verifier']:
- if self.code.code_challenge_method == 'S256':
- new_code_challenge = urlsafe_b64encode(
- hashlib.sha256(self.params['code_verifier'].encode('ascii')).digest()
- ).decode('utf-8').replace('=', '')
+ if self.params["code_verifier"]:
+ if self.code.code_challenge_method == "S256":
+ new_code_challenge = (
+ urlsafe_b64encode(
+ hashlib.sha256(
+ self.params["code_verifier"].encode("ascii")
+ ).digest()
+ )
+ .decode("utf-8")
+ .replace("=", "")
+ )
else:
- new_code_challenge = self.params['code_verifier']
+ new_code_challenge = self.params["code_verifier"]
# TODO: We should explain the error.
if not (new_code_challenge == self.code.code_challenge):
- raise TokenError('invalid_grant')
+ raise TokenError("invalid_grant")
- elif self.params['grant_type'] == 'password':
- if not settings.get('OIDC_GRANT_TYPE_PASSWORD_ENABLE'):
- raise TokenError('unsupported_grant_type')
+ elif self.params["grant_type"] == "password":
+ if not settings.get("OIDC_GRANT_TYPE_PASSWORD_ENABLE"):
+ raise TokenError("unsupported_grant_type")
auth_args = (self.request,)
try:
@@ -105,8 +103,8 @@ class TokenEndpoint(object):
user = authenticate(
*auth_args,
- username=self.params['username'],
- password=self.params['password']
+ username=self.params["username"],
+ password=self.params["password"]
)
if not user:
@@ -114,44 +112,46 @@ class TokenEndpoint(object):
self.user = user
- elif self.params['grant_type'] == 'refresh_token':
- if not self.params['refresh_token']:
- logger.debug('[Token] Missing refresh token')
- raise TokenError('invalid_grant')
+ elif self.params["grant_type"] == "refresh_token":
+ if not self.params["refresh_token"]:
+ logger.debug("[Token] Missing refresh token")
+ raise TokenError("invalid_grant")
try:
- self.token = Token.objects.get(refresh_token=self.params['refresh_token'],
- client=self.client)
+ self.token = Token.objects.get(
+ refresh_token=self.params["refresh_token"], client=self.client
+ )
except Token.DoesNotExist:
logger.debug(
- '[Token] Refresh token does not exist: %s', self.params['refresh_token'])
- raise TokenError('invalid_grant')
- elif self.params['grant_type'] == 'client_credentials':
+ "[Token] Refresh token does not exist: %s",
+ self.params["refresh_token"],
+ )
+ raise TokenError("invalid_grant")
+ elif self.params["grant_type"] == "client_credentials":
if not self.client._scope:
- logger.debug('[Token] Client using client credentials with empty scope')
- raise TokenError('invalid_scope')
+ logger.debug("[Token] Client using client credentials with empty scope")
+ raise TokenError("invalid_scope")
else:
- logger.debug('[Token] Invalid grant type: %s', self.params['grant_type'])
- raise TokenError('unsupported_grant_type')
+ logger.debug("[Token] Invalid grant type: %s", self.params["grant_type"])
+ raise TokenError("unsupported_grant_type")
def create_response_dic(self):
- if self.params['grant_type'] == 'authorization_code':
+ if self.params["grant_type"] == "authorization_code":
return self.create_code_response_dic()
- elif self.params['grant_type'] == 'refresh_token':
+ elif self.params["grant_type"] == "refresh_token":
return self.create_refresh_response_dic()
- elif self.params['grant_type'] == 'password':
+ elif self.params["grant_type"] == "password":
return self.create_access_token_response_dic()
- elif self.params['grant_type'] == 'client_credentials':
+ elif self.params["grant_type"] == "client_credentials":
return self.create_client_credentials_response_dic()
def create_code_response_dic(self):
# See https://tools.ietf.org/html/rfc6749#section-4.1
token = create_token(
- user=self.code.user,
- client=self.code.client,
- scope=self.code.scope)
+ user=self.code.user, client=self.code.client, scope=self.code.scope
+ )
if self.code.is_authentication:
id_token_dic = create_id_token(
@@ -174,11 +174,11 @@ class TokenEndpoint(object):
self.code.delete()
dic = {
- 'access_token': token.access_token,
- 'refresh_token': token.refresh_token,
- 'token_type': 'bearer',
- 'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
- 'id_token': encode_id_token(id_token_dic, token.client),
+ "access_token": token.access_token,
+ "refresh_token": token.refresh_token,
+ "token_type": "bearer",
+ "expires_in": settings.get("OIDC_TOKEN_EXPIRE"),
+ "id_token": encode_id_token(id_token_dic, token.client),
}
return dic
@@ -186,16 +186,15 @@ class TokenEndpoint(object):
def create_refresh_response_dic(self):
# See https://tools.ietf.org/html/rfc6749#section-6
- scope_param = self.params['scope']
- scope = (scope_param.split(' ') if scope_param else self.token.scope)
+ scope_param = self.params["scope"]
+ scope = scope_param.split(" ") if scope_param else self.token.scope
unauthorized_scopes = set(scope) - set(self.token.scope)
if unauthorized_scopes:
- raise TokenError('invalid_scope')
+ raise TokenError("invalid_scope")
token = create_token(
- user=self.token.user,
- client=self.token.client,
- scope=scope)
+ user=self.token.user, client=self.token.client, scope=scope
+ )
# If the Token has an id_token it's an Authentication request.
if self.token.id_token:
@@ -219,11 +218,11 @@ class TokenEndpoint(object):
self.token.delete()
dic = {
- 'access_token': token.access_token,
- 'refresh_token': token.refresh_token,
- 'token_type': 'bearer',
- 'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
- 'id_token': encode_id_token(id_token_dic, self.token.client),
+ "access_token": token.access_token,
+ "refresh_token": token.refresh_token,
+ "token_type": "bearer",
+ "expires_in": settings.get("OIDC_TOKEN_EXPIRE"),
+ "id_token": encode_id_token(id_token_dic, self.token.client),
}
return dic
@@ -231,16 +230,13 @@ class TokenEndpoint(object):
def create_access_token_response_dic(self):
# See https://tools.ietf.org/html/rfc6749#section-4.3
- token = create_token(
- self.user,
- self.client,
- self.params['scope'].split(' '))
+ token = create_token(self.user, self.client, self.params["scope"].split(" "))
id_token_dic = create_id_token(
token=token,
user=self.user,
aud=self.client.client_id,
- nonce='self.code.nonce',
+ nonce="self.code.nonce",
at_hash=token.at_hash,
request=self.request,
scope=token.scope,
@@ -250,28 +246,25 @@ class TokenEndpoint(object):
token.save()
return {
- 'access_token': token.access_token,
- 'refresh_token': token.refresh_token,
- 'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
- 'token_type': 'bearer',
- 'id_token': encode_id_token(id_token_dic, token.client),
+ "access_token": token.access_token,
+ "refresh_token": token.refresh_token,
+ "expires_in": settings.get("OIDC_TOKEN_EXPIRE"),
+ "token_type": "bearer",
+ "id_token": encode_id_token(id_token_dic, token.client),
}
def create_client_credentials_response_dic(self):
# See https://tools.ietf.org/html/rfc6749#section-4.4.3
- token = create_token(
- user=None,
- client=self.client,
- scope=self.client.scope)
+ token = create_token(user=None, client=self.client, scope=self.client.scope)
token.save()
return {
- 'access_token': token.access_token,
- 'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
- 'token_type': 'bearer',
- 'scope': self.client._scope,
+ "access_token": token.access_token,
+ "expires_in": settings.get("OIDC_TOKEN_EXPIRE"),
+ "token_type": "bearer",
+ "scope": self.client._scope,
}
@classmethod
@@ -280,7 +273,7 @@ class TokenEndpoint(object):
Create and return a response object.
"""
response = JsonResponse(dic, status=status)
- response['Cache-Control'] = 'no-store'
- response['Pragma'] = 'no-cache'
+ response["Cache-Control"] = "no-store"
+ response["Pragma"] = "no-cache"
return response
Index: django-oidc-provider-0.7.0/oidc_provider/lib/errors.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/lib/errors.py
+++ django-oidc-provider-0.7.0/oidc_provider/lib/errors.py
@@ -6,15 +6,17 @@ except ImportError:
class RedirectUriError(Exception):
- error = 'Redirect URI Error'
- description = 'The request fails due to a missing, invalid, or mismatching' \
- ' redirection URI (redirect_uri).'
+ error = "Redirect URI Error"
+ description = (
+ "The request fails due to a missing, invalid, or mismatching"
+ " redirection URI (redirect_uri)."
+ )
class ClientIdError(Exception):
- error = 'Client ID Error'
- description = 'The client identifier (client_id) is missing or invalid.'
+ error = "Client ID Error"
+ description = "The client identifier (client_id) is missing or invalid."
class UserAuthError(Exception):
@@ -22,13 +24,14 @@ class UserAuthError(Exception):
Specific to the Resource Owner Password Credentials flow when
the Resource Owners credentials are not valid.
"""
- error = 'access_denied'
- description = 'The resource owner or authorization server denied the request.'
+
+ error = "access_denied"
+ description = "The resource owner or authorization server denied the request."
def create_dict(self):
return {
- 'error': self.error,
- 'error_description': self.description,
+ "error": self.error,
+ "error_description": self.description,
}
@@ -38,6 +41,7 @@ class TokenIntrospectionError(Exception)
to an "active: false" response, as per the spec.
See https://tools.ietf.org/html/rfc7662
"""
+
pass
@@ -46,56 +50,39 @@ class AuthorizeError(Exception):
_errors = {
# Oauth2 errors.
# https://tools.ietf.org/html/rfc6749#section-4.1.2.1
- 'invalid_request': 'The request is otherwise malformed',
-
- 'unauthorized_client': 'The client is not authorized to request an '
- 'authorization code using this method',
-
- 'access_denied': 'The resource owner or authorization server denied '
- 'the request',
-
- 'unsupported_response_type': 'The authorization server does not '
- 'support obtaining an authorization code '
- 'using this method',
-
- 'invalid_scope': 'The requested scope is invalid, unknown, or '
- 'malformed',
-
- 'server_error': 'The authorization server encountered an error',
-
- 'temporarily_unavailable': 'The authorization server is currently '
- 'unable to handle the request due to a '
- 'temporary overloading or maintenance of '
- 'the server',
-
+ "invalid_request": "The request is otherwise malformed",
+ "unauthorized_client": "The client is not authorized to request an "
+ "authorization code using this method",
+ "access_denied": "The resource owner or authorization server denied "
+ "the request",
+ "unsupported_response_type": "The authorization server does not "
+ "support obtaining an authorization code "
+ "using this method",
+ "invalid_scope": "The requested scope is invalid, unknown, or " "malformed",
+ "server_error": "The authorization server encountered an error",
+ "temporarily_unavailable": "The authorization server is currently "
+ "unable to handle the request due to a "
+ "temporary overloading or maintenance of "
+ "the server",
# OpenID errors.
# http://openid.net/specs/openid-connect-core-1_0.html#AuthError
- 'interaction_required': 'The Authorization Server requires End-User '
- 'interaction of some form to proceed',
-
- 'login_required': 'The Authorization Server requires End-User '
- 'authentication',
-
- 'account_selection_required': 'The End-User is required to select a '
- 'session at the Authorization Server',
-
- 'consent_required': 'The Authorization Server requires End-User'
- 'consent',
-
- 'invalid_request_uri': 'The request_uri in the Authorization Request '
- 'returns an error or contains invalid data',
-
- 'invalid_request_object': 'The request parameter contains an invalid '
- 'Request Object',
-
- 'request_not_supported': 'The provider does not support use of the '
- 'request parameter',
-
- 'request_uri_not_supported': 'The provider does not support use of the '
- 'request_uri parameter',
-
- 'registration_not_supported': 'The provider does not support use of '
- 'the registration parameter',
+ "interaction_required": "The Authorization Server requires End-User "
+ "interaction of some form to proceed",
+ "login_required": "The Authorization Server requires End-User "
+ "authentication",
+ "account_selection_required": "The End-User is required to select a "
+ "session at the Authorization Server",
+ "consent_required": "The Authorization Server requires End-User" "consent",
+ "invalid_request_uri": "The request_uri in the Authorization Request "
+ "returns an error or contains invalid data",
+ "invalid_request_object": "The request parameter contains an invalid "
+ "Request Object",
+ "request_not_supported": "The provider does not support use of the "
+ "request parameter",
+ "request_uri_not_supported": "The provider does not support use of the "
+ "request_uri parameter",
+ "registration_not_supported": "The provider does not support use of "
+ "the registration parameter",
}
def __init__(self, redirect_uri, error, grant_type):
@@ -109,16 +96,14 @@ class AuthorizeError(Exception):
# See:
# http://openid.net/specs/openid-connect-core-1_0.html#ImplicitAuthError
- hash_or_question = '#' if self.grant_type == 'implicit' else '?'
+ hash_or_question = "#" if self.grant_type == "implicit" else "?"
- uri = '{0}{1}error={2}&error_description={3}'.format(
- redirect_uri,
- hash_or_question,
- self.error,
- description)
+ uri = "{0}{1}error={2}&error_description={3}".format(
+ redirect_uri, hash_or_question, self.error, description
+ )
# Add state if present.
- uri = uri + ('&state={0}'.format(state) if state else '')
+ uri = uri + ("&state={0}".format(state) if state else "")
return uri
@@ -130,25 +115,20 @@ class TokenError(Exception):
"""
_errors = {
- 'invalid_request': 'The request is otherwise malformed',
-
- 'invalid_client': 'Client authentication failed (e.g., unknown client, '
- 'no client authentication included, or unsupported '
- 'authentication method)',
-
- 'invalid_grant': 'The provided authorization grant or refresh token is '
- 'invalid, expired, revoked, does not match the '
- 'redirection URI used in the authorization request, '
- 'or was issued to another client',
-
- 'unauthorized_client': 'The authenticated client is not authorized to '
- 'use this authorization grant type',
-
- 'unsupported_grant_type': 'The authorization grant type is not '
- 'supported by the authorization server',
-
- 'invalid_scope': 'The requested scope is invalid, unknown, malformed, '
- 'or exceeds the scope granted by the resource owner',
+ "invalid_request": "The request is otherwise malformed",
+ "invalid_client": "Client authentication failed (e.g., unknown client, "
+ "no client authentication included, or unsupported "
+ "authentication method)",
+ "invalid_grant": "The provided authorization grant or refresh token is "
+ "invalid, expired, revoked, does not match the "
+ "redirection URI used in the authorization request, "
+ "or was issued to another client",
+ "unauthorized_client": "The authenticated client is not authorized to "
+ "use this authorization grant type",
+ "unsupported_grant_type": "The authorization grant type is not "
+ "supported by the authorization server",
+ "invalid_scope": "The requested scope is invalid, unknown, malformed, "
+ "or exceeds the scope granted by the resource owner",
}
def __init__(self, error):
@@ -157,8 +137,8 @@ class TokenError(Exception):
def create_dict(self):
dic = {
- 'error': self.error,
- 'error_description': self.description,
+ "error": self.error,
+ "error_description": self.description,
}
return dic
@@ -171,21 +151,21 @@ class BearerTokenError(Exception):
"""
_errors = {
- 'invalid_request': (
- 'The request is otherwise malformed', 400
- ),
- 'invalid_token': (
- 'The access token provided is expired, revoked, malformed, '
- 'or invalid for other reasons', 401
+ "invalid_request": ("The request is otherwise malformed", 400),
+ "invalid_token": (
+ "The access token provided is expired, revoked, malformed, "
+ "or invalid for other reasons",
+ 401,
),
- 'insufficient_scope': (
- 'The request requires higher privileges than provided by '
- 'the access token', 403
+ "insufficient_scope": (
+ "The request requires higher privileges than provided by "
+ "the access token",
+ 403,
),
}
def __init__(self, code):
self.code = code
- error_tuple = self._errors.get(code, ('', ''))
+ error_tuple = self._errors.get(code, ("", ""))
self.description = error_tuple[0]
self.status = error_tuple[1]
Index: django-oidc-provider-0.7.0/oidc_provider/lib/utils/authorize.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/lib/utils/authorize.py
+++ django-oidc-provider-0.7.0/oidc_provider/lib/utils/authorize.py
@@ -1,8 +1,9 @@
try:
from urllib import urlencode
- from urlparse import urlsplit, parse_qs, urlunsplit
+
+ from urlparse import parse_qs, urlsplit, urlunsplit
except ImportError:
- from urllib.parse import urlsplit, parse_qs, urlunsplit, urlencode
+ from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit
def strip_prompt_login(path):
@@ -11,11 +12,11 @@ def strip_prompt_login(path):
"""
uri = urlsplit(path)
query_params = parse_qs(uri.query)
- prompt_list = query_params.get('prompt', '')[0].split()
- if 'login' in prompt_list:
- prompt_list.remove('login')
- query_params['prompt'] = ' '.join(prompt_list)
- if not query_params['prompt']:
- del query_params['prompt']
+ prompt_list = query_params.get("prompt", "")[0].split()
+ if "login" in prompt_list:
+ prompt_list.remove("login")
+ query_params["prompt"] = " ".join(prompt_list)
+ if not query_params["prompt"]:
+ del query_params["prompt"]
uri = uri._replace(query=urlencode(query_params, doseq=True))
return urlunsplit(uri)
Index: django-oidc-provider-0.7.0/oidc_provider/lib/utils/common.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/lib/utils/common.py
+++ django-oidc-provider-0.7.0/oidc_provider/lib/utils/common.py
@@ -6,7 +6,6 @@ from django.utils.cache import patch_var
from oidc_provider import settings
-
if django.VERSION >= (1, 11):
from django.urls import reverse
else:
@@ -17,8 +16,8 @@ def redirect(uri):
"""
Custom Response object for redirecting to a Non-HTTP url scheme.
"""
- response = HttpResponse('', status=302)
- response['Location'] = uri
+ response = HttpResponse("", status=302)
+ response["Location"] = uri
return response
@@ -31,15 +30,17 @@ def get_site_url(site_url=None, request=
2. valid `SITE_URL` in settings
3. construct from `request` object
"""
- site_url = site_url or settings.get('SITE_URL')
+ site_url = site_url or settings.get("SITE_URL")
if site_url:
return site_url
elif request:
- return '{}://{}'.format(request.scheme, request.get_host())
+ return "{}://{}".format(request.scheme, request.get_host())
else:
- raise Exception('Either pass `site_url`, '
- 'or set `SITE_URL` in settings, '
- 'or pass `request` object.')
+ raise Exception(
+ "Either pass `site_url`, "
+ "or set `SITE_URL` in settings, "
+ "or pass `request` object."
+ )
def get_issuer(site_url=None, request=None):
@@ -48,8 +49,9 @@ def get_issuer(site_url=None, request=No
appended.
"""
site_url = get_site_url(site_url=site_url, request=request)
- path = reverse('oidc_provider:provider-info') \
- .split('/.well-known/openid-configuration')[0]
+ path = reverse("oidc_provider:provider-info").split(
+ "/.well-known/openid-configuration"
+ )[0]
issuer = site_url + path
return str(issuer)
@@ -78,8 +80,13 @@ def default_after_userlogin_hook(request
def default_after_end_session_hook(
- request, id_token=None, post_logout_redirect_uri=None,
- state=None, client=None, next_page=None):
+ request,
+ id_token=None,
+ post_logout_redirect_uri=None,
+ state=None,
+ client=None,
+ next_page=None,
+):
"""
Default function for setting OIDC_AFTER_END_SESSION_HOOK.
@@ -108,8 +115,7 @@ def default_after_end_session_hook(
return None
-def default_idtoken_processing_hook(
- id_token, user, token, request, **kwargs):
+def default_idtoken_processing_hook(id_token, user, token, request, **kwargs):
"""
Hook to perform some additional actions to `id_token` dictionary just before serialization.
@@ -146,9 +152,10 @@ def get_browser_state_or_default(request
"""
Determine value to use as session state.
"""
- key = (request.session.session_key or
- settings.get('OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY'))
- return sha224(key.encode('utf-8')).hexdigest()
+ key = request.session.session_key or settings.get(
+ "OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY"
+ )
+ return sha224(key.encode("utf-8")).hexdigest()
def run_processing_hook(subject, hook_settings_name, **kwargs):
@@ -168,19 +175,20 @@ def cors_allow_any(request, response):
Add headers to permit CORS requests from any origin, with or without credentials,
with any headers.
"""
- origin = request.META.get('HTTP_ORIGIN')
+ origin = request.headers.get("Origin")
if not origin:
return response
# From the CORS spec: The string "*" cannot be used for a resource that supports credentials.
- response['Access-Control-Allow-Origin'] = origin
- patch_vary_headers(response, ['Origin'])
- response['Access-Control-Allow-Credentials'] = 'true'
-
- if request.method == 'OPTIONS':
- if 'HTTP_ACCESS_CONTROL_REQUEST_HEADERS' in request.META:
- response['Access-Control-Allow-Headers'] \
- = request.META['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']
- response['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
+ response["Access-Control-Allow-Origin"] = origin
+ patch_vary_headers(response, ["Origin"])
+ response["Access-Control-Allow-Credentials"] = "true"
+
+ if request.method == "OPTIONS":
+ if "HTTP_ACCESS_CONTROL_REQUEST_HEADERS" in request.META:
+ response["Access-Control-Allow-Headers"] = request.META[
+ "HTTP_ACCESS_CONTROL_REQUEST_HEADERS"
+ ]
+ response["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"
return response
Index: django-oidc-provider-0.7.0/oidc_provider/lib/utils/oauth2.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/lib/utils/oauth2.py
+++ django-oidc-provider-0.7.0/oidc_provider/lib/utils/oauth2.py
@@ -1,13 +1,12 @@
-from base64 import b64decode
import logging
import re
+from base64 import b64decode
from django.http import HttpResponse
from oidc_provider.lib.errors import BearerTokenError
from oidc_provider.models import Token
-
logger = logging.getLogger(__name__)
@@ -19,12 +18,12 @@ def extract_access_token(request):
Return a string.
"""
- auth_header = request.META.get('HTTP_AUTHORIZATION', '')
+ auth_header = request.headers.get("Authorization", "")
- if re.compile('^[Bb]earer\s{1}.+$').match(auth_header):
+ if re.compile("^[Bb]earer\s{1}.+$").match(auth_header):
access_token = auth_header.split()[1]
else:
- access_token = request.GET.get('access_token', '')
+ access_token = request.GET.get("access_token", "")
return access_token
@@ -37,18 +36,18 @@ def extract_client_auth(request):
Return a tuple `(client_id, client_secret)`.
"""
- auth_header = request.META.get('HTTP_AUTHORIZATION', '')
+ auth_header = request.headers.get("Authorization", "")
- if re.compile('^Basic\s{1}.+$').match(auth_header):
+ if re.compile("^Basic\s{1}.+$").match(auth_header):
b64_user_pass = auth_header.split()[1]
try:
- user_pass = b64decode(b64_user_pass).decode('utf-8').split(':')
+ user_pass = b64decode(b64_user_pass).decode("utf-8").split(":")
client_id, client_secret = tuple(user_pass)
except Exception:
- client_id = client_secret = ''
+ client_id = client_secret = ""
else:
- client_id = request.POST.get('client_id', '')
- client_secret = request.POST.get('client_secret', '')
+ client_id = request.POST.get("client_id", "")
+ client_secret = request.POST.get("client_secret", "")
return (client_id, client_secret)
@@ -63,30 +62,33 @@ def protected_resource_view(scopes=None)
scopes = []
def wrapper(view):
- def view_wrapper(request, *args, **kwargs):
+ def view_wrapper(request, *args, **kwargs):
access_token = extract_access_token(request)
try:
try:
- kwargs['token'] = Token.objects.get(access_token=access_token)
+ kwargs["token"] = Token.objects.get(access_token=access_token)
except Token.DoesNotExist:
- logger.debug('[UserInfo] Token does not exist: %s', access_token)
- raise BearerTokenError('invalid_token')
+ logger.debug("[UserInfo] Token does not exist: %s", access_token)
+ raise BearerTokenError("invalid_token")
- if kwargs['token'].has_expired():
- logger.debug('[UserInfo] Token has expired: %s', access_token)
- raise BearerTokenError('invalid_token')
-
- if not set(scopes).issubset(set(kwargs['token'].scope)):
- logger.debug('[UserInfo] Missing openid scope.')
- raise BearerTokenError('insufficient_scope')
+ if kwargs["token"].has_expired():
+ logger.debug("[UserInfo] Token has expired: %s", access_token)
+ raise BearerTokenError("invalid_token")
+
+ if not set(scopes).issubset(set(kwargs["token"].scope)):
+ logger.debug("[UserInfo] Missing openid scope.")
+ raise BearerTokenError("insufficient_scope")
except BearerTokenError as error:
response = HttpResponse(status=error.status)
- response['WWW-Authenticate'] = 'error="{0}", error_description="{1}"'.format(
- error.code, error.description)
+ response[
+ "WWW-Authenticate"
+ ] = 'error="{0}", error_description="{1}"'.format(
+ error.code, error.description
+ )
return response
- return view(request, *args, **kwargs)
+ return view(request, *args, **kwargs)
return view_wrapper
Index: django-oidc-provider-0.7.0/oidc_provider/lib/utils/token.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/lib/utils/token.py
+++ django-oidc-provider-0.7.0/oidc_provider/lib/utils/token.py
@@ -1,6 +1,6 @@
-from datetime import timedelta
import time
import uuid
+from datetime import timedelta
from Cryptodome.PublicKey.RSA import importKey
from django.utils import dateformat, timezone
@@ -9,17 +9,13 @@ from jwkest.jwk import SYMKey
from jwkest.jws import JWS
from jwkest.jwt import JWT
-from oidc_provider.lib.utils.common import get_issuer, run_processing_hook
-from oidc_provider.lib.claims import StandardScopeClaims
-from oidc_provider.models import (
- Code,
- RSAKey,
- Token,
-)
from oidc_provider import settings
+from oidc_provider.lib.claims import StandardScopeClaims
+from oidc_provider.lib.utils.common import get_issuer, run_processing_hook
+from oidc_provider.models import Code, RSAKey, Token
-def create_id_token(token, user, aud, nonce='', at_hash='', request=None, scope=None):
+def create_id_token(token, user, aud, nonce="", at_hash="", request=None, scope=None):
"""
Creates the id_token dictionary.
See: http://openid.net/specs/openid-connect-core-1_0.html#IDToken
@@ -53,7 +49,7 @@ def create_id_token(token, user, aud, no
if at_hash:
dic['at_hash'] = at_hash
- # Inlude (or not) user standard claims in the id_token.
+ # Include (or not) user standard claims in the id_token.
if settings.get('OIDC_IDTOKEN_INCLUDE_CLAIMS'):
standard_claims = StandardScopeClaims(token)
dic.update(standard_claims.create_response_dic())
@@ -93,7 +89,7 @@ def client_id_from_id_token(id_token):
Returns a string or None.
"""
payload = JWT().unpack(id_token).payload()
- aud = payload.get('aud', None)
+ aud = payload.get("aud", None)
if aud is None:
return None
if isinstance(aud, list):
@@ -116,14 +112,22 @@ def create_token(user, client, scope, id
token.refresh_token = uuid.uuid4().hex
token.expires_at = timezone.now() + timedelta(
- seconds=settings.get('OIDC_TOKEN_EXPIRE'))
+ seconds=settings.get("OIDC_TOKEN_EXPIRE")
+ )
token.scope = scope
return token
-def create_code(user, client, scope, nonce, is_authentication,
- code_challenge=None, code_challenge_method=None):
+def create_code(
+ user,
+ client,
+ scope,
+ nonce,
+ is_authentication,
+ code_challenge=None,
+ code_challenge_method=None,
+):
"""
Create and populate a Code object.
Return a Code object.
@@ -139,7 +143,8 @@ def create_code(user, client, scope, non
code.code_challenge_method = code_challenge_method
code.expires_at = timezone.now() + timedelta(
- seconds=settings.get('OIDC_CODE_EXPIRE'))
+ seconds=settings.get("OIDC_CODE_EXPIRE")
+ )
code.scope = scope
code.nonce = nonce
code.is_authentication = is_authentication
@@ -152,15 +157,15 @@ def get_client_alg_keys(client):
Takes a client and returns the set of keys associated with it.
Returns a list of keys.
"""
- if client.jwt_alg == 'RS256':
+ if client.jwt_alg == "RS256":
keys = []
for rsakey in RSAKey.objects.all():
keys.append(jwk_RSAKey(key=importKey(rsakey.key), kid=rsakey.kid))
if not keys:
- raise Exception('You must add at least one RSA Key.')
- elif client.jwt_alg == 'HS256':
+ raise Exception("You must add at least one RSA Key.")
+ elif client.jwt_alg == "HS256":
keys = [SYMKey(key=client.client_secret, alg=client.jwt_alg)]
else:
- raise Exception('Unsupported key algorithm.')
+ raise Exception("Unsupported key algorithm.")
return keys
Index: django-oidc-provider-0.7.0/oidc_provider/management/commands/creatersakey.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/management/commands/creatersakey.py
+++ django-oidc-provider-0.7.0/oidc_provider/management/commands/creatersakey.py
@@ -1,16 +1,19 @@
from Cryptodome.PublicKey import RSA
from django.core.management.base import BaseCommand
+
from oidc_provider.models import RSAKey
class Command(BaseCommand):
- help = 'Randomly generate a new RSA key for the OpenID server'
+ help = "Randomly generate a new RSA key for the OpenID server"
def handle(self, *args, **options):
try:
key = RSA.generate(2048)
- rsakey = RSAKey(key=key.exportKey('PEM').decode('utf8'))
+ rsakey = RSAKey(key=key.exportKey("PEM").decode("utf8"))
rsakey.save()
- self.stdout.write(u'RSA key successfully created with kid: {0}'.format(rsakey.kid))
+ self.stdout.write(
+ "RSA key successfully created with kid: {0}".format(rsakey.kid)
+ )
except Exception as e:
- self.stdout.write('Something goes wrong: {0}'.format(e))
+ self.stdout.write("Something goes wrong: {0}".format(e))
Index: django-oidc-provider-0.7.0/oidc_provider/middleware.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/middleware.py
+++ django-oidc-provider-0.7.0/oidc_provider/middleware.py
@@ -16,6 +16,8 @@ class SessionManagementMiddleware(Middle
"""
def process_response(self, request, response):
- if settings.get('OIDC_SESSION_MANAGEMENT_ENABLE'):
- response.set_cookie('op_browser_state', get_browser_state_or_default(request))
+ if settings.get("OIDC_SESSION_MANAGEMENT_ENABLE"):
+ response.set_cookie(
+ "op_browser_state", get_browser_state_or_default(request)
+ )
return response
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0001_initial.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0001_initial.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0001_initial.py
@@ -1,103 +1,194 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.db import models, migrations
from django.conf import settings
+from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('auth', '0001_initial'),
+ ("auth", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
- name='Client',
+ name="Client",
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('name', models.CharField(default=b'', max_length=100)),
- ('client_id', models.CharField(unique=True, max_length=255)),
- ('client_secret', models.CharField(unique=True, max_length=255)),
- ('response_type', models.CharField(max_length=30, choices=[
- (b'code', b'code (Authorization Code Flow)'), (b'id_token', b'id_token (Implicit Flow)'),
- (b'id_token token', b'id_token token (Implicit Flow)')])),
- ('_redirect_uris', models.TextField(default=b'')),
+ (
+ "id",
+ models.AutoField(
+ verbose_name="ID",
+ serialize=False,
+ auto_created=True,
+ primary_key=True,
+ ),
+ ),
+ ("name", models.CharField(default=b"", max_length=100)),
+ ("client_id", models.CharField(unique=True, max_length=255)),
+ ("client_secret", models.CharField(unique=True, max_length=255)),
+ (
+ "response_type",
+ models.CharField(
+ max_length=30,
+ choices=[
+ (b"code", b"code (Authorization Code Flow)"),
+ (b"id_token", b"id_token (Implicit Flow)"),
+ (b"id_token token", b"id_token token (Implicit Flow)"),
+ ],
+ ),
+ ),
+ ("_redirect_uris", models.TextField(default=b"")),
],
- options={
- },
+ options={},
bases=(models.Model,),
),
migrations.CreateModel(
- name='Code',
+ name="Code",
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('expires_at', models.DateTimeField()),
- ('_scope', models.TextField(default=b'')),
- ('code', models.CharField(unique=True, max_length=255)),
- ('client', models.ForeignKey(to='oidc_provider.Client', on_delete=models.CASCADE)),
+ (
+ "id",
+ models.AutoField(
+ verbose_name="ID",
+ serialize=False,
+ auto_created=True,
+ primary_key=True,
+ ),
+ ),
+ ("expires_at", models.DateTimeField()),
+ ("_scope", models.TextField(default=b"")),
+ ("code", models.CharField(unique=True, max_length=255)),
+ (
+ "client",
+ models.ForeignKey(
+ to="oidc_provider.Client", on_delete=models.CASCADE
+ ),
+ ),
],
options={
- 'abstract': False,
+ "abstract": False,
},
bases=(models.Model,),
),
migrations.CreateModel(
- name='Token',
+ name="Token",
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('expires_at', models.DateTimeField()),
- ('_scope', models.TextField(default=b'')),
- ('access_token', models.CharField(unique=True, max_length=255)),
- ('_id_token', models.TextField()),
- ('client', models.ForeignKey(to='oidc_provider.Client', on_delete=models.CASCADE)),
+ (
+ "id",
+ models.AutoField(
+ verbose_name="ID",
+ serialize=False,
+ auto_created=True,
+ primary_key=True,
+ ),
+ ),
+ ("expires_at", models.DateTimeField()),
+ ("_scope", models.TextField(default=b"")),
+ ("access_token", models.CharField(unique=True, max_length=255)),
+ ("_id_token", models.TextField()),
+ (
+ "client",
+ models.ForeignKey(
+ to="oidc_provider.Client", on_delete=models.CASCADE
+ ),
+ ),
],
options={
- 'abstract': False,
+ "abstract": False,
},
bases=(models.Model,),
),
migrations.CreateModel(
- name='UserInfo',
+ name="UserInfo",
fields=[
- ('user', models.OneToOneField(primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
- ('given_name', models.CharField(max_length=255, null=True, blank=True)),
- ('family_name', models.CharField(max_length=255, null=True, blank=True)),
- ('middle_name', models.CharField(max_length=255, null=True, blank=True)),
- ('nickname', models.CharField(max_length=255, null=True, blank=True)),
- ('gender', models.CharField(max_length=100, null=True, choices=[(b'F', b'Female'), (b'M', b'Male')])),
- ('birthdate', models.DateField(null=True)),
- ('zoneinfo', models.CharField(default=b'', max_length=100, null=True, blank=True)),
- ('preferred_username', models.CharField(max_length=255, null=True, blank=True)),
- ('profile', models.URLField(default=b'', null=True, blank=True)),
- ('picture', models.URLField(default=b'', null=True, blank=True)),
- ('website', models.URLField(default=b'', null=True, blank=True)),
- ('email_verified', models.NullBooleanField(default=False)),
- ('locale', models.CharField(max_length=100, null=True, blank=True)),
- ('phone_number', models.CharField(max_length=255, null=True, blank=True)),
- ('phone_number_verified', models.NullBooleanField(default=False)),
- ('address_street_address', models.CharField(max_length=255, null=True, blank=True)),
- ('address_locality', models.CharField(max_length=255, null=True, blank=True)),
- ('address_region', models.CharField(max_length=255, null=True, blank=True)),
- ('address_postal_code', models.CharField(max_length=255, null=True, blank=True)),
- ('address_country', models.CharField(max_length=255, null=True, blank=True)),
- ('updated_at', models.DateTimeField(auto_now=True, null=True)),
+ (
+ "user",
+ models.OneToOneField(
+ primary_key=True,
+ serialize=False,
+ to=settings.AUTH_USER_MODEL,
+ on_delete=models.CASCADE,
+ ),
+ ),
+ ("given_name", models.CharField(max_length=255, null=True, blank=True)),
+ (
+ "family_name",
+ models.CharField(max_length=255, null=True, blank=True),
+ ),
+ (
+ "middle_name",
+ models.CharField(max_length=255, null=True, blank=True),
+ ),
+ ("nickname", models.CharField(max_length=255, null=True, blank=True)),
+ (
+ "gender",
+ models.CharField(
+ max_length=100,
+ null=True,
+ choices=[(b"F", b"Female"), (b"M", b"Male")],
+ ),
+ ),
+ ("birthdate", models.DateField(null=True)),
+ (
+ "zoneinfo",
+ models.CharField(
+ default=b"", max_length=100, null=True, blank=True
+ ),
+ ),
+ (
+ "preferred_username",
+ models.CharField(max_length=255, null=True, blank=True),
+ ),
+ ("profile", models.URLField(default=b"", null=True, blank=True)),
+ ("picture", models.URLField(default=b"", null=True, blank=True)),
+ ("website", models.URLField(default=b"", null=True, blank=True)),
+ ("email_verified", models.BooleanField(default=False, null=True)),
+ ("locale", models.CharField(max_length=100, null=True, blank=True)),
+ (
+ "phone_number",
+ models.CharField(max_length=255, null=True, blank=True),
+ ),
+ ("phone_number_verified", models.BooleanField(default=False, null=True)),
+ (
+ "address_street_address",
+ models.CharField(max_length=255, null=True, blank=True),
+ ),
+ (
+ "address_locality",
+ models.CharField(max_length=255, null=True, blank=True),
+ ),
+ (
+ "address_region",
+ models.CharField(max_length=255, null=True, blank=True),
+ ),
+ (
+ "address_postal_code",
+ models.CharField(max_length=255, null=True, blank=True),
+ ),
+ (
+ "address_country",
+ models.CharField(max_length=255, null=True, blank=True),
+ ),
+ ("updated_at", models.DateTimeField(auto_now=True, null=True)),
],
- options={
- },
+ options={},
bases=(models.Model,),
),
migrations.AddField(
- model_name='token',
- name='user',
- field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE),
+ model_name="token",
+ name="user",
+ field=models.ForeignKey(
+ to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE
+ ),
preserve_default=True,
),
migrations.AddField(
- model_name='code',
- name='user',
- field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE),
+ model_name="code",
+ name="user",
+ field=models.ForeignKey(
+ to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE
+ ),
preserve_default=True,
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0002_userconsent.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0002_userconsent.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0002_userconsent.py
@@ -1,29 +1,47 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.db import models, migrations
from django.conf import settings
+from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ('oidc_provider', '0001_initial'),
+ ("oidc_provider", "0001_initial"),
]
operations = [
migrations.CreateModel(
- name='UserConsent',
+ name="UserConsent",
fields=[
- ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
- ('expires_at', models.DateTimeField()),
- ('_scope', models.TextField(default=b'')),
- ('client', models.ForeignKey(to='oidc_provider.Client', on_delete=models.CASCADE)),
- ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)),
+ (
+ "id",
+ models.AutoField(
+ verbose_name="ID",
+ serialize=False,
+ auto_created=True,
+ primary_key=True,
+ ),
+ ),
+ ("expires_at", models.DateTimeField()),
+ ("_scope", models.TextField(default=b"")),
+ (
+ "client",
+ models.ForeignKey(
+ to="oidc_provider.Client", on_delete=models.CASCADE
+ ),
+ ),
+ (
+ "user",
+ models.ForeignKey(
+ to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE
+ ),
+ ),
],
options={
- 'abstract': False,
+ "abstract": False,
},
bases=(models.Model,),
),
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0003_code_nonce.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0003_code_nonce.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0003_code_nonce.py
@@ -1,19 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.db import models, migrations
+from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0002_userconsent'),
+ ("oidc_provider", "0002_userconsent"),
]
operations = [
migrations.AddField(
- model_name='code',
- name='nonce',
- field=models.CharField(default=b'', max_length=255, blank=True),
+ model_name="code",
+ name="nonce",
+ field=models.CharField(default=b"", max_length=255, blank=True),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0004_remove_userinfo.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0004_remove_userinfo.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0004_remove_userinfo.py
@@ -7,15 +7,15 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0003_code_nonce'),
+ ("oidc_provider", "0003_code_nonce"),
]
operations = [
migrations.RemoveField(
- model_name='userinfo',
- name='user',
+ model_name="userinfo",
+ name="user",
),
migrations.DeleteModel(
- name='UserInfo',
+ name="UserInfo",
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0005_token_refresh_token.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0005_token_refresh_token.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0005_token_refresh_token.py
@@ -1,19 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.db import models, migrations
+from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0004_remove_userinfo'),
+ ("oidc_provider", "0004_remove_userinfo"),
]
operations = [
migrations.AddField(
- model_name='token',
- name='refresh_token',
+ model_name="token",
+ name="refresh_token",
field=models.CharField(max_length=255, unique=True, null=True),
preserve_default=True,
),
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0006_unique_user_client.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0006_unique_user_client.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0006_unique_user_client.py
@@ -7,12 +7,12 @@ from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0005_token_refresh_token'),
+ ("oidc_provider", "0005_token_refresh_token"),
]
operations = [
migrations.AlterUniqueTogether(
- name='userconsent',
- unique_together=set([('user', 'client')]),
+ name="userconsent",
+ unique_together=set([("user", "client")]),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0007_auto_20160111_1844.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0007_auto_20160111_1844.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0007_auto_20160111_1844.py
@@ -3,6 +3,7 @@
from __future__ import unicode_literals
import datetime
+
from django.db import migrations, models
from django.utils.timezone import utc
@@ -10,32 +11,41 @@ from django.utils.timezone import utc
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0006_unique_user_client'),
+ ("oidc_provider", "0006_unique_user_client"),
]
operations = [
migrations.AlterModelOptions(
- name='client',
- options={'verbose_name': 'Client', 'verbose_name_plural': 'Clients'},
+ name="client",
+ options={"verbose_name": "Client", "verbose_name_plural": "Clients"},
),
migrations.AlterModelOptions(
- name='code',
- options={'verbose_name': 'Authorization Code', 'verbose_name_plural': 'Authorization Codes'},
+ name="code",
+ options={
+ "verbose_name": "Authorization Code",
+ "verbose_name_plural": "Authorization Codes",
+ },
),
migrations.AlterModelOptions(
- name='token',
- options={'verbose_name': 'Token', 'verbose_name_plural': 'Tokens'},
+ name="token",
+ options={"verbose_name": "Token", "verbose_name_plural": "Tokens"},
),
migrations.AddField(
- model_name='client',
- name='date_created',
+ model_name="client",
+ name="date_created",
field=models.DateField(
- auto_now_add=True, default=datetime.datetime(2016, 1, 11, 18, 44, 32, 192477, tzinfo=utc)),
+ auto_now_add=True,
+ default=datetime.datetime(2016, 1, 11, 18, 44, 32, 192477, tzinfo=utc),
+ ),
preserve_default=False,
),
migrations.AlterField(
- model_name='client',
- name='_redirect_uris',
- field=models.TextField(default=b'', help_text='Enter each URI on a new line.', verbose_name='Redirect URI'),
+ model_name="client",
+ name="_redirect_uris",
+ field=models.TextField(
+ default=b"",
+ help_text="Enter each URI on a new line.",
+ verbose_name="Redirect URI",
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0008_rsakey.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0008_rsakey.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0008_rsakey.py
@@ -8,15 +8,23 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0007_auto_20160111_1844'),
+ ("oidc_provider", "0007_auto_20160111_1844"),
]
operations = [
migrations.CreateModel(
- name='RSAKey',
+ name="RSAKey",
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('key', models.TextField()),
+ (
+ "id",
+ models.AutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ ("key", models.TextField()),
],
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0009_auto_20160202_1945.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0009_auto_20160202_1945.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0009_auto_20160202_1945.py
@@ -8,17 +8,17 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0008_rsakey'),
+ ("oidc_provider", "0008_rsakey"),
]
operations = [
migrations.AlterModelOptions(
- name='rsakey',
- options={'verbose_name': 'RSA Key', 'verbose_name_plural': 'RSA Keys'},
+ name="rsakey",
+ options={"verbose_name": "RSA Key", "verbose_name_plural": "RSA Keys"},
),
migrations.AlterField(
- model_name='rsakey',
- name='key',
- field=models.TextField(help_text='Paste your private RSA Key here.'),
+ model_name="rsakey",
+ name="key",
+ field=models.TextField(help_text="Paste your private RSA Key here."),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0010_code_is_authentication.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0010_code_is_authentication.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0010_code_is_authentication.py
@@ -8,13 +8,13 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0009_auto_20160202_1945'),
+ ("oidc_provider", "0009_auto_20160202_1945"),
]
operations = [
migrations.AddField(
- model_name='code',
- name='is_authentication',
+ model_name="code",
+ name="is_authentication",
field=models.BooleanField(default=False),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0011_client_client_type.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0011_client_client_type.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0011_client_client_type.py
@@ -8,18 +8,19 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0010_code_is_authentication'),
+ ("oidc_provider", "0010_code_is_authentication"),
]
operations = [
migrations.AddField(
- model_name='client',
- name='client_type',
+ model_name="client",
+ name="client_type",
field=models.CharField(
- choices=[(b'confidential', b'Confidential'), (b'public', b'Public')],
- default=b'confidential',
- help_text='<b>Confidential</b> clients are capable of maintaining the confidentiality of their '
- 'credentials. <b>Public</b> clients are incapable.',
- max_length=30),
+ choices=[(b"confidential", b"Confidential"), (b"public", b"Public")],
+ default=b"confidential",
+ help_text="<b>Confidential</b> clients are capable of maintaining the confidentiality of their "
+ "credentials. <b>Public</b> clients are incapable.",
+ max_length=30,
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0012_auto_20160405_2041.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0012_auto_20160405_2041.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0012_auto_20160405_2041.py
@@ -8,13 +8,13 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0011_client_client_type'),
+ ("oidc_provider", "0011_client_client_type"),
]
operations = [
migrations.AlterField(
- model_name='client',
- name='client_secret',
- field=models.CharField(blank=True, default=b'', max_length=255),
+ model_name="client",
+ name="client_secret",
+ field=models.CharField(blank=True, default=b"", max_length=255),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0013_auto_20160407_1912.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0013_auto_20160407_1912.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0013_auto_20160407_1912.py
@@ -8,18 +8,18 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0012_auto_20160405_2041'),
+ ("oidc_provider", "0012_auto_20160405_2041"),
]
operations = [
migrations.AddField(
- model_name='code',
- name='code_challenge',
+ model_name="code",
+ name="code_challenge",
field=models.CharField(max_length=255, null=True),
),
migrations.AddField(
- model_name='code',
- name='code_challenge_method',
+ model_name="code",
+ name="code_challenge_method",
field=models.CharField(max_length=255, null=True),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0014_client_jwt_alg.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0014_client_jwt_alg.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0014_client_jwt_alg.py
@@ -8,17 +8,18 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0013_auto_20160407_1912'),
+ ("oidc_provider", "0013_auto_20160407_1912"),
]
operations = [
migrations.AddField(
- model_name='client',
- name='jwt_alg',
+ model_name="client",
+ name="jwt_alg",
field=models.CharField(
- choices=[(b'HS256', b'HS256'), (b'RS256', b'RS256')],
- default=b'RS256',
+ choices=[(b"HS256", b"HS256"), (b"RS256", b"RS256")],
+ default=b"RS256",
max_length=10,
- verbose_name='JWT Algorithm'),
+ verbose_name="JWT Algorithm",
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0015_change_client_code.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0015_change_client_code.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0015_change_client_code.py
@@ -8,71 +8,80 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0014_client_jwt_alg'),
+ ("oidc_provider", "0014_client_jwt_alg"),
]
operations = [
migrations.AlterField(
- model_name='client',
- name='_redirect_uris',
- field=models.TextField(default='', help_text='Enter each URI on a new line.', verbose_name='Redirect URI'),
+ model_name="client",
+ name="_redirect_uris",
+ field=models.TextField(
+ default="",
+ help_text="Enter each URI on a new line.",
+ verbose_name="Redirect URI",
+ ),
+ ),
+ migrations.AlterField(
+ model_name="client",
+ name="client_secret",
+ field=models.CharField(blank=True, default="", max_length=255),
),
migrations.AlterField(
- model_name='client',
- name='client_secret',
- field=models.CharField(blank=True, default='', max_length=255),
- ),
- migrations.AlterField(
- model_name='client',
- name='client_type',
+ model_name="client",
+ name="client_type",
field=models.CharField(
- choices=[('confidential', 'Confidential'), ('public', 'Public')],
- default='confidential',
- help_text='<b>Confidential</b> clients are capable of maintaining the confidentiality of their'
- ' credentials. <b>Public</b> clients are incapable.',
- max_length=30),
+ choices=[("confidential", "Confidential"), ("public", "Public")],
+ default="confidential",
+ help_text="<b>Confidential</b> clients are capable of maintaining the confidentiality of their"
+ " credentials. <b>Public</b> clients are incapable.",
+ max_length=30,
+ ),
),
migrations.AlterField(
- model_name='client',
- name='jwt_alg',
+ model_name="client",
+ name="jwt_alg",
field=models.CharField(
- choices=[('HS256', 'HS256'), ('RS256', 'RS256')],
- default='RS256',
+ choices=[("HS256", "HS256"), ("RS256", "RS256")],
+ default="RS256",
max_length=10,
- verbose_name='JWT Algorithm'),
+ verbose_name="JWT Algorithm",
+ ),
),
migrations.AlterField(
- model_name='client',
- name='name',
- field=models.CharField(default='', max_length=100),
+ model_name="client",
+ name="name",
+ field=models.CharField(default="", max_length=100),
),
migrations.AlterField(
- model_name='client',
- name='response_type',
+ model_name="client",
+ name="response_type",
field=models.CharField(
choices=[
- ('code', 'code (Authorization Code Flow)'), ('id_token', 'id_token (Implicit Flow)'),
- ('id_token token', 'id_token token (Implicit Flow)')],
- max_length=30),
+ ("code", "code (Authorization Code Flow)"),
+ ("id_token", "id_token (Implicit Flow)"),
+ ("id_token token", "id_token token (Implicit Flow)"),
+ ],
+ max_length=30,
+ ),
),
migrations.AlterField(
- model_name='code',
- name='_scope',
- field=models.TextField(default=''),
+ model_name="code",
+ name="_scope",
+ field=models.TextField(default=""),
),
migrations.AlterField(
- model_name='code',
- name='nonce',
- field=models.CharField(blank=True, default='', max_length=255),
+ model_name="code",
+ name="nonce",
+ field=models.CharField(blank=True, default="", max_length=255),
),
migrations.AlterField(
- model_name='token',
- name='_scope',
- field=models.TextField(default=''),
+ model_name="token",
+ name="_scope",
+ field=models.TextField(default=""),
),
migrations.AlterField(
- model_name='userconsent',
- name='_scope',
- field=models.TextField(default=''),
+ model_name="userconsent",
+ name="_scope",
+ field=models.TextField(default=""),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0016_userconsent_and_verbosenames.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0016_userconsent_and_verbosenames.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0016_userconsent_and_verbosenames.py
@@ -3,182 +3,226 @@
from __future__ import unicode_literals
import datetime
+
+import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
-import django.db.models.deletion
from django.utils.timezone import utc
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0015_change_client_code'),
+ ("oidc_provider", "0015_change_client_code"),
]
operations = [
migrations.AddField(
- model_name='userconsent',
- name='date_given',
+ model_name="userconsent",
+ name="date_given",
field=models.DateTimeField(
- default=datetime.datetime(2016, 6, 10, 17, 53, 48, 889808, tzinfo=utc), verbose_name='Date Given'),
+ default=datetime.datetime(2016, 6, 10, 17, 53, 48, 889808, tzinfo=utc),
+ verbose_name="Date Given",
+ ),
preserve_default=False,
),
migrations.AlterField(
- model_name='client',
- name='_redirect_uris',
+ model_name="client",
+ name="_redirect_uris",
field=models.TextField(
- default=b'', help_text='Enter each URI on a new line.', verbose_name='Redirect URIs'),
+ default=b"",
+ help_text="Enter each URI on a new line.",
+ verbose_name="Redirect URIs",
+ ),
),
migrations.AlterField(
- model_name='client',
- name='client_id',
- field=models.CharField(max_length=255, unique=True, verbose_name='Client ID'),
+ model_name="client",
+ name="client_id",
+ field=models.CharField(
+ max_length=255, unique=True, verbose_name="Client ID"
+ ),
),
migrations.AlterField(
- model_name='client',
- name='client_secret',
- field=models.CharField(blank=True, default=b'', max_length=255, verbose_name='Client SECRET'),
+ model_name="client",
+ name="client_secret",
+ field=models.CharField(
+ blank=True, default=b"", max_length=255, verbose_name="Client SECRET"
+ ),
),
migrations.AlterField(
- model_name='client',
- name='client_type',
+ model_name="client",
+ name="client_type",
field=models.CharField(
- choices=[(b'confidential', b'Confidential'), (b'public', b'Public')],
- default=b'confidential',
- help_text='<b>Confidential</b> clients are capable of maintaining the confidentiality of their '
- 'credentials. <b>Public</b> clients are incapable.',
+ choices=[(b"confidential", b"Confidential"), (b"public", b"Public")],
+ default=b"confidential",
+ help_text="<b>Confidential</b> clients are capable of maintaining the confidentiality of their "
+ "credentials. <b>Public</b> clients are incapable.",
max_length=30,
- verbose_name='Client Type'),
+ verbose_name="Client Type",
+ ),
),
migrations.AlterField(
- model_name='client',
- name='date_created',
- field=models.DateField(auto_now_add=True, verbose_name='Date Created'),
+ model_name="client",
+ name="date_created",
+ field=models.DateField(auto_now_add=True, verbose_name="Date Created"),
),
migrations.AlterField(
- model_name='client',
- name='name',
- field=models.CharField(default=b'', max_length=100, verbose_name='Name'),
+ model_name="client",
+ name="name",
+ field=models.CharField(default=b"", max_length=100, verbose_name="Name"),
),
migrations.AlterField(
- model_name='client',
- name='response_type',
+ model_name="client",
+ name="response_type",
field=models.CharField(
choices=[
- (b'code', b'code (Authorization Code Flow)'), (b'id_token', b'id_token (Implicit Flow)'),
- (b'id_token token', b'id_token token (Implicit Flow)')],
+ (b"code", b"code (Authorization Code Flow)"),
+ (b"id_token", b"id_token (Implicit Flow)"),
+ (b"id_token token", b"id_token token (Implicit Flow)"),
+ ],
max_length=30,
- verbose_name='Response Type'),
+ verbose_name="Response Type",
+ ),
),
migrations.AlterField(
- model_name='code',
- name='_scope',
- field=models.TextField(default=b'', verbose_name='Scopes'),
+ model_name="code",
+ name="_scope",
+ field=models.TextField(default=b"", verbose_name="Scopes"),
),
migrations.AlterField(
- model_name='code',
- name='client',
+ model_name="code",
+ name="client",
field=models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE, to='oidc_provider.Client', verbose_name='Client'),
+ on_delete=django.db.models.deletion.CASCADE,
+ to="oidc_provider.Client",
+ verbose_name="Client",
+ ),
),
migrations.AlterField(
- model_name='code',
- name='code',
- field=models.CharField(max_length=255, unique=True, verbose_name='Code'),
+ model_name="code",
+ name="code",
+ field=models.CharField(max_length=255, unique=True, verbose_name="Code"),
),
migrations.AlterField(
- model_name='code',
- name='code_challenge',
- field=models.CharField(max_length=255, null=True, verbose_name='Code Challenge'),
+ model_name="code",
+ name="code_challenge",
+ field=models.CharField(
+ max_length=255, null=True, verbose_name="Code Challenge"
+ ),
),
migrations.AlterField(
- model_name='code',
- name='code_challenge_method',
- field=models.CharField(max_length=255, null=True, verbose_name='Code Challenge Method'),
+ model_name="code",
+ name="code_challenge_method",
+ field=models.CharField(
+ max_length=255, null=True, verbose_name="Code Challenge Method"
+ ),
),
migrations.AlterField(
- model_name='code',
- name='expires_at',
- field=models.DateTimeField(verbose_name='Expiration Date'),
+ model_name="code",
+ name="expires_at",
+ field=models.DateTimeField(verbose_name="Expiration Date"),
),
migrations.AlterField(
- model_name='code',
- name='is_authentication',
- field=models.BooleanField(default=False, verbose_name='Is Authentication?'),
+ model_name="code",
+ name="is_authentication",
+ field=models.BooleanField(default=False, verbose_name="Is Authentication?"),
),
migrations.AlterField(
- model_name='code',
- name='nonce',
- field=models.CharField(blank=True, default=b'', max_length=255, verbose_name='Nonce'),
+ model_name="code",
+ name="nonce",
+ field=models.CharField(
+ blank=True, default=b"", max_length=255, verbose_name="Nonce"
+ ),
),
migrations.AlterField(
- model_name='code',
- name='user',
+ model_name="code",
+ name="user",
field=models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User'),
+ on_delete=django.db.models.deletion.CASCADE,
+ to=settings.AUTH_USER_MODEL,
+ verbose_name="User",
+ ),
),
migrations.AlterField(
- model_name='rsakey',
- name='key',
- field=models.TextField(help_text='Paste your private RSA Key here.', verbose_name='Key'),
+ model_name="rsakey",
+ name="key",
+ field=models.TextField(
+ help_text="Paste your private RSA Key here.", verbose_name="Key"
+ ),
),
migrations.AlterField(
- model_name='token',
- name='_id_token',
- field=models.TextField(verbose_name='ID Token'),
+ model_name="token",
+ name="_id_token",
+ field=models.TextField(verbose_name="ID Token"),
),
migrations.AlterField(
- model_name='token',
- name='_scope',
- field=models.TextField(default=b'', verbose_name='Scopes'),
+ model_name="token",
+ name="_scope",
+ field=models.TextField(default=b"", verbose_name="Scopes"),
),
migrations.AlterField(
- model_name='token',
- name='access_token',
- field=models.CharField(max_length=255, unique=True, verbose_name='Access Token'),
+ model_name="token",
+ name="access_token",
+ field=models.CharField(
+ max_length=255, unique=True, verbose_name="Access Token"
+ ),
),
migrations.AlterField(
- model_name='token',
- name='client',
+ model_name="token",
+ name="client",
field=models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE, to='oidc_provider.Client', verbose_name='Client'),
+ on_delete=django.db.models.deletion.CASCADE,
+ to="oidc_provider.Client",
+ verbose_name="Client",
+ ),
),
migrations.AlterField(
- model_name='token',
- name='expires_at',
- field=models.DateTimeField(verbose_name='Expiration Date'),
+ model_name="token",
+ name="expires_at",
+ field=models.DateTimeField(verbose_name="Expiration Date"),
),
migrations.AlterField(
- model_name='token',
- name='refresh_token',
- field=models.CharField(max_length=255, null=True, unique=True, verbose_name='Refresh Token'),
+ model_name="token",
+ name="refresh_token",
+ field=models.CharField(
+ max_length=255, null=True, unique=True, verbose_name="Refresh Token"
+ ),
),
migrations.AlterField(
- model_name='token',
- name='user',
+ model_name="token",
+ name="user",
field=models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User'),
+ on_delete=django.db.models.deletion.CASCADE,
+ to=settings.AUTH_USER_MODEL,
+ verbose_name="User",
+ ),
),
migrations.AlterField(
- model_name='userconsent',
- name='_scope',
- field=models.TextField(default=b'', verbose_name='Scopes'),
+ model_name="userconsent",
+ name="_scope",
+ field=models.TextField(default=b"", verbose_name="Scopes"),
),
migrations.AlterField(
- model_name='userconsent',
- name='client',
+ model_name="userconsent",
+ name="client",
field=models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE, to='oidc_provider.Client', verbose_name='Client'),
+ on_delete=django.db.models.deletion.CASCADE,
+ to="oidc_provider.Client",
+ verbose_name="Client",
+ ),
),
migrations.AlterField(
- model_name='userconsent',
- name='expires_at',
- field=models.DateTimeField(verbose_name='Expiration Date'),
+ model_name="userconsent",
+ name="expires_at",
+ field=models.DateTimeField(verbose_name="Expiration Date"),
),
migrations.AlterField(
- model_name='userconsent',
- name='user',
+ model_name="userconsent",
+ name="user",
field=models.ForeignKey(
- on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User'),
+ on_delete=django.db.models.deletion.CASCADE,
+ to=settings.AUTH_USER_MODEL,
+ verbose_name="User",
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0017_auto_20160811_1954.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0017_auto_20160811_1954.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0017_auto_20160811_1954.py
@@ -8,64 +8,76 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0016_userconsent_and_verbosenames'),
+ ("oidc_provider", "0016_userconsent_and_verbosenames"),
]
operations = [
migrations.AlterField(
- model_name='client',
- name='_redirect_uris',
- field=models.TextField(default='', help_text='Enter each URI on a new line.', verbose_name='Redirect URIs'),
+ model_name="client",
+ name="_redirect_uris",
+ field=models.TextField(
+ default="",
+ help_text="Enter each URI on a new line.",
+ verbose_name="Redirect URIs",
+ ),
),
migrations.AlterField(
- model_name='client',
- name='client_secret',
- field=models.CharField(blank=True, default='', max_length=255, verbose_name='Client SECRET'),
+ model_name="client",
+ name="client_secret",
+ field=models.CharField(
+ blank=True, default="", max_length=255, verbose_name="Client SECRET"
+ ),
),
migrations.AlterField(
- model_name='client',
- name='client_type',
+ model_name="client",
+ name="client_type",
field=models.CharField(
- choices=[('confidential', 'Confidential'), ('public', 'Public')],
- default='confidential',
- help_text='<b>Confidential</b> clients are capable of maintaining the confidentiality of their '
- 'credentials. <b>Public</b> clients are incapable.',
+ choices=[("confidential", "Confidential"), ("public", "Public")],
+ default="confidential",
+ help_text="<b>Confidential</b> clients are capable of maintaining the confidentiality of their "
+ "credentials. <b>Public</b> clients are incapable.",
max_length=30,
- verbose_name='Client Type'),
+ verbose_name="Client Type",
+ ),
),
migrations.AlterField(
- model_name='client',
- name='name',
- field=models.CharField(default='', max_length=100, verbose_name='Name'),
+ model_name="client",
+ name="name",
+ field=models.CharField(default="", max_length=100, verbose_name="Name"),
),
migrations.AlterField(
- model_name='client',
- name='response_type',
+ model_name="client",
+ name="response_type",
field=models.CharField(
choices=[
- ('code', 'code (Authorization Code Flow)'), ('id_token', 'id_token (Implicit Flow)'),
- ('id_token token', 'id_token token (Implicit Flow)')],
+ ("code", "code (Authorization Code Flow)"),
+ ("id_token", "id_token (Implicit Flow)"),
+ ("id_token token", "id_token token (Implicit Flow)"),
+ ],
max_length=30,
- verbose_name='Response Type'),
+ verbose_name="Response Type",
+ ),
),
migrations.AlterField(
- model_name='code',
- name='_scope',
- field=models.TextField(default='', verbose_name='Scopes'),
+ model_name="code",
+ name="_scope",
+ field=models.TextField(default="", verbose_name="Scopes"),
),
migrations.AlterField(
- model_name='code',
- name='nonce',
- field=models.CharField(blank=True, default='', max_length=255, verbose_name='Nonce'),
+ model_name="code",
+ name="nonce",
+ field=models.CharField(
+ blank=True, default="", max_length=255, verbose_name="Nonce"
+ ),
),
migrations.AlterField(
- model_name='token',
- name='_scope',
- field=models.TextField(default='', verbose_name='Scopes'),
+ model_name="token",
+ name="_scope",
+ field=models.TextField(default="", verbose_name="Scopes"),
),
migrations.AlterField(
- model_name='userconsent',
- name='_scope',
- field=models.TextField(default='', verbose_name='Scopes'),
+ model_name="userconsent",
+ name="_scope",
+ field=models.TextField(default="", verbose_name="Scopes"),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0018_hybridflow_and_clientattrs.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0018_hybridflow_and_clientattrs.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0018_hybridflow_and_clientattrs.py
@@ -8,56 +8,70 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0017_auto_20160811_1954'),
+ ("oidc_provider", "0017_auto_20160811_1954"),
]
operations = [
migrations.AddField(
- model_name='client',
- name='contact_email',
- field=models.CharField(blank=True, default='', max_length=255, verbose_name='Contact Email'),
+ model_name="client",
+ name="contact_email",
+ field=models.CharField(
+ blank=True, default="", max_length=255, verbose_name="Contact Email"
+ ),
),
migrations.AddField(
- model_name='client',
- name='logo',
+ model_name="client",
+ name="logo",
field=models.FileField(
- blank=True, default='', upload_to='oidc_provider/clients', verbose_name='Logo Image'),
+ blank=True,
+ default="",
+ upload_to="oidc_provider/clients",
+ verbose_name="Logo Image",
+ ),
),
migrations.AddField(
- model_name='client',
- name='terms_url',
+ model_name="client",
+ name="terms_url",
field=models.CharField(
blank=True,
- default='',
- help_text='External reference to the privacy policy of the client.',
+ default="",
+ help_text="External reference to the privacy policy of the client.",
max_length=255,
- verbose_name='Terms URL'),
+ verbose_name="Terms URL",
+ ),
),
migrations.AddField(
- model_name='client',
- name='website_url',
- field=models.CharField(blank=True, default='', max_length=255, verbose_name='Website URL'),
+ model_name="client",
+ name="website_url",
+ field=models.CharField(
+ blank=True, default="", max_length=255, verbose_name="Website URL"
+ ),
),
migrations.AlterField(
- model_name='client',
- name='jwt_alg',
+ model_name="client",
+ name="jwt_alg",
field=models.CharField(
- choices=[('HS256', 'HS256'), ('RS256', 'RS256')],
- default='RS256',
- help_text='Algorithm used to encode ID Tokens.',
+ choices=[("HS256", "HS256"), ("RS256", "RS256")],
+ default="RS256",
+ help_text="Algorithm used to encode ID Tokens.",
max_length=10,
- verbose_name='JWT Algorithm'),
+ verbose_name="JWT Algorithm",
+ ),
),
migrations.AlterField(
- model_name='client',
- name='response_type',
+ model_name="client",
+ name="response_type",
field=models.CharField(
choices=[
- ('code', 'code (Authorization Code Flow)'), ('id_token', 'id_token (Implicit Flow)'),
- ('id_token token', 'id_token token (Implicit Flow)'), ('code token', 'code token (Hybrid Flow)'),
- ('code id_token', 'code id_token (Hybrid Flow)'),
- ('code id_token token', 'code id_token token (Hybrid Flow)')],
+ ("code", "code (Authorization Code Flow)"),
+ ("id_token", "id_token (Implicit Flow)"),
+ ("id_token token", "id_token token (Implicit Flow)"),
+ ("code token", "code token (Hybrid Flow)"),
+ ("code id_token", "code id_token (Hybrid Flow)"),
+ ("code id_token token", "code id_token token (Hybrid Flow)"),
+ ],
max_length=30,
- verbose_name='Response Type'),
+ verbose_name="Response Type",
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0019_auto_20161005_1552.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0019_auto_20161005_1552.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0019_auto_20161005_1552.py
@@ -8,13 +8,15 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0018_hybridflow_and_clientattrs'),
+ ("oidc_provider", "0018_hybridflow_and_clientattrs"),
]
operations = [
migrations.AlterField(
- model_name='client',
- name='client_secret',
- field=models.CharField(blank=True, max_length=255, verbose_name='Client SECRET'),
+ model_name="client",
+ name="client_secret",
+ field=models.CharField(
+ blank=True, max_length=255, verbose_name="Client SECRET"
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0020_client__post_logout_redirect_uris.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0020_client__post_logout_redirect_uris.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0020_client__post_logout_redirect_uris.py
@@ -8,17 +8,18 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0019_auto_20161005_1552'),
+ ("oidc_provider", "0019_auto_20161005_1552"),
]
operations = [
migrations.AddField(
- model_name='client',
- name='_post_logout_redirect_uris',
+ model_name="client",
+ name="_post_logout_redirect_uris",
field=models.TextField(
blank=True,
- default='',
- help_text='Enter each URI on a new line.',
- verbose_name='Post Logout Redirect URIs'),
+ default="",
+ help_text="Enter each URI on a new line.",
+ verbose_name="Post Logout Redirect URIs",
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0021_refresh_token_not_unique.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0021_refresh_token_not_unique.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0021_refresh_token_not_unique.py
@@ -8,14 +8,16 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0020_client__post_logout_redirect_uris'),
+ ("oidc_provider", "0020_client__post_logout_redirect_uris"),
]
operations = [
migrations.AlterField(
- model_name='token',
- name='refresh_token',
- field=models.CharField(default='', max_length=255, unique=True, verbose_name='Refresh Token'),
+ model_name="token",
+ name="refresh_token",
+ field=models.CharField(
+ default="", max_length=255, unique=True, verbose_name="Refresh Token"
+ ),
preserve_default=False,
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0022_auto_20170331_1626.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0022_auto_20170331_1626.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0022_auto_20170331_1626.py
@@ -8,25 +8,27 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0021_refresh_token_not_unique'),
+ ("oidc_provider", "0021_refresh_token_not_unique"),
]
operations = [
migrations.AddField(
- model_name='client',
- name='require_consent',
+ model_name="client",
+ name="require_consent",
field=models.BooleanField(
default=True,
- help_text='If disabled, the Server will NEVER ask the user for consent.',
- verbose_name='Require Consent?'),
+ help_text="If disabled, the Server will NEVER ask the user for consent.",
+ verbose_name="Require Consent?",
+ ),
),
migrations.AddField(
- model_name='client',
- name='reuse_consent',
+ model_name="client",
+ name="reuse_consent",
field=models.BooleanField(
default=True,
help_text="If enabled, the Server will save the user consent given to a specific client,"
- " so that user won't be prompted for the same authorization multiple times.",
- verbose_name='Reuse Consent?'),
+ " so that user won't be prompted for the same authorization multiple times.",
+ verbose_name="Reuse Consent?",
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0023_client_owner.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0023_client_owner.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0023_client_owner.py
@@ -2,22 +2,30 @@
# Generated by Django 1.11 on 2017-11-08 21:43
from __future__ import unicode_literals
+import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
-import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ('oidc_provider', '0022_auto_20170331_1626'),
+ ("oidc_provider", "0022_auto_20170331_1626"),
]
operations = [
migrations.AddField(
- model_name='client',
- name='owner',
- field=models.ForeignKey(blank=True, default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='oidc_clients_set', to=settings.AUTH_USER_MODEL, verbose_name='Owner'),
+ model_name="client",
+ name="owner",
+ field=models.ForeignKey(
+ blank=True,
+ default=None,
+ null=True,
+ on_delete=django.db.models.deletion.SET_NULL,
+ related_name="oidc_clients_set",
+ to=settings.AUTH_USER_MODEL,
+ verbose_name="Owner",
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0024_auto_20180327_1959.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0024_auto_20180327_1959.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0024_auto_20180327_1959.py
@@ -6,13 +6,17 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0023_client_owner'),
+ ("oidc_provider", "0023_client_owner"),
]
operations = [
migrations.AlterField(
- model_name='client',
- name='reuse_consent',
- field=models.BooleanField(default=True, help_text="If enabled, server will save the user consent given to a specific client, so that user won't be prompted for the same authorization multiple times.", verbose_name='Reuse Consent?'),
+ model_name="client",
+ name="reuse_consent",
+ field=models.BooleanField(
+ default=True,
+ help_text="If enabled, server will save the user consent given to a specific client, so that user won't be prompted for the same authorization multiple times.",
+ verbose_name="Reuse Consent?",
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0025_user_field_codetoken.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0025_user_field_codetoken.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0025_user_field_codetoken.py
@@ -1,25 +1,35 @@
# Generated by Django 2.0.3 on 2018-04-13 19:34
+import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
-import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0024_auto_20180327_1959'),
+ ("oidc_provider", "0024_auto_20180327_1959"),
]
operations = [
migrations.AddField(
- model_name='client',
- name='_scope',
- field=models.TextField(blank=True, default='', help_text='Specifies the authorized scope values for the client app.', verbose_name='Scopes'),
+ model_name="client",
+ name="_scope",
+ field=models.TextField(
+ blank=True,
+ default="",
+ help_text="Specifies the authorized scope values for the client app.",
+ verbose_name="Scopes",
+ ),
),
migrations.AlterField(
- model_name='token',
- name='user',
- field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='User'),
+ model_name="token",
+ name="user",
+ field=models.ForeignKey(
+ null=True,
+ on_delete=django.db.models.deletion.CASCADE,
+ to=settings.AUTH_USER_MODEL,
+ verbose_name="User",
+ ),
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0026_client_multiple_response_types.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/migrations/0026_client_multiple_response_types.py
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0026_client_multiple_response_types.py
@@ -5,17 +5,17 @@ from django.db import migrations, models
def migrate_response_type(apps, schema_editor):
RESPONSE_TYPES = [
- ('code', 'code (Authorization Code Flow)'),
- ('id_token', 'id_token (Implicit Flow)'),
- ('id_token token', 'id_token token (Implicit Flow)'),
- ('code token', 'code token (Hybrid Flow)'),
- ('code id_token', 'code id_token (Hybrid Flow)'),
- ('code id_token token', 'code id_token token (Hybrid Flow)'),
+ ("code", "code (Authorization Code Flow)"),
+ ("id_token", "id_token (Implicit Flow)"),
+ ("id_token token", "id_token token (Implicit Flow)"),
+ ("code token", "code token (Hybrid Flow)"),
+ ("code id_token", "code id_token (Hybrid Flow)"),
+ ("code id_token token", "code id_token token (Hybrid Flow)"),
]
# ensure we get proper, versioned model with the deleted response_type field;
# importing directly yields the latest without response_type
- ResponseType = apps.get_model('oidc_provider', 'ResponseType')
- Client = apps.get_model('oidc_provider', 'Client')
+ ResponseType = apps.get_model("oidc_provider", "ResponseType")
+ Client = apps.get_model("oidc_provider", "Client")
for value, description in RESPONSE_TYPES:
ResponseType.objects.create(value=value, description=description)
for client in Client.objects.all():
@@ -25,27 +25,53 @@ def migrate_response_type(apps, schema_e
class Migration(migrations.Migration):
dependencies = [
- ('oidc_provider', '0025_user_field_codetoken'),
+ ("oidc_provider", "0025_user_field_codetoken"),
]
operations = [
migrations.CreateModel(
- name='ResponseType',
+ name="ResponseType",
fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('value', models.CharField(choices=[('code', 'code (Authorization Code Flow)'), ('id_token', 'id_token (Implicit Flow)'), ('id_token token', 'id_token token (Implicit Flow)'), ('code token', 'code token (Hybrid Flow)'), ('code id_token', 'code id_token (Hybrid Flow)'), ('code id_token token', 'code id_token token (Hybrid Flow)')], max_length=30, unique=True, verbose_name='Response Type Value')),
- ('description', models.CharField(max_length=50)),
+ (
+ "id",
+ models.AutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ (
+ "value",
+ models.CharField(
+ choices=[
+ ("code", "code (Authorization Code Flow)"),
+ ("id_token", "id_token (Implicit Flow)"),
+ ("id_token token", "id_token token (Implicit Flow)"),
+ ("code token", "code token (Hybrid Flow)"),
+ ("code id_token", "code id_token (Hybrid Flow)"),
+ (
+ "code id_token token",
+ "code id_token token (Hybrid Flow)",
+ ),
+ ],
+ max_length=30,
+ unique=True,
+ verbose_name="Response Type Value",
+ ),
+ ),
+ ("description", models.CharField(max_length=50)),
],
),
migrations.AddField(
- model_name='client',
- name='response_types',
- field=models.ManyToManyField(to='oidc_provider.ResponseType'),
+ model_name="client",
+ name="response_types",
+ field=models.ManyToManyField(to="oidc_provider.ResponseType"),
),
# omitting reverse migrate_response_type since removing response_type is irreversible (nonnull and no default)
migrations.RunPython(migrate_response_type),
migrations.RemoveField(
- model_name='client',
- name='response_type',
+ model_name="client",
+ name="response_type",
),
]
Index: django-oidc-provider-0.7.0/oidc_provider/migrations/0027_alter_client_id_alter_code_id_alter_responsetype_id_and_more.py
===================================================================
--- /dev/null
+++ django-oidc-provider-0.7.0/oidc_provider/migrations/0027_alter_client_id_alter_code_id_alter_responsetype_id_and_more.py
@@ -0,0 +1,43 @@
+# Generated by Django 4.0.2 on 2022-02-03 14:13
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('oidc_provider', '0026_client_multiple_response_types'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='client',
+ name='id',
+ field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
+ ),
+ migrations.AlterField(
+ model_name='code',
+ name='id',
+ field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
+ ),
+ migrations.AlterField(
+ model_name='responsetype',
+ name='id',
+ field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
+ ),
+ migrations.AlterField(
+ model_name='rsakey',
+ name='id',
+ field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
+ ),
+ migrations.AlterField(
+ model_name='token',
+ name='id',
+ field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
+ ),
+ migrations.AlterField(
+ model_name='userconsent',
+ name='id',
+ field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
+ ),
+ ]
Index: django-oidc-provider-0.7.0/oidc_provider/models.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/models.py
+++ django-oidc-provider-0.7.0/oidc_provider/models.py
@@ -1,32 +1,31 @@
# -*- coding: utf-8 -*-
import base64
import binascii
-from hashlib import md5, sha256
import json
+from hashlib import md5, sha256
+from django.conf import settings
from django.db import models
from django.utils import timezone
-from django.utils.translation import ugettext_lazy as _
-from django.conf import settings
-
+from django.utils.translation import gettext_lazy as _
CLIENT_TYPE_CHOICES = [
- ('confidential', 'Confidential'),
- ('public', 'Public'),
+ ("confidential", "Confidential"),
+ ("public", "Public"),
]
RESPONSE_TYPE_CHOICES = [
- ('code', 'code (Authorization Code Flow)'),
- ('id_token', 'id_token (Implicit Flow)'),
- ('id_token token', 'id_token token (Implicit Flow)'),
- ('code token', 'code token (Hybrid Flow)'),
- ('code id_token', 'code id_token (Hybrid Flow)'),
- ('code id_token token', 'code id_token token (Hybrid Flow)'),
+ ("code", "code (Authorization Code Flow)"),
+ ("id_token", "id_token (Implicit Flow)"),
+ ("id_token token", "id_token token (Implicit Flow)"),
+ ("code token", "code token (Hybrid Flow)"),
+ ("code id_token", "code id_token (Hybrid Flow)"),
+ ("code id_token token", "code id_token token (Hybrid Flow)"),
]
JWT_ALGS = [
- ('HS256', 'HS256'),
- ('RS256', 'RS256'),
+ ("HS256", "HS256"),
+ ("RS256", "RS256"),
]
@@ -42,82 +41,112 @@ class ResponseType(models.Model):
max_length=30,
choices=RESPONSE_TYPE_CHOICES,
unique=True,
- verbose_name=_(u'Response Type Value'))
+ verbose_name=_("Response Type Value"),
+ )
description = models.CharField(
max_length=50,
)
def natural_key(self):
- return self.value, # natural_key must return tuple
+ return (self.value,) # natural_key must return tuple
def __str__(self):
- return u'{0}'.format(self.description)
+ return "{0}".format(self.description)
class Client(models.Model):
- name = models.CharField(max_length=100, default='', verbose_name=_(u'Name'))
+ name = models.CharField(max_length=100, default="", verbose_name=_("Name"))
owner = models.ForeignKey(
- settings.AUTH_USER_MODEL, verbose_name=_(u'Owner'), blank=True,
- null=True, default=None, on_delete=models.SET_NULL, related_name='oidc_clients_set')
+ settings.AUTH_USER_MODEL,
+ verbose_name=_("Owner"),
+ blank=True,
+ null=True,
+ default=None,
+ on_delete=models.SET_NULL,
+ related_name="oidc_clients_set",
+ )
client_type = models.CharField(
max_length=30,
choices=CLIENT_TYPE_CHOICES,
- default='confidential',
- verbose_name=_(u'Client Type'),
- help_text=_(u'<b>Confidential</b> clients are capable of maintaining the confidentiality'
- u' of their credentials. <b>Public</b> clients are incapable.'))
- client_id = models.CharField(max_length=255, unique=True, verbose_name=_(u'Client ID'))
- client_secret = models.CharField(max_length=255, blank=True, verbose_name=_(u'Client SECRET'))
+ default="confidential",
+ verbose_name=_("Client Type"),
+ help_text=_(
+ "<b>Confidential</b> clients are capable of maintaining the confidentiality"
+ " of their credentials. <b>Public</b> clients are incapable."
+ ),
+ )
+ client_id = models.CharField(
+ max_length=255, unique=True, verbose_name=_("Client ID")
+ )
+ client_secret = models.CharField(
+ max_length=255, blank=True, verbose_name=_("Client SECRET")
+ )
response_types = models.ManyToManyField(ResponseType)
jwt_alg = models.CharField(
max_length=10,
choices=JWT_ALGS,
- default='RS256',
- verbose_name=_(u'JWT Algorithm'),
- help_text=_(u'Algorithm used to encode ID Tokens.'))
- date_created = models.DateField(auto_now_add=True, verbose_name=_(u'Date Created'))
+ default="RS256",
+ verbose_name=_("JWT Algorithm"),
+ help_text=_("Algorithm used to encode ID Tokens."),
+ )
+ date_created = models.DateField(auto_now_add=True, verbose_name=_("Date Created"))
website_url = models.CharField(
- max_length=255, blank=True, default='', verbose_name=_(u'Website URL'))
+ max_length=255, blank=True, default="", verbose_name=_("Website URL")
+ )
terms_url = models.CharField(
max_length=255,
blank=True,
- default='',
- verbose_name=_(u'Terms URL'),
- help_text=_(u'External reference to the privacy policy of the client.'))
+ default="",
+ verbose_name=_("Terms URL"),
+ help_text=_("External reference to the privacy policy of the client."),
+ )
contact_email = models.CharField(
- max_length=255, blank=True, default='', verbose_name=_(u'Contact Email'))
+ max_length=255, blank=True, default="", verbose_name=_("Contact Email")
+ )
logo = models.FileField(
- blank=True, default='', upload_to='oidc_provider/clients', verbose_name=_(u'Logo Image'))
+ blank=True,
+ default="",
+ upload_to="oidc_provider/clients",
+ verbose_name=_("Logo Image"),
+ )
reuse_consent = models.BooleanField(
default=True,
- verbose_name=_('Reuse Consent?'),
- help_text=_('If enabled, server will save the user consent given to a specific client, '
- 'so that user won\'t be prompted for the same authorization multiple times.'))
+ verbose_name=_("Reuse Consent?"),
+ help_text=_(
+ "If enabled, server will save the user consent given to a specific client, "
+ "so that user won't be prompted for the same authorization multiple times."
+ ),
+ )
require_consent = models.BooleanField(
default=True,
- verbose_name=_('Require Consent?'),
- help_text=_('If disabled, the Server will NEVER ask the user for consent.'))
+ verbose_name=_("Require Consent?"),
+ help_text=_("If disabled, the Server will NEVER ask the user for consent."),
+ )
_redirect_uris = models.TextField(
- default='', verbose_name=_(u'Redirect URIs'),
- help_text=_(u'Enter each URI on a new line.'))
+ default="",
+ verbose_name=_("Redirect URIs"),
+ help_text=_("Enter each URI on a new line."),
+ )
_post_logout_redirect_uris = models.TextField(
blank=True,
- default='',
- verbose_name=_(u'Post Logout Redirect URIs'),
- help_text=_(u'Enter each URI on a new line.'))
+ default="",
+ verbose_name=_("Post Logout Redirect URIs"),
+ help_text=_("Enter each URI on a new line."),
+ )
_scope = models.TextField(
blank=True,
- default='',
- verbose_name=_(u'Scopes'),
- help_text=_('Specifies the authorized scope values for the client app.'))
+ default="",
+ verbose_name=_("Scopes"),
+ help_text=_("Specifies the authorized scope values for the client app."),
+ )
class Meta:
- verbose_name = _(u'Client')
- verbose_name_plural = _(u'Clients')
+ verbose_name = _("Client")
+ verbose_name_plural = _("Clients")
def __str__(self):
- return u'{0}'.format(self.name)
+ return "{0}".format(self.name)
def __unicode__(self):
return self.__str__()
@@ -127,7 +156,9 @@ class Client(models.Model):
def response_type_descriptions(self):
# return as a list, rather than a generator, so descriptions display correctly in admin
- return [response_type.description for response_type in self.response_types.all()]
+ return [
+ response_type.description for response_type in self.response_types.all()
+ ]
@property
def redirect_uris(self):
@@ -135,7 +166,7 @@ class Client(models.Model):
@redirect_uris.setter
def redirect_uris(self, value):
- self._redirect_uris = '\n'.join(value)
+ self._redirect_uris = "\n".join(value)
@property
def post_logout_redirect_uris(self):
@@ -143,7 +174,7 @@ class Client(models.Model):
@post_logout_redirect_uris.setter
def post_logout_redirect_uris(self, value):
- self._post_logout_redirect_uris = '\n'.join(value)
+ self._post_logout_redirect_uris = "\n".join(value)
@property
def scope(self):
@@ -151,18 +182,20 @@ class Client(models.Model):
@scope.setter
def scope(self, value):
- self._scope = ' '.join(value)
+ self._scope = " ".join(value)
@property
def default_redirect_uri(self):
- return self.redirect_uris[0] if self.redirect_uris else ''
+ return self.redirect_uris[0] if self.redirect_uris else ""
class BaseCodeTokenModel(models.Model):
- client = models.ForeignKey(Client, verbose_name=_(u'Client'), on_delete=models.CASCADE)
- expires_at = models.DateTimeField(verbose_name=_(u'Expiration Date'))
- _scope = models.TextField(default='', verbose_name=_(u'Scopes'))
+ client = models.ForeignKey(
+ Client, verbose_name=_("Client"), on_delete=models.CASCADE
+ )
+ expires_at = models.DateTimeField(verbose_name=_("Expiration Date"))
+ _scope = models.TextField(default="", verbose_name=_("Scopes"))
class Meta:
abstract = True
@@ -173,7 +206,7 @@ class BaseCodeTokenModel(models.Model):
@scope.setter
def scope(self, value):
- self._scope = ' '.join(value)
+ self._scope = " ".join(value)
def __unicode__(self):
return self.__str__()
@@ -185,33 +218,49 @@ class BaseCodeTokenModel(models.Model):
class Code(BaseCodeTokenModel):
user = models.ForeignKey(
- settings.AUTH_USER_MODEL, verbose_name=_(u'User'), on_delete=models.CASCADE)
- code = models.CharField(max_length=255, unique=True, verbose_name=_(u'Code'))
- nonce = models.CharField(max_length=255, blank=True, default='', verbose_name=_(u'Nonce'))
- is_authentication = models.BooleanField(default=False, verbose_name=_(u'Is Authentication?'))
- code_challenge = models.CharField(max_length=255, null=True, verbose_name=_(u'Code Challenge'))
+ settings.AUTH_USER_MODEL, verbose_name=_("User"), on_delete=models.CASCADE
+ )
+ code = models.CharField(max_length=255, unique=True, verbose_name=_("Code"))
+ nonce = models.CharField(
+ max_length=255, blank=True, default="", verbose_name=_("Nonce")
+ )
+ is_authentication = models.BooleanField(
+ default=False, verbose_name=_("Is Authentication?")
+ )
+ code_challenge = models.CharField(
+ max_length=255, null=True, verbose_name=_("Code Challenge")
+ )
code_challenge_method = models.CharField(
- max_length=255, null=True, verbose_name=_(u'Code Challenge Method'))
+ max_length=255, null=True, verbose_name=_("Code Challenge Method")
+ )
class Meta:
- verbose_name = _(u'Authorization Code')
- verbose_name_plural = _(u'Authorization Codes')
+ verbose_name = _("Authorization Code")
+ verbose_name_plural = _("Authorization Codes")
def __str__(self):
- return u'{0} - {1}'.format(self.client, self.code)
+ return "{0} - {1}".format(self.client, self.code)
class Token(BaseCodeTokenModel):
user = models.ForeignKey(
- settings.AUTH_USER_MODEL, null=True, verbose_name=_(u'User'), on_delete=models.CASCADE)
- access_token = models.CharField(max_length=255, unique=True, verbose_name=_(u'Access Token'))
- refresh_token = models.CharField(max_length=255, unique=True, verbose_name=_(u'Refresh Token'))
- _id_token = models.TextField(verbose_name=_(u'ID Token'))
+ settings.AUTH_USER_MODEL,
+ null=True,
+ verbose_name=_("User"),
+ on_delete=models.CASCADE,
+ )
+ access_token = models.CharField(
+ max_length=255, unique=True, verbose_name=_("Access Token")
+ )
+ refresh_token = models.CharField(
+ max_length=255, unique=True, verbose_name=_("Refresh Token")
+ )
+ _id_token = models.TextField(verbose_name=_("ID Token"))
class Meta:
- verbose_name = _(u'Token')
- verbose_name_plural = _(u'Tokens')
+ verbose_name = _("Token")
+ verbose_name_plural = _("Tokens")
@property
def id_token(self):
@@ -222,46 +271,52 @@ class Token(BaseCodeTokenModel):
self._id_token = json.dumps(value)
def __str__(self):
- return u'{0} - {1}'.format(self.client, self.access_token)
+ return "{0} - {1}".format(self.client, self.access_token)
@property
def at_hash(self):
# @@@ d-o-p only supports 256 bits (change this if that changes)
- hashed_access_token = sha256(
- self.access_token.encode('ascii')
- ).hexdigest().encode('ascii')
- return base64.urlsafe_b64encode(
- binascii.unhexlify(
- hashed_access_token[:len(hashed_access_token) // 2]
+ hashed_access_token = (
+ sha256(self.access_token.encode("ascii")).hexdigest().encode("ascii")
+ )
+ return (
+ base64.urlsafe_b64encode(
+ binascii.unhexlify(hashed_access_token[: len(hashed_access_token) // 2])
)
- ).rstrip(b'=').decode('ascii')
+ .rstrip(b"=")
+ .decode("ascii")
+ )
class UserConsent(BaseCodeTokenModel):
user = models.ForeignKey(
- settings.AUTH_USER_MODEL, verbose_name=_(u'User'), on_delete=models.CASCADE)
- date_given = models.DateTimeField(verbose_name=_(u'Date Given'))
+ settings.AUTH_USER_MODEL, verbose_name=_("User"), on_delete=models.CASCADE
+ )
+ date_given = models.DateTimeField(verbose_name=_("Date Given"))
class Meta:
- unique_together = ('user', 'client')
+ unique_together = ("user", "client")
class RSAKey(models.Model):
key = models.TextField(
- verbose_name=_(u'Key'), help_text=_(u'Paste your private RSA Key here.'))
+ verbose_name=_("Key"), help_text=_("Paste your private RSA Key here.")
+ )
class Meta:
- verbose_name = _(u'RSA Key')
- verbose_name_plural = _(u'RSA Keys')
+ verbose_name = _("RSA Key")
+ verbose_name_plural = _("RSA Keys")
def __str__(self):
- return u'{0}'.format(self.kid)
+ return "{0}".format(self.kid)
def __unicode__(self):
return self.__str__()
@property
def kid(self):
- return u'{0}'.format(md5(self.key.encode('utf-8')).hexdigest() if self.key else '')
+ return "{0}".format(
+ md5(self.key.encode("utf-8")).hexdigest() if self.key else ""
+ )
Index: django-oidc-provider-0.7.0/oidc_provider/settings.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/settings.py
+++ django-oidc-provider-0.7.0/oidc_provider/settings.py
@@ -31,7 +31,7 @@ class DefaultSettings(object):
OPTIONAL. Provide a way to plug into the process after
the user has logged in, typically to perform some business logic.
"""
- return 'oidc_provider.lib.utils.common.default_after_userlogin_hook'
+ return "oidc_provider.lib.utils.common.default_after_userlogin_hook"
@property
def OIDC_AFTER_END_SESSION_HOOK(self):
@@ -39,14 +39,14 @@ class DefaultSettings(object):
OPTIONAL. Provide a way to plug into the end session process just before calling
Django's logout function, typically to perform some business logic.
"""
- return 'oidc_provider.lib.utils.common.default_after_end_session_hook'
+ return "oidc_provider.lib.utils.common.default_after_end_session_hook"
@property
def OIDC_CODE_EXPIRE(self):
"""
OPTIONAL. Code expiration time expressed in seconds.
"""
- return 60*10
+ return 60 * 10
@property
def OIDC_EXTRA_SCOPE_CLAIMS(self):
@@ -61,7 +61,7 @@ class DefaultSettings(object):
"""
OPTIONAL. Id token expiration time expressed in seconds.
"""
- return 60*10
+ return 60 * 10
@property
def OIDC_IDTOKEN_SUB_GENERATOR(self):
@@ -70,7 +70,7 @@ class DefaultSettings(object):
reassigned identifier within the Issuer for the End-User,
which is intended to be consumed by the Client.
"""
- return 'oidc_provider.lib.utils.common.default_sub_generator'
+ return "oidc_provider.lib.utils.common.default_sub_generator"
@property
def OIDC_IDTOKEN_INCLUDE_CLAIMS(self):
@@ -94,8 +94,10 @@ class DefaultSettings(object):
# Memoize generated value
if not self._unauthenticated_session_management_key:
- self._unauthenticated_session_management_key = ''.join(
- random.choice(string.ascii_uppercase + string.digits) for _ in range(100))
+ self._unauthenticated_session_management_key = "".join(
+ random.choice(string.ascii_uppercase + string.digits)
+ for _ in range(100)
+ )
return self._unauthenticated_session_management_key
@property
@@ -103,7 +105,7 @@ class DefaultSettings(object):
"""
OPTIONAL. User consent expiration after been granted.
"""
- return 30*3
+ return 30 * 3
@property
def OIDC_TOKEN_EXPIRE(self):
@@ -111,7 +113,7 @@ class DefaultSettings(object):
OPTIONAL. Token object expiration after been created.
Expressed in seconds.
"""
- return 60*60
+ return 60 * 60
@property
def OIDC_USERINFO(self):
@@ -119,7 +121,7 @@ class DefaultSettings(object):
OPTIONAL. A string with the location of your function.
Used to populate standard claims with your user information.
"""
- return 'oidc_provider.lib.utils.common.default_userinfo'
+ return "oidc_provider.lib.utils.common.default_userinfo"
@property
def OIDC_IDTOKEN_PROCESSING_HOOK(self):
@@ -127,7 +129,7 @@ class DefaultSettings(object):
OPTIONAL. A string with the location of your hook.
Used to add extra dictionary values specific for your app into id_token.
"""
- return 'oidc_provider.lib.utils.common.default_idtoken_processing_hook'
+ return "oidc_provider.lib.utils.common.default_idtoken_processing_hook"
@property
def OIDC_INTROSPECTION_PROCESSING_HOOK(self):
@@ -135,7 +137,7 @@ class DefaultSettings(object):
OPTIONAL. A string with the location of your function.
Used to update the response for a valid introspection token request.
"""
- return 'oidc_provider.lib.utils.common.default_introspection_processing_hook'
+ return "oidc_provider.lib.utils.common.default_introspection_processing_hook"
@property
def OIDC_INTROSPECTION_VALIDATE_AUDIENCE_SCOPE(self):
@@ -164,8 +166,8 @@ class DefaultSettings(object):
@property
def OIDC_TEMPLATES(self):
return {
- 'authorize': 'oidc_provider/authorize.html',
- 'error': 'oidc_provider/error.html'
+ "authorize": "oidc_provider/authorize.html",
+ "error": "oidc_provider/error.html",
}
@@ -177,12 +179,16 @@ def import_from_str(value):
Attempt to import a class from a string representation.
"""
try:
- parts = value.split('.')
- module_path, class_name = '.'.join(parts[:-1]), parts[-1]
+ parts = value.split(".")
+ module_path, class_name = ".".join(parts[:-1]), parts[-1]
module = importlib.import_module(module_path)
return getattr(module, class_name)
except ImportError as e:
- msg = 'Could not import %s for settings. %s: %s.' % (value, e.__class__.__name__, e)
+ msg = "Could not import %s for settings. %s: %s." % (
+ value,
+ e.__class__.__name__,
+ e,
+ )
raise ImportError(msg)
@@ -197,7 +203,7 @@ def get(name, import_str=False):
value = getattr(settings, name)
except AttributeError:
if name in default_settings.required_attrs:
- raise Exception('You must set ' + name + ' in your settings.')
+ raise Exception("You must set " + name + " in your settings.")
if isinstance(default_value, dict) and value:
default_value.update(value)
Index: django-oidc-provider-0.7.0/oidc_provider/signals.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/signals.py
+++ django-oidc-provider-0.7.0/oidc_provider/signals.py
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
from django.dispatch import Signal
-
-user_accept_consent = Signal(providing_args=['user', 'client', 'scope'])
-user_decline_consent = Signal(providing_args=['user', 'client', 'scope'])
+user_accept_consent = Signal()
+user_decline_consent = Signal()
Index: django-oidc-provider-0.7.0/oidc_provider/templates/registration/login.html
===================================================================
--- /dev/null
+++ django-oidc-provider-0.7.0/oidc_provider/templates/registration/login.html
@@ -0,0 +1,13 @@
+<!-- templates/registration/login.html -->
+{% extends 'base.html' %}
+
+{% block title %}Login{% endblock %}
+
+{% block content %}
+<h2>Log In</h2>
+<form method="post">
+ {% csrf_token %}
+ {{ form.as_p }}
+ <button type="submit">Log In</button>
+</form>
+{% endblock %}
Index: django-oidc-provider-0.7.0/oidc_provider/tests/app/urls.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/app/urls.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/app/urls.py
@@ -1,18 +1,25 @@
from django.contrib.auth import views as auth_views
+
try:
from django.urls import include, url
except ImportError:
- from django.conf.urls import include, url
+ from django.urls import include, path
+
from django.contrib import admin
from django.views.generic import TemplateView
-
urlpatterns = [
- url(r'^$', TemplateView.as_view(template_name='home.html'), name='home'),
- url(r'^accounts/login/$',
- auth_views.LoginView.as_view(template_name='accounts/login.html'), name='login'),
- url(r'^accounts/logout/$',
- auth_views.LogoutView.as_view(template_name='accounts/logout.html'), name='logout'),
- url(r'^openid/', include('oidc_provider.urls', namespace='oidc_provider')),
- url(r'^admin/', admin.site.urls),
+ path("", TemplateView.as_view(template_name="home.html"), name="home"),
+ path(
+ "accounts/login/",
+ auth_views.LoginView.as_view(template_name="accounts/login.html"),
+ name="login",
+ ),
+ path(
+ "accounts/logout/",
+ auth_views.LogoutView.as_view(template_name="accounts/logout.html"),
+ name="logout",
+ ),
+ path("openid/", include("oidc_provider.urls", namespace="oidc_provider")),
+ path("admin/", admin.site.urls),
]
Index: django-oidc-provider-0.7.0/oidc_provider/tests/app/utils.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/app/utils.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/app/utils.py
@@ -9,21 +9,17 @@ try:
except ImportError:
from urllib.parse import parse_qs, urlsplit
-from django.utils import timezone
from django.contrib.auth.models import User
+from django.utils import timezone
-from oidc_provider.models import (
- Client,
- Code,
- Token,
- ResponseType)
-
+from oidc_provider.models import Client, Code, ResponseType, Token
-FAKE_NONCE = 'cb584e44c43ed6bd0bc2d9c7e242837d'
-FAKE_RANDOM_STRING = ''.join(
- random.choice(string.ascii_uppercase + string.digits) for _ in range(32))
-FAKE_CODE_CHALLENGE = 'YlYXEqXuRm-Xgi2BOUiK50JW1KsGTX6F1TDnZSC8VTg'
-FAKE_CODE_VERIFIER = 'SmxGa0XueyNh5bDgTcSrqzAh2_FmXEqU8kDT6CuXicw'
+FAKE_NONCE = "cb584e44c43ed6bd0bc2d9c7e242837d"
+FAKE_RANDOM_STRING = "".join(
+ random.choice(string.ascii_uppercase + string.digits) for _ in range(32)
+)
+FAKE_CODE_CHALLENGE = "YlYXEqXuRm-Xgi2BOUiK50JW1KsGTX6F1TDnZSC8VTg"
+FAKE_CODE_VERIFIER = "SmxGa0XueyNh5bDgTcSrqzAh2_FmXEqU8kDT6CuXicw"
def create_fake_user():
@@ -33,11 +29,11 @@ def create_fake_user():
Return a User object.
"""
user = User()
- user.username = 'johndoe'
- user.email = 'johndoe@example.com'
- user.first_name = 'John'
- user.last_name = 'Doe'
- user.set_password('1234')
+ user.username = "johndoe"
+ user.email = "johndoe@example.com"
+ user.first_name = "John"
+ user.last_name = "Doe"
+ user.set_password("1234")
user.save()
@@ -52,20 +48,20 @@ def create_fake_client(response_type, is
Return a Client object.
"""
client = Client()
- client.name = 'Some Client'
+ client.name = "Some Client"
client.client_id = str(random.randint(1, 999999)).zfill(6)
if is_public:
- client.client_type = 'public'
- client.client_secret = ''
+ client.client_type = "public"
+ client.client_secret = ""
else:
client.client_secret = str(random.randint(1, 999999)).zfill(6)
- client.redirect_uris = ['http://example.com/']
+ client.redirect_uris = ["http://example.com/"]
client.require_consent = require_consent
client.save()
# check if response_type is a string in a python 2 and 3 compatible way
- if isinstance(response_type, ("".__class__, u"".__class__)):
+ if isinstance(response_type, ("".__class__, "".__class__)):
response_type = (response_type,)
for value in response_type:
client.response_types.add(ResponseType.objects.get(value=value))
@@ -90,7 +86,7 @@ def is_code_valid(url, user, client):
try:
parsed = urlsplit(url)
params = parse_qs(parsed.query or parsed.fragment)
- code = params['code'][0]
+ code = params["code"][0]
code = Code.objects.get(code=code)
is_code_ok = (code.client == client) and (code.user == user)
except Exception:
@@ -103,12 +99,12 @@ def userinfo(claims, user):
"""
Fake function for setting OIDC_USERINFO.
"""
- claims['given_name'] = 'John'
- claims['family_name'] = 'Doe'
- claims['name'] = '{0} {1}'.format(claims['given_name'], claims['family_name'])
- claims['email'] = user.email
- claims['email_verified'] = True
- claims['address']['country'] = 'Argentina'
+ claims["given_name"] = "John"
+ claims["family_name"] = "Doe"
+ claims["name"] = "{0} {1}".format(claims["given_name"], claims["family_name"])
+ claims["email"] = user.email
+ claims["email_verified"] = True
+ claims["address"]["country"] = "Argentina"
return claims
@@ -123,8 +119,8 @@ def fake_idtoken_processing_hook(id_toke
"""
Fake function for inserting some keys into token. Testing OIDC_IDTOKEN_PROCESSING_HOOK.
"""
- id_token['test_idtoken_processing_hook'] = FAKE_RANDOM_STRING
- id_token['test_idtoken_processing_hook_user_email'] = user.email
+ id_token["test_idtoken_processing_hook"] = FAKE_RANDOM_STRING
+ id_token["test_idtoken_processing_hook_user_email"] = user.email
return id_token
@@ -133,8 +129,8 @@ def fake_idtoken_processing_hook2(id_tok
Fake function for inserting some keys into token.
Testing OIDC_IDTOKEN_PROCESSING_HOOK - tuple or list as param
"""
- id_token['test_idtoken_processing_hook2'] = FAKE_RANDOM_STRING
- id_token['test_idtoken_processing_hook_user_email2'] = user.email
+ id_token["test_idtoken_processing_hook2"] = FAKE_RANDOM_STRING
+ id_token["test_idtoken_processing_hook_user_email2"] = user.email
return id_token
@@ -142,7 +138,7 @@ def fake_idtoken_processing_hook3(id_tok
"""
Fake function for checking scope is passed to processing hook.
"""
- id_token['scope_of_token_passed_to_processing_hook'] = token.scope
+ id_token["scope_of_token_passed_to_processing_hook"] = token.scope
return id_token
@@ -150,20 +146,21 @@ def fake_idtoken_processing_hook4(id_tok
"""
Fake function for checking kwargs passed to processing hook.
"""
- id_token['kwargs_passed_to_processing_hook'] = {
- key: repr(value)
- for (key, value) in kwargs.items()
+ id_token["kwargs_passed_to_processing_hook"] = {
+ key: repr(value) for (key, value) in kwargs.items()
}
return id_token
def fake_introspection_processing_hook(response_dict, client, id_token):
- response_dict['test_introspection_processing_hook'] = FAKE_RANDOM_STRING
+ response_dict["test_introspection_processing_hook"] = FAKE_RANDOM_STRING
return response_dict
class TestAuthBackend:
def authenticate(self, *args, **kwargs):
- if django.VERSION[0] >= 2 or (django.VERSION[0] == 1 and django.VERSION[1] >= 11):
+ if django.VERSION[0] >= 2 or (
+ django.VERSION[0] == 1 and django.VERSION[1] >= 11
+ ):
assert len(args) > 0 and args[0]
return ModelBackend().authenticate(*args, **kwargs)
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_authorize_endpoint.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_authorize_endpoint.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_authorize_endpoint.py
@@ -1,57 +1,55 @@
from oidc_provider.lib.errors import RedirectUriError
try:
- from urllib.parse import urlencode, quote
+ from urllib.parse import quote, urlencode
except ImportError:
- from urllib import urlencode, quote
+ from urllib import quote, urlencode
try:
from urllib.parse import parse_qs, urlsplit
except ImportError:
from urlparse import parse_qs, urlsplit
+
import uuid
-from mock import patch, mock
from django.contrib.auth.models import AnonymousUser
from django.core.management import call_command
+from mock import mock, patch
+
try:
from django.urls import reverse
except ImportError:
from django.core.urlresolvers import reverse
-from django.test import (
- RequestFactory,
- override_settings,
-)
-from django.test import TestCase
+
+from django.test import RequestFactory, TestCase, override_settings
from jwkest.jwt import JWT
from oidc_provider import settings
+from oidc_provider.lib.endpoints.authorize import AuthorizeEndpoint
+from oidc_provider.lib.utils.authorize import strip_prompt_login
from oidc_provider.tests.app.utils import (
- create_fake_user,
- create_fake_client,
FAKE_CODE_CHALLENGE,
+ create_fake_client,
+ create_fake_user,
is_code_valid,
)
-from oidc_provider.lib.utils.authorize import strip_prompt_login
from oidc_provider.views import AuthorizeView
-from oidc_provider.lib.endpoints.authorize import AuthorizeEndpoint
class AuthorizeEndpointMixin(object):
-
def _auth_request(self, method, data=None, is_user_authenticated=False):
if data is None:
data = {}
- url = reverse('oidc_provider:authorize')
+ url = reverse("oidc_provider:authorize")
- if method.lower() == 'get':
- query_str = urlencode(data).replace('+', '%20')
+ if method.lower() == "get":
+ query_str = urlencode(data).replace("+", "%20")
if query_str:
- url += '?' + query_str
+ url += "?" + query_str
request = self.factory.get(url)
- elif method.lower() == 'post':
+ elif method.lower() == "post":
request = self.factory.post(url, data=data)
else:
- raise Exception('Method unsupported for an Authorization Request.')
+ raise Exception("Method unsupported for an Authorization Request.")
# Simulate that the user is logged.
request.user = self.user if is_user_authenticated else AnonymousUser()
@@ -67,15 +65,17 @@ class AuthorizationCodeFlowTestCase(Test
"""
def setUp(self):
- call_command('creatersakey')
+ call_command("creatersakey")
self.factory = RequestFactory()
self.user = create_fake_user()
- self.client = create_fake_client(response_type='code')
+ self.client = create_fake_client(response_type="code")
self.client_with_no_consent = create_fake_client(
- response_type='code', require_consent=False)
- self.client_public = create_fake_client(response_type='code', is_public=True)
+ response_type="code", require_consent=False
+ )
+ self.client_public = create_fake_client(response_type="code", is_public=True)
self.client_public_with_no_consent = create_fake_client(
- response_type='code', is_public=True, require_consent=False)
+ response_type="code", is_public=True, require_consent=False
+ )
self.state = uuid.uuid4().hex
self.nonce = uuid.uuid4().hex
@@ -87,7 +87,7 @@ class AuthorizationCodeFlowTestCase(Test
See: https://tools.ietf.org/html/rfc6749#section-4.1.2.1
"""
- response = self._auth_request('get')
+ response = self._auth_request("get")
self.assertEqual(response.status_code, 200)
self.assertEqual(bool(response.content), True)
@@ -101,20 +101,20 @@ class AuthorizationCodeFlowTestCase(Test
"""
# Create an authorize request with an unsupported response_type.
data = {
- 'client_id': self.client.client_id,
- 'response_type': 'something_wrong',
- 'redirect_uri': self.client.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
+ "client_id": self.client.client_id,
+ "response_type": "something_wrong",
+ "redirect_uri": self.client.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
}
- response = self._auth_request('get', data)
+ response = self._auth_request("get", data)
self.assertEqual(response.status_code, 302)
- self.assertEqual(response.has_header('Location'), True)
+ self.assertEqual(response.has_header("Location"), True)
# Should be an 'error' component in query.
- self.assertIn('error=', response['Location'])
+ self.assertIn("error=", response["Location"])
def test_user_not_logged(self):
"""
@@ -124,17 +124,17 @@ class AuthorizationCodeFlowTestCase(Test
See: http://openid.net/specs/openid-connect-core-1_0.html#Authenticates
"""
data = {
- 'client_id': self.client.client_id,
- 'response_type': 'code',
- 'redirect_uri': self.client.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
+ "client_id": self.client.client_id,
+ "response_type": "code",
+ "redirect_uri": self.client.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
}
- response = self._auth_request('get', data)
+ response = self._auth_request("get", data)
# Check if user was redirected to the login view.
- self.assertIn(settings.get('OIDC_LOGIN_URL'), response['Location'])
+ self.assertIn(settings.get("OIDC_LOGIN_URL"), response["Location"])
def test_user_consent_inputs(self):
"""
@@ -145,33 +145,37 @@ class AuthorizationCodeFlowTestCase(Test
See: http://openid.net/specs/openid-connect-core-1_0.html#Consent
"""
data = {
- 'client_id': self.client.client_id,
- 'response_type': 'code',
- 'redirect_uri': self.client.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
+ "client_id": self.client.client_id,
+ "response_type": "code",
+ "redirect_uri": self.client.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
# PKCE parameters.
- 'code_challenge': FAKE_CODE_CHALLENGE,
- 'code_challenge_method': 'S256',
+ "code_challenge": FAKE_CODE_CHALLENGE,
+ "code_challenge_method": "S256",
}
- response = self._auth_request('get', data, is_user_authenticated=True)
+ response = self._auth_request("get", data, is_user_authenticated=True)
# Check if hidden inputs exists in the form,
# also if their values are valid.
input_html = '<input name="{0}" type="hidden" value="{1}" />'
to_check = {
- 'client_id': self.client.client_id,
- 'redirect_uri': self.client.default_redirect_uri,
- 'response_type': 'code',
- 'code_challenge': FAKE_CODE_CHALLENGE,
- 'code_challenge_method': 'S256',
+ "client_id": self.client.client_id,
+ "redirect_uri": self.client.default_redirect_uri,
+ "response_type": "code",
+ "code_challenge": FAKE_CODE_CHALLENGE,
+ "code_challenge_method": "S256",
}
for key, value in iter(to_check.items()):
- is_input_ok = input_html.format(key, value) in response.content.decode('utf-8')
- self.assertEqual(is_input_ok, True, msg='Hidden input for "' + key + '" fails.')
+ is_input_ok = input_html.format(key, value) in response.content.decode(
+ "utf-8"
+ )
+ self.assertEqual(
+ is_input_ok, True, msg='Hidden input for "' + key + '" fails.'
+ )
def test_user_consent_response(self):
"""
@@ -186,37 +190,42 @@ class AuthorizationCodeFlowTestCase(Test
by adding them as query parameters to the redirect_uri.
"""
data = {
- 'client_id': self.client.client_id,
- 'redirect_uri': self.client.default_redirect_uri,
- 'response_type': 'code',
- 'scope': 'openid email',
- 'state': self.state,
+ "client_id": self.client.client_id,
+ "redirect_uri": self.client.default_redirect_uri,
+ "response_type": "code",
+ "scope": "openid email",
+ "state": self.state,
# PKCE parameters.
- 'code_challenge': FAKE_CODE_CHALLENGE,
- 'code_challenge_method': 'S256',
+ "code_challenge": FAKE_CODE_CHALLENGE,
+ "code_challenge_method": "S256",
}
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
# Because user doesn't allow app, SHOULD exists an error parameter
# in the query.
- self.assertIn('error=', response['Location'], msg='error param is missing in query.')
self.assertIn(
- 'access_denied', response['Location'], msg='"access_denied" code is missing in query.')
+ "error=", response["Location"], msg="error param is missing in query."
+ )
+ self.assertIn(
+ "access_denied",
+ response["Location"],
+ msg='"access_denied" code is missing in query.',
+ )
# Simulate user authorization.
- data['allow'] = 'Accept' # Will be the value of the button.
+ data["allow"] = "Accept" # Will be the value of the button.
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- is_code_ok = is_code_valid(url=response['Location'],
- user=self.user,
- client=self.client)
- self.assertEqual(is_code_ok, True, msg='Code returned is invalid.')
+ is_code_ok = is_code_valid(
+ url=response["Location"], user=self.user, client=self.client
+ )
+ self.assertEqual(is_code_ok, True, msg="Code returned is invalid.")
# Check if the state is returned.
- state = (response['Location'].split('state='))[1].split('&')[0]
- self.assertEqual(state, self.state, msg='State change or is missing.')
+ state = (response["Location"].split("state="))[1].split("&")[0]
+ self.assertEqual(state, self.state, msg="State change or is missing.")
def test_user_consent_skipped(self):
"""
@@ -225,37 +234,38 @@ class AuthorizationCodeFlowTestCase(Test
authorization multiple times, the server skip it.
"""
data = {
- 'client_id': self.client_with_no_consent.client_id,
- 'redirect_uri': self.client_with_no_consent.default_redirect_uri,
- 'response_type': 'code',
- 'scope': 'openid email',
- 'state': self.state,
- 'allow': 'Accept',
+ "client_id": self.client_with_no_consent.client_id,
+ "redirect_uri": self.client_with_no_consent.default_redirect_uri,
+ "response_type": "code",
+ "scope": "openid email",
+ "state": self.state,
+ "allow": "Accept",
}
- request = self.factory.post(reverse('oidc_provider:authorize'),
- data=data)
+ request = self.factory.post(reverse("oidc_provider:authorize"), data=data)
# Simulate that the user is logged.
request.user = self.user
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- self.assertIn('code', response['Location'], msg='Code is missing in the returned url.')
+ self.assertIn(
+ "code", response["Location"], msg="Code is missing in the returned url."
+ )
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- is_code_ok = is_code_valid(url=response['Location'],
- user=self.user,
- client=self.client_with_no_consent)
- self.assertEqual(is_code_ok, True, msg='Code returned is invalid.')
+ is_code_ok = is_code_valid(
+ url=response["Location"], user=self.user, client=self.client_with_no_consent
+ )
+ self.assertEqual(is_code_ok, True, msg="Code returned is invalid.")
- del data['allow']
- response = self._auth_request('get', data, is_user_authenticated=True)
+ del data["allow"]
+ response = self._auth_request("get", data, is_user_authenticated=True)
- is_code_ok = is_code_valid(url=response['Location'],
- user=self.user,
- client=self.client_with_no_consent)
- self.assertEqual(is_code_ok, True, msg='Code returned is invalid or missing.')
+ is_code_ok = is_code_valid(
+ url=response["Location"], user=self.user, client=self.client_with_no_consent
+ )
+ self.assertEqual(is_code_ok, True, msg="Code returned is invalid or missing.")
def test_response_uri_is_properly_constructed(self):
"""
@@ -263,33 +273,36 @@ class AuthorizationCodeFlowTestCase(Test
Only 'state' and 'code' should be appended.
"""
data = {
- 'client_id': self.client.client_id,
- 'redirect_uri': self.client.default_redirect_uri,
- 'response_type': 'code',
- 'scope': 'openid email',
- 'state': self.state,
- 'allow': 'Accept',
+ "client_id": self.client.client_id,
+ "redirect_uri": self.client.default_redirect_uri,
+ "response_type": "code",
+ "scope": "openid email",
+ "state": self.state,
+ "allow": "Accept",
}
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- parsed = urlsplit(response['Location'])
+ parsed = urlsplit(response["Location"])
params = parse_qs(parsed.query or parsed.fragment)
- state = params['state'][0]
+ state = params["state"][0]
self.assertEquals(self.state, state, msg="State returned is invalid or missing")
- is_code_ok = is_code_valid(url=response['Location'],
- user=self.user,
- client=self.client)
- self.assertTrue(is_code_ok, msg='Code returned is invalid or missing')
+ is_code_ok = is_code_valid(
+ url=response["Location"], user=self.user, client=self.client
+ )
+ self.assertTrue(is_code_ok, msg="Code returned is invalid or missing")
self.assertEquals(
- set(params.keys()), {'state', 'code'},
- msg='More than state or code appended as query params')
+ set(params.keys()),
+ {"state", "code"},
+ msg="More than state or code appended as query params",
+ )
self.assertTrue(
- response['Location'].startswith(self.client.default_redirect_uri),
- msg='Different redirect_uri returned')
+ response["Location"].startswith(self.client.default_redirect_uri),
+ msg="Different redirect_uri returned",
+ )
def test_unknown_redirect_uris_are_rejected(self):
"""
@@ -297,16 +310,19 @@ class AuthorizationCodeFlowTestCase(Test
See http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest.
"""
data = {
- 'client_id': self.client.client_id,
- 'response_type': 'code',
- 'redirect_uri': 'http://neverseenthis.com',
- 'scope': 'openid email',
- 'state': self.state,
+ "client_id": self.client.client_id,
+ "response_type": "code",
+ "redirect_uri": "http://neverseenthis.com",
+ "scope": "openid email",
+ "state": self.state,
}
- response = self._auth_request('get', data)
+ response = self._auth_request("get", data)
self.assertIn(
- RedirectUriError.error, response.content.decode('utf-8'), msg='No redirect_uri error')
+ RedirectUriError.error,
+ response.content.decode("utf-8"),
+ msg="No redirect_uri error",
+ )
def test_manipulated_redirect_uris_are_rejected(self):
"""
@@ -314,16 +330,19 @@ class AuthorizationCodeFlowTestCase(Test
See http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest.
"""
data = {
- 'client_id': self.client.client_id,
- 'response_type': 'code',
- 'redirect_uri': self.client.default_redirect_uri + "?some=query",
- 'scope': 'openid email',
- 'state': self.state,
+ "client_id": self.client.client_id,
+ "response_type": "code",
+ "redirect_uri": self.client.default_redirect_uri + "?some=query",
+ "scope": "openid email",
+ "state": self.state,
}
- response = self._auth_request('get', data)
+ response = self._auth_request("get", data)
self.assertIn(
- RedirectUriError.error, response.content.decode('utf-8'), msg='No redirect_uri error')
+ RedirectUriError.error,
+ response.content.decode("utf-8"),
+ msg="No redirect_uri error",
+ )
def test_public_client_auto_approval(self):
"""
@@ -331,16 +350,16 @@ class AuthorizationCodeFlowTestCase(Test
clients using Authorization Code.
"""
data = {
- 'client_id': self.client_public_with_no_consent.client_id,
- 'response_type': 'code',
- 'redirect_uri': self.client_public_with_no_consent.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
+ "client_id": self.client_public_with_no_consent.client_id,
+ "response_type": "code",
+ "redirect_uri": self.client_public_with_no_consent.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
}
- response = self._auth_request('get', data, is_user_authenticated=True)
+ response = self._auth_request("get", data, is_user_authenticated=True)
- self.assertIn('Request for Permission', response.content.decode('utf-8'))
+ self.assertIn("Request for Permission", response.content.decode("utf-8"))
def test_prompt_none_parameter(self):
"""
@@ -349,26 +368,26 @@ class AuthorizationCodeFlowTestCase(Test
See: http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
"""
data = {
- 'client_id': self.client.client_id,
- 'response_type': next(self.client.response_type_values()),
- 'redirect_uri': self.client.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
- 'prompt': 'none'
+ "client_id": self.client.client_id,
+ "response_type": next(self.client.response_type_values()),
+ "redirect_uri": self.client.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
+ "prompt": "none",
}
- response = self._auth_request('get', data)
+ response = self._auth_request("get", data)
# An error is returned if an End-User is not already authenticated.
- self.assertIn('login_required', response['Location'])
+ self.assertIn("login_required", response["Location"])
- response = self._auth_request('get', data, is_user_authenticated=True)
+ response = self._auth_request("get", data, is_user_authenticated=True)
# An error is returned if the Client does not have pre-configured
# consent for the requested Claims.
- self.assertIn('consent_required', response['Location'])
+ self.assertIn("consent_required", response["Location"])
- @patch('oidc_provider.views.django_user_logout')
+ @patch("oidc_provider.views.django_user_logout")
def test_prompt_login_parameter(self, logout_function):
"""
Specifies whether the Authorization Server prompts the End-User for
@@ -376,31 +395,31 @@ class AuthorizationCodeFlowTestCase(Test
See: http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
"""
data = {
- 'client_id': self.client.client_id,
- 'response_type': next(self.client.response_type_values()),
- 'redirect_uri': self.client.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
- 'prompt': 'login'
+ "client_id": self.client.client_id,
+ "response_type": next(self.client.response_type_values()),
+ "redirect_uri": self.client.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
+ "prompt": "login",
}
- response = self._auth_request('get', data)
- self.assertIn(settings.get('OIDC_LOGIN_URL'), response['Location'])
+ response = self._auth_request("get", data)
+ self.assertIn(settings.get("OIDC_LOGIN_URL"), response["Location"])
self.assertNotIn(
- quote('prompt=login'),
- response['Location'],
+ quote("prompt=login"),
+ response["Location"],
"Found prompt=login, this leads to infinite login loop. See "
- "https://github.com/juanifioren/django-oidc-provider/issues/197."
+ "https://github.com/juanifioren/django-oidc-provider/issues/197.",
)
- response = self._auth_request('get', data, is_user_authenticated=True)
- self.assertIn(settings.get('OIDC_LOGIN_URL'), response['Location'])
+ response = self._auth_request("get", data, is_user_authenticated=True)
+ self.assertIn(settings.get("OIDC_LOGIN_URL"), response["Location"])
self.assertTrue(logout_function.called_once())
self.assertNotIn(
- quote('prompt=login'),
- response['Location'],
+ quote("prompt=login"),
+ response["Location"],
"Found prompt=login, this leads to infinite login loop. See "
- "https://github.com/juanifioren/django-oidc-provider/issues/197."
+ "https://github.com/juanifioren/django-oidc-provider/issues/197.",
)
def test_prompt_login_none_parameter(self):
@@ -410,21 +429,21 @@ class AuthorizationCodeFlowTestCase(Test
See: http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
"""
data = {
- 'client_id': self.client.client_id,
- 'response_type': next(self.client.response_type_values()),
- 'redirect_uri': self.client.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
- 'prompt': 'login none'
+ "client_id": self.client.client_id,
+ "response_type": next(self.client.response_type_values()),
+ "redirect_uri": self.client.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
+ "prompt": "login none",
}
- response = self._auth_request('get', data)
- self.assertIn('login_required', response['Location'])
+ response = self._auth_request("get", data)
+ self.assertIn("login_required", response["Location"])
- response = self._auth_request('get', data, is_user_authenticated=True)
- self.assertIn('login_required', response['Location'])
+ response = self._auth_request("get", data, is_user_authenticated=True)
+ self.assertIn("login_required", response["Location"])
- @patch('oidc_provider.views.render')
+ @patch("oidc_provider.views.render")
def test_prompt_consent_parameter(self, render_patched):
"""
Specifies whether the Authorization Server prompts the End-User for
@@ -432,21 +451,22 @@ class AuthorizationCodeFlowTestCase(Test
See: http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
"""
data = {
- 'client_id': self.client.client_id,
- 'response_type': next(self.client.response_type_values()),
- 'redirect_uri': self.client.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
- 'prompt': 'consent'
+ "client_id": self.client.client_id,
+ "response_type": next(self.client.response_type_values()),
+ "redirect_uri": self.client.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
+ "prompt": "consent",
}
- response = self._auth_request('get', data)
- self.assertIn(settings.get('OIDC_LOGIN_URL'), response['Location'])
+ response = self._auth_request("get", data)
+ self.assertIn(settings.get("OIDC_LOGIN_URL"), response["Location"])
- response = self._auth_request('get', data, is_user_authenticated=True)
+ response = self._auth_request("get", data, is_user_authenticated=True)
render_patched.assert_called_once()
self.assertTrue(
- render_patched.call_args[0][1], settings.get('OIDC_TEMPLATES')['authorize'])
+ render_patched.call_args[0][1], settings.get("OIDC_TEMPLATES")["authorize"]
+ )
def test_prompt_consent_none_parameter(self):
"""
@@ -455,47 +475,51 @@ class AuthorizationCodeFlowTestCase(Test
See: http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
"""
data = {
- 'client_id': self.client.client_id,
- 'response_type': next(self.client.response_type_values()),
- 'redirect_uri': self.client.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
- 'prompt': 'consent none'
+ "client_id": self.client.client_id,
+ "response_type": next(self.client.response_type_values()),
+ "redirect_uri": self.client.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
+ "prompt": "consent none",
}
- response = self._auth_request('get', data)
- self.assertIn('login_required', response['Location'])
+ response = self._auth_request("get", data)
+ self.assertIn("login_required", response["Location"])
- response = self._auth_request('get', data, is_user_authenticated=True)
- self.assertIn('consent_required', response['Location'])
+ response = self._auth_request("get", data, is_user_authenticated=True)
+ self.assertIn("consent_required", response["Location"])
def test_strip_prompt_login(self):
"""
Test for helper method test_strip_prompt_login.
"""
# Original paths
- path0 = 'http://idp.com/?prompt=login'
- path1 = 'http://idp.com/?prompt=consent login none'
- path2 = ('http://idp.com/?response_type=code&client' +
- '_id=112233&prompt=consent login')
- path3 = ('http://idp.com/?response_type=code&client' +
- '_id=112233&prompt=login none&redirect_uri' +
- '=http://localhost:8000')
-
- self.assertNotIn('prompt', strip_prompt_login(path0))
-
- self.assertIn('prompt', strip_prompt_login(path1))
- self.assertIn('consent', strip_prompt_login(path1))
- self.assertIn('none', strip_prompt_login(path1))
- self.assertNotIn('login', strip_prompt_login(path1))
-
- self.assertIn('prompt', strip_prompt_login(path2))
- self.assertIn('consent', strip_prompt_login(path1))
- self.assertNotIn('login', strip_prompt_login(path2))
-
- self.assertIn('prompt', strip_prompt_login(path3))
- self.assertIn('none', strip_prompt_login(path3))
- self.assertNotIn('login', strip_prompt_login(path3))
+ path0 = "http://idp.com/?prompt=login"
+ path1 = "http://idp.com/?prompt=consent login none"
+ path2 = (
+ "http://idp.com/?response_type=code&client"
+ + "_id=112233&prompt=consent login"
+ )
+ path3 = (
+ "http://idp.com/?response_type=code&client"
+ + "_id=112233&prompt=login none&redirect_uri"
+ + "=http://localhost:8000"
+ )
+
+ self.assertNotIn("prompt", strip_prompt_login(path0))
+
+ self.assertIn("prompt", strip_prompt_login(path1))
+ self.assertIn("consent", strip_prompt_login(path1))
+ self.assertIn("none", strip_prompt_login(path1))
+ self.assertNotIn("login", strip_prompt_login(path1))
+
+ self.assertIn("prompt", strip_prompt_login(path2))
+ self.assertIn("consent", strip_prompt_login(path1))
+ self.assertNotIn("login", strip_prompt_login(path2))
+
+ self.assertIn("prompt", strip_prompt_login(path3))
+ self.assertIn("none", strip_prompt_login(path3))
+ self.assertNotIn("login", strip_prompt_login(path3))
class AuthorizationImplicitFlowTestCase(TestCase, AuthorizeEndpointMixin):
@@ -504,18 +528,23 @@ class AuthorizationImplicitFlowTestCase(
"""
def setUp(self):
- call_command('creatersakey')
+ call_command("creatersakey")
self.factory = RequestFactory()
self.user = create_fake_user()
- self.client = create_fake_client(response_type='id_token token')
- self.client_public = create_fake_client(response_type='id_token token', is_public=True)
+ self.client = create_fake_client(response_type="id_token token")
+ self.client_public = create_fake_client(
+ response_type="id_token token", is_public=True
+ )
self.client_public_no_consent = create_fake_client(
- response_type='id_token token', is_public=True,
- require_consent=False)
- self.client_no_access = create_fake_client(response_type='id_token')
- self.client_public_no_access = create_fake_client(response_type='id_token', is_public=True)
+ response_type="id_token token", is_public=True, require_consent=False
+ )
+ self.client_no_access = create_fake_client(response_type="id_token")
+ self.client_public_no_access = create_fake_client(
+ response_type="id_token", is_public=True
+ )
self.client_multiple_response_types = create_fake_client(
- response_type=('id_token', 'id_token token'))
+ response_type=("id_token", "id_token token")
+ )
self.state = uuid.uuid4().hex
self.nonce = uuid.uuid4().hex
@@ -524,16 +553,16 @@ class AuthorizationImplicitFlowTestCase(
The `nonce` parameter is REQUIRED if you use the Implicit Flow.
"""
data = {
- 'client_id': self.client.client_id,
- 'response_type': next(self.client.response_type_values()),
- 'redirect_uri': self.client.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
+ "client_id": self.client.client_id,
+ "response_type": next(self.client.response_type_values()),
+ "redirect_uri": self.client.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
}
- response = self._auth_request('get', data, is_user_authenticated=True)
+ response = self._auth_request("get", data, is_user_authenticated=True)
- self.assertIn('#error=invalid_request', response['Location'])
+ self.assertIn("#error=invalid_request", response["Location"])
def test_idtoken_token_response(self):
"""
@@ -541,29 +570,29 @@ class AuthorizationImplicitFlowTestCase(
and access token as the result of the authorization request.
"""
data = {
- 'client_id': self.client.client_id,
- 'redirect_uri': self.client.default_redirect_uri,
- 'response_type': next(self.client.response_type_values()),
- 'scope': 'openid email',
- 'state': self.state,
- 'nonce': self.nonce,
- 'allow': 'Accept',
+ "client_id": self.client.client_id,
+ "redirect_uri": self.client.default_redirect_uri,
+ "response_type": next(self.client.response_type_values()),
+ "scope": "openid email",
+ "state": self.state,
+ "nonce": self.nonce,
+ "allow": "Accept",
}
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- self.assertIn('access_token', response['Location'])
- self.assertIn('id_token', response['Location'])
+ self.assertIn("access_token", response["Location"])
+ self.assertIn("id_token", response["Location"])
# same for public client
- data['client_id'] = self.client_public.client_id,
- data['redirect_uri'] = self.client_public.default_redirect_uri,
- data['response_type'] = next(self.client_public.response_type_values()),
+ data["client_id"] = (self.client_public.client_id,)
+ data["redirect_uri"] = (self.client_public.default_redirect_uri,)
+ data["response_type"] = (next(self.client_public.response_type_values()),)
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- self.assertIn('access_token', response['Location'])
- self.assertIn('id_token', response['Location'])
+ self.assertIn("access_token", response["Location"])
+ self.assertIn("id_token", response["Location"])
def test_idtoken_response(self):
"""
@@ -571,29 +600,31 @@ class AuthorizationImplicitFlowTestCase(
only an id token as the result of the authorization request.
"""
data = {
- 'client_id': self.client_no_access.client_id,
- 'redirect_uri': self.client_no_access.default_redirect_uri,
- 'response_type': next(self.client_no_access.response_type_values()),
- 'scope': 'openid email',
- 'state': self.state,
- 'nonce': self.nonce,
- 'allow': 'Accept',
+ "client_id": self.client_no_access.client_id,
+ "redirect_uri": self.client_no_access.default_redirect_uri,
+ "response_type": next(self.client_no_access.response_type_values()),
+ "scope": "openid email",
+ "state": self.state,
+ "nonce": self.nonce,
+ "allow": "Accept",
}
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- self.assertNotIn('access_token', response['Location'])
- self.assertIn('id_token', response['Location'])
+ self.assertNotIn("access_token", response["Location"])
+ self.assertIn("id_token", response["Location"])
# same for public client
- data['client_id'] = self.client_public_no_access.client_id,
- data['redirect_uri'] = self.client_public_no_access.default_redirect_uri,
- data['response_type'] = next(self.client_public_no_access.response_type_values()),
+ data["client_id"] = (self.client_public_no_access.client_id,)
+ data["redirect_uri"] = (self.client_public_no_access.default_redirect_uri,)
+ data["response_type"] = (
+ next(self.client_public_no_access.response_type_values()),
+ )
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- self.assertNotIn('access_token', response['Location'])
- self.assertIn('id_token', response['Location'])
+ self.assertNotIn("access_token", response["Location"])
+ self.assertIn("id_token", response["Location"])
def test_idtoken_token_at_hash(self):
"""
@@ -601,25 +632,25 @@ class AuthorizationImplicitFlowTestCase(
`at_hash` in `id_token`.
"""
data = {
- 'client_id': self.client.client_id,
- 'redirect_uri': self.client.default_redirect_uri,
- 'response_type': next(self.client.response_type_values()),
- 'scope': 'openid email',
- 'state': self.state,
- 'nonce': self.nonce,
- 'allow': 'Accept',
+ "client_id": self.client.client_id,
+ "redirect_uri": self.client.default_redirect_uri,
+ "response_type": next(self.client.response_type_values()),
+ "scope": "openid email",
+ "state": self.state,
+ "nonce": self.nonce,
+ "allow": "Accept",
}
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- self.assertIn('id_token', response['Location'])
+ self.assertIn("id_token", response["Location"])
# obtain `id_token` portion of Location
- components = urlsplit(response['Location'])
+ components = urlsplit(response["Location"])
fragment = parse_qs(components[4])
- id_token = JWT().unpack(fragment["id_token"][0].encode('utf-8')).payload()
+ id_token = JWT().unpack(fragment["id_token"][0].encode("utf-8")).payload()
- self.assertIn('at_hash', id_token)
+ self.assertIn("at_hash", id_token)
def test_idtoken_at_hash(self):
"""
@@ -627,74 +658,74 @@ class AuthorizationImplicitFlowTestCase(
`at_hash` in `id_token`.
"""
data = {
- 'client_id': self.client_no_access.client_id,
- 'redirect_uri': self.client_no_access.default_redirect_uri,
- 'response_type': next(self.client_no_access.response_type_values()),
- 'scope': 'openid email',
- 'state': self.state,
- 'nonce': self.nonce,
- 'allow': 'Accept',
+ "client_id": self.client_no_access.client_id,
+ "redirect_uri": self.client_no_access.default_redirect_uri,
+ "response_type": next(self.client_no_access.response_type_values()),
+ "scope": "openid email",
+ "state": self.state,
+ "nonce": self.nonce,
+ "allow": "Accept",
}
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- self.assertIn('id_token', response['Location'])
+ self.assertIn("id_token", response["Location"])
# obtain `id_token` portion of Location
- components = urlsplit(response['Location'])
+ components = urlsplit(response["Location"])
fragment = parse_qs(components[4])
- id_token = JWT().unpack(fragment["id_token"][0].encode('utf-8')).payload()
+ id_token = JWT().unpack(fragment["id_token"][0].encode("utf-8")).payload()
- self.assertNotIn('at_hash', id_token)
+ self.assertNotIn("at_hash", id_token)
def test_public_client_implicit_auto_approval(self):
"""
Public clients using Implicit Flow should be able to reuse consent.
"""
data = {
- 'client_id': self.client_public_no_consent.client_id,
- 'response_type': next(self.client_public_no_consent.response_type_values()),
- 'redirect_uri': self.client_public_no_consent.default_redirect_uri,
- 'scope': 'openid email',
- 'state': self.state,
- 'nonce': self.nonce,
+ "client_id": self.client_public_no_consent.client_id,
+ "response_type": next(self.client_public_no_consent.response_type_values()),
+ "redirect_uri": self.client_public_no_consent.default_redirect_uri,
+ "scope": "openid email",
+ "state": self.state,
+ "nonce": self.nonce,
}
- response = self._auth_request('get', data, is_user_authenticated=True)
- response_text = response.content.decode('utf-8')
- self.assertEquals(response_text, '')
- components = urlsplit(response['Location'])
+ response = self._auth_request("get", data, is_user_authenticated=True)
+ response_text = response.content.decode("utf-8")
+ self.assertEquals(response_text, "")
+ components = urlsplit(response["Location"])
fragment = parse_qs(components[4])
- self.assertIn('access_token', fragment)
- self.assertIn('id_token', fragment)
- self.assertIn('expires_in', fragment)
+ self.assertIn("access_token", fragment)
+ self.assertIn("id_token", fragment)
+ self.assertIn("expires_in", fragment)
def test_multiple_response_types(self):
"""
Clients should be able to be configured for multiple response types.
"""
data = {
- 'client_id': self.client_multiple_response_types.client_id,
- 'redirect_uri': self.client_multiple_response_types.default_redirect_uri,
- 'response_type': 'id_token',
- 'scope': 'openid email',
- 'state': self.state,
- 'nonce': self.nonce,
- 'allow': 'Accept',
+ "client_id": self.client_multiple_response_types.client_id,
+ "redirect_uri": self.client_multiple_response_types.default_redirect_uri,
+ "response_type": "id_token",
+ "scope": "openid email",
+ "state": self.state,
+ "nonce": self.nonce,
+ "allow": "Accept",
}
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- self.assertNotIn('access_token', response['Location'])
- self.assertIn('id_token', response['Location'])
+ self.assertNotIn("access_token", response["Location"])
+ self.assertIn("id_token", response["Location"])
# should also support "id_token token" response_type
- data['response_type'] = 'id_token token'
+ data["response_type"] = "id_token token"
- response = self._auth_request('post', data, is_user_authenticated=True)
+ response = self._auth_request("post", data, is_user_authenticated=True)
- self.assertIn('access_token', response['Location'])
- self.assertIn('id_token', response['Location'])
+ self.assertIn("access_token", response["Location"])
+ self.assertIn("id_token", response["Location"])
class AuthorizationHybridFlowTestCase(TestCase, AuthorizeEndpointMixin):
@@ -703,23 +734,26 @@ class AuthorizationHybridFlowTestCase(Te
"""
def setUp(self):
- call_command('creatersakey')
+ call_command("creatersakey")
self.factory = RequestFactory()
self.user = create_fake_user()
self.client_code_idtoken_token = create_fake_client(
- response_type='code id_token token', is_public=True)
+ response_type="code id_token token", is_public=True
+ )
self.state = uuid.uuid4().hex
self.nonce = uuid.uuid4().hex
# Base data for the auth request.
self.data = {
- 'client_id': self.client_code_idtoken_token.client_id,
- 'redirect_uri': self.client_code_idtoken_token.default_redirect_uri,
- 'response_type': next(self.client_code_idtoken_token.response_type_values()),
- 'scope': 'openid email',
- 'state': self.state,
- 'nonce': self.nonce,
- 'allow': 'Accept',
+ "client_id": self.client_code_idtoken_token.client_id,
+ "redirect_uri": self.client_code_idtoken_token.default_redirect_uri,
+ "response_type": next(
+ self.client_code_idtoken_token.response_type_values()
+ ),
+ "scope": "openid email",
+ "state": self.state,
+ "nonce": self.nonce,
+ "allow": "Accept",
}
def test_code_idtoken_token_response(self):
@@ -727,49 +761,51 @@ class AuthorizationHybridFlowTestCase(Te
Implicit client requesting `id_token token` receives both id token
and access token as the result of the authorization request.
"""
- response = self._auth_request('post', self.data, is_user_authenticated=True)
+ response = self._auth_request("post", self.data, is_user_authenticated=True)
- self.assertIn('#', response['Location'])
- self.assertIn('access_token', response['Location'])
- self.assertIn('id_token', response['Location'])
- self.assertIn('state', response['Location'])
- self.assertIn('code', response['Location'])
+ self.assertIn("#", response["Location"])
+ self.assertIn("access_token", response["Location"])
+ self.assertIn("id_token", response["Location"])
+ self.assertIn("state", response["Location"])
+ self.assertIn("code", response["Location"])
# Validate code.
- is_code_ok = is_code_valid(url=response['Location'],
- user=self.user,
- client=self.client_code_idtoken_token)
- self.assertEqual(is_code_ok, True, msg='Code returned is invalid.')
+ is_code_ok = is_code_valid(
+ url=response["Location"],
+ user=self.user,
+ client=self.client_code_idtoken_token,
+ )
+ self.assertEqual(is_code_ok, True, msg="Code returned is invalid.")
@override_settings(OIDC_TOKEN_EXPIRE=36000)
def test_access_token_expiration(self):
"""
Add ten hours of expiration to access_token. Check for the expires_in query in fragment.
"""
- response = self._auth_request('post', self.data, is_user_authenticated=True)
+ response = self._auth_request("post", self.data, is_user_authenticated=True)
- self.assertIn('expires_in=36000', response['Location'])
+ self.assertIn("expires_in=36000", response["Location"])
class TestCreateResponseURI(TestCase):
def setUp(self):
- url = reverse('oidc_provider:authorize')
+ url = reverse("oidc_provider:authorize")
user = create_fake_user()
- client = create_fake_client(response_type='code', is_public=True)
+ client = create_fake_client(response_type="code", is_public=True)
# Base data to create a uri response
data = {
- 'client_id': client.client_id,
- 'redirect_uri': client.default_redirect_uri,
- 'response_type': next(client.response_type_values()),
+ "client_id": client.client_id,
+ "redirect_uri": client.default_redirect_uri,
+ "response_type": next(client.response_type_values()),
}
factory = RequestFactory()
self.request = factory.post(url, data=data)
self.request.user = user
- @patch('oidc_provider.lib.endpoints.authorize.create_code')
- @patch('oidc_provider.lib.endpoints.authorize.logger.exception')
+ @patch("oidc_provider.lib.endpoints.authorize.create_code")
+ @patch("oidc_provider.lib.endpoints.authorize.logger.exception")
def test_create_response_uri_logs_to_error(self, log_exception, create_code):
"""
A lot can go wrong when creating a response uri and this is caught
@@ -787,10 +823,13 @@ class TestCreateResponseURI(TestCase):
authorization_endpoint.create_response_uri()
log_exception.assert_called_once_with(
- '[Authorize] Error when trying to create response uri: %s', exception)
+ "[Authorize] Error when trying to create response uri: %s", exception
+ )
@override_settings(OIDC_SESSION_MANAGEMENT_ENABLE=True)
- def test_create_response_uri_generates_session_state_if_session_management_enabled(self):
+ def test_create_response_uri_generates_session_state_if_session_management_enabled(
+ self,
+ ):
# RequestFactory doesn't support sessions, so we mock it
self.request.session = mock.Mock(session_key=None)
@@ -798,4 +837,4 @@ class TestCreateResponseURI(TestCase):
authorization_endpoint.validate_params()
uri = authorization_endpoint.create_response_uri()
- self.assertIn('session_state=', uri)
+ self.assertIn("session_state=", uri)
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_claims.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_claims.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_claims.py
@@ -1,86 +1,90 @@
from __future__ import unicode_literals
from django.test import TestCase
-from django.utils.six import text_type
from django.utils.translation import override as override_language
-from oidc_provider.lib.claims import ScopeClaims, StandardScopeClaims, STANDARD_CLAIMS
-from oidc_provider.tests.app.utils import create_fake_user, create_fake_client, create_fake_token
+from oidc_provider.lib.claims import STANDARD_CLAIMS, ScopeClaims, StandardScopeClaims
+from oidc_provider.tests.app.utils import (
+ create_fake_client,
+ create_fake_token,
+ create_fake_user,
+)
class ClaimsTestCase(TestCase):
-
def setUp(self):
self.user = create_fake_user()
- self.scopes = ['openid', 'address', 'email', 'phone', 'profile', 'foo']
- self.client = create_fake_client('code')
+ self.scopes = ["openid", "address", "email", "phone", "profile", "foo"]
+ self.client = create_fake_client("code")
self.token = create_fake_token(self.user, self.scopes, self.client)
self.scopeClaims = ScopeClaims(self.token)
def test_empty_standard_claims(self):
- for v in [v for k, v in STANDARD_CLAIMS.items() if k != 'address']:
- self.assertEqual(v, '')
+ for v in [v for k, v in STANDARD_CLAIMS.items() if k != "address"]:
+ self.assertEqual(v, "")
- for v in STANDARD_CLAIMS['address'].values():
- self.assertEqual(v, '')
+ for v in STANDARD_CLAIMS["address"].values():
+ self.assertEqual(v, "")
def test_clean_dic(self):
- """ assert that _clean_dic function returns a clean dictionnary
- (no empty claims) """
+ """assert that _clean_dic function returns a clean dictionnary
+ (no empty claims)"""
dict_to_clean = {
- 'phone_number_verified': '',
- 'middle_name': '',
- 'name': 'John Doe',
- 'website': '',
- 'profile': '',
- 'family_name': 'Doe',
- 'birthdate': '',
- 'preferred_username': '',
- 'picture': '',
- 'zoneinfo': '',
- 'locale': '',
- 'gender': '',
- 'updated_at': '',
- 'address': {},
- 'given_name': 'John',
- 'email_verified': '',
- 'nickname': '',
- 'email': u'johndoe@example.com',
- 'phone_number': '',
+ "phone_number_verified": "",
+ "middle_name": "",
+ "name": "John Doe",
+ "website": "",
+ "profile": "",
+ "family_name": "Doe",
+ "birthdate": "",
+ "preferred_username": "",
+ "picture": "",
+ "zoneinfo": "",
+ "locale": "",
+ "gender": "",
+ "updated_at": "",
+ "address": {},
+ "given_name": "John",
+ "email_verified": "",
+ "nickname": "",
+ "email": "johndoe@example.com",
+ "phone_number": "",
}
clean_dict = self.scopeClaims._clean_dic(dict_to_clean)
self.assertEquals(
clean_dict,
{
- 'family_name': 'Doe',
- 'given_name': 'John',
- 'name': 'John Doe',
- 'email': u'johndoe@example.com'
- }
+ "family_name": "Doe",
+ "given_name": "John",
+ "name": "John Doe",
+ "email": "johndoe@example.com",
+ },
)
def test_locale(self):
- with override_language('fr'):
- self.assertEqual(text_type(StandardScopeClaims.info_profile[0]), 'Profil de base')
+ with override_language("fr"):
+ self.assertEqual(
+ str(StandardScopeClaims.info_profile[0]), "Profil de base"
+ )
def test_scopeclaims_class_inheritance(self):
# Generate example class that will be used for `OIDC_EXTRA_SCOPE_CLAIMS` setting.
class CustomScopeClaims(ScopeClaims):
- info_foo = ('Title', 'Description')
+ info_foo = ("Title", "Description")
def scope_foo(self):
- dic = {'test': self.user.id}
+ dic = {"test": self.user.id}
return dic
- info_notadd = ('Title', 'Description')
+ info_notadd = ("Title", "Description")
def scope_notadd(self):
- dic = {'test': self.user.id}
+ dic = {"test": self.user.id}
return dic
claims = CustomScopeClaims(self.token)
response = claims.create_response_dic()
- self.assertTrue('test' in response.keys())
- self.assertFalse('notadd' in response.keys())
+ self.assertTrue("test" in response.keys())
+ self.assertFalse("notadd" in response.keys())
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_commands.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_commands.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_commands.py
@@ -1,16 +1,15 @@
from django.core.management import call_command
from django.test import TestCase
-from django.utils.six import StringIO
+from io import StringIO
class CommandsTest(TestCase):
-
def test_creatersakey_output(self):
out = StringIO()
- call_command('creatersakey', stdout=out)
- self.assertIn('RSA key successfully created', out.getvalue())
+ call_command("creatersakey", stdout=out)
+ self.assertIn("RSA key successfully created", out.getvalue())
def test_makemigrations_output(self):
out = StringIO()
- call_command('makemigrations', 'oidc_provider', stdout=out)
- self.assertIn('No changes detected in app', out.getvalue())
+ call_command("makemigrations", "oidc_provider", stdout=out)
+ self.assertIn("No changes detected in app", out.getvalue())
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_end_session_endpoint.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_end_session_endpoint.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_end_session_endpoint.py
@@ -1,21 +1,16 @@
from django.core.management import call_command
+
try:
from django.urls import reverse
except ImportError:
from django.core.urlresolvers import reverse
+
+import mock
from django.test import TestCase
-from oidc_provider.lib.utils.token import (
- create_token,
- create_id_token,
- encode_id_token,
-)
from oidc_provider import settings
-from oidc_provider.tests.app.utils import (
- create_fake_client,
- create_fake_user,
-)
-import mock
+from oidc_provider.lib.utils.token import create_id_token, create_token, encode_id_token
+from oidc_provider.tests.app.utils import create_fake_client, create_fake_user
class EndSessionTestCase(TestCase):
@@ -24,57 +19,60 @@ class EndSessionTestCase(TestCase):
"""
def setUp(self):
- call_command('creatersakey')
+ call_command("creatersakey")
self.user = create_fake_user()
- self.oidc_client = create_fake_client('id_token')
- self.LOGOUT_URL = 'http://example.com/logged-out/'
+ self.oidc_client = create_fake_client("id_token")
+ self.LOGOUT_URL = "http://example.com/logged-out/"
self.oidc_client.post_logout_redirect_uris = [self.LOGOUT_URL]
self.oidc_client.save()
- self.url = reverse('oidc_provider:end-session')
+ self.url = reverse("oidc_provider:end-session")
def test_redirects_when_aud_is_str(self):
query_params = {
- 'post_logout_redirect_uri': self.LOGOUT_URL,
+ "post_logout_redirect_uri": self.LOGOUT_URL,
}
response = self.client.get(self.url, query_params)
# With no id_token the OP MUST NOT redirect to the requested
# redirect_uri.
self.assertRedirects(
- response, settings.get('OIDC_LOGIN_URL'),
- fetch_redirect_response=False)
+ response, settings.get("OIDC_LOGIN_URL"), fetch_redirect_response=False
+ )
token = create_token(self.user, self.oidc_client, [])
id_token_dic = create_id_token(
- token=token, user=self.user, aud=self.oidc_client.client_id)
+ token=token, user=self.user, aud=self.oidc_client.client_id
+ )
id_token = encode_id_token(id_token_dic, self.oidc_client)
- query_params['id_token_hint'] = id_token
+ query_params["id_token_hint"] = id_token
response = self.client.get(self.url, query_params)
- self.assertRedirects(
- response, self.LOGOUT_URL, fetch_redirect_response=False)
+ self.assertRedirects(response, self.LOGOUT_URL, fetch_redirect_response=False)
def test_redirects_when_aud_is_list(self):
"""Check with 'aud' containing a list of str."""
query_params = {
- 'post_logout_redirect_uri': self.LOGOUT_URL,
+ "post_logout_redirect_uri": self.LOGOUT_URL,
}
token = create_token(self.user, self.oidc_client, [])
id_token_dic = create_id_token(
- token=token, user=self.user, aud=self.oidc_client.client_id)
- id_token_dic['aud'] = [id_token_dic['aud']]
+ token=token, user=self.user, aud=self.oidc_client.client_id
+ )
+ id_token_dic["aud"] = [id_token_dic["aud"]]
id_token = encode_id_token(id_token_dic, self.oidc_client)
- query_params['id_token_hint'] = id_token
+ query_params["id_token_hint"] = id_token
response = self.client.get(self.url, query_params)
- self.assertRedirects(
- response, self.LOGOUT_URL, fetch_redirect_response=False)
+ self.assertRedirects(response, self.LOGOUT_URL, fetch_redirect_response=False)
- @mock.patch(settings.get('OIDC_AFTER_END_SESSION_HOOK'))
+ @mock.patch(settings.get("OIDC_AFTER_END_SESSION_HOOK"))
def test_call_post_end_session_hook(self, hook_function):
self.client.get(self.url)
- self.assertTrue(hook_function.called, 'OIDC_AFTER_END_SESSION_HOOK should be called')
+ self.assertTrue(
+ hook_function.called, "OIDC_AFTER_END_SESSION_HOOK should be called"
+ )
self.assertTrue(
hook_function.call_count == 1,
- 'OIDC_AFTER_END_SESSION_HOOK should be called once')
+ "OIDC_AFTER_END_SESSION_HOOK should be called once",
+ )
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_introspection_endpoint.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_introspection_endpoint.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_introspection_endpoint.py
@@ -1,97 +1,101 @@
-import time
import random
+import time
from mock import patch
+
try:
from urllib.parse import urlencode
except ImportError:
from urllib import urlencode
-from django.utils.encoding import force_text
+
from django.core.management import call_command
-from django.test import TestCase, RequestFactory, override_settings
+from django.test import RequestFactory, TestCase, override_settings
from django.utils import timezone
+from django.utils.encoding import force_str
+
try:
from django.urls import reverse
except ImportError:
from django.core.urlresolvers import reverse
+from oidc_provider.lib.utils.token import create_id_token
from oidc_provider.tests.app.utils import (
- create_fake_user,
+ FAKE_RANDOM_STRING,
create_fake_client,
create_fake_token,
- FAKE_RANDOM_STRING)
-from oidc_provider.lib.utils.token import create_id_token
+ create_fake_user,
+)
from oidc_provider.views import TokenIntrospectionView
class IntrospectionTestCase(TestCase):
-
def setUp(self):
- call_command('creatersakey')
+ call_command("creatersakey")
self.factory = RequestFactory()
self.user = create_fake_user()
- self.aud = 'testaudience'
- self.client = create_fake_client(response_type='id_token token')
- self.resource = create_fake_client(response_type='id_token token')
- self.resource.scope = ['token_introspection', self.aud]
+ self.aud = "testaudience"
+ self.client = create_fake_client(response_type="id_token token")
+ self.resource = create_fake_client(response_type="id_token token")
+ self.resource.scope = ["token_introspection", self.aud]
self.resource.save()
self.token = create_fake_token(self.user, self.client.scope, self.client)
self.token.access_token = str(random.randint(1, 999999)).zfill(6)
self.now = time.time()
- with patch('oidc_provider.lib.utils.token.time.time') as time_func:
+ with patch("oidc_provider.lib.utils.token.time.time") as time_func:
time_func.return_value = self.now
self.token.id_token = create_id_token(self.token, self.user, self.aud)
self.token.save()
def _assert_inactive(self, response):
self.assertEqual(response.status_code, 200)
- self.assertJSONEqual(force_text(response.content), {'active': False})
+ self.assertJSONEqual(force_str(response.content), {"active": False})
def _assert_active(self, response, **kwargs):
self.assertEqual(response.status_code, 200)
expected_content = {
- 'active': True,
- 'aud': self.aud,
- 'client_id': self.client.client_id,
- 'sub': str(self.user.pk),
- 'iat': int(self.now),
- 'exp': int(self.now + 600),
- 'iss': 'http://localhost:8000/openid',
+ "active": True,
+ "aud": self.aud,
+ "client_id": self.client.client_id,
+ "sub": str(self.user.pk),
+ "iat": int(self.now),
+ "exp": int(self.now + 600),
+ "iss": "http://localhost:8000/openid",
}
expected_content.update(kwargs)
- self.assertJSONEqual(force_text(response.content), expected_content)
+ self.assertJSONEqual(force_str(response.content), expected_content)
def _make_request(self, **kwargs):
- url = reverse('oidc_provider:token-introspection')
+ url = reverse("oidc_provider:token-introspection")
data = {
- 'client_id': kwargs.get('client_id', self.resource.client_id),
- 'client_secret': kwargs.get('client_secret', self.resource.client_secret),
- 'token': kwargs.get('access_token', self.token.access_token),
+ "client_id": kwargs.get("client_id", self.resource.client_id),
+ "client_secret": kwargs.get("client_secret", self.resource.client_secret),
+ "token": kwargs.get("access_token", self.token.access_token),
}
- request = self.factory.post(url, data=urlencode(data),
- content_type='application/x-www-form-urlencoded')
+ request = self.factory.post(
+ url, data=urlencode(data), content_type="application/x-www-form-urlencoded"
+ )
return TokenIntrospectionView.as_view()(request)
def test_no_client_params_returns_inactive(self):
- response = self._make_request(client_id='')
+ response = self._make_request(client_id="")
self._assert_inactive(response)
def test_no_client_secret_returns_inactive(self):
- response = self._make_request(client_secret='')
+ response = self._make_request(client_secret="")
self._assert_inactive(response)
def test_invalid_client_returns_inactive(self):
- response = self._make_request(client_id='invalid')
+ response = self._make_request(client_id="invalid")
self._assert_inactive(response)
def test_token_not_found_returns_inactive(self):
- response = self._make_request(access_token='invalid')
+ response = self._make_request(access_token="invalid")
self._assert_inactive(response)
def test_scope_no_audience_returns_inactive(self):
- self.resource.scope = ['token_introspection']
+ self.resource.scope = ["token_introspection"]
self.resource.save()
response = self._make_request()
self._assert_inactive(response)
@@ -106,14 +110,18 @@ class IntrospectionTestCase(TestCase):
response = self._make_request()
self._assert_active(response)
- @override_settings(OIDC_INTROSPECTION_PROCESSING_HOOK='oidc_provider.tests.app.utils.fake_introspection_processing_hook') # NOQA
+ @override_settings(
+ OIDC_INTROSPECTION_PROCESSING_HOOK="oidc_provider.tests.app.utils.fake_introspection_processing_hook"
+ ) # NOQA
def test_custom_introspection_hook_called_on_valid_request(self):
response = self._make_request()
- self._assert_active(response, test_introspection_processing_hook=FAKE_RANDOM_STRING)
+ self._assert_active(
+ response, test_introspection_processing_hook=FAKE_RANDOM_STRING
+ )
@override_settings(OIDC_INTROSPECTION_VALIDATE_AUDIENCE_SCOPE=False)
def test_disable_audience_validation(self):
- self.resource.scope = ['token_introspection']
+ self.resource.scope = ["token_introspection"]
self.resource.save()
response = self._make_request()
self._assert_active(response)
@@ -122,11 +130,14 @@ class IntrospectionTestCase(TestCase):
def test_valid_client_grant_token_without_aud_validation(self):
self.token.id_token = None # client_credentials tokens do not have id_token
self.token.save()
- self.resource.scope = ['token_introspection']
+ self.resource.scope = ["token_introspection"]
self.resource.save()
response = self._make_request()
self.assertEqual(response.status_code, 200)
- self.assertJSONEqual(force_text(response.content), {
- 'active': True,
- 'client_id': self.client.client_id,
- })
+ self.assertJSONEqual(
+ force_str(response.content),
+ {
+ "active": True,
+ "client_id": self.client.client_id,
+ },
+ )
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_middleware.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_middleware.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_middleware.py
@@ -1,7 +1,7 @@
try:
from django.urls import url
except ImportError:
- from django.conf.urls import url
+ from django.urls import path
from django.test import TestCase, override_settings
from django.views.generic import View
from mock import mock
@@ -11,33 +11,40 @@ class StubbedViews:
class SampleView(View):
pass
- urlpatterns = [url('^test/', SampleView.as_view())]
+ urlpatterns = [path("test/", SampleView.as_view())]
-MW_CLASSES = ('django.contrib.sessions.middleware.SessionMiddleware',
- 'oidc_provider.middleware.SessionManagementMiddleware')
+MW_CLASSES = (
+ "django.contrib.sessions.middleware.SessionMiddleware",
+ "oidc_provider.middleware.SessionManagementMiddleware",
+)
-@override_settings(ROOT_URLCONF=StubbedViews,
- MIDDLEWARE=MW_CLASSES,
- MIDDLEWARE_CLASSES=MW_CLASSES,
- OIDC_SESSION_MANAGEMENT_ENABLE=True)
+@override_settings(
+ ROOT_URLCONF=StubbedViews,
+ MIDDLEWARE=MW_CLASSES,
+ MIDDLEWARE_CLASSES=MW_CLASSES,
+ OIDC_SESSION_MANAGEMENT_ENABLE=True,
+)
class MiddlewareTestCase(TestCase):
-
def setUp(self):
- patcher = mock.patch('oidc_provider.middleware.get_browser_state_or_default')
+ patcher = mock.patch("oidc_provider.middleware.get_browser_state_or_default")
self.mock_get_state = patcher.start()
def test_session_management_middleware_sets_cookie_on_response(self):
- response = self.client.get('/test/')
+ response = self.client.get("/test/")
- self.assertIn('op_browser_state', response.cookies)
- self.assertEqual(response.cookies['op_browser_state'].value,
- str(self.mock_get_state.return_value))
+ self.assertIn("op_browser_state", response.cookies)
+ self.assertEqual(
+ response.cookies["op_browser_state"].value,
+ str(self.mock_get_state.return_value),
+ )
self.mock_get_state.assert_called_once_with(response.wsgi_request)
@override_settings(OIDC_SESSION_MANAGEMENT_ENABLE=False)
- def test_session_management_middleware_does_not_set_cookie_if_session_management_disabled(self):
- response = self.client.get('/test/')
+ def test_session_management_middleware_does_not_set_cookie_if_session_management_disabled(
+ self,
+ ):
+ response = self.client.get("/test/")
- self.assertNotIn('op_browser_state', response.cookies)
+ self.assertNotIn("op_browser_state", response.cookies)
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_provider_info_endpoint.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_provider_info_endpoint.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_provider_info_endpoint.py
@@ -2,14 +2,13 @@ try:
from django.urls import reverse
except ImportError:
from django.core.urlresolvers import reverse
-from django.test import RequestFactory
-from django.test import TestCase
+
+from django.test import RequestFactory, TestCase
from oidc_provider.views import ProviderInfoView
class ProviderInfoTestCase(TestCase):
-
def setUp(self):
self.factory = RequestFactory()
@@ -18,12 +17,12 @@ class ProviderInfoTestCase(TestCase):
See if the endpoint is returning the corresponding
server information by checking status, content type, etc.
"""
- url = reverse('oidc_provider:provider-info')
+ url = reverse("oidc_provider:provider-info")
request = self.factory.get(url)
response = ProviderInfoView.as_view()(request)
self.assertEqual(response.status_code, 200)
- self.assertEqual(response['Content-Type'] == 'application/json', True)
+ self.assertEqual(response["Content-Type"] == "application/json", True)
self.assertEqual(bool(response.content), True)
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_settings.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_settings.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_settings.py
@@ -2,28 +2,24 @@ from django.test import TestCase, overri
from oidc_provider import settings
-CUSTOM_TEMPLATES = {
- 'authorize': 'custom/authorize.html',
- 'error': 'custom/error.html'
-}
+CUSTOM_TEMPLATES = {"authorize": "custom/authorize.html", "error": "custom/error.html"}
class SettingsTest(TestCase):
-
@override_settings(OIDC_TEMPLATES=CUSTOM_TEMPLATES)
def test_override_templates(self):
- self.assertEqual(settings.get('OIDC_TEMPLATES'), CUSTOM_TEMPLATES)
+ self.assertEqual(settings.get("OIDC_TEMPLATES"), CUSTOM_TEMPLATES)
def test_unauthenticated_session_management_key_has_default(self):
- key = settings.get('OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY')
- self.assertRegexpMatches(key, r'[a-zA-Z0-9]+')
+ key = settings.get("OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY")
+ self.assertRegexpMatches(key, r"[a-zA-Z0-9]+")
self.assertGreater(len(key), 50)
def test_unauthenticated_session_management_key_has_constant_value(self):
- key1 = settings.get('OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY')
- key2 = settings.get('OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY')
+ key1 = settings.get("OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY")
+ key2 = settings.get("OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY")
self.assertEqual(key1, key2)
@override_settings(OIDC_INTROSPECTION_VALIDATE_AUDIENCE_SCOPE=False)
def test_can_override_with_false_value(self):
- self.assertFalse(settings.get('OIDC_INTROSPECTION_VALIDATE_AUDIENCE_SCOPE'))
+ self.assertFalse(settings.get("OIDC_INTROSPECTION_VALIDATE_AUDIENCE_SCOPE"))
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_token_endpoint.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_token_endpoint.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_token_endpoint.py
@@ -1,7 +1,6 @@
import json
import time
import uuid
-
from base64 import b64encode
try:
@@ -11,15 +10,13 @@ except ImportError:
from django.core.management import call_command
from django.http import JsonResponse
+
try:
from django.urls import reverse
except ImportError:
from django.core.urlresolvers import reverse
-from django.test import (
- RequestFactory,
- override_settings,
-)
-from django.test import TestCase
+
+from django.test import RequestFactory, TestCase, override_settings
from django.views.decorators.http import require_http_methods
from jwkest.jwk import KEYS
from jwkest.jws import JWS
@@ -31,18 +28,14 @@ from oidc_provider.lib.utils.oauth2 impo
from oidc_provider.lib.utils.token import create_code
from oidc_provider.models import Token
from oidc_provider.tests.app.utils import (
- create_fake_user,
- create_fake_client,
FAKE_CODE_CHALLENGE,
FAKE_CODE_VERIFIER,
FAKE_NONCE,
FAKE_RANDOM_STRING,
+ create_fake_client,
+ create_fake_user,
)
-from oidc_provider.views import (
- JwksView,
- TokenView,
- userinfo,
-)
+from oidc_provider.views import JwksView, TokenView, userinfo
class TokenTestCase(TestCase):
@@ -53,21 +46,21 @@ class TokenTestCase(TestCase):
"""
def setUp(self):
- call_command('creatersakey')
+ call_command("creatersakey")
self.factory = RequestFactory()
self.user = create_fake_user()
self.request_client = self.client
- self.client = create_fake_client(response_type='code')
+ self.client = create_fake_client(response_type="code")
def _password_grant_post_data(self, scope=None):
result = {
- 'username': 'johndoe',
- 'password': '1234',
- 'grant_type': 'password',
- 'scope': 'openid email',
+ "username": "johndoe",
+ "password": "1234",
+ "grant_type": "password",
+ "scope": "openid email",
}
if scope is not None:
- result['scope'] = ' '.join(scope)
+ result["scope"] = " ".join(scope)
return result
def _auth_code_post_data(self, code, scope=None):
@@ -75,15 +68,15 @@ class TokenTestCase(TestCase):
All the data that will be POSTed to the Token Endpoint.
"""
post_data = {
- 'client_id': self.client.client_id,
- 'client_secret': self.client.client_secret,
- 'redirect_uri': self.client.default_redirect_uri,
- 'grant_type': 'authorization_code',
- 'code': code,
- 'state': uuid.uuid4().hex,
+ "client_id": self.client.client_id,
+ "client_secret": self.client.client_secret,
+ "redirect_uri": self.client.default_redirect_uri,
+ "grant_type": "authorization_code",
+ "code": code,
+ "state": uuid.uuid4().hex,
}
if scope is not None:
- post_data['scope'] = ' '.join(scope)
+ post_data["scope"] = " ".join(scope)
return post_data
@@ -92,13 +85,13 @@ class TokenTestCase(TestCase):
All the data that will be POSTed to the Token Endpoint.
"""
post_data = {
- 'client_id': self.client.client_id,
- 'client_secret': self.client.client_secret,
- 'grant_type': 'refresh_token',
- 'refresh_token': refresh_token,
+ "client_id": self.client.client_id,
+ "client_secret": self.client.client_secret,
+ "grant_type": "refresh_token",
+ "refresh_token": refresh_token,
}
if scope is not None:
- post_data['scope'] = ' '.join(scope)
+ post_data["scope"] = " ".join(scope)
return post_data
@@ -108,13 +101,14 @@ class TokenTestCase(TestCase):
`post_data` parameters using the 'application/x-www-form-urlencoded'
format.
"""
- url = reverse('oidc_provider:token')
+ url = reverse("oidc_provider:token")
request = self.factory.post(
url,
data=urlencode(post_data),
- content_type='application/x-www-form-urlencoded',
- **extras)
+ content_type="application/x-www-form-urlencoded",
+ **extras
+ )
response = TokenView.as_view()(request)
@@ -127,9 +121,10 @@ class TokenTestCase(TestCase):
code = create_code(
user=self.user,
client=self.client,
- scope=(scope if scope else ['openid', 'email']),
+ scope=(scope if scope else ["openid", "email"]),
nonce=FAKE_NONCE,
- is_authentication=True)
+ is_authentication=True,
+ )
code.save()
return code
@@ -138,137 +133,136 @@ class TokenTestCase(TestCase):
"""
Get public key from discovery.
"""
- request = self.factory.get(reverse('oidc_provider:jwks'))
+ request = self.factory.get(reverse("oidc_provider:jwks"))
response = JwksView.as_view()(request)
- jwks_dic = json.loads(response.content.decode('utf-8'))
+ jwks_dic = json.loads(response.content.decode("utf-8"))
SIGKEYS = KEYS()
SIGKEYS.load_dict(jwks_dic)
return SIGKEYS
def _get_userinfo(self, access_token):
- url = reverse('oidc_provider:userinfo')
+ url = reverse("oidc_provider:userinfo")
request = self.factory.get(url)
- request.META['HTTP_AUTHORIZATION'] = 'Bearer ' + access_token
+ request.META["HTTP_AUTHORIZATION"] = "Bearer " + access_token
return userinfo(request)
def _password_grant_auth_header(self):
- user_pass = self.client.client_id + ':' + self.client.client_secret
- auth = b'Basic ' + b64encode(user_pass.encode('utf-8'))
- auth_header = {'HTTP_AUTHORIZATION': auth.decode('utf-8')}
+ user_pass = self.client.client_id + ":" + self.client.client_secret
+ auth = b"Basic " + b64encode(user_pass.encode("utf-8"))
+ auth_header = {"HTTP_AUTHORIZATION": auth.decode("utf-8")}
return auth_header
def test_default_setting_does_not_allow_grant_type_password(self):
post_data = self._password_grant_post_data()
response = self._post_request(
- post_data=post_data,
- extras=self._password_grant_auth_header()
+ post_data=post_data, extras=self._password_grant_auth_header()
)
- response_dict = json.loads(response.content.decode('utf-8'))
+ response_dict = json.loads(response.content.decode("utf-8"))
self.assertEqual(400, response.status_code)
- self.assertEqual('unsupported_grant_type', response_dict['error'])
+ self.assertEqual("unsupported_grant_type", response_dict["error"])
@override_settings(OIDC_GRANT_TYPE_PASSWORD_ENABLE=True)
def test_password_grant_get_access_token_without_scope(self):
post_data = self._password_grant_post_data()
- del (post_data['scope'])
+ del post_data["scope"]
response = self._post_request(
- post_data=post_data,
- extras=self._password_grant_auth_header()
+ post_data=post_data, extras=self._password_grant_auth_header()
)
- response_dict = json.loads(response.content.decode('utf-8'))
- self.assertIn('access_token', response_dict)
+ response_dict = json.loads(response.content.decode("utf-8"))
+ self.assertIn("access_token", response_dict)
@override_settings(OIDC_GRANT_TYPE_PASSWORD_ENABLE=True)
def test_password_grant_get_access_token_with_scope(self):
response = self._post_request(
post_data=self._password_grant_post_data(),
- extras=self._password_grant_auth_header()
+ extras=self._password_grant_auth_header(),
)
- response_dict = json.loads(response.content.decode('utf-8'))
- self.assertIn('access_token', response_dict)
+ response_dict = json.loads(response.content.decode("utf-8"))
+ self.assertIn("access_token", response_dict)
@override_settings(OIDC_GRANT_TYPE_PASSWORD_ENABLE=True)
def test_password_grant_get_access_token_invalid_user_credentials(self):
invalid_post = self._password_grant_post_data()
- invalid_post['password'] = 'wrong!'
+ invalid_post["password"] = "wrong!"
response = self._post_request(
- post_data=invalid_post,
- extras=self._password_grant_auth_header()
+ post_data=invalid_post, extras=self._password_grant_auth_header()
)
- response_dict = json.loads(response.content.decode('utf-8'))
+ response_dict = json.loads(response.content.decode("utf-8"))
self.assertEqual(403, response.status_code)
- self.assertEqual('access_denied', response_dict['error'])
+ self.assertEqual("access_denied", response_dict["error"])
def test_password_grant_get_access_token_invalid_client_credentials(self):
- self.client.client_id = 'foo'
- self.client.client_secret = 'bar'
+ self.client.client_id = "foo"
+ self.client.client_secret = "bar"
response = self._post_request(
post_data=self._password_grant_post_data(),
- extras=self._password_grant_auth_header()
+ extras=self._password_grant_auth_header(),
)
- response_dict = json.loads(response.content.decode('utf-8'))
+ response_dict = json.loads(response.content.decode("utf-8"))
self.assertEqual(400, response.status_code)
- self.assertEqual('invalid_client', response_dict['error'])
+ self.assertEqual("invalid_client", response_dict["error"])
def test_password_grant_full_response(self):
- self.check_password_grant(scope=['openid', 'email'])
+ self.check_password_grant(scope=["openid", "email"])
def test_password_grant_scope(self):
- self.check_password_grant(scope=['openid', 'profile'])
+ self.check_password_grant(scope=["openid", "profile"])
- @override_settings(OIDC_TOKEN_EXPIRE=120,
- OIDC_GRANT_TYPE_PASSWORD_ENABLE=True)
+ @override_settings(OIDC_TOKEN_EXPIRE=120, OIDC_GRANT_TYPE_PASSWORD_ENABLE=True)
def check_password_grant(self, scope):
response = self._post_request(
post_data=self._password_grant_post_data(scope),
- extras=self._password_grant_auth_header()
+ extras=self._password_grant_auth_header(),
)
- response_dict = json.loads(response.content.decode('utf-8'))
+ response_dict = json.loads(response.content.decode("utf-8"))
id_token = JWS().verify_compact(
- response_dict['id_token'].encode('utf-8'), self._get_keys())
+ response_dict["id_token"].encode("utf-8"), self._get_keys()
+ )
token = Token.objects.get(user=self.user)
- self.assertEqual(response_dict['access_token'], token.access_token)
- self.assertEqual(response_dict['refresh_token'], token.refresh_token)
- self.assertEqual(response_dict['expires_in'], 120)
- self.assertEqual(response_dict['token_type'], 'bearer')
- self.assertEqual(id_token['sub'], str(self.user.id))
- self.assertEqual(id_token['aud'], self.client.client_id)
+ self.assertEqual(response_dict["access_token"], token.access_token)
+ self.assertEqual(response_dict["refresh_token"], token.refresh_token)
+ self.assertEqual(response_dict["expires_in"], 120)
+ self.assertEqual(response_dict["token_type"], "bearer")
+ self.assertEqual(id_token["sub"], str(self.user.id))
+ self.assertEqual(id_token["aud"], self.client.client_id)
# Check the scope is honored by checking the claims in the userinfo
- userinfo_response = self._get_userinfo(response_dict['access_token'])
- userinfo = json.loads(userinfo_response.content.decode('utf-8'))
+ userinfo_response = self._get_userinfo(response_dict["access_token"])
+ userinfo = json.loads(userinfo_response.content.decode("utf-8"))
- for (scope_param, claim) in [('email', 'email'), ('profile', 'name')]:
+ for (scope_param, claim) in [("email", "email"), ("profile", "name")]:
if scope_param in scope:
self.assertIn(claim, userinfo)
else:
self.assertNotIn(claim, userinfo)
- @override_settings(OIDC_GRANT_TYPE_PASSWORD_ENABLE=True,
- AUTHENTICATION_BACKENDS=("oidc_provider.tests.app.utils.TestAuthBackend",))
+ @override_settings(
+ OIDC_GRANT_TYPE_PASSWORD_ENABLE=True,
+ AUTHENTICATION_BACKENDS=("oidc_provider.tests.app.utils.TestAuthBackend",),
+ )
def test_password_grant_passes_request_to_backend(self):
response = self._post_request(
post_data=self._password_grant_post_data(),
- extras=self._password_grant_auth_header()
+ extras=self._password_grant_auth_header(),
)
- response_dict = json.loads(response.content.decode('utf-8'))
- self.assertIn('access_token', response_dict)
+ response_dict = json.loads(response.content.decode("utf-8"))
+ self.assertIn("access_token", response_dict)
@override_settings(OIDC_TOKEN_EXPIRE=720)
def test_authorization_code(self):
@@ -283,49 +277,51 @@ class TokenTestCase(TestCase):
post_data = self._auth_code_post_data(code=code.code)
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
+ response_dic = json.loads(response.content.decode("utf-8"))
- id_token = JWS().verify_compact(response_dic['id_token'].encode('utf-8'), SIGKEYS)
+ id_token = JWS().verify_compact(
+ response_dic["id_token"].encode("utf-8"), SIGKEYS
+ )
token = Token.objects.get(user=self.user)
- self.assertEqual(response_dic['access_token'], token.access_token)
- self.assertEqual(response_dic['refresh_token'], token.refresh_token)
- self.assertEqual(response_dic['token_type'], 'bearer')
- self.assertEqual(response_dic['expires_in'], 720)
- self.assertEqual(id_token['sub'], str(self.user.id))
- self.assertEqual(id_token['aud'], self.client.client_id)
+ self.assertEqual(response_dic["access_token"], token.access_token)
+ self.assertEqual(response_dic["refresh_token"], token.refresh_token)
+ self.assertEqual(response_dic["token_type"], "bearer")
+ self.assertEqual(response_dic["expires_in"], 720)
+ self.assertEqual(id_token["sub"], str(self.user.id))
+ self.assertEqual(id_token["aud"], self.client.client_id)
- @override_settings(OIDC_TOKEN_EXPIRE=720,
- OIDC_IDTOKEN_INCLUDE_CLAIMS=True)
+ @override_settings(OIDC_TOKEN_EXPIRE=720, OIDC_IDTOKEN_INCLUDE_CLAIMS=True)
def test_scope_is_ignored_for_auth_code(self):
"""
Scope is ignored for token respones to auth code grant type.
This comes down to that the scopes requested in authorize are returned.
"""
SIGKEYS = self._get_keys()
- for code_scope in [['openid'], ['openid', 'email'], ['openid', 'profile']]:
+ for code_scope in [["openid"], ["openid", "email"], ["openid", "profile"]]:
code = self._create_code(code_scope)
- post_data = self._auth_code_post_data(
- code=code.code, scope=code_scope)
+ post_data = self._auth_code_post_data(code=code.code, scope=code_scope)
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
+ response_dic = json.loads(response.content.decode("utf-8"))
self.assertEqual(response.status_code, 200)
- id_token = JWS().verify_compact(response_dic['id_token'].encode('utf-8'), SIGKEYS)
-
- if 'email' in code_scope:
- self.assertIn('email', id_token)
- self.assertIn('email_verified', id_token)
+ id_token = JWS().verify_compact(
+ response_dic["id_token"].encode("utf-8"), SIGKEYS
+ )
+
+ if "email" in code_scope:
+ self.assertIn("email", id_token)
+ self.assertIn("email_verified", id_token)
else:
- self.assertNotIn('email', id_token)
+ self.assertNotIn("email", id_token)
- if 'profile' in code_scope:
- self.assertIn('given_name', id_token)
+ if "profile" in code_scope:
+ self.assertIn("given_name", id_token)
else:
- self.assertNotIn('given_name', id_token)
+ self.assertNotIn("given_name", id_token)
def test_refresh_token(self):
"""
@@ -343,7 +339,7 @@ class TokenTestCase(TestCase):
though the original authorized scope in the authorization code
request is only ['openid', 'email'].
"""
- self.do_refresh_token_check(scope=['openid', 'profile'])
+ self.do_refresh_token_check(scope=["openid", "profile"])
def test_refresh_token_narrowed_scope(self):
"""
@@ -353,7 +349,7 @@ class TokenTestCase(TestCase):
though the original authorized scope in the authorization code
request is ['openid', 'email'].
"""
- self.do_refresh_token_check(scope=['openid'])
+ self.do_refresh_token_check(scope=["openid"])
@override_settings(OIDC_IDTOKEN_INCLUDE_CLAIMS=True)
def do_refresh_token_check(self, scope=None):
@@ -361,73 +357,84 @@ class TokenTestCase(TestCase):
# Retrieve refresh token
code = self._create_code()
- self.assertEqual(code.scope, ['openid', 'email'])
+ self.assertEqual(code.scope, ["openid", "email"])
post_data = self._auth_code_post_data(code=code.code)
start_time = time.time()
- with patch('oidc_provider.lib.utils.token.time.time') as time_func:
+ with patch("oidc_provider.lib.utils.token.time.time") as time_func:
time_func.return_value = start_time
response = self._post_request(post_data)
- response_dic1 = json.loads(response.content.decode('utf-8'))
- id_token1 = JWS().verify_compact(response_dic1['id_token'].encode('utf-8'), SIGKEYS)
+ response_dic1 = json.loads(response.content.decode("utf-8"))
+ id_token1 = JWS().verify_compact(
+ response_dic1["id_token"].encode("utf-8"), SIGKEYS
+ )
# Use refresh token to obtain new token
- post_data = self._refresh_token_post_data(
- response_dic1['refresh_token'], scope)
- with patch('oidc_provider.lib.utils.token.time.time') as time_func:
+ post_data = self._refresh_token_post_data(response_dic1["refresh_token"], scope)
+ with patch("oidc_provider.lib.utils.token.time.time") as time_func:
time_func.return_value = start_time + 600
response = self._post_request(post_data)
- response_dic2 = json.loads(response.content.decode('utf-8'))
+ response_dic2 = json.loads(response.content.decode("utf-8"))
if scope and set(scope) - set(code.scope): # too broad scope
self.assertEqual(response.status_code, 400) # Bad Request
- self.assertIn('error', response_dic2)
- self.assertEqual(response_dic2['error'], 'invalid_scope')
+ self.assertIn("error", response_dic2)
+ self.assertEqual(response_dic2["error"], "invalid_scope")
return # No more checks
- id_token2 = JWS().verify_compact(response_dic2['id_token'].encode('utf-8'), SIGKEYS)
+ id_token2 = JWS().verify_compact(
+ response_dic2["id_token"].encode("utf-8"), SIGKEYS
+ )
- if scope and 'email' not in scope: # narrowed scope The auth
+ if scope and "email" not in scope: # narrowed scope The auth
# The auth code request had email in scope, so it should be
# in the first id token
- self.assertIn('email', id_token1)
+ self.assertIn("email", id_token1)
# but the refresh request had no email in scope
- self.assertNotIn('email', id_token2, 'email was not requested')
+ self.assertNotIn("email", id_token2, "email was not requested")
- self.assertNotEqual(response_dic1['id_token'], response_dic2['id_token'])
- self.assertNotEqual(response_dic1['access_token'], response_dic2['access_token'])
- self.assertNotEqual(response_dic1['refresh_token'], response_dic2['refresh_token'])
+ self.assertNotEqual(response_dic1["id_token"], response_dic2["id_token"])
+ self.assertNotEqual(
+ response_dic1["access_token"], response_dic2["access_token"]
+ )
+ self.assertNotEqual(
+ response_dic1["refresh_token"], response_dic2["refresh_token"]
+ )
# http://openid.net/specs/openid-connect-core-1_0.html#rfc.section.12.2
- self.assertEqual(id_token1['iss'], id_token2['iss'])
- self.assertEqual(id_token1['sub'], id_token2['sub'])
- self.assertNotEqual(id_token1['iat'], id_token2['iat'])
- self.assertEqual(id_token1['iat'], int(start_time))
- self.assertEqual(id_token2['iat'], int(start_time + 600))
- self.assertEqual(id_token1['aud'], id_token2['aud'])
- self.assertEqual(id_token1['auth_time'], id_token2['auth_time'])
- self.assertEqual(id_token1.get('azp'), id_token2.get('azp'))
+ self.assertEqual(id_token1["iss"], id_token2["iss"])
+ self.assertEqual(id_token1["sub"], id_token2["sub"])
+ self.assertNotEqual(id_token1["iat"], id_token2["iat"])
+ self.assertEqual(id_token1["iat"], int(start_time))
+ self.assertEqual(id_token2["iat"], int(start_time + 600))
+ self.assertEqual(id_token1["aud"], id_token2["aud"])
+ self.assertEqual(id_token1["auth_time"], id_token2["auth_time"])
+ self.assertEqual(id_token1.get("azp"), id_token2.get("azp"))
# Refresh token can't be reused
- post_data = self._refresh_token_post_data(response_dic1['refresh_token'])
+ post_data = self._refresh_token_post_data(response_dic1["refresh_token"])
response = self._post_request(post_data)
- self.assertIn('invalid_grant', response.content.decode('utf-8'))
+ self.assertIn("invalid_grant", response.content.decode("utf-8"))
# Old access token is invalidated
- self.assertEqual(self._get_userinfo(response_dic1['access_token']).status_code, 401)
- self.assertEqual(self._get_userinfo(response_dic2['access_token']).status_code, 200)
+ self.assertEqual(
+ self._get_userinfo(response_dic1["access_token"]).status_code, 401
+ )
+ self.assertEqual(
+ self._get_userinfo(response_dic2["access_token"]).status_code, 200
+ )
# Empty refresh token is invalid
- post_data = self._refresh_token_post_data('')
+ post_data = self._refresh_token_post_data("")
response = self._post_request(post_data)
- self.assertIn('invalid_grant', response.content.decode('utf-8'))
+ self.assertIn("invalid_grant", response.content.decode("utf-8"))
# No refresh token is invalid
- post_data = self._refresh_token_post_data('')
- del post_data['refresh_token']
+ post_data = self._refresh_token_post_data("")
+ del post_data["refresh_token"]
response = self._post_request(post_data)
- self.assertIn('invalid_grant', response.content.decode('utf-8'))
+ self.assertIn("invalid_grant", response.content.decode("utf-8"))
def test_client_redirect_uri(self):
"""
@@ -440,29 +447,29 @@ class TokenTestCase(TestCase):
post_data = self._auth_code_post_data(code=code.code)
# Unregistered URI
- post_data['redirect_uri'] = 'http://invalid.example.org'
+ post_data["redirect_uri"] = "http://invalid.example.org"
response = self._post_request(post_data)
- self.assertIn('invalid_client', response.content.decode('utf-8'))
+ self.assertIn("invalid_client", response.content.decode("utf-8"))
# Registered URI, but with query string appended
- post_data['redirect_uri'] = self.client.default_redirect_uri + '?foo=bar'
+ post_data["redirect_uri"] = self.client.default_redirect_uri + "?foo=bar"
response = self._post_request(post_data)
- self.assertIn('invalid_client', response.content.decode('utf-8'))
+ self.assertIn("invalid_client", response.content.decode("utf-8"))
# Registered URI
- post_data['redirect_uri'] = self.client.default_redirect_uri
+ post_data["redirect_uri"] = self.client.default_redirect_uri
response = self._post_request(post_data)
- self.assertNotIn('invalid_client', response.content.decode('utf-8'))
+ self.assertNotIn("invalid_client", response.content.decode("utf-8"))
def test_request_methods(self):
"""
Client sends an HTTP POST request to the Token Endpoint. Other request
methods MUST NOT be allowed.
"""
- url = reverse('oidc_provider:token')
+ url = reverse("oidc_provider:token")
requests = [
self.factory.get(url),
@@ -474,16 +481,20 @@ class TokenTestCase(TestCase):
response = TokenView.as_view()(request)
self.assertEqual(
- response.status_code, 405,
- msg=request.method + ' request does not return a 405 status.')
+ response.status_code,
+ 405,
+ msg=request.method + " request does not return a 405 status.",
+ )
request = self.factory.post(url)
response = TokenView.as_view()(request)
self.assertEqual(
- response.status_code, 400,
- msg=request.method + ' request does not return a 400 status.')
+ response.status_code,
+ 400,
+ msg=request.method + " request does not return a 400 status.",
+ )
def test_client_authentication(self):
"""
@@ -501,42 +512,47 @@ class TokenTestCase(TestCase):
response = self._post_request(post_data)
self.assertNotIn(
- 'invalid_client',
- response.content.decode('utf-8'),
- msg='Client authentication fails using request-body credentials.')
+ "invalid_client",
+ response.content.decode("utf-8"),
+ msg="Client authentication fails using request-body credentials.",
+ )
# Now, test with an invalid client_id.
invalid_data = post_data.copy()
- invalid_data['client_id'] = self.client.client_id * 2 # Fake id.
+ invalid_data["client_id"] = self.client.client_id * 2 # Fake id.
# Create another grant code.
code = self._create_code()
- invalid_data['code'] = code.code
+ invalid_data["code"] = code.code
response = self._post_request(invalid_data)
self.assertIn(
- 'invalid_client',
- response.content.decode('utf-8'),
- msg='Client authentication success with an invalid "client_id".')
+ "invalid_client",
+ response.content.decode("utf-8"),
+ msg='Client authentication success with an invalid "client_id".',
+ )
# Now, test using HTTP Basic Authentication method.
basicauth_data = post_data.copy()
# Create another grant code.
code = self._create_code()
- basicauth_data['code'] = code.code
+ basicauth_data["code"] = code.code
- del basicauth_data['client_id']
- del basicauth_data['client_secret']
+ del basicauth_data["client_id"]
+ del basicauth_data["client_secret"]
- response = self._post_request(basicauth_data, self._password_grant_auth_header())
- response.content.decode('utf-8')
+ response = self._post_request(
+ basicauth_data, self._password_grant_auth_header()
+ )
+ response.content.decode("utf-8")
self.assertNotIn(
- 'invalid_client',
- response.content.decode('utf-8'),
- msg='Client authentication fails using HTTP Basic Auth.')
+ "invalid_client",
+ response.content.decode("utf-8"),
+ msg="Client authentication fails using HTTP Basic Auth.",
+ )
def test_access_token_contains_nonce(self):
"""
@@ -554,21 +570,21 @@ class TokenTestCase(TestCase):
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
- id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
+ response_dic = json.loads(response.content.decode("utf-8"))
+ id_token = JWT().unpack(response_dic["id_token"].encode("utf-8")).payload()
- self.assertEqual(id_token.get('nonce'), FAKE_NONCE)
+ self.assertEqual(id_token.get("nonce"), FAKE_NONCE)
# Client does not supply a nonce parameter.
- code.nonce = ''
+ code.nonce = ""
code.save()
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
+ response_dic = json.loads(response.content.decode("utf-8"))
- id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
+ id_token = JWT().unpack(response_dic["id_token"].encode("utf-8")).payload()
- self.assertEqual(id_token.get('nonce'), None)
+ self.assertEqual(id_token.get("nonce"), None)
def test_id_token_contains_at_hash(self):
"""
@@ -580,10 +596,10 @@ class TokenTestCase(TestCase):
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
- id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
+ response_dic = json.loads(response.content.decode("utf-8"))
+ id_token = JWT().unpack(response_dic["id_token"].encode("utf-8")).payload()
- self.assertTrue(id_token.get('at_hash'))
+ self.assertTrue(id_token.get("at_hash"))
def test_idtoken_sign_validation(self):
"""
@@ -592,19 +608,20 @@ class TokenTestCase(TestCase):
the JOSE Header.
"""
SIGKEYS = self._get_keys()
- RSAKEYS = [k for k in SIGKEYS if k.kty == 'RSA']
+ RSAKEYS = [k for k in SIGKEYS if k.kty == "RSA"]
code = self._create_code()
post_data = self._auth_code_post_data(code=code.code)
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
+ response_dic = json.loads(response.content.decode("utf-8"))
- JWS().verify_compact(response_dic['id_token'].encode('utf-8'), RSAKEYS)
+ JWS().verify_compact(response_dic["id_token"].encode("utf-8"), RSAKEYS)
@override_settings(
- OIDC_IDTOKEN_SUB_GENERATOR='oidc_provider.tests.app.utils.fake_sub_generator')
+ OIDC_IDTOKEN_SUB_GENERATOR="oidc_provider.tests.app.utils.fake_sub_generator"
+ )
def test_custom_sub_generator(self):
"""
Test custom function for setting OIDC_IDTOKEN_SUB_GENERATOR.
@@ -615,13 +632,14 @@ class TokenTestCase(TestCase):
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
- id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
+ response_dic = json.loads(response.content.decode("utf-8"))
+ id_token = JWT().unpack(response_dic["id_token"].encode("utf-8")).payload()
- self.assertEqual(id_token.get('sub'), self.user.email)
+ self.assertEqual(id_token.get("sub"), self.user.email)
@override_settings(
- OIDC_IDTOKEN_PROCESSING_HOOK='oidc_provider.tests.app.utils.fake_idtoken_processing_hook')
+ OIDC_IDTOKEN_PROCESSING_HOOK="oidc_provider.tests.app.utils.fake_idtoken_processing_hook"
+ )
def test_additional_idtoken_processing_hook(self):
"""
Test custom function for setting OIDC_IDTOKEN_PROCESSING_HOOK.
@@ -632,15 +650,19 @@ class TokenTestCase(TestCase):
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
- id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
+ response_dic = json.loads(response.content.decode("utf-8"))
+ id_token = JWT().unpack(response_dic["id_token"].encode("utf-8")).payload()
- self.assertEqual(id_token.get('test_idtoken_processing_hook'), FAKE_RANDOM_STRING)
- self.assertEqual(id_token.get('test_idtoken_processing_hook_user_email'), self.user.email)
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook"), FAKE_RANDOM_STRING
+ )
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook_user_email"), self.user.email
+ )
@override_settings(
OIDC_IDTOKEN_PROCESSING_HOOK=(
- 'oidc_provider.tests.app.utils.fake_idtoken_processing_hook',
+ "oidc_provider.tests.app.utils.fake_idtoken_processing_hook",
)
)
def test_additional_idtoken_processing_hook_one_element_in_tuple(self):
@@ -653,15 +675,19 @@ class TokenTestCase(TestCase):
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
- id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
+ response_dic = json.loads(response.content.decode("utf-8"))
+ id_token = JWT().unpack(response_dic["id_token"].encode("utf-8")).payload()
- self.assertEqual(id_token.get('test_idtoken_processing_hook'), FAKE_RANDOM_STRING)
- self.assertEqual(id_token.get('test_idtoken_processing_hook_user_email'), self.user.email)
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook"), FAKE_RANDOM_STRING
+ )
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook_user_email"), self.user.email
+ )
@override_settings(
OIDC_IDTOKEN_PROCESSING_HOOK=[
- 'oidc_provider.tests.app.utils.fake_idtoken_processing_hook',
+ "oidc_provider.tests.app.utils.fake_idtoken_processing_hook",
]
)
def test_additional_idtoken_processing_hook_one_element_in_list(self):
@@ -674,16 +700,20 @@ class TokenTestCase(TestCase):
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
- id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
+ response_dic = json.loads(response.content.decode("utf-8"))
+ id_token = JWT().unpack(response_dic["id_token"].encode("utf-8")).payload()
- self.assertEqual(id_token.get('test_idtoken_processing_hook'), FAKE_RANDOM_STRING)
- self.assertEqual(id_token.get('test_idtoken_processing_hook_user_email'), self.user.email)
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook"), FAKE_RANDOM_STRING
+ )
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook_user_email"), self.user.email
+ )
@override_settings(
OIDC_IDTOKEN_PROCESSING_HOOK=[
- 'oidc_provider.tests.app.utils.fake_idtoken_processing_hook',
- 'oidc_provider.tests.app.utils.fake_idtoken_processing_hook2',
+ "oidc_provider.tests.app.utils.fake_idtoken_processing_hook",
+ "oidc_provider.tests.app.utils.fake_idtoken_processing_hook2",
]
)
def test_additional_idtoken_processing_hook_two_elements_in_list(self):
@@ -696,19 +726,27 @@ class TokenTestCase(TestCase):
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
- id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
+ response_dic = json.loads(response.content.decode("utf-8"))
+ id_token = JWT().unpack(response_dic["id_token"].encode("utf-8")).payload()
- self.assertEqual(id_token.get('test_idtoken_processing_hook'), FAKE_RANDOM_STRING)
- self.assertEqual(id_token.get('test_idtoken_processing_hook_user_email'), self.user.email)
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook"), FAKE_RANDOM_STRING
+ )
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook_user_email"), self.user.email
+ )
- self.assertEqual(id_token.get('test_idtoken_processing_hook2'), FAKE_RANDOM_STRING)
- self.assertEqual(id_token.get('test_idtoken_processing_hook_user_email2'), self.user.email)
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook2"), FAKE_RANDOM_STRING
+ )
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook_user_email2"), self.user.email
+ )
@override_settings(
OIDC_IDTOKEN_PROCESSING_HOOK=(
- 'oidc_provider.tests.app.utils.fake_idtoken_processing_hook',
- 'oidc_provider.tests.app.utils.fake_idtoken_processing_hook2',
+ "oidc_provider.tests.app.utils.fake_idtoken_processing_hook",
+ "oidc_provider.tests.app.utils.fake_idtoken_processing_hook2",
)
)
def test_additional_idtoken_processing_hook_two_elements_in_tuple(self):
@@ -721,43 +759,57 @@ class TokenTestCase(TestCase):
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
- id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
+ response_dic = json.loads(response.content.decode("utf-8"))
+ id_token = JWT().unpack(response_dic["id_token"].encode("utf-8")).payload()
- self.assertEqual(id_token.get('test_idtoken_processing_hook'), FAKE_RANDOM_STRING)
- self.assertEqual(id_token.get('test_idtoken_processing_hook_user_email'), self.user.email)
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook"), FAKE_RANDOM_STRING
+ )
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook_user_email"), self.user.email
+ )
- self.assertEqual(id_token.get('test_idtoken_processing_hook2'), FAKE_RANDOM_STRING)
- self.assertEqual(id_token.get('test_idtoken_processing_hook_user_email2'), self.user.email)
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook2"), FAKE_RANDOM_STRING
+ )
+ self.assertEqual(
+ id_token.get("test_idtoken_processing_hook_user_email2"), self.user.email
+ )
@override_settings(
OIDC_IDTOKEN_PROCESSING_HOOK=(
- 'oidc_provider.tests.app.utils.fake_idtoken_processing_hook3'))
+ "oidc_provider.tests.app.utils.fake_idtoken_processing_hook3"
+ )
+ )
def test_additional_idtoken_processing_hook_scope_available(self):
"""
Test scope is available in OIDC_IDTOKEN_PROCESSING_HOOK.
"""
id_token = self._request_id_token_with_scope(
- ['openid', 'email', 'profile', 'dummy'])
+ ["openid", "email", "profile", "dummy"]
+ )
self.assertEqual(
- id_token.get('scope_of_token_passed_to_processing_hook'),
- ['openid', 'email', 'profile', 'dummy'])
+ id_token.get("scope_of_token_passed_to_processing_hook"),
+ ["openid", "email", "profile", "dummy"],
+ )
@override_settings(
OIDC_IDTOKEN_PROCESSING_HOOK=(
- 'oidc_provider.tests.app.utils.fake_idtoken_processing_hook4'))
+ "oidc_provider.tests.app.utils.fake_idtoken_processing_hook4"
+ )
+ )
def test_additional_idtoken_processing_hook_kwargs(self):
"""
Test correct kwargs are passed to OIDC_IDTOKEN_PROCESSING_HOOK.
"""
- id_token = self._request_id_token_with_scope(['openid', 'profile'])
- kwargs_passed = id_token.get('kwargs_passed_to_processing_hook')
+ id_token = self._request_id_token_with_scope(["openid", "profile"])
+ kwargs_passed = id_token.get("kwargs_passed_to_processing_hook")
assert kwargs_passed
- self.assertTrue(kwargs_passed.get('token').startswith(
- '<Token: Some Client -'))
- self.assertEqual(kwargs_passed.get('request'),
- "<WSGIRequest: POST '/openid/token'>")
- self.assertEqual(set(kwargs_passed.keys()), {'token', 'request'})
+ self.assertTrue(kwargs_passed.get("token").startswith("<Token: Some Client -"))
+ self.assertEqual(
+ kwargs_passed.get("request"), "<WSGIRequest: POST '/openid/token'>"
+ )
+ self.assertEqual(set(kwargs_passed.keys()), {"token", "request"})
def _request_id_token_with_scope(self, scope):
code = self._create_code(scope)
@@ -766,8 +818,8 @@ class TokenTestCase(TestCase):
response = self._post_request(post_data)
- response_dic = json.loads(response.content.decode('utf-8'))
- id_token = JWT().unpack(response_dic['id_token'].encode('utf-8')).payload()
+ response_dic = json.loads(response.content.decode("utf-8"))
+ id_token = JWT().unpack(response_dic["id_token"].encode("utf-8")).payload()
return id_token
def test_pkce_parameters(self):
@@ -775,94 +827,103 @@ class TokenTestCase(TestCase):
Test Proof Key for Code Exchange by OAuth Public Clients.
https://tools.ietf.org/html/rfc7636
"""
- code = create_code(user=self.user, client=self.client,
- scope=['openid', 'email'], nonce=FAKE_NONCE, is_authentication=True,
- code_challenge=FAKE_CODE_CHALLENGE, code_challenge_method='S256')
+ code = create_code(
+ user=self.user,
+ client=self.client,
+ scope=["openid", "email"],
+ nonce=FAKE_NONCE,
+ is_authentication=True,
+ code_challenge=FAKE_CODE_CHALLENGE,
+ code_challenge_method="S256",
+ )
code.save()
post_data = self._auth_code_post_data(code=code.code)
# Add parameters.
- post_data['code_verifier'] = FAKE_CODE_VERIFIER
+ post_data["code_verifier"] = FAKE_CODE_VERIFIER
response = self._post_request(post_data)
- json.loads(response.content.decode('utf-8'))
+ json.loads(response.content.decode("utf-8"))
@override_settings(OIDC_INTROSPECTION_VALIDATE_AUDIENCE_SCOPE=False)
def test_client_credentials_grant_type(self):
- fake_scopes_list = ['scopeone', 'scopetwo', INTROSPECTION_SCOPE]
+ fake_scopes_list = ["scopeone", "scopetwo", INTROSPECTION_SCOPE]
# Add scope for this client.
self.client.scope = fake_scopes_list
self.client.save()
post_data = {
- 'client_id': self.client.client_id,
- 'client_secret': self.client.client_secret,
- 'grant_type': 'client_credentials',
+ "client_id": self.client.client_id,
+ "client_secret": self.client.client_secret,
+ "grant_type": "client_credentials",
}
response = self._post_request(post_data)
- response_dict = json.loads(response.content.decode('utf-8'))
+ response_dict = json.loads(response.content.decode("utf-8"))
# Ensure access token exists in the response, also check if scopes are
# the ones we registered previously.
- self.assertTrue('access_token' in response_dict)
- self.assertEqual(' '.join(fake_scopes_list), response_dict['scope'])
+ self.assertTrue("access_token" in response_dict)
+ self.assertEqual(" ".join(fake_scopes_list), response_dict["scope"])
- access_token = response_dict['access_token']
+ access_token = response_dict["access_token"]
# Create a protected resource and test the access_token.
- @require_http_methods(['GET'])
+ @require_http_methods(["GET"])
@protected_resource_view(fake_scopes_list)
def protected_api(request, *args, **kwargs):
- return JsonResponse({'protected': 'information'}, status=200)
+ return JsonResponse({"protected": "information"}, status=200)
# Deploy view on some url. So, base url could be anything.
request = self.factory.get(
- '/api/protected/?access_token={0}'.format(access_token))
+ "/api/protected/?access_token={0}".format(access_token)
+ )
response = protected_api(request)
- response_dict = json.loads(response.content.decode('utf-8'))
+ response_dict = json.loads(response.content.decode("utf-8"))
self.assertEqual(response.status_code, 200)
- self.assertTrue('protected' in response_dict)
+ self.assertTrue("protected" in response_dict)
# Protected resource test ends here.
# Verify access_token can be validated with token introspection
response = self.request_client.post(
- reverse('oidc_provider:token-introspection'), data={'token': access_token},
- **self._password_grant_auth_header())
+ reverse("oidc_provider:token-introspection"),
+ data={"token": access_token},
+ **self._password_grant_auth_header()
+ )
self.assertEqual(response.status_code, 200)
- response_dict = json.loads(response.content.decode('utf-8'))
- self.assertTrue(response_dict.get('active'))
+ response_dict = json.loads(response.content.decode("utf-8"))
+ self.assertTrue(response_dict.get("active"))
# End token introspection test
# Clean scopes for this client.
- self.client.scope = ''
+ self.client.scope = ""
self.client.save()
response = self._post_request(post_data)
- response_dict = json.loads(response.content.decode('utf-8'))
+ response_dict = json.loads(response.content.decode("utf-8"))
# It should fail when client does not have any scope added.
self.assertEqual(400, response.status_code)
- self.assertEqual('invalid_scope', response_dict['error'])
+ self.assertEqual("invalid_scope", response_dict["error"])
def test_printing_token_used_by_client_credentials_grant_type(self):
# Add scope for this client.
- self.client.scope = ['something']
+ self.client.scope = ["something"]
self.client.save()
post_data = {
- 'client_id': self.client.client_id,
- 'client_secret': self.client.client_secret,
- 'grant_type': 'client_credentials',
+ "client_id": self.client.client_id,
+ "client_secret": self.client.client_secret,
+ "grant_type": "client_credentials",
}
response = self._post_request(post_data)
- response_dict = json.loads(response.content.decode('utf-8'))
- token = Token.objects.get(access_token=response_dict['access_token'])
+ response_dict = json.loads(response.content.decode("utf-8"))
+ token = Token.objects.get(access_token=response_dict["access_token"])
self.assertTrue(str(token))
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_userinfo_endpoint.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_userinfo_endpoint.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_userinfo_endpoint.py
@@ -1,6 +1,6 @@
import json
-
from datetime import timedelta
+
try:
from urllib.parse import urlencode
except ImportError:
@@ -10,28 +10,24 @@ try:
from django.urls import reverse
except ImportError:
from django.core.urlresolvers import reverse
-from django.test import RequestFactory
-from django.test import TestCase
+
+from django.test import RequestFactory, TestCase
from django.utils import timezone
-from oidc_provider.lib.utils.token import (
- create_id_token,
- create_token,
-)
+from oidc_provider.lib.utils.token import create_id_token, create_token
from oidc_provider.tests.app.utils import (
- create_fake_user,
- create_fake_client,
FAKE_NONCE,
+ create_fake_client,
+ create_fake_user,
)
from oidc_provider.views import userinfo
class UserInfoTestCase(TestCase):
-
def setUp(self):
self.factory = RequestFactory()
self.user = create_fake_user()
- self.client = create_fake_client(response_type='code')
+ self.client = create_fake_client(response_type="code")
def _create_token(self, extra_scope=None):
"""
@@ -39,12 +35,9 @@ class UserInfoTestCase(TestCase):
"""
if extra_scope is None:
extra_scope = []
- scope = ['openid', 'email'] + extra_scope
+ scope = ["openid", "email"] + extra_scope
- token = create_token(
- user=self.user,
- client=self.client,
- scope=scope)
+ token = create_token(user=self.user, client=self.client, scope=scope)
id_token_dic = create_id_token(
token=token,
@@ -59,17 +52,17 @@ class UserInfoTestCase(TestCase):
return token
- def _post_request(self, access_token, schema='Bearer'):
+ def _post_request(self, access_token, schema="Bearer"):
"""
Makes a request to the userinfo endpoint by sending the
`post_data` parameters using the 'multipart/form-data'
format.
"""
- url = reverse('oidc_provider:userinfo')
+ url = reverse("oidc_provider:userinfo")
- request = self.factory.post(url, data={}, content_type='multipart/form-data')
+ request = self.factory.post(url, data={}, content_type="multipart/form-data")
- request.META['HTTP_AUTHORIZATION'] = schema + ' ' + access_token
+ request.META["HTTP_AUTHORIZATION"] = schema + " " + access_token
response = userinfo(request)
@@ -91,7 +84,7 @@ class UserInfoTestCase(TestCase):
"""
token = self._create_token()
- response = self._post_request(token.access_token, schema='bearer')
+ response = self._post_request(token.access_token, schema="bearer")
self.assertEqual(response.status_code, 200)
self.assertEqual(bool(response.content), True)
@@ -108,7 +101,7 @@ class UserInfoTestCase(TestCase):
self.assertEqual(response.status_code, 401)
try:
- is_header_field_ok = 'invalid_token' in response['WWW-Authenticate']
+ is_header_field_ok = "invalid_token" in response["WWW-Authenticate"]
except KeyError:
is_header_field_ok = False
self.assertEqual(is_header_field_ok, True)
@@ -116,7 +109,7 @@ class UserInfoTestCase(TestCase):
def test_response_with_invalid_scope(self):
token = self._create_token()
- token.scope = ['otherone']
+ token.scope = ["otherone"]
token.save()
response = self._post_request(token.access_token)
@@ -124,7 +117,7 @@ class UserInfoTestCase(TestCase):
self.assertEqual(response.status_code, 403)
try:
- is_header_field_ok = 'insufficient_scope' in response['WWW-Authenticate']
+ is_header_field_ok = "insufficient_scope" in response["WWW-Authenticate"]
except KeyError:
is_header_field_ok = False
self.assertEqual(is_header_field_ok, True)
@@ -136,9 +129,15 @@ class UserInfoTestCase(TestCase):
"""
token = self._create_token()
- url = reverse('oidc_provider:userinfo') + '?' + urlencode({
- 'access_token': token.access_token,
- })
+ url = (
+ reverse("oidc_provider:userinfo")
+ + "?"
+ + urlencode(
+ {
+ "access_token": token.access_token,
+ }
+ )
+ )
request = self.factory.get(url)
response = userinfo(request)
@@ -147,20 +146,29 @@ class UserInfoTestCase(TestCase):
self.assertEqual(bool(response.content), True)
def test_user_claims_in_response(self):
- token = self._create_token(extra_scope=['profile'])
+ token = self._create_token(extra_scope=["profile"])
response = self._post_request(token.access_token)
- response_dic = json.loads(response.content.decode('utf-8'))
+ response_dic = json.loads(response.content.decode("utf-8"))
self.assertEqual(response.status_code, 200)
self.assertEqual(bool(response.content), True)
- self.assertIn('given_name', response_dic, msg='"given_name" claim should be in response.')
- self.assertNotIn('profile', response_dic, msg='"profile" claim should not be in response.')
+ self.assertIn(
+ "given_name", response_dic, msg='"given_name" claim should be in response.'
+ )
+ self.assertNotIn(
+ "profile", response_dic, msg='"profile" claim should not be in response.'
+ )
# Now adding `address` scope.
- token = self._create_token(extra_scope=['profile', 'address'])
+ token = self._create_token(extra_scope=["profile", "address"])
response = self._post_request(token.access_token)
- response_dic = json.loads(response.content.decode('utf-8'))
+ response_dic = json.loads(response.content.decode("utf-8"))
- self.assertIn('address', response_dic, msg='"address" claim should be in response.')
self.assertIn(
- 'country', response_dic['address'], msg='"country" claim should be in response.')
+ "address", response_dic, msg='"address" claim should be in response.'
+ )
+ self.assertIn(
+ "country",
+ response_dic["address"],
+ msg='"country" claim should be in response.',
+ )
Index: django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_utils.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/cases/test_utils.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/cases/test_utils.py
@@ -7,50 +7,51 @@ from django.test import TestCase, overri
from django.utils import timezone
from mock import mock
-from oidc_provider.lib.utils.common import get_issuer, get_browser_state_or_default
-from oidc_provider.lib.utils.token import create_token, create_id_token
-from oidc_provider.tests.app.utils import create_fake_user, create_fake_client
+from oidc_provider.lib.utils.common import get_browser_state_or_default, get_issuer
+from oidc_provider.lib.utils.token import create_id_token, create_token
+from oidc_provider.tests.app.utils import create_fake_client, create_fake_user
class Request(object):
"""
Mock request object.
"""
- scheme = 'http'
+
+ scheme = "http"
def get_host(self):
- return 'host-from-request:8888'
+ return "host-from-request:8888"
class CommonTest(TestCase):
"""
Test cases for common utils.
"""
+
def test_get_issuer(self):
request = Request()
# from default settings
- self.assertEqual(get_issuer(),
- 'http://localhost:8000/openid')
+ self.assertEqual(get_issuer(), "http://localhost:8000/openid")
# from custom settings
- with self.settings(SITE_URL='http://otherhost:8000'):
- self.assertEqual(get_issuer(),
- 'http://otherhost:8000/openid')
+ with self.settings(SITE_URL="http://otherhost:8000"):
+ self.assertEqual(get_issuer(), "http://otherhost:8000/openid")
# `SITE_URL` not set, from `request`
- with self.settings(SITE_URL=''):
- self.assertEqual(get_issuer(request=request),
- 'http://host-from-request:8888/openid')
+ with self.settings(SITE_URL=""):
+ self.assertEqual(
+ get_issuer(request=request), "http://host-from-request:8888/openid"
+ )
# use settings first if both are provided
- self.assertEqual(get_issuer(request=request),
- 'http://localhost:8000/openid')
+ self.assertEqual(get_issuer(request=request), "http://localhost:8000/openid")
# `site_url` can even be overridden manually
- self.assertEqual(get_issuer(site_url='http://127.0.0.1:9000',
- request=request),
- 'http://127.0.0.1:9000/openid')
+ self.assertEqual(
+ get_issuer(site_url="http://127.0.0.1:9000", request=request),
+ "http://127.0.0.1:9000/openid",
+ )
def timestamp_to_datetime(timestamp):
@@ -69,32 +70,38 @@ class TokenTest(TestCase):
self.user.last_login = timestamp_to_datetime(login_timestamp)
client = create_fake_client("code")
token = create_token(self.user, client, [])
- id_token_data = create_id_token(token=token, user=self.user, aud='test-aud')
- iat = id_token_data['iat']
+ id_token_data = create_id_token(token=token, user=self.user, aud="test-aud")
+ iat = id_token_data["iat"]
self.assertEqual(type(iat), int)
self.assertGreaterEqual(iat, start_time)
self.assertLessEqual(iat - start_time, 5) # Can't take more than 5 s
- self.assertEqual(id_token_data, {
- 'aud': 'test-aud',
- 'auth_time': login_timestamp,
- 'exp': iat + 600,
- 'iat': iat,
- 'iss': 'http://localhost:8000/openid',
- 'sub': str(self.user.id),
- })
+ self.assertEqual(
+ id_token_data,
+ {
+ "aud": "test-aud",
+ "auth_time": login_timestamp,
+ "exp": iat + 600,
+ "iat": iat,
+ "iss": "http://localhost:8000/openid",
+ "sub": str(self.user.id),
+ },
+ )
class BrowserStateTest(TestCase):
-
- @override_settings(OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY='my_static_key')
- def test_get_browser_state_uses_value_from_settings_to_calculate_browser_state(self):
+ @override_settings(OIDC_UNAUTHENTICATED_SESSION_MANAGEMENT_KEY="my_static_key")
+ def test_get_browser_state_uses_value_from_settings_to_calculate_browser_state(
+ self,
+ ):
request = HttpRequest()
request.session = mock.Mock(session_key=None)
state = get_browser_state_or_default(request)
- self.assertEqual(state, sha224('my_static_key'.encode('utf-8')).hexdigest())
+ self.assertEqual(state, sha224("my_static_key".encode("utf-8")).hexdigest())
- def test_get_browser_state_uses_session_key_to_calculate_browser_state_if_available(self):
+ def test_get_browser_state_uses_session_key_to_calculate_browser_state_if_available(
+ self,
+ ):
request = HttpRequest()
- request.session = mock.Mock(session_key='my_session_key')
+ request.session = mock.Mock(session_key="my_session_key")
state = get_browser_state_or_default(request)
- self.assertEqual(state, sha224('my_session_key'.encode('utf-8')).hexdigest())
+ self.assertEqual(state, sha224("my_session_key".encode("utf-8")).hexdigest())
Index: django-oidc-provider-0.7.0/oidc_provider/tests/settings.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/tests/settings.py
+++ django-oidc-provider-0.7.0/oidc_provider/tests/settings.py
@@ -1,79 +1,79 @@
DEBUG = False
-SECRET_KEY = 'this-should-be-top-secret'
+SECRET_KEY = "this-should-be-top-secret"
DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': ':memory:',
+ "default": {
+ "ENGINE": "django.db.backends.sqlite3",
+ "NAME": ":memory:",
}
}
SITE_ID = 1
MIDDLEWARE_CLASSES = [
- 'django.middleware.common.CommonMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ "django.middleware.common.CommonMiddleware",
+ "django.contrib.sessions.middleware.SessionMiddleware",
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
]
MIDDLEWARE = [
- 'django.middleware.common.CommonMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ "django.middleware.common.CommonMiddleware",
+ "django.contrib.sessions.middleware.SessionMiddleware",
+ "django.contrib.auth.middleware.AuthenticationMiddleware",
]
TEMPLATES = [
{
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [],
- 'APP_DIRS': True,
- 'OPTIONS': {
- 'context_processors': [
- 'django.template.context_processors.debug',
- 'django.template.context_processors.request',
- 'django.contrib.auth.context_processors.auth',
- 'django.contrib.messages.context_processors.messages',
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": [],
+ "APP_DIRS": True,
+ "OPTIONS": {
+ "context_processors": [
+ "django.template.context_processors.debug",
+ "django.template.context_processors.request",
+ "django.contrib.auth.context_processors.auth",
+ "django.contrib.messages.context_processors.messages",
],
},
},
]
INSTALLED_APPS = [
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.sites',
- 'django.contrib.messages',
- 'django.contrib.admin',
- 'oidc_provider',
+ "django.contrib.auth",
+ "django.contrib.contenttypes",
+ "django.contrib.sessions",
+ "django.contrib.sites",
+ "django.contrib.messages",
+ "django.contrib.admin",
+ "oidc_provider",
]
-ROOT_URLCONF = 'oidc_provider.tests.app.urls'
+ROOT_URLCONF = "oidc_provider.tests.app.urls"
TEMPLATE_DIRS = [
- 'oidc_provider/tests/templates',
+ "oidc_provider/tests/templates",
]
USE_TZ = True
LOGGING = {
- 'version': 1,
- 'disable_existing_loggers': False,
- 'handlers': {
- 'console': {
- 'class': 'logging.StreamHandler',
+ "version": 1,
+ "disable_existing_loggers": False,
+ "handlers": {
+ "console": {
+ "class": "logging.StreamHandler",
},
},
- 'loggers': {
- 'oidc_provider': {
- 'handlers': ['console'],
- 'level': 'DEBUG',
+ "loggers": {
+ "oidc_provider": {
+ "handlers": ["console"],
+ "level": "DEBUG",
},
},
}
# OIDC Provider settings.
-SITE_URL = 'http://localhost:8000'
-OIDC_USERINFO = 'oidc_provider.tests.app.utils.userinfo'
+SITE_URL = "http://localhost:8000"
+OIDC_USERINFO = "oidc_provider.tests.app.utils.userinfo"
Index: django-oidc-provider-0.7.0/oidc_provider/urls.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/urls.py
+++ django-oidc-provider-0.7.0/oidc_provider/urls.py
@@ -1,28 +1,36 @@
try:
from django.urls import url
except ImportError:
- from django.conf.urls import url
+ from django.urls import re_path
+
from django.views.decorators.csrf import csrf_exempt
-from oidc_provider import (
- settings,
- views,
-)
+from oidc_provider import settings, views
-app_name = 'oidc_provider'
+app_name = "oidc_provider"
urlpatterns = [
- url(r'^authorize/?$', views.AuthorizeView.as_view(), name='authorize'),
- url(r'^token/?$', csrf_exempt(views.TokenView.as_view()), name='token'),
- url(r'^userinfo/?$', csrf_exempt(views.userinfo), name='userinfo'),
- url(r'^end-session/?$', views.EndSessionView.as_view(), name='end-session'),
- url(r'^\.well-known/openid-configuration/?$', views.ProviderInfoView.as_view(),
- name='provider-info'),
- url(r'^introspect/?$', views.TokenIntrospectionView.as_view(), name='token-introspection'),
- url(r'^jwks/?$', views.JwksView.as_view(), name='jwks'),
+ re_path(r"^authorize/?$", views.AuthorizeView.as_view(), name="authorize"),
+ re_path(r"^token/?$", csrf_exempt(views.TokenView.as_view()), name="token"),
+ re_path(r"^userinfo/?$", csrf_exempt(views.userinfo), name="userinfo"),
+ re_path(r"^end-session/?$", views.EndSessionView.as_view(), name="end-session"),
+ re_path(
+ r"^\.well-known/openid-configuration/?$",
+ views.ProviderInfoView.as_view(),
+ name="provider-info",
+ ),
+ re_path(
+ r"^introspect/?$",
+ views.TokenIntrospectionView.as_view(),
+ name="token-introspection",
+ ),
+ re_path(r"^jwks/?$", views.JwksView.as_view(), name="jwks"),
]
-if settings.get('OIDC_SESSION_MANAGEMENT_ENABLE'):
+if settings.get("OIDC_SESSION_MANAGEMENT_ENABLE"):
urlpatterns += [
- url(r'^check-session-iframe/?$', views.CheckSessionIframeView.as_view(),
- name='check-session-iframe'),
+ re_path(
+ r"^check-session-iframe/?$",
+ views.CheckSessionIframeView.as_view(),
+ name="check-session-iframe",
+ ),
]
Index: django-oidc-provider-0.7.0/oidc_provider/version.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/version.py
+++ django-oidc-provider-0.7.0/oidc_provider/version.py
@@ -1 +1 @@
-__version__ = '0.7.0'
+__version__ = "0.7.0"
Index: django-oidc-provider-0.7.0/oidc_provider/views.py
===================================================================
--- django-oidc-provider-0.7.0.orig/oidc_provider/views.py
+++ django-oidc-provider-0.7.0/oidc_provider/views.py
@@ -3,23 +3,24 @@ import logging
from django.views.decorators.csrf import csrf_exempt
from oidc_provider.lib.endpoints.introspection import TokenIntrospectionEndpoint
+
try:
from urllib import urlencode
- from urlparse import urlsplit, parse_qs, urlunsplit
+
+ from urlparse import parse_qs, urlsplit, urlunsplit
except ImportError:
from urllib.parse import urlsplit, parse_qs, urlunsplit, urlencode
from Cryptodome.PublicKey import RSA
-from django.contrib.auth.views import (
- redirect_to_login,
- LogoutView,
-)
+from django.contrib.auth.views import LogoutView, redirect_to_login
+
try:
from django.urls import reverse
except ImportError:
from django.core.urlresolvers import reverse
+
from django.contrib.auth import logout as django_user_logout
-from django.http import JsonResponse, HttpResponse
+from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django.template.loader import render_to_string
from django.utils.decorators import method_decorator
@@ -28,6 +29,7 @@ from django.views.decorators.http import
from django.views.generic import View
from jwkest import long_to_base64
+from oidc_provider import settings, signals
from oidc_provider.compat import get_attr_or_callable
from oidc_provider.lib.claims import StandardScopeClaims
from oidc_provider.lib.endpoints.authorize import AuthorizeEndpoint
@@ -37,28 +39,23 @@ from oidc_provider.lib.errors import (
ClientIdError,
RedirectUriError,
TokenError,
+ TokenIntrospectionError,
UserAuthError,
- TokenIntrospectionError)
+)
from oidc_provider.lib.utils.authorize import strip_prompt_login
from oidc_provider.lib.utils.common import (
- redirect,
- get_site_url,
- get_issuer,
cors_allow_any,
+ get_issuer,
+ get_site_url,
+ redirect,
)
from oidc_provider.lib.utils.oauth2 import protected_resource_view
from oidc_provider.lib.utils.token import client_id_from_id_token
-from oidc_provider.models import (
- Client,
- RSAKey,
- ResponseType)
-from oidc_provider import settings
-from oidc_provider import signals
-
+from oidc_provider.models import Client, ResponseType, RSAKey
logger = logging.getLogger(__name__)
-OIDC_TEMPLATES = settings.get('OIDC_TEMPLATES')
+OIDC_TEMPLATES = settings.get("OIDC_TEMPLATES")
class AuthorizeView(View):
@@ -70,101 +67,124 @@ class AuthorizeView(View):
try:
authorize.validate_params()
- if get_attr_or_callable(request.user, 'is_authenticated'):
+ if get_attr_or_callable(request.user, "is_authenticated"):
# Check if there's a hook setted.
- hook_resp = settings.get('OIDC_AFTER_USERLOGIN_HOOK', import_str=True)(
- request=request, user=request.user,
- client=authorize.client)
+ hook_resp = settings.get("OIDC_AFTER_USERLOGIN_HOOK", import_str=True)(
+ request=request, user=request.user, client=authorize.client
+ )
if hook_resp:
return hook_resp
- if 'login' in authorize.params['prompt']:
- if 'none' in authorize.params['prompt']:
+ if "login" in authorize.params["prompt"]:
+ if "none" in authorize.params["prompt"]:
raise AuthorizeError(
- authorize.params['redirect_uri'], 'login_required',
- authorize.grant_type)
+ authorize.params["redirect_uri"],
+ "login_required",
+ authorize.grant_type,
+ )
else:
django_user_logout(request)
next_page = strip_prompt_login(request.get_full_path())
- return redirect_to_login(next_page, settings.get('OIDC_LOGIN_URL'))
+ return redirect_to_login(
+ next_page, settings.get("OIDC_LOGIN_URL")
+ )
- if 'select_account' in authorize.params['prompt']:
+ if "select_account" in authorize.params["prompt"]:
# TODO: see how we can support multiple accounts for the end-user.
- if 'none' in authorize.params['prompt']:
+ if "none" in authorize.params["prompt"]:
raise AuthorizeError(
- authorize.params['redirect_uri'], 'account_selection_required',
- authorize.grant_type)
+ authorize.params["redirect_uri"],
+ "account_selection_required",
+ authorize.grant_type,
+ )
else:
django_user_logout(request)
return redirect_to_login(
- request.get_full_path(), settings.get('OIDC_LOGIN_URL'))
+ request.get_full_path(), settings.get("OIDC_LOGIN_URL")
+ )
- if {'none', 'consent'}.issubset(authorize.params['prompt']):
+ if {"none", "consent"}.issubset(authorize.params["prompt"]):
raise AuthorizeError(
- authorize.params['redirect_uri'], 'consent_required', authorize.grant_type)
+ authorize.params["redirect_uri"],
+ "consent_required",
+ authorize.grant_type,
+ )
- implicit_flow_resp_types = {'id_token', 'id_token token'}
+ implicit_flow_resp_types = {"id_token", "id_token token"}
allow_skipping_consent = (
- authorize.client.client_type != 'public' or
- authorize.params['response_type'] in implicit_flow_resp_types)
+ authorize.client.client_type != "public"
+ or authorize.params["response_type"] in implicit_flow_resp_types
+ )
if not authorize.client.require_consent and (
- allow_skipping_consent and
- 'consent' not in authorize.params['prompt']):
+ allow_skipping_consent
+ and "consent" not in authorize.params["prompt"]
+ ):
return redirect(authorize.create_response_uri())
if authorize.client.reuse_consent:
# Check if user previously give consent.
if authorize.client_has_user_consent() and (
- allow_skipping_consent and
- 'consent' not in authorize.params['prompt']):
+ allow_skipping_consent
+ and "consent" not in authorize.params["prompt"]
+ ):
return redirect(authorize.create_response_uri())
- if 'none' in authorize.params['prompt']:
+ if "none" in authorize.params["prompt"]:
raise AuthorizeError(
- authorize.params['redirect_uri'], 'consent_required', authorize.grant_type)
+ authorize.params["redirect_uri"],
+ "consent_required",
+ authorize.grant_type,
+ )
# Generate hidden inputs for the form.
context = {
- 'params': authorize.params,
+ "params": authorize.params,
}
- hidden_inputs = render_to_string('oidc_provider/hidden_inputs.html', context)
+ hidden_inputs = render_to_string(
+ "oidc_provider/hidden_inputs.html", context
+ )
# Remove `openid` from scope list
# since we don't need to print it.
- if 'openid' in authorize.params['scope']:
- authorize.params['scope'].remove('openid')
+ if "openid" in authorize.params["scope"]:
+ authorize.params["scope"].remove("openid")
context = {
- 'client': authorize.client,
- 'hidden_inputs': hidden_inputs,
- 'params': authorize.params,
- 'scopes': authorize.get_scopes_information(),
+ "client": authorize.client,
+ "hidden_inputs": hidden_inputs,
+ "params": authorize.params,
+ "scopes": authorize.get_scopes_information(),
}
- return render(request, OIDC_TEMPLATES['authorize'], context)
+ return render(request, OIDC_TEMPLATES["authorize"], context)
else:
- if 'none' in authorize.params['prompt']:
+ if "none" in authorize.params["prompt"]:
raise AuthorizeError(
- authorize.params['redirect_uri'], 'login_required', authorize.grant_type)
- if 'login' in authorize.params['prompt']:
+ authorize.params["redirect_uri"],
+ "login_required",
+ authorize.grant_type,
+ )
+ if "login" in authorize.params["prompt"]:
next_page = strip_prompt_login(request.get_full_path())
- return redirect_to_login(next_page, settings.get('OIDC_LOGIN_URL'))
+ return redirect_to_login(next_page, settings.get("OIDC_LOGIN_URL"))
- return redirect_to_login(request.get_full_path(), settings.get('OIDC_LOGIN_URL'))
+ return redirect_to_login(
+ request.get_full_path(), settings.get("OIDC_LOGIN_URL")
+ )
except (ClientIdError, RedirectUriError) as error:
context = {
- 'error': error.error,
- 'description': error.description,
+ "error": error.error,
+ "description": error.description,
}
- return render(request, OIDC_TEMPLATES['error'], context)
+ return render(request, OIDC_TEMPLATES["error"], context)
except AuthorizeError as error:
uri = error.create_uri(
- authorize.params['redirect_uri'],
- authorize.params['state'])
+ authorize.params["redirect_uri"], authorize.params["state"]
+ )
return redirect(uri)
@@ -174,18 +194,26 @@ class AuthorizeView(View):
try:
authorize.validate_params()
- if not request.POST.get('allow'):
+ if not request.POST.get("allow"):
signals.user_decline_consent.send(
- self.__class__, user=request.user,
- client=authorize.client, scope=authorize.params['scope'])
-
- raise AuthorizeError(authorize.params['redirect_uri'],
- 'access_denied',
- authorize.grant_type)
+ self.__class__,
+ user=request.user,
+ client=authorize.client,
+ scope=authorize.params["scope"],
+ )
+
+ raise AuthorizeError(
+ authorize.params["redirect_uri"],
+ "access_denied",
+ authorize.grant_type,
+ )
signals.user_accept_consent.send(
- self.__class__, user=request.user, client=authorize.client,
- scope=authorize.params['scope'])
+ self.__class__,
+ user=request.user,
+ client=authorize.client,
+ scope=authorize.params["scope"],
+ )
# Save the user consent given to the client.
authorize.set_client_user_consent()
@@ -196,8 +224,8 @@ class AuthorizeView(View):
except AuthorizeError as error:
uri = error.create_uri(
- authorize.params['redirect_uri'],
- authorize.params['state'])
+ authorize.params["redirect_uri"], authorize.params["state"]
+ )
return redirect(uri)
@@ -219,8 +247,8 @@ class TokenView(View):
return TokenEndpoint.response(error.create_dict(), status=403)
-@require_http_methods(['GET', 'POST', 'OPTIONS'])
-@protected_resource_view(['openid'])
+@require_http_methods(["GET", "POST", "OPTIONS"])
+@protected_resource_view(["openid"])
def userinfo(request, *args, **kwargs):
"""
Create a dictionary with all the requested claims about the End-User.
@@ -230,25 +258,25 @@ def userinfo(request, *args, **kwargs):
"""
def set_headers(response):
- response['Cache-Control'] = 'no-store'
- response['Pragma'] = 'no-cache'
+ response["Cache-Control"] = "no-store"
+ response["Pragma"] = "no-cache"
cors_allow_any(request, response)
return response
- if request.method == 'OPTIONS':
+ if request.method == "OPTIONS":
return set_headers(HttpResponse())
- token = kwargs['token']
+ token = kwargs["token"]
dic = {
- 'sub': token.id_token.get('sub'),
+ "sub": token.id_token.get("sub"),
}
standard_claims = StandardScopeClaims(token)
dic.update(standard_claims.create_response_dic())
- if settings.get('OIDC_EXTRA_SCOPE_CLAIMS'):
- extra_claims = settings.get('OIDC_EXTRA_SCOPE_CLAIMS', import_str=True)(token)
+ if settings.get("OIDC_EXTRA_SCOPE_CLAIMS"):
+ extra_claims = settings.get("OIDC_EXTRA_SCOPE_CLAIMS", import_str=True)(token)
dic.update(extra_claims.create_response_dic())
success_response = JsonResponse(dic, status=200)
@@ -262,32 +290,40 @@ class ProviderInfoView(View):
dic = dict()
site_url = get_site_url(request=request)
- dic['issuer'] = get_issuer(site_url=site_url, request=request)
+ dic["issuer"] = get_issuer(site_url=site_url, request=request)
- dic['authorization_endpoint'] = site_url + reverse('oidc_provider:authorize')
- dic['token_endpoint'] = site_url + reverse('oidc_provider:token')
- dic['userinfo_endpoint'] = site_url + reverse('oidc_provider:userinfo')
- dic['end_session_endpoint'] = site_url + reverse('oidc_provider:end-session')
- dic['introspection_endpoint'] = site_url + reverse('oidc_provider:token-introspection')
+ dic["authorization_endpoint"] = site_url + reverse("oidc_provider:authorize")
+ dic["token_endpoint"] = site_url + reverse("oidc_provider:token")
+ dic["userinfo_endpoint"] = site_url + reverse("oidc_provider:userinfo")
+ dic["end_session_endpoint"] = site_url + reverse("oidc_provider:end-session")
+ dic["introspection_endpoint"] = site_url + reverse(
+ "oidc_provider:token-introspection"
+ )
- types_supported = [response_type.value for response_type in ResponseType.objects.all()]
- dic['response_types_supported'] = types_supported
+ types_supported = [
+ response_type.value for response_type in ResponseType.objects.all()
+ ]
+ dic["response_types_supported"] = types_supported
- dic['jwks_uri'] = site_url + reverse('oidc_provider:jwks')
+ dic["jwks_uri"] = site_url + reverse("oidc_provider:jwks")
- dic['id_token_signing_alg_values_supported'] = ['HS256', 'RS256']
+ dic["id_token_signing_alg_values_supported"] = ["HS256", "RS256"]
# See: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
- dic['subject_types_supported'] = ['public']
-
- dic['token_endpoint_auth_methods_supported'] = ['client_secret_post',
- 'client_secret_basic']
+ dic["subject_types_supported"] = ["public"]
- if settings.get('OIDC_SESSION_MANAGEMENT_ENABLE'):
- dic['check_session_iframe'] = site_url + reverse('oidc_provider:check-session-iframe')
+ dic["token_endpoint_auth_methods_supported"] = [
+ "client_secret_post",
+ "client_secret_basic",
+ ]
+
+ if settings.get("OIDC_SESSION_MANAGEMENT_ENABLE"):
+ dic["check_session_iframe"] = site_url + reverse(
+ "oidc_provider:check-session-iframe"
+ )
response = JsonResponse(dic)
- response['Access-Control-Allow-Origin'] = '*'
+ response["Access-Control-Allow-Origin"] = "*"
return response
@@ -298,30 +334,34 @@ class JwksView(View):
for rsakey in RSAKey.objects.all():
public_key = RSA.importKey(rsakey.key).publickey()
- dic['keys'].append({
- 'kty': 'RSA',
- 'alg': 'RS256',
- 'use': 'sig',
- 'kid': rsakey.kid,
- 'n': long_to_base64(public_key.n),
- 'e': long_to_base64(public_key.e),
- })
+ dic["keys"].append(
+ {
+ "kty": "RSA",
+ "alg": "RS256",
+ "use": "sig",
+ "kid": rsakey.kid,
+ "n": long_to_base64(public_key.n),
+ "e": long_to_base64(public_key.e),
+ }
+ )
response = JsonResponse(dic)
- response['Access-Control-Allow-Origin'] = '*'
+ response["Access-Control-Allow-Origin"] = "*"
return response
class EndSessionView(LogoutView):
def dispatch(self, request, *args, **kwargs):
- id_token_hint = request.GET.get('id_token_hint', '')
- post_logout_redirect_uri = request.GET.get('post_logout_redirect_uri', '')
- state = request.GET.get('state', '')
+ id_token_hint = request.GET.get("id_token_hint", "")
+ post_logout_redirect_uri = request.GET.get("post_logout_redirect_uri", "")
+ state = request.GET.get("state", "")
client = None
- next_page = settings.get('OIDC_LOGIN_URL')
- after_end_session_hook = settings.get('OIDC_AFTER_END_SESSION_HOOK', import_str=True)
+ next_page = settings.get("OIDC_LOGIN_URL")
+ after_end_session_hook = settings.get(
+ "OIDC_AFTER_END_SESSION_HOOK", import_str=True
+ )
if id_token_hint:
client_id = client_id_from_id_token(id_token_hint)
@@ -331,7 +371,7 @@ class EndSessionView(LogoutView):
if state:
uri = urlsplit(post_logout_redirect_uri)
query_params = parse_qs(uri.query)
- query_params['state'] = state
+ query_params["state"] = state
uri = uri._replace(query=urlencode(query_params, doseq=True))
next_page = urlunsplit(uri)
else:
@@ -345,7 +385,7 @@ class EndSessionView(LogoutView):
post_logout_redirect_uri=post_logout_redirect_uri,
state=state,
client=client,
- next_page=next_page
+ next_page=next_page,
)
self.next_page = next_page
@@ -358,7 +398,7 @@ class CheckSessionIframeView(View):
return super(CheckSessionIframeView, self).dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs):
- return render(request, 'oidc_provider/check_session_iframe.html', kwargs)
+ return render(request, "oidc_provider/check_session_iframe.html", kwargs)
class TokenIntrospectionView(View):
@@ -374,4 +414,4 @@ class TokenIntrospectionView(View):
dic = introspection.create_response_dic()
return TokenIntrospectionEndpoint.response(dic)
except TokenIntrospectionError:
- return TokenIntrospectionEndpoint.response({'active': False})
+ return TokenIntrospectionEndpoint.response({"active": False})
Index: django-oidc-provider-0.7.0/setup.py
===================================================================
--- django-oidc-provider-0.7.0.orig/setup.py
+++ django-oidc-provider-0.7.0/setup.py
@@ -1,8 +1,6 @@
import os
-from setuptools import (
- find_packages,
- setup,
-)
+
+from setuptools import find_packages, setup
version = {}
with open("./oidc_provider/version.py") as fp:
@@ -12,40 +10,40 @@ with open("./oidc_provider/version.py")
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
setup(
- name='django-oidc-provider',
- version=version['__version__'],
+ name="django-oidc-provider",
+ version=version["__version__"],
packages=find_packages(),
include_package_data=True,
- license='MIT License',
- description='OpenID Connect Provider implementation for Django.',
- long_description='http://github.com/juanifioren/django-oidc-provider',
- url='http://github.com/juanifioren/django-oidc-provider',
- author='Juan Ignacio Fiorentino',
- author_email='juanifioren@gmail.com',
+ license="MIT License",
+ description="OpenID Connect Provider implementation for Django.",
+ long_description="http://github.com/juanifioren/django-oidc-provider",
+ url="http://github.com/juanifioren/django-oidc-provider",
+ author="Juan Ignacio Fiorentino",
+ author_email="juanifioren@gmail.com",
zip_safe=False,
classifiers=[
- 'Development Status :: 5 - Production/Stable',
- 'Environment :: Web Environment',
- 'Framework :: Django',
- 'Intended Audience :: Developers',
- 'License :: OSI Approved :: MIT License',
- 'Operating System :: OS Independent',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.7',
- 'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.5',
- 'Programming Language :: Python :: 3.6',
- 'Topic :: Internet :: WWW/HTTP',
- 'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
+ "Development Status :: 5 - Production/Stable",
+ "Environment :: Web Environment",
+ "Framework :: Django",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: MIT License",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.5",
+ "Programming Language :: Python :: 3.6",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Internet :: WWW/HTTP :: Dynamic Content",
],
- test_suite='runtests.runtests',
+ test_suite="runtests.runtests",
tests_require=[
- 'pyjwkest>=1.3.0',
- 'mock>=2.0.0',
+ "pyjwkest>=1.3.0",
+ "mock>=2.0.0",
],
-
install_requires=[
- 'pyjwkest>=1.3.0',
+ "django>=3.2",
+ "pyjwkest>=1.3.0",
],
)
Index: django-oidc-provider-0.7.0/tox-django4-devtests.ini
===================================================================
--- /dev/null
+++ django-oidc-provider-0.7.0/tox-django4-devtests.ini
@@ -0,0 +1,45 @@
+[tox]
+envlist=
+ docs,
+ py27-django{111},
+ py35-django{111,20,21},
+ py36-django{111,20,21},
+
+[testenv]
+changedir=
+ oidc_provider
+deps =
+ mock
+ psycopg2
+ pytest==3.6.4
+ pytest-django
+ pytest-flake8
+ pytest-cov
+ django111: django>=1.11,<1.12
+ django20: django>=2.0,<2.1
+ django21: django>=2.1,<2.2
+
+commands =
+ pytest --flake8 --cov=oidc_provider {posargs}
+
+[testenv:docs]
+basepython = python2.7
+changedir = docs
+whitelist_externals =
+ mkdir
+deps =
+ sphinx
+ sphinx_rtd_theme
+commands =
+ mkdir -p _static/
+ sphinx-build -v -W -b html -d {envtmpdir}/doctrees -D html_static_path="_static" . {envtmpdir}/html
+
+[pytest]
+DJANGO_SETTINGS_MODULE = oidc_provider.tests.settings
+python_files = test_*.py
+flake8-max-line-length = 100
+flake8-ignore =
+ .git ALL
+ __pycache__ ALL
+ .ropeproject ALL
+ migrations/* ALL