| 1 | == Extension Point : ''IPermissionRequestor'' == |
| 2 | |
| 3 | ||'''Interface'''||''IPermissionRequestor''||'''Since'''||0.9|| |
| 4 | ||'''Module'''||''trac.perm''||'''Source'''||[source:trunk/trac/perm.py#L60 perm.py]|| |
| 5 | |
| 6 | |
| 7 | The (somewhat confusingly named) ''IPermissionRequestor'' simply allows components to define permission actions (and meta permission actions and their relations to other permission actions). |
| 8 | |
| 9 | == Purpose == |
| 10 | |
| 11 | Many of Trac's features are only available to users with certain permissions. By default these are the coarse permissions described in TracPermissions. More fine-grained per-resource permissions as described by TracFineGrainedPermissions are also possible. |
| 12 | |
| 13 | While a component can check for any permissions already defined by other components, it might want to define its own permission types for its actions on resources. |
| 14 | |
| 15 | == Usage == |
| 16 | |
| 17 | Implementing the interface follows the standard guidelines found in [wiki:TracDev/ComponentArchitecture] and of course [wiki:TracDev/PluginDevelopment]. |
| 18 | |
| 19 | Only one method has to be defined: {{{get_permission_actions()}}}. This method should return a list of permission actions. Each action is either the name of the action (a simple string) or, for so called ''meta permissions'' a tuple, where the first tuple item is the name of the action, and the second tuple item is a list of subsumed action names. (The meta permission covers all listed permissions. If multiple implementations return the same meta permission, they are combined.) |
| 20 | |
| 21 | Action names should be in ALL_CAPS_WITH_UNDERSCORES and usually consist of two parts: |
| 22 | * The resource type / module name. |
| 23 | * The action to perform on that resource. |
| 24 | |
| 25 | The most common action is VIEW, to allow basic usage (viewing) of a resource. It is often required for components implementing [wiki:TracDev/PluginDevelopment/ExtensionPoints/IRequestHandler IRequestHandler], where {{{process_request()}}} would check for permissions categorically ({{{req.perm.require('RESOURCE_VIEW')}}}) or selectively ({{{if 'RESOURCE_ACTION' in req.perm:}}}). (Such an IRequestHandler - or any other kind of checked resource access - could also be implemented by any other Component.) |
| 26 | |
| 27 | Anyone with access to a ''perm'' (trac.perm.PermissionCache) can perform permission check. It is usually obtained from ''req'' (a trac.web.api.Request). More fine-grained per-resource permission checks can be performed by obtaining a specialized cache using {{{req.perm(resource)}}} or {{{req.perm(realm, resource_id)}}}. |
| 28 | |
| 29 | A slightly more complex pattern is to return multiple simple RESOURCE_ACTION permission actions and one RESOURCE_ADMIN meta permission action covering the others. Even more complex hierarchies of permissions are possible. (See [#Ticket]) |
| 30 | |
| 31 | == Examples == |
| 32 | |
| 33 | === Minimal === |
| 34 | |
| 35 | An almost minimal example defining two new permissions to be checked elsewhere: |
| 36 | {{{#!python |
| 37 | from trac.core import Component, implements |
| 38 | from trac.perm import IPermissionRequestor |
| 39 | |
| 40 | class CoffeePermissions(Component): |
| 41 | implements(IPermissionRequestor) |
| 42 | |
| 43 | def get_permission_actions(self): |
| 44 | return ('COFFEE_BREW', 'COFFEE_DRINK') |
| 45 | }}} |
| 46 | |
| 47 | === Upgrade example === |
| 48 | |
| 49 | If a new version of a component renames / merges / splits existing permissions of an older version, it might want to implement an environment upgrade ([wiki:TracDev/PluginDevelopment/ExtensionPoints/IEnvironmentSetupParticipant IEnvironmentSetupParticipant]). |
| 50 | |
| 51 | A real example would be [h:TracPastePlugin], which changed from a single permission PASTEBIN_USE to multiple permissions PASTEBIN_VIEW and PASTEBIN_CREATE. In [h:changeset:4983 this changeset], ({{{environment_needs_upgrade}}} checks {{{_has_old_permission}}} for any of the old permissions and {{{upgrade_environment}}} calls {{{convert_use_permissions}}} (via the {{{version_map}}} if required) to convert them to the new permissions. |
| 52 | |
| 53 | == Available Implementations == |
| 54 | |
| 55 | === Simple === #Simple |
| 56 | |
| 57 | One of the simplest use cases is to define one permission to view the resources of that module: |
| 58 | |
| 59 | * [source:trunk/trac/timeline/web_ui.py#L80 trac.timeline.web_ui.TimelineModule] |
| 60 | {{{#!python |
| 61 | return ['TIMELINE_VIEW'] |
| 62 | }}} |
| 63 | |
| 64 | * [source:trunk/trac/search/web_ui.py#L72 trac.search.web_ui.SearchModule] |
| 65 | {{{#!python |
| 66 | return ['SEARCH_VIEW'] |
| 67 | }}} |
| 68 | |
| 69 | * [source:trunk/trac/about.py#L49 trac.about.AboutModule] |
| 70 | {{{#!python |
| 71 | return ['CONFIG_VIEW'] |
| 72 | }}} |
| 73 | |
| 74 | === Ticket === #Ticket |
| 75 | |
| 76 | The most complex example in Trac itself. Various meta permissions subsume certain / all other permissions for convenience. |
| 77 | |
| 78 | * [source:trunk/trac/ticket/api.py#L417 trac.ticket.api.TicketSystem] |
| 79 | {{{#!python |
| 80 | return ['TICKET_APPEND', 'TICKET_CREATE', 'TICKET_CHGPROP', |
| 81 | 'TICKET_VIEW', 'TICKET_EDIT_CC', 'TICKET_EDIT_DESCRIPTION', |
| 82 | 'TICKET_EDIT_COMMENT', |
| 83 | ('TICKET_MODIFY', ['TICKET_APPEND', 'TICKET_CHGPROP']), |
| 84 | ('TICKET_ADMIN', ['TICKET_CREATE', 'TICKET_MODIFY', |
| 85 | 'TICKET_VIEW', 'TICKET_EDIT_CC', |
| 86 | 'TICKET_EDIT_DESCRIPTION', |
| 87 | 'TICKET_EDIT_COMMENT'])] |
| 88 | }}} |
| 89 | |
| 90 | * [source:trunk/trac/ticket/report.py#L77 trac.ticket.report.ReportModule] |
| 91 | {{{#!python |
| 92 | actions = ['REPORT_CREATE', 'REPORT_DELETE', 'REPORT_MODIFY', |
| 93 | 'REPORT_SQL_VIEW', 'REPORT_VIEW'] |
| 94 | return actions + [('REPORT_ADMIN', actions)] |
| 95 | }}} |
| 96 | |
| 97 | === Roadmap === #Roadmap |
| 98 | |
| 99 | For historical reasons a bit unintuitive. Planned to be simplified in the future (see #4292 / #3022) |
| 100 | |
| 101 | * [source:trunk/trac/ticket/roadmap.py#L361 trac.ticket.roadmap.RoadmapModule] |
| 102 | {{{#!python |
| 103 | actions = ['MILESTONE_CREATE', 'MILESTONE_DELETE', 'MILESTONE_MODIFY', |
| 104 | 'MILESTONE_VIEW', 'ROADMAP_VIEW'] |
| 105 | return ['ROADMAP_VIEW'] + [('ROADMAP_ADMIN', actions)] |
| 106 | }}} |
| 107 | |
| 108 | * [source:trunk/trac/ticket/roadmap.py#L562 MilestoneModule] |
| 109 | {{{#!python |
| 110 | actions = ['MILESTONE_CREATE', 'MILESTONE_DELETE', 'MILESTONE_MODIFY', |
| 111 | 'MILESTONE_VIEW'] |
| 112 | return actions + [('MILESTONE_ADMIN', actions)] |
| 113 | }}} |
| 114 | |
| 115 | === Wiki === #Wiki |
| 116 | |
| 117 | * [source:trunk/trac/wiki/web_ui.py#L96 trac.wiki.web_ui.WikiModule] |
| 118 | {{{#!python |
| 119 | actions = ['WIKI_CREATE', 'WIKI_DELETE', 'WIKI_MODIFY', 'WIKI_RENAME', |
| 120 | 'WIKI_VIEW'] |
| 121 | return actions + [('WIKI_ADMIN', actions)] |
| 122 | }}} |
| 123 | |
| 124 | As an interesting peculiarity: Permissions to manipulate permissions: |
| 125 | |
| 126 | * [source:trunk/trac/admin/web_ui.py#L347 trac.admin.web_ui.PermissionAdminPanel] |
| 127 | {{{#!python |
| 128 | actions = ['PERMISSION_GRANT', 'PERMISSION_REVOKE'] |
| 129 | return actions + [('PERMISSION_ADMIN', actions)] |
| 130 | }}} |
| 131 | |
| 132 | === Version control === #VersionControl |
| 133 | |
| 134 | An example of a component to combine permissions of other components into a meta permission. |
| 135 | |
| 136 | * [source:trunk/trac/versioncontrol/admin.py#L156 trac.versioncontrol.admin.VersionControlAdmin] |
| 137 | {{{#!python |
| 138 | return [('VERSIONCONTROL_ADMIN', ['BROWSER_VIEW', 'CHANGESET_VIEW', |
| 139 | 'FILE_VIEW', 'LOG_VIEW'])] |
| 140 | }}} |
| 141 | |
| 142 | * [source:trunk/trac/versioncontrol/web_ui/browser.py#L301 trac.versioncontrol.web_ui.browser.BrowserModule] |
| 143 | {{{#!python |
| 144 | return ['BROWSER_VIEW', 'FILE_VIEW'] |
| 145 | }}} |
| 146 | |
| 147 | * [source:trunk/trac/versioncontrol/web_ui/changeset.py#L176 trac.versioncontrol.web_ui.changeset.ChangesetModule] |
| 148 | {{{#!python |
| 149 | return ['CHANGESET_VIEW'] |
| 150 | }}} |
| 151 | |
| 152 | * [source:trunk/trac/versioncontrol/web_ui/log.py#L66 trac.versioncontrol.web_ui.log.LogModule] |
| 153 | {{{#!python |
| 154 | return ['LOG_VIEW'] |
| 155 | }}} |
| 156 | |
| 157 | == Additional Information and References == |
| 158 | |
| 159 | * [http://www.edgewall.org/docs/trac-trunk/html/api/trac_perm.html#trac.perm.IPermissionRequestor API Reference] |
| 160 | * Ticket about extending exsting meta-permissions: #8036 |
| 161 | * Mailing list [http://article.gmane.org/gmane.comp.version-control.subversion.trac.general/3119 message] about the initial design of IPermissionRequestor, [wiki:TracDev/PluginDevelopment/ExtensionPoints/IPermissionStore IPermissionStore] and [wiki:TracDev/PluginDevelopment/ExtensionPoints/IPermissionGroupProvider IPermissionGroupProvider] |