Read only ticket according to custom resolution type

141 views
Skip to first unread message

Jared Bownds

unread,
Jul 26, 2014, 7:33:16 PM7/26/14
to trac-...@googlegroups.com
Reference:  http://trac-hacks.org/ticket/11885

I am looking for a solution that will work like this:
  • Create a new permission group called SIGNER
  • Add 'signed' as a resolution type
  • Users with permission SIGNER are allowed to resolve a request as 'Signed'
Desired behavior:
  • Once a ticket is resolved as 'Signed', the ticket is now read only except to TRAC_ADMIN
  • Users without TRAC_ADMIN permissions are unable to modify the ticket in any way. When an attempt is made, the user should receive an error upon save indicating the ticket is signed and therefore read only.
  • Visually distinguish tickets resolved as 'Signed' by either slightly changing the color of the description body, or add a draft style 'SIGNED' watermark to the right and left side of the description body.

Olemis Lang

unread,
Jul 26, 2014, 8:06:35 PM7/26/14
to trac-...@googlegroups.com
On 7/26/14, Jared Bownds <jared....@gmail.com> wrote:
> Reference: http://trac-hacks.org/ticket/11885
>
> I am looking for a solution that will work like this:
>
> - Create a new permission group called SIGNER
> - Add 'signed' as a resolution type
> - Users with permission SIGNER are allowed to resolve a request as
> 'Signed'
>
> Desired behavior:
>
> - Once a ticket is resolved as 'Signed', the ticket is now read only
> except to TRAC_ADMIN
> - Users without TRAC_ADMIN permissions are unable to modify the ticket
> in any way. When an attempt is made, the user should receive an error
> upon
> save indicating the ticket is signed and therefore read only.

I'm not sure of whether a plugin provides this behavior OOTB , but if
not , it is possible to get this done by implementing a custom
IPermissionPolicy (... and enabling it in trac.ini , of course ;) .
IMHO that's the way to go , al least as a last recourse .

[...]

--
Regards,

Olemis - @olemislc

Apache(tm) Bloodhound contributor
http://issues.apache.org/bloodhound
http://blood-hound.net

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:

Jared Bownds

unread,
Jul 26, 2014, 8:15:17 PM7/26/14
to trac-...@googlegroups.com
From the research I've done so far, there is presently no plugin that offers the permission functionality, or the visual indication according to resolution type i.e. 'SIGNED'.

With regards to a custom permission policy, I'd be interested in learning how to implement it to achieve the desired behavior.

parvin...@yahoo.in

unread,
Jul 27, 2014, 2:38:04 AM7/27/14
to trac-...@googlegroups.com

restore

Sent from Yahoo Mail on Android



From: Jared Bownds <jared....@gmail.com>;
To: <trac-...@googlegroups.com>;
Subject: [Trac] Read only ticket according to custom resolution type
Sent: Sat, Jul 26, 2014 11:33:16 PM

--
You received this message because you are subscribed to the Google Groups "Trac Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Peter Suter

unread,
Jul 27, 2014, 3:46:04 AM7/27/14
to trac-...@googlegroups.com
Hi

On 27.07.2014 01:33, Jared Bownds wrote:
> * Once a ticket is resolved as 'Signed', the ticket is now read only
> except to TRAC_ADMIN

Custom code for that part might look something like this:

{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
implements(IPermissionPolicy)

def check_permission(self, action, username, resource, perm):
if resource is None or resource.realm != 'ticket' or \
resource.id is None or action == 'TICKET_VIEW' or \
'TRAC_ADMIN' in perm:
return None

t = Ticket(self.env, resource.id)
if t['resolution'] == 'Signed':
return False
}}}


See
http://trac.edgewall.org/wiki/TracDev/PluginDevelopment/ExtensionPoints/trac.perm.IPermissionPolicy

Jared Bownds

unread,
Jul 27, 2014, 1:58:20 PM7/27/14
to trac-...@googlegroups.com
Hi Peter,

thanks for contributing.  Would this bit of code be implemented in perm.py?  Any tips you can provide to help me implement this functionality would be greatly appreciated.

Best,

-Jared

Jared Bownds

unread,
Jul 27, 2014, 2:10:11 PM7/27/14
to trac-...@googlegroups.com
I do see how this bit of code matches the requisites for a plugin, however I don't have experience using setup tools to accomplish this task.  I do however have setup tools installed.  Nevertheless, practical steps would be extremely appreciated!

Resources:


--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.

To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.



--

Jared Bownds

unread,
Jul 27, 2014, 2:33:28 PM7/27/14
to trac-...@googlegroups.com
Okay, I've made some progress, and I want to include that progress so others can come up to speed quicker on the 'basics'.

Here is what I have done so far:
  1. Create a file called setup.py
  2. Create a file called ReadonlySignedTickets.py  (contents of both .py files are below)
  3. Install setup tools
  4. place both aforementioned .py files in the same arbitrary directory and run python setup.py bdist_egg
  5. The aforementioned command created a .egg file in a new directory called dist
  6. Copy the .egg file from dist to the plugin directory of my trac install
At this stage, what should the next steps be?


Contents of setup.py
from setuptools import setup, find_packages
setup(name='ReadonlySignedTickets',
      version='1.0',
      packages = find_packages(),
      )

Contents of ReadonlySignedTickets.py
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \
           'TRAC_ADMIN' in perm:
            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'Signed':
            return False

Ryan Ollos

unread,
Jul 27, 2014, 2:39:43 PM7/27/14
to trac-...@googlegroups.com
On Sun, Jul 27, 2014 at 11:09 AM, Jared Bownds <jared....@gmail.com> wrote:
I do see how this bit of code matches the requisites for a plugin, however I don't have experience using setup tools to accomplish this task.  I do however have setup tools installed.  Nevertheless, practical steps would be extremely appreciated!

Resources:

You can create a package if you like, but that is certainly not a requirement. You can also just put the code in a file with a name of your choosing, placing it in your environment's `plugins` directory.

For creating a package, the EggCookingTutorial might help you: http://trac-hacks.org/wiki/EggCookingTutorial

Olemis Lang

unread,
Jul 27, 2014, 2:41:37 PM7/27/14
to trac-...@googlegroups.com
On 7/27/14, Jared Bownds <jared....@gmail.com> wrote:
> I do see how this bit of code matches the requisites for a plugin, however
> I don't have experience using setup tools to accomplish this task. I do
> however have setup tools installed. Nevertheless, practical steps would be
> extremely appreciated!
>

The fastest path would be to write a single .py file and add it in
environment's /plugins folder .

[...]

--
Regards,

Olemis - @olemislc

Apache(tm) Bloodhound contributor
http://issues.apache.org/bloodhound
http://blood-hound.net

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:



Google Groups

Jared Bownds

unread,
Jul 27, 2014, 3:23:06 PM7/27/14
to trac-...@googlegroups.com
Thanks Ryan and Olemis,

What steps are necessary to ensure the plugin is actively being considered by Trac?  Do I need to make any modifications to the trac.ini?
--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.


--

Jared Bownds
m. 916.224.2324
e. Jared....@gmail.com

Ryan Ollos

unread,
Jul 27, 2014, 6:40:02 PM7/27/14
to trac-...@googlegroups.com
On Sun, Jul 27, 2014 at 12:22 PM, Jared Bownds <jared....@gmail.com> wrote:
Thanks Ryan and Olemis,

What steps are necessary to ensure the plugin is actively being considered by Trac?  Do I need to make any modifications to the trac.ini?

The easiest route is to look on the plugin admin page and enable the plugin from there if it's not already enabled. At least in a dev environment, plugins in the `plugins` directory are enabled by default. 

Jared Bownds

unread,
Jul 27, 2014, 7:02:24 PM7/27/14
to trac-...@googlegroups.com
Hi Ryan,

Thanks for the feedback, i'm now confident ReadonlySignedTickets.py is enabled as a plugin.

I've run a few tests on the code below.  I created a user called temp1 that does not have TRAC_ADMIN privileges.  Also, I created a request (#1968) and resolved it as signed.  While the permissions feedback provided by the trac log indicates the user does not have the necessary permissions to comment on the ticket, I am still able to modify the request as user temp1.  I would appreciate feedback on ReadonlySignedTickets.py to try and identify why the desired behavior is not functioning.

Contents below: 
  • Installed Plugins
  • ReadonlySignedTickets.py
  • Trac Log


Installed Plugins

Inline image 2

ReadonlySignedTickets.py

{{{ 
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \
           'TRAC_ADMIN' in perm:
            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'Signed':
            return False
}}}

Trac Log

2014-07-27 15:46:45,022 Trac[main] DEBUG: Dispatching <RequestWithSession "POST '/ticket/1968'">
2014-07-27 15:46:45,025 Trac[session] DEBUG: Retrieving session for ID u'temp1'
2014-07-27 15:46:45,032 Trac[main] DEBUG: Negotiated locale: None -> en_US
2014-07-27 15:46:45,049 Trac[blackmagic] DEBUG: Validating ticket: 1968
2014-07-27 15:46:45,049 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADD_HOURS', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:45,049 Trac[blackmagic] DEBUG: Checking permission TICKET_ADD_HOURS
2014-07-27 15:46:45,049 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADD_HOURS on <Resource u'ticket:1968'>
2014-07-27 15:46:45,050 Trac[blackmagic] DEBUG: totalhours disabled or hidden
2014-07-27 15:46:45,054 Trac[blackmagic] DEBUG: OT: 0
2014-07-27 15:46:45,054 Trac[blackmagic] DEBUG: NEW: 0
2014-07-27 15:46:45,054 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TRAC_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:45,055 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:45,055 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:45,055 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADMIN on <Resource u'ticket:1968'>
2014-07-27 15:46:45,056 Trac[blackmagic] DEBUG: component disabled or hidden
2014-07-27 15:46:45,060 Trac[blackmagic] DEBUG: OT: General Requests
2014-07-27 15:46:45,060 Trac[blackmagic] DEBUG: NEW: General Requests
2014-07-27 15:46:45,060 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:45,060 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:45,061 Trac[blackmagic] DEBUG: priority disabled or hidden
2014-07-27 15:46:45,065 Trac[blackmagic] DEBUG: OT: High
2014-07-27 15:46:45,065 Trac[blackmagic] DEBUG: NEW: High
2014-07-27 15:46:45,065 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:45,066 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:45,066 Trac[blackmagic] DEBUG: parents disabled or hidden
2014-07-27 15:46:45,070 Trac[blackmagic] DEBUG: OT:
2014-07-27 15:46:45,070 Trac[blackmagic] DEBUG: NEW:
2014-07-27 15:46:45,071 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': '', 'tip': u'Unless you know who should own this ticket, please leave this field default.', 'label': None, 'ondenial': 'disable', 'disable': False}
2014-07-27 15:46:45,071 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADD_HOURS', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:45,071 Trac[blackmagic] DEBUG: Checking permission TICKET_ADD_HOURS
2014-07-27 15:46:45,071 Trac[blackmagic] DEBUG: estimatedhours disabled or hidden
2014-07-27 15:46:45,076 Trac[blackmagic] DEBUG: OT: 0
2014-07-27 15:46:45,076 Trac[blackmagic] DEBUG: NEW: 0
2014-07-27 15:46:45,076 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:45,077 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:45,077 Trac[blackmagic] DEBUG: type disabled or hidden
2014-07-27 15:46:45,081 Trac[blackmagic] DEBUG: OT: Task
2014-07-27 15:46:45,081 Trac[blackmagic] DEBUG: NEW: Task
2014-07-27 15:46:45,090 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADD_HOURS on None
2014-07-27 15:46:45,114 Trac[notification] INFO: Sending notification through SMTP at exsmtp.na.bayer.cnb:25 to [u'jared....@bayer.com', u'te...@bayer.com']
2014-07-27 15:46:45,983 Trac[web_ui] DEBUG: Side effect for ConfigurableTicketWorkflow
2014-07-27 15:46:46,656 Trac[main] DEBUG: Dispatching <RequestWithSession "GET '/ticket/1968'">
2014-07-27 15:46:46,659 Trac[session] DEBUG: Retrieving session for ID u'temp1'
2014-07-27 15:46:46,665 Trac[main] DEBUG: Negotiated locale: None -> en_US
2014-07-27 15:46:46,686 Trac[default_workflow] DEBUG: render_ticket_action_control: action "leave"
2014-07-27 15:46:46,687 Trac[default_workflow] DEBUG: render_ticket_action_control: action "reopen"
2014-07-27 15:46:46,694 Trac[chrome] DEBUG: Prepare chrome data for request
2014-07-27 15:46:46,697 Trac[perm] DEBUG: No policy allowed temp1 performing ACCTMGR_CONFIG_ADMIN on None
2014-07-27 15:46:46,697 Trac[perm] DEBUG: No policy allowed temp1 performing ACCTMGR_USER_ADMIN on None
2014-07-27 15:46:46,697 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADMIN on None
2014-07-27 15:46:46,698 Trac[perm] DEBUG: No policy allowed temp1 performing REPORT_ADMIN on None
2014-07-27 15:46:46,698 Trac[perm] DEBUG: No policy allowed temp1 performing TRAC_ADMIN on None
2014-07-27 15:46:46,698 Trac[perm] DEBUG: No policy allowed temp1 performing PERMISSION_GRANT on None
2014-07-27 15:46:46,699 Trac[perm] DEBUG: No policy allowed temp1 performing PERMISSION_REVOKE on None
2014-07-27 15:46:46,699 Trac[perm] DEBUG: No policy allowed temp1 performing MILESTONE_VIEW on None
2014-07-27 15:46:46,699 Trac[perm] DEBUG: No policy allowed temp1 performing VERSIONCONTROL_ADMIN on None
2014-07-27 15:46:46,701 Trac[perm] DEBUG: No policy allowed temp1 performing ROADMAP_VIEW on None
2014-07-27 15:46:46,701 Trac[perm] DEBUG: No policy allowed temp1 performing TIMELINE_VIEW on None
2014-07-27 15:46:46,702 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_VIEW_HOURS on None
2014-07-27 15:46:46,706 Trac[blackmagic] DEBUG: Checking ticket permissions  for type Enhancement
2014-07-27 15:46:46,707 Trac[blackmagic] DEBUG: User temp1 has permission
2014-07-27 15:46:46,707 Trac[blackmagic] DEBUG: Checking ticket permissions  for type Defect
2014-07-27 15:46:46,707 Trac[blackmagic] DEBUG: User temp1 has permission
2014-07-27 15:46:46,707 Trac[blackmagic] DEBUG: Checking ticket permissions  for type Task
2014-07-27 15:46:46,707 Trac[blackmagic] DEBUG: User temp1 has permission
2014-07-27 15:46:46,709 Trac[blackmagic] DEBUG: Permissions TICKET_ADD_HOURS
2014-07-27 15:46:46,709 Trac[blackmagic] DEBUG: Checking permission TICKET_ADD_HOURS
2014-07-27 15:46:46,709 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADD_HOURS on <Resource u'ticket:1968'>
2014-07-27 15:46:46,711 Trac[blackmagic] DEBUG: Permissions TRAC_ADMIN
2014-07-27 15:46:46,711 Trac[blackmagic] DEBUG: Checking permission TRAC_ADMIN
2014-07-27 15:46:46,711 Trac[perm] DEBUG: No policy allowed temp1 performing TRAC_ADMIN on <Resource u'ticket:1968'>
2014-07-27 15:46:46,712 Trac[blackmagic] DEBUG: Permissions TICKET_ADMIN
2014-07-27 15:46:46,713 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:46,713 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADMIN on <Resource u'ticket:1968'>
2014-07-27 15:46:46,714 Trac[blackmagic] DEBUG: Permissions TICKET_ADMIN
2014-07-27 15:46:46,714 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:46,716 Trac[blackmagic] DEBUG: Permissions TICKET_ADMIN
2014-07-27 15:46:46,716 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:46,718 Trac[blackmagic] DEBUG: Permissions TICKET_ADD_HOURS
2014-07-27 15:46:46,718 Trac[blackmagic] DEBUG: Checking permission TICKET_ADD_HOURS
2014-07-27 15:46:46,719 Trac[blackmagic] DEBUG: Permissions TICKET_ADMIN
2014-07-27 15:46:46,720 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:46,925 Trac[main] DEBUG: Dispatching <RequestWithSession "POST '/ticket/1968'">
2014-07-27 15:46:46,928 Trac[session] DEBUG: Retrieving session for ID u'temp1'
2014-07-27 15:46:46,936 Trac[main] DEBUG: Negotiated locale: None -> en_US
2014-07-27 15:46:46,940 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_EDIT_COMMENT on <Resource u'ticket:1968'>
2014-07-27 15:46:46,952 Trac[chrome] DEBUG: Prepare chrome data for request
2014-07-27 15:46:46,955 Trac[perm] DEBUG: No policy allowed temp1 performing ACCTMGR_CONFIG_ADMIN on None
2014-07-27 15:46:46,955 Trac[perm] DEBUG: No policy allowed temp1 performing ACCTMGR_USER_ADMIN on None
2014-07-27 15:46:46,955 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADMIN on None
2014-07-27 15:46:46,956 Trac[perm] DEBUG: No policy allowed temp1 performing REPORT_ADMIN on None
2014-07-27 15:46:46,956 Trac[perm] DEBUG: No policy allowed temp1 performing TRAC_ADMIN on None
2014-07-27 15:46:46,956 Trac[perm] DEBUG: No policy allowed temp1 performing PERMISSION_GRANT on None
2014-07-27 15:46:46,957 Trac[perm] DEBUG: No policy allowed temp1 performing PERMISSION_REVOKE on None
2014-07-27 15:46:46,957 Trac[perm] DEBUG: No policy allowed temp1 performing MILESTONE_VIEW on None
2014-07-27 15:46:46,957 Trac[perm] DEBUG: No policy allowed temp1 performing VERSIONCONTROL_ADMIN on None
2014-07-27 15:46:46,959 Trac[perm] DEBUG: No policy allowed temp1 performing ROADMAP_VIEW on None
2014-07-27 15:46:46,959 Trac[perm] DEBUG: No policy allowed temp1 performing TIMELINE_VIEW on None
2014-07-27 15:46:46,960 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_VIEW_HOURS on None
2014-07-27 15:46:46,960 Trac[blackmagic] DEBUG: Validating ticket: 1968
2014-07-27 15:46:46,961 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADD_HOURS', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:46,961 Trac[blackmagic] DEBUG: Checking permission TICKET_ADD_HOURS
2014-07-27 15:46:46,961 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADD_HOURS on <Resource u'ticket:1968'>
2014-07-27 15:46:46,962 Trac[blackmagic] DEBUG: totalhours disabled or hidden
2014-07-27 15:46:46,966 Trac[blackmagic] DEBUG: OT: 0
2014-07-27 15:46:46,966 Trac[blackmagic] DEBUG: NEW: 0
2014-07-27 15:46:46,966 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TRAC_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:46,967 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:46,967 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:46,967 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADMIN on <Resource u'ticket:1968'>
2014-07-27 15:46:46,967 Trac[blackmagic] DEBUG: component disabled or hidden
2014-07-27 15:46:46,972 Trac[blackmagic] DEBUG: OT: General Requests
2014-07-27 15:46:46,972 Trac[blackmagic] DEBUG: NEW: General Requests
2014-07-27 15:46:46,972 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:46,972 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:46,973 Trac[blackmagic] DEBUG: priority disabled or hidden
2014-07-27 15:46:46,977 Trac[blackmagic] DEBUG: OT: High
2014-07-27 15:46:46,977 Trac[blackmagic] DEBUG: NEW: High
2014-07-27 15:46:46,977 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:46,978 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:46,978 Trac[blackmagic] DEBUG: parents disabled or hidden
2014-07-27 15:46:46,982 Trac[blackmagic] DEBUG: OT:
2014-07-27 15:46:46,982 Trac[blackmagic] DEBUG: NEW:
2014-07-27 15:46:46,983 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': '', 'tip': u'Unless you know who should own this ticket, please leave this field default.', 'label': None, 'ondenial': 'disable', 'disable': False}
2014-07-27 15:46:46,983 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADD_HOURS', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:46,983 Trac[blackmagic] DEBUG: Checking permission TICKET_ADD_HOURS
2014-07-27 15:46:46,983 Trac[blackmagic] DEBUG: estimatedhours disabled or hidden
2014-07-27 15:46:46,988 Trac[blackmagic] DEBUG: OT: 0
2014-07-27 15:46:46,988 Trac[blackmagic] DEBUG: NEW: 0
2014-07-27 15:46:46,988 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-27 15:46:46,989 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-27 15:46:46,989 Trac[blackmagic] DEBUG: type disabled or hidden
2014-07-27 15:46:46,993 Trac[blackmagic] DEBUG: OT: Task
2014-07-27 15:46:46,994 Trac[blackmagic] DEBUG: NEW: Task
2014-07-27 15:46:47,002 Trac[default_workflow] DEBUG: render_ticket_action_control: action "leave"
2014-07-27 15:46:47,002 Trac[default_workflow] DEBUG: render_ticket_action_control: action "reopen"
2014-07-27 15:46:47,014 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_EDIT_COMMENT on <Resource u'ticket:1968'>


--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.



--

Peter Suter

unread,
Jul 28, 2014, 1:49:18 AM7/28/14
to trac-...@googlegroups.com
On 28.07.2014 01:01, Jared Bownds wrote:
> Thanks for the feedback, i'm now confident ReadonlySignedTickets.py is
> enabled as a plugin.
>
> I've run a few tests on the code below. I created a user called temp1
> that does not have TRAC_ADMIN privileges. Also, I created a request
> (#1968) and resolved it as signed. While the permissions feedback
> provided by the trac log indicates the user does not have the necessary
> permissions to comment on the ticket, I am still able to modify the
> request as user temp1. I would appreciate feedback on
> ReadonlySignedTickets.py to try and identify why the desired behavior is
> not functioning.

Permission policy plugins also need to be listed in the trac.ini config
file under [trac] permission_policies. For example if you previously
only had the current default policies, add ReadonlySignedTickets to the
front of the list:

[trac]
permission_policies = ReadonlySignedTickets, ReadonlyWikiPolicy,
DefaultPermissionPolicy, LegacyAttachmentPolicy

(Note that the order can be important!)

Hope this helps.

[1]
http://trac.edgewall.org/wiki/TracDev/PluginDevelopment/ExtensionPoints/trac.perm.IPermissionPolicy#Usage
[2]
http://trac.edgewall.org/wiki/TracFineGrainedPermissions#PermissionPolicies

RjOllos

unread,
Jul 28, 2014, 2:55:27 AM7/28/14
to trac-...@googlegroups.com


On Sunday, July 27, 2014 10:49:18 PM UTC-7, Peter Suter wrote:
On 28.07.2014 01:01, Jared Bownds wrote:
> Thanks for the feedback, i'm now confident ReadonlySignedTickets.py is
> enabled as a plugin.
>
> I've run a few tests on the code below.  I created a user called temp1
> that does not have TRAC_ADMIN privileges.  Also, I created a request
> (#1968) and resolved it as signed.  While the permissions feedback
> provided by the trac log indicates the user does not have the necessary
> permissions to comment on the ticket, I am still able to modify the
> request as user temp1.  I would appreciate feedback on
> ReadonlySignedTickets.py to try and identify why the desired behavior is
> not functioning.

Permission policy plugins also need to be listed in the trac.ini config
file under [trac] permission_policies. For example if you previously
only had the current default policies, add ReadonlySignedTickets to the
front of the list:

[trac]
permission_policies = ReadonlySignedTickets, ReadonlyWikiPolicy,
DefaultPermissionPolicy, LegacyAttachmentPolicy

(Note that the order can be important!)

Hope this helps.

I'm encountering the dreaded issue: RuntimeError: maximum recursion depth exceeded while calling a Python object

The issue seems to be with the check: 'TRAC_ADMIN' in perm.

I tried reworking the conditional checks in various ways, such as making it look as close as possible to SecurityTicketsPolicy:
http://trac.edgewall.org/browser/trunk/sample-plugins/permissions/vulnerability_tickets.py

Btw, in vulnerable_tickets.py, should the check be changed?:
if 'VULNERABILITY_VIEW' not in perm:
->

if 'VULNERABILITY_VIEW' not in perm(resource):

Jared Bownds

unread,
Jul 28, 2014, 10:22:01 AM7/28/14
to trac-...@googlegroups.com
I'm receiving the same error.  It can be reproduced by navigating to the any ticket



--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Steffen Hoffmann

unread,
Jul 28, 2014, 11:46:15 AM7/28/14
to trac-...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 28.07.2014 08:55, RjOllos wrote:
> Btw, in vulnerable_tickets.py, should the check be changed?:
> if 'VULNERABILITY_VIEW' not in perm:
> ->
>
> if 'VULNERABILITY_VIEW' not in perm(resource):

It depends on the intention. From earlier discussion I remember, that
recommended, performance conscious practice of Trac permission checking
involves a rather cheep pre-check, if the required permission is
assigned to the SID at all. That's what the first line would be good for.

The suggested replacement does the fine-grained check, that required the
resource object.
I've been testing with 'only' 30.000+ tickets in my Trac development
environment to learn, that constructing resource objects IS a costly
task that shall be avoided, if possible.

Just my 2 cents.

Steffen Hoffmann
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iEYEARECAAYFAlPWcDoACgkQ31DJeiZFuHfkdgCg1mOSo/WP+SIhnFbOQgAoomac
GpsAnA3jTWSLj6fkz5E+3+6IrnwQqBVd
=UsxY
-----END PGP SIGNATURE-----

Peter Suter

unread,
Jul 28, 2014, 1:38:48 PM7/28/14
to trac-...@googlegroups.com
On 28.07.2014 08:55, RjOllos wrote:
> I'm encountering the dreaded issue: RuntimeError: maximum recursion
> depth exceeded while calling a Python object
>
> The issue seems to be with the check: 'TRAC_ADMIN' in perm.

Oops, right. I think adding `action == 'TRAC_ADMIN'` to the check
(before the `'TRAC_ADMIN' in perm` recursion) should be both sufficient
to stop the recursion and correct in the non-recursive case:

{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
implements(IPermissionPolicy)

def check_permission(self, action, username, resource, perm):
if resource is None or resource.realm != 'ticket' or \
resource.id is None or action == 'TICKET_VIEW' or \
action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:
return None

t = Ticket(self.env, resource.id)
return False
}}}



> I tried reworking the conditional checks in various ways, such as making
> it look as close as possible to SecurityTicketsPolicy:
> http://trac.edgewall.org/browser/trunk/sample-plugins/permissions/vulnerability_tickets.py
>
> Btw, in vulnerable_tickets.py, should the check be changed?:
> if 'VULNERABILITY_VIEW' not in perm:
> ->
>
> if 'VULNERABILITY_VIEW' not in perm(resource):

Hm, subtle.

Usually in IPermissionPolicy `perm` should already be specific to the
checked resource, so `perm` is the same as `perm(resource)`.

But in SecurityTicketsPolicy resource might be changed to the parent
resource (i.e. the ticket) if it was initially a child resource (e.g. an
attachment). So here changing `perm` to `perm(resource)` would change
the logic: Instead of the current behaviour where VULNERABILITY_VIEW is
required on the child resource (attachment), it would be required on the
parent resource (ticket).

I guess for attachments (assuming the usual LegacyDelegate is used to
forward the check to the parent anyway) it makes no difference.

To me it sounds slightly better the way it is (require
VULNERABILITY_VIEW on the child resource), but I've not used
fine-grained permissions much.

Or am I on the wrong track? :)

Peter Suter

unread,
Jul 28, 2014, 1:56:22 PM7/28/14
to trac-...@googlegroups.com
Oops, and now I dropped the `if t['resolution'] == 'Signed':` test by
mistake..

{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
implements(IPermissionPolicy)

def check_permission(self, action, username, resource, perm):
if resource is None or resource.realm != 'ticket' or \
resource.id is None or action == 'TICKET_VIEW' or \
action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:
return None

t = Ticket(self.env, resource.id)

Jared Bownds

unread,
Jul 28, 2014, 1:56:37 PM7/28/14
to trac-...@googlegroups.com
You nailed it!  The code below works.  However, users are still able to 'edit' their own comments once a ticket is resolved as signed.   

{{{
--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+unsubscribe@googlegroups.com.

To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Jared Bownds

unread,
Jul 28, 2014, 2:27:15 PM7/28/14
to trac-...@googlegroups.com
Peter,

Should this be included, or excluded?  For clarity, please provide the entire block of code that should be used to implement the following behavior:
  • Once a ticket is resolved as 'Signed', the ticket is now read only except by TRAC_ADMIN

Next, how do we implement the desired error feedback outlined below?
  • Visually distinguish tickets resolved as 'Signed' by either slightly changing the color of the description body, or add a draft style 'SIGNED' watermark to the right and left side of the description body.
--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+unsubscribe@googlegroups.com.

To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Ryan Ollos

unread,
Jul 28, 2014, 2:31:56 PM7/28/14
to trac-...@googlegroups.com
On Mon, Jul 28, 2014 at 10:55 AM, Jared Bownds <jared....@gmail.com> wrote:
You nailed it!  The code below works.  However, users are still able to 'edit' their own comments once a ticket is resolved as signed.   

{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \
           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'signed':
            return False
}}}

Peter's plugin shown above work for me on 1.0-stable, and users aren't able to edit comments even if they have been granted TICKET_ADMIN. I used resolution //signed// rather than //Signed// since all of Trac's predefined resolutions are in lowercase.

Which Trac version are you running?

In order to implement your other requirements, it sounds like you'll want to:
 * Enable ExtraPermissionsProvider
   [components]
   tracopt.perm.config_perm_provider.extrapermissionsprovider = enabled

 * Add the signed permission:
   [extra-permissions]
   _perms = TICKET_SIGNED

 * Grant TICKET_SIGNED to the appropriate user.

 * Modify your workflow to only allow users with TICKET_SIGNED to resolve a ticket as signed. This is where things seem to get a bit tricky. You may need to have a workflow state signed rather than using a resolution, but that might not work since you probably want tickets to end in the closed state. You might need to implement a workflow action to replace set_resolution, which does permission checking to decide who can resolve a ticket as signed ... or perhaps the permission checking can be done in the ReadonlySignedTickets policy as well. I'll have to give that more thought.


 

Ryan Ollos

unread,
Jul 28, 2014, 3:00:15 PM7/28/14
to trac-...@googlegroups.com
On Mon, Jul 28, 2014 at 11:26 AM, Jared Bownds <jared....@gmail.com> wrote:
Next, how do we implement the desired error feedback outlined below?
  • Visually distinguish tickets resolved as 'Signed' by either slightly changing the color of the description body, or add a draft style 'SIGNED' watermark to the right and left side of the description body.

The following works for me:

2. Add site.html to your Environment templates directory: http://trac.edgewall.org/wiki/TracInterfaceCustomization#SiteAppearance (the first code snippet in that section is what you want to copy to site.html)
3. Add site.css to your Environment htdocs directory.
4. Add the following to site.css as a test case:
body.resolution_is_signed { background-color: #f5deb3; /* wheat */    }
5. Enabled ContextChromePlugin:
[components]
contextchrome.style.typeclasstoticket = enabled

Now you can add whatever CSS rules you want using the selector body.resolution_is_signed. For example, you could use any of the background properties: http://www.w3schools.com/css/css_background.asp

Jared Bownds

unread,
Jul 28, 2014, 4:04:13 PM7/28/14
to trac-...@googlegroups.com
Hi Ryan,


2. Add site.html to your Environment templates directory: http://trac.edgewall.org/wiki/TracInterfaceCustomization#SiteAppearance (the first code snippet in that section is what you want to copy to site.html)

Response:  Is this the code I want to add in site.html contained within my environments template directory?

site.html

      py:strip="">
  <!--! Add site-specific style sheet -->

  <head py:match="head" py:attrs="select('@*')">

    ${select('*|comment()|text()')}

    <link rel="stylesheet" type="text/css"

          href="${href.chrome('site/style.css')}" />

  </head>


  <body py:match="body" py:attrs="select('@*')">

    <!--! Add site-specific header -->
    <div id="siteheader">

      <!--! Place your header content here... -->
    </div>
    ${select('*|text()')}


    <!--! Add site-specific footer -->
    <div id="sitefooter">

      <!--! Place your footer content here... -->
    </div>
  </body>

</html>


4. Add the following to site.css as a test case:
body.resolution_is_signed { background-color: #f5deb3; /* wheat */    }

Response:  I've done this, and also tried variations such as body.resolution_is_closed and I am not seeing the desired results, with any color background i.e. #0000FF



--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.

To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Jared Bownds

unread,
Jul 28, 2014, 4:11:23 PM7/28/14
to trac-...@googlegroups.com, ryan.j...@gmail.com
Peter's plugin shown above work for me on 1.0-stable, and users aren't able to edit comments even if they have been granted TICKET_ADMIN. I used resolution //signed// rather than //Signed// since all of Trac's predefined resolutions are in lowercase.

I'm running version 1.0

On Monday, July 28, 2014 11:31:56 AM UTC-7, RjOllos wrote:
On Mon, Jul 28, 2014 at 10:55 AM, Jared Bownds <jared....@gmail.com> wrote:
You nailed it!  The code below works.  However, users are still able to 'edit' their own comments once a ticket is resolved as signed.   

{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \
           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'signed':
            return False
}}}

Peter's plugin shown above work for me on 1.0-stable, and users aren't able to edit comments even if they have been granted TICKET_ADMIN. I used resolution //signed// rather than //Signed// since all of Trac's predefined resolutions are in lowercase.

Which Trac version are you running?

I'm running version 1.0
 

Ryan Ollos

unread,
Jul 28, 2014, 4:16:36 PM7/28/14
to trac-...@googlegroups.com

That site.html looks correct.

I can assure you that the recipe does works since I tested it out, so we just have to debug where things went wrong in your setup. Do you see site.css on the ticket page when viewing the page source?

Jared Bownds

unread,
Jul 28, 2014, 4:27:19 PM7/28/14
to trac-...@googlegroups.com
Hi Ryan,

I'm using style.css, and it does show up in the source.

Inline image 1



--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Ryan Ollos

unread,
Jul 28, 2014, 4:34:34 PM7/28/14
to trac-...@googlegroups.com
On Mon, Jul 28, 2014 at 1:26 PM, Jared Bownds <jared....@gmail.com> wrote:
Hi Ryan,

I'm using style.css, and it does show up in the source.

The casing of "Signed" might cause an issue, but probably not.

I left out a step:

[ticket]
decorate_fields = resolution
 

Jared Bownds

unread,
Jul 28, 2014, 4:55:18 PM7/28/14
to trac-...@googlegroups.com
I left out a step:

[ticket]
decorate_fields = resolution

I added to trac.ini, it's still not working.  I'm at a loss as to why it's not working.

[ticket]
decorate_fields = resolution

Here is a snippet from the log

2014-07-28 13:53:09,218 Trac[main] DEBUG: Dispatching <RequestWithSession "GET '/chrome/site/style.css'">
2014-07-28 13:53:09,219 Trac[chrome] DEBUG: Prepare chrome data for request
2014-07-28 13:53:09,220 Trac[session] DEBUG: Retrieving session for ID u'jbownds'
2014-07-28 13:53:09,222 Trac[main] DEBUG: Negotiated locale: None -> en_US
2014-07-28 13:53:09,342 Trac[main] DEBUG: Dispatching <RequestWithSession "GET '/ticketvalidator.options'">
2014-07-28 13:53:09,343 Trac[chrome] DEBUG: Prepare chrome data for request
2014-07-28 13:53:09,345 Trac[session] DEBUG: Retrieving session for ID u'jbownds'
2014-07-28 13:53:09,347 Trac[main] DEBUG: Negotiated locale: None -> en_US



--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Jared Bownds

unread,
Jul 28, 2014, 5:05:38 PM7/28/14
to trac-...@googlegroups.com
Also, it turns out the this bit of code is not working.  I thought it was working, but it turns out the test user (temp1) was not authenticated.

Judging by the log, it seems as though everything is working as you would expect, temp1 should not be able to edit the request.  However, the update commits and subsequent notifications are sent.

ReadonlySignedTickets.py
{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \
           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'signed':
            return False
}}}

Trac Log
2014-07-28 14:02:15,937 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-28 14:02:15,938 Trac[blackmagic] DEBUG: type disabled or hidden
2014-07-28 14:02:15,942 Trac[blackmagic] DEBUG: OT: Task
2014-07-28 14:02:15,942 Trac[blackmagic] DEBUG: NEW: Task
2014-07-28 14:02:15,954 Trac[default_workflow] DEBUG: render_ticket_action_control: action "leave"
2014-07-28 14:02:15,954 Trac[default_workflow] DEBUG: render_ticket_action_control: action "reopen"
2014-07-28 14:02:15,974 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_EDIT_COMMENT on <Resource u'ticket:1969'>



--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.

To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Ryan Ollos

unread,
Jul 28, 2014, 5:06:00 PM7/28/14
to trac-...@googlegroups.com
On Mon, Jul 28, 2014 at 1:54 PM, Jared Bownds <jared....@gmail.com> wrote:
I left out a step:

[ticket]
decorate_fields = resolution

I added to trac.ini, it's still not working.  I'm at a loss as to why it's not working.

[ticket]
decorate_fields = resolution

Here is a snippet from the log

2014-07-28 13:53:09,218 Trac[main] DEBUG: Dispatching <RequestWithSession "GET '/chrome/site/style.css'">
2014-07-28 13:53:09,219 Trac[chrome] DEBUG: Prepare chrome data for request
2014-07-28 13:53:09,220 Trac[session] DEBUG: Retrieving session for ID u'jbownds'
2014-07-28 13:53:09,222 Trac[main] DEBUG: Negotiated locale: None -> en_US
2014-07-28 13:53:09,342 Trac[main] DEBUG: Dispatching <RequestWithSession "GET '/ticketvalidator.options'">
2014-07-28 13:53:09,343 Trac[chrome] DEBUG: Prepare chrome data for request
2014-07-28 13:53:09,345 Trac[session] DEBUG: Retrieving session for ID u'jbownds'
2014-07-28 13:53:09,347 Trac[main] DEBUG: Negotiated locale: None -> en_US


Does the opening body tag in the page have the class "resolution_is_signed"? If not, then look at whether ContextChromePlugin is loading. You should see it loaded with the log level at Debug and restarting Trac.

Jared Bownds

unread,
Jul 28, 2014, 5:21:37 PM7/28/14
to trac-...@googlegroups.com
I think your onto something, the plugin may not be loading.  Has anyone encountered this error before?  Also, I opened a ticket regarding the error.

http://trac-hacks.org/ticket/11889

Trac detected an internal error:

AttributeError: 'datetime.timedelta' object has no attribute 'total_seconds'


--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Ryan Ollos

unread,
Jul 28, 2014, 5:27:08 PM7/28/14
to trac-...@googlegroups.com
On Mon, Jul 28, 2014 at 2:20 PM, Jared Bownds <jared....@gmail.com> wrote:
I think your onto something, the plugin may not be loading.  Has anyone encountered this error before?  Also, I opened a ticket regarding the error.

http://trac-hacks.org/ticket/11889

Trac detected an internal error:
AttributeError: 'datetime.timedelta' object has no attribute 'total_seconds'

You can leave the DecayedWiki component disabled if you think it is causing problems. We just need to make sure the TypeClassToTicket component is enabled. I had the following:

[components]
contextchrome.cors.
crossoriginresourcesharingenabler = disabled
contextchrome.linkdeco.internalstylesheet = disabled
contextchrome.linkdeco.intertracticketlinkdecorator = disabled
contextchrome.linkdeco.ticketlinkdecorator = disabled
contextchrome.linkdeco.wikilinknewdecolator = disabled
contextchrome.style.typeclasstoticket = enabled
contextchrome.ticketvalidator.ticketvalidatordecolator = disabled
decayed.wiki.decayedwiki = disabled
 

Jared Bownds

unread,
Jul 28, 2014, 6:02:22 PM7/28/14
to trac-...@googlegroups.com
DevayedWiki was causing a problem, thanks for pointing that out - below is my configuration in trac.ini

I'm still not sure why it's not working.  Do you have any other ideas on what I can check?

[components]
contextchrome.cors.crossoriginresourcesharingenabler = disabled
contextchrome.linkdeco.internalstylesheet = disabled
contextchrome.linkdeco.intertracticketlinkdecorator = disabled
contextchrome.linkdeco.ticketlinkdecorator = disabled
contextchrome.linkdeco.wikilinknewdecolator = disabled
contextchrome.style.typeclasstoticket = enabled
contextchrome.ticketvalidator.ticketvalidatordecolator = disabled

--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Ryan Ollos

unread,
Jul 28, 2014, 6:16:48 PM7/28/14
to trac-...@googlegroups.com
On Mon, Jul 28, 2014 at 3:01 PM, Jared Bownds <jared....@gmail.com> wrote:
DevayedWiki was causing a problem, thanks for pointing that out - below is my configuration in trac.ini

I'm still not sure why it's not working.  Do you have any other ideas on what I can check?

[components]
contextchrome.cors.crossoriginresourcesharingenabler = disabled
contextchrome.linkdeco.internalstylesheet = disabled
contextchrome.linkdeco.intertracticketlinkdecorator = disabled
contextchrome.linkdeco.ticketlinkdecorator = disabled
contextchrome.linkdeco.wikilinknewdecolator = disabled
contextchrome.style.typeclasstoticket = enabled
contextchrome.ticketvalidator.ticketvalidatordecolator = disabled

Have you confirmed that the ContextChrome entry point is loading when Trac starts?

03:11:52 PM Trac[loader] DEBUG: Loading ContextChrome from /home/user/Workspace/trachacks.git/contextchromeplugin/0.12

Jared Bownds

unread,
Jul 28, 2014, 6:43:32 PM7/28/14
to trac-...@googlegroups.com
Is that not the following?

Trac[loader] DEBUG: Loading ContextChrome from /srv/trac/trac/plugins/ContextChrome-0.3-py2.6.egg




--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Ryan Ollos

unread,
Jul 28, 2014, 6:46:16 PM7/28/14
to trac-...@googlegroups.com
On Mon, Jul 28, 2014 at 3:42 PM, Jared Bownds <jared....@gmail.com> wrote:
Is that not the following?

Trac[loader] DEBUG: Loading ContextChrome from /srv/trac/trac/plugins/ContextChrome-0.3-py2.6.egg

That looks good.

Does the opening body tag on the ticket page have the class "resolution_is_signed"?

Jared Bownds

unread,
Jul 28, 2014, 6:51:21 PM7/28/14
to trac-...@googlegroups.com
resolution_is_signed<body class="resolution_is_Signed Task"><div id="WzTtDiV" style="visibility: hidden; position: absolute; overflow: hidden; padding: 0px; width: 1679px; left: -1680px; top: 0px;"></div>




--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Jared Bownds

unread,
Jul 28, 2014, 6:55:00 PM7/28/14
to trac-...@googlegroups.com
I found it, it is case sensitive.  According the the class name,

resolution_is_signed<body class="resolution_is_Signed Task"><div id="WzTtDiV" style="visibility: hidden; position: absolute; overflow: hidden; padding: 0px; width: 1679px; left: -1680px; top: 0px;"></div>


--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Jared Bownds

unread,
Jul 28, 2014, 6:55:55 PM7/28/14
to trac-...@googlegroups.com
I found it, it is case sensitive.  According the the class name, style.css needs to contain: 

style.css
body.resolution_is_Signed { background-color: #b3caf5; /* soft blue */    }

body tag
resolution_is_signed<body class="resolution_is_Signed Task"><div id="WzTtDiV" style="visibility: hidden; position: absolute; overflow: hidden; padding: 0px; width: 1679px; left: -1680px; top: 0px;"></div>


--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Franz

unread,
Jul 29, 2014, 1:02:57 AM7/29/14
to trac-...@googlegroups.com
Hi Jared,

we need a similar solution. In our case, it's probably named "released" (instead of "signed"). The use-case is that nobody should change ticket properties when the ticket is released (only commenting).

Have you created a Trac-Plugin on Trac-hacks [1] for that solution?

Thank you,
Franz


[1] http://trac-hacks.org/


On Sunday, July 27, 2014 1:33:16 AM UTC+2, Jared Bownds wrote:
Reference:  http://trac-hacks.org/ticket/11885

I am looking for a solution that will work like this:
  • Create a new permission group called SIGNER
  • Add 'signed' as a resolution type
  • Users with permission SIGNER are allowed to resolve a request as 'Signed'
Desired behavior:
  • Once a ticket is resolved as 'Signed', the ticket is now read only except to TRAC_ADMIN
  • Users without TRAC_ADMIN permissions are unable to modify the ticket in any way. When an attempt is made, the user should receive an error upon save indicating the ticket is signed and therefore read only.

Jared Bownds

unread,
Jul 29, 2014, 10:15:43 AM7/29/14
to trac-...@googlegroups.com
Hi Ryan,

ReadonlySignedTickets.py (outlined below) is not working for me.  Moreover, I can tell in the Trac log that the plugin is being considered.

I've tried both if t['resolution'] == 'Signed': and if t['resolution'] == 'signed':

Any thoughts?


ReadonlySignedTickets.py
{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \
           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'Signed':
            return False
}}}


On Mon, Jul 28, 2014 at 11:31 AM, Ryan Ollos <rjo...@gmail.com> wrote:

--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.

To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Jared Bownds

unread,
Jul 29, 2014, 10:18:01 AM7/29/14
to trac-...@googlegroups.com
Hi Franz, 

Since i'm not the primary contributor to the code for the plug in dealing with the permissions, I'm not sure I would be the one to publish it.

Perhaps Ryan or Peter are interested in publishing a more flexible version of this plugin on trac-hacks.  Otherwise, once we finish the plugin you can simply follow the instructions outlined in the email chain to implement desired behavior you outlined.


--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Ryan Ollos

unread,
Jul 29, 2014, 11:19:42 AM7/29/14
to trac-...@googlegroups.com
On Tue, Jul 29, 2014 at 7:14 AM, Jared Bownds <jared....@gmail.com> wrote:
Hi Ryan,

ReadonlySignedTickets.py (outlined below) is not working for me.  Moreover, I can tell in the Trac log that the plugin is being considered.

I've tried both if t['resolution'] == 'Signed': and if t['resolution'] == 'signed':

You'll need to use whatever casing was used to define the resolution. Unless that has changed since yesterday, it is "Signed".

What do you see in the Trac log?

In an earlier email Peter described the permission_policies setting. What is your value for?:
[trac]
permission_policies

Ryan Ollos

unread,
Jul 29, 2014, 11:52:30 AM7/29/14
to trac-...@googlegroups.com
On Mon, Jul 28, 2014 at 10:02 PM, Franz <f.m...@web.de> wrote:
Hi Jared,

we need a similar solution. In our case, it's probably named "released" (instead of "signed"). The use-case is that nobody should change ticket properties when the ticket is released (only commenting).

Have you created a Trac-Plugin on Trac-hacks [1] for that solution?

Thank you,
Franz


[1] http://trac-hacks.org/


I had a similar requirement at my previous company so I've been thinking about the implementation a bit more.

In that case, we would have liked to keep the existing resolutions and perhaps had a "signed" status that followed "closed". It seems all that would be necessary would be a minor change to Peter's plugin, to check ticket['status'] rather than ticket['resolution'], and the rest could be implemented in the workflow and with a special permission (see below). We'd probably also want to have a workflow operation to get a ticket out of the signed state, perhaps with another elevated permission for performing that operation.

For your requirement of only allowing ticket commenting, you could probably just tweak the ReadonlySignedTickets permissions policy to only allow TICKET_APPEND rather than only allowing TICKET_VIEW when in the signed state.

[extra-permissions]
_perms = TICKET_SIGN

[ticket-workflow]
sign = closed -> signed
sign.permissions = TICKET_SIGN




from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \
           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['status'] == 'signed':
            return False

Jared Bownds

unread,
Jul 29, 2014, 5:03:05 PM7/29/14
to trac-...@googlegroups.com
Hi Ryan,

Here are the values for permissions_policies in trac.ini and the log results for user temp1 when updating a ticket resolved as "Signed".

[trac]
permission_policies = ReadonlySignedTickets, DefaultPermissionPolicy, LegacyAttachmentPolicy

Log
2014-07-29 14:00:13,616 Trac[session] DEBUG: Retrieving session for ID u'temp1'
2014-07-29 14:00:13,624 Trac[main] DEBUG: Negotiated locale: None -> en_US
2014-07-29 14:00:13,640 Trac[perm] DEBUG: No policy allowed temp1 performing TRAC_ADMIN on <Resource u'ticket:1969'>
2014-07-29 14:00:13,650 Trac[blackmagic] DEBUG: Validating ticket: 1969
2014-07-29 14:00:13,650 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADD_HOURS', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-29 14:00:13,651 Trac[blackmagic] DEBUG: Checking permission TICKET_ADD_HOURS
2014-07-29 14:00:13,655 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADD_HOURS on <Resource u'ticket:1969'>
2014-07-29 14:00:13,655 Trac[blackmagic] DEBUG: totalhours disabled or hidden
2014-07-29 14:00:13,660 Trac[blackmagic] DEBUG: OT: 0
2014-07-29 14:00:13,660 Trac[blackmagic] DEBUG: NEW: 0
2014-07-29 14:00:13,660 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TRAC_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-29 14:00:13,661 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-29 14:00:13,661 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-29 14:00:13,665 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADMIN on <Resource u'ticket:1969'>
2014-07-29 14:00:13,666 Trac[blackmagic] DEBUG: component disabled or hidden
2014-07-29 14:00:13,670 Trac[blackmagic] DEBUG: OT: General Requests
2014-07-29 14:00:13,670 Trac[blackmagic] DEBUG: NEW: General Requests
2014-07-29 14:00:13,671 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-29 14:00:13,671 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-29 14:00:13,671 Trac[blackmagic] DEBUG: priority disabled or hidden
2014-07-29 14:00:13,676 Trac[blackmagic] DEBUG: OT: High
2014-07-29 14:00:13,676 Trac[blackmagic] DEBUG: NEW: High
2014-07-29 14:00:13,676 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-29 14:00:13,676 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-29 14:00:13,677 Trac[blackmagic] DEBUG: parents disabled or hidden
2014-07-29 14:00:13,681 Trac[blackmagic] DEBUG: OT:
2014-07-29 14:00:13,682 Trac[blackmagic] DEBUG: NEW:
2014-07-29 14:00:13,682 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': '', 'tip': u'Unless you know who should own this ticket, please leave this field default.', 'label': None, 'ondenial': 'disable', 'disable': False}
2014-07-29 14:00:13,682 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADD_HOURS', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-29 14:00:13,682 Trac[blackmagic] DEBUG: Checking permission TICKET_ADD_HOURS
2014-07-29 14:00:13,683 Trac[blackmagic] DEBUG: estimatedhours disabled or hidden
2014-07-29 14:00:13,687 Trac[blackmagic] DEBUG: OT: 0
2014-07-29 14:00:13,687 Trac[blackmagic] DEBUG: NEW: 0
2014-07-29 14:00:13,688 Trac[blackmagic] DEBUG: {'notice': None, 'hide': False, 'permission': u'TICKET_ADMIN', 'tip': None, 'label': None, 'ondenial': u'hide', 'disable': False}
2014-07-29 14:00:13,688 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-29 14:00:13,688 Trac[blackmagic] DEBUG: type disabled or hidden
2014-07-29 14:00:13,693 Trac[blackmagic] DEBUG: OT: Task
2014-07-29 14:00:13,693 Trac[blackmagic] DEBUG: NEW: Task
2014-07-29 14:00:13,725 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADD_HOURS on None
2014-07-29 14:00:14,082 Trac[notification] INFO: Sending notification through SMTP at exsmtp.na.bayer.cnb:25 to [u'te...@bayer.com', u'jared....@bayer.com']
2014-07-29 14:00:15,057 Trac[web_ui] DEBUG: Side effect for ConfigurableTicketWorkflow
2014-07-29 14:00:15,141 Trac[main] DEBUG: Dispatching <RequestWithSession "GET '/ticket/1969'">
2014-07-29 14:00:15,144 Trac[session] DEBUG: Retrieving session for ID u'temp1'
2014-07-29 14:00:15,151 Trac[main] DEBUG: Negotiated locale: None -> en_US
2014-07-29 14:00:15,167 Trac[perm] DEBUG: No policy allowed temp1 performing TRAC_ADMIN on <Resource u'ticket:1969'>
2014-07-29 14:00:15,181 Trac[default_workflow] DEBUG: render_ticket_action_control: action "leave"
2014-07-29 14:00:15,182 Trac[default_workflow] DEBUG: render_ticket_action_control: action "reopen"
2014-07-29 14:00:15,194 Trac[chrome] DEBUG: Prepare chrome data for request
2014-07-29 14:00:15,197 Trac[perm] DEBUG: No policy allowed temp1 performing ACCTMGR_CONFIG_ADMIN on None
2014-07-29 14:00:15,197 Trac[perm] DEBUG: No policy allowed temp1 performing ACCTMGR_USER_ADMIN on None
2014-07-29 14:00:15,197 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADMIN on None
2014-07-29 14:00:15,198 Trac[perm] DEBUG: No policy allowed temp1 performing REPORT_ADMIN on None
2014-07-29 14:00:15,198 Trac[perm] DEBUG: No policy allowed temp1 performing TRAC_ADMIN on None
2014-07-29 14:00:15,199 Trac[perm] DEBUG: No policy allowed temp1 performing PERMISSION_GRANT on None
2014-07-29 14:00:15,199 Trac[perm] DEBUG: No policy allowed temp1 performing PERMISSION_REVOKE on None
2014-07-29 14:00:15,200 Trac[perm] DEBUG: No policy allowed temp1 performing MILESTONE_VIEW on None
2014-07-29 14:00:15,200 Trac[perm] DEBUG: No policy allowed temp1 performing VERSIONCONTROL_ADMIN on None
2014-07-29 14:00:15,201 Trac[perm] DEBUG: No policy allowed temp1 performing ROADMAP_VIEW on None
2014-07-29 14:00:15,202 Trac[perm] DEBUG: No policy allowed temp1 performing TIMELINE_VIEW on None
2014-07-29 14:00:15,203 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_VIEW_HOURS on None
2014-07-29 14:00:15,208 Trac[blackmagic] DEBUG: Checking ticket permissions  for type Enhancement
2014-07-29 14:00:15,208 Trac[blackmagic] DEBUG: User temp1 has permission
2014-07-29 14:00:15,209 Trac[blackmagic] DEBUG: Checking ticket permissions  for type Defect
2014-07-29 14:00:15,209 Trac[blackmagic] DEBUG: User temp1 has permission
2014-07-29 14:00:15,209 Trac[blackmagic] DEBUG: Checking ticket permissions  for type Task
2014-07-29 14:00:15,209 Trac[blackmagic] DEBUG: User temp1 has permission
2014-07-29 14:00:15,211 Trac[blackmagic] DEBUG: Permissions TICKET_ADD_HOURS
2014-07-29 14:00:15,211 Trac[blackmagic] DEBUG: Checking permission TICKET_ADD_HOURS
2014-07-29 14:00:15,216 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADD_HOURS on <Resource u'ticket:1969'>
2014-07-29 14:00:15,218 Trac[blackmagic] DEBUG: Permissions TRAC_ADMIN
2014-07-29 14:00:15,218 Trac[blackmagic] DEBUG: Checking permission TRAC_ADMIN
2014-07-29 14:00:15,220 Trac[blackmagic] DEBUG: Permissions TICKET_ADMIN
2014-07-29 14:00:15,220 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-29 14:00:15,225 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_ADMIN on <Resource u'ticket:1969'>
2014-07-29 14:00:15,226 Trac[blackmagic] DEBUG: Permissions TICKET_ADMIN
2014-07-29 14:00:15,226 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-29 14:00:15,228 Trac[blackmagic] DEBUG: Permissions TICKET_ADMIN
2014-07-29 14:00:15,228 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-29 14:00:15,230 Trac[blackmagic] DEBUG: Permissions TICKET_ADD_HOURS
2014-07-29 14:00:15,230 Trac[blackmagic] DEBUG: Checking permission TICKET_ADD_HOURS
2014-07-29 14:00:15,232 Trac[blackmagic] DEBUG: Permissions TICKET_ADMIN
2014-07-29 14:00:15,232 Trac[blackmagic] DEBUG: Checking permission TICKET_ADMIN
2014-07-29 14:00:15,427 Trac[perm] DEBUG: No policy allowed temp1 performing TICKET_EDIT_COMMENT on <Resource u'ticket:1969'>




--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Ryan Ollos

unread,
Jul 29, 2014, 5:54:08 PM7/29/14
to trac-...@googlegroups.com
On Tue, Jul 29, 2014 at 2:02 PM, Jared Bownds <jared....@gmail.com> wrote:
Hi Ryan,



If the policy is working correctly you will see messages like the following when navigating to a "signed" ticket:

02:49:07 PM Trac[perm] DEBUG: ReadonlySignedTickets denies user1 performing TICKET_MODIFY on <Resource u'ticket:5'>

So most likely either the policy isn't enabled or is failing to load.

(side note: we made Trac more robust for 1.0.2 so that a TracError will be raised if one of the PermissionPolicies can't be loaded: http://trac.edgewall.org/ticket/10285)

Jared Bownds

unread,
Jul 29, 2014, 6:49:05 PM7/29/14
to trac-...@googlegroups.com
When enabling the plugin I can see it's is being loaded successfully.  You said the code below works properly for you?

Trac log
2014-07-29 15:36:29,284 Trac[loader] DEBUG: Loading file plugin ReadonlySignedTickets from /srv/trac/trac/plugins/ReadonlySignedTickets.py

ReadonlySignedTickets.py
{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_APPEND' or \
           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'signed':
            return False
}}}

[trac]
permission_policies = ReadonlySignedTickets, DefaultPermissionPolicy, LegacyAttachmentPolicy

--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Ryan Ollos

unread,
Jul 29, 2014, 6:55:29 PM7/29/14
to trac-...@googlegroups.com
On Tue, Jul 29, 2014 at 3:48 PM, Jared Bownds <jared....@gmail.com> wrote:
When enabling the plugin I can see it's is being loaded successfully.  You said the code below works properly for you?

Yes, it works for me.

You will need to change "signed" -> "Signed" according to your previous email, and make sure you restart Trac so that the plugin is reloaded after making that change.

Jared Bownds

unread,
Jul 30, 2014, 10:15:29 AM7/30/14
to trac-...@googlegroups.com
Hi Ryan,

Thanks for your help so far.  I now have the plugin loading, however even users with TICKET_VIEW permissions are now unable to view tickets resolved as "Signed".  Any idea why this may be happening?

Inline image 3

2014-07-30 07:11:07,965 Trac[perm] DEBUG: ReadonlySignedTickets denies temp1 performing TICKET_VIEW on <Resource u'ticket:1969'>


{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_APPEND' or \
           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'Signed':
            return False
}}}


--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Peter Suter

unread,
Jul 30, 2014, 10:36:35 AM7/30/14
to trac-...@googlegroups.com
Hi

On 30.07.2014 16:14, Jared Bownds wrote:
> Thanks for your help so far. I now have the plugin loading, however
> even users with TICKET_VIEW permissions are now unable to view tickets
> resolved as "Signed". Any idea why this may be happening?

Probably because you switched the allowed action from
action == 'TICKET_VIEW'
to
action == 'TICKET_APPEND'

If you want to allow both, you could instead try e.g.
action in ['TICKET_VIEW', 'TICKET_APPEND']

Jared Bownds

unread,
Jul 30, 2014, 11:20:32 AM7/30/14
to trac-...@googlegroups.com
That was it, thanks for pointing it out.


--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+unsubscribe@googlegroups.com.

To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Jared Bownds

unread,
Aug 1, 2014, 1:53:50 PM8/1/14
to trac-...@googlegroups.com
Okay, hopefully this is the last iteration!

Using the code below as our example, for some reason users who are not TRAC_ADMIN are unable to comment or modify tickets, irrespective of resolution status.

Also, I've included my permission policy configuration below.

ReadonlySignedTickets.py
{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \

           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'Signed':
            return False
}}}

[trac]
permission_policies = DefaultPermissionPolicy, ReadonlySignedTickets, LegacyAttachmentPolicy (this configuration locks any user but TRAC_ADMIN irrespective of resolution type)
OR
permission_policies = ReadonlySignedTickets, DefaultPermissionPolicy, LegacyAttachmentPolicy (This configuration doesn't work according to the desired behavior, since I believe permissions are processed in order, one superseding another)



On Mon, Jul 28, 2014 at 11:31 AM, Ryan Ollos <rjo...@gmail.com> wrote:
On Mon, Jul 28, 2014 at 10:55 AM, Jared Bownds <jared....@gmail.com> wrote:
You nailed it!  The code below works.  However, users are still able to 'edit' their own comments once a ticket is resolved as signed.   

{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \

           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'signed':
            return False
}}}

Peter's plugin shown above work for me on 1.0-stable, and users aren't able to edit comments even if they have been granted TICKET_ADMIN. I used resolution //signed// rather than //Signed// since all of Trac's predefined resolutions are in lowercase.

Which Trac version are you running?

In order to implement your other requirements, it sounds like you'll want to:
 * Enable ExtraPermissionsProvider
   [components]
   tracopt.perm.config_perm_provider.extrapermissionsprovider = enabled

 * Add the signed permission:
   [extra-permissions]
   _perms = TICKET_SIGNED

 * Grant TICKET_SIGNED to the appropriate user.

 * Modify your workflow to only allow users with TICKET_SIGNED to resolve a ticket as signed. This is where things seem to get a bit tricky. You may need to have a workflow state signed rather than using a resolution, but that might not work since you probably want tickets to end in the closed state. You might need to implement a workflow action to replace set_resolution, which does permission checking to decide who can resolve a ticket as signed ... or perhaps the permission checking can be done in the ReadonlySignedTickets policy as well. I'll have to give that more thought.


 

--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.

To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.

Ryan Ollos

unread,
Aug 1, 2014, 7:39:24 PM8/1/14
to trac-...@googlegroups.com
On Fri, Aug 1, 2014 at 10:52 AM, Jared Bownds <jared....@gmail.com> wrote:
Okay, hopefully this is the last iteration!

Using the code below as our example, for some reason users who are not TRAC_ADMIN are unable to comment or modify tickets, irrespective of resolution status.

Also, I've included my permission policy configuration below.

ReadonlySignedTickets.py
{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \
           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'Signed':
            return False
}}}

[trac]
permission_policies = DefaultPermissionPolicy, ReadonlySignedTickets, LegacyAttachmentPolicy (this configuration locks any user but TRAC_ADMIN irrespective of resolution type)
OR
permission_policies = ReadonlySignedTickets, DefaultPermissionPolicy, LegacyAttachmentPolicy (This configuration doesn't work according to the desired behavior, since I believe permissions are processed in order, one superseding another)

The latter is what you want to use. You need ReadonlySignedTickets to deny actions in the ticket realm other than TICKET_VIEW before DefaultPermissionPolicy is able to grant actions to users possessing those permissions.

If you continue to have trouble, look in the log to figure out why user are being denied permission. The decision is logged at DEBUG log level, as we've already seen.


Peter: do you think it would be worthwhile to add this permissions policy as an example in the CookBook?
http://trac.edgewall.org/wiki/CookBook

Jared Bownds

unread,
Aug 3, 2014, 9:50:30 AM8/3/14
to trac-...@googlegroups.com
Hi Ryan,

My present challenge with the latter permission policy configuration and ReadonlySignedTickets.py is that all users but TRAC_ADMIN are unable to comment on any ticket, irrespective of its status (new, assigned, open, closed as closed).  In summary, it's simply not working as desired.  

The debug log indicates that ReadonlySignedTickets.py has denied TICKET_APPEND and all other permissions, except view.  However,  as I mentioned earlier TRAC_ADMIN remains able to edit any ticket, signed or otherwise.

What are your thoughts?
--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.


--

Jared Bownds
m. 916.224.2324
e. Jared....@gmail.com

Peter Suter

unread,
Aug 3, 2014, 10:36:06 AM8/3/14
to trac-...@googlegroups.com
On 03.08.2014 15:50, Jared Bownds wrote:
My present challenge with the latter permission policy configuration and ReadonlySignedTickets.py is that all users but TRAC_ADMIN are unable to comment on any ticket, irrespective of its status (new, assigned, open, closed as closed).  In summary, it's simply not working as desired.  
The code you quoted does not look at status, only at resolution:

if t['resolution'] == 'Signed':
If you reopened the ticket after resolving it as 'Signed', the resolution might still remain 'Signed'. Could that be what happened?
Maybe try this instead:
if t['resolution'] == 'Signed' and t['status'] == 'closed':

If this doesn't help please specify exactly what code and configuration you use and what steps you perform and the corresponding section of the log file.
Do you use other permission plugins (like blackmagic)?

Peter Suter

unread,
Aug 3, 2014, 4:11:15 PM8/3/14
to trac-...@googlegroups.com
On 02.08.2014 01:39, Ryan Ollos wrote:
> Peter: do you think it would be worthwhile to add this permissions
> policy as an example in the CookBook?
> http://trac.edgewall.org/wiki/CookBook

Sure, why not. I just created:
http://trac.edgewall.org/wiki/CookBook/Configuration/SignedTickets

Please review and amend...

Jared Bownds

unread,
Aug 3, 2014, 10:35:30 PM8/3/14
to trac-...@googlegroups.com
Alright, permissions are now working properly. For some reason I omitted the last if statement qualifying the resolution type. 

Moving forward, I'm having a problem with the visual indication here.  I can see in the trac log that signed.png is being loaded, however I'm not seeing the image displayed on a signed ticket.  Keep in mind, I do however see the ticket body change color - signed.png is located in my environments htdocs folder.

style.css
{{{
body.resolution_is_Signed {
    background: #f5deb3 url(signed.png);
}
}}}

site.html
{{{
      xmlns:py="http://genshi.edgewall.org/"
      py:strip="">

  <!--! Add site-specific style sheet -->
  <head py:match="head" py:attrs="select('@*')">
    ${select('*|comment()|text()')}
    <link rel="stylesheet" type="text/css"
          href="${href.chrome('site/style.css')}" />
  </head>

  <body py:match="body" py:attrs="select('@*')">
    <!--! Add site-specific header -->
    <div id="siteheader">
      <!--! Place your header content here... -->
    </div>

    ${select('*|text()')}

    <!--! Add site-specific footer -->
    <div id="sitefooter">
      <!--! Place your footer content here... -->
    </div>
  </body>
</html>
}}}


--
You received this message because you are subscribed to a topic in the Google Groups "Trac Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/trac-users/1GNDHTObQKg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to trac-users+...@googlegroups.com.
To post to this group, send email to trac-...@googlegroups.com.
Visit this group at http://groups.google.com/group/trac-users.
For more options, visit https://groups.google.com/d/optout.



--

Ryan Ollos

unread,
Aug 3, 2014, 10:50:07 PM8/3/14
to trac-...@googlegroups.com
On Sun, Aug 3, 2014 at 7:34 PM, Jared Bownds <jared....@gmail.com> wrote:
Alright, permissions are now working properly. For some reason I omitted the last if statement qualifying the resolution type. 

Moving forward, I'm having a problem with the visual indication here.  I can see in the trac log that signed.png is being loaded, however I'm not seeing the image displayed on a signed ticket.  Keep in mind, I do however see the ticket body change color - signed.png is located in my environments htdocs folder.

style.css
{{{
body.resolution_is_Signed {
    background: #f5deb3 url(signed.png);
}
}}}

It works fine for me. Make sure the image displays when you navigate to <base_url>/chrome/site/signed.png. That should rule out any permissions-related issues.

The cookbook page looks really great. Very thorough!

Ahmed M.

unread,
Dec 10, 2015, 4:55:17 PM12/10/15
to Trac Users, ryan.j...@gmail.com
I want to apply this to all closed tickets (no special resolution) and I am not having much luck. I tried to change the line if t['resolution'] == 'fixed', if t['resolution'] == 'closed' but nothing happened. any idea how I can debug\fix this? 

Thanks, 


On Monday, July 28, 2014 at 2:31:56 PM UTC-4, RjOllos wrote:
On Mon, Jul 28, 2014 at 10:55 AM, Jared Bownds <jared....@gmail.com> wrote:
You nailed it!  The code below works.  However, users are still able to 'edit' their own comments once a ticket is resolved as signed.   

{{{
from trac.core import *
from trac.perm import IPermissionPolicy
from trac.ticket.model import Ticket

class ReadonlySignedTickets(Component):
    implements(IPermissionPolicy)

    def check_permission(self, action, username, resource, perm):
        if resource is None or resource.realm != 'ticket' or \
           resource.id is None or action == 'TICKET_VIEW' or \
           action == 'TRAC_ADMIN' or 'TRAC_ADMIN' in perm:

            return None

        t = Ticket(self.env, resource.id)
        if t['resolution'] == 'signed':
            return False
}}}

RjOllos

unread,
Dec 10, 2015, 5:20:36 PM12/10/15
to Trac Users, ryan.j...@gmail.com


On Thursday, December 10, 2015 at 1:55:17 PM UTC-8, Ahmed M. wrote:
I want to apply this to all closed tickets (no special resolution) and I am not having much luck. I tried to change the line if t['resolution'] == 'fixed', if t['resolution'] == 'closed' but nothing happened. any idea how I can debug\fix this? 

Thanks, 

Please try:
t['status'] == 'closed' 

Ahmed M.

unread,
Dec 11, 2015, 9:54:30 AM12/11/15
to Trac Users, ryan.j...@gmail.com
Here is what I did, I put the code in a .py file in the plugins directory and enabled it in the trac ini file - see attached screenshots. No change what so ever! I don't even see the plugin in the web admin screen!
So I read again the above threads and found that I need to update my permission_policies to include it - which I did:
permission_policies = ReadonlyClosedTickets, DefaultPermissionPolicy, LegacyAttachmentPolicy

now I can't even login to the site - I get an error screen (see attached screenshot).

Sorry but I am stuck - again!
trac11DEC2015-trac_ini_components.PNG
trac11DEC2015-code.PNG
trac11DEC2015-error.PNG

Ahmed M.

unread,
Dec 11, 2015, 11:39:04 AM12/11/15
to Trac Users, ryan.j...@gmail.com
I take that back - it was an indentation issue with my script, fixed it and IT WORKS! 
Thank you so much for your help!

Ahmed
Reply all
Reply to author
Forward
0 new messages