| 204 | == Restrict Tickets Per Milestone |
| 205 | |
| 206 | Milestones access can be restricted per-milestone using [TracFineGrainedPermissions#AuthzPolicy AuthzPolicy]. |
| 207 | This permission policy further allows users to only |
| 208 | view tickets that are assigned to viewable milestones. |
| 209 | |
| 210 | To install and activate the plugin: |
| 211 | 1. Create a [TracDev/PluginDevelopment#Singlefileplugins single file plugin] that implements [wiki:TracDev/PluginDevelopment/ExtensionPoints/trac.perm.IPermissionPolicy IPermissionPolicy]: |
| 212 | {{{#!python |
| 213 | # -*- coding: utf-8 -*- |
| 214 | # |
| 215 | # Copyright (C) 2019 Edgewall Software |
| 216 | # All rights reserved. |
| 217 | # |
| 218 | # This software is licensed as described in the file COPYING, which |
| 219 | # you should have received as part of this distribution. The terms |
| 220 | # are also available at https://trac.edgewall.org/wiki/TracLicense. |
| 221 | # |
| 222 | # This software consists of voluntary contributions made by many |
| 223 | # individuals. For the exact contribution history, see the revision |
| 224 | # history and logs, available at https://trac.edgewall.org/log/. |
| 225 | |
| 226 | from trac.core import * |
| 227 | from trac.perm import IPermissionPolicy |
| 228 | from trac.resource import ResourceNotFound |
| 229 | from trac.ticket.model import Ticket |
| 230 | |
| 231 | |
| 232 | class TicketMilestonePolicy(Component): |
| 233 | """Provides a permission for restricting ticket access to |
| 234 | viewable milestones. |
| 235 | """ |
| 236 | |
| 237 | implements(IPermissionPolicy) |
| 238 | |
| 239 | # IPermissionPolicy methods |
| 240 | |
| 241 | def check_permission(self, action, username, resource, perm): |
| 242 | if action == 'TICKET_VIEW': |
| 243 | if resource is None or \ |
| 244 | resource.realm == 'ticket' and \ |
| 245 | resource.id is None: |
| 246 | return True |
| 247 | elif resource.realm == 'ticket' and \ |
| 248 | resource.id is not None: |
| 249 | try: |
| 250 | ticket = Ticket(self.env, resource.id) |
| 251 | except ResourceNotFound: |
| 252 | pass |
| 253 | else: |
| 254 | return 'MILESTONE_VIEW' in perm('milestone', |
| 255 | ticket['milestone']) |
| 256 | |
| 257 | }}} |
| 258 | 1. Edit [[TracIni#trac-permission_policies-option|[trac] permission_policies]] in trac.ini, adding the `TicketMilestonePolicy` and `AuthzPolicy` components ''before'' the default [TracPermissions permission] policy: |
| 259 | {{{#!ini |
| 260 | [trac] |
| 261 | permission_policies = TicketMilestonePolicy, AuthzPolicy, ... |
| 262 | }}} |
| 263 | 1. Revoke the coarse-grained `MILESTONE_VIEW` and configure [TracFineGrainedPermissions#AuthzPolicy AuthzPolicy] with a policy that grants `MILESTONE_VIEW` per milestone-resource: |
| 264 | {{{#!ini |
| 265 | [milestone:milestone1] |
| 266 | user1 = MILESTONE_VIEW |
| 267 | |
| 268 | [milestone:milestone2] |
| 269 | user2 = MILESTONE_VIEW |
| 270 | }}} |
| 271 | 1. Grant `TICKET_VIEW` to any users that you wish to view some (but not necessarily all) tickets. The `TicketMilestonePolicy` will deny access to a ticket if the users isn't allowed to view the associated milestone for the ticket, even though the user has coarse-grained `TICKET_VIEW`. |
| 272 | 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 assigned to milestones they can view. |
| 273 | |