| [4216] | 1 | #!/usr/bin/env python |
|---|
| 2 | """ |
|---|
| [5171] | 3 | programmatic front end to trac-admin tasks |
|---|
| [4216] | 4 | """ |
|---|
| 5 | |
|---|
| [5171] | 6 | import pkg_resources |
|---|
| [7236] | 7 | import sys |
|---|
| [4216] | 8 | |
|---|
| [7236] | 9 | from martini.config import ConfigMunger |
|---|
| 10 | from martini.utils import getlist |
|---|
| 11 | from optparse import OptionParser |
|---|
| [4216] | 12 | from trac.admin.console import TracAdmin |
|---|
| [5171] | 13 | from trac.env import open_environment |
|---|
| [6188] | 14 | from trac.perm import PermissionSystem |
|---|
| [5171] | 15 | from trac.ticket import model |
|---|
| [4216] | 16 | |
|---|
| 17 | class TracLegosAdmin(TracAdmin): |
|---|
| 18 | """TracLegos front-end to Trac's command-line-admin interface""" |
|---|
| 19 | |
|---|
| 20 | def __init__(self, env): |
|---|
| 21 | TracAdmin.__init__(self, env) |
|---|
| [5171] | 22 | self.env = open_environment(env) |
|---|
| 23 | |
|---|
| [5170] | 24 | # new style, as of trac:changeset:7677 |
|---|
| 25 | # see trac:#7770 |
|---|
| [5171] | 26 | # for now, support both use-cases |
|---|
| [5170] | 27 | if not hasattr(self, 'get_component_list'): |
|---|
| 28 | # TODO: create these functions |
|---|
| [5171] | 29 | from trac.ticket.admin import ComponentAdminPanel |
|---|
| 30 | from trac.ticket.admin import MilestoneAdminPanel |
|---|
| 31 | from trac.wiki.admin import WikiAdmin |
|---|
| [4216] | 32 | |
|---|
| [5171] | 33 | self.ComponentAdminPanel = ComponentAdminPanel(self.env) |
|---|
| 34 | self.get_component_list = self.ComponentAdminPanel.get_component_list |
|---|
| 35 | self._do_component_remove = self.ComponentAdminPanel._do_remove |
|---|
| 36 | self.MilestoneAdminPanel = MilestoneAdminPanel(self.env) |
|---|
| 37 | self.get_milestone_list = self.MilestoneAdminPanel.get_milestone_list |
|---|
| 38 | self._do_milestone_remove = self.MilestoneAdminPanel._do_remove |
|---|
| 39 | self.WikiAdmin = WikiAdmin(self.env) |
|---|
| 40 | self._do_wiki_load = self.WikiAdmin.load_pages |
|---|
| 41 | |
|---|
| 42 | |
|---|
| [4216] | 43 | def list(self, field): |
|---|
| 44 | """ |
|---|
| 45 | list fields of a particular type |
|---|
| 46 | """ |
|---|
| [5169] | 47 | # XXX these fucntions are no longer in trunk |
|---|
| [4216] | 48 | list_functions = { 'component': self.get_component_list, |
|---|
| 49 | 'milestone': self.get_milestone_list, |
|---|
| 50 | } |
|---|
| [5169] | 51 | |
|---|
| [4216] | 52 | assert field in list_functions |
|---|
| 53 | return list_functions[field]() |
|---|
| 54 | |
|---|
| 55 | def remove(self, field, name): |
|---|
| 56 | """ |
|---|
| 57 | remove a field of a type with a particular name |
|---|
| 58 | """ |
|---|
| [5169] | 59 | # XXX these fucntions are no longer in trunk |
|---|
| [4216] | 60 | remove_functions = { 'component': self._do_component_remove, |
|---|
| 61 | 'milestone': self._do_milestone_remove, |
|---|
| 62 | } |
|---|
| [5169] | 63 | |
|---|
| [4216] | 64 | assert field in remove_functions |
|---|
| 65 | remove_functions[field](name) |
|---|
| 66 | |
|---|
| 67 | |
|---|
| 68 | def delete_all(self, fields=('component', 'milestone')): |
|---|
| 69 | """delete all default cruft""" |
|---|
| 70 | |
|---|
| 71 | for field in fields: |
|---|
| 72 | for value in self.list(field): |
|---|
| 73 | self.remove(field, value) |
|---|
| [5171] | 74 | |
|---|
| [6733] | 75 | def load_pages(self, pages_dir=None): |
|---|
| 76 | if pages_dir is None: |
|---|
| 77 | # default Trac wiki pages |
|---|
| 78 | pages_dir = pkg_resources.resource_filename('trac.wiki', |
|---|
| 79 | 'default-pages') |
|---|
| [5171] | 80 | cnx = self.env.get_db_cnx() |
|---|
| 81 | cursor = cnx.cursor() |
|---|
| 82 | self._do_wiki_load(pages_dir, cursor) # should probably make this silent |
|---|
| 83 | cnx.commit() |
|---|
| [6188] | 84 | |
|---|
| 85 | def add_permissions(self, permissions): |
|---|
| 86 | perm = PermissionSystem(self.env) |
|---|
| 87 | for agent, p in permissions.items(): |
|---|
| 88 | for permission in p: |
|---|
| [7236] | 89 | try: |
|---|
| 90 | perm.grant_permission(agent, permission) |
|---|
| 91 | except: |
|---|
| 92 | continue |
|---|
| [6188] | 93 | |
|---|
| [7236] | 94 | def remove_permissions(self, permissions): |
|---|
| 95 | perm = PermissionSystem(self.env) |
|---|
| 96 | for agent, p in permissions.items(): |
|---|
| 97 | if '*' in p: |
|---|
| 98 | p = [ i for i, j in perm.get_user_permissions(agent).items() if j] |
|---|
| 99 | for permission in p: |
|---|
| 100 | |
|---|
| 101 | try: |
|---|
| 102 | perm.revoke_permission(agent, permission) |
|---|
| 103 | except: |
|---|
| 104 | continue |
|---|
| 105 | |
|---|
| 106 | |
|---|
| 107 | def apply_permissions(envs, ini): |
|---|
| 108 | munger = ConfigMunger(*ini) |
|---|
| 109 | |
|---|
| 110 | if munger.has_section('permissions'): |
|---|
| 111 | add_permissions = dict([(i, getlist(j)) |
|---|
| 112 | for i, j in munger['permissions'].items()]) |
|---|
| 113 | else: |
|---|
| 114 | add_permissions = None |
|---|
| 115 | if munger.has_section('remove-permissions'): |
|---|
| 116 | remove_permissions = dict([(i, getlist(j)) |
|---|
| 117 | for i, j in munger['remove-permissions'].items()]) |
|---|
| 118 | else: |
|---|
| 119 | remove_permissions = None |
|---|
| 120 | |
|---|
| 121 | for env in envs: |
|---|
| 122 | admin = TracLegosAdmin(env) |
|---|
| 123 | if add_permissions: |
|---|
| 124 | admin.add_permissions(add_permissions) |
|---|
| 125 | if remove_permissions: |
|---|
| 126 | admin.remove_permissions(remove_permissions) |
|---|
| 127 | |
|---|
| 128 | def main(args=sys.argv[1:]): |
|---|
| 129 | parser = OptionParser("%prog -e /path/to/env [-e /path/to/env2] [...] permissions.ini [permissions2.ini] [...]") |
|---|
| 130 | parser.add_option('-e', '--env', dest='env', action='append', |
|---|
| 131 | help="trac environment(s)") |
|---|
| 132 | options, args = parser.parse_args(args) |
|---|
| 133 | if not args: |
|---|
| 134 | parser.error("Please specify one or more permissions .ini files") |
|---|
| 135 | if not options.env: |
|---|
| 136 | parser.error("Please specify one or more Trac environments") |
|---|
| 137 | |
|---|
| 138 | apply_permissions(options.env, args) |
|---|
| 139 | |
|---|
| 140 | |
|---|
| 141 | if __name__ == '__main__': |
|---|
| 142 | main() |
|---|