[Python-modules-commits] [python-django-casclient] 02/02: Imported Debian patch 1.2.0-1
Joost van Baal
joostvb at moszumanska.debian.org
Tue Mar 15 09:03:33 UTC 2016
This is an automated email from the git hooks/post-receive script.
joostvb pushed a commit to branch master
in repository python-django-casclient.
commit 496d4d7f110901b3d906bda915e950cb7efd06a4
Author: Joost van Baal-Ilić <joostvb at debian.org>
Date: Fri Mar 11 13:59:58 2016 +0000
Imported Debian patch 1.2.0-1
---
debian/changelog | 11 +
debian/compat | 1 +
debian/control | 49 ++++
debian/copyright | 38 +++
debian/postinst | 39 ++++
debian/prerm | 38 +++
.../lib/python2.7/dist-packages/cas/__init__.py | 32 +++
.../lib/python2.7/dist-packages/cas/backends.py | 257 +++++++++++++++++++++
.../lib/python2.7/dist-packages/cas/decorators.py | 93 ++++++++
.../lib/python2.7/dist-packages/cas/exceptions.py | 17 ++
.../lib/python2.7/dist-packages/cas/middleware.py | 92 ++++++++
.../usr/lib/python2.7/dist-packages/cas/models.py | 108 +++++++++
.../python2.7/dist-packages/cas/tests/__init__.py | 3 +
.../python2.7/dist-packages/cas/tests/factories.py | 15 ++
.../dist-packages/cas/tests/test_backend.py | 30 +++
.../dist-packages/cas/tests/test_smoke.py | 7 +
.../dist-packages/cas/tests/test_views.py | 46 ++++
.../usr/lib/python2.7/dist-packages/cas/utils.py | 26 +++
.../usr/lib/python2.7/dist-packages/cas/views.py | 257 +++++++++++++++++++++
.../django_cas_client-1.2.0.egg-info/PKG-INFO | 184 +++++++++++++++
.../dependency_links.txt | 1 +
.../django_cas_client-1.2.0.egg-info/top_level.txt | 1 +
.../django_cas_client-1.2.0.egg-info/zip-safe | 1 +
debian/python-django-casclient-doc.docs | 14 ++
.../lib/python3.5/dist-packages/cas/__init__.py | 32 +++
.../lib/python3.5/dist-packages/cas/backends.py | 257 +++++++++++++++++++++
.../lib/python3.5/dist-packages/cas/decorators.py | 93 ++++++++
.../lib/python3.5/dist-packages/cas/exceptions.py | 17 ++
.../lib/python3.5/dist-packages/cas/middleware.py | 92 ++++++++
.../usr/lib/python3.5/dist-packages/cas/models.py | 108 +++++++++
.../python3.5/dist-packages/cas/tests/__init__.py | 3 +
.../python3.5/dist-packages/cas/tests/factories.py | 15 ++
.../dist-packages/cas/tests/test_backend.py | 30 +++
.../dist-packages/cas/tests/test_smoke.py | 7 +
.../dist-packages/cas/tests/test_views.py | 46 ++++
.../usr/lib/python3.5/dist-packages/cas/utils.py | 26 +++
.../usr/lib/python3.5/dist-packages/cas/views.py | 257 +++++++++++++++++++++
.../django_cas_client-1.2.0.egg-info/PKG-INFO | 184 +++++++++++++++
.../dependency_links.txt | 1 +
.../django_cas_client-1.2.0.egg-info/top_level.txt | 1 +
.../django_cas_client-1.2.0.egg-info/zip-safe | 1 +
debian/rules | 22 ++
debian/source/format | 1 +
debian/watch | 23 ++
44 files changed, 2576 insertions(+)
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..dfceb47
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,11 @@
+python-django-casclient (1.2.0-1) unstable; urgency=medium
+
+ * Private release for Tilburg University.
+ * FIXME: tests fail; see debian/rules:
+ ImproperlyConfigured: Requested setting CAS_EXTRA_LOGIN_PARAMS, but
+ settings are not configured. You must either define the environment
+ variable DJANGO_SETTINGS_MODULE or call settings.configure() before
+ accessing settings.
+ Ran 3 tests in 0.000s FAILED (errors=3)
+
+ -- Joost van Baal-Ilić <joostvb at debian.org> Fri, 11 Mar 2016 13:59:58 +0000
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..ec63514
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+9
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..d32660b
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,49 @@
+Source: python-django-casclient
+Section: python
+Priority: optional
+Maintainer: Joost van Baal-Ilić <joostvb at debian.org>
+Build-Depends: debhelper (>=9), dh-python, python-all (>= 2.6.6-3~),
+ python-setuptools, python3-all, python3-setuptools,
+ python-django-appconf, python3-django-appconf
+Standards-Version: 3.9.6
+Homepage: https://github.com/kstateome/django-cas/
+X-Python-Version: >= 2.6
+X-Python3-Version: >= 3.2
+#Vcs-Git: git://anonscm.debian.org/collab-maint/django-cas.git
+#Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/django-cas.git
+
+Package: python-django-casclient
+Architecture: all
+Depends: ${python:Depends}, ${misc:Depends}
+Suggests: python-django-cas-doc
+Description: CAS client library for Django, K-State's version (Python 2)
+ Django-cas is a CAS client library for Django. It is K-State's
+ fork of the original and includes Edmund Crewe's proxy ticket
+ patch and several additional features as well as features merged
+ from KTHse's django-cas2.
+ .
+ This package installs the library for Python 2.
+
+Package: python3-django-casclient
+Architecture: all
+Depends: ${python3:Depends}, ${misc:Depends}
+Suggests: python-django-cas-doc
+Description: CAS client library for Django, K-State's version (Python 3)
+ Django-cas is a CAS client library for Django. It is K-State's
+ fork of the original and includes Edmund Crewe's proxy ticket
+ patch and several additional features as well as features merged
+ from KTHse's django-cas2.
+ .
+ This package installs the library for Python 3.
+
+Package: python-django-casclient-doc
+Architecture: all
+Section: doc
+Depends: ${sphinxdoc:Depends}, ${misc:Depends}
+Description: CAS client library for Django, K-State's version (common documentation)
+ Django-cas is a CAS client library for Django. It is K-State's
+ fork of the original and includes Edmund Crewe's proxy ticket
+ patch and several additional features as well as features merged
+ from KTHse's django-cas2.
+ .
+ This is the common documentation package.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..37bc41a
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,38 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: django-cas
+Source: https://codeload.github.com/kstateome/django-cas
+
+Files: *
+Copyright: <years> <put author's name and email here>
+ <years> <likewise for another author>
+License: <special license>
+ <Put the license of the package here indented by 1 space>
+ <This follows the format of Description: lines in control file>
+ .
+ <Including paragraphs>
+
+# If you want to use GPL v2 or later for the /debian/* files use
+# the following clauses, or change it to suit. Delete these two lines
+Files: debian/*
+Copyright: 2016 Joost van Baal-Ilić <joostvb at debian.org>
+License: GPL-2+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <https://www.gnu.org/licenses/>
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
+# Please avoid picking licenses with terms that are more restrictive than the
+# packaged work, as it may make Debian's contributions unacceptable upstream.
diff --git a/debian/postinst b/debian/postinst
new file mode 100644
index 0000000..688b92f
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,39 @@
+#!/bin/sh
+# postinst script for django-cas
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <postinst> `abort-remove'
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see https://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ configure)
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/prerm b/debian/prerm
new file mode 100644
index 0000000..6d31c40
--- /dev/null
+++ b/debian/prerm
@@ -0,0 +1,38 @@
+#!/bin/sh
+# prerm script for django-cas
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <prerm> `remove'
+# * <old-prerm> `upgrade' <new-version>
+# * <new-prerm> `failed-upgrade' <old-version>
+# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
+# * <deconfigured's-prerm> `deconfigure' `in-favour'
+# <package-being-installed> <version> `removing'
+# <conflicting-package> <version>
+# for details, see https://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ remove|upgrade|deconfigure)
+ ;;
+
+ failed-upgrade)
+ ;;
+
+ *)
+ echo "prerm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/__init__.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/__init__.py
new file mode 100644
index 0000000..59ea0eb
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/__init__.py
@@ -0,0 +1,32 @@
+"""Django CAS 1.0/2.0 authentication backend"""
+
+from django.conf import settings
+
+__all__ = []
+
+_DEFAULTS = {
+ 'CAS_ADMIN_PREFIX': None,
+ 'CAS_EXTRA_LOGIN_PARAMS': None,
+ 'CAS_IGNORE_REFERER': False,
+ 'CAS_LOGOUT_COMPLETELY': True,
+ 'CAS_REDIRECT_URL': '/',
+ 'CAS_RETRY_LOGIN': False,
+ 'CAS_SERVER_URL': None,
+ 'CAS_VERSION': '2',
+ 'CAS_GATEWAY': False,
+ 'CAS_PROXY_CALLBACK': None,
+ 'CAS_RESPONSE_CALLBACKS': None,
+ 'CAS_CUSTOM_FORBIDDEN': None,
+ 'CAS_PGT_FETCH_WAIT': True,
+ 'CAS_FORCE_SSL_SERVICE_URL': False,
+ 'CAS_AUTO_CREATE_USER': True,
+}
+
+for key, value in _DEFAULTS.items():
+ try:
+ getattr(settings, key)
+ except AttributeError:
+ setattr(settings, key, value)
+ # Suppress errors from DJANGO_SETTINGS_MODULE not being set
+ except ImportError:
+ pass
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/backends.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/backends.py
new file mode 100644
index 0000000..5a646aa
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/backends.py
@@ -0,0 +1,257 @@
+import logging
+from xml.dom import minidom
+import time
+
+try:
+ from xml.etree import ElementTree
+except ImportError:
+ from elementtree import ElementTree
+
+try:
+ from urllib import urlencode
+except ImportError:
+ from urllib.parse import urlencode
+try:
+ from urllib import urlopen
+except ImportError:
+ from urllib.request import urlopen
+try:
+ from urlparse import urljoin
+except ImportError:
+ from urllib.parse import urljoin
+
+
+from django.conf import settings
+from django.contrib.auth import get_user_model
+
+from cas.exceptions import CasTicketException
+from cas.models import Tgt, PgtIOU
+from cas.utils import cas_response_callbacks
+
+__all__ = ['CASBackend']
+
+logger = logging.getLogger(__name__)
+
+
+def _verify_cas1(ticket, service):
+ """
+ Verifies CAS 1.0 authentication ticket.
+
+ :param: ticket
+ :param: service
+
+ Returns username on success and None on failure.
+ """
+
+ params = {'ticket': ticket, 'service': service}
+ url = (urljoin(settings.CAS_SERVER_URL, 'validate') + '?' +
+ urlencode(params))
+ page = urlopen(url)
+
+ try:
+ verified = page.readline().strip()
+ if verified == 'yes':
+ return page.readline().strip()
+ else:
+ return None
+ finally:
+ page.close()
+
+
+def _verify_cas2(ticket, service):
+ """
+ Verifies CAS 2.0+ XML-based authentication ticket.
+
+ :param: ticket
+ :param: service
+ """
+ return _internal_verify_cas(ticket, service, 'proxyValidate')
+
+
+def _verify_cas3(ticket, service):
+ return _internal_verify_cas(ticket, service, 'p3/proxyValidate')
+
+
+def _internal_verify_cas(ticket, service, suffix):
+ """Verifies CAS 2.0 and 3.0 XML-based authentication ticket.
+
+ Returns username on success and None on failure.
+ """
+
+ params = {'ticket': ticket, 'service': service}
+ if settings.CAS_PROXY_CALLBACK:
+ params['pgtUrl'] = settings.CAS_PROXY_CALLBACK
+
+ url = (urljoin(settings.CAS_SERVER_URL, suffix) + '?' +
+ urlencode(params))
+
+ page = urlopen(url)
+
+ username = None
+
+ try:
+ response = page.read()
+ tree = ElementTree.fromstring(response)
+ document = minidom.parseString(response)
+
+ if tree[0].tag.endswith('authenticationSuccess'):
+ if settings.CAS_RESPONSE_CALLBACKS:
+ cas_response_callbacks(tree)
+
+ username = tree[0][0].text
+
+ pgt_el = document.getElementsByTagName('cas:proxyGrantingTicket')
+
+ if pgt_el:
+ pgt = pgt_el[0].firstChild.nodeValue
+ try:
+ pgtIou = _get_pgtiou(pgt)
+ tgt = Tgt.objects.get(username=username)
+ tgt.tgt = pgtIou.tgt
+ tgt.save()
+ pgtIou.delete()
+ except Tgt.DoesNotExist:
+ Tgt.objects.create(username=username, tgt=pgtIou.tgt)
+ logger.info('Creating TGT ticket for {user}'.format(
+ user=username
+ ))
+ pgtIou.delete()
+ except Exception as e:
+ logger.warning('Failed to do proxy authentication. {message}'.format(
+ message=e
+ ))
+
+ else:
+ failure = document.getElementsByTagName('cas:authenticationFailure')
+ if failure:
+ logger.warn('Authentication failed from CAS server: %s',
+ failure[0].firstChild.nodeValue)
+
+ except Exception as e:
+ logger.error('Failed to verify CAS authentication: {message}'.format(
+ message=e
+ ))
+
+ finally:
+ page.close()
+
+ return username
+
+
+def verify_proxy_ticket(ticket, service):
+ """
+ Verifies CAS 2.0+ XML-based proxy ticket.
+
+ :param: ticket
+ :param: service
+
+ Returns username on success and None on failure.
+ """
+
+ params = {'ticket': ticket, 'service': service}
+
+ url = (urljoin(settings.CAS_SERVER_URL, 'proxyValidate') + '?' +
+ urlencode(params))
+
+ page = urlopen(url)
+
+ try:
+ response = page.read()
+ tree = ElementTree.fromstring(response)
+ if tree[0].tag.endswith('authenticationSuccess'):
+ username = tree[0][0].text
+ proxies = []
+ if len(tree[0]) > 1:
+ for element in tree[0][1]:
+ proxies.append(element.text)
+ return {"username": username, "proxies": proxies}
+ else:
+ return None
+ finally:
+ page.close()
+
+_PROTOCOLS = {'1': _verify_cas1, '2': _verify_cas2, '3': _verify_cas3}
+
+if settings.CAS_VERSION not in _PROTOCOLS:
+ raise ValueError('Unsupported CAS_VERSION %r' % settings.CAS_VERSION)
+
+_verify = _PROTOCOLS[settings.CAS_VERSION]
+
+
+def _get_pgtiou(pgt):
+ """
+ Returns a PgtIOU object given a pgt.
+
+ The PgtIOU (tgt) is set by the CAS server in a different request
+ that has completed before this call, however, it may not be found in
+ the database by this calling thread, hence the attempt to get the
+ ticket is retried for up to 5 seconds. This should be handled some
+ better way.
+
+ Users can opt out of this waiting period by setting CAS_PGT_FETCH_WAIT = False
+
+ :param: pgt
+
+ """
+
+ pgtIou = None
+ retries_left = 5
+
+ if not settings.CAS_PGT_FETCH_WAIT:
+ retries_left = 1
+
+ while not pgtIou and retries_left:
+ try:
+ return PgtIOU.objects.get(tgt=pgt)
+ except PgtIOU.DoesNotExist:
+ if settings.CAS_PGT_FETCH_WAIT:
+ time.sleep(1)
+ retries_left -= 1
+ logger.info('Did not fetch ticket, trying again. {tries} tries left.'.format(
+ tries=retries_left
+ ))
+ raise CasTicketException("Could not find pgtIou for pgt %s" % pgt)
+
+
+class CASBackend(object):
+ """
+ CAS authentication backend
+ """
+
+ supports_object_permissions = False
+ supports_inactive_user = False
+
+ def authenticate(self, ticket, service):
+ """
+ Verifies CAS ticket and gets or creates User object
+ NB: Use of PT to identify proxy
+ """
+
+ User = get_user_model()
+ username = _verify(ticket, service)
+
+ if not username:
+ return None
+
+ try:
+ user = User.objects.get(username__iexact=username)
+ except User.DoesNotExist:
+ # user will have an "unusable" password
+ if settings.CAS_AUTO_CREATE_USER:
+ user = User.objects.create_user(username, '')
+ user.save()
+ else:
+ user = None
+ return user
+
+ def get_user(self, user_id):
+ """
+ Retrieve the user's entry in the User model if it exists
+ """
+
+ User = get_user_model()
+
+ try:
+ return User.objects.get(pk=user_id)
+ except User.DoesNotExist:
+ return None
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/decorators.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/decorators.py
new file mode 100644
index 0000000..7cc0e3c
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/decorators.py
@@ -0,0 +1,93 @@
+try:
+ from functools import wraps
+except ImportError:
+ from django.utils.functional import wraps
+
+try:
+ from urllib import urlencode
+except ImportError:
+ from urllib.parse import urlencode
+
+from django.contrib.auth import REDIRECT_FIELD_NAME
+from django.http import HttpResponseForbidden, HttpResponseRedirect
+from django.utils.http import urlquote
+from django.conf import settings
+from django.core.exceptions import ImproperlyConfigured
+
+__all__ = ['permission_required', 'user_passes_test']
+
+
+def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
+ """
+ Replacement for django.contrib.auth.decorators.user_passes_test that
+ returns 403 Forbidden if the user is already logged in.
+ """
+
+ if not login_url:
+ login_url = settings.LOGIN_URL
+
+ def decorator(view_func):
+ @wraps(view_func)
+ def wrapper(request, *args, **kwargs):
+ if test_func(request.user):
+ return view_func(request, *args, **kwargs)
+ elif request.user.is_authenticated():
+ return HttpResponseForbidden('<h1>Permission denied</h1>')
+ else:
+ path = '%s?%s=%s' % (login_url, redirect_field_name,
+ urlquote(request.get_full_path()))
+ return HttpResponseRedirect(path)
+ return wrapper
+ return decorator
+
+
+def permission_required(perm, login_url=None):
+ """
+ Replacement for django.contrib.auth.decorators.permission_required that
+ returns 403 Forbidden if the user is already logged in.
+ """
+
+ return user_passes_test(lambda u: u.has_perm(perm), login_url=login_url)
+
+
+def gateway():
+ """
+ Authenticates single sign on session if ticket is available,
+ but doesn't redirect to sign in url otherwise.
+ """
+
+ if settings.CAS_GATEWAY == False:
+ raise ImproperlyConfigured('CAS_GATEWAY must be set to True')
+
+ def wrap(func):
+ def wrapped_f(*args):
+
+ from cas.views import login
+ request = args[0]
+
+ if request.user.is_authenticated():
+ # Is Authed, fine
+ pass
+ else:
+ path_with_params = request.path + '?' + urlencode(request.GET.copy())
+ if request.GET.get('ticket'):
+ # Not Authed, but have a ticket!
+ # Try to authenticate
+ response = login(request, path_with_params, False, True)
+ if isinstance(response, HttpResponseRedirect):
+ # For certain instances where a forbidden occurs, we need to pass instead of return a response.
+ return response
+ else:
+ #Not Authed, but no ticket
+ gatewayed = request.GET.get('gatewayed')
+ if gatewayed == 'true':
+ pass
+ else:
+ # Not Authed, try to authenticate
+ response = login(request, path_with_params, False, True)
+ if isinstance(response, HttpResponseRedirect):
+ return response
+
+ return func(*args)
+ return wrapped_f
+ return wrap
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/exceptions.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/exceptions.py
new file mode 100644
index 0000000..c50d3c2
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/exceptions.py
@@ -0,0 +1,17 @@
+from django.core.exceptions import ValidationError
+
+
+class CasTicketException(ValidationError):
+ """
+ The ticket fails to validate
+ """
+
+ pass
+
+
+class CasConfigException(ValidationError):
+ """
+ The config is wrong
+ """
+
+ pass
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/middleware.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/middleware.py
new file mode 100644
index 0000000..771a1d1
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/middleware.py
@@ -0,0 +1,92 @@
+"""CAS authentication middleware"""
+
+try:
+ from urllib import urlencode
+except ImportError:
+ from urllib.parse import urlencode
+
+from django.conf import settings
+from django.contrib.auth import REDIRECT_FIELD_NAME
+from django.contrib.auth import logout as do_logout
+from django.contrib.auth.views import login, logout
+from django.core.urlresolvers import reverse
+from django.http import HttpResponseRedirect, HttpResponseForbidden
+from django.core.exceptions import ImproperlyConfigured
+
+from cas.exceptions import CasTicketException
+from cas.views import login as cas_login, logout as cas_logout
+
+__all__ = ['CASMiddleware']
+
+
+class CASMiddleware(object):
+ """
+ Middleware that allows CAS authentication on admin pages
+ """
+
+ def process_request(self, request):
+ """
+ Checks that the authentication middleware is installed
+
+ :param: request
+
+ """
+
+ error = ("The Django CAS middleware requires authentication "
+ "middleware to be installed. Edit your MIDDLEWARE_CLASSES "
+ "setting to insert 'django.contrib.auth.middleware."
+ "AuthenticationMiddleware'.")
+ assert hasattr(request, 'user'), error
+
+ def process_view(self, request, view_func, view_args, view_kwargs):
+ """
+ Forwards unauthenticated requests to the admin page to the CAS
+ login URL, as well as calls to django.contrib.auth.views.login and
+ logout.
+ """
+
+ if view_func == login:
+ return cas_login(request, *view_args, **view_kwargs)
+ elif view_func == logout:
+ return cas_logout(request, *view_args, **view_kwargs)
+
+ if settings.CAS_ADMIN_PREFIX:
+ if not request.path.startswith(settings.CAS_ADMIN_PREFIX):
+ return None
+ elif not view_func.__module__.startswith('django.contrib.admin.'):
+ return None
+
+ if request.user.is_authenticated():
+ if request.user.is_staff:
+ return None
+ else:
+ error = ('<h1>Forbidden</h1><p>You do not have staff '
+ 'privileges.</p>')
+ return HttpResponseForbidden(error)
+
+ params = urlencode({REDIRECT_FIELD_NAME: request.get_full_path()})
+ return HttpResponseRedirect(reverse(cas_login) + '?' + params)
+
+ def process_exception(self, request, exception):
+ """
+ When we get a CasTicketException, that is probably caused by the ticket timing out.
+ So logout/login and get the same page again.
+ """
+
+ if isinstance(exception, CasTicketException):
+ do_logout(request)
+ # This assumes that request.path requires authentication.
+ return HttpResponseRedirect(request.path)
+ else:
+ return None
+
+
+class ProxyMiddleware(object):
+
+ # Middleware used to "fake" the django app that it lives at the Proxy Domain
+ def process_request(self, request):
+ proxy = getattr(settings, 'PROXY_DOMAIN', None)
+ if not proxy:
+ raise ImproperlyConfigured('To use Proxy Middleware you must set a PROXY_DOMAIN setting.')
+ else:
+ request.META['HTTP_HOST'] = proxy
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/models.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/models.py
new file mode 100644
index 0000000..54b1606
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/models.py
@@ -0,0 +1,108 @@
+import logging
+from datetime import datetime
+try:
+ from xml.etree import ElementTree
+except ImportError:
+ from elementtree import ElementTree
+try:
+ from urlparse import urljoin
+except ImportError:
+ from urllib.parse import urljoin
+try:
+ from urllib import urlencode
+except ImportError:
+ from urllib.parse import urlencode
+try:
+ from urllib import urlopen
+except ImportError:
+ from urllib.request import urlopen
+
+from django.db import models
+from django.conf import settings
+from django.core.exceptions import ObjectDoesNotExist
+from django.db.models.signals import post_save
+
+
+from cas.exceptions import CasTicketException, CasConfigException
+
+
+logger = logging.getLogger(__name__)
+
+
+class Tgt(models.Model):
+ username = models.CharField(max_length=255, unique=True)
+ tgt = models.CharField(max_length=255)
+
+ def get_proxy_ticket_for(self, service):
+ """
+ Verifies CAS 2.0+ XML-based authentication ticket.
+
+ :param: service
+
+ Returns username on success and None on failure.
+ """
+
+ if not settings.CAS_PROXY_CALLBACK:
+ raise CasConfigException("No proxy callback set in settings")
+
+ params = {'pgt': self.tgt, 'targetService': service}
+
+ url = (urljoin(settings.CAS_SERVER_URL, 'proxy') + '?' +
+ urlencode(params))
+
+ page = urlopen(url)
+
+ try:
+ response = page.read()
+ tree = ElementTree.fromstring(response)
+ if tree[0].tag.endswith('proxySuccess'):
+ return tree[0][0].text
+ else:
+ logger.warning('Failed to get proxy ticket')
+ raise CasTicketException('Failed to get proxy ticket: %s' % \
+ tree[0].text.strip())
+ finally:
+ page.close()
+
+
+class PgtIOU(models.Model):
+ """
+ Proxy granting ticket and IOU
+ """
+ pgtIou = models.CharField(max_length = 255, unique = True)
+ tgt = models.CharField(max_length = 255)
+ created = models.DateTimeField(auto_now = True)
+
+
+def get_tgt_for(user):
+ """
+ Fetch a ticket granting ticket for a given user.
+
+ :param user: UserObj
+
+ :return: TGT or Exepction
+ """
+ if not settings.CAS_PROXY_CALLBACK:
+ raise CasConfigException("No proxy callback set in settings")
+
+ try:
+ return Tgt.objects.get(username=user.username)
+ except ObjectDoesNotExist:
+ logger.warning('No ticket found for user {user}'.format(
+ user=user.username
+ ))
+ raise CasTicketException("no ticket found for user " + user.username)
+
+
+def delete_old_tickets(**kwargs):
+ """
+ Delete tickets if they are over 2 days old
+ kwargs = ['raw', 'signal', 'instance', 'sender', 'created']
+
+ """
+ sender = kwargs.get('sender', None)
+ now = datetime.now()
+ expire = datetime(now.year, now.month, now.day - 2)
+ sender.objects.filter(created__lt=expire).delete()
+
+post_save.connect(delete_old_tickets, sender=PgtIOU)
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/__init__.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/__init__.py
new file mode 100644
index 0000000..3b172cc
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/__init__.py
@@ -0,0 +1,3 @@
+from cas.tests.test_smoke import *
+from cas.tests.test_backend import *
+from cas.tests.test_views import *
\ No newline at end of file
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/factories.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/factories.py
new file mode 100644
index 0000000..865d348
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/factories.py
@@ -0,0 +1,15 @@
+from django.contrib.auth.models import User
+
+
+import factory
+
+
+class UserFactory(factory.DjangoModelFactory):
+ class Meta:
+ model = User
+
+ username = "derekst"
+ first_name = "new"
+ last_name = "user"
+ is_staff = True
+ password = factory.PostGenerationMethodCall('set_password', '1234')
\ No newline at end of file
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/test_backend.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/test_backend.py
new file mode 100644
index 0000000..cdcb2c9
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/test_backend.py
@@ -0,0 +1,30 @@
+import mock
+from django.test import TestCase
+
+from cas.backends import CASBackend
+from cas.tests import factories
+
+
+class CASBackendTest(TestCase):
+
+ def setUp(self):
+ self.user = factories.UserFactory.create()
+
+ def test_get_user(self):
+ backend = CASBackend()
+
+ self.assertEqual(backend.get_user(self.user.pk), self.user)
+
+ @mock.patch('cas.backends._verify')
+ def test_user_auto_create(self, verify):
+ username = 'faker'
+ verify.return_value = username
+ backend = CASBackend()
+
+ with self.settings(CAS_AUTO_CREATE_USER=False):
+ user = backend.authenticate('fake', 'fake')
+ self.assertIsNone(user)
+
+ with self.settings(CAS_AUTO_CREATE_USER=True):
+ user = backend.authenticate('fake', 'fake')
+ self.assertEquals(user.username, username)
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/test_smoke.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/test_smoke.py
new file mode 100644
index 0000000..19f78d8
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/test_smoke.py
@@ -0,0 +1,7 @@
+from cas.models import *
+from cas.backends import *
+from cas.middleware import *
+from cas.views import *
+from cas.decorators import *
+from cas.exceptions import *
+from cas.utils import *
diff --git a/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/test_views.py b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/test_views.py
new file mode 100644
index 0000000..1f5643a
--- /dev/null
+++ b/debian/python-django-cas/usr/lib/python2.7/dist-packages/cas/tests/test_views.py
@@ -0,0 +1,46 @@
+from django.test import TestCase, RequestFactory
+from django.test.utils import override_settings
+
+from cas.views import _redirect_url, _login_url, _logout_url, _service_url
+
+
+class RequestFactoryRemix(RequestFactory):
+
+ path = '/'
+
+ def get_host(self):
+ return 'signin.k-state.edu'
+
+ def is_secure(self):
... 1896 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-django-casclient.git
More information about the Python-modules-commits
mailing list