Exemple #1
0
def serve_response(*path):
    """Serve up various respones with their correct response type"""
    known_types = dict(
        png=PNGResponse,
        jpg=JPGResponse,
        gif=PNGResponse,
        ico=ICOResponse,
        css=CSSResponse,
        js=JavascriptResponse,
    )
    filename = os.path.realpath(os.path.join(*path))
    logger = logging.getLogger(__name__)
    logger.debug('attempting to serve up filename %r', filename)
    if os.path.exists(filename):
        filenamel = filename.lower()
        for file_type in known_types:
            if filenamel.endswith('.' + file_type):
                data = open(filename, 'rb').read()
                response = known_types[file_type](data)
                return response
        return HTMLResponse('unknown file type')
    else:
        logger.warning('unable to serve filename %r', filename)
        relative_path = os.path.join(*path[1:])
        msg = 'file not found: {}'
        return HTMLResponse(msg.format(relative_path))
Exemple #2
0
def run_as_cgi(instance_path='..', start_time=timeit.default_timer()):

    if not os.path.exists(os.path.join(instance_path, 'dz.conf')):
        response = HTMLResponse(NEW_INSTALL_MESSAGE)
    else:
        response = generate_response(instance_path, start_time)

    sys.stdout.write(response.render())
Exemple #3
0
def run_as_cgi(instance_path='..', start_time=timeit.default_timer()):

    if not os.path.exists(os.path.join(instance_path, 'dz.conf')):
        response = HTMLResponse(NEW_INSTALL_MESSAGE)
    else:
        response = generate_response(instance_path, start_time)

    sys.stdout.write(response.render())
def trap_errors(request, handler, *rest):
    """Trap exceptions and raise a server error

    >>> def exception_handler(request, *rest):
    ...     raise Exception('error!')
    >>> def content_handler(request, *rest):
    ...     return HTMLResponse('nuthin')
    >>> request = {}
    >>> response = trap_errors(request, content_handler)
    >>> status, headers, content = response.as_wsgi()
    >>> content
    b'nuthin'
    >>> status
    '200 OK'
    >>> response = trap_errors(request, exception_handler)
    >>> status, headers, content = response.as_wsgi()
    >>> status
    '500 Internal Server Error'
    >>> 'Server Error' in str(content)
    True
    """
    try:
        return handler(request, *rest)
    except Exception:
        status = '500 Internal Server Error'
        return HTMLResponse(
            zoom.templates.internal_server_error_500,
            status
        )
Exemple #5
0
    def render(self, request):
        """render page"""

        logger = logging.getLogger(__name__)
        logger.debug('rendering page')

        self.content = render(self.header(), self.content, *self.args)

        app_theme = request.app.theme if hasattr(request, 'app') else None
        site_theme = request.site.theme
        self.theme = self.kwargs.get('theme', app_theme or site_theme
                                     or 'default')
        self.theme_uri = '/themes/' + self.theme

        zoom.render.add_helpers(
            zoom.forms.helpers(request),
            self.helpers(request),
        )

        template = zoom.tools.get_template(self.template, self.theme)

        if zoom.system.site.settings.site.cookie_consent:
            zoom.requires('cookieconsent')

        return HTMLResponse(template, status=self.status)
Exemple #6
0
def debug(request):
    """fake app for development purposes"""
    def format_section(title, content):
        """format a section for debugging output"""
        return '<pre>\n====== %s ======\n%s\n</pre>' % (title, repr(content))

    def formatr(title, content):
        """format a section for debugging output in raw form"""
        return '<pre>\n====== %s ======\n%s</pre>' % (title, content)

    content = []

    try:
        status = '200 OK'

        if request.module == 'wsgi':
            title = 'Hello from WSGI!'
        else:
            title = 'Hello from CGI!'

        content.extend([
            '<br>\n',
            '<img src="/themes/default/images/banner_logo.png" />\n',
            '<hr>\n',
            # '<pre>{printed_output}</pre>\n',
            '<img src="/static/zoom/images/checkmark.png" />\n',
            '<br>\n',
            title,
        ])

        # content.append(formatr('printed output', '{printed_output}'))

        content.append(formatr('test form', SAMPLE_FORM))
        content.append(formatr('request', request))
        content.append(
            formatr(
                'paths',
                json.dumps(dict(
                    path=[sys.path],
                    directory=os.path.abspath('.'),
                    pathname=__file__,
                ),
                           indent=2)))
        content.append(
            formatr('environment',
                    json.dumps(list(os.environ.items()), indent=2)))

        # print('testing printed output')

        data = request.data
        if 'photo' in data and data['photo'].filename:
            content.append(format_section('filename', data['photo'].filename))
            content.append(format_section('filedata', data['photo'].value))

    except Exception:
        content = ['<pre>{}</pre>'.format(traceback.format_exc())]

    return HTMLResponse(''.join(content), status=status)
Exemple #7
0
def respond(content, request):
    """construct a response"""
    if content:
        if isinstance(content, Response):
            result = content

        elif hasattr(content, 'render') and content.render:
            result = content.render(request)

        elif isinstance(content, (list, set, tuple)):
            result = HTMLResponse(''.join(content))

        elif isinstance(content, str):
            result = HTMLResponse(content)

        else:
            result = HTMLResponse('OK')

        return result
def debug(request):  # pragma: no cover
    """Debugging page

    >>> type(debug(zoom.request.build('http://localhost/')))
    <class 'zoom.response.HTMLResponse'>
    """

    def section(title, content):
        """format a section for debugging output in raw form"""
        return '<h2>%s</h2>%s' % (title, content)

    pretty = zoom.utils.pretty

    content = []

    try:

        if request.module == 'wsgi':
            title = 'Hello from WSGI!'
        else:
            title = 'Hello from CGI!'

        content.extend([
            '<img src="/static/zoom/images/checkmark.png" />ZOOM Debug',
            '<hr>',
            '<h1>',
            title,
            '</h1>',
        ])

        content.extend(
            section('request', '<pre>%s</pre>' % request) +
            section(
                'paths',
                '<pre>%s</pre>' % pretty(
                    dict(
                        path=[sys.path],
                        directory=os.path.abspath('.'),
                        pathname=__file__,
                    )
                )
            ) +
            section('request.env', '<pre>%s</pre>' % pretty(request.env)) +
            section('os.env', '<pre>%s</pre>' % pretty(os.environ))
        )

    except Exception:
        content = ['<pre>{}</pre>'.format(traceback.format_exc())]

    return HTMLResponse(''.join(content))
Exemple #9
0
def run_as_app(a_request):
    """run as a wsgi style app"""

    request.__dict__ = a_request.__dict__

    data.clear()
    data.update(request.data)

    del route[:]
    route.extend(request.route)

    if not os.path.exists(os.path.join(request.instance, 'dz.conf')):
        response = HTMLResponse(NEW_INSTALL_MESSAGE)
    else:
        response = generate_response(request.instance)

    return response
Exemple #10
0
    def render(self, request):
        """render page"""

        logger = logging.getLogger(__name__)
        logger.debug('rendering page')

        if self.title or self.subtitle or self.actions or self.search:
            full_page = Component(PageHeader(page=self), self.content)
        else:
            full_page = Component(self.content)
        self.content = full_page.render()

        zoom.render.add_helpers(
            zoom.forms.helpers(request),
            self.helpers(request),
        )

        template = request.site.get_template(self.template)

        return HTMLResponse(template)
Exemple #11
0
    def render(self, request):
        """render page"""

        logger = logging.getLogger(__name__)
        logger.debug('rendering page')

        if self.title or self.subtitle or self.actions or self.search:
            full_page = Component(PageHeader(page=self), self.content)
        else:
            full_page = Component(self.content)
        self.content = full_page.render()

        self.theme = self.kwargs.get('theme', zoom.system.site.theme)
        self.theme_uri = '/themes/' + self.theme

        zoom.render.add_helpers(
            zoom.forms.helpers(request),
            self.helpers(request),
        )

        template = zoom.tools.get_template(self.template, self.theme)

        return HTMLResponse(template)
Exemple #12
0
def serve_static(request, handler, *rest):
    """Serve a static file

    Static files can be served in serveral ways.  This particular
    middleware intended to be inserted into the middleware stack
    near the front before most other things.  The reason being is
    that in many cases the static files are not site specific or
    app specific but rather are shared by the entire instance.  In
    addition, many times static files require no authorization or
    special rights.  This means that in many cases static files
    can be served without knowing who is asking or what site they
    are for.  That is what this middleware does.

    This handler is mainly intended for development purposes as
    in a production evironment this type of content would typically
    be served up by the HTTP server or a caching layer.

    Note: This layer looks in four separate places for static files
    to serve.  Three related to the zoom instance, and one, as a last
    resort, from the zoom library itself.  If you are concerned
    about exposing the wrong files, be careful what you put in those
    directories or better yet, use a proxy.

    In addition to this instance wide static serving Sites and Apps
    may implement static file serving.  If they do, this layer is
    unaware of that fact.

    The locations this handler will look are relative to the zoom
    instance. They are:
        <instance>/static
        <instance>/www/static
        <instance>/../static
        zoom/web/www/static

    >>> url = 'http://localhost/static/zoom/zoom.js'
    >>> request = zoom.request.build(url)
    >>> result = serve_static(request, lambda a: False)
    >>> isinstance(result, JavascriptResponse)
    True

    >>> url = 'http://localhost/notstatic/zoom/zoom.js'
    >>> request = zoom.request.build(url)
    >>> result = serve_static(request, lambda a: False)
    >>> isinstance(result, JavascriptResponse)
    False
    """
    if request.path.startswith('/static/'):
        logger = logging.getLogger(__name__)
        isdir, join = os.path.isdir, os.path.join
        locations = list(
            filter(isdir, [
                join(request.instance, 'static'),
                join(request.instance, 'www', 'static'),
                join(request.instance, '..', 'static'),
                zoom.tools.zoompath('zoom', '_assets', 'web', 'www', 'static'),
            ]))
        for location in locations:
            pathname = join(location, *request.route[1:])
            logger.debug('looking for %r', pathname)
            if os.path.isfile(pathname):
                return serve_response(pathname)
        path = '/'.join(request.route[1:])
        logger.warning('static resource %r not found in %r', path, locations)
        msg = 'resource not found: {!r}'
        return HTMLResponse(msg.format(path), status='404 Not Found')
    else:
        return handler(request, *rest)
Exemple #13
0
def serve_response(*path):
    """Serve up various respones with their correct response type

    >>> zoom_js = zoom.tools.zoompath('zoom/_assets/web/www/static/zoom/zoom.js')
    >>> response = serve_response(zoom_js)
    >>> isinstance(response, JavascriptResponse)
    True

    >>> zoom_path = zoom.tools.zoompath('zoom', '_assets', 'web')
    >>> response = serve_response(zoom_path, 'www/static/zoom/nada.js')
    >>> isinstance(response, JavascriptResponse)
    False

    >>> response.content
    "file not found: 'www/static/zoom/nada.js'"
    >>> response.status
    '404 Not Found'

    >>> zoom_path = zoom.tools.zoompath('zoom', '_assets', 'web')
    >>> response = serve_response(zoom_path, 'www/static/zoom/images')
    >>> isinstance(response, JavascriptResponse)
    False

    >>> response.content
    "unknown file type ''"
    >>> response.status
    '415 Unsupported Media Type'
    """
    known_types = dict(
        png=PNGResponse,
        jpg=JPGResponse,
        gif=PNGResponse,
        ico=ICOResponse,
        css=CSSResponse,
        sass=CSSResponse,
        js=JavascriptResponse,
        ttf=TTFResponse,
        json=JSONResponse,
        woff=WOFFResponse,
        woff2=WOFF2Response,
        map=BinaryResponse,
        svg=SVGResponse,
    )
    exists = os.path.exists
    isfile = os.path.isfile
    pathname = os.path.realpath(os.path.join(*path))

    logger = logging.getLogger(__name__)
    logger.debug('attempting to serve up file %r', pathname)

    if not isfile(pathname) and pathname.endswith('.css'):
        alt_pathname = pathname[:-3] + 'sass'
        logger.debug('trying alt_pathname %r', alt_pathname)
        if isfile(alt_pathname):
            pathname = alt_pathname
        else:
            raise Exception('not a file')

    if exists(pathname):
        pathnamel = pathname.lower()
        _, file_type = os.path.splitext(pathnamel)
        file_type = file_type[1:]
        response_type = known_types.get(file_type)
        if response_type:

            if file_type == 'json':

                with open(pathname, 'rb') as f:
                    data = f.read()

                # JSONResponse expects an object which it will seriaize
                # so this unserializaing / reserializing an extra step
                # which may be unnecessary.  For now, we'll use the
                # JSONResponse as designed but we may eventually want to
                # create a different response type in this case.
                data = zoom.jsonz.loads(data)

            elif file_type == 'sass':
                logger.debug('rendering sass file response %r', pathname)
                data = zoom.tools.sass(pathname).encode('utf8')

            else:
                with open(pathname, 'rb') as f:
                    data = f.read()

            return response_type(data)

        msg = 'unknown file type {!r}'.format(file_type)
        logger.warning(msg)
        return HTMLResponse(msg, status='415 Unsupported Media Type')
    else:
        logger.warning('unable to serve file %r', pathname)
        relative_path = os.path.join(*path[1:])
        msg = 'file not found: {!r}'
        return HTMLResponse(msg.format(relative_path), status='404 Not Found')
Exemple #14
0
def generate_response(instance_path, start_time=None):
    """generate response to web request"""

    profiler = None
    debugging = True

    system_timer = SystemTimer(start_time)

    # capture stdout
    real_stdout = sys.stdout
    sys.stdout = StringIO.StringIO()
    try:
        try:
            # initialize context
            system.setup(instance_path, request.server, system_timer)
            system_timer.add('system initializated')

            user.setup()
            system_timer.add('user initializated')

            manager.setup()
            system_timer.add('manager initializated')

            if user.is_disabled:
                # we know who the user is, and their account is disabled
                msg = 'User {user.link} is disabled'
                raise UnauthorizedException(msg.format(user=user))

            debugging = (system.debugging or system.show_errors
                         or user.is_developer or user.is_administrator)

            session = system.session

            if system.track_visits:
                visited(request.subject, session.sid)

            csrf_token = data.pop('csrf_token', None)
            if request.method == 'POST' and system.csrf_validation:
                if csrf_token == session.csrf_token:
                    del session.csrf_token
                else:
                    msg = 'expected:%s got:%s' % (session.csrf_token,
                                                  csrf_token)
                    raise CrossSiteRequestForgeryAttempt(msg)

            requested_app_name = manager.requested_app_name()
            default_app_name = manager.default_app_name()

            os.chdir(system.config.sites_path)

            if not request.route:
                request.route.append(default_app_name)

            for app in manager.apps.values():
                app.initialize(request)

            if manager.can_run(requested_app_name):
                system.app = manager.get_app(requested_app_name)

                profiler = (system.profile or user.profile) \
                    and cProfile.Profile()
                if profiler:
                    profiler.enable()

                system_timer.add('app ready')

                response = system.app.run(request)

                system_timer.add('app returned')

                if profiler:
                    profiler.disable()

            elif manager.can_run_if_login(requested_app_name):
                # as it stands now, an attacker can generate a list of
                # enabled apps by iterating the/a namespace and seeing
                # which ones return a logon form.

                def referrer():
                    """get the referrer"""
                    uri = urllib.urlencode(dict(referrer=request.uri))
                    return uri and "?{}".format(uri) or ''

                response = redirect_to('/login{}'.format(referrer()))

            elif not requested_app_name:
                app = manager.get_app(default_app_name)
                if app:
                    system.app = app
                else:
                    raise Exception(default_app_name + ' app missing')
                response = system.app.run(request)

            elif manager.can_run(default_app_name):
                response = redirect_to('/')

            else:
                response = Page(PAGE_MISSING_MESSAGE).render()
                response.status = '404'

            timeout = session.save_session()
            set_session_cookie(
                response,
                session.sid,
                request.subject,
                timeout,
                system.secure_cookies,
            )

        except UnauthorizedException:
            logger.security('unauthorized access attempt')
            if debugging:
                raise
            else:
                response = Page(UNAUTHORIZED_MESSAGE).render()
                response.status = '403'

        except CrossSiteRequestForgeryAttempt:
            logger.security('cross site forgery attempt')
            if debugging:
                raise
            else:
                response = redirect_to('/')

        except SessionExpiredException:
            response = Page(
                load_template('system_application_session_expired',
                              SESSION_EXPIRED_MESSAGE)).render()

        except:
            t = htmlquote(traceback.format_exc())
            logger.error(t)
            if debugging:
                try:
                    tpl = load_template('system_application_error_developer',
                                        STANDARD_ERROR_MESSAGE)
                    msg = tpl % dict(message=t)
                except:
                    msg = SYSTEM_ERROR_MESSAGE % dict(message=t)
            else:
                try:
                    msg = load_template('system_application_error_user',
                                        FRIENDLY_ERROR_MESSAGE)
                except:
                    msg = FRIENDLY_ERROR_MESSAGE

            try:
                response = Page(msg).render()
            except:
                response = HTMLResponse(msg)

        if profiler:
            stats_s = StringIO.StringIO()
            sortby = 'cumulative'
            ps = pstats.Stats(profiler, stream=stats_s)
            ps.sort_stats(sortby)
            ps.print_stats(.1)
            t = stats_s.getvalue()
            t = t.replace(system.lib_path, '~zoom').replace(
                '/usr/lib/python2.7/dist-packages/',
                '~').replace('/usr/local/lib/python2.7/dist-packages/', '~')

            print(''.join([
                '\n\n  System Performance Metrics\n ' + '=' * 30,
                system_timer.report(),
                system.database.report(),
                system.db.report(), '  Profiler\n ------------\n', t
            ]))
    finally:
        printed_output = sys.stdout.getvalue()
        sys.stdout.close()
        sys.stdout = real_stdout
        logger.complete()

    system.release()

    if hasattr(response, 'printed_output'):
        response.printed_output = printed_output.replace('<', '&lt;').replace(
            '>', '&gt;')

    return response