[open-ils-commits] r969 - in servres/trunk: . conifer conifer/integration conifer/plumbing conifer/syrup conifer/syrup/views conifer/templates (gfawcett)
svn at svn.open-ils.org
svn at svn.open-ils.org
Tue Aug 17 22:46:19 EDT 2010
Author: gfawcett
Date: 2010-08-17 22:46:17 -0400 (Tue, 17 Aug 2010)
New Revision: 969
Added:
servres/trunk/conifer/integration/cas.py
Modified:
servres/trunk/.gitignore
servres/trunk/conifer/integration/uwindsor.py
servres/trunk/conifer/plumbing/hooksystem.py
servres/trunk/conifer/settings.py
servres/trunk/conifer/syrup/integration.py
servres/trunk/conifer/syrup/views/_common.py
servres/trunk/conifer/syrup/views/genshi_namespace.py
servres/trunk/conifer/templates/browse_index.xhtml
servres/trunk/conifer/templates/master.xhtml
servres/trunk/conifer/templates/search_results.xhtml
servres/trunk/conifer/urls.py
Log:
CAS authentication.
See: http://code.google.com/p/django-cas/
To use CAS authentication, you must "easy_install django-cas", then add these
to your local_settings.py:
CAS_AUTHENTICATION = True
CAS_SERVER_URL = 'https://my.cas.server.example.net/cas/'
You will probably also want to define two customization hooks:
external_person_lookup and user_needs_decoration. See:
conifer/syrup/integration.py.
Modified: servres/trunk/.gitignore
===================================================================
--- servres/trunk/.gitignore 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/.gitignore 2010-08-18 02:46:17 UTC (rev 969)
@@ -13,3 +13,4 @@
/conifer/remodel.sqlite3
*~
/conifer/test.db
+/conifer/syrup/test.db
Added: servres/trunk/conifer/integration/cas.py
===================================================================
--- servres/trunk/conifer/integration/cas.py (rev 0)
+++ servres/trunk/conifer/integration/cas.py 2010-08-18 02:46:17 UTC (rev 969)
@@ -0,0 +1,53 @@
+# CAS authentication. See http://code.google.com/p/django-cas/
+#
+# To use CAS authentication, you must "easy_install django-cas", then add these
+# to your local_settings.py:
+#
+# CAS_AUTHENTICATION = True
+# CAS_SERVER_URL = 'https://my.cas.server.example.net/cas/'
+#
+# You will probably also want to define two customization hooks:
+# external_person_lookup and user_needs_decoration. See:
+# conifer/syrup/integration.py.
+
+from conifer.plumbing.hooksystem import gethook, callhook
+import django_cas.backends
+
+
+class CASBackend(django_cas.backends.CASBackend):
+
+ def authenticate(self, ticket, service):
+ """Authenticates CAS ticket and retrieves user data"""
+
+ user = super(CASBackend, self).authenticate(ticket, service)
+ if user and gethook('external_person_lookup'):
+ decorate_user(user)
+ return user
+
+
+# TODO is this really CAS specific? Wouldn't linktool (for example)
+# also need such a decorator?
+
+def decorate_user(user):
+ dectest = gethook('user_needs_decoration', default=_user_needs_decoration)
+ if not dectest(user):
+ return
+
+ dir_entry = callhook('external_person_lookup', user.username)
+ if dir_entry is None:
+ return
+
+ user.first_name = dir_entry['given_name']
+ user.last_name = dir_entry['surname']
+ user.email = dir_entry.get('email', user.email)
+ user.save()
+
+ if 'patron_id' in dir_entry:
+ # note, we overrode user.get_profile() to automatically create
+ # missing profiles. See models.py.
+ user.get_profile().ils_userid = dir_entry['patron_id']
+ profile.save()
+
+
+def _user_needs_decoration(user):
+ return user.last_name is not None
Modified: servres/trunk/conifer/integration/uwindsor.py
===================================================================
--- servres/trunk/conifer/integration/uwindsor.py 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/conifer/integration/uwindsor.py 2010-08-18 02:46:17 UTC (rev 969)
@@ -135,7 +135,8 @@
Given a userid, return either None (if the user cannot be found),
or a dictionary representing the user. The dictionary must contain
the keys ('given_name', 'surname') and should contain 'email' if
- an email address is known.
+ an email address is known, and 'patron_id' if a library-system ID
+ is known.
"""
return uwindsor_campus_info.call('person_lookup', userid)
Modified: servres/trunk/conifer/plumbing/hooksystem.py
===================================================================
--- servres/trunk/conifer/plumbing/hooksystem.py 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/conifer/plumbing/hooksystem.py 2010-08-18 02:46:17 UTC (rev 969)
@@ -6,8 +6,6 @@
__all__ = ['callhook', 'callhook_required', 'gethook']
def gethook(name, default=None):
- print dir(HOOKS)
- print (name, getattr(HOOKS, name))
return getattr(HOOKS, name) or default
def callhook_required(name, *args, **kwargs):
@@ -19,3 +17,5 @@
f = getattr(HOOKS, name)
if f:
return f(*args, **kwargs)
+ else:
+ return None
Modified: servres/trunk/conifer/settings.py
===================================================================
--- servres/trunk/conifer/settings.py 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/conifer/settings.py 2010-08-18 02:46:17 UTC (rev 969)
@@ -87,9 +87,11 @@
'conifer.syrup',
]
+LOGIN_URL = '/accounts/login/'
+LOGOUT_URL = '/accounts/logout'
+
AUTH_PROFILE_MODULE = 'syrup.UserProfile'
-
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend'
]
@@ -97,6 +99,10 @@
EVERGREEN_AUTHENTICATION = False
LINKTOOL_AUTHENTICATION = False
+# CAS authentication requires 'django-cas',
+# http://code.google.com/p/django-cas/
+CAS_AUTHENTICATION = False
+
#---------------------------------------------------------------------------
# local_settings.py
@@ -126,3 +132,8 @@
if LINKTOOL_AUTHENTICATION:
AUTHENTICATION_BACKENDS.append(
'conifer.integration.linktool.backend.LinktoolAuthBackend')
+
+if CAS_AUTHENTICATION:
+ AUTHENTICATION_BACKENDS.append('conifer.integration.cas.CASBackend')
+ LOGIN_URL = '/cas/login'
+ LOGOUT_URL = '/cas/logout'
Modified: servres/trunk/conifer/syrup/integration.py
===================================================================
--- servres/trunk/conifer/syrup/integration.py 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/conifer/syrup/integration.py 2010-08-18 02:46:17 UTC (rev 969)
@@ -109,3 +109,14 @@
an email address is known.
"""
+ at disable
+def user_needs_decoration(user_obj):
+ """
+ User objects are sometimes created automatically, with only a
+ username. This function determines whether it would be fruitful to
+ "decorate" the User object with, e.g., a given name, surname, and
+ email address. It doesn't perform the decoration, it simply tests
+ whether the current user object is "incomplete." Another hook
+ 'external_person_lookup,' is used by Syrup to fetch the personal
+ information when needed.
+ """
Modified: servres/trunk/conifer/syrup/views/_common.py
===================================================================
--- servres/trunk/conifer/syrup/views/_common.py 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/conifer/syrup/views/_common.py 2010-08-18 02:46:17 UTC (rev 969)
@@ -4,10 +4,12 @@
# is a module which acts as a global namespace when expanding a Genshi
# template.
+from . import genshi_namespace
from conifer.here import HERE
from conifer.plumbing.genshi_support import TemplateSet
-from . import genshi_namespace
+from django.conf import settings
+
g = TemplateSet(HERE('templates'), genshi_namespace)
#----------------------------------------------------------------------
@@ -48,10 +50,11 @@
def _access_denied(request, message):
if request.user.is_anonymous():
# then take them to login screen....
- dest = (request.META['SCRIPT_NAME'] + \
- '/accounts/login/?next=%s%s' % (
- request.META['SCRIPT_NAME'],
- request.META['PATH_INFO']))
+ dest = (request.META['SCRIPT_NAME'] +
+ settings.LOGIN_URL +
+ '?next=' +
+ request.META['SCRIPT_NAME'] +
+ request.META['PATH_INFO'])
return HttpResponseRedirect(dest)
else:
return simple_message(_('Access denied.'), message,
Modified: servres/trunk/conifer/syrup/views/genshi_namespace.py
===================================================================
--- servres/trunk/conifer/syrup/views/genshi_namespace.py 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/conifer/syrup/views/genshi_namespace.py 2010-08-18 02:46:17 UTC (rev 969)
@@ -13,4 +13,5 @@
from conifer.plumbing.hooksystem import gethook, callhook
from conifer.syrup import models
+from django.conf import settings
from django.utils.translation import ugettext as _
Modified: servres/trunk/conifer/templates/browse_index.xhtml
===================================================================
--- servres/trunk/conifer/templates/browse_index.xhtml 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/conifer/templates/browse_index.xhtml 2010-08-18 02:46:17 UTC (rev 969)
@@ -15,7 +15,7 @@
<h1>${title}</h1>
<div py:if="user.is_anonymous()">
(Note: some reserve materials may require you
- to <a href="${ROOT}/accounts/login/?next=${ROOT}/">log in</a>)
+ to <a href="${ROOT}${settings.LOGIN_URL}?next=${ROOT}/">log in</a>)
</div>
Modified: servres/trunk/conifer/templates/master.xhtml
===================================================================
--- servres/trunk/conifer/templates/master.xhtml 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/conifer/templates/master.xhtml 2010-08-18 02:46:17 UTC (rev 969)
@@ -51,12 +51,12 @@
</div>
<div id="welcome" py:if="user.is_authenticated()">
<strong style="padding-right: 18px;">Welcome, ${user.first_name or user.username}!</strong>
- <a href="${ROOT}/accounts/logout">Log Out</a>
+ <a href="${ROOT}${settings.LOGOUT_URL}">Log Out</a>
• <a href="${ROOT}/prefs/">Preferences</a>
</div>
<div id="welcome" py:if="not user.is_authenticated()">
<strong style="padding-right: 18px;">Welcome!</strong>
- <a class="loginbutton" href="${ROOT}/accounts/login/">Log In</a>
+ <a class="loginbutton" href="${ROOT}${settings.LOGIN_URL}">Log In</a>
• <a href="${ROOT}/prefs/">Preferences</a>
</div>
</div>
Modified: servres/trunk/conifer/templates/search_results.xhtml
===================================================================
--- servres/trunk/conifer/templates/search_results.xhtml 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/conifer/templates/search_results.xhtml 2010-08-18 02:46:17 UTC (rev 969)
@@ -53,7 +53,7 @@
<div py:if="user.is_anonymous()">
Your searches may return more results if you <a
- href="${ROOT}/accounts/login/?next=${ROOT}/">log in</a> before
+ href="${ROOT}${settings.LOGIN_URL}?next=${ROOT}/">log in</a> before
searching.
</div>
Modified: servres/trunk/conifer/urls.py
===================================================================
--- servres/trunk/conifer/urls.py 2010-08-18 02:45:46 UTC (rev 968)
+++ servres/trunk/conifer/urls.py 2010-08-18 02:46:17 UTC (rev 969)
@@ -47,3 +47,9 @@
(r'^linktool-welcome/copy_old$', 'linktool_copy_old'),
(r'^linktool-welcome/associate$', 'linktool_associate'),
)
+
+if settings.CAS_AUTHENTICATION:
+ urlpatterns += patterns(
+ 'django_cas.views',
+ (r'^%s$' % settings.LOGIN_URL[1:], 'login'),
+ (r'^%s$' % settings.LOGOUT_URL[1:], 'logout'))
More information about the open-ils-commits
mailing list