--- attachmentpolicy/attachment_policy.py.orig   2013-04-12 21:35:56.000000000 -0400
+++ attachmentpolicy/attachment_policy.py        2013-05-17 11:22:56.000000000 -0400
@@ -1,38 +1,68 @@
 from trac.core import Component, implements
 from trac.perm import IPermissionPolicy, IPermissionRequestor

-class AttachmentDeletePolicy(Component):
-    """Adds permission `TICKET_ATTACHMENT_DELETE` for exclusive right to delete and replace
-attachments, regardless who added / changed it.
-
-Everybody who has permission `TICKET_ATTACHMENT_DELETE` can delete / replace attachments,
-regardless who added / changed it.
-
-Once this plugin is enabled, you'll have to insert it at the appropriate
-place in your list of permission policies, e.g.
-{{{
-[trac]
-permission_policies = AttachmentDeletePolicy, DefaultPermissionPolicy, LegacyAttachmentPolicy
-}}}
-"""
+class CustomAttachmentPolicy(Component):
+    """Adds permissions for exclusive rights to create and/or delete or replace
+       attachments, regardless who added / changed it.
+
+       For delete functionality, everybody who has an associated permission `TICKET_ATTACHMENT_DELETE`,
+       `MILESTONE_ATTACHMENT_DELETE`, or `WIKI_ATTACHMENT_DELETE` can delete / replace attachments
+       attached to TICKETS, MILESTONES, or WIKI pages, regardless who added / changed it.
+
+       For create functionality, everybody who has an associated permission `TICKET_ATTACHMENT_CREATE`,
+       `MILESTONE_ATTACHMENT_CREATE`, or `WIKI_ATTACHMENT_CREATE` can add attachments to TICKETS,
+       MILESTONES, or WIKI pages without having the ability to create or modify those entities.
+
+       The `ATTACHMENT_ADMIN` permission gives both DELETE and CREATE functionality on all three entities.
+
+       Once this plugin is enabled, you'll have to insert it at the appropriate
+       place in your list of permission policies, e.g.
+       {{{
+       [trac]
+       permission_policies = CustomAttachmentPolicy, DefaultPermissionPolicy, LegacyAttachmentPolicy
+       }}}
+    """
     implements(IPermissionPolicy, IPermissionRequestor)

     # IPermissionPolicy methods
     def check_permission(self, action, username, resource, perm):
-        # We add the 'TICKET_ATTACHMENT_DELETE' pre-requisite for any action
-        # other than 'TICKET_ATTACHMENT_DELETE' itself, as this would lead
-        # to recursion. (copied from sample-plugins/permissions/vulnerability_tickets.py)
-        if action == 'TICKET_ATTACHMENT_DELETE':
+        ''' Special check_permission for CustomAttachmentPolicy '''
+        # We add the special permissions pre-requisite for any action
+        # other than special permissions themselves, as this would lead
+        # to recursion.
+        # (copied from sample-plugins/permissions/vulnerability_tickets.py)
+        if action in ['TICKET_ATTACHMENT_CREATE',
+                     'MILESTONE_ATTACHMENT_CREATE',
+                     'WIKI_ATTACHMENT_CREATE',
+                     'TICKET_ATTACHMENT_DELETE',
+                     'MILESTONE_ATTACHMENT_DELETE',
+                     'WIKI_ATTACHMENT_DELETE',
+                     'ATTACHMENT_ADMIN']:
             return

-#        self.log.info( "action: %s, resource: %s" % (action, resource) )
-        # Check whether we're dealing with a ticket resource
-        if action and action == 'ATTACHMENT_DELETE' \
-        and resource and resource.realm == 'attachment' \
-        and 'TICKET_ATTACHMENT_DELETE' in perm:
-            self.log.info( "granted permission for user %s deleting attachment %s" % (username, resource) )
-            return True
+        # self.log.info( "action: %s, resource: %s" % (action, resource) )
+        # Check whether we're dealing with the correct resource
+
+        if action and action in ['ATTACHMENT_CREATE', 'ATTACHMENT_DELETE'] \
+           and resource and resource.realm == 'attachment':
+            parent = resource.parent.realm.upper()
+            permission = '%s_%s' % (parent, action)
+            if action == 'ATTACHMENT_CREATE':
+                action_text = 'creating'
+            else:
+                action_text = 'deleting'
+            if permission in perm or 'ATTACHMENT_ADMIN' in perm:
+                self.log.info("granted perm for user %s %s attachment %s" % \
+                                           (username, action_text, resource))
+                return True

     # IPermissionRequestor methods
     def get_permission_actions(self):
-        yield 'TICKET_ATTACHMENT_DELETE'
\ No newline at end of file
+        ''' Returns new permissions '''
+        return ['TICKET_ATTACHMENT_CREATE',
+                'MILESTONE_ATTACHMENT_CREATE',
+                'WIKI_ATTACHMENT_CREATE',
+                'TICKET_ATTACHMENT_DELETE',
+                'MILESTONE_ATTACHMENT_DELETE',
+                'WIKI_ATTACHMENT_DELETE',
+                'ATTACHMENT_ADMIN']
