auth: Rename the phpbb_login class to PhpbbAuth.
[matthijs/projects/wipi.git] / conf / auth / phpbb_login.py
index 0e93517fcec53092fdf227e50a051aec61412b35..3c1f80686a746a0b2d1cea319798a2cfed8b495c 100644 (file)
@@ -10,14 +10,111 @@ import MySQLdb
 import md5
 from MoinMoin import user
 from MoinMoin.auth import BaseAuth, ContinueLogin
+from MoinMoin.datastruct.backends import LazyGroupsBackend, LazyGroup
 from MoinMoin import log
 logging = log.getLogger(__name__)
 
-class phpbb_login(BaseAuth):
+
+class PhpbbGroupsBackend(LazyGroupsBackend):
+    class PhpbbGroup(LazyGroup):
+        pass
+
+
+    def __init__(self, request, auth):
+        super(LazyGroupsBackend, self).__init__(request)
+
+        self.auth = auth
+        self.request = request
+
+    def __iter__(self):
+        return self.list_query("SELECT group_name \
+                                FROM `%sgroups` \
+                                WHERE group_single_user = 0"
+                                % self.auth.phpbb_prefix)
+
+    def __contains__(self, group_name):
+        return self.single_query("SELECT EXISTS ( \
+                                      SELECT * \
+                                      FROM `%sgroups` \
+                                      WHERE group_single_user = 0 \
+                                            AND group_name=%%s)" % self.auth.phpbb_prefix,
+                                 group_name)
+
+    def __getitem__(self, group_name):
+        return self.PhpbbGroup(self.request, group_name, self)
+
+    def _iter_group_members(self, group_name):
+        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),
+                                group_name)
+
+    def _group_has_member(self, group_name, member):
+        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),
+                                  (group_name, member))
+        
+    def groups_with_member(self, member):
+        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),
+                                member)
+
+    def single_query(self, *args):
+        """
+        Runs an SQL query, that returns single row with a single column.
+        Returns just that single result.
+        """
+        conn = None
+        cursor = None
+        try:
+            conn = self.auth.connect(self.request)
+            cursor = conn.cursor()
+            cursor.execute(*args)
+
+            return cursor.fetchone()[0]
+        finally:
+            if cursor:
+                cursor.close()
+            if conn:
+                conn.close()
+        
+    def list_query(self, *args):
+        """
+        Runs an SQL query, that returns any number of single-column rows.
+        Returns the results as a list of single values
+        """
+        conn = None
+        cursor = None
+        try:
+            conn = self.auth.connect(self.request)
+            cursor = conn.cursor()
+            cursor.execute(*args)
+
+            for row in cursor:
+                yield row[0]
+        finally:
+            if cursor:
+                cursor.close()
+            if conn:
+                conn.close()
+        
+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, hint=None):
+    def __init__(self, name='phpbb', dbhost=None, dbuser=None, dbpass=None, dbname=None, dbport=None, phpbb_prefix='', hint=None):
         """
             Authenticate using credentials from a phpbb database
 
@@ -30,8 +127,13 @@ class phpbb_login(BaseAuth):
         self.dbpass  = dbpass
         self.dbname  = dbname
         self.dbport  = dbport
+        self.phpbb_prefix = phpbb_prefix
         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
@@ -42,9 +144,13 @@ class phpbb_login(BaseAuth):
         if not conn:
             return False
 
-        # Get some data
+        # 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.
         cursor = conn.cursor ()
-        cursor.execute ("SELECT user_password,user_email FROM lex_users WHERE username=%s", username)
+        cursor.execute ("SELECT user_password,user_email FROM `%susers` WHERE username=%%s" % self.phpbb_prefix, username)
 
         # No data? No login.
         if (cursor.rowcount == 0):