Commits

Anonymous committed 73c4f47

[svn r9899] 0.11.7.1: backport the check for parent resource existence as a precondition for allowing to create attachments (starting with r9720)

Comments (0)

Files changed (3)

trac/attachment.py

 
     def _do_save(self, req, attachment):
         req.perm(attachment.resource).require('ATTACHMENT_CREATE')
+        parent_resource = attachment.resource.parent
+        if resource_exists(self.env, parent_resource) is False:
+            raise ResourceNotFound(
+                _("%(parent)s doesn't exist, can't create attachment",
+                  parent=get_resource_name(self.env, parent_resource)))
+        # `None` is OK on 0.11.x, for backward compatibility; not so with 0.12x
 
         if 'cancel' in req.args:
-            req.redirect(get_resource_url(self.env, attachment.resource.parent,
-                                          req.href))
+            req.redirect(get_resource_url(self.env, parent_resource, req.href))
 
         upload = req.args['attachment']
         if not hasattr(upload, 'filename') or not upload.filename:
         default mode) will be used.
         """
 
+    def resource_exists(resource):
+        """Check whether the given `resource` exists physically.
+
+        :rtype: bool
+
+        Attempting to retrieve the model object for a non-existing
+        resource should raise a `ResourceNotFound` exception.
+        (since 0.12)
+        """
+
 
 class Resource(object):
     """Resource identifier.
     if not isinstance(link, Element):
         link = tag.a(link, href=get_resource_url(env, resource, context.href))
     return link
+
+def resource_exists(env, resource):
+    """Checks for resource existence without actually instantiating a model.
+
+        :return: `True` if the resource exists, `False` if it doesn't
+        and `None` in case no conclusion could be made (i.e. when
+        `IResourceManager.resource_exists` is not implemented).
+
+        >>> from trac.test import EnvironmentStub
+        >>> env = EnvironmentStub()
+
+        >>> resource_exists(env, Resource('dummy-realm', 'dummy-id')) is None
+        True
+        >>> resource_exists(env, Resource('dummy-realm'))
+        False
+    """
+    manager = ResourceSystem(env).get_resource_manager(resource.realm)
+    if manager and hasattr(manager, 'resource_exists'):
+        return manager.resource_exists(resource)
+    elif resource.id is None:
+        return False
         'Wiki Start'
         """
         return self.format_page_name(resource.id)
+
+    def resource_exists(self, resource):
+        """
+        >>> from trac.test import EnvironmentStub
+        >>> from trac.resource import Resource, resource_exists
+        >>> env = EnvironmentStub()
+
+        >>> resource_exists(env, Resource('wiki', 'WikiStart'))
+        False
+
+        >>> from trac.wiki.model import WikiPage
+        >>> main = WikiPage(env, 'WikiStart')
+        >>> main.text = 'some content'
+        >>> main.save('author', 'no comment', '::1')
+        >>> resource_exists(env, main.resource)
+        True
+        """
+        if resource.version is None:
+            return resource.id in self.get_pages()
+        db = self.env.get_db_cnx()
+        cursor = db.cursor()
+        cursor.execute("SELECT name FROM wiki WHERE name=%s AND version=%s",
+                       (resource.id, resource.version))
+        return bool(cursor.fetchall())