1 import MySQLdb as db
   2 import md5
   3 
   4 from MoinMoin.auth import BaseAuth
   5 from MoinMoin import log, user
   6 logging = log.getLogger(__name__)
   7 
   8 
   9 class JoomlaAuth(BaseAuth):
  10     name = 'joomla!'
  11     def __init__(self, mysql_user, mysql_pass, database, table_prefix,
  12                  session_lifetime, hash_secret, trusted_aro_group,
  13                  live_site=None):
  14         BaseAuth.__init__(self)
  15         self._session_lifetime = session_lifetime
  16         self._hash_secret = hash_secret
  17         self._live_site = live_site
  18         self._table_prefix = table_prefix
  19         self._trusted_aro_group = trusted_aro_group
  20         
  21         conn = db.connect(user=mysql_user, passwd=mysql_pass, db=database)
  22         self._cursor = conn.cursor()
  23 
  24     def logout(self, request, user_obj, **kw):
  25         return user_obj, True
  26 
  27     def request(self, request, user_obj, **kw):
  28         cname = self._get_cookie_name(request)
  29         cookie = kw.get('cookie', None)
  30         if not cookie or not cname in cookie:
  31             # no cookie, no login!
  32             return None, True
  33 
  34         cval = cookie[cname].value
  35         hash = md5.md5()
  36         hash.update(cval)
  37         hash.update(request.remote_addr)
  38         hash.update(request.http_user_agent)
  39 
  40         session_hash = md5.md5()
  41         session_hash.update(self._hash_secret)
  42         session_hash.update(hash.hexdigest())
  43                                                 
  44         session_id = session_hash.hexdigest()
  45 
  46         # now see if it's valid
  47         data = self._load_session_data(session_id)
  48         if not data:
  49             return None, True
  50 
  51         username, guest, uid, usertype, gid = data
  52         data = self._get_and_check_user_data(uid)
  53         if data is None:
  54             return None, True
  55         trusted, email, fullname = data
  56         authname = 'joomla_untrusted'
  57         if trusted:
  58             authname = 'joomla_trusted'
  59         uobj = user.User(request, id=str(uid), name=username, auth_method=authname,
  60                          auth_attribs=('name', 'email', 'aliasname'))
  61         if not uobj.exists() or uobj.email != email or uobj.aliasname != fullname:
  62             uobj.email = email
  63             uobj.aliasname = fullname
  64             uobj.save()
  65         uobj.valid = True
  66         return uobj, True
  67 
  68     def _get_cookie_name(self, request):
  69         if not self._live_site:
  70             server_name = request.http_host
  71         else:
  72             server_name = self._live_site
  73 
  74         return md5.md5("site" + server_name).hexdigest()
  75 
  76     def _load_session_data(self, session_id):
  77         table = self._table_prefix + 'session'
  78         sql = "SELECT username, guest, userid, usertype, gid FROM %s WHERE session_id=%%s AND time >= (UNIX_TIMESTAMP()-%i);" % (
  79                   table, self._session_lifetime)
  80         self._cursor.execute(sql, (session_id, ))
  81         if self._cursor.rowcount == 0:
  82             return None
  83         row = self._cursor.fetchone()
  84         # yay, at least a valid session, let's update the timestamp
  85         sql = "UPDATE %s SET time=UNIX_TIMESTAMP() WHERE session_id=%%s" % table
  86         self._cursor.execute(sql, (session_id, ))
  87         return row
  88 
  89     def _get_and_check_user_data(self, uid):
  90         res = self._get_user_data(uid)
  91 
  92         if not res:
  93             return None
  94 
  95         gid, email, fullname = res
  96 
  97         groups = self._get_child_groups(name=self._trusted_aro_group)
  98         trusted = groups.has_key(gid)
  99 
 100         return trusted, email, fullname
 101 
 102     def _get_child_groups(self, gid=None, name=None):
 103         cursor = self._cursor
 104         
 105         table = self._table_prefix + "core_acl_aro_groups"
 106         sql = """
 107               SELECT child.group_id, child.name FROM %(table)s
 108               parent LEFT JOIN %(table)s child ON parent.lft <= child.lft AND parent.rgt >= child.rgt
 109               """ % { 'table': table}
 110         if gid is None:
 111             assert name is not None
 112             sql += "WHERE parent.name = %s"
 113             param = name
 114         else:
 115             sql += "WHERE parent.group_id = %s"
 116             param = gid
 117         cursor.execute(sql, (param, ))
 118 
 119         result = {}
 120         for row in cursor.fetchall():
 121             result[row[0]] = row[1]
 122         return result
 123 
 124     def _get_user_data(self, uid):
 125         cursor = self._cursor
 126         
 127         user_table = self._table_prefix + 'users'
 128         sql = "SELECT gid, email, name FROM %s WHERE id=%%s" % user_table
 129 
 130         cursor.execute(sql, (uid, ))
 131 
 132         if cursor.rowcount == 0:
 133             return None
 134 
 135         return cursor.fetchone()

MoinMoin: JoomlaIntegration/auth (last edited 2008-06-28 13:08:53 by JohannesBerg)