Attachment 'wiki_auth.py'

Download

   1 # Copyright 2011 SPIELO International.
   2 #
   3 # Redistribution and use in source and binary forms, with or without modification,
   4 # are permitted provided that the following conditions are met:
   5 #
   6 #     1. Redistributions of source code must retain the above copyright notice, 
   7 #        this list of conditions and the following disclaimer.
   8 #  
   9 #     2. Redistributions in binary form must reproduce the above copyright 
  10 #        notice, this list of conditions and the following disclaimer in the
  11 #        documentation and/or other materials provided with the distribution.
  12 #
  13 #     3. Neither the name of Django nor the names of its contributors may be used
  14 #        to endorse or promote products derived from this software without
  15 #        specific prior written permission.
  16 #
  17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  18 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20 # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  21 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  24 # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27 #
  28 #
  29 # Revision history:
  30 #
  31 # 2011-10-16  Michael Foetsch  mfoetsch@spielo-int.com
  32 #
  33 #       * Initial version
  34 #
  35 
  36 import codecs
  37 import logging
  38 import os
  39 import pickle
  40 from django.contrib import auth
  41 from django.contrib.auth.backends import ModelBackend
  42 from django.contrib.auth.models import User
  43 from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
  44 
  45 class WikiAuthMiddleware(object):
  46     COOKIE_NAME = "MOIN_SESSION_443_ROOT"
  47     SESSION_DIR = "/wiki/data/cache/__session__"
  48     USER_DIR = "/wiki/data/user"
  49 
  50     def process_request(self, request):
  51         if not hasattr(request, 'user'):
  52             raise ImproperlyConfigured(
  53                 "You need to add "
  54                 " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
  55                 " before WikiAuthMiddleware to the MIDDLEWARE_CLASSES setting.")
  56         try:
  57             token = request.COOKIES[self.COOKIE_NAME]
  58             logging.getLogger('wiki_auth').debug('found token %r' % (token,))
  59         except KeyError:
  60             return
  61 
  62         session_file = os.path.join(self.SESSION_DIR, token)
  63         if not os.path.isfile(session_file):
  64             logging.getLogger('wiki_auth').debug('session_file %r does not exist' % (session_file,))
  65             return
  66         try:
  67             f = open(session_file, "rb")
  68         except OSError:
  69             logging.getLogger('wiki_auth').warning('cannot open session_file %r' % (session_file,))
  70 	    return
  71         session_data = f.read(4096)
  72         f.close()
  73         try:
  74             session_dict = pickle.loads(session_data)
  75         except:
  76             logging.getLogger('wiki_auth').warning('cannot unpickle session_file %r' % (session_file,))
  77             return
  78         try:
  79             user_id = session_dict['user.id']
  80         except KeyError:
  81             logging.getLogger('wiki_auth').warning('session_dict does not contain "user.id"')
  82             return
  83         logging.getLogger('wiki_auth').debug('user.id = %r' % (user_id,))
  84 
  85         user_file = os.path.join(self.USER_DIR, user_id)
  86         try:
  87             f = codecs.open(user_file, "r", "utf-8")
  88         except OSError:
  89             logging.getLogger('wiki_auth').warning('user %r does not exist' % (user_id,))
  90             return
  91         user_name = None
  92         user_email = None
  93         user_alias = None
  94         for ln in f:
  95             if not '=' in ln:
  96                 continue
  97             split_ln = ln.split('=')
  98             key = split_ln[0]
  99             value = '='.join(split_ln[1:]).strip()
 100             if key == 'name':
 101                 user_name = value
 102             elif key == 'email':
 103                 user_email = value
 104             elif key == 'aliasname':
 105                 user_alias = value
 106         logging.getLogger('wiki_auth').debug('credentials: user_name = %r, user_email = %r, user_alias = %r' % (user_name, user_email, user_alias))
 107 
 108         if request.user.is_authenticated() and request.user.username == user_name:
 109             logging.getLogger('wiki_auth').debug('user %r already logged in' % (user_name,))
 110             return
 111 
 112         user = auth.authenticate(user_name=user_name, user_email=user_email, user_alias=user_alias)
 113         if user:
 114             logging.getLogger('wiki_auth').debug('user %r is valid, logging in' % (user_name,))
 115             request.user = user
 116             auth.login(request, user)
 117 
 118 class WikiAuthBackend(ModelBackend):
 119     def authenticate(self, user_name=None, user_email=None, user_alias=None):
 120         if not user_name:
 121             return
 122         user = None
 123         user, created = User.objects.get_or_create(username=user_name)
 124         if created:
 125             logging.getLogger('wiki_auth').debug('created user %r' % (user_name,))
 126             user.set_unusable_password()
 127 
 128         if user_email:
 129             user.email = user_email
 130         if user_alias:
 131             # Try to get first/last name from alias. Doesn't work so
 132             # well for someone named "William Henry Mountbatten Windsor",
 133             # but should be good enough.
 134             split_name = user_alias.split()
 135             user.first_name = split_name[0]
 136             user.last_name = ' '.join(split_name[1:])
 137         else:
 138             user.first_name = user_name
 139         user.save()
 140         return user

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2011-10-27 15:31:38, 5.8 KB) [[attachment:wiki_auth.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.