Attachment 'hierachical-acl-666.diff'

Download

   1 diff -Naur old/MoinMoin/multiconfig.py new/MoinMoin/multiconfig.py
   2 --- old/MoinMoin/multiconfig.py	2005-06-12 13:43:48.613091432 +0200
   3 +++ new/MoinMoin/multiconfig.py	2005-06-12 13:36:54.337070960 +0200
   4 @@ -151,6 +151,7 @@
   5      FIXME: update according to MoinMoin:UpdateConfiguration
   6      """    
   7      acl_enabled = 0
   8 +    acl_hierarchic = 0
   9      # All acl_right lines must use unicode!
  10      acl_rights_default = u"Trusted:read,write,delete,revert Known:read,write,delete,revert All:read,write"
  11      acl_rights_before = u""
  12 @@ -324,6 +325,13 @@
  13          # e.g u'%(page_front_page)s' % self
  14          self.navi_bar = [elem % self for elem in self.navi_bar]
  15  
  16 +        # precompile acl strings
  17 +        if self.acl_enabled:
  18 +            from wikiacl import AccessControlList
  19 +            self.acl_default = AccessControlList(None, [self.acl_rights_default], cfg=self)
  20 +            self.acl_before = AccessControlList(None, [self.acl_rights_before], cfg=self)
  21 +            self.acl_after = AccessControlList(None, [self.acl_rights_after], cfg=self)
  22 +
  23      def _config_check(self):
  24          """ Check namespace and warn about unknown names
  25          
  26 diff -Naur old/MoinMoin/PageEditor.py new/MoinMoin/PageEditor.py
  27 --- old/MoinMoin/PageEditor.py	2005-06-12 13:43:48.609092040 +0200
  28 +++ new/MoinMoin/PageEditor.py	2005-06-12 13:37:11.216504896 +0200
  29 @@ -916,7 +916,7 @@
  30              # of wating for next request.
  31              acl = self.getACL(self.request)
  32              if (not self.request.user.may.admin(self.page_name) and
  33 -                parseACL(self.request, newtext) != acl and
  34 +                parseACL(self.request, newtext).acl != acl.acl and
  35                  action != "SAVE/REVERT"):
  36                  msg = _("You can't change ACLs on this page since you have no admin rights on it!")
  37                  raise self.NoAdmin, msg
  38 diff -Naur old/MoinMoin/security.py new/MoinMoin/security.py
  39 --- old/MoinMoin/security.py	2005-06-12 13:43:48.616090976 +0200
  40 +++ new/MoinMoin/security.py	2005-06-12 13:37:18.395413536 +0200
  41 @@ -22,8 +22,21 @@
  42  class Permissions:
  43      """ Basic interface for user permissions and system policy.
  44  
  45 -        Note that you still need to allow some of the related actions, this
  46 -        just controls their behaviour, not their activation.
  47 +    Note that you still need to allow some of the related actions, this
  48 +    just controls their behavior, not their activation.
  49 +
  50 +    When sub classing this class, you must extend the class methods, not
  51 +    replace them, or you might break the acl in the wiki. Correct sub
  52 +    classing look like this:
  53 +
  54 +    def read(self, pagename):
  55 +        # Your special security rule
  56 +        if somehting:
  57 +            return false
  58 +
  59 +        # Do not return True or you break acl!
  60 +        # This call will use the default acl rules
  61 +        return Permissions.read(pagename)
  62      """
  63  
  64      def __init__(self, user):
  65 @@ -32,27 +45,105 @@
  66          from MoinMoin.Page import Page
  67          self.Page = Page
  68          self.name = user.name
  69 +        self.user = user
  70          self.request = user._request
  71  
  72      def save(self, editor, newtext, rev, **kw):
  73          """ Check whether user may save a page.
  74  
  75 -            `editor` is the PageEditor instance, the other arguments are
  76 -            those of the `PageEditor.saveText` method.
  77 +        Default implementation ignore newtext, rev and kw, and just try
  78 +        to get permission for write.
  79 +
  80 +        @param editor: PageEditor instance.
  81 +        @param newtext: new page text, you can enable of disable saving according
  82 +            to the content of the text, e.g. prevent link spam.
  83 +        @param rev: new revision number? XXX
  84 +        @param kw: XXX
  85 +        @rtype: bool
  86 +        @return: True if you can save or False
  87          """
  88          return self.write(editor.page_name)
  89  
  90      def __getattr__(self, attr):
  91 -        """ if attr is one of the rights in acl_rights_valid, then return a
  92 -            checking function for it. Else raise an error.
  93 +        """ Shortcut to export getPermission function for all known acl rights
  94 +        
  95 +        if attr is one of the rights in acl_rights_valid, then return a
  96 +        checking function for it. Else use normal getattr().
  97 +
  98 +        @param attr: one of acl known rights as defined in acl_rights_valid
  99 +        @rtype: function
 100 +        @return: checking function for that right, accepting a pagename
 101          """
 102 -        request = self.request
 103 -        Page = self.Page
 104 -        if attr in request.cfg.acl_rights_valid:
 105 -            return lambda pagename, Page=Page, request=request, attr=attr: Page(request, pagename).getACL(request).may(request, self.name, attr)
 106 +        if attr in self.request.cfg.acl_rights_valid:
 107 +            self._right = attr
 108 +            return self._getPermission
 109          else:
 110              raise AttributeError, attr
 111          
 112 +    def _getPermission(self, pagename):
 113 +        """ Get permission by transversing page hierarchy
 114 + 
 115 +        If cfg.acl_hierarchic, we check each page in the hierarchy. If all
 116 +        pages agree, we have permission. If one page in the hierarchy
 117 +        does not agree, we don't. Otherwise, only pagename is checked.
 118 +
 119 +        This method should not be called by users, use __getattr__
 120 +        instead. If you want to get permission for delete, try:
 121 +        instance.delete(pagename).
 122 +
 123 +        @param pagename: pagename to get permission from
 124 +        @rtype: bool
 125 +        @return: True if you have permission or False
 126 +        """
 127 +        from MoinMoin.Page import Page
 128 +
 129 +        # Use page hierarchy or only pagename, according to wiki config.
 130 +        if self.request.cfg.acl_hierarchic:
 131 +            pages = pagename.split('/')
 132 +            #open('/tmp/acl.log','a').write('acl_hierarchic enabled\n')
 133 +        else:
 134 +            #open('/tmp/acl.log','a').write('acl_hierarchic disabled\n')
 135 +            pages = [pagename]
 136 +
 137 +        # disable logging seems not bugfree
 138 +        #open('/tmp/acl.log','a').write('may(%s): pages %s\n'%(self._right, pages,))
 139 +        # check before
 140 +        allowed = self.request.cfg.acl_before.may(self.request, self.user.name, self._right)
 141 +        if allowed is not None:
 142 +            #open('/tmp/acl.log','a').write('may: before returns %s\n'%(allowed,))
 143 +            return allowed
 144 +        
 145 +        # Get permission
 146 +        some_acl = False
 147 +        for i in range(len(pages), 0, -1):
 148 +            # Create the next pagename in the hierarchy
 149 +            # starting with the leave, going to the root
 150 +            name = '/'.join(pages[:i])
 151 +            # Get page acl and ask for permission
 152 +            acl = Page(self.request, name).getACL(self.request)
 153 +            #open('/tmp/acl.log','a').write('may: checking acl of %s (%s)\n'%(name, `acl.acl`))
 154 +            if acl.acl:
 155 +                some_acl = True
 156 +                allowed = acl.may(self.request, self.user.name, self._right)
 157 +                if allowed is not None:
 158 +                    #open('/tmp/acl.log','a').write('may: acl of %s (%s) returns %s\n'%(name, `acl.acl`, allowed,))
 159 +                    return allowed
 160 +        if not some_acl:
 161 +            allowed = self.request.cfg.acl_default.may(self.request, self.user.name, self._right)
 162 +            if allowed is not None:
 163 +                #open('/tmp/acl.log','a').write('may: default returns %s\n'%(allowed,))
 164 +                return allowed
 165 +
 166 +        # check after
 167 +        allowed = self.request.cfg.acl_after.may(self.request, self.user.name, self._right)
 168 +        if allowed is not None:
 169 +            #open('/tmp/acl.log','a').write('may: after returns %s\n'%(allowed,))
 170 +            return allowed
 171 +
 172 +        # sane default permission, if you want True,
 173 +        # just put 'All:read' (or more) into your acl_rights_after
 174 +        return False
 175 +
 176  
 177  # make an alias for the default policy
 178  Default = Permissions
 179 diff -Naur old/MoinMoin/wikiacl.py new/MoinMoin/wikiacl.py
 180 --- old/MoinMoin/wikiacl.py	2005-06-12 13:43:48.620090368 +0200
 181 +++ new/MoinMoin/wikiacl.py	2005-06-12 13:37:29.537719648 +0200
 182 @@ -113,33 +113,24 @@
 183  
 184      special_users = ["All", "Known", "Trusted"]
 185  
 186 -    def __init__(self, request, lines=[]):
 187 +    def __init__(self, request, lines=[], cfg=None):
 188          """Initialize an ACL, starting from <nothing>.
 189          """
 190 -        self.setLines(request.cfg, lines)
 191 +        if cfg is not None:
 192 +            self.setLines(cfg, lines)
 193 +        else:
 194 +            self.setLines(request.cfg, lines)
 195  
 196      def setLines(self, cfg, lines=[]):
 197          self.clean()
 198 -        self.addBefore(cfg)
 199 -        if not lines:
 200 -            self.addDefault(cfg)
 201 -        else:
 202 -            for line in lines:
 203 -                self.addLine(cfg, line)
 204 -        self.addAfter(cfg)
 205 +        for line in lines:
 206 +            self.addLine(cfg, line)
 207  
 208      def clean(self):
 209          self.acl = [] # [ ('User', {"read": 0, ...}), ... ]
 210          self.acl_lines = []
 211          self._is_group = {}
 212  
 213 -    def addBefore(self, cfg):
 214 -        self.addLine(cfg, cfg.acl_rights_before, remember=0)
 215 -    def addDefault(self, cfg):
 216 -        self.addLine(cfg, cfg.acl_rights_default, remember=0)
 217 -    def addAfter(self, cfg):
 218 -        self.addLine(cfg, cfg.acl_rights_after, remember=0)
 219 -
 220      def addLine(self, cfg, aclstring, remember=1):
 221          """ Add another ACL line
 222  
 223 @@ -182,7 +173,7 @@
 224                          rightsdict[right] = (right in rights)
 225                  self.acl.append((entry, rightsdict))
 226  
 227 -    def may(self, request, name, dowhat):
 228 +    def may(self, request, name, dowhat, recurse=False):
 229          """May <name> <dowhat>?
 230             Returns boolean answer.
 231          """
 232 @@ -210,7 +201,7 @@
 233                  allowed = rightsdict.get(dowhat)
 234              if allowed is not None:
 235                  return allowed
 236 -        return 0
 237 +        return allowed
 238  
 239      def getString(self, b='#acl ', e='\n'):
 240          """print the acl strings we were fed with"""

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2005-06-12 13:12:37, 9.7 KB) [[attachment:hierachical-acl-666.diff]]
  • [get | view] (2005-11-21 12:20:12, 9.0 KB) [[attachment:hierachical-acl-moin--main--1.3-935.diff]]
  • [get | view] (2005-01-19 19:05:25, 9.6 KB) [[attachment:hierachical-acl.diff]]
  • [get | view] (2005-01-18 08:11:27, 2.7 KB) [[attachment:inherit-parent-acl.diff]]
  • [get | view] (2005-01-18 08:57:38, 3.3 KB) [[attachment:split-before-after.diff]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.