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))
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))
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'])
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))
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'])
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))
class RoutingController(web.core.Dialect): """Routes-based dispatch. Subclass and override __init__ to define your routes. E.g. class RootController(RoutesController): def __init__(self): super(RootController, self).__init__() self._map.connect(None, "/error/{method}/{id}, action="error") # ... Methods to be called are named attributes or named attributes of nested controllers. Nested controllers may be simple new-style class instances; they do not need to inherit from Dialect or RoutesController. In your route definitions, 'action' refers to the method, 'controller' optionally refers to a nested controller and you can use dot notation to refer to sub-sub controllers, etc. """ def __init__(self): self._map = Mapper() self._map.minimization = False def __call__(self, request): result = self._map.match(environ=request.environ) if not result: raise web.core.http.HTTPNotFound() parts = result.get("controller").split(".") if "controller" in result else [] controller = self for part in parts: if not hasattr(controller, part): raise web.core.http.HTTPNotFound() controller = getattr(controller, part) method = result.get("action", None) if method is None: raise web.core.http.HTTPNotFound() try: del result["controller"] except: pass del result["action"] return getattr(controller, method)(**result)
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)
class WSGIApplication(object): def __init__(self): super(WSGIApplication, self).__init__() self.mapper = Mapper() self._match = lambda req: self.mapper.match(environ=req.environ) @WsgiHack def __call__(self, req, start_response): match = self._match(req) if not match: return HTTPNotFound() req.start_response = start_response req.urlvars = match name = match["controller"].__name__ controller = match["controller"](req) return controller(req)
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()
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()
def route_matches(route, request): m = RouteMapper() m.extend([route]) return m.match(request["uri"])