= Custom Permission Policies Permission policies were introduced on the [TracFineGrainedPermissions#PermissionPolicies TracFineGrainedPermissions] page. Custom policies can often be implemented with a short plugin. Some custom permission policy examples are given on this page. == Restrict a Workflow Action to the Ticket Owner This permissions policy can be used to restrict a workflow action to the ticket's owner. To install and activate the plugin: 1. Create a [TracDev/PluginDevelopment#Singlefileplugins single file plugin] that implements [wiki:TracDev/PluginDevelopment/ExtensionPoints/trac.perm.IPermissionPolicy IPermissionPolicy] and [wiki:TracDev/PluginDevelopment/ExtensionPoints/trac.perm.IPermissionRequestor IPermissionRequestor]: {{{#!python # -*- coding: utf-8 -*- # # Copyright (C) 2014 Edgewall Software # All rights reserved. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms # are also available at http://trac.edgewall.org/wiki/TracLicense. # # This software consists of voluntary contributions made by many # individuals. For the exact contribution history, see the revision # history and logs, available at http://trac.edgewall.org/log/. from trac.core import * from trac.perm import IPermissionPolicy, IPermissionRequestor from trac.ticket.model import Ticket class RestrictTicketActionsPolicy(Component): """Provides a permission for restricting ticket actions to the ticket owner. """ implements(IPermissionPolicy, IPermissionRequestor) # IPermissionRequestor methods def get_permission_actions(self): return ['TICKET_CHANGE_STATE'] # IPermissionPolicy methods def check_permission(self, action, username, resource, perm): if action == 'TICKET_CHANGE_STATE' and \ resource is not None and \ resource.realm == 'ticket' and \ resource.id is not None: ticket = Ticket(self.env, resource.id) return ticket['owner'] == username return None }}} 1. Edit the `permission_policies` option in the [TracIni#trac-section "[trac]"] section of trac.ini, adding the component ''before'' the default [TracPermissions permission] policy: {{{#!ini [trac] permission_policies = RestrictTicketActions, ... }}} 1. Require `TICKET_CHANGE_STATE` for one or more workflow actions. For example, the [TracWorkflow#Environmentscreatedwith0.11 default workflow] could be modified so that only the ticket owner can assign tickets: {{{#!diff -reassign.permissions = TICKET_MODIFY +reassign.permissions = TICKET_CHANGE_STATE }}} 1. Grant the `TICKET_CHANGE_STATE` permission to your users. == Grant a permission to the Ticket Owner This permissions policy can be used to grant permissions to the ticket's owner. To install and activate the plugin: 1. Create a [TracDev/PluginDevelopment#Singlefileplugins single file plugin] that implements [wiki:TracDev/PluginDevelopment/ExtensionPoints/trac.perm.IPermissionPolicy IPermissionPolicy]: {{{#!python # -*- coding: utf-8 -*- # # Copyright (C) 2014 Edgewall Software # All rights reserved. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms # are also available at http://trac.edgewall.org/wiki/TracLicense. # # This software consists of voluntary contributions made by many # individuals. For the exact contribution history, see the revision # history and logs, available at http://trac.edgewall.org/log/. from trac.core import * from trac.perm import IPermissionPolicy from trac.ticket.model import Ticket class GrantTicketOwnerPermissionsPolicy(Component): """Grants permissions to the ticket owner.""" implements(IPermissionPolicy) allowed_actions = ( 'TICKET_CHGPROP', 'TICKET_EDIT_CC', 'TICKET_EDIT_DESCRIPTION', 'TICKET_EDIT_COMMENT') # IPermissionPolicy methods def check_permission(self, action, username, resource, perm): if action in self.allowed_actions and \ resource is not None and \ resource.realm == 'ticket' and \ resource.id is not None: ticket = Ticket(self.env, resource.id) if ticket['owner'] == username: return True return None }}} 1. Edit the `permission_policies` option in the [TracIni#trac-section "[trac]"] section of trac.ini, adding the component ''before'' the default [TracPermissions permission] policy: {{{#!ini [trac] permission_policies = GrantTicketOwnerPermissionsPolicy, ... }}} ==== Variations * Remove permissions from the `allowed_actions` or add others. * Change `ticket['owner']` to `ticket['reporter']` to grant the permissions to the Ticket Reporter instead. == Support Desk Policy This permission policy allows users to view only tickets they have reported. To install and activate the plugin: 1. Create a [TracDev/PluginDevelopment#Singlefileplugins single file plugin] that implements [wiki:TracDev/PluginDevelopment/ExtensionPoints/trac.perm.IPermissionPolicy IPermissionPolicy]: {{{#!python # -*- coding: utf-8 -*- # # Copyright (C) 2017 Edgewall Software # All rights reserved. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms # are also available at http://trac.edgewall.org/wiki/TracLicense. # # This software consists of voluntary contributions made by many # individuals. For the exact contribution history, see the revision # history and logs, available at http://trac.edgewall.org/log/. from trac.core import * from trac.perm import IPermissionPolicy, IPermissionRequestor from trac.ticket.model import Ticket class SupportDeskPolicy(Component): """Provides a permission for restricting ticket actions to the ticket owner. """ implements(IPermissionPolicy, IPermissionRequestor) # IPermissionRequestor methods def get_permission_actions(self): return ['TICKET_VIEW_REPORTED'] # IPermissionPolicy methods def check_permission(self, action, username, resource, perm): if username != 'anonymous' and \ action == 'TICKET_VIEW' and \ resource is not None and \ resource.realm == 'ticket' and \ resource.id is not None and \ 'TICKET_VIEW_REPORTED' in perm: ticket = Ticket(self.env, resource.id) return ticket['reporter'] == username }}} 1. Revoke `TICKET_VIEW` and grant `TICKET_VIEW_REPORTED` for users that should only view tickets they reported. 1. Grant other permissions such as `TICKET_CHGPROP`, `TICKET_APPEND` or `TICKET_MODIFY`. Users can only change tickets they can view, therefore you'll only be granting these permissions for tickets the user reported. ---- See also: [CookBook/Configuration/SignedTickets#Readonlylogic ReadonlySignedTickets policy], [gmessage:trac-users:0XDa9f9fAos/PFsiA32GLJAJ mailing list discussion] about !RestrictTicketActionsPolicy