/usr/share/pyshared/virtualticketpermissions/policy.py is in trac-virtualticketpermissions 1.0.0+svn4153-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | # Created by Norman Rasmussen on 2008-08-19.
# Copyright (c) 2008 Norman Rasmussen. All rights reserved.
# Based on the PrivateTicketsPlugin by Noah Kantrowitz
from trac.core import *
from trac.perm import IPermissionRequestor, IPermissionGroupProvider, IPermissionPolicy, PermissionSystem
from trac.ticket.model import Ticket
from trac.config import IntOption, ListOption
from trac.util.compat import set
class VirtualTicketPermissionsPolicy(Component):
"""Central tasks for the VirtualTicketPermissions plugin."""
implements(IPermissionRequestor, IPermissionPolicy)
group_providers = ExtensionPoint(IPermissionGroupProvider)
blacklist = ListOption('virtualticketpermissions', 'group_blacklist', default='anonymous, authenticated',
doc='Groups that do not affect the common membership check.')
virtual_permissions = set([
'TICKET_IS_REPORTER',
'TICKET_IS_OWNER',
'TICKET_IS_CC',
'TICKET_IS_REPORTER_GROUP',
'TICKET_IS_OWNER_GROUP',
'TICKET_IS_CC_GROUP',
])
# IPermissionPolicy(Interface)
def check_permission(self, action, username, resource, perm):
if username == 'anonymous' or \
not action in self.virtual_permissions:
# In these two cases, checking makes no sense
return None
if 'TRAC_ADMIN' in perm:
# In this case, checking makes no sense
return True
# Look up the resource parentage for a ticket.
while resource:
if resource.realm == 'ticket':
break
resource = resource.parent
if resource and resource.realm == 'ticket' and resource.id is not None:
return self.check_ticket_permissions(action, perm, resource)
return None
# IPermissionRequestor methods
def get_permission_actions(self):
actions = ['TICKET_IS_REPORTER', 'TICKET_IS_OWNER', 'TICKET_IS_CC']
group_actions = ['TICKET_IS_REPORTER_GROUP', 'TICKET_IS_OWNER_GROUP', 'TICKET_IS_CC_GROUP']
all_actions = actions + [(a+'_GROUP', [a]) for a in actions]
return all_actions + [('TICKET_IS_SELF', actions), ('TICKET_IS_GROUP', group_actions)]
# Public methods
def check_ticket_permissions(self, action, perm, res):
"""Return if this req is generating permissions for the given ticket ID."""
try:
tkt = Ticket(self.env, res.id)
except TracError:
return None # Ticket doesn't exist
if action == 'TICKET_IS_SELF':
return tkt['reporter'] == perm.username or \
perm.username == tkt['owner'] or \
perm.username in [x.strip() for x in tkt['cc'].split(',')]
if action == 'TICKET_IS_REPORTER':
return tkt['reporter'] == perm.username
if action == 'TICKET_IS_CC':
return perm.username in [x.strip() for x in tkt['cc'].split(',')]
if action == 'TICKET_IS_OWNER':
return perm.username == tkt['owner']
if action == 'TICKET_IS_GROUP':
result = self._check_group(perm.username, tkt['reporter']) or \
self._check_group(perm.username, tkt['owner'])
for user in tkt['cc'].split(','):
#self.log.debug('Private: CC check: %s, %s', req.authname, user.strip())
if self._check_group(perm.username, user.strip()):
result = True
return result
if action == 'TICKET_IS_REPORTER_GROUP':
return self._check_group(perm.username, tkt['reporter'])
if action == 'TICKET_IS_OWNER_GROUP':
return self._check_group(perm.username, tkt['owner'])
if action == 'TICKET_IS_CC_GROUP':
result = False
for user in tkt['cc'].split(','):
#self.log.debug('Private: CC check: %s, %s', req.authname, user.strip())
if self._check_group(perm.username, user.strip()):
result = True
return result
# We should never get here
return None
# Internal methods
def _check_group(self, user1, user2):
"""Check if user1 and user2 share a common group."""
user1_groups = self._get_groups(user1)
user2_groups = self._get_groups(user2)
both = user1_groups.intersection(user2_groups)
both -= set(self.blacklist)
#self.log.debug('PrivateTicket: %s&%s = (%s)&(%s) = (%s)', user1, user2, ','.join(user1_groups), ','.join(user2_groups), ','.join(both))
return bool(both)
def _get_groups(self, user):
# Get initial subjects
groups = set([user])
for provider in self.group_providers:
for group in provider.get_permission_groups(user):
groups.add(group)
perms = PermissionSystem(self.env).get_all_permissions()
repeat = True
while repeat:
repeat = False
for subject, action in perms:
if subject in groups and action.islower() and action not in groups:
groups.add(action)
repeat = True
return groups
|