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
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
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
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()