Merge pull request #25 from django-py/master
Adding test settings, coverage file, templates, CI integration and loggers
This commit is contained in:
commit
4dcd69f8d7
8
.coveragerc
Normal file
8
.coveragerc
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[run]
|
||||||
|
omit =
|
||||||
|
tests/*
|
||||||
|
example_project/*
|
||||||
|
.tox/*
|
||||||
|
setup.py
|
||||||
|
*.egg/*
|
||||||
|
*/__main__.py
|
11
.travis.yml
Normal file
11
.travis.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
language: python
|
||||||
|
python:
|
||||||
|
- "2.7"
|
||||||
|
env:
|
||||||
|
- DJANGO=1.7.8
|
||||||
|
- DJANGO=1.8.2
|
||||||
|
install:
|
||||||
|
- pip install -q Django==$DJANGO --use-mirrors
|
||||||
|
- pip install pyjwt==1.1.0 --use-mirrors
|
||||||
|
script:
|
||||||
|
- PYTHONPATH=$PYTHONPATH:$PWD django-admin.py test oidc_provider --settings=oidc_provider.tests.test_settings
|
|
@ -1,6 +1,10 @@
|
||||||
|
|
||||||
Django OIDC Provider
|
Django OIDC Provider
|
||||||
####################
|
####################
|
||||||
|
.. image:: https://api.travis-ci.org/django-py/django-openid-provider.png?branch=master
|
||||||
|
:alt: Build Status
|
||||||
|
:target: http://travis-ci.org/django-py/django-openid-provider
|
||||||
|
|
||||||
|
|
||||||
Django OIDC Provider can help you providing out of the box all the endpoints, data and logic needed to add OpenID Connect capabilities to your Django projects.
|
Django OIDC Provider can help you providing out of the box all the endpoints, data and logic needed to add OpenID Connect capabilities to your Django projects.
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
from datetime import timedelta
|
import logging
|
||||||
import uuid
|
|
||||||
|
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
from oidc_provider.lib.errors import *
|
from oidc_provider.lib.errors import *
|
||||||
from oidc_provider.lib.utils.params import *
|
from oidc_provider.lib.utils.params import *
|
||||||
from oidc_provider.lib.utils.token import *
|
from oidc_provider.lib.utils.token import *
|
||||||
from oidc_provider.models import *
|
from oidc_provider.models import *
|
||||||
from oidc_provider import settings
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AuthorizeEndpoint(object):
|
class AuthorizeEndpoint(object):
|
||||||
|
@ -134,6 +132,10 @@ class AuthorizeEndpoint(object):
|
||||||
if self.params.response_type == 'id_token token':
|
if self.params.response_type == 'id_token token':
|
||||||
uri += '&access_token={0}'.format(token.access_token)
|
uri += '&access_token={0}'.format(token.access_token)
|
||||||
except:
|
except:
|
||||||
|
logger.error('Authorization server error, grant_type: %s' %self.grant_type, extra={
|
||||||
|
'redirect_uri': self.redirect_uri,
|
||||||
|
'state': self.params.state
|
||||||
|
})
|
||||||
raise AuthorizeError(
|
raise AuthorizeError(
|
||||||
self.params.redirect_uri,
|
self.params.redirect_uri,
|
||||||
'server_error',
|
'server_error',
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import logging
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
|
@ -8,6 +9,7 @@ from oidc_provider.lib.utils.token import *
|
||||||
from oidc_provider.models import *
|
from oidc_provider.models import *
|
||||||
from oidc_provider import settings
|
from oidc_provider import settings
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class TokenEndpoint(object):
|
class TokenEndpoint(object):
|
||||||
|
|
||||||
|
@ -16,6 +18,11 @@ class TokenEndpoint(object):
|
||||||
self.params = Params()
|
self.params = Params()
|
||||||
self._extract_params()
|
self._extract_params()
|
||||||
|
|
||||||
|
logger.debug('Request %s', self.request)
|
||||||
|
logger.debug('TokenEndPoint request.POST --> : %s', self.request.POST)
|
||||||
|
logger.debug('TokenEndpoint request.GET --> : %s', self.request.GET)
|
||||||
|
logger.debug('TokenEndPoint extract_params --> : %s', self.params.__dict__)
|
||||||
|
|
||||||
def _extract_params(self):
|
def _extract_params(self):
|
||||||
query_dict = self.request.POST
|
query_dict = self.request.POST
|
||||||
|
|
||||||
|
@ -29,21 +36,25 @@ class TokenEndpoint(object):
|
||||||
|
|
||||||
def validate_params(self):
|
def validate_params(self):
|
||||||
if not (self.params.grant_type == 'authorization_code'):
|
if not (self.params.grant_type == 'authorization_code'):
|
||||||
|
logger.error('Unsupported grant type: --> : %s', self.params.grant_type)
|
||||||
raise TokenError('unsupported_grant_type')
|
raise TokenError('unsupported_grant_type')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.client = Client.objects.get(client_id=self.params.client_id)
|
self.client = Client.objects.get(client_id=self.params.client_id)
|
||||||
|
|
||||||
if not (self.client.client_secret == self.params.client_secret):
|
if not (self.client.client_secret == self.params.client_secret):
|
||||||
|
logger.error('Invalid client, client secret -->: %s', self.params.client_secret)
|
||||||
raise TokenError('invalid_client')
|
raise TokenError('invalid_client')
|
||||||
|
|
||||||
if not (self.params.redirect_uri in self.client.redirect_uris):
|
if not (self.params.redirect_uri in self.client.redirect_uris):
|
||||||
|
logger.error('Invalid client, redirect_uri --> : %s', self.params.redirect_uri)
|
||||||
raise TokenError('invalid_client')
|
raise TokenError('invalid_client')
|
||||||
|
|
||||||
self.code = Code.objects.get(code=self.params.code)
|
self.code = Code.objects.get(code=self.params.code)
|
||||||
|
|
||||||
if not (self.code.client == self.client) \
|
if not (self.code.client == self.client) \
|
||||||
or self.code.has_expired():
|
or self.code.has_expired():
|
||||||
|
logger.error('Invalid grant, code client --> %s', self.code.client)
|
||||||
raise TokenError('invalid_grant')
|
raise TokenError('invalid_grant')
|
||||||
|
|
||||||
except Client.DoesNotExist:
|
except Client.DoesNotExist:
|
||||||
|
@ -77,7 +88,7 @@ class TokenEndpoint(object):
|
||||||
'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
|
'expires_in': settings.get('OIDC_TOKEN_EXPIRE'),
|
||||||
'id_token': id_token,
|
'id_token': id_token,
|
||||||
}
|
}
|
||||||
|
logger.debug('Response dictionary --> : %s', dic)
|
||||||
return dic
|
return dic
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -89,4 +100,6 @@ class TokenEndpoint(object):
|
||||||
response['Cache-Control'] = 'no-store'
|
response['Cache-Control'] = 'no-store'
|
||||||
response['Pragma'] = 'no-cache'
|
response['Pragma'] = 'no-cache'
|
||||||
|
|
||||||
|
logger.debug('JSON Response --> : %s', response.__dict__)
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
24
oidc_provider/tests/templates/accounts/login.html
Normal file
24
oidc_provider/tests/templates/accounts/login.html
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="panel panel-default" style="width:400px;margin:0 auto 25px auto;">
|
||||||
|
<div class="panel-body">
|
||||||
|
<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">Username and password are incorrect.</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" class="form-control" name="username" placeholder="Username">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="password" class="form-control" name="password" placeholder="Password">
|
||||||
|
</div>
|
||||||
|
<input type="submit" class="btn btn-success btn-lg btn-block" value="Enter">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
12
oidc_provider/tests/templates/accounts/logout.html
Normal file
12
oidc_provider/tests/templates/accounts/logout.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="panel panel-default" style="width:400px;margin:0 auto 25px auto;">
|
||||||
|
<div class="panel-body">
|
||||||
|
<h1>Bye!</h1>
|
||||||
|
<p>Thanks for spending some quality time with the web site today.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
50
oidc_provider/tests/templates/base.html
Normal file
50
oidc_provider/tests/templates/base.html
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>OpenID Provider</title>
|
||||||
|
|
||||||
|
<!-- Bootstrap -->
|
||||||
|
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.4/cerulean/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<style type="text/css">body{padding-top:20px;padding-bottom:20px}.footer,.header,.marketing{padding-right:15px;padding-left:15px}.header{padding-bottom:20px;border-bottom:1px solid #e5e5e5}.header h3{margin-top:0;margin-bottom:0;line-height:40px}.footer{padding-top:19px;color:#777;border-top:1px solid #e5e5e5}@media (min-width:768px){.container{max-width:730px}}.container-narrow>hr{margin:30px 0}.jumbotron{border-bottom:1px solid #e5e5e5}.jumbotron .btn{padding:14px 24px;font-size:21px}.marketing{margin:40px 0}.marketing p+h4{margin-top:28px}@media screen and (min-width:768px){.footer,.header,.marketing{padding-right:0;padding-left:0}.header{margin-bottom:30px}.jumbotron{border-bottom:0}}</style>
|
||||||
|
|
||||||
|
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||||||
|
<!--[if lt IE 9]>
|
||||||
|
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||||
|
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||||
|
<![endif]-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="header clearfix">
|
||||||
|
<nav>
|
||||||
|
<ul class="nav nav-pills pull-right">
|
||||||
|
<li role="presentation"><a href="{% url 'home' %}">Home</a></li>
|
||||||
|
{% if user.is_authenticated %}
|
||||||
|
<li role="presentation"><a href="#">{{ user.email }}</a></li>
|
||||||
|
<li role="presentation"><a href="{% url 'logout' %}">Logout</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li role="presentation"><a href="{% url 'login' %}">Login</a></li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<h3 class="text-muted">django-oidc-provider</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
|
||||||
|
<footer class="footer">
|
||||||
|
<p>Developed by <a href="http://github.com/juanifioren" target="_BLANK">Juan Ignacio Fiorentino</a>.</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</div> <!-- /container -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
11
oidc_provider/tests/templates/home.html
Normal file
11
oidc_provider/tests/templates/home.html
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="jumbotron">
|
||||||
|
<h1>Welcome!</h1>
|
||||||
|
<p class="lead">Django OIDC Provider can help you providing out of the box all the endpoints, data and logic needed to add OpenID Connect capabilities to your Django projects.</p>
|
||||||
|
<p><a class="btn btn-lg btn-success" href="https://github.com/juanifioren/django-oidc-provider" role="button">View on Github</a></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
30
oidc_provider/tests/templates/oidc_provider/authorize.html
Normal file
30
oidc_provider/tests/templates/oidc_provider/authorize.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">Request for Permission</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<p>Client <strong>{{ client.name }}</strong> would like to access this information of you ...</p>
|
||||||
|
|
||||||
|
<form method="post" action="{% url 'oidc_provider:authorize' %}">
|
||||||
|
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
{{ hidden_inputs }}
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% for scope in params.scope %}
|
||||||
|
<li>{{ scope | capfirst }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<input name="allow" class="btn btn-primary btn-lg btn-block" type="submit" value="Authorize" />
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
14
oidc_provider/tests/templates/oidc_provider/error.html
Normal file
14
oidc_provider/tests/templates/oidc_provider/error.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="panel panel-danger">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">{{ error }}</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{{ description }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
90
oidc_provider/tests/test_settings.py
Normal file
90
oidc_provider/tests/test_settings.py
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import os
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
|
DATABASES = {
|
||||||
|
'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',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
LOGGING = {
|
||||||
|
'version': 1,
|
||||||
|
'disable_existing_loggers': False,
|
||||||
|
|
||||||
|
'formatters': {
|
||||||
|
'simple': {
|
||||||
|
'format': '%(asctime)s %(process)d [%(levelname)s] %(name)s Line: %(lineno)s id: %(process)d : %(message)s'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'filters': {
|
||||||
|
'require_debug_false': {
|
||||||
|
'()': 'django.utils.log.RequireDebugFalse',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
|
'console': {
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'filters': ['require_debug_false'],
|
||||||
|
'formatter': 'simple',
|
||||||
|
},
|
||||||
|
'mail_admins': {
|
||||||
|
'level': 'ERROR',
|
||||||
|
'filters': ['require_debug_false'],
|
||||||
|
'class': 'django.utils.log.AdminEmailHandler',
|
||||||
|
'formatter': 'simple',
|
||||||
|
},
|
||||||
|
"debug_file_handler": {
|
||||||
|
"class": "logging.handlers.RotatingFileHandler",
|
||||||
|
"level": "DEBUG",
|
||||||
|
"formatter": "simple",
|
||||||
|
'filename': 'debug.log',
|
||||||
|
'formatter': 'simple',
|
||||||
|
"maxBytes": 10485760,
|
||||||
|
"backupCount": 20,
|
||||||
|
"encoding": "utf8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'loggers': {
|
||||||
|
'oidc_provider': {
|
||||||
|
'handlers': ['console', 'debug_file_handler'],
|
||||||
|
'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTALLED_APPS = (
|
||||||
|
'django.contrib.auth',
|
||||||
|
'django.contrib.contenttypes',
|
||||||
|
'django.contrib.sessions',
|
||||||
|
'django.contrib.sites',
|
||||||
|
'django.contrib.messages',
|
||||||
|
'django.contrib.admin',
|
||||||
|
|
||||||
|
'oidc_provider',
|
||||||
|
)
|
||||||
|
|
||||||
|
SECRET_KEY = 'secret-for-test-secret-top-secret'
|
||||||
|
|
||||||
|
ROOT_URLCONF = 'oidc_provider.tests.test_urls'
|
||||||
|
|
||||||
|
TEMPLATE_DIRS = (
|
||||||
|
"oidc_provider/tests/templates",
|
||||||
|
)
|
||||||
|
|
||||||
|
# OIDC Provider settings.
|
||||||
|
|
||||||
|
SITE_URL = 'http://localhost:8000'
|
15
oidc_provider/tests/test_urls.py
Normal file
15
oidc_provider/tests/test_urls.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
from django.contrib.auth import views as auth_views
|
||||||
|
from django.conf.urls import patterns, include, url
|
||||||
|
from django.contrib import admin
|
||||||
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
url(r'^$', TemplateView.as_view(template_name='home.html'), name='home'),
|
||||||
|
url(r'^accounts/login/$', auth_views.login, {'template_name': 'accounts/login.html'}, name='login'),
|
||||||
|
url(r'^accounts/logout/$', auth_views.logout, {'template_name': 'accounts/logout.html'}, name='logout'),
|
||||||
|
|
||||||
|
url(r'^openid/', include('oidc_provider.urls', namespace='oidc_provider')),
|
||||||
|
|
||||||
|
url(r'^admin/', include(admin.site.urls)),
|
||||||
|
)
|
27
openid_provider/lib/utils/http.py
Normal file
27
openid_provider/lib/utils/http.py
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
from django.core.serializers.json import DjangoJSONEncoder
|
||||||
|
from django.http import HttpResponse
|
||||||
|
|
||||||
|
|
||||||
|
# CLass JsonResponse see: https://github.com/django/django/blob/master/django/http/response.py#L456
|
||||||
|
|
||||||
|
class JsonResponse(HttpResponse):
|
||||||
|
"""
|
||||||
|
An HTTP response class that consumes data to be serialized to JSON.
|
||||||
|
:param data: Data to be dumped into json. By default only ``dict`` objects
|
||||||
|
are allowed to be passed due to a security flaw before EcmaScript 5. See
|
||||||
|
the ``safe`` parameter for more information.
|
||||||
|
:param encoder: Should be an json encoder class. Defaults to
|
||||||
|
``django.core.serializers.json.DjangoJSONEncoder``.
|
||||||
|
:param safe: Controls if only ``dict`` objects may be serialized. Defaults
|
||||||
|
to ``True``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, data, encoder=DjangoJSONEncoder, safe=True, **kwargs):
|
||||||
|
if safe and not isinstance(data, dict):
|
||||||
|
raise TypeError('In order to allow non-dict objects to be serialized set the safe parameter to False')
|
||||||
|
kwargs.setdefault('content_type', 'application/json')
|
||||||
|
data = json.dumps(data, cls=encoder)
|
||||||
|
super(JsonResponse, self).__init__(content=data, **kwargs)
|
83
openid_provider/settings.py
Normal file
83
openid_provider/settings.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultSettings(object):
|
||||||
|
|
||||||
|
@property
|
||||||
|
def LOGIN_URL(self):
|
||||||
|
"""
|
||||||
|
REQUIRED.
|
||||||
|
"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def SITE_URL(self):
|
||||||
|
"""
|
||||||
|
REQUIRED.
|
||||||
|
"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def OIDC_AFTER_USERLOGIN_HOOK(self):
|
||||||
|
"""
|
||||||
|
OPTIONAL.
|
||||||
|
"""
|
||||||
|
def default_hook_func(request, user, client):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return default_hook_func
|
||||||
|
|
||||||
|
@property
|
||||||
|
def OIDC_CODE_EXPIRE(self):
|
||||||
|
"""
|
||||||
|
OPTIONAL.
|
||||||
|
"""
|
||||||
|
return 60*10
|
||||||
|
|
||||||
|
@property
|
||||||
|
def OIDC_EXTRA_SCOPE_CLAIMS(self):
|
||||||
|
"""
|
||||||
|
OPTIONAL.
|
||||||
|
"""
|
||||||
|
from oidc_provider.lib.claims import AbstractScopeClaims
|
||||||
|
|
||||||
|
return AbstractScopeClaims
|
||||||
|
|
||||||
|
@property
|
||||||
|
def OIDC_IDTOKEN_EXPIRE(self):
|
||||||
|
"""
|
||||||
|
OPTIONAL.
|
||||||
|
"""
|
||||||
|
return 60*10
|
||||||
|
|
||||||
|
@property
|
||||||
|
def OIDC_IDTOKEN_SUB_GENERATOR(self):
|
||||||
|
"""
|
||||||
|
OPTIONAL.
|
||||||
|
"""
|
||||||
|
def default_sub_generator(user):
|
||||||
|
return user.id
|
||||||
|
|
||||||
|
return default_sub_generator
|
||||||
|
|
||||||
|
@property
|
||||||
|
def OIDC_TOKEN_EXPIRE(self):
|
||||||
|
"""
|
||||||
|
OPTIONAL.
|
||||||
|
"""
|
||||||
|
return 60*60
|
||||||
|
|
||||||
|
default_settings = DefaultSettings()
|
||||||
|
|
||||||
|
def get(name):
|
||||||
|
'''
|
||||||
|
Helper function to use inside the package.
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
value = getattr(default_settings, name)
|
||||||
|
value = getattr(settings, name)
|
||||||
|
except AttributeError:
|
||||||
|
if value == None:
|
||||||
|
raise Exception('You must set ' + name + ' in your settings.')
|
||||||
|
|
||||||
|
return value
|
4
setup.py
4
setup.py
|
@ -33,6 +33,10 @@ setup(
|
||||||
'Topic :: Internet :: WWW/HTTP',
|
'Topic :: Internet :: WWW/HTTP',
|
||||||
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
|
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
|
||||||
],
|
],
|
||||||
|
tests_require=[
|
||||||
|
'pyjwt==1.1.0'
|
||||||
|
],
|
||||||
|
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'pyjwt==1.1.0',
|
'pyjwt==1.1.0',
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in a new issue