--- MoinMoin/wikiacl.py.orig    2005-02-09 18:10:35.260641900 +0100
+++ MoinMoin/wikiacl.py 2005-02-11 12:11:47.128222400 +0100
@@ -255,7 +255,7 @@
             # process data
     """

-    def __init__(self, rights, aclstring):
+    def __init__(self, rights, aclstring, arguments_allowed = False):
         """ Initialize acl iterator

         @param rights: the acl rights to consider when parsing
@@ -264,11 +264,41 @@
         self.rights = rights
         self.rest = aclstring.strip()
         self.finished = 0
+        self.arguments_allowed = arguments_allowed

     def __iter__(self):
         """ Required by the Iterator protocol """
         return self

+    def splitoff(self, data, separatorchars, must_encounter = True):
+        quoted = False
+        quotepositions = []
+        escape = -1
+        encountered = False
+        result = ''
+        l = len(data)
+        pos = 0
+        sep = None
+        while pos < l:
+            if not quoted and data[pos] in separatorchars:
+                encountered = True
+                sep = data[pos]
+                break
+            elif quoted and data[pos] == '\\':
+                escape = pos+1
+                quotepositions  = [pos] + quotepositions
+            elif escape < pos and (data[pos] == '"'):
+                quoted = not quoted
+                quotepositions = [pos] + quotepositions
+            pos += 1
+        if not encountered and must_encounter:
+            self.finished = 1
+            raise StopIteration("Can't parse rest of string")
+        s = data[0:pos]
+        for i in quotepositions:
+            s = s[0:i] + s[i+1:]
+        return s, data[pos+1:], sep
+
     def next(self):
         """ Return the next values from the acl string

@@ -293,34 +323,52 @@
         # Handle the Default meta acl
         if self.rest.startswith('Default ') or self.rest == 'Default':
             self.rest = self.rest[8:]
-            entries, rights = ['Default'], []
+            users, rights = ['Default'], []

-        # Handle entries:rights pairs
+        # Handle users:rights pairs
         else:
-            # Get entries
-            try:
-                # XXX TODO disallow : and , in usernames
-                entries, self.rest = self.rest.split(':', 1)
-            except ValueError:
-                self.finished = 1
-                raise StopIteration("Can't parse rest of string")
-            if entries == '':
-                entries = []
-            else:
-                # TODO strip each entry from blanks?
-                entries = entries.split(',')
-
-            # Get rights
-            try:
-                rights, self.rest = self.rest.split(' ', 1)
-                # Remove extra white space after rights fragment,
-                # allowing using multiple spaces between items.
-                self.rest = self.rest.lstrip()
-            except ValueError:
-                rights, self.rest = self.rest, ''
-            rights = [r for r in rights.split(',') if r in self.rights]
+            # split off leading spaces
+            self.rest = self.rest.lstrip()
+            # Get specified usernames
+            users  = []
+            sep = None
+            while sep != ':':
+                user, self.rest, sep = self.splitoff(self.rest, ',:')
+                user = user.strip() # TODO: check if this is really good
+                if user != '': users  += [user]
+
+            # Get specified rights
+            in_arguments = False
+            args = None
+            sep = None
+            right = None
+            args = ()
+            rights = []
+            while sep != ' ':
+                if in_arguments:
+                    word, self.rest, sep = self.splitoff(self.rest, ',)')
+                else:
+                    word, self.rest, sep = self.splitoff(self.rest, ', (', must_encounter = False)
+                if sep is None: sep = ' '
+                if sep == ')':
+                    if right is None: raise StopIteration("Can't parse rest of string")
+                    if right in self.rights:
+                        if self.arguments_allowed:
+                            args = args + (word,)
+                            rights = rights + [(right,)+args]
+                        right = None
+                        args = ()
+                    in_arguments = False
+                if (sep == ',' and not in_arguments) or sep == ' ':
+                    if word in self.rights:
+                        rights = rights + [word.strip()]
+                if sep == ',' and in_arguments:
+                    args = args + (word,)
+                if sep == '(':
+                    right = word.strip()
+                    in_arguments = True

-        return modifier, entries, rights
+        return modifier, users, rights


 def parseACL(request, body):

MoinMoin: JohannesBerg/PluggableACLs/wikiacl.patch (last edited 2007-10-29 19:20:31 by localhost)