view roundup/cgi/apache.py @ 5222:9bf221cebef3

Make properties method return only properties the user can search. See: https://sourceforge.net/p/roundup/mailman/roundup-devel/thread/20170405002844.2004B80690%40vm71.cs.umb.edu/#msg35769250 [Roundup-devel] Bug in context/properties, lists properties user can't search. The HTMLClass::properties() method returns a list of all properties. This is used when creating sort on/group by filters on index pages. However somewhere in the code, a user needs search permission on the property in order for it to be used for grouping or sorting. This means the user can choose to sort/group an index page by a property that they have no search permission for. As a result the sort/group is ignored. This is confusing. I have changed the properties method to only return properties the user has View/Search permissions on. I also added a new cansearch argument set by default to True. If set to False, all properties regardless of Search permission are returned. Doc updated to include the new default operation and mention the use of cansearch argument.
author John Rouillard <rouilj@ieee.org>
date Wed, 05 Apr 2017 21:38:32 -0400
parents 302bc481ceb1
children 92757447dcf0 86b6cea7a975
line wrap: on
line source

# mod_python interface for Roundup Issue Tracker
#
# This module is free software, you may redistribute it
# and/or modify under the same terms as Python.
#
# This module provides Roundup Web User Interface
# using mod_python Apache module.  Initially written
# with python 2.3.3, mod_python 3.1.3, roundup 0.7.0.
#
# This module operates with only one tracker
# and must be placed in the tracker directory.
#

import cgi
import os
import threading

from mod_python import apache

import roundup.instance
from roundup.cgi import TranslationService

class Headers(dict):

    """HTTP headers wrapper"""

    def __init__(self, headers):
        """Initialize with `apache.table`"""
        super(Headers, self).__init__(headers)
        self.getheader = self.get

class Request(object):

    """`apache.Request` object wrapper providing roundup client interface"""

    def __init__(self, request):
        """Initialize with `apache.Request` object"""
        self._req = request
        # .headers.getheader()
        self.headers = Headers(request.headers_in)
        # .wfile.write()
        self.wfile = self._req

    def start_response(self, headers, response):
        self.send_response(response)
        for key, value in headers:
            self.send_header(key, value)
        self.end_headers()

    def send_response(self, response_code):
        """Set HTTP response code"""
        self._req.status = response_code

    def send_header(self, name, value):
        """Set output header"""
        # value may be an instance of roundup.cgi.exceptions.HTTPException
        value = str(value)
        # XXX default content_type is "text/plain",
        #   and ain't overrided by "Content-Type" header
        if name == "Content-Type":
            self._req.content_type = value
        else:
            self._req.headers_out.add(name, value)

    def end_headers(self):
        """NOOP. There aint no such thing as 'end_headers' in mod_python"""
        pass

 
    def sendfile(self, filename, offset = 0, len = -1):
        """Send 'filename' to the user."""

        return self._req.sendfile(filename, offset, len)

__tracker_cache = {}
"""A cache of optimized tracker instances.
 
The keys are strings giving the directories containing the trackers.
The values are tracker instances."""

__tracker_cache_lock = threading.Lock()
"""A lock used to guard access to the cache."""


def handler(req):
    """HTTP request handler"""
    _options = req.get_options()
    _home = _options.get("TrackerHome")
    _lang = _options.get("TrackerLanguage")
    _timing = _options.get("TrackerTiming", "no")
    if _timing.lower() in ("no", "false"):
        _timing = ""
    _debug = _options.get("TrackerDebug", "no")
    _debug = _debug.lower() not in ("no", "false")

    # We do not need to take a lock here (the fast path) because reads
    # from dictionaries are atomic.
    if not _debug and _home in __tracker_cache:
        _tracker = __tracker_cache[_home]
    else:
        if not (_home and os.path.isdir(_home)):
            apache.log_error(
                "PythonOption TrackerHome missing or invalid for %(uri)s"
                % {'uri': req.uri})
            return apache.HTTP_INTERNAL_SERVER_ERROR
        if _debug:
            _tracker = roundup.instance.open(_home, optimize=0)
        else:
            __tracker_cache_lock.acquire()
            try:
                # The tracker may have been added while we were acquiring
                # the lock.
                if _home in __tracker_cache:
                    _tracker = __tracker_cache[home]
                else:
                    _tracker = roundup.instance.open(_home, optimize=1)
                    __tracker_cache[_home] = _tracker
            finally:
                __tracker_cache_lock.release()
    # create environment
    # Note: cookies are read from HTTP variables, so we need all HTTP vars
    req.add_common_vars()
    _env = dict(req.subprocess_env)
    # XXX classname must be the first item in PATH_INFO.  roundup.cgi does:
    #       path = string.split(os.environ.get('PATH_INFO', '/'), '/')
    #       os.environ['PATH_INFO'] = string.join(path[2:], '/')
    #   we just remove the first character ('/')
    _env["PATH_INFO"] = req.path_info[1:]
    if _timing:
        _env["CGI_SHOW_TIMING"] = _timing
    _form = cgi.FieldStorage(req, environ=_env)
    _client = _tracker.Client(_tracker, Request(req), _env, _form,
        translator=TranslationService.get_translation(_lang,
            tracker_home=_home))
    _client.main()
    return apache.OK

# vim: set et sts=4 sw=4 :

Roundup Issue Tracker: http://roundup-tracker.org/