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
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.º 8
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.º 9
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.º 10
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.º 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_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.º 15
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.º 16
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.º 17
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.º 18
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()