remove authentic2_idp_openid (fixes #23515)
Code is no more used nor maintained. Also remove diagnose.py which is obsolete too and referrred to django-authopenid (and south and other obsolete things). Mentions of OpenID libraries licenses were removed from license files.
This commit is contained in:
parent
ad4b1fe051
commit
d0bcf4a992
3
COPYING
3
COPYING
|
@ -662,6 +662,3 @@ specific requirements.
|
|||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
OpenID idp module is derived of the project django_openid_provider which is
|
||||
distributed under the Apache 2.0 license.
|
||||
|
|
|
@ -13,7 +13,6 @@ recursive-include src/authentic2/manager/static *.css *.js *.png
|
|||
recursive-include src/authentic2/saml/templates *.html *.txt *.xml
|
||||
recursive-include src/authentic2/templates *.html *.txt *.xml
|
||||
recursive-include src/authentic2/idp/templates *.html *.txt *.xml
|
||||
recursive-include src/authentic2_idp_openid/templates *.html *.txt *.xml
|
||||
recursive-include src/authentic2_idp_cas/templates *.html *.txt *.xml
|
||||
recursive-include src/authentic2/idp/saml/templates *.html *.txt *.xml
|
||||
recursive-include src/authentic2/auth2_auth/auth2_ssl/templates *.html *.txt *.xml
|
||||
|
@ -30,7 +29,6 @@ recursive-include src/authentic2/locale *.po *.mo
|
|||
recursive-include src/authentic2/saml/locale *.po *.mo
|
||||
recursive-include src/authentic2/idp/locale *.po *.mo
|
||||
recursive-include src/authentic2/idp/saml/locale *.po *.mo
|
||||
recursive-include src/authentic2_idp_openid/locale *.po *.mo
|
||||
recursive-include src/authentic2_idp_cas/locale *.po *.mo
|
||||
recursive-include src/authentic2/auth2_auth/locale *.po *.mo
|
||||
recursive-include src/authentic2/auth2_auth/auth2_ssl/locale *.po *.mo
|
||||
|
|
11
README
11
README
|
@ -7,7 +7,7 @@ broad range of needs, from simple to complex setups; it has support for many
|
|||
protocols and can bridge between them.
|
||||
|
||||
Authentic 2 supports many protocols and standards, including SAML2, CAS,
|
||||
OpenID, LDAP, X509 and OAUTH2.
|
||||
LDAP, X509 and OAUTH2.
|
||||
|
||||
Authentic 2 is under the GNU AGPL version 3 licence.
|
||||
|
||||
|
@ -23,14 +23,13 @@ Features
|
|||
--------
|
||||
|
||||
* SAML 2.0 Identity and service provider
|
||||
* OpenID 1.0 and 2.0 identity provider
|
||||
* Server CAS 1.0 and 2.0 using a plugin
|
||||
* Standards authentication mechanisms:
|
||||
|
||||
* Login/password through internal directory or LDAP
|
||||
* X509 certificate over SSL/TLS
|
||||
|
||||
* Protocol proxying, for instance between OpenID and SAML
|
||||
* Protocol proxying
|
||||
* Support of LDAP v2 and v3 directories
|
||||
* Support of the PAM backend
|
||||
* One-time password (OATH and Google-Authenticator) using a plugin
|
||||
|
@ -89,9 +88,3 @@ Copyright
|
|||
Authentic is copyrighted by Entr'ouvert and is licensed through the GNU Affero
|
||||
General Public Licence, version 3 or later. A copy of the whole license text
|
||||
is available in the COPYING file.
|
||||
|
||||
The OpenID IdP originates in the project django_openid_provider by Roman
|
||||
Barczy¿ski, which is under the Apache 2.0 licence. This imply that you must
|
||||
distribute authentic2 under the AGPL3 licence when distributing this part of
|
||||
the project which is the only AGPL licence version compatible with the
|
||||
Apache 2.0 licence.
|
||||
|
|
|
@ -29,10 +29,8 @@ export SAML_SIGNATURE_PRIVATE_KEY="`cat /etc/authentic2/key.pem`"
|
|||
|
||||
# Enables some features
|
||||
#export IDP_SAML2='yes'
|
||||
#export IDP_OPENID='yes' # require package python-openid
|
||||
#export IDP_CAS='yes'
|
||||
#export AUTH_SAML2='yes'
|
||||
#export AUTH_OPENID='yes' # require package python-openid
|
||||
#export AUTH_SSL='yes'
|
||||
|
||||
# Sentry / Raven configuration
|
||||
|
|
|
@ -31,7 +31,7 @@ Depends: ${misc:Depends}, ${python:Depends},
|
|||
python-django-filters (>= 1),
|
||||
python-django-filters (<< 2)
|
||||
Provides: ${python:Provides}
|
||||
Recommends: python-openid, python-ldap
|
||||
Recommends: python-ldap
|
||||
Suggests: python-raven
|
||||
Description: Versatile identity server
|
||||
Authentic is a versatile identity provider aiming to address a broad
|
||||
|
|
|
@ -672,6 +672,3 @@ For more information on this, and how to apply and follow the GNU AGPL, see
|
|||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
External modules oath and totp-js modules are licensed under a BSD-like licence.
|
||||
|
||||
OpenID idp module is derived of the project django_openid_provider which is
|
||||
distributed under the Apache 2.0 license.
|
||||
|
|
|
@ -137,8 +137,6 @@ def extract_settings_from_environ():
|
|||
'A2_AUTH_PASSWORD_ENABLE',
|
||||
'SSLAUTH_ENABLE',
|
||||
'A2_IDP_SAML2_ENABLE',
|
||||
'IDP_OPENID',
|
||||
|
||||
)
|
||||
|
||||
def to_boolean(name, default=True):
|
||||
|
|
|
@ -64,8 +64,6 @@ TIME_ZONE = 'Europe/Paris'
|
|||
#A2_IDP_SAML2_ENABLE = False
|
||||
# CAS 1.0 / 2.0 IDP
|
||||
#A2_IDP_CAS_ENABLE = False
|
||||
# OpenID 1.0 / 2.0 IDP
|
||||
#A2_IDP_OPENID_ENABLE = False
|
||||
|
||||
# Authentifications
|
||||
#A2_AUTH_PASSWORD_ENABLE = True
|
||||
|
|
|
@ -29,10 +29,8 @@ export SAML_SIGNATURE_PRIVATE_KEY="`cat /etc/authentic2/key.pem`"
|
|||
|
||||
# Enables some features
|
||||
#export IDP_SAML2='yes'
|
||||
#export IDP_OPENID='yes' # require package python-openid
|
||||
#export IDP_CAS='yes'
|
||||
#export AUTH_SAML2='yes'
|
||||
#export AUTH_OPENID='yes' # require package python-openid
|
||||
#export AUTH_SSL='yes'
|
||||
|
||||
# Sentry / Raven configuration
|
||||
|
|
|
@ -28,7 +28,7 @@ Depends: ${misc:Depends}, ${python:Depends},
|
|||
python-six (>= 1.0),
|
||||
python-django-filters (>= 1)
|
||||
Provides: ${python:Provides}
|
||||
Recommends: python-openid, python-ldap
|
||||
Recommends: python-ldap
|
||||
Suggests: python-raven
|
||||
Description: Versatile identity server
|
||||
Authentic is a versatile identity provider aiming to address a broad
|
||||
|
|
|
@ -672,6 +672,3 @@ For more information on this, and how to apply and follow the GNU AGPL, see
|
|||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
External modules oath and totp-js modules are licensed under a BSD-like licence.
|
||||
|
||||
OpenID idp module is derived of the project django_openid_provider which is
|
||||
distributed under the Apache 2.0 license.
|
||||
|
|
|
@ -140,8 +140,6 @@ def extract_settings_from_environ():
|
|||
'A2_AUTH_PASSWORD_ENABLE',
|
||||
'SSLAUTH_ENABLE',
|
||||
'A2_IDP_SAML2_ENABLE',
|
||||
'IDP_OPENID',
|
||||
|
||||
)
|
||||
|
||||
def to_boolean(name, default=True):
|
||||
|
|
|
@ -64,8 +64,6 @@ TIME_ZONE = 'Europe/Paris'
|
|||
#A2_IDP_SAML2_ENABLE = False
|
||||
# CAS 1.0 / 2.0 IDP
|
||||
#A2_IDP_CAS_ENABLE = False
|
||||
# OpenID 1.0 / 2.0 IDP
|
||||
#A2_IDP_OPENID_ENABLE = False
|
||||
|
||||
# Authentifications
|
||||
#A2_AUTH_PASSWORD_ENABLE = True
|
||||
|
|
|
@ -11,13 +11,12 @@ Index: authentic2/setup.py
|
|||
'XStatic-jQuery',
|
||||
'XStatic-jquery-ui',
|
||||
'xstatic-select2',
|
||||
@@ -163,11 +161,9 @@ setup(name="authentic2",
|
||||
@@ -163,10 +161,8 @@ setup(name="authentic2",
|
||||
'authentic2.plugin': [
|
||||
'authentic2-auth-ssl = authentic2.auth2_auth.auth2_ssl:Plugin',
|
||||
'authentic2-auth-saml = authentic2_auth_saml:Plugin',
|
||||
- 'authentic2-auth-oidc = authentic2_auth_oidc:Plugin',
|
||||
'authentic2-idp-saml2 = authentic2.idp.saml:Plugin',
|
||||
'authentic2-idp-openid = authentic2_idp_openid:Plugin',
|
||||
'authentic2-idp-cas = authentic2_idp_cas:Plugin',
|
||||
- 'authentic2-idp-oidc = authentic2_idp_oidc:Plugin',
|
||||
'authentic2-provisionning-ldap = authentic2_provisionning_ldap:Plugin',
|
||||
|
|
21
diagnose.py
21
diagnose.py
|
@ -1,21 +0,0 @@
|
|||
import os
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'authentic2.settings'
|
||||
try:
|
||||
import django
|
||||
print 'Django:', django.get_version()
|
||||
except ImportError:
|
||||
print 'django is missing: easy_install django'
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
import south
|
||||
print 'South:', south.__version__
|
||||
except ImportError:
|
||||
print 'south is missing: easy_isntall south'
|
||||
try:
|
||||
import django_authopenid
|
||||
print 'Django-authopenid:', django_authopenid.__version__
|
||||
except ImportError:
|
||||
raise
|
||||
print 'django_authopenid is missing: easy_install django-authopenid'
|
||||
|
|
@ -8,11 +8,5 @@ Authentic and Authentic 2 are copyrighted by Entr'ouvert and are licensed
|
|||
through the GNU AFFERO GENERAL PUBLIC LICENSE, version 3 or later. A copy of
|
||||
the whole license text is available in the COPYING file.
|
||||
|
||||
The OpenID IdP originates in the project django_openid_provider by Roman
|
||||
Barczyski, which is under the Apache 2.0 licence. This imply that you must
|
||||
distribute authentic2 under the AGPL3 licence when distributing this part of the
|
||||
project which is the only AGPL licence version compatible with the Apache 2.0
|
||||
licence.
|
||||
|
||||
The Documentation is under the licence Creative Commons
|
||||
`CC BY-SA 2.0 <http://creativecommons.org/licenses/by-sa/2.0/>`_.
|
||||
|
|
|
@ -86,16 +86,6 @@ If SAML_ENCRYPTION_PUBLIC_KEY or SAML_ENCRYPTION_PRIVATE_KEY are not given,
|
|||
the signature keys are used for encryption.
|
||||
|
||||
|
||||
Activate or deactivate Authentic 2 as an OpenID provider
|
||||
========================================================
|
||||
|
||||
Variable: IDP_OPENID
|
||||
|
||||
Values:
|
||||
|
||||
* False: deactivate OpenID provider
|
||||
* True: activate OpenID provider
|
||||
|
||||
Activate or deactivate Authentic 2 as a CAS server
|
||||
==================================================
|
||||
|
||||
|
|
|
@ -5,9 +5,6 @@ SECRET_KEY = 'changeme'
|
|||
# Activate SAML 2 idp
|
||||
A2_IDP_SAML2_ENABLE = True
|
||||
|
||||
# Activate OpenID idp
|
||||
A2_IDP_OPENID_ENABLE = True
|
||||
|
||||
# Debugging helper
|
||||
try:
|
||||
import debug_toolbar
|
||||
|
|
4
setup.py
4
setup.py
|
@ -133,9 +133,6 @@ setup(name="authentic2",
|
|||
'XStatic-jquery-ui<1.12',
|
||||
'xstatic-select2',
|
||||
],
|
||||
extras_require = {
|
||||
'idp-openid': ['python-openid'],
|
||||
},
|
||||
zip_safe=False,
|
||||
classifiers=[
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
|
@ -165,7 +162,6 @@ setup(name="authentic2",
|
|||
'authentic2-auth-saml = authentic2_auth_saml:Plugin',
|
||||
'authentic2-auth-oidc = authentic2_auth_oidc:Plugin',
|
||||
'authentic2-idp-saml2 = authentic2.idp.saml:Plugin',
|
||||
'authentic2-idp-openid = authentic2_idp_openid:Plugin',
|
||||
'authentic2-idp-cas = authentic2_idp_cas:Plugin',
|
||||
'authentic2-idp-oidc = authentic2_idp_oidc:Plugin',
|
||||
'authentic2-provisionning-ldap = authentic2_provisionning_ldap:Plugin',
|
||||
|
|
|
@ -67,7 +67,6 @@ class CustomIndexDashboard(Dashboard):
|
|||
'authentic2.models.AuthenticationEvent',
|
||||
'authentic2.models.UserExternalId',
|
||||
'authentic2.models.DeletedUser',
|
||||
'authentic2.idp.idp_openid.models.*',
|
||||
'django.contrib.sessions.*',
|
||||
),
|
||||
))
|
||||
|
|
|
@ -140,7 +140,7 @@ def fill_assertion(request, saml_request, assertion, provider_id, nid_format):
|
|||
policy.
|
||||
|
||||
TODO: determine and add attributes from the session, for anonymous users
|
||||
(pseudonymous federation, openid without accounts)
|
||||
(pseudonymous federation)
|
||||
# TODO: add information from the login event, of the session or linked
|
||||
# to the request id
|
||||
# TODO: use information from the consent event to specialize release of
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
||||
try:
|
||||
import openid
|
||||
except ImportError:
|
||||
from . import app_settings
|
||||
if app_settings.ENABLE:
|
||||
raise ImproperlyConfigured('OpenID idp is enabled by python-openid is not installed')
|
||||
class Plugin(object):
|
||||
pass
|
||||
else:
|
||||
class Plugin(object):
|
||||
def get_before_urls(self):
|
||||
from . import app_settings
|
||||
from django.conf.urls import patterns, include
|
||||
from authentic2.decorators import (setting_enabled, required,
|
||||
lasso_required)
|
||||
|
||||
return required(
|
||||
(
|
||||
setting_enabled('ENABLE', settings=app_settings),
|
||||
lasso_required()
|
||||
),
|
||||
patterns('',
|
||||
(r'^idp/openid/', include(__name__ + '.urls'))))
|
||||
|
||||
def get_apps(self):
|
||||
return [__name__]
|
||||
|
||||
def get_admin_modules(self):
|
||||
from admin_tools.dashboard import modules
|
||||
return [modules.ModelList(
|
||||
_('OpenID'),
|
||||
models=(
|
||||
'%s.models.*' % __name__,
|
||||
),
|
||||
)]
|
||||
|
||||
def get_idp_backends(self):
|
||||
return ['%s.backend.OpenIDBackend' % __name__]
|
||||
|
||||
def get_before_middleware(self):
|
||||
return ['%s.middleware.OpenIDMiddleware' % __name__]
|
|
@ -1,8 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.contrib import admin
|
||||
from models import TrustedRoot, Association, Nonce
|
||||
|
||||
admin.site.register(TrustedRoot)
|
||||
admin.site.register(Association)
|
||||
admin.site.register(Nonce)
|
|
@ -1,34 +0,0 @@
|
|||
class AppSettings(object):
|
||||
__DEFAULTS = dict(
|
||||
ENABLE=False,
|
||||
OPENID_ACTIONS={},
|
||||
)
|
||||
|
||||
def __init__(self, prefix):
|
||||
self.prefix = prefix
|
||||
|
||||
def _setting(self, name, dflt):
|
||||
from django.conf import settings
|
||||
return getattr(settings, name, dflt)
|
||||
|
||||
def _setting_with_prefix(self, name, dflt):
|
||||
return self._setting(self.prefix + name, dflt)
|
||||
|
||||
@property
|
||||
def ENABLE(self):
|
||||
return self._setting_with_prefix('ENABLE',
|
||||
self._settings('IDP_OPENID',
|
||||
self.__DEFAULTS['ENABLE']))
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name not in self.__DEFAULTS:
|
||||
raise AttributeError(name)
|
||||
return self._setting_with_prefix(name, self.__DEFAULTS[name])
|
||||
|
||||
|
||||
# Ugly? Guido recommends this himself ...
|
||||
# http://mail.python.org/pipermail/python-ideas/2012-May/014969.html
|
||||
import sys
|
||||
app_settings = AppSettings('A2_IDP_OPENID_')
|
||||
app_settings.__name__ = __name__
|
||||
sys.modules[__name__] = app_settings
|
|
@ -1,30 +0,0 @@
|
|||
import logging
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from authentic2.utils import Service
|
||||
|
||||
from . import models, app_settings
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OpenIDBackend(object):
|
||||
def service_list(self, request):
|
||||
if not request.user.is_authenticated():
|
||||
return ()
|
||||
q = models.TrustedRoot.objects.filter(user=request.user.id)
|
||||
ls = []
|
||||
for service_provider in q:
|
||||
actions = []
|
||||
actions.append(('go', 'GET', service_provider.trust_root, None))
|
||||
if app_settings.OPENID_ACTIONS:
|
||||
tpl = app_settings.OPENID_ACTIONS.get(service_provider.trust_root, None)
|
||||
if tpl:
|
||||
actions.append(('template', tpl))
|
||||
actions.append(('unlink', 'GET', reverse('trustedroot_delete',
|
||||
kwargs={'pk': service_provider.id}), None))
|
||||
ls.append(Service(url=None, name=service_provider.trust_root,
|
||||
actions=actions))
|
||||
return ls
|
|
@ -1,11 +0,0 @@
|
|||
import os
|
||||
import tempfile
|
||||
from django.conf import settings
|
||||
|
||||
tempdir = tempfile.gettempdir()
|
||||
|
||||
STORE = getattr(settings, 'OPENID_PROVIDER_STORE',
|
||||
'authentic2.idp.idp_openid.openid_store.DjangoOpenIDStore')
|
||||
|
||||
FILESTORE_PATH = getattr(settings, 'OPENID_PROVIDER_FILESTORE_PATH',
|
||||
os.path.join(tempdir, 'openid-filestore'))
|
|
@ -1,7 +0,0 @@
|
|||
from authentic2.decorators import setting_enabled
|
||||
|
||||
from . import app_settings
|
||||
|
||||
def openid_enabled(func):
|
||||
return setting_enabled('ENABLE', app_settings)(func)
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
# authentic2 idp openid french l10n
|
||||
# Copyright (C) 2015 Entr'ouvert
|
||||
# This file is distributed under the same license as the Authentic package.
|
||||
# Frederic Peters <fpeters@entrouvert.com>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Authentic\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-01-24 12:02+0100\n"
|
||||
"PO-Revision-Date: 2018-01-24 12:12+0100\n"
|
||||
"Last-Translator: Mikaël Ates <mates@entrouvert.com>\n"
|
||||
"Language-Team: None\n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n>1;\n"
|
||||
|
||||
#: src/authentic2_idp_openid/__init__.py:34
|
||||
msgid "OpenID"
|
||||
msgstr "Gérer la connexion OpenID"
|
||||
|
||||
#: src/authentic2_idp_openid/models.py:35
|
||||
msgid "trusted root"
|
||||
msgstr "Site de confiance"
|
||||
|
||||
#: src/authentic2_idp_openid/models.py:36
|
||||
msgid "trusted roots"
|
||||
msgstr "Sites de confiance"
|
||||
|
||||
#: src/authentic2_idp_openid/models.py:57
|
||||
msgid "association"
|
||||
msgstr "association"
|
||||
|
||||
#: src/authentic2_idp_openid/models.py:58
|
||||
msgid "associations"
|
||||
msgstr "associations"
|
||||
|
||||
#: src/authentic2_idp_openid/models.py:125
|
||||
msgid "nonce"
|
||||
msgstr "nonce"
|
||||
|
||||
#: src/authentic2_idp_openid/models.py:126
|
||||
msgid "nonces"
|
||||
msgstr "nonces"
|
||||
|
||||
#: src/authentic2_idp_openid/templates/django_openid_provider/manage_id.html:5
|
||||
#: src/authentic2_idp_openid/templates/django_openid_provider/manage_id_confirm.html:5
|
||||
msgid "Manage OpenID"
|
||||
msgstr "Gérer la connexion OpenID"
|
||||
|
||||
#: src/authentic2_idp_openid/templates/django_openid_provider/manage_id.html:23
|
||||
msgid "Your current OpenID"
|
||||
msgstr "Vos identifiants OpenID actuels"
|
||||
|
||||
#: src/authentic2_idp_openid/templates/django_openid_provider/manage_id.html:52
|
||||
msgid "Add a new OpenID identity"
|
||||
msgstr "Ajouter une nouvelle identité OpenID"
|
||||
|
||||
#: src/authentic2_idp_openid/templates/django_openid_provider/manage_trustroot.html:5
|
||||
msgid "Manage trusted site"
|
||||
msgstr "Gérer vos sites de confiance"
|
||||
|
||||
#: src/authentic2_idp_openid/templates/django_openid_provider/manage_trustroot.html:17
|
||||
msgid "Your trusted site"
|
||||
msgstr "Vos sites de confiance"
|
||||
|
||||
#: src/authentic2_idp_openid/templates/idp/openid/trustedroot_confirm_delete.html:5
|
||||
msgid "Remove Link ?"
|
||||
msgstr "Supprimer le lien ?"
|
||||
|
||||
#: src/authentic2_idp_openid/templates/idp/openid/trustedroot_confirm_delete.html:7
|
||||
msgid "Are you sure you want to delete link with"
|
||||
msgstr "Êtes-vous sûr de vouloir supprimer le lien avec"
|
||||
|
||||
#: src/authentic2_idp_openid/templates/idp/openid/trustedroot_confirm_delete.html:10
|
||||
msgid "Back"
|
||||
msgstr "Retour"
|
||||
|
||||
#: src/authentic2_idp_openid/views.py:278
|
||||
msgid "Trust this site?"
|
||||
msgstr "Faire confiance à ce site ?"
|
|
@ -1,13 +0,0 @@
|
|||
from django.core.urlresolvers import reverse
|
||||
|
||||
from . import views
|
||||
|
||||
class OpenIDMiddleware(object):
|
||||
'''Add OpenID discovery header to all responses,
|
||||
if Accept header is 'application/xrds+xml' also return an XRDS document.
|
||||
'''
|
||||
def process_response(self, request, response):
|
||||
response['X-XRDS-Location'] = request.build_absolute_uri(reverse('a2-idp-openid-xrds'))
|
||||
if request.META.get('HTTP_ACCEPT') == 'application/xrds+xml':
|
||||
return views.openid_xrds(request)
|
||||
return response
|
|
@ -1,17 +0,0 @@
|
|||
"""utils to help rename apps and South migrations"""
|
||||
import os
|
||||
from south.models import MigrationHistory
|
||||
|
||||
def was_applied(migration_file_path, app_name):
|
||||
"""true if migration with a given file name ``migration_file``
|
||||
was applied to app with name ``app_name``"""
|
||||
try:
|
||||
migration_file = os.path.basename(migration_file_path)
|
||||
migration_name = migration_file.split('.')[0]
|
||||
MigrationHistory.objects.get(
|
||||
app_name = app_name,
|
||||
migration = migration_name
|
||||
)
|
||||
return True
|
||||
except MigrationHistory.DoesNotExist:
|
||||
return False
|
|
@ -1,71 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import authentic2.saml.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Association',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('server_url', models.CharField(max_length=768)),
|
||||
('handle', models.CharField(max_length=255)),
|
||||
('secret', authentic2.saml.fields.PickledObjectField(editable=False)),
|
||||
('issued', models.DateTimeField(verbose_name=b'Issue time for this association, as seconds since EPOCH', editable=False)),
|
||||
('lifetime', models.IntegerField(verbose_name=b'Lifetime of this association as seconds since the issued time')),
|
||||
('expire', models.DateTimeField(verbose_name=b'After this time, the association will be expired')),
|
||||
('assoc_type', models.CharField(max_length=64)),
|
||||
],
|
||||
options={
|
||||
'db_table': 'idp_openid_association',
|
||||
'verbose_name': 'association',
|
||||
'verbose_name_plural': 'associations',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Nonce',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('salt', models.CharField(max_length=40)),
|
||||
('server_url', models.CharField(max_length=768)),
|
||||
('timestamp', models.IntegerField()),
|
||||
],
|
||||
options={
|
||||
'db_table': 'idp_openid_nonce',
|
||||
'verbose_name': 'nonce',
|
||||
'verbose_name_plural': 'nonces',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TrustedRoot',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('user', models.CharField(max_length=255)),
|
||||
('trust_root', models.CharField(max_length=200)),
|
||||
('choices', authentic2.saml.fields.PickledObjectField()),
|
||||
],
|
||||
options={
|
||||
'db_table': 'idp_openid_trustedroot',
|
||||
'verbose_name': 'trusted root',
|
||||
'verbose_name_plural': 'trusted roots',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='nonce',
|
||||
unique_together=set([('server_url', 'salt')]),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='association',
|
||||
unique_together=set([('server_url', 'handle')]),
|
||||
),
|
||||
]
|
|
@ -1,149 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vim: set ts=4 sw=4 : */
|
||||
|
||||
import datetime
|
||||
import time
|
||||
import calendar
|
||||
|
||||
import openid.association
|
||||
import openid.store.nonce
|
||||
from django.db import models
|
||||
from django.utils.timezone import now, utc
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from authentic2.saml.fields import PickledObjectField
|
||||
|
||||
|
||||
def utctimestamp_to_aware_datetime(tst):
|
||||
if settings.USE_TZ:
|
||||
return datetime.datetime.utcfromtimestamp(tst) \
|
||||
.replace(tz_info=utc)
|
||||
else:
|
||||
return datetime.datetime.utcfromtimestamp(tst)
|
||||
|
||||
|
||||
class TrustedRoot(models.Model):
|
||||
user = models.CharField(max_length=255)
|
||||
trust_root = models.CharField(max_length=200)
|
||||
choices = PickledObjectField()
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.trust_root)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('trusted root')
|
||||
verbose_name_plural = _('trusted roots')
|
||||
db_table = 'idp_openid_trustedroot' # app was named idp_openid before
|
||||
|
||||
|
||||
|
||||
class Association(models.Model):
|
||||
server_url = models.CharField(max_length=768, blank=False)
|
||||
handle = models.CharField(max_length=255, blank=False)
|
||||
secret = PickledObjectField(editable=False)
|
||||
issued = models.DateTimeField(editable=False,
|
||||
verbose_name="Issue time for this association, as seconds \
|
||||
since EPOCH")
|
||||
lifetime = models.IntegerField(
|
||||
verbose_name="Lifetime of this association as seconds since \
|
||||
the issued time")
|
||||
expire = models.DateTimeField("After this time, the association will \
|
||||
be expired")
|
||||
assoc_type = models.CharField(max_length=64, blank=False)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('server_url', 'handle')
|
||||
verbose_name = _('association')
|
||||
verbose_name_plural = _('associations')
|
||||
db_table = 'idp_openid_association' # app was named idp_openid before
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
'''Overload default save() method to compute the expire field'''
|
||||
self.issued = now()
|
||||
self.expire = self.issued + datetime.timedelta(seconds=self.lifetime)
|
||||
super(Association, self).save(*args, **kwargs)
|
||||
|
||||
def to_association(self):
|
||||
'''Convert a model instance to an Association object of the openid
|
||||
library.
|
||||
'''
|
||||
return openid.association.Association(handle=self.handle,
|
||||
secret=self.secret,
|
||||
issued=calendar.timegm(self.issued.utctimetuple()),
|
||||
lifetime=self.lifetime,
|
||||
assoc_type=self.assoc_type)
|
||||
|
||||
@classmethod
|
||||
def get_association(cls, server_url, handle=None):
|
||||
try:
|
||||
filter = cls.objects.filter(server_url=server_url,
|
||||
expire__gt=now())
|
||||
if handle is not None:
|
||||
filter = filter.filter(handle=handle)
|
||||
return filter.latest('issued').to_association()
|
||||
except cls.DoesNotExist:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def cleanup_associations(cls):
|
||||
filter = cls.objects.filter(expire__lt=now())
|
||||
count = filter.count()
|
||||
filter.delete()
|
||||
return count
|
||||
|
||||
@classmethod
|
||||
def remove_association(cls, server_url, handle=None):
|
||||
filter = cls.objects.filter(server_url=server_url)
|
||||
if handle is not None:
|
||||
filter = filter.filter(handle=handle)
|
||||
filter.delete()
|
||||
|
||||
@classmethod
|
||||
def store_association(cls, server_url, association):
|
||||
Association(server_url=server_url,
|
||||
handle=association.handle,
|
||||
secret=association.secret,
|
||||
issued=utctimestamp_to_aware_datetime(association.issued),
|
||||
lifetime=association.lifetime,
|
||||
assoc_type=association.assoc_type).save()
|
||||
|
||||
class NonceManager(models.Manager):
|
||||
def cleanup(self):
|
||||
expire = openid.store.nonce.SKEW
|
||||
timestamp = calendar.timegm(now().utctimetuple())
|
||||
self.filter(timestamp__lt=timestamp-expire).delete()
|
||||
|
||||
class Nonce(models.Model):
|
||||
salt = models.CharField(max_length=40)
|
||||
server_url = models.CharField(max_length=768)
|
||||
timestamp = models.IntegerField()
|
||||
|
||||
objects = NonceManager()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('nonce')
|
||||
verbose_name_plural = _('nonces')
|
||||
unique_together = ('server_url', 'salt')
|
||||
db_table = 'idp_openid_nonce' # app was named idp_openid before
|
||||
|
||||
@classmethod
|
||||
def use_nonce(cls, server_url, timestamp, salt):
|
||||
now = time.time()
|
||||
if timestamp > now or timestamp + openid.store.nonce.SKEW < now:
|
||||
return False
|
||||
|
||||
n, created = cls.objects.get_or_create(server_url=server_url,
|
||||
salt=salt)
|
||||
if created:
|
||||
n.timestamp = timestamp
|
||||
n.save()
|
||||
return created
|
||||
|
||||
@classmethod
|
||||
def cleanup_nonces(cls):
|
||||
filter = cls.objects.filter(
|
||||
timestamp_lt=time.time()-openid.store.nonce.SKEW)
|
||||
count = filter.count()
|
||||
filter.delete()
|
||||
return count
|
|
@ -1,38 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vim: set ts=4 sw=4 : */
|
||||
|
||||
import time
|
||||
|
||||
import openid.store.interface
|
||||
from django.conf import settings
|
||||
|
||||
import models
|
||||
from authentic2 import nonce
|
||||
|
||||
|
||||
NONCE_TIMEOUT = getattr(settings, 'OPENID_NONCE_TIMEOUT',
|
||||
getattr(settings, 'NONCE_TIMEOUT', openid.store.nonce.SKEW))
|
||||
|
||||
class DjangoOpenIDStore(openid.store.interface.OpenIDStore):
|
||||
def cleanupAssociations(self):
|
||||
return models.Association.cleanup_associations()
|
||||
|
||||
def cleanupNonces(self):
|
||||
nonce.cleanup_nonces()
|
||||
|
||||
def storeAssociation(self, server_url, association):
|
||||
return models.Association.store_association(server_url, association)
|
||||
|
||||
def getAssociation(self, server_url, handle=None):
|
||||
return models.Association.get_association(server_url, handle)
|
||||
|
||||
def removeAssociation(self, server_url, handle):
|
||||
return models.Association.remove_association(server_url, handle)
|
||||
|
||||
def useNonce(self, server_url, timestamp, salt):
|
||||
now = time.time()
|
||||
if not (timestamp < now < (timestamp + NONCE_TIMEOUT)):
|
||||
return False
|
||||
value = '%s_%s_%s' % (server_url, timestamp, salt)
|
||||
|
||||
return nonce.accept_nonce(value, 'OpenID', NONCE_TIMEOUT)
|
|
@ -1,64 +0,0 @@
|
|||
{% extends "authentic2/base-page.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Manage OpenID" %}
|
||||
{% endblock %}
|
||||
|
||||
{% load breadcrumbs %}
|
||||
{% block breadcrumbs %}
|
||||
{{ block.super }}
|
||||
{% breadcrumb_url 'Manage OpenID' 'manage_id' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if message %}
|
||||
<ul class="errorlist">{{ message }}</ul>
|
||||
{% endif %}
|
||||
<p>
|
||||
{% if nb_openids > 0 %}
|
||||
<a href="/openid/manage/">Manage your trusted site</a>
|
||||
</p>
|
||||
<fieldset>
|
||||
<legend>{% trans "Your current OpenID" %}</legend>
|
||||
<p> Choose your identities to remove, be careful this will remove all the trusted site for these identities.
|
||||
You can change your default OpenID by clicking on "Make Default"
|
||||
</p>
|
||||
<form action="." id="form1" method="post">
|
||||
{% csrf_token %}
|
||||
{% for key,value in openids.items %}
|
||||
<p> <h4> {{ uri }}{{ oipath }}/{{ value.caption }}/
|
||||
{% if value.Default %}
|
||||
(Default)
|
||||
{% endif %}
|
||||
</h4>
|
||||
{% for key2, value2 in value.trustroot.items %}
|
||||
<li class="indented"> {{ value2 }} </li>
|
||||
{% empty %}
|
||||
There is no trusted site for this identity.
|
||||
{% endfor %}
|
||||
{% if not value.Default %}
|
||||
<input type = "submit" name= {{ value.caption }} value = "Make default" />
|
||||
{% endif %}
|
||||
<input type = "submit" name = {{ value.caption }} value = "Remove"/>
|
||||
</p>
|
||||
{% endfor %}
|
||||
</form>
|
||||
</fieldset>
|
||||
{% else %}
|
||||
<p> You have no OpenID account for the moment</p>
|
||||
{% endif %}
|
||||
<fieldset>
|
||||
<legend>{% trans "Add a new OpenID identity" %} </legend>
|
||||
<p>
|
||||
<form action = "/openid/addopenid/" id = "form2" method = "post">
|
||||
{% csrf_token %}
|
||||
<p> Leave blank to create an anonymous OpenID</p>
|
||||
{{ uri }}{{ oipath }}/{{ form.openid }}/
|
||||
{{ form.Default }}
|
||||
Check if you want this OpenID account become your default OpenID account.
|
||||
<input type = "submit" value = "Add" />
|
||||
</p>
|
||||
</form>
|
||||
</fieldset>
|
||||
{% endblock %}
|
|
@ -1,19 +0,0 @@
|
|||
{% extends "authentic2/base-page.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Manage OpenID" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form action = "/openid/manageid_confirm/" id = "form" method = "post">
|
||||
{% csrf_token %}
|
||||
<p>Are you sure, you want to delete <strong> {{ id }} </strong> and these trusted site:</p>
|
||||
{% for i in trust %}
|
||||
{{ i }}
|
||||
{% endfor %}
|
||||
<input type = "hidden" name = "idremove" value = {{ id }}>
|
||||
<input type = "submit" value = "Yes" name = "Answer" />
|
||||
<input type = "submit" value = "No" name = "Answer" />
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,37 +0,0 @@
|
|||
{% extends "authentic2/base-page.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}
|
||||
{% trans "Manage trusted site" %}
|
||||
{% endblock %}
|
||||
|
||||
{% load breadcrumbs %}
|
||||
{% block breadcrumbs %}
|
||||
{{ block.super }}
|
||||
{% breadcrumb_url 'Manage OpenID' 'manage_id' %}
|
||||
{% breadcrumb_url 'Manage trusted site' 'manage_trustroot' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<fieldset>
|
||||
<legend>{% trans "Your trusted site" %} </legend>
|
||||
<p>Check the trusted site that you want to remove and click on remove to remove these trusted site from these </p>
|
||||
<form action="." id="form" method="post">
|
||||
{% csrf_token %}
|
||||
{% for key, value in openids.items %}
|
||||
<p> <h4> {{ uri }}{{ oipath }}/{{ value.caption }}/ </h4>
|
||||
<ul class="NoBullet">
|
||||
{% for key2, value2 in value.trustroot.items %}
|
||||
<li class="indented"> <input type="checkbox" name = "trustremove" value = {{ key2 }} /> {{ value2 }} </li>
|
||||
{% empty %}
|
||||
You have no trusted site for this openid
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</p>
|
||||
{% endfor %}
|
||||
{% if trust_sum != 0 %}
|
||||
<input type="submit" value="Remove" />
|
||||
{% endif %}
|
||||
</form>
|
||||
</fieldset>
|
||||
{% endblock %}
|
|
@ -1,36 +0,0 @@
|
|||
{% extends "authentic2/base-page.html" %}
|
||||
|
||||
{% block extrahead %}{{ block.super }}
|
||||
<meta http-equiv="x-xrds-location" content="{{ host }}{% url 'openid-provider-xrds' %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
OpenID endpoint
|
||||
{% endblock %}
|
||||
|
||||
{% load breadcrumbs %}
|
||||
{% block breadcrumbs %}
|
||||
{{ block.super }}
|
||||
{% breadcrumb_url 'OpenID' 'openid-provider-root' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if nb_openid > 0 %}
|
||||
<p>To manage your OpenID accounts go on <a href='/openid/manageid/'> manage your OpenID account</a></p>
|
||||
<h3>Your OpenID account are: </h3>
|
||||
{% for key, value in openids.items %}
|
||||
<p> <h4> {{ uri }}{{ oipath }}/{{ value.caption }}/ </h4>
|
||||
{% for key2, value2 in value.trustroot.items %}
|
||||
<li> {{ value2 }} </li>
|
||||
{% empty %}
|
||||
You have no trusted site for this openid.
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p>You currently have no OpenID account.
|
||||
To create an OpenID account go on <a href='/openid/manageid/'> create an OpenID account</a></p>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
|
@ -1 +0,0 @@
|
|||
{% extends "base.html" %}
|
|
@ -1,57 +0,0 @@
|
|||
{% extends "authentic2/base-page.html" %}
|
||||
|
||||
{% block content %}
|
||||
{% ifequal trust_root_valid "Valid" %}
|
||||
<!-- Trust root has been validated by OpenID 2 mechanism. -->
|
||||
<p>The site <tt>{{ trust_root|escape }}</tt> has requested verification
|
||||
of your OpenID.</p>
|
||||
{% endifequal %}
|
||||
{% ifequal trust_root_valid "Invalid" %}
|
||||
<div class="error">
|
||||
<p>This request claims to be from {{ trust_root|escape }} but I have
|
||||
determined that <em>it is a pack of lies</em>. Beware, if you release
|
||||
information to them, they are likely to do unconscionable things with it,
|
||||
being the lying liars that they are.</p>
|
||||
<p>Please tell the <em>real</em> {{ trust_root|escape }} that someone is
|
||||
trying to abuse your trust in their good name.</p>
|
||||
</div>
|
||||
{% endifequal %}
|
||||
{% ifequal trust_root_valid "Unreachable" %}
|
||||
<p>The site <tt>{{ trust_root|escape }}</tt> has requested verification
|
||||
of your OpenID. I have failed to reach it and thus cannot vouch for its
|
||||
authenticity. Perhaps it is on your local network.</p>
|
||||
{% endifequal %}
|
||||
{% ifequal trust_root_valid "DISCOVERY_FAILED" %}
|
||||
<p>The site <tt>{{ trust_root|escape }}</tt> has requested verification
|
||||
of your OpenID. However, <tt>{{ trust_root|escape }}</tt> does not
|
||||
implement OpenID 2.0's relying party verification mechanism. Please use
|
||||
extra caution in deciding whether to release information to this party,
|
||||
and ask <tt>{{ trust_root|escape }}</tt> to implement relying party
|
||||
verification for your future transactions.</p>
|
||||
{% endifequal %}
|
||||
|
||||
<!-- trust_root_valid is {{ trust_root_valid }} -->
|
||||
|
||||
<form method="post" action="{% url 'openid-provider-decide' %}">
|
||||
{% csrf_token %}
|
||||
{% if required %}
|
||||
<p>
|
||||
It requires the following attributes:
|
||||
<ul>
|
||||
{% for att in required %}
|
||||
<li>{{ att }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if optional %}
|
||||
The following attributes are optional:
|
||||
<ul>
|
||||
{{ form.as_ul }}
|
||||
</ul>
|
||||
</p>
|
||||
{% endif %}
|
||||
<p>Allow Identity-Hub to verify your identity ?</p>
|
||||
<input type="submit" value="Yes (Allow)" name="allow" />
|
||||
<input type="submit" value="No (Cancel)" name="cancel" />
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,8 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="openid.server" href="{{ openid_server }}" />
|
||||
<meta http-equiv="refresh" content="1;url=/">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +0,0 @@
|
|||
{% extends "authentic2/base-page.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{{ title }}</h2>
|
||||
{{ msg }}
|
||||
{% endblock %}
|
|
@ -1,11 +0,0 @@
|
|||
{% extends "authentic2/base-page.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{% trans "Remove Link ?" %}</h2>
|
||||
<form action="" method="post">{% csrf_token %}
|
||||
<p>{% trans "Are you sure you want to delete link with" %} {{ trustedroot }} ?</p>
|
||||
<input type="submit" value="Yes" />
|
||||
</form>
|
||||
<p><a href="/">{% trans "Back" %}</a></p>
|
||||
{% endblock %}
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xrds:XRDS xmlns:xrds="xri://$xrds" xmlns="xri://$xrd*($v*2.0)">
|
||||
<XRD>
|
||||
<Service priority="0">{% for uri in types %}
|
||||
<Type>{{ uri|escape }}</Type>
|
||||
{% endfor %}{% for endpoint in endpoints %}
|
||||
<URI>{{ endpoint }}</URI>
|
||||
{% endfor %}{% for local_id in local_ids %}
|
||||
<LocalID>{{ local_id }}</LocalID>
|
||||
{% endfor %}</Service>
|
||||
</XRD>
|
||||
</xrds:XRDS>
|
|
@ -1,26 +0,0 @@
|
|||
# vim: set ts=4 sw=4 : */
|
||||
|
||||
from django.conf.urls import patterns, url
|
||||
from . import views
|
||||
|
||||
urlpatterns = patterns('authentic2.idp.idp_openid.views',
|
||||
url(r'^$',
|
||||
views.openid_server,
|
||||
name='a2-idp-openid-root'),
|
||||
url(r'^trustedroot/(?P<pk>\d+)/delete/$',
|
||||
views.openid_trustedroot_delete,
|
||||
name='trustedroot_delete'),
|
||||
url(r'^decide/$',
|
||||
views.openid_decide,
|
||||
name='a2-idp-openid-decide'),
|
||||
url(r'^xrds/$',
|
||||
views.openid_xrds,
|
||||
name='a2-idp-openid-xrds'),
|
||||
url(r'^(?P<id>.+)/xrds/$',
|
||||
views.openid_xrds,
|
||||
{'identity': True},
|
||||
name='a2-idp-openid-identity-xrds'),
|
||||
url(r'^(?P<id>.+)/$',
|
||||
views.openid_discovery,
|
||||
name='a2-idp-openid-identity'),
|
||||
)
|
|
@ -1,36 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vim: set ts=4 sw=4 fdm=indent : */
|
||||
# some code from http://www.djangosnippets.org/snippets/310/ by simon
|
||||
# and from examples/djopenid from python-openid-2.2.4
|
||||
|
||||
import openid.server
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.utils.importlib import import_module
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
|
||||
import conf
|
||||
|
||||
def oresponse_to_response(server, oresponse):
|
||||
try:
|
||||
webresponse = server.encodeResponse(oresponse)
|
||||
except openid.server.EncodingError:
|
||||
return HttpResponseRedirect('/')
|
||||
response = HttpResponse(webresponse.body)
|
||||
response.status_code = webresponse.code
|
||||
for key, value in webresponse.headers.items():
|
||||
response[key] = value
|
||||
return response
|
||||
|
||||
def import_module_attr(path):
|
||||
package, module = path.rsplit('.', 1)
|
||||
return getattr(import_module(package), module)
|
||||
|
||||
def get_store(request):
|
||||
try:
|
||||
store_class = import_module_attr(conf.STORE)
|
||||
except ImportError:
|
||||
raise ImproperlyConfigured("OpenID store %r could not be imported" % conf.STORE)
|
||||
# The FileOpenIDStore requires a path to save the user files.
|
||||
if conf.STORE == 'openid.store.filestore.FileOpenIDStore':
|
||||
return store_class(conf.FILESTORE_PATH)
|
||||
return store_class()
|
|
@ -1,303 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# some code from http://www.djangosnippets.org/snippets/310/ by simon
|
||||
# and from examples/djopenid from python-openid-2.2.4
|
||||
|
||||
import logging
|
||||
import hashlib
|
||||
import urlparse
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.shortcuts import render_to_response
|
||||
from django.template import RequestContext
|
||||
from django.utils.translation import ugettext as _
|
||||
try:
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
except ImportError:
|
||||
from django.contrib.csrf.middleware import csrf_exempt
|
||||
import django.forms as forms
|
||||
from django.conf import settings
|
||||
from django.http import Http404
|
||||
from django.views.generic import DeleteView
|
||||
|
||||
from openid.consumer.discover import OPENID_IDP_2_0_TYPE, \
|
||||
OPENID_2_0_TYPE, OPENID_1_0_TYPE, OPENID_1_1_TYPE
|
||||
from openid.fetchers import HTTPFetchingError
|
||||
from openid.server.server import Server, ProtocolError
|
||||
from openid.server.trustroot import verifyReturnTo
|
||||
from openid.yadis.discover import DiscoveryFailure
|
||||
from openid.yadis.constants import YADIS_CONTENT_TYPE
|
||||
from openid.message import IDENTIFIER_SELECT
|
||||
from openid.extensions.sreg import ns_uri as SREG_TYPE, SRegRequest, \
|
||||
SRegResponse, data_fields
|
||||
|
||||
from utils import get_store, oresponse_to_response
|
||||
from authentic2.utils import login_require, redirect
|
||||
from authentic2.constants import NONCE_FIELD_NAME
|
||||
from . import models
|
||||
from .decorators import openid_enabled
|
||||
|
||||
|
||||
logger = logging.getLogger('authentic.idp.idp_openid')
|
||||
|
||||
|
||||
def check_exploded(exploded, request):
|
||||
username = request.user.username
|
||||
return not exploded.path.startswith(request.path) \
|
||||
or exploded.path[len(request.path):].strip('/') != username \
|
||||
or exploded.params \
|
||||
or exploded.query \
|
||||
or exploded.fragment
|
||||
|
||||
@csrf_exempt
|
||||
@openid_enabled
|
||||
def openid_server(request):
|
||||
"""
|
||||
This view is the actual OpenID server - running at the URL pointed to by
|
||||
the <link rel="openid.server"> tag.
|
||||
"""
|
||||
server = Server(get_store(request),
|
||||
op_endpoint=request.build_absolute_uri(
|
||||
reverse('openid-provider-root')))
|
||||
|
||||
# Cancellation
|
||||
if 'cancel' in request.GET:
|
||||
if 'OPENID_REQUEST' in request.session:
|
||||
return oresponse_to_response(server,
|
||||
request.session['OPENID_REQUEST'].answer(False))
|
||||
else:
|
||||
return redirect('auth_homepage')
|
||||
|
||||
# Clear AuthorizationInfo session var, if it is set
|
||||
if request.session.get('AuthorizationInfo', None):
|
||||
del request.session['AuthorizationInfo']
|
||||
|
||||
querydict = dict(request.GET.items())
|
||||
try:
|
||||
orequest = server.decodeRequest(querydict)
|
||||
except ProtocolError, why:
|
||||
logger.error('Invalid OpenID message %s' % querydict)
|
||||
return oresponse_to_response(server, why)
|
||||
if not orequest:
|
||||
orequest = request.session.get('OPENID_REQUEST', None)
|
||||
if orequest:
|
||||
logger.info('Restarting saved request by %s' % orequest.trust_root)
|
||||
# remove session stored data:
|
||||
pass
|
||||
# del request.session['OPENID_REQUEST']
|
||||
else:
|
||||
logger.info('No OpenID request redirecting to homepage')
|
||||
return redirect('auth_homepage')
|
||||
else:
|
||||
logger.info('Received OpenID request: %s' % querydict)
|
||||
sreg_request = SRegRequest.fromOpenIDRequest(orequest)
|
||||
logger.debug('SREG request: %s' % sreg_request.__dict__)
|
||||
|
||||
if orequest.mode in ("checkid_immediate", "checkid_setup"):
|
||||
# User is not logged
|
||||
if not request.user.is_authenticated():
|
||||
# Site does not want interaction
|
||||
if orequest.immediate:
|
||||
logger.debug('User not logged and checkid immediate request, \
|
||||
returning OpenID failure')
|
||||
return oresponse_to_response(server, orequest.answer(False))
|
||||
else:
|
||||
# Try to login
|
||||
request.session['OPENID_REQUEST'] = orequest
|
||||
logger.debug('User not logged and checkid request, \
|
||||
redirecting to login page')
|
||||
return login_require(request, params={NONCE_FIELD_NAME: '1'})
|
||||
else:
|
||||
identity = orequest.identity
|
||||
if identity != IDENTIFIER_SELECT:
|
||||
exploded = urlparse.urlparse(identity)
|
||||
# Allows only /openid/<user_id>
|
||||
if check_exploded(exploded, request):
|
||||
# We only support directed identity
|
||||
logger.debug('Invalid OpenID identity %s' % identity)
|
||||
return oresponse_to_response(server, orequest.answer(False))
|
||||
if getattr(settings, 'RESTRICT_OPENID_RP', None):
|
||||
logger.debug('RP restriction is activated')
|
||||
if orequest.trust_root in getattr(settings, 'RESTRICT_OPENID_RP'):
|
||||
logger.debug('The RP %s is authorized' % orequest.trust_root)
|
||||
else:
|
||||
logger.debug('The RP %s is not authorized, return 404.' \
|
||||
% orequest.trust_root)
|
||||
raise Http404
|
||||
try:
|
||||
trusted_root = models.TrustedRoot.objects.get(
|
||||
user=request.user.id, trust_root=orequest.trust_root)
|
||||
# Check the choices are sufficient
|
||||
if not set(sreg_request.required)\
|
||||
.issubset(set(trusted_root.choices)):
|
||||
# Current assertion is not sufficent, ask again !
|
||||
if orequest.immediate:
|
||||
logger.debug('Attributes authorization unsufficient \
|
||||
and checkid immediate, returning OpenID failure')
|
||||
return oresponse_to_response(server,
|
||||
orequest.answer(False))
|
||||
request.session['OPENID_REQUEST'] = orequest
|
||||
logger.debug('Attributes authorization unsufficient \
|
||||
for %s, redirecting to consent page' % orequest.trust_root)
|
||||
return redirect('openid-provider-decide')
|
||||
user_data = {}
|
||||
for field in trusted_root.choices:
|
||||
if field == 'email':
|
||||
user_data[field] = request.user.email
|
||||
elif field == 'fullname':
|
||||
user_data[field] = '%s %s' % (request.user.first_name,
|
||||
request.user.last_name)
|
||||
elif field == 'nickname':
|
||||
user_data[field] = getattr(request.user, 'username',
|
||||
'')
|
||||
else:
|
||||
logger.debug('Could not provide SReg field %s' % field)
|
||||
except models.TrustedRoot.MultipleObjectsReturned:
|
||||
# Too much trustedroots remove
|
||||
models.TrustedRoot.objects.filter(user=request.user.id,
|
||||
trust_root=orequest.trust_root).delete()
|
||||
# RP does not want any interaction
|
||||
if orequest.immediate:
|
||||
logger.warning('Too much trusted root records and \
|
||||
checkid immediate, returning OpenID failure')
|
||||
return oresponse_to_response(server,
|
||||
orequest.answer(False))
|
||||
request.session['OPENID_REQUEST'] = orequest
|
||||
logger.info('Too much trusted root for %s, redirecting to \
|
||||
consent page' % orequest.trust_root)
|
||||
return redirect('openid-provider-decide')
|
||||
except models.TrustedRoot.DoesNotExist:
|
||||
# RP does not want any interaction
|
||||
if orequest.immediate:
|
||||
logger.info('Trusted root unknown and checkid \
|
||||
immediate, returning OpenID failure')
|
||||
return oresponse_to_response(server,
|
||||
orequest.answer(False))
|
||||
request.session['OPENID_REQUEST'] = orequest
|
||||
logger.info('Trusted root %s unknown, redirecting to \
|
||||
consent page' % orequest.trust_root)
|
||||
return redirect('openid-provider-decide')
|
||||
|
||||
# Create a directed identity if needed
|
||||
if identity == IDENTIFIER_SELECT:
|
||||
hash = hashlib.sha1(str(request.user.id)+'|'+orequest.trust_root) \
|
||||
.hexdigest()
|
||||
claimed_id = request.build_absolute_uri(
|
||||
reverse('openid-provider-identity', args=[hash]))
|
||||
logger.info('Giving directed identity %r to trusted root %r \
|
||||
with sreg data %s' % (claimed_id, orequest.trust_root, user_data))
|
||||
else:
|
||||
claimed_id = identity
|
||||
logger.info('Giving claimed identity %r to trusted root %r \
|
||||
with sreg data %s' % (claimed_id, orequest.trust_root, user_data))
|
||||
|
||||
oresponse = orequest.answer(True, identity=claimed_id)
|
||||
sreg_response = SRegResponse.extractResponse(sreg_request, user_data)
|
||||
oresponse.addExtension(sreg_response)
|
||||
else:
|
||||
oresponse = server.handleRequest(orequest)
|
||||
logger.info('Returning OpenID response %s' % oresponse)
|
||||
return oresponse_to_response(server, oresponse)
|
||||
|
||||
@openid_enabled
|
||||
def openid_xrds(request, identity=False, id=None):
|
||||
'''XRDS discovery page'''
|
||||
logger.debug('OpenID XRDS identity:%(identity)s id:%(id)s' % locals())
|
||||
if identity:
|
||||
types = [OPENID_2_0_TYPE, OPENID_1_0_TYPE, OPENID_1_1_TYPE, SREG_TYPE]
|
||||
local_ids = []
|
||||
else:
|
||||
types = [OPENID_IDP_2_0_TYPE,SREG_TYPE]
|
||||
local_ids = []
|
||||
endpoints = [request.build_absolute_uri(reverse('openid-provider-root'))]
|
||||
return render_to_response('idp/openid/xrds.xml', {
|
||||
'host': request.build_absolute_uri('/'),
|
||||
'types': types,
|
||||
'endpoints': endpoints,
|
||||
'local_ids': local_ids,
|
||||
}, context_instance=RequestContext(request), mimetype=YADIS_CONTENT_TYPE)
|
||||
|
||||
class DecideForm(forms.Form):
|
||||
def __init__(self, sreg_request=None, *args, **kwargs):
|
||||
super(DecideForm, self).__init__(*args, **kwargs)
|
||||
for field in sreg_request.optional:
|
||||
self.fields[str(field)] = forms.BooleanField(
|
||||
label=data_fields[str(field)], required=False)
|
||||
logger.info('3SREG request: %s' % self.fields)
|
||||
|
||||
@openid_enabled
|
||||
def openid_decide(request):
|
||||
"""
|
||||
The page that asks the user if they really want to sign in to the site, and
|
||||
lets them add the consumer to their trusted whitelist.
|
||||
# If user is logged in, ask if they want to trust this trust_root
|
||||
# If they are NOT logged in, show the landing page
|
||||
"""
|
||||
orequest = request.session.get('OPENID_REQUEST')
|
||||
# No request ? Failure..
|
||||
if not orequest:
|
||||
logger.warning('OpenID decide view failed, \
|
||||
because no OpenID request is saved')
|
||||
return redirect('auth_homepage')
|
||||
sreg_request = SRegRequest.fromOpenIDRequest(orequest)
|
||||
logger.debug('SREG request: %s' % sreg_request.__dict__)
|
||||
if not request.user.is_authenticated():
|
||||
# Not authenticated ? Authenticate and go back to the server endpoint
|
||||
return login_require(request, params={NONCE_FIELD_NAME: '1'})
|
||||
|
||||
if request.method == 'POST':
|
||||
if 'cancel' in request.POST:
|
||||
# User refused
|
||||
logger.info('OpenID decide canceled')
|
||||
return redirect(openid_server, params={'cancel': ''})
|
||||
else:
|
||||
form = DecideForm(sreg_request=sreg_request, data=request.POST)
|
||||
if form.is_valid():
|
||||
data = form.cleaned_data
|
||||
# Remember the choice
|
||||
t, created = models.TrustedRoot.objects.get_or_create(
|
||||
user=request.user.id, trust_root=orequest.trust_root)
|
||||
t.choices = sreg_request.required \
|
||||
+ [ field for field in data if data[field] ]
|
||||
t.save()
|
||||
logger.debug('OpenID decide, user choice:%s' % data)
|
||||
return redirect('openid-provider-root')
|
||||
else:
|
||||
form = DecideForm(sreg_request=sreg_request)
|
||||
logger.info('OpenID device view, orequest:%s' % orequest)
|
||||
|
||||
# verify return_to of trust_root
|
||||
try:
|
||||
trust_root_valid = verifyReturnTo(orequest.trust_root,
|
||||
orequest.return_to) and "Valid" or "Invalid"
|
||||
except HTTPFetchingError:
|
||||
trust_root_valid = "Unreachable"
|
||||
except DiscoveryFailure:
|
||||
trust_root_valid = "DISCOVERY_FAILED"
|
||||
|
||||
return render_to_response('idp/openid/decide.html', {
|
||||
'title': _('Trust this site?'),
|
||||
'required': sreg_request.required,
|
||||
'optional': sreg_request.optional,
|
||||
'trust_root_valid': trust_root_valid,
|
||||
'form': form,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
@openid_enabled
|
||||
def openid_discovery(request, id):
|
||||
'''HTML discovery page'''
|
||||
xrds_url = request.build_absolute_uri(
|
||||
reverse('openid-provider-identity-xrds', args=[id]))
|
||||
response = render_to_response('idp/openid/discovery.html', {
|
||||
'xrds': xrds_url,
|
||||
'openid_server': request.build_absolute_uri(
|
||||
reverse('openid-provider-root'))
|
||||
}, context_instance=RequestContext(request))
|
||||
response['X-XRDS-Location'] = xrds_url
|
||||
return response
|
||||
|
||||
class TrustedRootDelete(DeleteView):
|
||||
model = models.TrustedRoot
|
||||
success_url = '/'
|
||||
template_name = 'idp/openid/trustedroot_confirm_delete.html'
|
||||
|
||||
openid_trustedroot_delete = openid_enabled(TrustedRootDelete.as_view())
|
Loading…
Reference in New Issue