Ejemplo n.º 1
0
def test_full():
    m = Mapper(explicit=False)
    m.minimization = False
    m.connect('/:controller/:action/', id=None)
    m.connect('/:controller/:action/:id')
    m.create_regs(['content'])
    
    # Recognize
    eq_(None, m.match('/content'))
    eq_(None, m.match('/content/index'))
    eq_({'controller':'content','action':'index','id':None}, 
        m.match('/content/index/'))
    eq_({'controller':'content','action':'index','id':'4'}, 
        m.match('/content/index/4'))
    eq_({'controller':'content','action':'view','id':'4.html'},
        m.match('/content/view/4.html'))
    
    # Generate
    eq_(None, m.generate(controller='content'))
    
    # Looks odd, but only controller/action are set with non-explicit, so we
    # do need the id to match
    eq_('/content/index/', m.generate(controller='content', id=None))
    eq_('/content/index/4', m.generate(controller='content', id=4))
    eq_('/content/view/3', m.generate(controller='content', action='view', id=3))
Ejemplo n.º 2
0
def test_full():
    m = Mapper(explicit=False)
    m.minimization = False
    m.connect('/:controller/:action/', id=None)
    m.connect('/:controller/:action/:id')
    m.create_regs(['content'])

    # Recognize
    eq_(None, m.match('/content'))
    eq_(None, m.match('/content/index'))
    eq_({'controller':'content','action':'index','id':None},
        m.match('/content/index/'))
    eq_({'controller':'content','action':'index','id':'4'},
        m.match('/content/index/4'))
    eq_({'controller':'content','action':'view','id':'4.html'},
        m.match('/content/view/4.html'))

    # Generate
    eq_(None, m.generate(controller='content'))

    # Looks odd, but only controller/action are set with non-explicit, so we
    # do need the id to match
    eq_('/content/index/', m.generate(controller='content', id=None))
    eq_('/content/index/4', m.generate(controller='content', id=4))
    eq_('/content/view/3', m.generate(controller='content', action='view', id=3))
Ejemplo n.º 3
0
def test_basic():
    m = Mapper(explicit=False)
    m.minimization = False
    m.connect('/:controller/:action/:id')
    m.create_regs(['content'])

    # Recognize
    eq_(None, m.match('/content'))
    eq_(None, m.match('/content/index'))
    eq_(None, m.match('/content/index/'))
    eq_({
        'controller': 'content',
        'action': 'index',
        'id': '4'
    }, m.match('/content/index/4'))
    eq_({
        'controller': 'content',
        'action': 'view',
        'id': '4.html'
    }, m.match('/content/view/4.html'))

    # Generate
    eq_(None, m.generate(controller='content'))
    eq_('/content/index/4', m.generate(controller='content', id=4))
    eq_('/content/view/3', m.generate(controller='content',
                                      action='view',
                                      id=3))
Ejemplo n.º 4
0
class URLMapper(object):
    """
    Maps the URLs users can access.
    """

    def __init__(self):
        self._map = Mapper(controller_scan=None)
        self._connect_urls()
        self._map.create_regs()

    def match(self, path, method):
        environ = {'PATH_INFO': path, 'REQUEST_METHOD': method}
        return self._map.match(environ=environ)

    def _connect(self, pattern, http_methods):
        self._map.connect(
            None, pattern, http_methods=http_methods,
            conditions=dict(method=http_methods),
            requirements={'dbname': DBNAME_CONSTRAINTS})

    def _connect_urls(self):
        """
        Register the authorization info in the mapper using C{SHARED_DB_NAME}
        as the user's database name.

        This method sets up the following authorization rules:

            URL path                        | Authorized actions
            ----------------------------------------------------
            /                               | GET
            /robots.txt                     | GET
            /shared-db                      | GET
            /shared-db/doc/{any_id}         | GET, PUT, DELETE
            /user-{uuid}/sync-from/{source} | GET, PUT, POST
            /blobs/{uuid}/{blob_id}         | GET, PUT, DELETE, POST
            /blobs/{uuid}                   | GET
            /incoming/                      | PUT
            /stream/{uuid}/                 | POST
        """
        # global resource
        self._connect('/', ['GET'])
        # robots
        self._connect('/robots.txt', ['GET'])
        # shared-db database resource
        self._connect('/%s' % SHARED_DB_NAME, ['GET'])
        # shared-db doc resource
        self._connect('/%s/doc/{id:.*}' % SHARED_DB_NAME,
                      ['GET', 'PUT', 'DELETE'])
        # user-db sync resource
        self._connect('/user-{uuid}/sync-from/{source_replica_uid}',
                      ['GET', 'PUT', 'POST'])
        # blobs resource
        self._connect('/blobs/{uuid}/{blob_id}',
                      ['GET', 'PUT', 'DELETE', 'POST'])
        self._connect('/blobs/{uuid}/', ['GET'])
        # streaming resource
        self._connect('/stream/{uuid}/', ['POST'])
        # incoming resource
        self._connect('/incoming/{target_user_uuid}/{incoming_id}', ['PUT'])
Ejemplo n.º 5
0
def test_other_special_chars():
    m = Mapper()
    m.minimization = False
    m.connect('/:year/:(slug).:(format),:(locale)', locale='en', format='html')
    m.create_regs(['content'])

    eq_('/2007/test.xml,ja', m.generate(year=2007, slug='test', format='xml', locale='ja'))
    eq_(None, m.generate(year=2007, format='html'))
Ejemplo n.º 6
0
def test_other_special_chars():
    m = Mapper()
    m.minimization = False
    m.connect('/:year/:(slug).:(format),:(locale)', locale='en', format='html')
    m.create_regs(['content'])
    
    eq_('/2007/test.xml,ja', m.generate(year=2007, slug='test', format='xml', locale='ja'))
    eq_(None, m.generate(year=2007, format='html'))
Ejemplo n.º 7
0
def test_unicode():
    hoge = u'\u30c6\u30b9\u30c8' # the word test in Japanese
    hoge_enc = urllib.quote(hoge.encode('utf-8'))
    m = Mapper()
    m.minimization = False
    m.connect(':hoge')
    eq_("/%s" % hoge_enc, m.generate(hoge=hoge))
    assert isinstance(m.generate(hoge=hoge), str)
Ejemplo n.º 8
0
def test_unicode():
    hoge = u'\u30c6\u30b9\u30c8' # the word test in Japanese
    hoge_enc = urllib.quote(hoge.encode('utf-8'))
    m = Mapper()
    m.minimization = False
    m.connect(':hoge')
    eq_("/%s" % hoge_enc, m.generate(hoge=hoge))
    assert isinstance(m.generate(hoge=hoge), str)
Ejemplo n.º 9
0
class URLMapper(object):
    """
    Maps the URLs users can access.
    """

    def __init__(self):
        self._map = Mapper(controller_scan=None)
        self._connect_urls()
        self._map.create_regs()

    def match(self, path, method):
        environ = {'PATH_INFO': path, 'REQUEST_METHOD': method}
        return self._map.match(environ=environ)

    def _connect(self, pattern, http_methods):
        self._map.connect(
            None, pattern, http_methods=http_methods,
            conditions=dict(method=http_methods),
            requirements={'dbname': DBNAME_CONSTRAINTS})

    def _connect_urls(self):
        """
        Register the authorization info in the mapper using C{SHARED_DB_NAME}
        as the user's database name.

        This method sets up the following authorization rules:

            URL path                        | Authorized actions
            ----------------------------------------------------
            /                               | GET
            /robots.txt                     | GET
            /shared-db                      | GET
            /shared-db/doc/{any_id}         | GET, PUT, DELETE
            /user-{uuid}/sync-from/{source} | GET, PUT, POST
            /blobs/{uuid}/{blob_id}         | GET, PUT, DELETE, POST
            /blobs/{uuid}                   | GET
            /incoming/                      | PUT
        """
        # global resource
        self._connect('/', ['GET'])
        # robots
        self._connect('/robots.txt', ['GET'])
        # shared-db database resource
        self._connect('/%s' % SHARED_DB_NAME, ['GET'])
        # shared-db doc resource
        self._connect('/%s/doc/{id:.*}' % SHARED_DB_NAME,
                      ['GET', 'PUT', 'DELETE'])
        # user-db sync resource
        self._connect('/user-{uuid}/sync-from/{source_replica_uid}',
                      ['GET', 'PUT', 'POST'])
        # blobs resource
        self._connect('/blobs/{uuid}/{blob_id}',
                      ['GET', 'PUT', 'DELETE', 'POST'])
        self._connect('/blobs/{uuid}/', ['GET'])
        # incoming resource
        self._connect('/incoming/{target_user_uuid}/{incoming_id}', ['PUT'])
Ejemplo n.º 10
0
def test_query_params():
    m = Mapper()
    m.minimization = False
    m.explicit = True
    m.connect('/:controller/index', action='index')
    m.create_regs(['content'])

    eq_(None, m.generate(controller='content'))
    eq_('/content/index?test=sample',
        m.generate(controller='content', action='index', test='sample'))
Ejemplo n.º 11
0
def test_query_params():
    m = Mapper()
    m.minimization = False
    m.explicit = True
    m.connect('/:controller/index', action='index')
    m.create_regs(['content'])
    
    eq_(None, m.generate(controller='content'))
    eq_('/content/index?test=sample', 
        m.generate(controller='content', action='index', test='sample'))
Ejemplo n.º 12
0
def test_action_required():
    m = Mapper()
    m.minimization = False
    m.explicit = True
    m.connect('/:controller/index', action='index')
    m.create_regs(['content'])
    
    eq_(None, m.generate(controller='content'))
    eq_(None, m.generate(controller='content', action='fred'))
    eq_('/content/index', m.generate(controller='content', action='index'))
Ejemplo n.º 13
0
def test_unicode_static():
    hoge = u'\u30c6\u30b9\u30c8' # the word test in Japanese
    hoge_enc = urllib.quote(hoge.encode('utf-8'))
    m = Mapper()
    m.minimization = False
    m.connect('google-jp', 'http://www.google.co.jp/search', _static=True)
    m.create_regs(['messages'])
    eq_("http://www.google.co.jp/search?q=" + hoge_enc,
                     url_for('google-jp', q=hoge))
    assert isinstance(url_for('google-jp', q=hoge), str)
Ejemplo n.º 14
0
def test_action_required():
    m = Mapper()
    m.minimization = False
    m.explicit = True
    m.connect('/:controller/index', action='index')
    m.create_regs(['content'])

    eq_(None, m.generate(controller='content'))
    eq_(None, m.generate(controller='content', action='fred'))
    eq_('/content/index', m.generate(controller='content', action='index'))
Ejemplo n.º 15
0
def test_unicode_static():
    hoge = u'\u30c6\u30b9\u30c8' # the word test in Japanese
    hoge_enc = urllib.quote(hoge.encode('utf-8'))
    m = Mapper()
    m.minimization = False
    m.connect('google-jp', 'http://www.google.co.jp/search', _static=True)
    m.create_regs(['messages'])
    eq_("http://www.google.co.jp/search?q=" + hoge_enc,
                     url_for('google-jp', q=hoge))
    assert isinstance(url_for('google-jp', q=hoge), str)
Ejemplo n.º 16
0
class App(object):
    def __init__(self):
        self.url_map = Mapper()
        self.Request = BaitoRequest
        self.Response = Response

        self._renderer = None

        self.conf = imp.new_module('baito.conf')

    def load_conf(self, path):
        self.conf.__file__ = path
        execfile(path, self.conf.__dict__, self.conf.__dict__)

    def connect(self, name, rule, **kwargs):
        kwargs['_module'] = None
        self.url_map.connect(name, rule, **kwargs)

    def expose(self, rule, name=None, **kwargs):
        def decorator(func):
            kwargs['_endpoint'] = func
            kwargs['_module'] = None
            self.url_map.connect(name or func.__name__, rule, **kwargs)
            return func

        return decorator

    def __call__(self, environ, start_response):
        request = self.Request(self, environ)
        try:
            result = self.url_map.match(None, environ)
            if not result:
                raise HTTPNotFound()

            try:
                endpoint = result.pop('_endpoint')
            except KeyError:
                return result.pop('_wsgi')(environ, start_response)

            request.module = result.pop('_module', None)
            response = endpoint(request, **result)
            if isinstance(response, basestring):
                response = self.Response(response)
        except HTTPException, e:
            response = e

        if request.session is not None:
            request.session.save()

        return response(environ, start_response)
Ejemplo n.º 17
0
    def setup_routes(self):
        """Setup the default TG2 routes

        Override this and setup your own routes maps if you want to use
        custom routes.

        It is recommended that you keep the existing application routing in
        tact, and just add new connections to the mapper above the routes_placeholder
        connection.  Lets say you want to add a pylons controller SamplesController,
        inside the controllers/samples.py file of your application.  You would
        augment the app_cfg.py in the following way::

            from routes import Mapper
            from tg.configuration import AppConfig

            class MyAppConfig(AppConfig):
                def setup_routes(self):
                    map = Mapper(directory=config['pylons.paths']['controllers'],
                                always_scan=config['debug'])

                    # Add a Samples route
                    map.connect('/samples/', controller='samples', action=index)

                    # Setup a default route for the root of object dispatch
                    map.connect('*url', controller='root', action='routes_placeholder')

                    config['routes.map'] = map


            base_config = MyAppConfig()

        """
        
        from tg.configuration import config
        from routes.mapper import Mapper

        map_ = Mapper(directory=config['pylons.paths']['controllers'],
                     always_scan=config['debug'])

        # Setup a default route for the root of object dispatch
        controller_ = 'root'
        root_folder = config.get('app.root_folder')
        if root_folder:
            controller_ = '%s/root' % root_folder

        map_.connect('*url', controller=controller_, action='routes_placeholder')

        config['routes.map'] = map_
Ejemplo n.º 18
0
def test_syntax():
    m = Mapper(explicit=False)
    m.minimization = False
    m.connect('/{controller}/{action}/{id}')
    m.create_regs(['content'])
    
    # Recognize
    eq_(None, m.match('/content'))
    eq_(None, m.match('/content/index'))
    eq_(None, m.match('/content/index/'))
    eq_({'controller':'content','action':'index','id':'4'}, 
        m.match('/content/index/4'))
    
    # Generate
    eq_(None, m.generate(controller='content'))
    eq_('/content/index/4', m.generate(controller='content', id=4))
    eq_('/content/view/3', m.generate(controller='content', action='view', id=3))
Ejemplo n.º 19
0
def test_syntax():
    m = Mapper(explicit=False)
    m.minimization = False
    m.connect('/{controller}/{action}/{id}')
    m.create_regs(['content'])

    # Recognize
    eq_(None, m.match('/content'))
    eq_(None, m.match('/content/index'))
    eq_(None, m.match('/content/index/'))
    eq_({'controller':'content','action':'index','id':'4'},
        m.match('/content/index/4'))

    # Generate
    eq_(None, m.generate(controller='content'))
    eq_('/content/index/4', m.generate(controller='content', id=4))
    eq_('/content/view/3', m.generate(controller='content', action='view', id=3))
Ejemplo n.º 20
0
 def mapperFor(cls, base, *handlers):
     '''Returns a list of all the mappers this application knows about.'''
     mapper = Mapper()
     mapper.sub_domains = True
     for handler in handlers:
         subdomain, path = cls.pathFor(handler)
         created = list(cls.routesFor(handler))
         for d in created:
             name = d['name']; del d['name']
             routepath = d['routepath']; del d['routepath']
             if subdomain:
                 conditions = d['conditions']
                 if isinstance(subdomain, str):
                      conditions["sub_domain"] = [subdomain,]
                 else:
                     conditions["sub_domain"] = subdomain
             mapper.connect(name, urljoin(base, path, routepath), controller=handler, **d)
     return mapper
Ejemplo n.º 21
0
def test_basic():
    m = Mapper(explicit=False)
    m.minimization = False
    m.connect('/:controller/:action/:id')
    m.create_regs(['content'])

    # Recognize
    eq_(None, m.match('/content'))
    eq_(None, m.match('/content/index'))
    eq_(None, m.match('/content/index/'))
    eq_({'controller':'content','action':'index','id':'4'},
        m.match('/content/index/4'))
    eq_({'controller':'content','action':'view','id':'4.html'},
        m.match('/content/view/4.html'))

    # Generate
    eq_(None, m.generate(controller='content'))
    eq_('/content/index/4', m.generate(controller='content', id=4))
    eq_('/content/view/3', m.generate(controller='content', action='view', id=3))
Ejemplo n.º 22
0
    def connect(self, *args, **kw):
        '''Connect a new route, storing any named routes for later.

        This custom connect() method wraps the standard connect() method,
        and additionally saves any named routes that are connected in a dict
        ckan.routing.named_routes, which ends up being accessible via the
        Pylons config as config['routes.named_routes'].

        Also takes some additional params:

        :param ckan_icon: name of the icon to be associated with this route,
            e.g. 'group', 'time'. Available icons are listed here:
            http://fortawesome.github.io/Font-Awesome/3.2.1/icons/
        :type ckan_icon: string
        :param highlight_actions: space-separated list of controller actions
            that should be treated as the same as this named route for menu
            highlighting purposes, e.g. 'index search'
        :type highlight_actions: string

        '''

        ckan_icon = kw.pop('ckan_icon', None)
        highlight_actions = kw.pop('highlight_actions', kw.get('action', ''))
        ckan_core = kw.pop('ckan_core', None)
        out = _Mapper.connect(self, *args, **kw)
        route = self.matchlist[-1]
        if ckan_core is not None:
            route._ckan_core = ckan_core
        if len(args) == 1 or args[0].startswith('_redirect_'):
            return out
        # we have a named route
        needed = []
        matches = re.findall('\{([^:}]*)(\}|:)', args[1])
        for match in matches:
            needed.append(match[0])
        route_data = {
            'icon': ckan_icon,
            # needed lists the names of the parameters that need defining
            # for the route to be generated
            'needed': needed,
            'controller': kw.get('controller'),
            'action': kw.get('action', ''),
            'highlight_actions': highlight_actions
        }
        named_routes[args[0]] = route_data
        return out
Ejemplo n.º 23
0
    def connect(self, *args, **kw):
        """Connect a new route, storing any named routes for later.

        This custom connect() method wraps the standard connect() method,
        and additionally saves any named routes that are connected in a dict
        ckan.routing.named_routes, which ends up being accessible via the
        Pylons config as config['routes.named_routes'].

        Also takes some additional params:

        :param ckan_icon: name of the icon to be associated with this route,
            e.g. 'group', 'time'. Available icons are listed here:
            http://fortawesome.github.io/Font-Awesome/3.2.1/icons/
        :type ckan_icon: string
        :param highlight_actions: space-separated list of controller actions
            that should be treated as the same as this named route for menu
            highlighting purposes, e.g. 'index search'
        :type highlight_actions: string

        """
        ckan_icon = kw.pop("ckan_icon", None)
        highlight_actions = kw.pop("highlight_actions", kw.get("action", ""))
        out = _Mapper.connect(self, *args, **kw)
        if len(args) == 1 or args[0].startswith("_redirect_"):
            return out
        # we have a named route
        needed = []
        matches = re.findall("\{([^:}]*)(\}|:)", args[1])
        for match in matches:
            needed.append(match[0])
        route_data = {
            "icon": ckan_icon,
            # needed lists the names of the parameters that need defining
            # for the route to be generated
            "needed": needed,
            "controller": kw.get("controller"),
            "action": kw.get("action", ""),
            "highlight_actions": highlight_actions,
        }
        named_routes[args[0]] = route_data
        return out
Ejemplo n.º 24
0
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import users

from routes.mapper import Mapper
from routes.middleware import RoutesMiddleware

from appetsy import storage


import appetsy

name = os.path.abspath(os.path.join(os.path.dirname(__file__)))
name = os.path.join(name, "controllers")

map = Mapper(directory=name)
map.connect('/', controller = 'index')
map.connect('/recent_views', controller = 'index', action = 'recent_views')
map.connect('/progress_box', controller = 'index', action = 'progress_box')
map.connect('/fans_today', controller = 'index', action = 'fans_today')
map.connect('/sold_and_featured_today', controller = 'index', action = 'sold_and_featured_today')
map.connect('/shop/:(id)', controller = 'index', action = 'switch_shop')

map.connect('goods/statistics', controller = 'goods', action = 'statistics')
map.connect('goods/active', controller = 'goods', action = 'active')
map.connect('goods/:(key)/edit', controller = 'goods', action = 'edit')
map.resource('goods', 'goods')

map.connect('expenses/active', controller = 'expenses', action = 'active')
map.connect('expenses/balance', controller = 'expenses', action = 'balance')
map.connect('expenses/:(key)/edit', controller = 'expenses', action = 'edit')
map.resource('expenses', 'expenses')
Ejemplo n.º 25
0

class MyWsgiApp(wsgi.LunrWsgiApp):
    def __init__(self, conf, urlmap, helper=None):
        self.conf = conf
        self.urlmap = urlmap
        self.helper = helper

    def call(self, request):
        # Match the Request URL to an action
        action = self.match(request)
        return action(request)


urlmap = Mapper()
urlmap.connect('/happy', controller=HappyController, action="happy_method")
urlmap.connect('/happyresponse', controller=HappyController,
               action="happy_response")
urlmap.connect('/notimplemented', controller=HappyController,
               action="not_implemented")
urlmap.connect('/fivehundred', controller=SadController, action="five_hundred")
urlmap.connect('/fail', controller=SadController, action="fail")


class TestiLunrWsgiApp(unittest.TestCase):
    def setUp(self):
        self.app = MyWsgiApp(TEST_CONF, urlmap)

    def tearDown(self):
        pass
Ejemplo n.º 26
0
class URLToAuthorization(object):
    """
    Verify if actions can be performed by a user.
    """

    HTTP_METHOD_GET = 'GET'
    HTTP_METHOD_PUT = 'PUT'
    HTTP_METHOD_DELETE = 'DELETE'
    HTTP_METHOD_POST = 'POST'

    def __init__(self, uuid):
        """
        Initialize the mapper.

        The C{uuid} is used to create the rules that will either allow or
        disallow the user to perform specific actions.

        @param uuid: The user uuid.
        @type uuid: str
        @param user_db_prefix: The string prefix of users' databases.
        @type user_db_prefix: str
        """
        self._map = Mapper(controller_scan=None)
        self._user_db_name = "%s%s" % (USER_DB_PREFIX, uuid)
        self._uuid = uuid
        self._register_auth_info()

    def is_authorized(self, environ):
        """
        Return whether an HTTP request that produced the CGI C{environ}
        corresponds to an authorized action.

        @param environ: Dictionary containing CGI variables.
        @type environ: dict

        @return: Whether the action is authorized or not.
        @rtype: bool
        """
        return self._map.match(environ=environ) is not None

    def _register(self, pattern, http_methods):
        """
        Register a C{pattern} in the mapper as valid for C{http_methods}.

        @param pattern: The URL pattern that corresponds to the user action.
        @type pattern: str
        @param http_methods: A list of authorized HTTP methods.
        @type http_methods: list of str
        """
        self._map.connect(None,
                          pattern,
                          http_methods=http_methods,
                          conditions=dict(method=http_methods),
                          requirements={'dbname': DBNAME_CONSTRAINTS})

    def _register_auth_info(self):
        """
        Register the authorization info in the mapper using C{SHARED_DB_NAME}
        as the user's database name.

        This method sets up the following authorization rules:

            URL path                      | Authorized actions
            --------------------------------------------------
            /                             | GET
            /shared-db                    | GET
            /shared-db/docs               | -
            /shared-db/doc/{any_id}       | GET, PUT, DELETE
            /shared-db/sync-from/{source} | -
            /shared-db/lock/{uuid}        | PUT, DELETE
            /user-db                      | GET, PUT, DELETE
            /user-db/docs                 | -
            /user-db/doc/{id}             | -
            /user-db/sync-from/{source}   | GET, PUT, POST
        """
        # auth info for global resource
        self._register('/', [self.HTTP_METHOD_GET])
        # auth info for shared-db database resource
        self._register('/%s' % SHARED_DB_NAME, [self.HTTP_METHOD_GET])
        # auth info for shared-db doc resource
        self._register('/%s/doc/{id:.*}' % SHARED_DB_NAME, [
            self.HTTP_METHOD_GET, self.HTTP_METHOD_PUT, self.HTTP_METHOD_DELETE
        ])
        # auth info for shared-db lock resource
        self._register('/%s/lock/%s' % (SHARED_DB_NAME, self._uuid),
                       [self.HTTP_METHOD_PUT, self.HTTP_METHOD_DELETE])
        # auth info for user-db database resource
        self._register('/%s' % self._user_db_name, [
            self.HTTP_METHOD_GET, self.HTTP_METHOD_PUT, self.HTTP_METHOD_DELETE
        ])
        # auth info for user-db sync resource
        self._register(
            '/%s/sync-from/{source_replica_uid}' % self._user_db_name, [
                self.HTTP_METHOD_GET, self.HTTP_METHOD_PUT,
                self.HTTP_METHOD_POST
            ])
        # generate the regular expressions
        self._map.create_regs()
Ejemplo n.º 27
0

class MyWsgiApp(wsgi.LunrWsgiApp):
    def __init__(self, conf, urlmap, helper=None):
        self.conf = conf
        self.urlmap = urlmap
        self.helper = helper

    def call(self, request):
        # Match the Request URL to an action
        action = self.match(request)
        return action(request)


urlmap = Mapper()
urlmap.connect('/happy', controller=HappyController, action="happy_method")
urlmap.connect('/happyresponse',
               controller=HappyController,
               action="happy_response")
urlmap.connect('/notimplemented',
               controller=HappyController,
               action="not_implemented")
urlmap.connect('/fivehundred', controller=SadController, action="five_hundred")
urlmap.connect('/fail', controller=SadController, action="fail")


class TestiLunrWsgiApp(unittest.TestCase):
    def setUp(self):
        self.app = MyWsgiApp(TEST_CONF, urlmap)

    def tearDown(self):
Ejemplo n.º 28
0
class URLToAuthorization(object):
    """
    Verify if actions can be performed by a user.
    """

    HTTP_METHOD_GET = 'GET'
    HTTP_METHOD_PUT = 'PUT'
    HTTP_METHOD_DELETE = 'DELETE'
    HTTP_METHOD_POST = 'POST'

    def __init__(self, uuid):
        """
        Initialize the mapper.

        The C{uuid} is used to create the rules that will either allow or
        disallow the user to perform specific actions.

        @param uuid: The user uuid.
        @type uuid: str
        @param user_db_prefix: The string prefix of users' databases.
        @type user_db_prefix: str
        """
        self._map = Mapper(controller_scan=None)
        self._user_db_name = "%s%s" % (USER_DB_PREFIX, uuid)
        self._uuid = uuid
        self._register_auth_info()

    def is_authorized(self, environ):
        """
        Return whether an HTTP request that produced the CGI C{environ}
        corresponds to an authorized action.

        @param environ: Dictionary containing CGI variables.
        @type environ: dict

        @return: Whether the action is authorized or not.
        @rtype: bool
        """
        return self._map.match(environ=environ) is not None

    def _register(self, pattern, http_methods):
        """
        Register a C{pattern} in the mapper as valid for C{http_methods}.

        @param pattern: The URL pattern that corresponds to the user action.
        @type pattern: str
        @param http_methods: A list of authorized HTTP methods.
        @type http_methods: list of str
        """
        self._map.connect(
            None, pattern, http_methods=http_methods,
            conditions=dict(method=http_methods),
            requirements={'dbname': DBNAME_CONSTRAINTS})

    def _register_auth_info(self):
        """
        Register the authorization info in the mapper using C{SHARED_DB_NAME}
        as the user's database name.

        This method sets up the following authorization rules:

            URL path                      | Authorized actions
            --------------------------------------------------
            /                             | GET
            /shared-db                    | GET
            /shared-db/docs               | -
            /shared-db/doc/{any_id}       | GET, PUT, DELETE
            /shared-db/sync-from/{source} | -
            /shared-db/lock/{uuid}        | PUT, DELETE
            /user-db                      | GET, PUT, DELETE
            /user-db/docs                 | -
            /user-db/doc/{id}             | -
            /user-db/sync-from/{source}   | GET, PUT, POST
        """
        # auth info for global resource
        self._register('/', [self.HTTP_METHOD_GET])
        # auth info for shared-db database resource
        self._register(
            '/%s' % SHARED_DB_NAME,
            [self.HTTP_METHOD_GET])
        # auth info for shared-db doc resource
        self._register(
            '/%s/doc/{id:.*}' % SHARED_DB_NAME,
            [self.HTTP_METHOD_GET, self.HTTP_METHOD_PUT,
             self.HTTP_METHOD_DELETE])
        # auth info for shared-db lock resource
        self._register(
            '/%s/lock/%s' % (SHARED_DB_NAME, self._uuid),
            [self.HTTP_METHOD_PUT, self.HTTP_METHOD_DELETE])
        # auth info for user-db database resource
        self._register(
            '/%s' % self._user_db_name,
            [self.HTTP_METHOD_GET, self.HTTP_METHOD_PUT,
             self.HTTP_METHOD_DELETE])
        # auth info for user-db sync resource
        self._register(
            '/%s/sync-from/{source_replica_uid}' % self._user_db_name,
            [self.HTTP_METHOD_GET, self.HTTP_METHOD_PUT,
             self.HTTP_METHOD_POST])
        # generate the regular expressions
        self._map.create_regs()
Ejemplo n.º 29
0
        return Response('non commital')


class SadController(object):
    def __init__(self, route, app):
        self.db = app.helper
        self.route = route
        self.app = app

    def fail_db(self, request):
        a = Account(id='happy account')
        self.db.add(a)
        raise Exception('dbfail')

urlmap = Mapper()
urlmap.connect('/db/happy', controller=HappyController, action="happy_db")
urlmap.connect('/db/lazy', controller=HappyController, action="lazy_db")
urlmap.connect('/db/fail', controller=SadController, action="fail_db")


class TestServer(unittest.TestCase):
    def setUp(self):
        self.app = ApiWsgiApp(TEST_CONF, urlmap)

    def tearDown(self):
        db.Session.remove()

    def test_happydb(self):
        request = Request.blank('/db/happy')
        res = self.app(request)
        self.assertEquals(res.status_int // 1, 200)