Signed Tickets
Some projects require a special workflow where tickets can be signed.
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.
Goals
- Users with
TICKET_SIGN
permission can sign tickets. - Signed tickets are considered closed with resolution
signed
. - Signed tickets are read only, except to users with
TICKET_ADMIN
permission. - Signed tickets are visually distinguished.
Steps
Signed Resolution
Add signed
as a Resolution through the web admin page Admin → Ticket System → Resolutions (/admin/ticket/resolution
), or using TracAdmin:
trac-admin $env resolution add signed
Sign workflow step
Configure your workflow adding a step to resolve as signed:
[ticket-workflow] sign = new,assigned,accepted,reopened -> closed sign.name = resolve sign.permissions = TICKET_SIGN sign.operations = set_resolution sign.set_resolution = signed
You probably also want to configure the list of Resolutions
for other actions with a set_resolution
operation, so
that the Signed resolution does not appear in the list.
resolve.set_resolution = fixed, invalid, wontfix, duplicate, worksforme
Readonly logic
Create a single file plugin that implements IPermissionPolicy:
# -*- coding: utf-8 -*- from trac.core import * from trac.perm import IPermissionPolicy, IPermissionRequestor from trac.resource import ResourceNotFound from trac.ticket.model import Ticket class ReadonlySignedTickets(Component): implements(IPermissionPolicy, IPermissionRequestor) allowed_actions = ('TICKET_VIEW',) # IPermissionRequestor methods def get_permission_actions(self): return ['TICKET_SIGN'] # IPermissionPolicy methods def check_permission(self, action, username, resource, perm): if resource is None or resource.realm != 'ticket' or \ resource.id is None or \ action in self.allowed_actions or \ action in ('TICKET_ADMIN', 'TRAC_ADMIN') or \ 'TICKET_ADMIN' in perm: return None try: t = Ticket(self.env, resource.id) except ResourceNotFound: pass else: if t['status'] == 'closed' and t['resolution'] == 'signed': return False
Edit the permission_policies
option in the [trac] section of trac.ini, adding the component before the default permission policy:
[trac] permission_policies = ReadonlySignedTickets, ...
Visual indication
- Install th:ContextChromePlugin#TicketcolorbyType and enable it:
[components] contextchrome.style.typeclasstoticket = enabled
- Configure it to decorate based on the ticket's resolution:
[ticket] decorate_fields = resolution
- Add site.html (the first code snippet in that section) to your Environment templates directory.
- Add
style.css
to your Environment htdocs directory. Add CSS using the selectorbody.resolution_is_signed
. For example:body.resolution_is_signed { background: #f5deb3 url(signed.png); }
- Add signed.png to the htdocs directory.
Variations
Allow ticket comments
Additional permissions can be specified in allowed_actions
.
If you wish to allow commenting on signed tickets, add
TICKET_APPEND
to the allowed_actions
:
allowed_actions = ('TICKET_VIEW', 'TICKET_APPEND')
Status instead of resolution
If you want to use a signed
status instead of a resolution, change the last two lines of code to:
# ... if t['status'] == 'signed': return False
And change the workflow step to:
[ticket-workflow] sign = closed -> signed sign.permissions = TICKET_SIGN
And configure signed
as an end state for milestone progress:
[milestone-groups] closed = closed,signed
Change resolution to status in the visual steps.
Attachments (1)
- signed.png (2.5 KB ) - added by 10 years ago.
Download all attachments as: .zip