[open-ils-commits] r132 - in servres/trunk/conifer: custom syrup (gfawcett)

svn at svn.open-ils.org svn at svn.open-ils.org
Sun Mar 1 16:18:54 EST 2009


Author: gfawcett
Date: 2009-03-01 16:18:50 -0500 (Sun, 01 Mar 2009)
New Revision: 132

Modified:
   servres/trunk/conifer/custom/auth_evergreen.py
   servres/trunk/conifer/syrup/models.py
Log:
generic make-a-user from backend data source

Modified: servres/trunk/conifer/custom/auth_evergreen.py
===================================================================
--- servres/trunk/conifer/custom/auth_evergreen.py	2009-03-01 21:18:17 UTC (rev 131)
+++ servres/trunk/conifer/custom/auth_evergreen.py	2009-03-01 21:18:50 UTC (rev 132)
@@ -11,17 +11,7 @@
     def authenticate(self, username=None, password=None):
         pwd_valid = self.login(username, password)
         if pwd_valid:
-            try:
-                user = User.objects.get(username=username)
-            except User.DoesNotExist:
-                u = self.lookup(username)
-                user = User(username=username,
-                            first_name= u['first_name'],
-                            last_name = u['last_name'],
-                            email     = u['email'])
-                user.set_unusable_password()
-                user.save()
-            return user
+            return self.maybe_initialize_user(username)
         return None
 
     def get_user(self, user_id):
@@ -29,3 +19,33 @@
             return User.objects.get(pk=user_id)
         except User.DoesNotExist:
             return None
+
+    def maybe_initialize_user(self, username, look_local=True):
+        """Look up user in Django db; if not found, fetch user detail
+        from backend and set up a local user object. Return None if no
+        such user exists in either Django or the backend.
+
+        Setting look_local=False skips the Django search and heads
+        straight to the backend; this shaves a database call when
+        walking a set of backends to initialize a user. Skipping
+        look_local on a username that already exists in Django will
+        certainly lead to an integrity error.
+
+        This method is NOT part of the Django backend interface.
+        """
+        user = None
+        if look_local:
+            try:
+                user = User.objects.get(username=username)
+            except User.DoesNotExist:
+                pass
+        if user is None:
+            u = self.lookup(username)
+            if u:           # user found in Evergreen.
+                user = User(username=username,
+                            first_name = u['first_name'],
+                            last_name  = u['last_name'],
+                            email      = u['email'])
+                user.set_unusable_password()
+                user.save()
+        return user

Modified: servres/trunk/conifer/syrup/models.py
===================================================================
--- servres/trunk/conifer/syrup/models.py	2009-03-01 21:18:17 UTC (rev 131)
+++ servres/trunk/conifer/syrup/models.py	2009-03-01 21:18:50 UTC (rev 132)
@@ -1,6 +1,7 @@
 from django.db import models as m
 from django.contrib.auth.models import User
 from django.contrib.auth.models import AnonymousUser
+from django.contrib.auth import get_backends
 from datetime import datetime
 from genshi import Markup
 import re
@@ -75,6 +76,33 @@
             .order_by('-user__last_name','-user__first_name')
 
 #----------------------------------------------------------------------
+# Initializing an external user account
+
+# For usernames that come from external authentication sources (LDAP,
+# Evergreen, etc.) we need a general way to look up a user who may not
+# yet have a Django account.  For example, you might want to add user
+# 'xsmith' as the instructor for a course. If 'xsmith' is in LDAP but
+# not yet in Django, it would be nice if a Django record were lazily
+# created for him upon lookup. 
+
+# That's what 'maybe_initialize_user' is for: participating backends
+# provide a 'maybe_initialize_user' method which creates a new User
+# record if one doesn't exist. Otherwise, 'maybe_initialize_user' is
+# equivalent to 'User.objects.get(username=username)'.
+
+_backends_that_can_initialize_users = [
+    be for be in get_backends() if hasattr(be, 'maybe_initialize_user')]
+
+def maybe_initialize_user(username):
+    try:
+        return User.objects.get(username=username)
+    except User.DoesNotExist:
+        for be in _backends_that_can_initialize_users:
+            user = be.maybe_initialize_user(username, look_local=False)
+            if user:
+                return user
+
+#----------------------------------------------------------------------
 # LIBRARIES, SERVICE DESKS
 
 class LibraryUnit(m.Model):



More information about the open-ils-commits mailing list