X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=conf%2Fauth%2Fphpbb.py;h=aa38df625a85a30a261183aa04c9b26227737270;hb=8610da3615f7d43ded326d74fc76b28c04d3aae0;hp=3c1f80686a746a0b2d1cea319798a2cfed8b495c;hpb=f4d058f5d7a2f194dba31314ca7b3f327d12d13b;p=matthijs%2Fprojects%2Fwipi.git diff --git a/conf/auth/phpbb.py b/conf/auth/phpbb.py index 3c1f806..aa38df6 100644 --- a/conf/auth/phpbb.py +++ b/conf/auth/phpbb.py @@ -4,6 +4,21 @@ @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 @@ -15,60 +30,118 @@ from MoinMoin import log logging = log.getLogger(__name__) +def connect(dbhost=None, dbport=None, dbname=None, dbuser=None, dbpass=None, **kwargs): + # This code was shamelessly stolen from + # django.db.backends.mysql.base.cursor + kwargs = { + 'charset': 'utf8', + 'use_unicode': False, + } + if dbuser: + kwargs['user'] = dbuser + if dbname: + kwargs['db'] = dbname + if dbpass: + kwargs['passwd'] = dbpass + if dbhost.startswith('/'): + kwargs['unix_socket'] = dbhost + elif dbhost: + kwargs['host'] = dbhost + if dbport: + kwargs['port'] = int(dbport) + + # End stolen code + + try: + conn = MySQLdb.connect (**kwargs) + except: + import sys + import traceback + info = sys.exc_info() + logging.error("phpbb: authentication failed due to exception connecting to DB, traceback follows...") + logging.error(''.join(traceback.format_exception(*info))) + return False + + return conn + + class PhpbbGroupsBackend(LazyGroupsBackend): class PhpbbGroup(LazyGroup): + """ + A group from phpbb. + """ pass - - def __init__(self, request, auth): + def __init__(self, request, **kwargs): super(LazyGroupsBackend, self).__init__(request) - self.auth = auth self.request = request + self.dbconfig = kwargs def __iter__(self): + """ + Return a list of group names. + """ return self.list_query("SELECT group_name \ FROM `%sgroups` \ WHERE group_single_user = 0" - % self.auth.phpbb_prefix) + % self.dbconfig['phpbb_prefix']) def __contains__(self, group_name): + """ + Does a group with the given name exist? + """ return self.single_query("SELECT EXISTS ( \ SELECT * \ FROM `%sgroups` \ WHERE group_single_user = 0 \ - AND group_name=%%s)" % self.auth.phpbb_prefix, + AND group_name=%%s)" % self.dbconfig['phpbb_prefix'], group_name) def __getitem__(self, group_name): + """ + Get the group with the given name. + """ return self.PhpbbGroup(self.request, group_name, self) def _iter_group_members(self, group_name): + """ + Get all member names for the given group. This is called by + LazyGroup.__iter__. + """ 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" - % (self.auth.phpbb_prefix, self.auth.phpbb_prefix, self.auth.phpbb_prefix), + % (self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix']), group_name) def _group_has_member(self, group_name, member): + """ + Does the group with the given name have a member with the given name? + This is called by LazyGroup.__contains__. + """ return self.single_query ("SELECT EXISTS( \ 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 g.group_name = %%s AND u.username = %%s)" - % (self.auth.phpbb_prefix, self.auth.phpbb_prefix, self.auth.phpbb_prefix), + % (self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix']), (group_name, member)) def groups_with_member(self, member): + """ + Return the group names for all groups that have a member with the + given name. + """ 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" - % (self.auth.phpbb_prefix, self.auth.phpbb_prefix, self.auth.phpbb_prefix), + % (self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix'], self.dbconfig['phpbb_prefix']), member) def single_query(self, *args): @@ -79,7 +152,7 @@ class PhpbbGroupsBackend(LazyGroupsBackend): conn = None cursor = None try: - conn = self.auth.connect(self.request) + conn = connect(**self.dbconfig) cursor = conn.cursor() cursor.execute(*args) @@ -98,7 +171,7 @@ class PhpbbGroupsBackend(LazyGroupsBackend): conn = None cursor = None try: - conn = self.auth.connect(self.request) + conn = connect(**self.dbconfig) cursor = conn.cursor() cursor.execute(*args) @@ -114,7 +187,7 @@ class PhpbbAuth(BaseAuth): logout_possible = True login_inputs = ['username', 'password'] - def __init__(self, name='phpbb', dbhost=None, dbuser=None, dbpass=None, dbname=None, dbport=None, phpbb_prefix='', hint=None): + def __init__(self, name='phpbb', hint=None, **kwargs): """ Authenticate using credentials from a phpbb database @@ -122,24 +195,15 @@ class PhpbbAuth(BaseAuth): The hint parameter is a snippet of HTML that is displayed below the login form. """ - self.dbhost = dbhost - self.dbuser = dbuser - self.dbpass = dbpass - self.dbname = dbname - self.dbport = dbport - self.phpbb_prefix = phpbb_prefix + self.dbconfig = kwargs self.name = name self.hint = hint - # Create a "constructor" to create a phpbb_groups instance, while - # passing ourselves to it. - self.groups_backend = lambda config, request: PhpbbGroupsBackend(request, self) - def check_login(self, request, username, password): """ Checks the given username password combination. Returns the corresponding emailaddress, or False if authentication failed. """ - conn = self.connect(request) + conn = connect(**self.dbconfig) if not conn: return False @@ -150,7 +214,7 @@ class PhpbbAuth(BaseAuth): # through the phpbb_prefix variable, but that should be a trusted # value anyway. cursor = conn.cursor () - cursor.execute ("SELECT user_password,user_email FROM `%susers` WHERE username=%%s" % self.phpbb_prefix, username) + cursor.execute ("SELECT user_password,user_email FROM `%susers` WHERE username=%%s" % self.dbconfig['phpbb_prefix'], username) # No data? No login. if (cursor.rowcount == 0): @@ -166,41 +230,10 @@ class PhpbbAuth(BaseAuth): else: return False - def connect(self, request): - # This code was shamelessly stolen from - # django.db.backends.mysql.base.cursor - kwargs = { - 'charset': 'utf8', - 'use_unicode': False, - } - if self.dbuser: - kwargs['user'] = self.dbuser - if self.dbname: - kwargs['db'] = self.dbname - if self.dbpass: - kwargs['passwd'] = self.dbpass - if self.dbhost.startswith('/'): - kwargs['unix_socket'] = self.dbhost - elif self.dbhost: - kwargs['host'] = self.dbhost - if self.dbport: - kwargs['port'] = int(self.dbport) - - # End stolen code - - try: - conn = MySQLdb.connect (**kwargs) - except: - import sys - import traceback - info = sys.exc_info() - logging.error("phpbb_login: authentication failed due to exception connecting to DB, traceback follows...") - logging.error(''.join(traceback.format_exception(*info))) - return False - - return conn - def login(self, request, user_obj, **kw): + """ + Handle a login. Called by moinmoin. + """ try: username = kw.get('username') password = kw.get('password') @@ -243,4 +276,41 @@ class PhpbbAuth(BaseAuth): """ Return a snippet of HTML that is displayed with the login form. """ return self.hint +def setup(**kwargs): + """ + Setup the phpbb backend. Takes the following keyword arguments: + dbhost -- The database server host + dbport -- The database server portname + dbname -- The database name + dbuser -- The username to log in + dbpass -- The password to log in + phpbb_prefix -- The table name prefix used for this phpbb installation + name -- The name to use for the auth backend + hint -- A hint to show in the login interface (HTML string) + + This function can be called multiple times to create backends for + different phpbb installations + + Returns a tuple (auth, groups) containing an (instantiated) auth backend + and a groups backend (constructor). These can be put directly into the + "auth" (as part of the list) and "groups" (directly) config directives. + + e.g., + + class FarmConfig: + (phpbb_auth, phpbb_groups) = phpbb.setup(...) + auth = [phpbb_auth] + groups = phpbb_groups + + (actual configuration parameters to setup() are omitted in this example) + """ + + # Create a "constructor" to create a phpbb_groups instance, while + # passing ourselves to it. + groups = lambda config, request: PhpbbGroupsBackend(request, **kwargs) + # Create an instantiated auth backend. + auth = PhpbbAuth(**kwargs) + + return (auth, groups) + # vim: set sw=4 expandtab sts=4:vim