pax_global_header00006660000000000000000000000064120264760410014514gustar00rootroot0000000000000052 comment=637b944841590fda84f47a2d74830fffd8be0baa trac-includemacro-3.0.0~r12030/000077500000000000000000000000001202647604100160565ustar00rootroot00000000000000trac-includemacro-3.0.0~r12030/COPYING000066400000000000000000000027261202647604100171200ustar00rootroot00000000000000Copyright (C) 2007-2008 Noah Kantrowitz Copyright (C) 2012 Ryan J Ollos All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. trac-includemacro-3.0.0~r12030/README000066400000000000000000000027751202647604100167510ustar00rootroot00000000000000Notes ===== This macro lets you include various things. Currently supported sources: * HTTP - ``http:`` and ``https:`` * FTP - ``ftp:`` * Wiki pages - ``wiki:`` * Repository files - ``source:`` * Ticket comments - ``ticket:N:comment:M`` (3.0dev, syntax may be changed before release) The default source is ``wiki`` if only a source path is given. An optional second argument sets the output MIME type, though in most cases the default will be correct. Permissions =========== The three remote sources (``http``, ``https``, and ``ftp``) require ``INCLUDE_URL`` to be rendered. Anyone can add a call to these, however they will not be shown. This is **not** a replacement for ``render_unsafe_content``, see below. Configuration ============= If ``[wiki] render_unsafe_content`` is off (the default), any produced HTML will be sanitized. .. caution:: This is a potential security risk! Please review the implications ``render_unsafe_content`` before using this feature. To enable the plugin:: [components] includemacro.* = enabled Example ======= Include another wiki page:: [[Include(PageName)]] Include the HEAD revision of a reStructuredText__ file from the repository:: [[Include(source:trunk/docs/README, text/x-rst)]] Include a specific revision of a file from the repository:: [[Include(source:trunk/docs/README@5, text/x-rst)]] __ http://docutils.sf.net/rst.html .. tip:: If you set the ``svn:mime-type`` property on the file, you can leave off the explicit MIME type.trac-includemacro-3.0.0~r12030/changelog000066400000000000000000000014441202647604100177330ustar00rootroot00000000000000IncludeMacro 3.0.0 (not yet released) - trunk resolved issues: * #2413: Replaced call to deprecated render_macro with expand_macro (0.11 compatibility). * #4162: Added multirepository support (0.12 compatibility). * #9931: Fine-grained permissions checks were not being performed for the wiki realm. new features: * #3204: Allow revision of the source file to be specified. * #3820: Allow revision of a wiki page to be specified. * #10070: Support for ticket comments. IncludeMacro 2.1.0 - 0.11 branch new features: * Escape included text when `[wiki]` `render_unsafe_content` is false (the default value). IncludeMacro 2.0.1 - 0.11 branch IncludeMacro 2.0.0 - 0.11 branch IncludeMacro 1.1.0 - 0.10 branch IncludeMacro 1.0.1 - 0.10 branch IncludeMacro 1.0.0 - 0.10 branchtrac-includemacro-3.0.0~r12030/includemacro/000077500000000000000000000000001202647604100205235ustar00rootroot00000000000000trac-includemacro-3.0.0~r12030/includemacro/__init__.py000066400000000000000000000000001202647604100226220ustar00rootroot00000000000000trac-includemacro-3.0.0~r12030/includemacro/macros.py000066400000000000000000000163331202647604100223670ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Copyright (C) 2007-2008 Noah Kantrowitz # Copyright (C) 2012 Ryan J Ollos # All rights reserved. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. # import urllib2 from StringIO import StringIO from genshi.core import escape from genshi.filters.html import HTMLSanitizer from genshi.input import HTMLParser, ParseError from trac.core import * from trac.mimeview.api import Mimeview, get_mimetype, Context from trac.perm import IPermissionRequestor from trac.resource import ResourceNotFound from trac.ticket.model import Ticket from trac.versioncontrol.api import RepositoryManager from trac.wiki.formatter import system_message from trac.wiki.macros import WikiMacroBase from trac.wiki.model import WikiPage __all__ = ['IncludeMacro'] class IncludeMacro(WikiMacroBase): """A macro to include other resources in wiki pages. More documentation to follow. """ implements(IPermissionRequestor) # Default output formats for sources that need them default_formats = { 'wiki': 'text/x-trac-wiki', } # IWikiMacroProvider methods def expand_macro(self, formatter, name, content): args = [x.strip() for x in content.split(',')] if len(args) == 1: args.append(None) elif len(args) != 2: return system_message('Invalid arguments "%s"'%content) # Pull out the arguments source, dest_format = args try: source_format, source_obj = source.split(':', 1) except ValueError: # If no : is present, assume its a wiki page source_format, source_obj = 'wiki', source # Apply a default format if needed if dest_format is None: try: dest_format = self.default_formats[source_format] except KeyError: pass if source_format in ('http', 'https', 'ftp'): # Since I can't really do recursion checking, and because this # could be a source of abuse allow selectively blocking it. # RFE: Allow blacklist/whitelist patterns for URLS. # RFE: Track page edits and prevent unauthorized users from ever entering a URL include. if not formatter.perm.has_permission('INCLUDE_URL'): self.log.info('IncludeMacro: Blocking attempt by %s to include URL %s on page %s', formatter.req.authname, source, formatter.req.path_info) return '' try: urlf = urllib2.urlopen(source) out = urlf.read() except urllib2.URLError, e: return system_message('Error while retrieving file', str(e)) except TracError, e: return system_message('Error while previewing', str(e)) ctxt = Context.from_request(formatter.req) elif source_format == 'wiki': # XXX: Check for recursion in page includes. if '@' in source_obj: page_name, page_version = source_obj.split('@', 1) else: page_name, page_version = source_obj, None page = WikiPage(self.env, page_name, page_version) if not 'WIKI_VIEW' in formatter.perm(page.resource): return '' if not page.exists: if page_version: return system_message('No version "%s" for wiki page "%s"' % (page_version, page_name)) else: return system_message('Wiki page "%s" does not exist' % page_name) out = page.text ctxt = Context.from_request(formatter.req, 'wiki', source_obj) elif source_format == 'source': if not formatter.perm.has_permission('FILE_VIEW'): return '' out, ctxt, dest_format = self._get_source(formatter, source_obj, dest_format) elif source_format == 'ticket': if ':' in source_obj: ticket_num, source_obj = source_obj.split(':', 1) if not Ticket.id_is_valid(ticket_num): return system_message("%s is not a valid ticket id" % ticket_num) try: ticket = Ticket(self.env, ticket_num) if not 'TICKET_VIEW' in formatter.perm(ticket.resource): return '' except ResourceNotFound, e: return system_message("Ticket %s does not exist" % ticket_num) if ':' in source_obj: source_format, comment_num = source_obj.split(':', 1) if source_format == 'comment': changelog = ticket.get_changelog() out = [] if changelog: for (ts, author, field, oldval, newval, permanent) in changelog: if field == 'comment' and oldval == comment_num: dest_format = 'text/x-trac-wiki' ctxt = Context.from_request(formatter.req, 'ticket', ticket_num) out = newval break if not out: return system_message("Comment %s does not exist for Ticket %s" % (comment_num, ticket_num)) else: system_message("Unsupported ticket field %s" % source_format) else: return system_message('Ticket field must be specified') else: # RFE: Add ticket: and comment: sources. # RFE: Add attachment: source. return system_message('Unsupported realm %s' % source) # If we have a preview format, use it if dest_format: out = Mimeview(self.env).render(ctxt, dest_format, out) # Escape if needed if not self.config.getbool('wiki', 'render_unsafe_content', False): try: out = HTMLParser(StringIO(out)).parse() | HTMLSanitizer() except ParseError: out = escape(out) return out # IPermissionRequestor methods def get_permission_actions(self): yield 'INCLUDE_URL' # Private methods def _get_source(self, formatter, source_obj, dest_format): repos_mgr = RepositoryManager(self.env) try: #0.12+ repos_name, repos,source_obj = repos_mgr.get_repository_by_path(source_obj) except AttributeError, e: #0.11 repos = repos_mgr.get_repository(formatter.req.authname) path, rev = _split_path(source_obj) node = repos.get_node(path, rev) out = node.get_content().read() if dest_format is None: dest_format = node.content_type or get_mimetype(path, out) ctxt = Context.from_request(formatter.req, 'source', path) return out, ctxt, dest_format def _split_path(source_obj): if '@' in source_obj: path, rev = source_obj.split('@', 1) else: path, rev = source_obj, None return path, rev trac-includemacro-3.0.0~r12030/setup.cfg000066400000000000000000000000631202647604100176760ustar00rootroot00000000000000[egg_info] tag_build = dev tag_svn_revision = true trac-includemacro-3.0.0~r12030/setup.py000077500000000000000000000022021202647604100175670ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright (C) 2007-2008 Noah Kantrowitz # Copyright (C) 2012 Ryan J Ollos # All rights reserved. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. # import os.path from setuptools import setup setup( name = 'TracIncludeMacro', version = '3.0.0', packages = ['includemacro'], author = 'Noah Kantrowitz', author_email = 'noah@coderanger.net', maintainer = 'Ryan J Ollos', maintainer_email = 'ryan.j.ollos@gmail.com', description = 'Include the contents of external URLs and other Trac objects in a wiki page.', long_description = open(os.path.join(os.path.dirname(__file__), 'README')).read(), license = '3-Clause BSD', keywords = 'trac 0.11 plugin wiki include macro', url = 'http://trac-hacks.org/wiki/IncludeMacro', classifiers = [ 'Framework :: Trac', ], install_requires = ['Trac'], entry_points = { 'trac.plugins': [ 'includemacro.macros = includemacro.macros', ] } )