X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=conf%2Fauth%2Fphpbb.py;h=54763b3558731a9db66e165c7583a145a973ea2c;hb=6143b643c63de8726c8858466aafe6b0b56546bf;hp=0558d53aa443791d876a6eff4b84f43ce53c2d56;hpb=ec774f80e9cbc1efdc32e2bbc7d7c50978e5fe70;p=matthijs%2Fprojects%2Fwipi.git diff --git a/conf/auth/phpbb.py b/conf/auth/phpbb.py index 0558d53..54763b3 100644 --- a/conf/auth/phpbb.py +++ b/conf/auth/phpbb.py @@ -4,10 +4,26 @@ @copyright: 2008 Matthijs Kooijman @license: GNU GPL, see COPYING for details. + + This plugin allows authentication (use accounts and password) and + authorization (use groups) against a phpbb Mysql database. + + To use this plugin, you should put it in a place where the config python + file can "see" it (somewhere in your pythonpath, or in the same dir as the + config file). Then import the setup function and call it. + + For example: + + class FarmConfig: + import phpbb + (phpbb_auth, phpbb_groups) = phpbb.setup(...) + auth = [phpbb_auth] + groups = phpbb_groups """ import MySQLdb -import md5 +# Password encryption module. Python port of the method used by phpbb3. +import phpass from MoinMoin import user from MoinMoin.auth import BaseAuth, ContinueLogin from MoinMoin.datastruct.backends import LazyGroupsBackend, LazyGroup @@ -68,8 +84,7 @@ class PhpbbGroupsBackend(LazyGroupsBackend): Return a list of group names. """ return self.list_query("SELECT group_name \ - FROM `%sgroups` \ - WHERE group_single_user = 0" + FROM `%sgroups`" % self.dbconfig['phpbb_prefix']) def __contains__(self, group_name): @@ -79,8 +94,7 @@ class PhpbbGroupsBackend(LazyGroupsBackend): return self.single_query("SELECT EXISTS ( \ SELECT * \ FROM `%sgroups` \ - WHERE group_single_user = 0 \ - AND group_name=%%s)" % self.dbconfig['phpbb_prefix'], + WHERE group_name=%%s)" % self.dbconfig['phpbb_prefix'], group_name) def __getitem__(self, group_name): @@ -97,8 +111,7 @@ class PhpbbGroupsBackend(LazyGroupsBackend): return self.list_query ("SELECT username \ FROM `%susers` as u, `%suser_group` as ug, `%sgroups` as g \ WHERE u.user_id = ug.user_id AND ug.group_id = g.group_id \ - AND ug.user_pending = 0 AND g.group_single_user = 0 \ - AND g.group_name = %%s" + AND ug.user_pending = 0 AND g.group_name = %%s" % (self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix']), group_name) @@ -111,7 +124,7 @@ class PhpbbGroupsBackend(LazyGroupsBackend): SELECT * \ FROM `%susers` as u, `%suser_group` as ug, `%sgroups` as g \ WHERE u.user_id = ug.user_id AND ug.group_id = g.group_id \ - AND ug.user_pending = 0 AND g.group_single_user = 0 \ + AND ug.user_pending = 0 \ AND g.group_name = %%s AND u.username = %%s)" % (self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix']), (group_name, member)) @@ -124,8 +137,7 @@ class PhpbbGroupsBackend(LazyGroupsBackend): return self.list_query ("SELECT g.group_name \ FROM `%susers` as u, `%suser_group` as ug, `%sgroups` as g \ WHERE u.user_id = ug.user_id AND ug.group_id = g.group_id \ - AND ug.user_pending = 0 AND g.group_single_user = 0 \ - AND u.username = %%s" + AND ug.user_pending = 0 AND u.username = %%s" % (self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix']), member) @@ -183,37 +195,44 @@ class PhpbbAuth(BaseAuth): self.dbconfig = kwargs self.name = name self.hint = hint + self.hash = phpass.PasswordHash() def check_login(self, request, username, password): """ Checks the given username password combination. Returns the - corresponding emailaddress, or False if authentication failed. + real username and corresponding emailaddress, or (False, False) + if authentication failed. Username checks are case insensitive, + so the real username (with the real casing) is returned (since + ACL checks _are_ case sensitive). """ conn = connect(**self.dbconfig) if not conn: - return False + return (False, False) # Get some data. Note that we interpolate the prefix ourselves, since # letting the mysql library do it only works with values (it adds '' # automatically). Note also that this allows possible SQL injection # through the phpbb_prefix variable, but that should be a trusted # value anyway. + # Finally note that by default, the phpbb database specifies a + # case insensitive collaction for the username field, so + # usernames are checked in case insensitive manner. cursor = conn.cursor () - cursor.execute ("SELECT user_password,user_email FROM `%susers` WHERE username=%%s" % self.dbconfig['phpbb_prefix'], username) + cursor.execute ("SELECT user_password,user_email,username FROM `%susers` WHERE LOWER(username)=LOWER(%%s)" % self.dbconfig['phpbb_prefix'], username) # No data? No login. if (cursor.rowcount == 0): conn.close() - return False + return (False, False) # Check password row = cursor.fetchone() conn.close() - if (md5.new(password).hexdigest() == row[0]): - return row[1] + if self.hash.check_password(password, row[0]): + return (row[1], row[2]) else: - return False + return (False, False) def login(self, request, user_obj, **kw): """ @@ -234,16 +253,19 @@ class PhpbbAuth(BaseAuth): if not username or not password: return ContinueLogin(user_obj) - email = self.check_login(request, username, password) + (email, real_username) = self.check_login(request, username, password) # Login incorrect if (not email): logging.debug("phpbb_login: authentication failed for %s" % (username)) return ContinueLogin(user_obj) - logging.debug("phpbb_login: authenticated %s (email %s)" % (username, email)) + logging.debug("phpbb_login: authenticated %s (email %s, real username %s)" % (username, email, real_username)) - u = user.User(request, auth_username=username, auth_method=self.name, auth_attribs=('name', 'password', 'email')) + # We use the username from the database (real_username) + # here, since the username from the request might have + # "wrong" casing (and ACL checks are case sensitive). + u = user.User(request, auth_username=real_username, auth_method=self.name, auth_attribs=('name', 'password', 'email')) u.email = email #u.remember_me = 0 # 0 enforces cookie_lifetime config param u.create_or_update(True)