ejucovy avatar ejucovy committed 9221bb2

configurable ticket_clone_permission setting (defaults to TICKET_ADMIN)

Comments (0)

Files changed (2)

 The NewTicketLikeThisPlugin adds a "Clone" button to existing tickets,
 which lets you create a new ticket whose fields derive from the original
-ticket if you have the TICKET_ADMIN permission.
+ticket if you have the appropriate permission.
 It is based on the tracopt.ticket.clone.ticketclonebutton extension that
 ships with Trac core.  Unlike that extension, the NewTicketLikeThisPlugin
 defines and consumes a pluggable interface for implementing custom policies
 to determine the way in which a new ticket is derived from the original.
 This allows flexible, customized business logic to be provided based on
-the needs and workflows of your team.
+the needs and workflows of your team.  Also, the NewTicketLikeThisPlugin
+allows you to configure the permission required to clone a ticket, whereas
+the core ``ticketclonebutton`` hard-codes the TICKET_ADMIN permission.
 Two policies are provided by default, in the ``newticketlikethis.policies`` 
 By default this will add the "Clone" button to the ticket view, and 
 will use the ``SimpleTicketCloner`` component to clone your tickets.
+The ``TICKET_ADMIN`` permission will be required for cloning tickets.
+=== Choosing a policy ===
 To use a different ticket-cloning policy, make sure to enable any
 necessary components and then set the ``newticketlikethis.ticket_cloner``
 ticket_cloner = ExcludedFieldsTicketCloner
+=== Configuring permissions ===
+By default the "Clone" button only appears if the user has the 
+``TICKET_ADMIN`` permission.  You can change the required permission
+using the ``newticketlikethis.ticket_clone_permission`` option:
+ticket_clone_permission = TICKET_CREATE
 === ExcludedFieldsTicketCloner ===
 If enabled, the ``ExcludedFieldsTicketCloner`` will look for an additional


 from genshi.builder import tag
 from genshi.filters import Transformer
-from trac.config import ExtensionOption
+from trac.config import ExtensionOption, Option
 from trac.core import Component, Interface, implements
 from trac.web.api import ITemplateStreamFilter
 from trac.util.translation import _
                                     """Name of the component implementing `ITicketCloner`, which provides the logic for building a new ticket from an existing one.""")
+    ticket_clone_permission = Option('newticketlikethis', 'ticket_clone_permission', 'TICKET_ADMIN',
+                                     """The permission required for the "Clone" button to appear on the ticket detail page""")
     # ITemplateStreamFilter methods
     def filter_stream(self, req, method, filename, stream, data):
         if filename == 'ticket.html':
             ticket = data.get('ticket')
             if ticket and ticket.exists and \
-                    'TICKET_ADMIN' in req.perm(ticket.resource):
+                    self.ticket_clone_permission in req.perm(ticket.resource):
                 filter = Transformer('//h3[@id="comment:description"]')
                 stream |= filter.after(self._clone_form(req, ticket, data))
         return stream
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.