Re: Restrict access of users to active issues

Ralf Schlatterbeck <[email protected]>
Newsgroups gmane.comp.bug-tracking.roundup.user
Message-ID <[email protected]>
On Mon, Jan 25, 2016 at 04:20:51PM +0100, Christian Wolf wrote:
> 
> Further I altered the following and removed the issue from the for list:
> 
> 
> for cl in 'file', 'msg', 'keyword':
>     db.security.addPermissionToRole('User', 'View', cl)
>     db.security.addPermissionToRole('User', 'Edit', cl)
>     db.security.addPermissionToRole('User', 'Create', cl)
> 
> 
> This leads to the desired effect, that a normal User does no more have
> access to issues where he is not on the nosy list. Nevertheless there is
> a side effect: When looking at the list of open issues, the grouping and
> sorting does not work. I cannot set any grouping neither using the
> selection boxes below the search result nor with the detailed search web
> interface.
> 
> Maybe someone might know if this has with my altered issues to do.

Two things here:
- Johns "shot in the dark" is ok, you need to add search permissions in
  this case
- you don't restrict access to messages. Since most of the confidential
  info is probably in the messages not in the other info in the issue, a
  user could display

  http://.../msg23

  to see the contents of this message even if (s)he is not on the nosy
  list for the issue.

  You can restrict message (and file) view also with a check method,
  by checking that a user has access to something that links to the
  message. *And* you should restrict linking/unlinking of messages to
  the *creator* of a message to prevent that someone links a message to
  an issue they have access to to see the message.


Code (please forgive the peculiar formatting which is not python pep
conforming, the project I'm copying from uses different coding
guidelines) -- for more of the code see
 http://sourceforge.net/projects/timetracktool/

Note that the following code is very generic -- in the tracker I'm
copying it from we have many classes with messages. So you will probably
have to remove some code and some special cases. We also use more roles
than the standard tracker.


Library, put this in the 'lib' directory in your tracker:

from roundup.hyperdb import Link, Multilink

def linkclass_iter (db, classname) :
    """ For the given classname find all properties in other classes
        that link to that class.
    """
    for clname in sorted (db.getclasses ()) :
        for p, v in sorted (db.getclass (clname).properties.iteritems ()) :
            if  (    (isinstance (v, Multilink) or isinstance (v, Link))
                and v.classname == classname
                ) :
                yield (clname, p)
# end def linkclass_iter


Detectors:

classprops = {}

def check_linking (db, cl, nodeid, new_values) :
    """ Allow linking to properties only if we created them """
    if db.getuid () == '1' :
        return
    for prop in classprops [cl.classname] :
        if prop not in new_values :
            continue
        old   = dict.fromkeys (old_props (cl, prop, nodeid))
        klass = db.getclass (cl.properties [prop].classname)
        for id in new_props (cl, prop, new_values) :
            if id not in old and klass.get (id, 'creator') != db.getuid () :
                cls  = _ (klass.classname)
                raise Reject, \
                    _ ("You may link only to your own %(cls)s") % locals ()
# end def check_linking

def check_unlinking (db, cl, nodeid, new_values) :
    """ Don't allow unlinking of properties """
    for prop in classprops [cl.classname] :
        if prop not in new_values :
            continue
        # allow admin
        if db.getuid () == '1' :
            continue
        ids = dict.fromkeys (new_props (cl, prop, new_values))
        for id in old_props (cl, prop, nodeid) :
            if id not in ids :
                name  = _ (cl.classname)
                kls   = cl.properties [prop]
                klass = db.getclass (kls.classname)
                cls   = _ (kls.classname)
                # Allow updating user pictures
                if cls == 'File' and name == 'User' :
                    continue
                # Allow Link properties if old linked prop is owned by user
                if  (   isinstance (kls, Link)
                    and klass.get (id, 'creator') == db.getuid ()
                    ) :
                    continue
                # Allow Multilink properties in exceptions if linked
                # prop is owned by user
                if  (   prop in exceptions.get (cl.classname, [])
                    and klass.get (id, 'creator') == db.getuid ()
                    ) :
                    continue
                # Allow IT and admin roles
                if common.user_has_role (db, db.getuid (), 'it', 'admin') :
                    continue
                raise Reject, \
                    _ ("You may not unlink %(cls)s from %(name)s") % locals ()
# end def check_unlinking



def init (db) :
    # certain checks of linking/unlinking of files and messages
    for x in 'msg', 'file' :
        for cl, prop in linkclass_iter (db, x) :
            if cl not in classprops :
                classprops [cl] = [prop]
                klass = db.getclass (cl)
                klass.audit ("create", check_linking)
                klass.audit ("create", check_unlinking)
                klass.audit ("set",    check_linking)
                klass.audit ("set",    check_unlinking)
            else :
                classprops [cl].append (prop)
# end def init


Access methods:

def register_permission_by_link (db, role, perm, linkclass, * classprops) :
    """ Install permission check methods for a given linkclass (e.g.
        msg, file) linked by other classes (e.g. issue) from a
        Multilink. The parameter classprops is a list of 2-tuple of
        classname and property name.
    """
    if linkclass not in db.classes :
        return
    classprops = [(c, p) for c, p in classprops
                  if c in db.classes and p in db.classes [c].getprops ()
                 ]
    def is_linked (db, uid, itemid) :
        if not itemid :
            return False
        for cls, prop in classprops :
            if cls not in db.classes :
                continue
            ids = db.getclass (cls).filter (None, {prop : itemid})
            for id in ids :
                if db.security.hasPermission \
                    (perm, uid, cls, itemid = id, property = prop) :
                    return True
        return False
    # end def is_linked
    p = db.security.addPermission \
        ( name        = perm
        , klass       = linkclass
        , check       = is_linked
        , description = \
            ''"User is allowed %(perm)s on %(linkclass)s"
            " if %(linkclass)s is linked from an item with %(perm)s"
            " permission" % locals ()
        )
    db.security.addPermissionToRole (role, p)
# end def register_permission_by_link

def register_linkperms (db, linkperms) :
    for cls, roles, perms, classprops in linkperms :
        for role in roles :
            if role.lower () not in db.security.role :
                continue
            for perm in perms :
                schemadef.register_permission_by_link \
                    (db, role, perm, cls, * classprops)
# end def register_linkperms

    linkperms = \
        [ ("file", ['User'],      ['View', 'Edit'], linkclass_iter (db, "file"))
        , ("msg",  ['User'],              ['View'], linkclass_iter (db, "msg"))
        , ("msg",  ['Issue_Admin', 'IT'], ['Edit'], linkclass_iter (db, "msg"))
        ]

    register_linkperms (db, linkperms)


Ralf
-- 
Dr. Ralf Schlatterbeck                  Tel:   +43/2243/26465-16
Open Source Consulting                  www:   http://www.runtux.com
Reichergasse 131, A-3411 Weidling       email: [email protected]

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.