Ticket #210: security_server_patch_2.diff

File security_server_patch_2.diff, 49.7 kB (added by sypasche, 4 months ago)

for review

  • server/python/testapp/development.ini

    old new  
     1# 
     2# testapp - Pylons development environment configuration 
     3# 
     4# The %(here)s variable will be replaced with the parent directory of this file 
     5# 
     6[DEFAULT] 
     7debug = true 
     8# Uncomment and replace with the address which should receive any error reports 
     9#email_to = you@yourdomain.com 
     10smtp_server = localhost 
     11error_email_from = paste@localhost 
     12 
     13[server:main] 
     14use = egg:Paste#http 
     15host = 0.0.0.0 
     16port = 5000 
     17 
     18[app:main] 
     19use = egg:testapp 
     20full_stack = true 
     21cache_dir = %(here)s/data 
     22beaker.session.key = testapp 
     23beaker.session.secret = somesecret 
     24 
     25# If you'd like to fine-tune the individual locations of the cache data dirs 
     26# for the Cache data, or the Session saves, un-comment the desired settings 
     27# here: 
     28#beaker.cache.data_dir = %(here)s/data/cache 
     29#beaker.session.data_dir = %(here)s/data/sessions 
     30 
     31# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* 
     32# Debug mode will enable the interactive debugging tool, allowing ANYONE to 
     33# execute malicious code after an exception is raised. 
     34#set debug = false 
     35 
     36 
     37# Logging configuration 
     38[loggers] 
     39keys = root, testapp 
     40 
     41[handlers] 
     42keys = console 
     43 
     44[formatters] 
     45keys = generic 
     46 
     47[logger_root] 
     48level = INFO 
     49handlers = console 
     50 
     51[logger_testapp] 
     52level = DEBUG 
     53handlers = 
     54qualname = testapp 
     55 
     56[handler_console] 
     57class = StreamHandler 
     58args = (sys.stderr,) 
     59level = NOTSET 
     60formatter = generic 
     61 
     62[formatter_generic] 
     63format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s 
     64datefmt = %H:%M:%S 
  • server/python/testapp/testapp/tests/functional/test_security.py

    old new  
     1from testapp.tests import * 
     2 
     3import simplejson 
     4 
     5class TestSecurityController(TestController): 
     6    def _get_permissions(self, user): 
     7        extra_environ = {} 
     8        if user: 
     9            extra_environ['REMOTE_USER'] = user 
     10        response = self.app.get(url_for(controller='security', 
     11                                        action='permissions'), 
     12                                extra_environ=extra_environ) 
     13        return simplejson.loads(response.body)['permissions'] 
     14 
     15    def test_permissions(self): 
     16        permissions = self._get_permissions(None) 
     17 
     18        assert permissions["application"] == False 
     19        assert permissions["application.widgets.edit"] == False 
     20        assert permissions.has_key("layer") 
     21        # TODO test inside the layer properties 
     22 
     23        permissions = self._get_permissions("alice") 
     24 
     25        assert permissions["application"] == True 
     26        assert permissions["application.widgets.edit"] == True 
     27        assert permissions.has_key("layer") 
     28        # TODO test inside the layer properties 
     29 
     30        permissions = self._get_permissions("carol") 
     31 
     32        assert permissions["application"] == True 
     33        assert permissions["application.widgets.edit"] == False 
     34        assert permissions.has_key("layer") 
     35        # TODO test inside the layer properties 
  • server/python/testapp/testapp/tests/functional/test_wms_auth_proxy.py

    old new  
     1from testapp.tests import * 
     2 
     3import paste.fixture 
     4import BaseHTTPServer 
     5import threading 
     6import urllib2 
     7import time 
     8 
     9# When running the tests, no HTTP server is started. To simulate a WMS server, 
     10# a small HTTP server is run on port 9999. 
     11 
     12 
     13class WMSHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): 
     14    def do_GET(self): 
     15        self.send_response(200) 
     16        self.send_header("Content-type", "text/plain") 
     17        self.end_headers() 
     18        self.wfile.write("Dummy response\n") 
     19 
     20def run_httpd(server_class=BaseHTTPServer.HTTPServer, 
     21              handler_class=WMSHTTPRequestHandler): 
     22    server_address = ('', 9999) 
     23    httpd = server_class(server_address, handler_class) 
     24    server_running = True 
     25    threading.Thread(target=httpd.serve_forever).start() 
     26    # Wait some times to allow the server to startup 
     27    import time 
     28    time.sleep(0.5) 
     29 
     30# Having the setup/teardown method inside TestWmsAuthProxyController is not working 
     31# so let's have them at the module level. 
     32def setup(): 
     33    run_httpd() 
     34 
     35class TestWmsAuthProxyController(TestController): 
     36    def check_access(self, alias, user, layers, expected_allowed): 
     37        # url_for() is not working for "<url>/*more syntax. So hardcoding is 
     38        # needed 
     39        url = "/wms_auth_proxy/%s/wms?layers=%s" % (alias, ",".join(layers)) 
     40        allowed = True 
     41        content = "" 
     42        try: 
     43            extra_environ = {} 
     44            if user: 
     45                extra_environ['REMOTE_USER'] = user 
     46            content = self.app.get(url, extra_environ=extra_environ) 
     47        except paste.fixture.AppError, e: 
     48            print "Exception: %s %s" % (e.__class__, e) 
     49            allowed = False 
     50        assert expected_allowed == allowed, "Unexpected access to resource " + \ 
     51               "alias: %s user: %s layers: %s allowed: %s" % \ 
     52               (alias, user, layers, expected_allowed) 
     53        # FIXME: can't make a distinction between invalid alias and denied response 
     54        if expected_allowed: 
     55            assert content, "Content shouldn't be empty (%s)" % repr(content) 
     56 
     57    def test_basic(self): 
     58        # Check that we fail for invalid alias 
     59        try: 
     60            self.check_access("non_existant", None, [], True) 
     61        except AssertionError: 
     62            pass 
     63        else:  
     64            raise AssertionError("Should have raised an assertion about wrong alias") 
     65 
     66    def test_no_restriction(self): 
     67        self.check_access("no_restrictions", None, [], True) 
     68        self.check_access("no_restrictions", "alice", ["parkings"], True) 
     69 
     70    def test_default_deny(self): 
     71        # Should we still allow access if no layers are given? 
     72        self.check_access("default_deny", None, [], True) 
     73        self.check_access("default_deny", "bob", [], True) 
     74        self.check_access("default_deny", None, ["parkings"], False) 
     75        self.check_access("default_deny", None, ["summits"], False) 
     76        self.check_access("default_deny", None, ["parkings", "summits"], False) 
     77 
     78        self.check_access("default_deny", "alice", ["parkings"], True) 
     79        self.check_access("default_deny", "alice", ["parkings", "summits"], False) 
     80 
     81    def test_default_allow(self): 
     82        self.check_access("default_allow", None, [], True) 
     83        self.check_access("default_allow", "bob", [], True) 
     84        self.check_access("default_allow", None, ["parkings"], False) 
     85        self.check_access("default_allow", None, ["summits"], True) 
     86        self.check_access("default_allow", None, ["parkings", "summits"], False) 
     87 
     88        self.check_access("default_allow", "alice", ["parkings"], True) 
     89        self.check_access("default_allow", "alice", ["parkings", "summits"], True) 
     90 
     91    def test_wms0(self): 
     92        self.check_access("wms0", None, [], True) 
     93        self.check_access("wms0", None, ["background"], True) 
     94        self.check_access("wms0", None, ["parkings"], False) 
     95        self.check_access("wms0", None, ["summits"], False) 
     96        self.check_access("wms0", None, ["background", "parkings"], False) 
     97        self.check_access("wms0", None, ["parkings", "summits"], False) 
     98        self.check_access("wms0", None, ["background", "parkings", "summits"], False) 
     99 
     100        self.check_access("wms0", "alice", [], True) 
     101        self.check_access("wms0", "alice", ["background"], True) 
     102        self.check_access("wms0", "alice", ["parkings"], True) 
     103        self.check_access("wms0", "alice", ["summits"], False) 
     104        self.check_access("wms0", "alice", ["background", "parkings"], True) 
     105        self.check_access("wms0", "alice", ["parkings", "summits"], False) 
     106        self.check_access("wms0", "alice", ["background", "parkings", "summits"], False) 
     107 
     108        self.check_access("wms0", "bob", [], True) 
     109        self.check_access("wms0", "bob", ["background"], True) 
     110        self.check_access("wms0", "bob", ["parkings"], True) 
     111        self.check_access("wms0", "bob", ["summits"], True) 
     112        self.check_access("wms0", "bob", ["background", "parkings"], True) 
     113        self.check_access("wms0", "bob", ["parkings", "summits"], True) 
     114        self.check_access("wms0", "bob", ["background", "parkings", "summits"], True) 
  • server/python/testapp/testapp/tests/__init__.py

    old new  
     1"""Pylons application test package 
     2 
     3When the test runner finds and executes tests within this directory, 
     4this file will be loaded to setup the test environment. 
     5 
     6It registers the root directory of the project in sys.path and 
     7pkg_resources, in case the project hasn't been installed with 
     8setuptools. It also initializes the application via websetup (paster 
     9setup-app) with the project's test.ini configuration file. 
     10""" 
     11import os 
     12import sys 
     13from unittest import TestCase 
     14 
     15import pkg_resources 
     16import paste.fixture 
     17import paste.script.appinstall 
     18from paste.deploy import loadapp 
     19from routes import url_for 
     20 
     21__all__ = ['url_for', 'TestController'] 
     22 
     23here_dir = os.path.dirname(os.path.abspath(__file__)) 
     24conf_dir = os.path.dirname(os.path.dirname(here_dir)) 
     25 
     26sys.path.insert(0, conf_dir) 
     27pkg_resources.working_set.add_entry(conf_dir) 
     28pkg_resources.require('Paste') 
     29pkg_resources.require('PasteScript') 
     30 
     31test_file = os.path.join(conf_dir, 'test.ini') 
     32cmd = paste.script.appinstall.SetupCommand('setup-app') 
     33cmd.run([test_file]) 
     34 
     35class TestController(TestCase): 
     36 
     37    def __init__(self, *args, **kwargs): 
     38        wsgiapp = loadapp('config:test.ini', relative_to=conf_dir) 
     39        self.app = paste.fixture.TestApp(wsgiapp) 
     40        TestCase.__init__(self, *args, **kwargs) 
  • server/python/testapp/testapp/config/permissions.py

    old new  
     1from authkit.permissions import HasAuthKitRole, ValidAuthKitUser 
     2from mapfish.controllers.security import Deny 
     3 
     4permissions = { 
     5    "application": ValidAuthKitUser(), 
     6    "application.widgets.edit": HasAuthKitRole("editor"), 
     7    "widgets.print.dpi.100": Deny() 
     8} 
  • server/python/testapp/testapp/config/middleware.py

    old new  
     1"""Pylons middleware initialization""" 
     2from paste.cascade import Cascade 
     3from paste.registry import RegistryManager 
     4from paste.urlparser import StaticURLParser 
     5from paste.deploy.converters import asbool 
     6 
     7from pylons import config 
     8from pylons.error import error_template 
     9from pylons.middleware import error_mapper, ErrorDocuments, ErrorHandler, \ 
     10    StaticJavascripts 
     11from pylons.wsgiapp import PylonsApp 
     12 
     13from testapp.config.environment import load_environment 
     14 
     15def make_app(global_conf, full_stack=True, **app_conf): 
     16    """Create a Pylons WSGI application and return it 
     17 
     18    ``global_conf`` 
     19        The inherited configuration for this application. Normally from 
     20        the [DEFAULT] section of the Paste ini file. 
     21 
     22    ``full_stack`` 
     23        Whether or not this application provides a full WSGI stack (by 
     24        default, meaning it handles its own exceptions and errors). 
     25        Disable full_stack when this application is "managed" by 
     26        another WSGI middleware. 
     27 
     28    ``app_conf`` 
     29        The application's local configuration. Normally specified in the 
     30        [app:<name>] section of the Paste ini file (where <name> 
     31        defaults to main). 
     32    """ 
     33    # Configure the Pylons environment 
     34    load_environment(global_conf, app_conf) 
     35 
     36    # The Pylons WSGI app 
     37    app = PylonsApp() 
     38 
     39    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares) 
     40 
     41    if asbool(full_stack): 
     42        # Handle Python exceptions 
     43        app = ErrorHandler(app, global_conf, error_template=error_template, 
     44                           **config['pylons.errorware']) 
     45 
     46        # AuthKit authentication 
     47        import authkit.authenticate 
     48        app = authkit.authenticate.middleware(app, app_conf) 
     49 
     50        # Display error documents for 401, 403, 404 status codes (and 
     51        # 500 when debug is disabled) 
     52        app = ErrorDocuments(app, global_conf, mapper=error_mapper, **app_conf) 
     53 
     54    # Establish the Registry for this application 
     55    app = RegistryManager(app) 
     56 
     57    # Static files 
     58    javascripts_app = StaticJavascripts() 
     59    static_app = StaticURLParser(config['pylons.paths']['static_files']) 
     60    app = Cascade([static_app, javascripts_app, app]) 
     61    return app 
  • server/python/testapp/testapp/config/environment.py

    old new  
     1"""Pylons environment configuration""" 
     2import os 
     3 
     4from pylons import config 
     5 
     6import testapp.lib.app_globals as app_globals 
     7import testapp.lib.helpers 
     8from testapp.config.routing import make_map 
     9 
     10def load_environment(global_conf, app_conf): 
     11    """Configure the Pylons environment via the ``pylons.config`` 
     12    object 
     13    """ 
     14    # Pylons paths 
     15    root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 
     16    paths = dict(root=root, 
     17                 controllers=os.path.join(root, 'controllers'), 
     18                 static_files=os.path.join(root, 'public'), 
     19                 templates=[os.path.join(root, 'templates')]) 
     20 
     21    # Initialize config with the basic options 
     22    config.init_app(global_conf, app_conf, package='testapp', 
     23                    template_engine='mako', paths=paths) 
     24 
     25    config['routes.map'] = make_map() 
     26    config['pylons.g'] = app_globals.Globals() 
     27    config['pylons.h'] = testapp.lib.helpers 
     28 
     29    # Customize templating options via this variable 
     30    tmpl_options = config['buffet.template_options'] 
     31 
     32    # CONFIGURATION OPTIONS HERE (note: all config options will override 
     33    # any Pylons config options) 
  • server/python/testapp/testapp/config/routing.py

    old new  
     1"""Routes configuration 
     2 
     3The more specific and detailed routes should be defined first so they 
     4may take precedent over the more generic routes. For more information 
     5refer to the routes manual at http://routes.groovie.org/docs/ 
     6""" 
     7from pylons import config 
     8from routes import Mapper 
     9 
     10def make_map(): 
     11    """Create, configure and return the routes Mapper""" 
     12    map = Mapper(directory=config['pylons.paths']['controllers'], 
     13                 always_scan=config['debug']) 
     14 
     15    # The ErrorController route (handles 404/500 error pages); it should 
     16    # likely stay at the top, ensuring it can always be resolved 
     17    map.connect('error/:action/:id', controller='error') 
     18 
     19    # CUSTOM ROUTES HERE 
     20    map.connect('wms_auth_proxy/*more', controller='wms_auth_proxy', action='get', 
     21                conditions={"method": ['GET']}) 
     22 
     23 
     24    map.connect(':controller/:action/:id') 
     25    map.connect('*url', controller='template', action='view') 
     26 
     27    return map 
  • server/python/testapp/testapp/websetup.py

    old new  
     1"""Setup the testapp application""" 
     2import logging 
     3 
     4from paste.deploy import appconfig 
     5from pylons import config 
     6 
     7from testapp.config.environment import load_environment 
     8 
     9log = logging.getLogger(__name__) 
     10 
     11def setup_config(command, filename, section, vars): 
     12    """Place any commands to setup testapp here""" 
     13    conf = appconfig('config:' + filename) 
     14    load_environment(conf.global_conf, conf.local_conf) 
  • server/python/testapp/testapp/controllers/wms_auth_proxy.py

    old new  
     1from mapfish.controllers.auth_proxy import AuthProxyController 
     2from mapfish.controllers.auth_proxy import WMSLayer, TileCacheLayer 
     3from mapfish.controllers.security import Deny 
     4 
     5from authkit.permissions import HasAuthKitRole, ValidAuthKitUser 
     6from authkit.authorize.pylons_adaptors import authorized 
     7 
     8from testapp.lib.base import * 
     9 
     10import logging 
     11log = logging.getLogger(__name__) 
     12 
     13def get_permissions(): 
     14    return WmsAuthProxyController()._get_permissions() 
     15 
     16class WmsAuthProxyController(AuthProxyController): 
     17    # FIXME: tests want to access the index method and fail if missing. 
     18    # Don't know where this is coming from. 
     19    def index(self): 
     20        return "" 
     21 
     22    def __init__(self): 
     23        layers = [] 
     24 
     25        # Configuration: 
     26        # 
     27        # Users 
     28        #  alice: rolealice, editor 
     29        #  bob: rolebob, admin 
     30        #  carol: - 
     31         
     32        # WMS sublayers: 
     33        #  parkings 
     34        #  summits 
     35        #  background 
     36 
     37        WMS_SERVER = "http://localhost:9999" 
     38 
     39        layers.append(WMSLayer(alias="no_restrictions", 
     40                               url=WMS_SERVER, 
     41                               layers={})) 
     42 
     43        layers.append(WMSLayer(alias="default_deny", 
     44                               url=WMS_SERVER, 
     45                               layers={ 
     46                                   "parkings": HasAuthKitRole('rolealice'), 
     47                                   "DEFAULT": Deny() 
     48                               })) 
     49 
     50        layers.append(WMSLayer(alias="default_allow", 
     51                               url=WMS_SERVER, 
     52                               layers={ 
     53                                   "parkings": HasAuthKitRole('rolealice') 
     54                               })) 
     55 
     56        layers.append(WMSLayer(alias="wms0", 
     57                               url=WMS_SERVER, 
     58                               layers={ 
     59                                   # background is public 
     60                                   "parkings": HasAuthKitRole('editor'), 
     61                                   "summits": HasAuthKitRole(['editor', 'admin'], all=True) 
     62                               })) 
     63 
     64        # TODO: test tilecache layer 
     65 
     66        self.set_layers(layers) 
  • server/python/testapp/testapp/controllers/error.py

    old new  
     1import cgi 
     2import os.path 
     3 
     4from paste.urlparser import StaticURLParser 
     5from pylons.middleware import error_document_template, media_path 
     6 
     7from testapp.lib.base import * 
     8 
     9class ErrorController(BaseController): 
     10    """Generates error documents as and when they are required. 
     11 
     12    The ErrorDocuments middleware forwards to ErrorController when error 
     13    related status codes are returned from the application. 
     14 
     15    This behaviour can be altered by changing the parameters to the 
     16    ErrorDocuments middleware in your config/middleware.py file. 
     17     
     18    """ 
     19    def document(self): 
     20        """Render the error document""" 
     21        page = error_document_template % \ 
     22            dict(prefix=request.environ.get('SCRIPT_NAME', ''), 
     23                 code=cgi.escape(request.params.get('code', '')), 
     24                 message=cgi.escape(request.params.get('message', ''))) 
     25        return page 
     26 
     27    def img(self, id): 
     28        """Serve Pylons' stock images""" 
     29        return self._serve_file(os.path.join(media_path, 'img'), id) 
     30 
     31    def style(self, id): 
     32        """Serve Pylons' stock stylesheets""" 
     33        return self._serve_file(os.path.join(media_path, 'style'), id) 
     34 
     35    def _serve_file(self, root, path): 
     36        """Call Paste's FileApp (a WSGI application) to serve the file 
     37        at the specified path 
     38        """ 
     39        static = StaticURLParser(root) 
     40        request.environ['PATH_INFO'] = '/%s' % path 
     41        return static(request.environ, self.start_response) 
  • server/python/testapp/testapp/controllers/template.py

    old new  
     1from testapp.lib.base import * 
     2 
     3class TemplateController(BaseController): 
     4 
     5    def view(self, url): 
     6        """By default, the final controller tried to fulfill the request 
     7        when no other routes match. It may be used to display a template 
     8        when all else fails, e.g.:: 
     9 
     10            def view(self, url): 
     11                return render('/%s' % url) 
     12 
     13        Or if you're using Mako and want to explicitly send a 404 (Not 
     14        Found) response code when the requested template doesn't exist:: 
     15 
     16            import mako.exceptions 
     17 
     18            def view(self, url): 
     19                try: 
     20                    return render('/%s' % url) 
     21                except mako.exceptions.TopLevelLookupException: 
     22                    abort(404) 
     23 
     24        By default this controller aborts the request with a 404 (Not 
     25        Found) 
     26        """ 
     27        abort(404) 
  • server/python/testapp/testapp/controllers/security.py

    old new  
     1import logging 
     2 
     3from testapp.lib.base import * 
     4import mapfish.controllers.security 
     5 
     6log = logging.getLogger(__name__) 
     7 
     8class SecurityController(mapfish.controllers.security.SecurityController): 
     9    pass 
  • server/python/testapp/testapp/lib/base.py

    old new  
     1"""The base Controller API 
     2 
     3Provides the BaseController class for subclassing, and other objects 
     4utilized by Controllers. 
     5""" 
     6from pylons import c, cache, config, g, request, response, session 
     7from pylons.controllers import WSGIController 
     8from pylons.controllers.util import abort, etag_cache, redirect_to 
     9from pylons.decorators import jsonify, validate 
     10from pylons.i18n import _, ungettext, N_ 
     11from pylons.templating import render 
     12 
     13import testapp.lib.helpers as h 
     14import testapp.model as model 
     15 
     16class BaseController(WSGIController): 
     17 
     18    def __call__(self, environ, start_response): 
     19        """Invoke the Controller""" 
     20        # WSGIController.__call__ dispatches to the Controller method 
     21        # the request is routed to. This routing information is 
     22        # available in environ['pylons.routes_dict'] 
     23        return WSGIController.__call__(self, environ, start_response) 
     24 
     25# Include the '_' function in the public names 
     26__all__ = [__name for __name in locals().keys() if not __name.startswith('_') \ 
     27           or __name == '_'] 
  • server/python/testapp/testapp/lib/helpers.py

    old new  
     1"""Helper functions 
     2 
     3Consists of functions to typically be used within templates, but also 
     4available to Controllers. This module is available to both as 'h'. 
     5""" 
     6from webhelpers import * 
  • server/python/testapp/testapp/lib/app_globals.py

    old new  
     1"""The application's Globals object""" 
     2from pylons import config 
     3 
     4class Globals(object): 
     5    """Globals acts as a container for objects available throughout the 
     6    life of the application 
     7    """ 
     8 
     9    def __init__(self): 
     10        """One instance of Globals is created during application 
     11        initialization and is available during requests via the 'g' 
     12        variable 
     13        """ 
     14        pass 
  • server/python/testapp/testapp/public/index.html

    old new  
     1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
     2   "http://www.w3.org/TR/html4/loose.dtd"> 
     3<html> 
     4<head> 
     5  <title>Pylons Default Page</title> 
     6  <style> 
     7    body { background-color: #fff; color: #333; } 
     8 
     9    body, p { 
     10      font-family: verdana, arial, helvetica, sans-serif; 
     11      font-size:   12px; 
     12      line-height: 18px; 
     13    } 
     14    pre { 
     15      background-color: #eee; 
     16      padding: 10px; 
     17      font-size: 11px; 
     18      line-height: 13px; 
     19    } 
     20 
     21    a { color: #000; } 
     22    a:visited { color: #666; } 
     23    a:hover { color: #fff; background-color:#000; } 
     24  </style> 
     25</head> 
     26<body> 
     27 
     28Test Pylons Web Application for MapFish 
     29 
     30</body> 
     31</html> 
  • server/python/testapp/setup.py

    old new  
     1try: 
     2    from setuptools import setup, find_packages 
     3except ImportError: 
     4    from ez_setup import use_setuptools 
     5    use_setuptools() 
     6    from setuptools import setup, find_packages 
     7 
     8setup( 
     9    name='testapp', 
     10    version="", 
     11    #description='', 
     12    #author='', 
     13    #author_email='', 
     14    #url='', 
     15    install_requires=["Pylons>=0.9.6.2"], 
     16    packages=find_packages(exclude=['ez_setup']), 
     17    include_package_data=True, 
     18    test_suite='nose.collector', 
     19    package_data={'testapp': ['i18n/*/LC_MESSAGES/*.mo']}, 
     20    #message_extractors = {'testapp': [ 
     21    #        ('**.py', 'python', None), 
     22    #        ('templates/**.mako', 'mako', None), 
     23    #        ('public/**', 'ignore', None)]}, 
     24    entry_points=""" 
     25    [paste.app_factory] 
     26    main = testapp.config.middleware:make_app 
     27 
     28    [paste.app_install] 
     29    main = pylons.util:PylonsInstaller 
     30    """, 
     31) 
  • server/python/testapp/docs/index.txt

    old new  
     1testapp 
     2+++++++ 
     3 
     4This is the main index page of your documentation. It should be written in 
     5`reStructuredText format <http://docutils.sourceforge.net/rst.html>`_. 
     6 
     7You can generate your documentation in HTML format by running this command:: 
     8 
     9    setup.py pudge 
     10 
     11For this to work you will need to download and install ``buildutils`` and 
     12``pudge``. 
  • server/python/testapp/testapp.egg-info/SOURCES.txt

    old new  
     1MANIFEST.in 
     2README.txt 
     3setup.cfg 
     4setup.py 
     5testapp/__init__.py 
     6testapp/websetup.py 
     7testapp.egg-info/PKG-INFO 
     8testapp.egg-info/SOURCES.txt 
     9testapp.egg-info/dependency_links.txt 
     10testapp.egg-info/entry_points.txt 
     11testapp.egg-info/paste_deploy_config.ini_tmpl 
     12testapp.egg-info/paster_plugins.txt 
     13testapp.egg-info/requires.txt 
     14testapp.egg-info/top_level.txt 
     15testapp/config/__init__.py 
     16testapp/config/environment.py 
     17testapp/config/middleware.py 
     18testapp/config/routing.py 
     19testapp/controllers/__init__.py 
     20testapp/controllers/error.py 
     21testapp/controllers/hello.py 
     22testapp/controllers/template.py 
     23testapp/lib/__init__.py 
     24testapp/lib/app_globals.py 
     25testapp/lib/base.py 
     26testapp/lib/helpers.py 
     27testapp/model/__init__.py 
     28testapp/public/index.html 
     29testapp/tests/__init__.py 
     30testapp/tests/test_models.py 
     31testapp/tests/functional/__init__.py 
     32testapp/tests/functional/test_hello.py 
  • server/python/testapp/testapp.egg-info/paste_deploy_config.ini_tmpl

    old new  
     1# 
     2# testapp - Pylons configuration 
     3# 
     4# The %(here)s variable will be replaced with the parent directory of this file 
     5# 
     6[DEFAULT] 
     7debug = true 
     8email_to = you@yourdomain.com 
     9smtp_server = localhost 
     10error_email_from = paste@localhost 
     11 
     12[server:main] 
     13use = egg:Paste#http 
     14host = 0.0.0.0 
     15port = 5000 
     16 
     17[app:main] 
     18use = egg:testapp 
     19full_stack = true 
     20cache_dir = %(here)s/data 
     21beaker.session.key = testapp 
     22beaker.session.secret = ${app_instance_secret} 
     23app_instance_uuid = ${app_instance_uuid} 
     24 
     25# If you'd like to fine-tune the individual locations of the cache data dirs 
     26# for the Cache data, or the Session saves, un-comment the desired settings 
     27# here: 
     28#beaker.cache.data_dir = %(here)s/data/cache 
     29#beaker.session.data_dir = %(here)s/data/sessions 
     30 
     31# WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* 
     32# Debug mode will enable the interactive debugging tool, allowing ANYONE to 
     33# execute malicious code after an exception is raised. 
     34set debug = false 
     35 
     36 
     37# Logging configuration 
     38[loggers] 
     39keys = root 
     40 
     41[handlers] 
     42keys = console 
     43 
     44[formatters] 
     45keys = generic 
     46 
     47[logger_root] 
     48level = INFO 
     49handlers = console 
     50 
     51[handler_console] 
     52class = StreamHandler 
     53args = (sys.stderr,) 
     54level = NOTSET 
     55formatter = generic 
     56 
     57[formatter_generic] 
     58format = %(asctime)s %(levelname)-5.5s [%(name)s] %(message)s 
  • server/python/testapp/testapp.egg-info/top_level.txt

    old new  
  • server/python/testapp/testapp.egg-info/PKG-INFO

    old new  
     1Metadata-Version: 1.0 
     2Name: testapp 
     3Version: 0.0.0dev 
     4Summary: UNKNOWN 
     5Home-page: UNKNOWN 
     6Author: UNKNOWN 
     7Author-email: UNKNOWN 
     8License: UNKNOWN 
     9Description: UNKNOWN 
     10Platform: UNKNOWN 
  • server/python/testapp/testapp.egg-info/entry_points.txt

    old new  
     1 
     2    [paste.app_factory] 
     3    main = testapp.config.middleware:make_app 
     4 
     5    [paste.app_install] 
     6    main = pylons.util:PylonsInstaller 
     7     
  • server/python/testapp/testapp.egg-info/dependency_links.txt

    old new  
  • server/python/testapp/testapp.egg-info/paster_plugins.txt

    old new  
     1Pylons 
     2WebHelpers 
     3PasteScript 
  • server/python/testapp/testapp.egg-info/requires.txt

    old new  
  • server/python/testapp/MANIFEST.in

    old new  
     1recursive-include testapp/public * 
     2recursive-include testapp/templates * 
  • server/python/testapp/README.txt

    old new  
     1This file is for you to describe the testapp application. Typically 
     2you would include information such as the information below: 
     3 
     4Installation and Setup 
     5====================== 
     6 
     7Install ``testapp`` using easy_install:: 
     8 
     9    easy_install testapp 
     10 
     11Make a config file as follows:: 
     12 
     13    paster make-config testapp config.ini 
     14 
     15Tweak the config file as appropriate and then setup the application:: 
     16 
     17    paster setup-app config.ini 
     18 
     19Then you are ready to go. 
  • server/python/testapp/test.ini

    old new  
     1# 
     2# testapp - Pylons testing environment configuration 
     3# 
     4# The %(here)s variable will be replaced with the parent directory of this file 
     5# 
     6[DEFAULT] 
     7debug = true 
     8# Uncomment and replace with the address which should receive any error reports 
     9#email_to = you@yourdomain.com 
     10smtp_server = localhost 
     11error_email_from = paste@localhost 
     12 
     13[server:main] 
     14use = egg:Paste#http 
     15host = 0.0.0.0 
     16port = 5000 
     17 
     18[app:main] 
     19use = config:development.ini 
     20 
     21# Add additional test specific configuration options as necessary. 
     22 
     23# If you'd like to fine-tune the individual locations of the cache data dirs 
     24# for the Cache data, or the Session saves, un-comment the desired settings 
     25# here: 
     26#beaker.cache.data_dir = %(here)s/data/cache 
     27#beaker.session.data_dir = %(here)s/data/sessions 
     28 
     29authkit.setup.method = form, cookie 
     30authkit.form.authenticate.user.data = alice:alice rolealice editor 
     31                                      bob:bob rolebob admin editor 
     32                                      carol:carol 
     33# XXX should be generated 
     34authkit.cookie.secret = 3db76b5f-cb74-448f-b291-63f3afc8e1bc 
     35authkit.cookie.signoutpath = /logout 
  • server/python/testapp/setup.cfg

    old new  
     1[egg_info] 
     2tag_build = dev 
     3tag_svn_revision = true 
     4 
     5[easy_install] 
     6find_links = http://www.pylonshq.com/download/ 
     7 
     8[pudge] 
     9theme = pythonpaste.org 
     10 
     11# Add extra doc files here with spaces between them 
     12docs = docs/index.txt 
     13 
     14# Doc Settings 
     15doc_base = docs/ 
     16dest = docs/html 
     17 
     18# Add extra modules here separated with commas 
     19modules = testapp 
     20title = Testapp 
     21organization = Pylons 
     22 
     23# Highlight code-block sections with Pygments 
     24highlighter = pygments 
     25 
     26# Optionally add extra links 
     27#organization_url = http://pylonshq.com/ 
     28#trac_url = http://pylonshq.com/project 
     29settings = no_about=true 
     30 
     31# Optionally add extra settings 
     32#           link1=/community/ Community 
     33#           link2=/download/ Download 
     34 
     35[publish] 
     36doc-dir=docs/html 
     37make-dirs=1 
     38 
     39# Babel configuration 
     40[compile_catalog] 
     41domain = testapp 
     42directory = testapp/i18n 
     43statistics = true 
     44 
     45[extract_messages] 
     46add_comments = TRANSLATORS: 
     47output_file = testapp/i18n/testapp.pot 
     48width = 80 
     49 
     50[init_catalog] 
     51domain = testapp 
     52input_file = testapp/i18n/testapp.pot 
     53output_dir = testapp/i18n 
     54 
     55[update_catalog] 
     56domain = testapp 
     57input_file = testapp/i18n/testapp.pot 
     58output_dir = testapp/i18n 
     59previous = true 
  • server/python/mapfish/controllers/auth_proxy.py

    old new  
     1from pylons import request, response 
     2from pylons.controllers import WSGIController 
     3 
     4from authkit.authorize.pylons_adaptors import authorized 
     5from authkit.authorize import NotAuthorizedError 
     6import re 
     7import cgi 
     8import urlparse 
     9import urllib2 
     10from urllib import urlencode 
     11 
     12def add_routes(map, url, controller): 
     13    """Add the pylons routes for a proxy 
     14    """ 
     15    map.connect(url + "*more", controller=controller, action='get', 
     16                conditions=dict(method=['GET'])) 
     17 
     18class Layer(object): 
     19    def __init__(self, alias, url, layers, **kwargs): 
     20        self.alias = alias 
     21        self.url = url 
     22        self.layers = layers 
     23        self.options = kwargs 
     24 
     25    def get_permissions(self): 
     26        return { 
     27            "url": self.url, 
     28            "layers": dict(((name, authorized(perm)) for (name, perm) in 
     29                            self.layers.iteritems())) 
     30        } 
     31 
     32    def check_permissions(self): 
     33        # Check layers 
     34        layers = self.get_requested_layers() 
     35        for layer in layers: 
     36            if self.layers.has_key(layer): 
     37                perm = self.layers[layer] 
     38            elif self.layers.has_key("DEFAULT"): 
     39                perm = self.layers["DEFAULT"] 
     40            else: 
     41                continue 
     42            if not authorized(perm): 
     43                return False, "Not allowed to access layer: %s" % cgi.escape(layer) 
     44 
     45        # TODO add other checks here (bbox, ...) 
     46 
     47        return True, "Access allowed" 
     48 
     49    def get_requested_layers(self): 
     50        raise NotImplementedError() 
     51 
     52    def get_requested_bbox(self): 
     53        raise NotImplementedError() 
     54 
     55class WMSLayer(Layer): 
     56    def get_param(self, name): 
     57        """Returns the request parameter given in argument, ignoring case. 
     58           If not found, None is returned. 
     59        """ 
     60        for k in request.params.keys(): 
     61            if k.lower() == name: 
     62                return request.params[k] 
     63        return None 
     64 
     65    def get_requested_layers(self): 
     66        layers = self.get_param("layers") 
     67        if not layers: 
     68            return [] 
     69        return layers.split(",") 
     70 
     71class TileCacheLayer(Layer): 
     72    def get_requested_layers(self): 
     73        raise NotImplementedError("TODO TileCacheLayer::get_requested_layers") 
     74 
     75 
     76class AuthProxyController(WSGIController): 
     77    def __init__(self): 
     78        self.layers = [] 
     79        self.alias_to_layer = {} 
     80 
     81    def set_layers(self, layers): 
     82        self.alias_to_layers = dict(((layer.alias, layer) for layer in layers)) 
     83        self.layers = layers 
     84 
     85    def _get_permissions(self): 
     86        return { 
     87            "layer": [l.get_permissions() for l in self.layers] 
     88        } 
     89 
     90    def get(self, more): 
     91        """Proxy action 
     92        """ 
     93        # extract the first segment of the url 
     94        m = re.match("/?([^/]+)(/?.*)$", more) 
     95        if not m: 
     96            response.status_code = 500 
     97            return "Invalid URL, missing alias in the path" 
     98        alias, more = m.groups() 
     99         
     100        if not self.alias_to_layers.has_key(alias): 
     101            response.status_code = 500 
     102            return "Wrong alias %s" % cgi.escape(alias) 
     103        layer = self.alias_to_layers[alias] 
     104 
     105        allowed, msg = layer.check_permissions() 
     106        if not allowed: 
     107            # We don't use 403 to avoid triggering AuthKit login dialog 
     108            response.status_code = 406 
     109            return msg 
     110 
     111        url = layer.url + more 
     112        return self._proxy(url) 
     113 
     114    def _proxy(self, url): 
     115        """Do the actual action of proxying the call. 
     116        """ 
     117        query = urlencode(request.params) 
     118        full_url = url 
     119        if query: 
     120            if not full_url.endswith("?"): 
     121    &nb