mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-10 03:11:07 +00:00
[thirdpart] Add shibboleth
This commit is contained in:
0
thirdpart/shibboleth/__init__.py
Executable file
0
thirdpart/shibboleth/__init__.py
Executable file
29
thirdpart/shibboleth/app_settings.py
Executable file
29
thirdpart/shibboleth/app_settings.py
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
|
||||||
|
#At a minimum you will need username,
|
||||||
|
default_shib_attributes = {
|
||||||
|
"Shibboleth-eppn": (True, "username"),
|
||||||
|
}
|
||||||
|
|
||||||
|
SHIB_ATTRIBUTE_MAP = getattr(settings, 'SHIBBOLETH_ATTRIBUTE_MAP', default_shib_attributes)
|
||||||
|
#Set to true if you are testing and want to insert sample headers.
|
||||||
|
SHIB_MOCK_HEADERS = getattr(settings, 'SHIBBOLETH_MOCK_HEADERS', False)
|
||||||
|
|
||||||
|
LOGIN_URL = getattr(settings, 'LOGIN_URL', None)
|
||||||
|
|
||||||
|
if not LOGIN_URL:
|
||||||
|
raise ImproperlyConfigured("A LOGIN_URL is required. Specify in settings.py")
|
||||||
|
|
||||||
|
#Optional logout parameters
|
||||||
|
#This should look like: https://sso.school.edu/idp/logout.jsp?return=%s
|
||||||
|
#The return url variable will be replaced in the LogoutView.
|
||||||
|
LOGOUT_URL = getattr(settings, 'SHIBBOLETH_LOGOUT_URL', None)
|
||||||
|
#LOGOUT_REDIRECT_URL specifies a default logout page that will always be used when
|
||||||
|
#users logout from Shibboleth.
|
||||||
|
LOGOUT_REDIRECT_URL = getattr(settings, 'SHIBBOLETH_LOGOUT_REDIRECT_URL', None)
|
||||||
|
#Name of key. Probably no need to change this.
|
||||||
|
LOGOUT_SESSION_KEY = getattr(settings, 'SHIBBOLETH_FORCE_REAUTH_SESSION_KEY', 'shib_force_reauth')
|
||||||
|
|
||||||
|
|
46
thirdpart/shibboleth/backends.py
Normal file
46
thirdpart/shibboleth/backends.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
from django.db import connection
|
||||||
|
from django.contrib.auth.models import User, Permission
|
||||||
|
from django.contrib.auth.backends import RemoteUserBackend
|
||||||
|
|
||||||
|
class ShibbolethRemoteUserBackend(RemoteUserBackend):
|
||||||
|
"""
|
||||||
|
This backend is to be used in conjunction with the ``RemoteUserMiddleware``
|
||||||
|
found in the middleware module of this package, and is used when the server
|
||||||
|
is handling authentication outside of Django.
|
||||||
|
|
||||||
|
By default, the ``authenticate`` method creates ``User`` objects for
|
||||||
|
usernames that don't already exist in the database. Subclasses can disable
|
||||||
|
this behavior by setting the ``create_unknown_user`` attribute to
|
||||||
|
``False``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Create a User object if not already in the database?
|
||||||
|
create_unknown_user = True
|
||||||
|
|
||||||
|
def authenticate(self, remote_user, shib_meta):
|
||||||
|
"""
|
||||||
|
The username passed as ``remote_user`` is considered trusted. This
|
||||||
|
method simply returns the ``User`` object with the given username,
|
||||||
|
creating a new ``User`` object if ``create_unknown_user`` is ``True``.
|
||||||
|
|
||||||
|
Returns None if ``create_unknown_user`` is ``False`` and a ``User``
|
||||||
|
object with the given username is not found in the database.
|
||||||
|
"""
|
||||||
|
if not remote_user:
|
||||||
|
return
|
||||||
|
user = None
|
||||||
|
username = self.clean_username(remote_user)
|
||||||
|
shib_user_params = dict([(k, shib_meta[k]) for k in User._meta.get_all_field_names() if k in shib_meta])
|
||||||
|
# Note that this could be accomplished in one try-except clause, but
|
||||||
|
# instead we use get_or_create when creating unknown users since it has
|
||||||
|
# built-in safeguards for multiple threads.
|
||||||
|
if self.create_unknown_user:
|
||||||
|
user, created = User.objects.get_or_create(username=shib_user_params.get('username'), defaults=shib_user_params)
|
||||||
|
if created:
|
||||||
|
user = self.configure_user(user)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
user = User.objects.get(**shib_user_params)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
pass
|
||||||
|
return user
|
26
thirdpart/shibboleth/context_processors.py
Executable file
26
thirdpart/shibboleth/context_processors.py
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
from urllib import quote
|
||||||
|
|
||||||
|
def login_link(request):
|
||||||
|
"""
|
||||||
|
This assumes your login link is the Shibboleth login page for your server
|
||||||
|
and uses the 'target' url parameter.
|
||||||
|
"""
|
||||||
|
full_path = quote(request.get_full_path())
|
||||||
|
login = reverse('shibboleth:login')
|
||||||
|
ll = "%s?target=%s" % (login, full_path)
|
||||||
|
return { 'login_link': ll }
|
||||||
|
|
||||||
|
def logout_link(request, *args):
|
||||||
|
"""
|
||||||
|
This assumes your login link is the Shibboleth login page for your server
|
||||||
|
and uses the 'target' url parameter.
|
||||||
|
e.g: https://school.edu/Shibboleth.sso/Login
|
||||||
|
"""
|
||||||
|
from app_settings import LOGOUT_URL, LOGOUT_REDIRECT_URL
|
||||||
|
#LOGOUT_REDIRECT_URL specifies a default logout page that will always be used when
|
||||||
|
#users logout from Shibboleth.
|
||||||
|
target = LOGOUT_REDIRECT_URL or quote(request.build_absolute_uri())
|
||||||
|
logout = reverse('shibboleth:logout')
|
||||||
|
ll = "%s?target=%s" % (logout, target)
|
||||||
|
return { 'logout_link': ll }
|
23
thirdpart/shibboleth/decorators.py
Executable file
23
thirdpart/shibboleth/decorators.py
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
"""
|
||||||
|
Decorators to use with Shibboleth.
|
||||||
|
"""
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib import auth
|
||||||
|
from middleware import ShibbolethRemoteUserMiddleware
|
||||||
|
|
||||||
|
def login_optional(func):
|
||||||
|
"""
|
||||||
|
Decorator to pull Shib attributes and log user in, if possible. Does not
|
||||||
|
enforce login.
|
||||||
|
"""
|
||||||
|
def decorator(request,*args, **kwargs):
|
||||||
|
#Do nothing if the remoteuser backend isn't activated
|
||||||
|
if 'shibboleth.backends.ShibbolethRemoteUserBackend' not in settings.AUTHENTICATION_BACKENDS:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
shib = ShibbolethRemoteUserMiddleware()
|
||||||
|
#Proccess the request with the Shib middlemare, which will log the
|
||||||
|
#user in if we can.
|
||||||
|
proc = shib.process_request(request)
|
||||||
|
return func(request, *args, **kwargs)
|
||||||
|
return decorator
|
102
thirdpart/shibboleth/middleware.py
Executable file
102
thirdpart/shibboleth/middleware.py
Executable file
@@ -0,0 +1,102 @@
|
|||||||
|
from django.contrib.auth.middleware import RemoteUserMiddleware
|
||||||
|
from django.contrib import auth
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
|
||||||
|
from shibboleth.app_settings import SHIB_ATTRIBUTE_MAP, LOGOUT_SESSION_KEY
|
||||||
|
|
||||||
|
class ShibbolethRemoteUserMiddleware(RemoteUserMiddleware):
|
||||||
|
"""
|
||||||
|
Authentication Middleware for use with Shibboleth. Uses the recommended pattern
|
||||||
|
for remote authentication from: http://code.djangoproject.com/svn/django/tags/releases/1.3/django/contrib/auth/middleware.py
|
||||||
|
"""
|
||||||
|
def process_request(self, request):
|
||||||
|
# AuthenticationMiddleware is required so that request.user exists.
|
||||||
|
if not hasattr(request, 'user'):
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
"The Django remote user auth middleware requires the"
|
||||||
|
" authentication middleware to be installed. Edit your"
|
||||||
|
" MIDDLEWARE_CLASSES setting to insert"
|
||||||
|
" 'django.contrib.auth.middleware.AuthenticationMiddleware'"
|
||||||
|
" before the RemoteUserMiddleware class.")
|
||||||
|
|
||||||
|
#To support logout. If this variable is True, do not
|
||||||
|
#authenticate user and return now.
|
||||||
|
if request.session.get(LOGOUT_SESSION_KEY) == True:
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
#Delete the shib reauth session key if present.
|
||||||
|
request.session.pop(LOGOUT_SESSION_KEY, None)
|
||||||
|
|
||||||
|
#Locate the remote user header.
|
||||||
|
try:
|
||||||
|
username = request.META[self.header]
|
||||||
|
except KeyError:
|
||||||
|
# If specified header doesn't exist then return (leaving
|
||||||
|
# request.user set to AnonymousUser by the
|
||||||
|
# AuthenticationMiddleware).
|
||||||
|
return
|
||||||
|
# If the user is already authenticated and that user is the user we are
|
||||||
|
# getting passed in the headers, then the correct user is already
|
||||||
|
# persisted in the session and we don't need to continue.
|
||||||
|
if request.user.is_authenticated():
|
||||||
|
if request.user.username == self.clean_username(username, request):
|
||||||
|
return
|
||||||
|
|
||||||
|
# Make sure we have all required Shiboleth elements before proceeding.
|
||||||
|
shib_meta, error = self.parse_attributes(request)
|
||||||
|
# Add parsed attributes to the session.
|
||||||
|
request.session['shib'] = shib_meta
|
||||||
|
if error:
|
||||||
|
raise ShibbolethValidationError("All required Shibboleth elements"
|
||||||
|
" not found. %s" % shib_meta)
|
||||||
|
|
||||||
|
# We are seeing this user for the first time in this session, attempt
|
||||||
|
# to authenticate the user.
|
||||||
|
user = auth.authenticate(remote_user=username, shib_meta=shib_meta)
|
||||||
|
if user:
|
||||||
|
# User is valid. Set request.user and persist user in the session
|
||||||
|
# by logging the user in.
|
||||||
|
request.user = user
|
||||||
|
auth.login(request, user)
|
||||||
|
user.set_unusable_password()
|
||||||
|
user.save()
|
||||||
|
# call make profile.
|
||||||
|
self.make_profile(user, shib_meta)
|
||||||
|
#setup session.
|
||||||
|
self.setup_session(request)
|
||||||
|
|
||||||
|
def make_profile(self, user, shib_meta):
|
||||||
|
"""
|
||||||
|
This is here as a stub to allow subclassing of ShibbolethRemoteUserMiddleware
|
||||||
|
to include a make_profile method that will create a Django user profile
|
||||||
|
from the Shib provided attributes. By default it does nothing.
|
||||||
|
"""
|
||||||
|
return
|
||||||
|
|
||||||
|
def setup_session(self, request):
|
||||||
|
"""
|
||||||
|
If you want to add custom code to setup user sessions, you
|
||||||
|
can extend this.
|
||||||
|
"""
|
||||||
|
return
|
||||||
|
|
||||||
|
def parse_attributes(self, request):
|
||||||
|
"""
|
||||||
|
Parse the incoming Shibboleth attributes.
|
||||||
|
From: https://github.com/russell/django-shibboleth/blob/master/django_shibboleth/utils.py
|
||||||
|
Pull the mapped attributes from the apache headers.
|
||||||
|
"""
|
||||||
|
shib_attrs = {}
|
||||||
|
error = False
|
||||||
|
meta = request.META
|
||||||
|
for header, attr in SHIB_ATTRIBUTE_MAP.items():
|
||||||
|
required, name = attr
|
||||||
|
value = meta.get(header, None)
|
||||||
|
shib_attrs[name] = value
|
||||||
|
if not value or value == '':
|
||||||
|
if required:
|
||||||
|
error = True
|
||||||
|
return shib_attrs, error
|
||||||
|
|
||||||
|
class ShibbolethValidationError(Exception):
|
||||||
|
pass
|
1
thirdpart/shibboleth/models.py
Executable file
1
thirdpart/shibboleth/models.py
Executable file
@@ -0,0 +1 @@
|
|||||||
|
#intentionally left blank
|
18
thirdpart/shibboleth/templates/shibboleth/user_info.html
Executable file
18
thirdpart/shibboleth/templates/shibboleth/user_info.html
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<h1>User stuff</h1>
|
||||||
|
<p>The mapped shib attributes will display here.</p>
|
||||||
|
<ul>
|
||||||
|
<li>username: {{ user.username }}</li>
|
||||||
|
<li>name: {{ user.first_name }} {{ user.last_name }}</li>
|
||||||
|
<li>email: {{ user.email }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
1
thirdpart/shibboleth/tests/__init__.py
Executable file
1
thirdpart/shibboleth/tests/__init__.py
Executable file
@@ -0,0 +1 @@
|
|||||||
|
from shib import *
|
118
thirdpart/shibboleth/tests/shib.py
Executable file
118
thirdpart/shibboleth/tests/shib.py
Executable file
@@ -0,0 +1,118 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.utils import unittest
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.test.client import RequestFactory
|
||||||
|
from django.test.client import Client
|
||||||
|
|
||||||
|
SAMPLE_HEADERS = {
|
||||||
|
"REMOTE_USER": 'devloper@school.edu',
|
||||||
|
"Shib-Application-ID": "default",
|
||||||
|
"Shib-Authentication-Method": "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified",
|
||||||
|
"Shib-AuthnContext-Class": "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified",
|
||||||
|
"Shib-Identity-Provider": "https://sso.college.edu/idp/shibboleth",
|
||||||
|
"Shib-Session-ID": "1",
|
||||||
|
"Shib-Session-Index": "12",
|
||||||
|
"Shibboleth-affiliation": "member@college.edu;staff@college.edu",
|
||||||
|
"Shibboleth-schoolBarCode": "12345678",
|
||||||
|
"Shibboleth-schoolNetId": "Sample_Developer",
|
||||||
|
"Shibboleth-schoolStatus": "active",
|
||||||
|
"Shibboleth-department": "University Library, Integrated Technology Services",
|
||||||
|
"Shibboleth-displayName": "Sample Developer",
|
||||||
|
"Shibboleth-eppn": "sampledeveloper@school.edu",
|
||||||
|
"Shibboleth-givenName": "Sample",
|
||||||
|
"Shibboleth-isMemberOf": "SCHOOL:COMMUNITY:EMPLOYEE:ADMINISTRATIVE:BASE;SCHOOL:COMMUNITY:EMPLOYEE:STAFF:SAC:P;COMMUNITY:ALL;SCHOOL:COMMUNITY:EMPLOYEE:STAFF:SAC:M;",
|
||||||
|
"Shibboleth-mail": "Sample_Developer@school.edu",
|
||||||
|
"Shibboleth-persistent-id": "https://sso.college.edu/idp/shibboleth!https://server.college.edu/shibboleth-sp!sk1Z9qKruvXY7JXvsq4GRb8GCUk=",
|
||||||
|
"Shibboleth-sn": "Developer",
|
||||||
|
"Shibboleth-title": "Library Developer",
|
||||||
|
"Shibboleth-unscoped-affiliation": "member;staff"
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.SHIBBOLETH_ATTRIBUTE_MAP = {
|
||||||
|
"Shib-Identity-Provider": (True, "idp"),
|
||||||
|
"Shibboleth-mail": (True, "email"),
|
||||||
|
"Shibboleth-eppn": (True, "username"),
|
||||||
|
"Shibboleth-schoolStatus": (True, "status"),
|
||||||
|
"Shibboleth-affiliation": (True, "affiliation"),
|
||||||
|
"Shib-Session-ID": (True, "session_id"),
|
||||||
|
"Shibboleth-givenName": (True, "first_name"),
|
||||||
|
"Shibboleth-sn": (True, "last_name"),
|
||||||
|
"Shibboleth-mail": (True, "email"),
|
||||||
|
"Shibboleth-schoolBarCode": (False, "barcode")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
settings.AUTHENTICATION_BACKENDS += (
|
||||||
|
'shibboleth.backends.ShibbolethRemoteUserBackend',
|
||||||
|
)
|
||||||
|
|
||||||
|
settings.MIDDLEWARE_CLASSES += (
|
||||||
|
'shibboleth.middleware.ShibbolethRemoteUserMiddleware',
|
||||||
|
)
|
||||||
|
|
||||||
|
settings.ROOT_URLCONF = 'shibboleth.urls'
|
||||||
|
|
||||||
|
settings.SHIBBOLETH_LOGOUT_URL = 'https://sso.school.edu/logout?next=%s'
|
||||||
|
settings.SHIBBOLETH_LOGOUT_REDIRECT_URL = 'http://school.edu/'
|
||||||
|
|
||||||
|
from shibboleth.views import ShibbolethView
|
||||||
|
|
||||||
|
def read(fname):
|
||||||
|
return open(os.path.join(os.path.dirname(__file__), fname)).read()
|
||||||
|
|
||||||
|
class AttributesTest(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.c = Client()
|
||||||
|
|
||||||
|
def test_decorator_not_authenticated(self):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
resp = self.c.get('/')
|
||||||
|
self.assertEqual(resp.status_code, 302)
|
||||||
|
#Test the context - shouldn't exist
|
||||||
|
self.assertEqual(resp.context, None)
|
||||||
|
|
||||||
|
def test_decorator_authenticated(self):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
resp = self.c.get('/', **SAMPLE_HEADERS)
|
||||||
|
self.assertEqual(resp.status_code, 200)
|
||||||
|
#Test the context
|
||||||
|
user = resp.context.get('user')
|
||||||
|
self.assertEqual(user.email, 'Sample_Developer@school.edu')
|
||||||
|
self.assertEqual(user.first_name, 'Sample')
|
||||||
|
self.assertEqual(user.last_name, 'Developer')
|
||||||
|
self.assertTrue(user.is_authenticated())
|
||||||
|
self.assertFalse(user.is_anonymous())
|
||||||
|
|
||||||
|
class LogoutTest(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.c = Client()
|
||||||
|
|
||||||
|
def test_logout(self):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
from shibboleth import app_settings
|
||||||
|
#Login
|
||||||
|
login = self.c.get('/', **SAMPLE_HEADERS)
|
||||||
|
self.assertEqual(login.status_code, 200)
|
||||||
|
#Logout
|
||||||
|
logout = self.c.get('/logout/', **SAMPLE_HEADERS)
|
||||||
|
self.assertEqual(logout.status_code, 302)
|
||||||
|
#Ensure redirect happened.
|
||||||
|
self.assertEqual(
|
||||||
|
logout['Location'],
|
||||||
|
'https://sso.school.edu/logout?next=http://school.edu/'
|
||||||
|
)
|
||||||
|
#Check to see if the session has the force logout key.
|
||||||
|
self.assertTrue(self.c.session.get(app_settings.LOGOUT_SESSION_KEY))
|
||||||
|
#Load root url to see if user is in fact logged out.
|
||||||
|
resp = self.c.get('/', **SAMPLE_HEADERS)
|
||||||
|
self.assertEqual(resp.status_code, 302)
|
||||||
|
#Make sure the context is empty.
|
||||||
|
self.assertEqual(resp.context, None)
|
||||||
|
|
14
thirdpart/shibboleth/urls.py
Executable file
14
thirdpart/shibboleth/urls.py
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
from distutils.version import StrictVersion
|
||||||
|
import django
|
||||||
|
if StrictVersion(django.get_version()) < StrictVersion('1.4'):
|
||||||
|
from django.conf.urls.defaults import *
|
||||||
|
else:
|
||||||
|
from django.conf.urls import patterns, url
|
||||||
|
|
||||||
|
from views import ShibbolethView, ShibbolethLogoutView, ShibbolethLoginView
|
||||||
|
|
||||||
|
urlpatterns = patterns('',
|
||||||
|
url(r'^login/$', ShibbolethLoginView.as_view(), name='login'),
|
||||||
|
url(r'^logout/$', ShibbolethLogoutView.as_view(), name='logout'),
|
||||||
|
url(r'^$', ShibbolethView.as_view(), name='info'),
|
||||||
|
)
|
80
thirdpart/shibboleth/views.py
Executable file
80
thirdpart/shibboleth/views.py
Executable file
@@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib import auth
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.shortcuts import redirect
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
|
from urllib import quote
|
||||||
|
|
||||||
|
#Logout settings.
|
||||||
|
from shibboleth.app_settings import LOGOUT_URL, LOGOUT_REDIRECT_URL, LOGOUT_SESSION_KEY
|
||||||
|
|
||||||
|
class ShibbolethView(TemplateView):
|
||||||
|
"""
|
||||||
|
This is here to offer a Shib protected page that we can
|
||||||
|
route users through to login.
|
||||||
|
"""
|
||||||
|
template_name = 'shibboleth/user_info.html'
|
||||||
|
|
||||||
|
@method_decorator(login_required)
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Django docs say to decorate the dispatch method for
|
||||||
|
class based views.
|
||||||
|
https://docs.djangoproject.com/en/dev/topics/auth/
|
||||||
|
"""
|
||||||
|
return super(ShibbolethView, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get(self, request, **kwargs):
|
||||||
|
"""Process the request."""
|
||||||
|
next = self.request.GET.get('next', None)
|
||||||
|
if next is not None:
|
||||||
|
return redirect(next)
|
||||||
|
return super(ShibbolethView, self).get(request)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super(ShibbolethView, self).get_context_data(**kwargs)
|
||||||
|
context['user'] = self.request.user
|
||||||
|
return context
|
||||||
|
|
||||||
|
class ShibbolethLoginView(TemplateView):
|
||||||
|
"""
|
||||||
|
Pass the user to the Shibboleth login page.
|
||||||
|
Some code borrowed from:
|
||||||
|
https://github.com/stefanfoulis/django-class-based-auth-views.
|
||||||
|
"""
|
||||||
|
redirect_field_name = "target"
|
||||||
|
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
#Remove session value that is forcing Shibboleth reauthentication.
|
||||||
|
self.request.session.pop(LOGOUT_SESSION_KEY, None)
|
||||||
|
login = settings.LOGIN_URL + '?target=%s' % quote(self.request.GET.get(self.redirect_field_name))
|
||||||
|
return redirect(login)
|
||||||
|
|
||||||
|
class ShibbolethLogoutView(TemplateView):
|
||||||
|
"""
|
||||||
|
Pass the user to the Shibboleth logout page.
|
||||||
|
Some code borrowed from:
|
||||||
|
https://github.com/stefanfoulis/django-class-based-auth-views.
|
||||||
|
"""
|
||||||
|
redirect_field_name = "target"
|
||||||
|
|
||||||
|
def get(self, *args, **kwargs):
|
||||||
|
#Log the user out.
|
||||||
|
auth.logout(self.request)
|
||||||
|
#Set session key that middleware will use to force
|
||||||
|
#Shibboleth reauthentication.
|
||||||
|
self.request.session[LOGOUT_SESSION_KEY] = True
|
||||||
|
#Get target url in order of preference.
|
||||||
|
target = LOGOUT_REDIRECT_URL or\
|
||||||
|
quote(self.request.GET.get(self.redirect_field_name)) or\
|
||||||
|
quote(request.build_absolute_uri())
|
||||||
|
logout = LOGOUT_URL % target
|
||||||
|
return redirect(logout)
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user