| 1 | [[PageOutline(2-3)]] |
| 2 | = Signed Tickets |
| 3 | |
| 4 | Some projects require a special workflow where tickets can be ''signed''. |
| 5 | |
| 6 | This recipe shows steps to implement various aspects of such a feature using a combination of configuration, existing plugins and a small custom permission policy containing the authorization rules. |
| 7 | |
| 8 | == Goals |
| 9 | 1. Users with `TICKET_SIGN` permission can sign tickets. |
| 10 | 1. Signed tickets are consideref closed them with resolution `signed`. |
| 11 | 1. Signed tickets are readonly, except to users with `TICKET_ADMIN` permission. |
| 12 | 1. Signed tickets are visually distinguished. |
| 13 | |
| 14 | == Steps |
| 15 | |
| 16 | === TICKET_SIGN permission |
| 17 | |
| 18 | Enable the optional component [TracPermissions#CreatingNewPrivileges ExtraPermissionsProvider] and configure a new permission: |
| 19 | {{{#!ini |
| 20 | [extra-permissions] |
| 21 | _perms = TICKET_SIGN |
| 22 | }}} |
| 23 | |
| 24 | === Sign workflow step |
| 25 | |
| 26 | Configure your [TracWorkflow workflow] adding a step to resolve as signed: |
| 27 | {{{#!ini |
| 28 | [ticket-workflow] |
| 29 | sign = new -> closed |
| 30 | sign.permissions = TICKET_SIGN |
| 31 | sign.operations = set_resolution |
| 32 | sign.set_resolution = signed |
| 33 | }}} |
| 34 | |
| 35 | === Readonly logic |
| 36 | |
| 37 | Create a [TracDev/PluginDevelopment#Singlefileplugins single file plugin] that implements [wiki:TracDev/PluginDevelopment/ExtensionPoints/trac.perm.IPermissionPolicy IPermissionPolicy]: |
| 38 | |
| 39 | {{{#!python |
| 40 | from trac.core import * |
| 41 | from trac.perm import IPermissionPolicy |
| 42 | from trac.ticket.model import Ticket |
| 43 | |
| 44 | class ReadonlySignedTickets(Component): |
| 45 | implements(IPermissionPolicy) |
| 46 | |
| 47 | def check_permission(self, action, username, resource, perm): |
| 48 | if resource is None or resource.realm != 'ticket' or \ |
| 49 | resource.id is None or action == 'TICKET_VIEW' or \ |
| 50 | action == 'TICKET_ADMIN' or 'TICKET_ADMIN' in perm: |
| 51 | return None |
| 52 | |
| 53 | t = Ticket(self.env, resource.id) |
| 54 | if t['status'] == 'closed' and t['resolution'] == 'signed': |
| 55 | return False |
| 56 | }}} |
| 57 | |
| 58 | |
| 59 | Configure the component ''before'' the default [TracPermissions permission] policy: |
| 60 | {{{#!ini |
| 61 | [trac] |
| 62 | permission_policies = ReadonlySignedTickets, ... |
| 63 | }}} |
| 64 | |
| 65 | === Visual indication |
| 66 | |
| 67 | 1. Install th:ContextChromePlugin#TicketcolorbyType and enable it: |
| 68 | {{{#!ini |
| 69 | [components] |
| 70 | contextchrome.style.typeclasstoticket = enabled |
| 71 | }}} |
| 72 | 2. Configure it to decorate based on the ticket's resolution: |
| 73 | {{{#!ini |
| 74 | [ticket] |
| 75 | decorate_fields = resolution |
| 76 | }}} |
| 77 | 3. Add [TracInterfaceCustomization#SiteAppearance site.html] (the first code snippet in that section) to your Environment templates directory. |
| 78 | 4. Add `style.css` to your Environment htdocs directory. Add CSS using the selector `body.resolution_is_signed`. For example: |
| 79 | {{{#!css |
| 80 | body.resolution_is_signed { |
| 81 | background: #f5deb3 url(signed.png); |
| 82 | } |
| 83 | }}} |
| 84 | 5. Add [attachment:signed.png] to the htdocs directory. |
| 85 | |
| 86 | == Variations |
| 87 | === Allow ticket comments |
| 88 | If you still want to allow commenting on signed tickets, change `action == 'TICKET_VIEW'` to `action in ['TICKET_VIEW', 'TICKET_APPEND']`. |
| 89 | |
| 90 | === Status instead of resolution |
| 91 | If you want to use a `signed` ''status'' instead of a resolution, change the last two lines of code to: |
| 92 | {{{#!python |
| 93 | # ... |
| 94 | if t['status'] == 'signed': |
| 95 | return False |
| 96 | }}} |
| 97 | And change the workflow step to: |
| 98 | {{{#!ini |
| 99 | [ticket-workflow] |
| 100 | sign = closed -> signed |
| 101 | sign.permissions = TICKET_SIGN |
| 102 | }}} |
| 103 | |
| 104 | And configure `signed` as an [CookBook/Configuration/Workflow#Multipleendstatesandmilestoneprogress end state for milestone progress]: |
| 105 | {{{#!ini |
| 106 | [milestone-groups] |
| 107 | closed = closed,signed |
| 108 | }}} |
| 109 | |
| 110 | Change ''resolution'' to ''status'' in the visual steps. |
| 111 | |
| 112 | ---- |
| 113 | See [Trac-ML:36200 original mailing list discussion] |