def get_recipients(self, pagename): QUERY_SIDS = """SELECT sid from session_attribute WHERE name=%s AND value LIKE %s""" QUERY_EMAILS = """SELECT value FROM session_attribute WHERE name=%s AND sid=%s""" tos = [] with self.env.db_query as db: cursor = db.cursor() cursor.execute( QUERY_SIDS, ('watched_pages', '%,' + pagename + ',%')) sids = cursor.fetchall() self.env.log.debug("SID'S TO NOTIFY: %s", sids) perm = PermissionSystem(self.env) resource = Resource('wiki', pagename) for sid in sids: if sid[0] != self.change_author and perm.check_permission(action='WIKI_VIEW', username=sid[0], resource=resource): self.env.log.debug('SID: %s', sid[0]) cursor.execute(QUERY_EMAILS, ('email', sid[0])) sid_email = cursor.fetchone() if sid_email is not None: tos.append(sid_email[0]) self.env.log.debug("TO's TO NOTIFY: %s", tos) return (tos, [])
def render_usermanager_admin_panel(self, req, panel, user, path_info): user_actions = self._get_user_permissions(user) all_user_actions = PermissionSystem(self.env).get_user_permissions(user.username) actions = PermissionSystem(self.env).get_actions()+list(set([group for group, permissions in PermissionSystem(self.env).get_all_permissions()])) data = dict(actions=actions, all_user_actions=all_user_actions, user_actions=user_actions, permsys = PermissionSystem(self.env), messages=[], errors=[]) if req.method=="POST": updated_user_permissions = req.args.getlist('um_permission') for action in actions: if action in updated_user_permissions: if not all_user_actions.has_key(action): try: PermissionSystem(self.env).grant_permission(user.username, action) data['messages'].append(_("Granted permission [%s] for user [%s].")%(action, user.username)) except Exception, e: data['errors'].append(e) else: if user_actions.has_key(action): try: PermissionSystem(self.env).revoke_permission(user.username, action) data['messages'].append(_("Revoked permission [%s] for user [%s].")%(action, user.username)) except Exception, e: data['errors'].append(e)
class _BaseTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(enable=[ 'trac.*', 'acct_mgr.api.*', 'acct_mgr.admin.*', 'acct_mgr.db.*', 'acct_mgr.register.*', 'acct_mgr.pwhash.HtDigestHashMethod', 'acct_mgr.tests.admin.BadCheck', 'acct_mgr.tests.admin.DummyCheck' ]) self.env.path = tempfile.mkdtemp() self.perm = PermissionSystem(self.env) # Create a user reference in the permission system. self.perm.grant_permission('admin', 'ACCTMGR_ADMIN') # Prepare a generic request object for admin actions. self.req = Mock(authname='admin', method='GET', args=dict(), abs_href=self.env.abs_href, chrome=dict(notices=[], warnings=[]), href=self.env.abs_href, locale='', redirect=lambda x: None, session=dict(), tz='' ) self.req.perm = PermissionCache(self.env, 'admin') self.acctmgr = AccountManager(self.env) def tearDown(self): shutil.rmtree(self.env.path)
def authenhandler(req): pw = req.get_basic_auth_pw() user = req.user env = _get_env(req) if env is None: return apache.HTTP_FORBIDDEN global acct_mgr if acct_mgr is None: from acct_mgr.api import AccountManager acct_mgr = AccountManager options = req.get_options() #if 'TracPerm' not in options: # req.log_error('mod_auth_acctmgr: You must specify a permission') # return apache.HTTP_FORBIDDEN perm = options.get('TracPerm') if acct_mgr(env).check_password(user, pw): if perm: user_perms = PermissionSystem(env).get_user_permissions(user) if not user_perms.get(perm): return apache.HTTP_FORBIDDEN return apache.OK else: return apache.HTTP_UNAUTHORIZED
def _users_query(self, q, limit=10): from simplifiedpermissionsadminplugin.simplifiedpermissions import SimplifiedPermissions if SimplifiedPermissions and self.env.is_enabled(SimplifiedPermissions): sp = SimplifiedPermissions(self.env) # Keep track of users that have already been found to prevent # yielding duplicates of users belonging to several groups yielded_sids = set() for group, data in sp.group_memberships().items(): for member in data['members']: if q in member.sid and member.sid not in yielded_sids: # if the 'never logged in' text changes, then update # plugins/open/autocompleteplugin/autocompleteplugin/htdocs/js/jquery.tracautocomplete.js yield {'sid': member.sid, 'name': member.get('name', member.sid), 'email': member.get('email','')} yielded_sids.add(member.sid) else: perm = PermissionSystem(self.env) users = [sid for sid, permission in perm.get_all_permissions() if sid not in set("anonymous", "authenticated", "admin")] for sid in sorted(set(users)): if q in sid: session = DetachedSession(self.env, sid) yield {'sid': sid, 'name': session.get('name',''), 'email': session.get('email','Never logged in')}
def _do_notice(self, req): perm = PermissionSystem(self.env) perms = perm.get_all_permissions() self._get_notice_options() (userinfos, groupinfos) = self._get_infos(perms) if req.method == 'POST': if req.args.get('fill'): self._set_notice_options(req) if req.args.get('use_ldap'): self._fill_from_ldap(userinfos,groupinfos) if req.args.get('use_file'): self._fill_from_file(req,userinfos,groupinfos) if req.args.get('change'): self._fill_from_fields(req,userinfos,groupinfos) if req.args.get('rmuser'): self._rm_user(req,userinfos,groupinfos) (userinfos, groupinfos) = self._get_infos(perms) if req.args.get('rminfo'): self._rm_info(req,userinfos,groupinfos) if req.args.get('rmall'): self._rm_all(req,userinfos,groupinfos) (userinfos, groupinfos) = self._get_infos(perms) if (len(userinfos) > 0) or (len(groupinfos)>0): self.error_message = "As long as permissions are defined for users/group, " + \ "they cannot be delete from this list." if req.args.get('extract'): self._extract_groups(req,userinfos,groupinfos) req.hdf['admin.userinfos'] = userinfos req.hdf['admin.groupinfos'] = groupinfos req.hdf['admin.options'] = self.options if self.error_message: req.hdf['admin.error_message'] = self.error_message return 'admin_notice.cs', None
def check_permission(self, action, username, resource, perm): if ConfigObj is None: self.log.error('configobj package not found') return None if self.authz_file and not self.authz_mtime or \ os.path.getmtime(self.get_authz_file()) > self.authz_mtime: self.parse_authz() resource_key = self.normalise_resource(resource) self.log.debug('Checking %s on %s', action, resource_key) permissions = self.authz_permissions(resource_key, username) if permissions is None: return None # no match, can't decide elif permissions == ['']: return False # all actions are denied # FIXME: expand all permissions once for all ps = PermissionSystem(self.env) for deny, perms in groupby(permissions, key=lambda p: p.startswith('!')): if deny and action in ps.expand_actions([p[1:] for p in perms]): return False # action is explicitly denied elif action in ps.expand_actions(perms): return True # action is explicitly granted return None # no match for action, can't decide
def import_perms(self, template_path): """Creates permissions from data stored in groups.xml. Parses this XML file to get the data we need to insert into the permissions table. If we have this data we clear the existing permission data, and then insert the template data using the PermissionSystem API. If we don't create a perm_data list, we exit the function and continue to use default data. """ # parse the tree to get username, action data # we know the file exists as we check that in import_groups() tree = ET.ElementTree(file=template_path) perm_data = [(subelement.attrib['name'], subelement.attrib['action']) for perm in tree.getroot() for subelement in perm if subelement.attrib['name'].strip()] @self.env.with_transaction() def clear_perms(db): """Clears the whole permissions table of default data.""" cursor = db.cursor() self.log.info("Clearing permissions table") # cant pass the table name as an arg so its hard coded cursor.execute("DELETE FROM permission") self.log.info("Inserting template data into permissions table") perm_system = PermissionSystem(self.env).store for username, action in perm_data: perm_system.grant_permission(username, action)
def _to_users(self, users_perms_and_groups, ticket): """Finds all users contained in the list of `users_perms_and_groups` by recursive lookup of users when a `group` is encountered. """ ps = PermissionSystem(self.env) groups = ps.get_groups_dict() def append_owners(users_perms_and_groups): for user_perm_or_group in users_perms_and_groups: if user_perm_or_group == 'authenticated': owners.update(set(u[0] for u in self.env.get_known_users())) elif user_perm_or_group.isupper(): perm = user_perm_or_group for user in ps.get_users_with_permission(perm): if perm in PermissionCache(self.env, user, ticket.resource): owners.add(user) elif user_perm_or_group not in groups: owners.add(user_perm_or_group) else: append_owners(groups[user_perm_or_group]) owners = set() append_owners(users_perms_and_groups) return sorted(owners)
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) # Essentially the default trac PermissionStore ignores user provided # groups so we have to look them up manually: # changed this to only do this for the default permission # store this has been reported as broken/very slow for the # LDAP permission store ps = PermissionSystem(self.env) if isinstance(ps.store, DefaultPermissionStore): perms = ps.get_all_permissions() repeat = True while repeat: repeat = False for subject, action in perms: if subject in groups and not action.isupper() and action not in groups: groups.add(action) repeat = True return groups
def create_user_and_grant_permissions(self, req, team_member): if self.use_account_manager_integration(team_member.name): password = team_member.name AccountManager(self.env).set_password(team_member.name, password) permission_system = PermissionSystem(self.env) if not permission_system.check_permission(Role.TEAM_MEMBER, team_member.name): permission_system.grant_permission(team_member.name, Role.TEAM_MEMBER)
def _has_edit_perm(self,pagename,username,req): perm_obj=PermissionSystem(self.env) user_permissions=perm_obj.get_user_permissions(username) perm_list=[] for i in user_permissions: if user_permissions[i]==True: perm_list.append(i) if "WIKI_MODIFY" in perm_list: if self._is_the_creator(pagename,username,req)==True: return True if "TRAC_ADMIN" in perm_list: return True else: cnx=self.env.get_db_cnx() cur=cnx.cursor() cur.execute("select count() from wiki_permission where pagename=\"%s\";"%(pagename,)) exist=cur.fetchone() if exist[0] == 0: cur.close() cnx.commit() cnx.close() return True cur.execute("select perm_w from wiki_permission where pagename=\"%s\" and username=\"%s\";"%(pagename,username)) perm=cur.fetchone() cur.close() cnx.commit() cnx.close() if perm and perm[0]==1: return True return False return False
def handle_edit_locale_admins(self, req, locale_id): if not locale_id: req.redirect(req.href.admin('translations', 'locales')) Session = session(self.env) locale = Session.query(Locale).get(int(locale_id)) known_users = self.env.get_known_users() errors = [] perm = PermissionSystem(self.env) sids_without_necessary_perms = [] for admin in locale.admins: if not 'L10N_MODERATE' in perm.get_user_permissions(admin.sid): sids_without_necessary_perms.append(admin.sid) if sids_without_necessary_perms: msg = ngettext( "%s does not have the required permissions to administrate." % \ ', '.join(["'%s'" % s for s in sids_without_necessary_perms]), "%s don't have the required permissions to administrate." % \ ', '.join(["'%s'" % s for s in sids_without_necessary_perms]), len(sids_without_necessary_perms)) errors.append( tag(msg, _(" Don't forget to "), tag.a(_('update permissions'), href=req.href.admin('general', 'perm')), '.')) if req.method == 'POST' and len(req.args.getlist('admins')) >= 1: current_admins = req.args.getlist('current_admins') selected = req.args.getlist('admins') self.log.debug('Current Admins: %s', current_admins) self.log.debug('Selected Admins: %s', selected) allow_delete_admins = len(selected) >= 1 if not allow_delete_admins: errors.append( tag(_("There must be at least on admin for each locale."))) for admin in current_admins: if not allow_delete_admins: break if admin not in selected: locale_admin = Session.query(LocaleAdmin). \ filter(locale_admin_table.c.sid==admin).first() Session.delete(locale_admin) for admin in selected: if admin not in locale.admins: locale.admins.append(LocaleAdmin(locale, admin)) Session.commit() req.redirect(req.href.admin('translations', 'locales')) elif req.method == 'POST' and len(req.args.getlist('admins')) < 1: errors.append( tag(_("There must be at least on admin for each locale."))) data = {'locale': locale, 'known_users': known_users} if errors: data['error'] = tag.ul(*[tag.li(e) for e in errors if e]) return 'l10n_admin_locale_admins.html', data
def add_permissions(self, permissions): perm = PermissionSystem(self.env) for agent, p in permissions.items(): for permission in p: try: perm.grant_permission(agent, permission) except: continue
def permissions(self): """Deprecated (but still used by the HDF compatibility layer) """ self.perm.env.log.warning("perm.permissions() is deprecated and " "is only present for HDF compatibility") permsys = PermissionSystem(self.perm.env) actions = permsys.get_user_permissions(self.perm.username) return [action for action in actions if action in self]
def check_permission(self, doc, context): product, doctype, id = doc['product'], doc['type'], doc['id'] username = context.req.authname env = self.env if product: env = ProductEnvironment(self.env, product) perm = PermissionSystem(env) action = self._required_permissions[doctype] return perm.check_permission(action, username, id)
def _test_get_allowed_owners(self): ticket = insert_ticket(self.env, summary='Ticket 1') self.env.insert_users([('user1', None, None, 1), ('user2', None, None, 1), ('user3', None, None, 1)]) ps = PermissionSystem(self.env) for user in ('user1', 'user3'): ps.grant_permission(user, 'TICKET_MODIFY') self.env.config.set('ticket', 'restrict_owner', True) return ticket
def _reporter(self, message): """return the ticket updater""" user = emailaddr2user(self.env, message['from']) # check permissions perm = PermissionSystem(self.env) if not perm.check_permission('MAIL2TICKET_COMMENT', user) : # None -> 'anoymous' raise EmailException("%s does not have MAIL2TRAC_COMMENT permissions" % (user or 'anonymous')) reporter = user or message['from'] return reporter
def setUp(self): self.global_env = self._setup_test_env(create_folder=False) self._upgrade_mp(self.global_env) self._setup_test_log(self.global_env) self._load_product_from_data(self.global_env, self.default_product) self.env = ProductEnvironment(self.global_env, self.default_product) self.perm = PermissionSystem(self.env) self.ticket_system = TicketSystem(self.env) self.req = Mock()
class ResetActionTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub(default_data=True) self.perm_sys = PermissionSystem(self.env) self.ctlr = TicketSystem(self.env).action_controllers[0] self.req1 = Mock(authname='user1', args={}, perm=PermissionCache(self.env, 'user1')) self.req2 = Mock(authname='user2', args={}, perm=PermissionCache(self.env, 'user2')) self.ticket = Ticket(self.env) self.ticket['status'] = 'invalid' self.ticket.insert() def tearDown(self): self.env.reset_db() def _reload_workflow(self): self.ctlr.actions = self.ctlr.get_all_actions() def test_default_reset_action(self): """Default reset action.""" self.perm_sys.grant_permission('user2', 'TICKET_ADMIN') self._reload_workflow() actions1 = self.ctlr.get_ticket_actions(self.req1, self.ticket) actions2 = self.ctlr.get_ticket_actions(self.req2, self.ticket) chgs2 = self.ctlr.get_ticket_changes(self.req2, self.ticket, '_reset') self.assertEqual(1, len(actions1)) self.assertNotIn((0, '_reset'), actions1) self.assertEqual(2, len(actions2)) self.assertIn((0, '_reset'), actions2) self.assertEqual('new', chgs2['status']) def test_custom_reset_action(self): """Custom reset action in [ticket-workflow] section.""" config = self.env.config['ticket-workflow'] config.set('_reset', '-> review') config.set('_reset.operations', 'reset_workflow') config.set('_reset.permissions', 'TICKET_BATCH_MODIFY') config.set('_reset.default', 2) self.perm_sys.grant_permission('user2', 'TICKET_BATCH_MODIFY') self._reload_workflow() actions1 = self.ctlr.get_ticket_actions(self.req1, self.ticket) actions2 = self.ctlr.get_ticket_actions(self.req2, self.ticket) chgs2 = self.ctlr.get_ticket_changes(self.req2, self.ticket, '_reset') self.assertEqual(1, len(actions1)) self.assertNotIn((2, '_reset'), actions1) self.assertEqual(2, len(actions2)) self.assertIn((2, '_reset'), actions2) self.assertEqual('review', chgs2['status'])
def setUp(self): self.env = EnvironmentStub(default_data=True) self.perm_sys = PermissionSystem(self.env) self.ctlr = TicketSystem(self.env).action_controllers[0] self.req1 = Mock(authname='user1', args={}, perm=PermissionCache(self.env, 'user1')) self.req2 = Mock(authname='user2', args={}, perm=PermissionCache(self.env, 'user2')) self.ticket = Ticket(self.env) self.ticket['status'] = 'invalid' self.ticket.insert()
def setUp(self): self.env = EnvironmentStub(enable=['trac.*', 'acct_mgr.api.*']) self.env.path = tempfile.mkdtemp() self.perm = PermissionSystem(self.env) # Create a user reference in the permission system. self.perm.grant_permission('admin', 'ACCTMGR_USER_ADMIN') # Prepare a generic registration request. args = dict(username='', name='', email='') self.req = Mock(authname='anonymous', args=args) self.req.perm = PermissionCache(self.env)
def _expand_perms(self, env): permsys = PermissionSystem(env) grant = frozenset(permsys.expand_actions(self.grant)) revoke = frozenset(permsys.expand_actions(self.revoke)) # Double check ambiguous action lists if grant & revoke: raise ValueError('Impossible to grant and revoke (%s)' % ', '.join(sorted(grant & revoke))) self.grant = grant self.revoke = revoke self._expanded = True
def remove_permissions(self, permissions): perm = PermissionSystem(self.env) for agent, p in permissions.items(): if '*' in p: p = [ i for i, j in perm.get_user_permissions(agent).items() if j] for permission in p: try: perm.revoke_permission(agent, permission) except: continue
def _has_permission(self, user, report_id): report_permissions = self._get_report_permissions(report_id) if not report_permissions: return True perms = PermissionSystem(self.env) report_permissions = set(report_permissions) user_perm = set(perms.get_user_permissions(user)) groups = set(self._get_user_groups(user)) user_perm.update(groups) if report_permissions.intersection(user_perm) != set([]): return True return False
def _has_permission(self, user, report_id): report_permissions = self._get_report_permissions(report_id) if report_permissions == None or report_permissions == []: return True perms = PermissionSystem(self.env) report_permissions = set(report_permissions) user_perm = set(perms.get_user_permissions(user)) groups = set(self._get_user_groups(user)) user_perm.update(groups) if report_permissions.intersection(user_perm) != set([]): return True return False
def do_purge(self, req, path, users): """Purge obsolete data - i.e. environment data (sessions, preferences, permissions) from users no longer existing @param req @param path path to the trac env to purge @param users users to keep @return boolean success @return msg info """ self.env.log.debug('+ Purging obsolete data') dryrun = self.env.config.getbool('user_sync','dryrun',True) sql = [] envpath, tracenv = os.path.split(path) try: env = Environment(path) except IOError: self.env.log.debug('Could not initialize environment at %s' % (path,)) return False, 'Could not initialize environment at %s' % (path,) perm = PermissionSystem(env) if not 'TRAC_ADMIN' in perm.get_user_permissions(req.perm.username): raise PermissionError excludes = self.get_perm_groups(path)+users protect = "'"+"','".join(excludes)+"'" self.env.log.debug("Excluding from purge: %s" % (protect,)) db = env.get_db_cnx() cursor = db.cursor() if not dryrun: self.env.log.debug('Updating database for %s' % (tracenv,)) cursor.execute('DELETE FROM auth_cookie WHERE name NOT IN (%s)' % (protect,)) cursor.execute('DELETE FROM session WHERE sid NOT IN (%s)' % (protect,)) cursor.execute('DELETE FROM session_attribute WHERE sid NOT IN (%s)' % (protect,)) cursor.execute('DELETE FROM permission WHERE username NOT IN (%s)' % (protect,)) db.commit() sql_file_path = self.env.config.get('user_sync','sql_file_path') or os.path.join(self.env.path,'log') if sql_file_path.lower() == 'none': self.env.log.debug('SQLFile disabled (sql_file_path is "none")') else: sqlfile = '%s.sql' % (tracenv,) sqlfile = os.path.join(sql_file_path,sqlfile) self.env.log.debug('Writing SQL to %s' % (sqlfile,)) try: f = open(sqlfile,'a') f.write('\n--- SQL for purging Trac environment %s\n' % (tracenv,)); f.write('DELETE FROM auth_cookie WHERE name NOT IN (%s);\n' % (protect,)) f.write('DELETE FROM session WHERE sid NOT IN (%s);\n' % (protect,)) f.write('DELETE FROM session_attribute WHERE sid NOT IN (%s);\n' % (protect,)) f.write('DELETE FROM permission WHERE username NOT IN (%s);\n' % (protect,)) except IOError: self.env.log.debug('Could not write SQL file %s!' % (sqlfile,)) return False, 'Could not write SQL file %s!' % (sqlfile,) return True, 'Successfully purged environment %s' % (tracenv,)
def get_user_from_message(self, message): """ Return the ticket user from `message` """ user = utils.email_to_user(self.env, message['from']) #Check permissions perm = PermissionSystem(self.env) if not perm.check_permission('TICKET_APPEND', user): # None -> 'anoymous' raise ValueError("%s does not have TICKET_APPEND permissions" % (user or 'anonymous')) reporter = user or message['from'] return reporter
def get_permission_actions(self): """ This method returnes a list with all the permission that this controller requires. @return: list """ permission_system = PermissionSystem(self.env) for subject, action in permission_system.get_all_permissions(): if action == 'PROJECT_ADMIN' : return [] return ['PROJECT_ADMIN']
def get_permission_actions(self): """ This method returnes a list with all the permission that this controller requires. @return: list """ permission_system = PermissionSystem(self.env) for subject, action in permission_system.get_all_permissions(): if action == 'PROJECT_ADMIN': return [] return ['PROJECT_ADMIN']
def test_new_team_members_get_teammember_permissions(self): req = Mock(authname='admin', perm=MockPerm()) new_member_name = 'fnord' admin_panel = TeamAdminPanel(self.env) team_member = ValueObject(dict(name=new_member_name)) admin_panel.create_user_and_grant_permissions(req, team_member) permission_system = PermissionSystem(self.env) permissions = permission_system.get_user_permissions(new_member_name) self.assert_true(Role.TEAM_MEMBER in permissions) self.assert_true(permissions[Role.TEAM_MEMBER])
class ProductTicketSystemTestCase(TicketSystemTestCase, MultiproductTestCase): def setUp(self): self.global_env = self._setup_test_env(create_folder=False) self._upgrade_mp(self.global_env) self._setup_test_log(self.global_env) self._load_product_from_data(self.global_env, self.default_product) self.env = ProductEnvironment(self.global_env, self.default_product) self.perm = PermissionSystem(self.env) self.ticket_system = TicketSystem(self.env) self.req = Mock() def tearDown(self): self.global_env.reset_db() def test_custom_field_isolation(self): self.env.config.set('ticket-custom', 'test', 'select') self.env.config.set('ticket-custom', 'test.label', 'Test') self.env.config.set('ticket-custom', 'test.value', '1') self.env.config.set('ticket-custom', 'test.options', 'option1|option2') self.global_env.config.set('ticket-custom', 'test', 'text') self.global_env.config.set('ticket-custom', 'test.label', 'Test') self.global_env.config.set('ticket-custom', 'test.value', 'Foo bar') self.global_env.config.set('ticket-custom', 'test.format', 'wiki') product_fields = TicketSystem(self.env).get_custom_fields() global_fields = TicketSystem(self.global_env).get_custom_fields() self.assertEqual({'name': 'test', 'type': 'select', 'label': 'Test', 'value': '1', 'options': ['option1', 'option2'], 'order': 0}, product_fields[0]) self.assertEqual({'name': 'test', 'type': 'text', 'label': 'Test', 'value': 'Foo bar', 'order': 0, 'format': 'wiki'}, global_fields[0]) def test_available_actions_isolation(self): # Grant TICKET_CREATE in product environment ... self.perm.grant_permission('anonymous', 'TICKET_CREATE') self.req.perm = PermissionCache(self.env) self.assertEqual(['leave', 'reopen'], self._get_actions({'status': 'closed'})) # ... but no perms in global environment self.req.perm = PermissionCache(self.global_env) product_env = self.env try: self.env = self.global_env self.assertEqual(['leave'], self._get_actions({'status': 'closed'})) finally: self.env = product_env
def process_admin_request(self, req, cat, page, path_info): envs = DatamoverSystem(self.env).all_environments() permissions = PermissionSystem(self.env).get_all_permissions() if req.method == 'POST': source_type = req.args.get('source') if not source_type or source_type not in ('permission', 'all'): raise TracError, "Source type not specified or invalid" source = req.args.get(source_type) dest = req.args.get('destination') action = None if 'copy' in req.args.keys(): action = 'copy' elif 'move' in req.args.keys(): action = 'move' else: raise TracError, 'Action not specified or invalid' action_verb = {'copy': 'Copied', 'move': 'Moved'}[action] perm_filter = None if source_type == 'permission': in_permissions = [ tuple(p.split(':', 2)) for p in req.args.getlist('perm') ] perm_filter = lambda p: p in in_permissions elif source_type == 'all': perm_filter = lambda p: True try: sel_permissions = [p for p in permissions if perm_filter(p)] dest_env = _open_environment(dest) for perm in sel_permissions: # revoke first in case it's already there # also, go directly to the store to bypass validity checks PermissionSystem(dest_env).store.revoke_permission( perm[0], perm[1]) PermissionSystem(dest_env).store.grant_permission( perm[0], perm[1]) if action == 'move': for perm in sel_permissions: PermissionSystem(self.env).revoke_permission( perm[0], perm[1]) req.hdf['datamover.message'] = '%s permissions %s' % ( action_verb, ', '.join( ["%s:%s" % (u, a) for u, a in sel_permissions])) except TracError, e: req.hdf[ 'datamover.message'] = "An error has occured: \n" + str(e) self.log.warn(req.hdf['datamover.message'], exc_info=True)
def remove_permissions(self, permissions): perm = PermissionSystem(self.env) for agent, p in permissions.items(): if '*' in p: p = [ i for i, j in perm.get_user_permissions(agent).items() if j ] for permission in p: try: perm.revoke_permission(agent, permission) except: continue
def reporter(self, message): """return the ticket reporter or updater""" user = emailaddr2user(self.env, message['from']) # check permissions perm = PermissionSystem(self.env) if not perm.check_permission('TICKET_CREATE', user): # None -> 'anoymous' raise EmailException("%s does not have TICKET_CREATE permissions" % (user or 'anonymous')) reporter = user or message['from'] return reporter
def process_request(self, req): add_script(req, 'cc_selector/cc_selector.js') # fetch list of available developers: cc_developers = [] db = self.env.get_db_cnx() perm = PermissionSystem(self.env) for username, name, email in self.env.get_known_users(db): if perm.get_user_permissions(username).get('TICKET_VIEW'): cc_developers.append(username) req.hdf['cc_developers'] = cc_developers return 'cc_selector.cs', None
def setUp(self): self.env = EnvironmentStub(default_data=True, enable=['trac.*', 'tracvote.*']) self.env.path = tempfile.mkdtemp() self.perm = PermissionSystem(self.env) self.req = Mock() self.db = self.env.get_db_cnx() self.votes = VoteSystem(self.env) # Current tracvotes schema is setup with enabled component anyway. # Revert these changes for getting default permissions inserted. self._revert_schema_init() self.votes.upgrade_environment(self.db)
class NavigationContributorTestCase(unittest.TestCase): def setUp(self): self.report_module = ReportModule(self.env) self.query_module = QueryModule(self.env) self.chrome_module = Chrome(self.env) self.perm_sys = PermissionSystem(self.env) if self.env.is_component_enabled(ReportModule): self.perm_sys.grant_permission('has_report_view', 'REPORT_VIEW') self.perm_sys.grant_permission('has_both', 'REPORT_VIEW') self.perm_sys.grant_permission('has_ticket_view', 'TICKET_VIEW') self.perm_sys.grant_permission('has_both', 'TICKET_VIEW') self.tickets_link = lambda href: '<a href="%s">View Tickets</a>' \ % href def tearDown(self): self.env.reset_db() def get_navigation_items(self, req, module): """Return navigation items for `module` in a list.""" for contributor in self.chrome_module.navigation_contributors: if contributor is module: return list(contributor.get_navigation_items(req)) return [] def assertNavItem(self, href, navigation_items): """Asserts that `navigation_items` contains only one entry and directs to `href`. """ self.assertEqual(1, len(navigation_items)) item = navigation_items[0] self.assertEqual(('mainnav', 'tickets'), item[0:2]) self.assertEqual(self.tickets_link(href), str(item[2]))
def setUp(self): self.env = EnvironmentStub(default_data=True, enable=[ default_workflow.ConfigurableTicketWorkflow, DefaultPermissionPolicy, DefaultPermissionStore, BatchModifyModule, api.TicketSystem, web_ui.TicketModule ]) self.env.config.set('trac', 'permission_policies', 'DefaultPermissionPolicy') self.env.config.set('ticket-custom', 'text1', 'text') self.env.config.set('ticket-custom', 'text1.max_size', 5) self.env.config.set('ticket-custom', 'time1', 'time') self.env.config.set('ticket-custom', 'time1.format', 'date') self.env.config.set('ticket-workflow', 'acknowledge', '* -> acknowledged') ps = PermissionSystem(self.env) ps.grant_permission('has_ta_&_bm', 'TICKET_ADMIN') ps.grant_permission('has_bm', 'TICKET_BATCH_MODIFY') ps.grant_permission('has_ta_&_bm', 'TICKET_BATCH_MODIFY') session = DetachedSession(self.env, 'has_ta_&_bm') session.set('query_href', '') session.save() session = DetachedSession(self.env, 'has_bm') session.set('query_href', '') session.save() self._insert_ticket('Ticket 1', reporter='user1', component='component1', description='the desc', keywords='foo one', status='new') self._insert_ticket('Ticket 2', reporter='user1', component='component2', description='the desc', keywords='baz two', status='new')
def setUp(self): self._mp_setup() self.global_env = self.env self.env = ProductEnvironment(self.global_env, self.default_product) self.global_env.enable_component(TestRequestSpy) self.env.enable_component(TestRequestSpy) TestRequestSpy(self.global_env).testMatch = self._assert_product_match PermissionSystem(self.global_env).grant_permission( 'testuser', 'PRODUCT_CREATE') PermissionSystem(self.global_env).grant_permission( 'testuser', 'PRODUCT_VIEW') PermissionSystem(self.global_env).grant_permission( 'testuser', 'PRODUCT_MODIFY')
def test_existing_ticket_ticket_edit_cc(self): """User with TICKET_EDIT_CC can modify the CC field.""" ps = PermissionSystem(self.env) for perm in ('TICKET_EDIT_CC', 'TICKET_VIEW'): ps.grant_permission('user', perm) self._insert_ticket(reporter='reporter') req = MockRequest(self.env, authname='user', path_info='/ticket/1') self.assertTrue(self.ticket_module.match_request(req)) data = self.ticket_module.process_request(req)[1] cc_field = self._get_field_by_name(data, 'cc') self.assertNotIn('cc_entry', cc_field) self.assertNotIn('cc_action', cc_field)
def setUp(self): self.env = EnvironmentStub(enable=['trac.*', 'bitten.*']) self.env.path = tempfile.mkdtemp() # Create tables db = self.env.get_db_cnx() cursor = db.cursor() connector, _ = DatabaseManager(self.env)._get_connector() for table in schema: for stmt in connector.to_sql(table): cursor.execute(stmt) # Set up permissions self.env.config.set('trac', 'permission_store', 'DefaultPermissionStore') PermissionSystem(self.env).grant_permission('joe', 'BUILD_CREATE') PermissionSystem(self.env).grant_permission('joe', 'BUILD_DELETE') PermissionSystem(self.env).grant_permission('joe', 'BUILD_MODIFY') if DefaultPermissionPolicy is not None and hasattr( DefaultPermissionPolicy, "CACHE_EXPIRY"): self.old_perm_cache_expiry = DefaultPermissionPolicy.CACHE_EXPIRY DefaultPermissionPolicy.CACHE_EXPIRY = -1 # Hook up a dummy repository self.repos = Mock(get_node=lambda path, rev=None: Mock( get_history=lambda: [], isdir=True), normalize_path=lambda path: path, sync=lambda: None, resource=Resource('repository', None)) self.env.get_repository = lambda authname=None: self.repos # 0.11 try: # 0.12+ from trac.core import Component, implements from trac.versioncontrol.api import IRepositoryConnector, \ IRepositoryProvider class DummyRepos(Component): implements(IRepositoryConnector, IRepositoryProvider) def get_supported_types(self): yield ('dummy', 9) def get_repository(this, repos_type, repos_dir, params): return self.repos # Note: 'this' vs 'self' usage def get_repositories(self): yield ('', {'dir': 'dummy_dir', 'type': 'dummy'}) self.dummy = DummyRepos except ImportError: self.dummy = None # not supported, will use get_repository()
def test_add_comment_requires_ticket_append(self): """Adding a ticket comment requires TICKET_APPEND.""" ps = PermissionSystem(self.env) ps.revoke_permission('authenticated', 'TICKET_MODIFY') ps.grant_permission('user1', 'TICKET_APPEND') ps.grant_permission('user2', 'TICKET_CHGPROP') ticket = self._insert_ticket(summary='the summary') comment = 'the comment' def make_req(authname): change_time = Ticket(self.env, 1)['changetime'] return MockRequest( self.env, authname=authname, method='POST', path_info='/ticket/1', args={'comment': comment, 'action': 'leave', 'submit': True, 'view_time': unicode(to_utimestamp(change_time))}) req = make_req('user1') self.assertTrue(self.ticket_module.match_request(req)) self.assertRaises(RequestDone, self.ticket_module.process_request, req) self.assertEqual([], req.chrome['warnings']) self.assertEqual(comment, ticket.get_change(1)['fields']['comment']['new']) req = make_req('user2') self.assertTrue(self.ticket_module.match_request(req)) self.ticket_module.process_request(req) self.assertEqual(1, len(req.chrome['warnings'])) self.assertEqual("No permissions to add a comment.", unicode(req.chrome['warnings'][0]))
def _get_all_users(self): """ Fetches all users/groups from PermissionSystem """ perm = PermissionSystem(self.env) users = ["*"] data = perm.get_all_permissions() if not data: return [] # we abort here for (subject, action) in data: if subject not in users and subject not in ["anonymous", "authenticated"]: users.append(subject) return users
def setUp(self): self.report_module = ReportModule(self.env) self.query_module = QueryModule(self.env) self.chrome_module = Chrome(self.env) self.perm_sys = PermissionSystem(self.env) if self.env.is_component_enabled(ReportModule): self.perm_sys.grant_permission('has_report_view', 'REPORT_VIEW') self.perm_sys.grant_permission('has_both', 'REPORT_VIEW') self.perm_sys.grant_permission('has_ticket_view', 'TICKET_VIEW') self.perm_sys.grant_permission('has_both', 'TICKET_VIEW') self.tickets_link = lambda href: '<a href="%s">View Tickets</a>' \ % href
def setUp(self): self.env = EnvironmentStub(default_data=True, enable=['trac.*', 'tractags.*']) self.env.path = tempfile.mkdtemp() self.perms = PermissionSystem(self.env) self.req = Mock() self.actions = ['TAGS_ADMIN', 'TAGS_MODIFY', 'TAGS_VIEW'] self.tag_s = TagSystem(self.env) self.db = self.env.get_db_cnx() setup = TagSetup(self.env) # Current tractags schema is setup with enabled component anyway. # Revert these changes for getting default permissions inserted. self._revert_tractags_schema_init() setup.upgrade_environment(self.db)
def projects(self, user): base_path, _project = os.path.split(self.env.path) _projects = [p for p in os.listdir(base_path) if p != _project] projects = {} for project in _projects: path = os.path.join(base_path, project) try: env = open_environment(path, use_cache=True) except: continue perm = PermissionSystem(env) if self.permission in perm.get_user_permissions(user): projects[project] = env return projects
def get_relevant_permissions(self, policy, username): ps = PermissionSystem(self.env) relevant_permissions = set(self._required_permissions.itervalues()) user_permissions = self.get_all_user_permissions(policy, username) for doc_type, doc_id, permissions in user_permissions: for deny, perms in groupby(permissions, key=lambda p: p.startswith('!')): if deny: for p in ps.expand_actions([p[1:] for p in perms]): if p in relevant_permissions: yield doc_type, doc_id, p, True else: for p in ps.expand_actions(perms): if p in relevant_permissions: yield doc_type, doc_id, p, False
def test_tag_query_save(self): """Save timeline tag query string in session.""" self.assertEqual('tag_query', self.tef.key) from trac.timeline.web_ui import TimelineModule TimelineModule(self.env) perms = PermissionSystem(self.env) perms.grant_permission('anonymous', 'TAGS_VIEW') perms.grant_permission('anonymous', 'TIMELINE_VIEW') req = self._create_request(args=dict(tag_query='query_str'), path_info='/timeline', method='GET') dispatcher = RequestDispatcher(self.env) self.assertRaises(RequestDone, dispatcher.dispatch, req) self.assertEqual('query_str', req.session['timeline.tag_query'])
def setUp(self): self.env = EnvironmentStub(default_data=True, enable=['trac.*', 'tractags.*']) self.env.path = tempfile.mkdtemp() self.perms = PermissionSystem(self.env) setup = TagSetup(self.env) # Current tractags schema is setup with enabled component anyway. # Revert these changes for getting default permissions inserted. self._revert_tractags_schema_init() setup.upgrade_environment() self.provider = TicketTagProvider(self.env) self.realm = 'ticket' self.tag_sys = TagSystem(self.env) self.tags = ['tag1', 'tag2'] # Populate tables with initial test data. self._create_ticket(self.tags) # Mock an anonymous request. self.anon_req = Mock() self.anon_req.perm = PermissionCache(self.env) self.req = Mock(authname='editor') self.req.authname = 'editor' self.req.perm = PermissionCache(self.env, username='******')
def check_permission(self, action, username, resource, perm): if resource is None or action.split('_')[0] != resource.realm.upper(): return None from tractags.api import TagSystem class FakeRequest(object): def __init__(self, perm): self.perm = perm permission = action.lower().split('_')[1] req = FakeRequest(perm) tags = TagSystem(self.env).get_tags(None, resource) # Explicitly denied? if ':-'.join((username, permission)) in tags: return False # Find all granted permissions for the requesting user from # tagged permissions by expanding any meta action as well. if action in set( PermissionSystem(self.env).expand_actions([ '_'.join([resource.realm, t.split(':')[1]]).upper() for t in tags if t.split(':')[0] == username ])): return True
def setUp(self): self.env = EnvironmentStub(default_data=True, enable=['trac.*', 'tractags.*']) self.env.path = tempfile.mkdtemp() self.perms = PermissionSystem(self.env) self.db = self.env.get_db_cnx() setup = TagSetup(self.env) # Current tractags schema is setup with enabled component anyway. # Revert these changes for getting default permissions inserted. self._revert_tractags_schema_init() setup.upgrade_environment(self.db) self.provider = TicketTagProvider(self.env) self.realm = 'ticket' self.tag_sys = TagSystem(self.env) self.tags = ['tag1'] cursor = self.db.cursor() # Populate table with initial test data, not synced with tickets yet. cursor.execute(""" INSERT INTO tags (tagspace, name, tag) VALUES ('ticket', '1', 'deleted')""") self.realm = 'ticket' self._create_ticket(self.tags) self.req = Mock() # Mock an anonymous request. self.req.perm = PermissionCache(self.env)
def setUp(self): self.env = EnvironmentStub(default_data=True, enable=['trac.*', 'tractags.*']) self.env.path = tempfile.mkdtemp() self.perms = PermissionSystem(self.env) self.tag_s = TagSystem(self.env) self.tag_wp = WikiTagProvider(self.env) self.db = self.env.get_db_cnx() setup = TagSetup(self.env) # Current tractags schema is partially setup with enabled component. # Revert these changes for getting a clean setup. self._revert_tractags_schema_init() setup.upgrade_environment(self.db) cursor = self.db.cursor() # Populate table with initial test data. cursor.execute(""" INSERT INTO tags (tagspace, name, tag) VALUES ('wiki', 'WikiStart', 'tag1') """) self.req = Mock() # Mock an anonymous request. self.req.perm = PermissionCache(self.env) self.realm = 'wiki' self.tags = ['tag1']