def info(self): """ Get print capabilities. """ templates = get_functionality('print_template', self.config, self.request) return self._info(templates)
def mobileconfig(self): """ View callable for the mobile application's config.js file. """ errors = set() interface = self.request.interface_name mobile_default_themes = get_functionality( 'mobile_default_theme', self.settings, self.request ) theme_name = self.request.params.get( 'theme', mobile_default_themes[0] if len(mobile_default_themes) > 0 else None ) user = self.request.user role_id = None if user is None else user.role.id themes, errors = self._themes(role_id, interface, False) for t in themes: self.flatten_layers(t) # comma-separated string including the feature types supported # by WFS service wfs_types, errors = self._internal_wfs_types(role_id) if len(errors) > 0: # pragma: no cover raise HTTPBadGateway('\n'.join(errors)) # info includes various information that is not used by config.js, # but by other - private to the integrator - parts of the mobile # application. info = { 'username': user.username if user else '' } # get the list of themes available for mobile themes_ = [] themes, errors = self._themes(role_id, interface, False) for theme in themes: # mobile theme or hidden theme explicitely loaded if theme['in_mobile_viewer'] or theme['name'] == theme_name: themes_.append({ 'name': theme['name'], 'icon': theme['icon'], 'allLayers': theme['allLayers'], 'layers': theme['layers'], }) self.request.response.content_type = 'application/javascript' self.request.response.headers["Vary"] = "Accept-Language" return { 'lang': self.lang, 'themes': themes_, 'theme': theme_name if theme_name is not None else "", 'wfs_types': wfs_types, 'server_error': errors, 'info': info, }
def info(self): """ Get print capabilities. """ templates = get_functionality( 'print_template', self.config, self.request) return self._info(templates)
def _functionality(self): functionality = {} for func in get_setting( self.settings, ('functionalities', 'available_in_templates'), []): functionality[func] = get_functionality( func, self.settings, self.request) return functionality
def _functionality(self): functionality = {} for func in get_setting(self.settings, ('functionalities', 'available_in_templates'), []): functionality[func] = get_functionality(func, self.settings, self.request) return functionality
def info(self): """ Get print capabilities. """ templates = get_functionality("print_template", self.config, self.request) # get query string params = dict(self.request.params) query_string = urllib.urlencode(params) return self._info(templates, query_string, self.request.method)
def _functionality_cached(self, role): functionality = {} for func in get_setting( self.settings, ("functionalities", "available_in_templates"), [] ): functionality[func] = get_functionality( func, self.settings, self.request ) return functionality
def mobileconfig(self): """ View callable for the mobile application's config.js file. """ errors = [] mobile_default_themes = get_functionality('mobile_default_theme', self.settings, self.request) theme_name = self.request.params.get( 'theme', mobile_default_themes[0] if len(mobile_default_themes) > 0 else None) user = self.request.user role_id = None if user is None else user.role.id themes, errors = self._themes(role_id, True) for t in themes: self.flatten_layers(t) # comma-separated string including the feature types supported # by WFS service wfs_types, errors = self._internal_wfs_types() if len(errors) > 0: # pragma: no cover raise HTTPBadGateway('\n'.join(errors)) wfs_types = ','.join(wfs_types) # info includes various information that is not used by config.js, # but by other - private to the integrator - parts of the mobile # application. info = {'username': user.username if user else ''} # get the list of themes available for mobile themes_ = [] themes, errors = self._themes(role_id, True) for theme in themes: # mobile theme or hidden theme explicitely loaded if theme['inMobileViewer'] or theme['name'] == theme_name: themes_.append({ 'name': theme['name'], 'icon': theme['icon'], 'allLayers': theme['allLayers'], 'layers': theme['layers'] }) self.request.response.content_type = 'application/javascript' return { 'lang': self.lang, 'themes': json.dumps(themes_), 'theme': theme_name if theme_name is not None else "", 'wfs_types': wfs_types, 'server_error': json.dumps(errors), 'info': json.dumps(info) }
def capabilities(self): """ Get print capabilities. """ templates = get_functionality("print_template", self.request) # get query string params = dict(self.request.params) query_string = urllib.urlencode(params) resp, content = self._capabilities(templates, query_string, self.request.method) return self._build_response(resp, content, PRIVATE_CACHE, "print")
def info(self): """ Get print capabilities. """ templates = get_functionality("print_template", self.request) # get query string params = dict(self.request.params) query_string = urllib.parse.urlencode(params) return self._info( templates, query_string, self.request.method, )
def info(self): """ Get print capabilities. """ templates = get_functionality('print_template', self.config, self.request) # get query string params = dict(self.request.params) query_string = urllib.urlencode(params) # get URL _url = self.config['print_url'] + 'info.json' + '?' + query_string log.info("Get print capabilities from %s." % _url) # forward request to target (without Host Header) http = httplib2.Http() h = dict(self.request.headers) if urlparse(_url).hostname != 'localhost': h.pop('Host') try: resp, content = http.request(_url, method='GET', headers=h) except: return HTTPBadGateway() try: capabilities = json.loads(content) except JSONDecodeError: # log and raise log.error("Unable to parse capabilities.") log.info(content) return content capabilities['layouts'] = list(layout for layout in capabilities['layouts'] if layout['name'] in templates) headers = dict(resp) del headers['content-length'] headers["Expires"] = "-1" headers["Pragma"] = "no-cache" headers["CacheControl"] = "no-cache" return Response(json.dumps(capabilities, separators=(',', ':')), status=resp.status, headers=headers)
def info(self): """ Get print capabilities. """ templates = get_functionality( 'print_template', self.config, self.request) # get query string params = dict(self.request.params) query_string = urllib.urlencode(params) # get URL _url = self.config['print_url'] + 'info.json' + '?' + query_string log.info("Get print capabilities from %s." % _url) # forward request to target (without Host Header) http = httplib2.Http() h = dict(self.request.headers) if urlparse(_url).hostname != 'localhost': h.pop('Host') try: resp, content = http.request(_url, method='GET', headers=h) except: return HTTPBadGateway() try: capabilities = json.loads(content) except JSONDecodeError: # log and raise log.error("Unable to parse capabilities.") log.info(content) return content capabilities['layouts'] = list( layout for layout in capabilities['layouts'] if layout['name'] in templates) headers = dict(resp) del headers['content-length'] headers["Expires"] = "-1" headers["Pragma"] = "no-cache" headers["CacheControl"] = "no-cache" return Response(json.dumps(capabilities, separators=(',', ':')), status=resp.status, headers=headers)
def capabilities(self): """ Get print capabilities. """ templates = get_functionality("print_template", self.request) # get query string params = dict(self.request.params) query_string = urllib.parse.urlencode(params) resp, content = self._capabilities( templates, query_string, self.request.method, ) return self._build_response( resp, content, PRIVATE_CACHE, "print", )
def test_functionalities(self): from tests.functional import create_dummy_request from c2cgeoportal.models import DBSession, User from c2cgeoportal.lib.functionality import get_functionality request = create_dummy_request() request.user = None request1 = create_dummy_request() request1.user = DBSession.query(User).filter( User.username == "__test_user1").one() request2 = create_dummy_request() request2.user = DBSession.query(User).filter( User.username == "__test_user2").one() settings = { "functionalities": { "anonymous": {}, "registered": {}, }, "admin_interface": { "available_functionalities": ["__test_a", "__test_s"] } } functionality.FUNCTIONALITIES_TYPES = None request.registry.settings.update(settings) request1.registry.settings.update(settings) request2.registry.settings.update(settings) self.assertEqual(get_functionality("__test_s", request), []) self.assertEqual(get_functionality("__test_a", request), []) self.assertEqual(get_functionality("__test_s", request1), []) self.assertEqual(get_functionality("__test_a", request1), []) self.assertEqual(get_functionality("__test_s", request2), ["db"]) self.assertEqual(get_functionality("__test_a", request2), ["db1", "db2"]) settings = { "functionalities": { "anonymous": {}, "registered": { "__test_s": "registered", "__test_a": ["r1", "r2"] } }, "admin_interface": { "available_functionalities": ["__test_a", "__test_s"] } } functionality.FUNCTIONALITIES_TYPES = None request.registry.settings.update(settings) request1.registry.settings.update(settings) request2.registry.settings.update(settings) self.assertEqual(get_functionality("__test_s", request), []) self.assertEqual(get_functionality("__test_a", request), []) self.assertEqual(get_functionality("__test_s", request1), ["registered"]) self.assertEqual(get_functionality("__test_a", request1), ["r1", "r2"]) self.assertEqual(get_functionality("__test_s", request2), ["db"]) self.assertEqual(get_functionality("__test_a", request2), ["db1", "db2"]) settings = { "functionalities": { "anonymous": { "__test_s": "anonymous", "__test_a": ["a1", "a2"] }, "registered": {} }, "admin_interface": { "available_functionalities": ["__test_a", "__test_s"] } } functionality.FUNCTIONALITIES_TYPES = None request.registry.settings.update(settings) request1.registry.settings.update(settings) request2.registry.settings.update(settings) self.assertEqual(get_functionality("__test_s", request), ["anonymous"]) self.assertEqual(get_functionality("__test_a", request), ["a1", "a2"]) self.assertEqual(get_functionality("__test_s", request1), ["anonymous"]) self.assertEqual(get_functionality("__test_a", request1), ["a1", "a2"]) self.assertEqual(get_functionality("__test_s", request2), ["db"]) self.assertEqual(get_functionality("__test_a", request2), ["db1", "db2"]) settings = { "functionalities": { "anonymous": { "__test_s": "anonymous", "__test_a": ["a1", "a2"] }, "registered": { "__test_s": "registered", "__test_a": ["r1", "r2"] } }, "admin_interface": { "available_functionalities": ["__test_a", "__test_s"] } } functionality.FUNCTIONALITIES_TYPES = None request.registry.settings.update(settings) request1.registry.settings.update(settings) request2.registry.settings.update(settings) self.assertEqual(get_functionality("__test_s", request), ["anonymous"]) self.assertEqual(get_functionality("__test_a", request), ["a1", "a2"]) self.assertEqual(get_functionality("__test_s", request1), ["registered"]) self.assertEqual(get_functionality("__test_a", request1), ["r1", "r2"]) self.assertEqual(get_functionality("__test_s", request2), ["db"]) self.assertEqual(get_functionality("__test_a", request2), ["db1", "db2"])
def proxy(request): user = request.user external = bool(request.params.get("EXTERNAL", None)) # params hold the parameters we're going to send to MapServer params = dict(request.params) # reset possible value of role_id and user_id if 'role_id' in params: del params['role_id'] if 'user_id' in params: del params['user_id'] if user: # We have a user logged in. We need to set group_id and # possible layer_name in the params. We set layer_name # when either QUERY_PARAMS or LAYERS is set in the # WMS params, i.e. for GetMap and GetFeatureInfo # requests. For GetLegendGraphic requests we don't # send layer_name, but MapServer shouldn't use the DATA # string for GetLegendGraphic. params['role_id'] = user.parent_role.id if external else user.role.id # In some application we want to display the features owned by a user # than we need his id. if not external: params['user_id'] = user.id # don't allows direct variable substitution for k in params.keys(): if k[:2].capitalize() == 'S_': log.warning("Direct substitution not allowed (%s=%s)." % (k, params[k])) del params[k] mss = get_functionality('mapserver_substitution', request.registry.settings, request) if mss: for s in mss: index = s.find('=') if index > 0: attribute = 's_' + s[:index] value = s[index + 1:] if attribute in params: params[attribute] += "," + value else: params[attribute] = value else: log.warning("Mapserver Substitution '%s' does not " "respect pattern: <attribute>=<value>" % s) # get method method = request.method # we want the browser to cache GetLegendGraphic requests, so # we need to know if the current request is a GetLegendGraphic # request is_glg = False # name of the JSON callback (value for the "callback" query string param # in the request). None if request has no "callback" param in the query # string callback = None if method == "GET": _params = dict( (k.lower(), unicode(v).lower()) for k, v in params.iteritems()) # For GET requests, params are added only if the REQUEST # parameter is actually provided. if 'request' not in _params: params = {} # pragma: no cover else: # WMS GetLegendGraphic request? is_glg = ('service' not in _params or _params['service'] == u'wms') and \ _params['request'] == u'getlegendgraphic' callback = params.get('callback') # get query string params_encoded = {} for k, v in params.iteritems(): if k == 'callback': continue params_encoded[k] = unicode(v).encode('utf-8') query_string = urllib.urlencode(params_encoded) # get URL _url = request.registry.settings['external_mapserv_url'] \ if external \ else request.registry.settings['mapserv_url'] _url += '?' + query_string log.info("Querying mapserver proxy at URL: %s." % _url) # get body body = None if method in ("POST", "PUT"): body = request.body # forward request to target (without Host Header) http = httplib2.Http() h = dict(request.headers) if urlparse(_url).hostname != 'localhost': h.pop('Host') # mapserver don't need the cookie, and sometimes it failed with it. if 'Cookie' in h: h.pop('Cookie') try: resp, content = http.request(_url, method=method, body=body, headers=h) except: # pragma: no cover log.error("Error '%s' while getting the URL: %s." % (sys.exc_info()[0], _url)) if method == "POST": log.error("--- With body ---") log.error(body) return HTTPBadGateway("See logs for details") # pragma: no cover if resp.status != 200: log.error("\nError\n '%s'\n in response from URL:\n %s\n " "with query:\n %s" % (resp.reason, _url, body)) # pragma: no cover return HTTPInternalServerError( "See logs for details") # pragma: no cover # check for allowed content types if "content-type" not in resp: return HTTPNotAcceptable() # pragma: no cover if method == "POST" and is_get_feature(request.body): content = limit_featurecollection(content, limit=200) content_type = None if callback: content_type = "application/javascript" # escape single quotes in the JavaScript string content = unicode(content.decode('utf8')) content = content.replace(u"'", ur"\'") content = u"%s('%s');" % (callback, u' '.join(content.splitlines())) else: content_type = resp["content-type"] headers = {"Content-Type": content_type} if is_glg: # 30min expiration for GetLegendGraphic headers.update({"Cache-Control": "public, max-age=1800"}) return Response(content, status=resp.status, headers=headers)
def mobileconfig(self): """ View callable for the mobile application's config.js file. """ errors = [] layer_info = [] public_only = True mobile_default_themes = get_functionality( 'mobile_default_theme', self.settings, self.request ) theme_name = self.request.params.get( 'theme', mobile_default_themes[0] if len(mobile_default_themes) > 0 else None ) user = self.request.user if theme_name: role_id = None if user is None else user.role.id themes, errors = self._themes(role_id) themes = filter(lambda theme: theme['name'] == theme_name, themes) theme = themes[0] if len(themes) > 0 else None def process(node, layer_info, public_only=True): if 'children' in node: for child_node in node['children']: public_only = process( child_node, layer_info, public_only) else: layer_info.append(node) public_only = public_only and node['public'] is True return public_only if theme is not None: public_only = process(theme, layer_info) # we only support WMS layers right now layer_info = filter(lambda li: li['type'] == 'internal WMS', layer_info) # comma-separated string including the names of layers of the # requested theme layers = ','.join(reversed([li['name'] for li in layer_info])) # comma-separated string including the names of layers that # should visible by default in the map visible_layers = filter(lambda li: li['isChecked'] is True, layer_info) visible_layers = ','.join(reversed([li['name'] for li in visible_layers])) # comma-separated string including the feature types supported # by WFS service wfs_types, errors = self._internal_wfs_types() if len(errors) > 0: raise HTTPBadGateway('\n'.join(errors)) wfs_types = ','.join(wfs_types) # info includes various information that is not used by config.js, # but by other - private to the integrator - parts of the mobile # application. info = { 'username': user.username if user else '', 'publicLayersOnly': public_only } self.request.response.content_type = 'application/javascript' return { 'lang': self.lang, 'layers': layers, 'visible_layers': visible_layers, 'wfs_types': wfs_types, 'server_error': json.dumps(errors), 'info': json.dumps(info) }
def test_functionalities(self): from c2cgeoportal.tests.functional import create_dummy_request from c2cgeoportal.models import DBSession, User from c2cgeoportal.lib.functionality import get_functionality request = create_dummy_request() request.user = None request1 = create_dummy_request() request1.user = DBSession.query(User).filter(User.username == "__test_user1").one() request2 = create_dummy_request() request2.user = DBSession.query(User).filter(User.username == "__test_user2").one() settings = { "functionalities": { "anonymous": {}, "registered": {}, }, "admin_interface": { "available_functionalities": ["__test_a", "__test_s"] } } functionality.FUNCTIONALITIES_TYPES = None request.registry.settings.update(settings) request1.registry.settings.update(settings) request2.registry.settings.update(settings) self.assertEquals(get_functionality("__test_s", request), []) self.assertEquals(get_functionality("__test_a", request), []) self.assertEquals(get_functionality("__test_s", request1), []) self.assertEquals(get_functionality("__test_a", request1), []) self.assertEquals(get_functionality("__test_s", request2), ["db"]) self.assertEquals(get_functionality("__test_a", request2), ["db1", "db2"]) settings = { "functionalities": { "anonymous": {}, "registered": { "__test_s": "registered", "__test_a": ["r1", "r2"] } }, "admin_interface": { "available_functionalities": ["__test_a", "__test_s"] } } functionality.FUNCTIONALITIES_TYPES = None request.registry.settings.update(settings) request1.registry.settings.update(settings) request2.registry.settings.update(settings) self.assertEquals(get_functionality("__test_s", request), []) self.assertEquals(get_functionality("__test_a", request), []) self.assertEquals(get_functionality("__test_s", request1), ["registered"]) self.assertEquals(get_functionality("__test_a", request1), ["r1", "r2"]) self.assertEquals(get_functionality("__test_s", request2), ["db"]) self.assertEquals(get_functionality("__test_a", request2), ["db1", "db2"]) settings = { "functionalities": { "anonymous": { "__test_s": "anonymous", "__test_a": ["a1", "a2"] }, "registered": {} }, "admin_interface": { "available_functionalities": ["__test_a", "__test_s"] } } functionality.FUNCTIONALITIES_TYPES = None request.registry.settings.update(settings) request1.registry.settings.update(settings) request2.registry.settings.update(settings) self.assertEquals(get_functionality("__test_s", request), ["anonymous"]) self.assertEquals(get_functionality("__test_a", request), ["a1", "a2"]) self.assertEquals(get_functionality("__test_s", request1), ["anonymous"]) self.assertEquals(get_functionality("__test_a", request1), ["a1", "a2"]) self.assertEquals(get_functionality("__test_s", request2), ["db"]) self.assertEquals(get_functionality("__test_a", request2), ["db1", "db2"]) settings = { "functionalities": { "anonymous": { "__test_s": "anonymous", "__test_a": ["a1", "a2"] }, "registered": { "__test_s": "registered", "__test_a": ["r1", "r2"] } }, "admin_interface": { "available_functionalities": ["__test_a", "__test_s"] } } functionality.FUNCTIONALITIES_TYPES = None request.registry.settings.update(settings) request1.registry.settings.update(settings) request2.registry.settings.update(settings) self.assertEquals(get_functionality("__test_s", request), ["anonymous"]) self.assertEquals(get_functionality("__test_a", request), ["a1", "a2"]) self.assertEquals(get_functionality("__test_s", request1), ["registered"]) self.assertEquals(get_functionality("__test_a", request1), ["r1", "r2"]) self.assertEquals(get_functionality("__test_s", request2), ["db"]) self.assertEquals(get_functionality("__test_a", request2), ["db1", "db2"])
def proxy(self): user = self.request.user external = bool(self.request.params.get("EXTERNAL", None)) useSecurityMetadata = bool(self.request.registry.settings.get( 'use_security_metadata', False )) # params hold the parameters we're going to send to MapServer params = dict(self.request.params) # reset possible value of role_id and user_id if 'role_id' in params: # pragma: no cover del params['role_id'] if 'user_id' in params: # pragma: no cover del params['user_id'] if user: # We have a user logged in. We need to set group_id and # possible layer_name in the params. We set layer_name # when either QUERY_PARAMS or LAYERS is set in the # WMS params, i.e. for GetMap and GetFeatureInfo # requests. For GetLegendGraphic requests we don't # send layer_name, but MapServer shouldn't use the DATA # string for GetLegendGraphic. params['role_id'] = user.parent_role.id if external else user.role.id # In some application we want to display the features owned by a user # than we need his id. if not external: params['user_id'] = user.id # don't allows direct variable substitution for k in params.keys(): if k[:2].capitalize() == 'S_': log.warning("Direct substitution not allowed (%s=%s)." % (k, params[k])) del params[k] # add protected layers enabling params if user and useSecurityMetadata: role_id = user.parent_role.id if external else user.role.id layers = self._get_protected_layers(role_id) _params = dict( (k.lower(), unicode(v).lower()) for k, v in params.iteritems() ) if 'layers' in _params: # limit the list to queried layers l = [] for layer in _params['layers'].split(','): if layer in layers: l.append(layer) layers = l for layer in layers: params['s_enable_' + str(layer)] = '*' # add functionalities params mss = get_functionality( 'mapserver_substitution', self.request.registry.settings, self.request ) if mss: for s in mss: index = s.find('=') if index > 0: attribute = 's_' + s[:index] value = s[index + 1:] if attribute in params: params[attribute] += "," + value else: params[attribute] = value else: log.warning("Mapserver Substitution '%s' does not " "respect pattern: <attribute>=<value>" % s) # get method method = self.request.method # we want the browser to cache GetLegendGraphic and # DescribeFeatureType requests use_cache = False if method == "GET": _params = dict( (k.lower(), unicode(v).lower()) for k, v in params.iteritems() ) # For GET requests, params are added only if the self.request # parameter is actually provided. if 'request' not in _params: params = {} # pragma: no cover else: # WMS GetLegendGraphic self.request? use_cache = ('service' not in _params or _params['service'] == u'wms') and \ _params['request'] == u'getlegendgraphic' if _params['service'] == u'wfs' and \ _params['request'] == u'describefeaturetype': use_cache = True # pragma: no cover if 'service' in _params and _params['service'] == u'wfs': _url = self._get_external_wfs_url() if external else self._get_wfs_url() else: _url = self.request.registry.settings['external_mapserv_url'] \ if external \ else self.request.registry.settings['mapserv_url'] else: # POST means WFS _url = self._get_external_wfs_url() if external else self._get_wfs_url() if use_cache: return self._proxy_cache(_url, params, method, self.request.headers) else: return self._proxy( _url, params, use_cache, method, self.request.body, self.request.headers )
def proxy(request): user = request.user external = bool(request.params.get("EXTERNAL", None)) # params hold the parameters we're going to send to MapServer params = dict(request.params) # reset possible value of role_id and user_id if "role_id" in params: del params["role_id"] if "user_id" in params: del params["user_id"] if user: # We have a user logged in. We need to set group_id and # possible layer_name in the params. We set layer_name # when either QUERY_PARAMS or LAYERS is set in the # WMS params, i.e. for GetMap and GetFeatureInfo # requests. For GetLegendGraphic requests we don't # send layer_name, but MapServer shouldn't use the DATA # string for GetLegendGraphic. params["role_id"] = user.parent_role.id if external else user.role.id # In some application we want to display the features owned by a user # than we need his id. if not external: params["user_id"] = user.id # don't allows direct variable substitution for k in params.keys(): if k[:2].capitalize() == "S_": log.warning("Direct substitution not allowed (%s=%s)." % (k, params[k])) del params[k] mss = get_functionality("mapserver_substitution", request.registry.settings, request) if mss: for s in mss: index = s.find("=") if index > 0: attribute = "s_" + s[:index] value = s[index + 1 :] if attribute in params: params[attribute] += "," + value else: params[attribute] = value else: log.warning("Mapserver Substitution '%s' does not " "respect pattern: <attribute>=<value>" % s) # get method method = request.method # we want the browser to cache GetLegendGraphic requests, so # we need to know if the current request is a GetLegendGraphic # request is_glg = False # name of the JSON callback (value for the "callback" query string param # in the request). None if request has no "callback" param in the query # string callback = None if method == "GET": _params = dict((k.lower(), unicode(v).lower()) for k, v in params.iteritems()) # For GET requests, params are added only if the REQUEST # parameter is actually provided. if "request" not in _params: params = {} # pragma: no cover else: # WMS GetLegendGraphic request? is_glg = ("service" not in _params or _params["service"] == u"wms") and _params[ "request" ] == u"getlegendgraphic" callback = params.get("callback") # get query string params_encoded = {} for k, v in params.iteritems(): if k == "callback": continue params_encoded[k] = unicode(v).encode("utf-8") query_string = urllib.urlencode(params_encoded) # get URL _url = request.registry.settings["external_mapserv_url"] if external else request.registry.settings["mapserv_url"] _url += "?" + query_string log.info("Querying mapserver proxy at URL: %s." % _url) # get body body = None if method in ("POST", "PUT"): body = request.body # forward request to target (without Host Header) http = httplib2.Http() h = dict(request.headers) if urlparse(_url).hostname != "localhost": h.pop("Host") # mapserver don't need the cookie, and sometimes it failed with it. if "Cookie" in h: h.pop("Cookie") try: resp, content = http.request(_url, method=method, body=body, headers=h) except: # pragma: no cover log.error("Error '%s' while getting the URL: %s." % (sys.exc_info()[0], _url)) if method == "POST": log.error("--- With body ---") log.error(body) return HTTPBadGateway("See logs for details") # pragma: no cover if resp.status != 200: log.error( "\nError\n '%s'\n in response from URL:\n %s\n " "with query:\n %s" % (resp.reason, _url, body) ) # pragma: no cover return HTTPInternalServerError("See logs for details") # pragma: no cover # check for allowed content types if "content-type" not in resp: return HTTPNotAcceptable() # pragma: no cover if method == "POST" and is_get_feature(request.body): content = limit_featurecollection(content, limit=200) content_type = None if callback: content_type = "application/javascript" # escape single quotes in the JavaScript string content = unicode(content.decode("utf8")) content = content.replace(u"'", ur"\'") content = u"%s('%s');" % (callback, u" ".join(content.splitlines())) else: content_type = resp["content-type"] headers = {"Content-Type": content_type} if is_glg: # 30min expiration for GetLegendGraphic headers.update({"Cache-Control": "public, max-age=1800"}) return Response(content, status=resp.status, headers=headers)
def test_functionalities(self): from c2cgeoportal.tests.functional import create_dummy_request from c2cgeoportal.models import DBSession, User from c2cgeoportal.lib.functionality import get_functionality request = create_dummy_request() request.user = None request1 = create_dummy_request() request1.user = DBSession.query(User).filter(User.username == "__test_user1").one() request2 = create_dummy_request() request2.user = DBSession.query(User).filter(User.username == "__test_user2").one() settings = { "functionalities": { "anonymous": {}, "registered": {}, } } self.assertEquals(get_functionality("__test_s", settings, request), []) self.assertEquals(get_functionality("__test_a", settings, request), []) self.assertEquals(get_functionality("__test_s", settings, request1), []) self.assertEquals(get_functionality("__test_a", settings, request1), []) self.assertEquals(get_functionality("__test_s", settings, request2), ["db"]) self.assertEquals(get_functionality("__test_a", settings, request2), ["db1", "db2"]) settings = { "functionalities": { "anonymous": {}, "registered": { "__test_s": "registered", "__test_a": ["r1", "r2"] } } } self.assertEquals(get_functionality("__test_s", settings, request), []) self.assertEquals(get_functionality("__test_a", settings, request), []) self.assertEquals(get_functionality("__test_s", settings, request1), ["registered"]) self.assertEquals(get_functionality("__test_a", settings, request1), ["r1", "r2"]) self.assertEquals(get_functionality("__test_s", settings, request2), ["db"]) self.assertEquals(get_functionality("__test_a", settings, request2), ["db1", "db2"]) settings = { "functionalities": { "anonymous": { "__test_s": "anonymous", "__test_a": ["a1", "a2"] }, "registered": {} } } self.assertEquals(get_functionality("__test_s", settings, request), ["anonymous"]) self.assertEquals(get_functionality("__test_a", settings, request), ["a1", "a2"]) self.assertEquals(get_functionality("__test_s", settings, request1), ["anonymous"]) self.assertEquals(get_functionality("__test_a", settings, request1), ["a1", "a2"]) self.assertEquals(get_functionality("__test_s", settings, request2), ["db"]) self.assertEquals(get_functionality("__test_a", settings, request2), ["db1", "db2"]) settings = { "functionalities": { "anonymous": { "__test_s": "anonymous", "__test_a": ["a1", "a2"] }, "registered": { "__test_s": "registered", "__test_a": ["r1", "r2"] } } } self.assertEquals(get_functionality("__test_s", settings, request), ["anonymous"]) self.assertEquals(get_functionality("__test_a", settings, request), ["a1", "a2"]) self.assertEquals(get_functionality("__test_s", settings, request1), ["registered"]) self.assertEquals(get_functionality("__test_a", settings, request1), ["r1", "r2"]) self.assertEquals(get_functionality("__test_s", settings, request2), ["db"]) self.assertEquals(get_functionality("__test_a", settings, request2), ["db1", "db2"])
def test_functionalities(self): from c2cgeoportal.tests.functional import createDummyRequest from c2cgeoportal.models import DBSession, User from c2cgeoportal.lib.functionality import get_functionality request = createDummyRequest() request.user = None request1 = createDummyRequest() request1.user = DBSession.query(User).filter(User.username == '__test_user1').one() request2 = createDummyRequest() request2.user = DBSession.query(User).filter(User.username == '__test_user2').one() settings = { 'functionalities': { 'anonymous': {}, 'registered': {}, } } self.assertEquals(get_functionality('__test_s', settings, request), []) self.assertEquals(get_functionality('__test_a', settings, request), []) self.assertEquals(get_functionality('__test_s', settings, request1), []) self.assertEquals(get_functionality('__test_a', settings, request1), []) self.assertEquals(get_functionality('__test_s', settings, request2), ['db']) self.assertEquals(get_functionality('__test_a', settings, request2), ['db1', 'db2']) settings = { 'functionalities': { 'anonymous': {}, 'registered': { "__test_s": "registered", "__test_a": ["r1", "r2"] } } } self.assertEquals(get_functionality('__test_s', settings, request), []) self.assertEquals(get_functionality('__test_a', settings, request), []) self.assertEquals(get_functionality('__test_s', settings, request1), ['registered']) self.assertEquals(get_functionality('__test_a', settings, request1), ['r1', 'r2']) self.assertEquals(get_functionality('__test_s', settings, request2), ['db']) self.assertEquals(get_functionality('__test_a', settings, request2), ['db1', 'db2']) settings = { 'functionalities': { 'anonymous': { "__test_s": "anonymous", "__test_a": ["a1", "a2"] }, 'registered': {} } } self.assertEquals(get_functionality('__test_s', settings, request), ['anonymous']) self.assertEquals(get_functionality('__test_a', settings, request), ['a1', 'a2']) self.assertEquals(get_functionality('__test_s', settings, request1), ['anonymous']) self.assertEquals(get_functionality('__test_a', settings, request1), ['a1', 'a2']) self.assertEquals(get_functionality('__test_s', settings, request2), ['db']) self.assertEquals(get_functionality('__test_a', settings, request2), ['db1', 'db2']) settings = { 'functionalities': { 'anonymous': { "__test_s": "anonymous", "__test_a": ["a1", "a2"] }, 'registered': { "__test_s": "registered", "__test_a": ["r1", "r2"] } } } self.assertEquals(get_functionality('__test_s', settings, request), ['anonymous']) self.assertEquals(get_functionality('__test_a', settings, request), ['a1', 'a2']) self.assertEquals(get_functionality('__test_s', settings, request1), ['registered']) self.assertEquals(get_functionality('__test_a', settings, request1), ['r1', 'r2']) self.assertEquals(get_functionality('__test_s', settings, request2), ['db']) self.assertEquals(get_functionality('__test_a', settings, request2), ['db1', 'db2'])
def mobileconfig(self): """ View callable for the mobile application's config.js file. """ errors = set() interface = self.request.interface_name mobile_default_themes = get_functionality( "mobile_default_theme", self.settings, self.request ) theme_name = self.request.params.get( "theme", mobile_default_themes[0] if len(mobile_default_themes) > 0 else None ) user = self.request.user role_id = None if user is None else user.role.id themes, errors = self._themes(role_id, interface, False) for t in themes: self.flatten_layers(t) # comma-separated string including the feature types supported # by WFS service wfs_types, errors = self._internal_wfs_types(role_id) if len(errors) > 0: # pragma: no cover raise HTTPBadGateway("\n".join(errors)) # info includes various information that is not used by config.js, # but by other - private to the integrator - parts of the mobile # application. info = { "username": user.username if user else "" } # get the list of themes available for mobile themes_ = [] themes, errors = self._themes(role_id, interface, False) for theme in themes: # mobile theme or hidden theme explicitely loaded if theme["in_mobile_viewer"] or theme["name"] == theme_name: themes_.append({ "name": theme["name"], "icon": theme["icon"], "allLayers": theme["allLayers"], "layers": theme["layers"], }) set_common_headers( self.request, "sencha_config", PRIVATE_CACHE, vary=True, content_type="application/javascript", ) return { "lang": self.lang, "themes": themes_, "theme": theme_name if theme_name is not None else "", "wfs_types": wfs_types, "server_error": errors, "info": info, }
def proxy(self): user = self.request.user external = bool(self.request.params.get("EXTERNAL", None)) # params hold the parameters we're going to send to MapServer params = dict(self.request.params) # reset possible value of role_id and user_id if 'role_id' in params: # pragma: no cover del params['role_id'] if 'user_id' in params: # pragma: no cover del params['user_id'] if user: # We have a user logged in. We need to set group_id and # possible layer_name in the params. We set layer_name # when either QUERY_PARAMS or LAYERS is set in the # WMS params, i.e. for GetMap and GetFeatureInfo # requests. For GetLegendGraphic requests we don't # send layer_name, but MapServer shouldn't use the DATA # string for GetLegendGraphic. params[ 'role_id'] = user.parent_role.id if external else user.role.id # In some application we want to display the features owned by a user # than we need his id. if not external: params['user_id'] = user.id # don't allows direct variable substitution for k in params.keys(): if k[:2].capitalize() == 'S_': log.warning("Direct substitution not allowed (%s=%s)." % (k, params[k])) del params[k] # add protected layers enabling params if user: role_id = user.parent_role.id if external else user.role.id layers = self._get_protected_layers(role_id) _params = dict( (k.lower(), unicode(v).lower()) for k, v in params.iteritems()) if 'layers' in _params: # limit the list to queried layers l = [] for layer in _params['layers'].split(','): if layer in layers: l.append(layer) layers = l for layer in layers: params['s_enable_' + str(layer)] = '*' # add functionalities params mss = get_functionality('mapserver_substitution', self.request.registry.settings, self.request) if mss: for s in mss: index = s.find('=') if index > 0: attribute = 's_' + s[:index] value = s[index + 1:] if attribute in params: params[attribute] += "," + value else: params[attribute] = value else: log.warning("Mapserver Substitution '%s' does not " "respect pattern: <attribute>=<value>" % s) # get method method = self.request.method # we want the browser to cache GetLegendGraphic and # DescribeFeatureType requests use_cache = False if method == "GET": _params = dict( (k.lower(), unicode(v).lower()) for k, v in params.iteritems()) # For GET requests, params are added only if the self.request # parameter is actually provided. if 'request' not in _params: params = {} # pragma: no cover else: # WMS GetLegendGraphic self.request? use_cache = ('service' not in _params or _params['service'] == u'wms') and \ _params['request'] == u'getlegendgraphic' if _params['service'] == u'wfs' and \ _params['request'] == u'describefeaturetype': use_cache = True # pragma: no cover if 'service' in _params and _params['service'] == u'wfs': _url = self._get_external_wfs_url( ) if external else self._get_wfs_url() else: _url = self.request.registry.settings['external_mapserv_url'] \ if external \ else self.request.registry.settings['mapserv_url'] else: # POST means WFS _url = self._get_external_wfs_url( ) if external else self._get_wfs_url() if use_cache: return self._proxy_cache(_url, params, method, self.request.headers) else: return self._proxy(_url, params, use_cache, method, self.request.body, self.request.headers)
def mobileconfig(self): """ View callable for the mobile application's config.js file. """ errors = [] layer_info = [] public_only = True mobile_default_themes = get_functionality('mobile_default_theme', self.settings, self.request) theme_name = self.request.params.get( 'theme', mobile_default_themes[0] if len(mobile_default_themes) > 0 else None) user = self.request.user if theme_name: role_id = None if user is None else user.role.id themes, errors = self._themes(role_id) themes = filter(lambda theme: theme['name'] == theme_name, themes) theme = themes[0] if len(themes) > 0 else None def process(node, layer_info, public_only=True): if 'children' in node: for child_node in node['children']: public_only = process(child_node, layer_info, public_only) else: layer_info.append(node) public_only = public_only and node['public'] is True return public_only if theme is not None: public_only = process(theme, layer_info) # we only support WMS layers right now layer_info = filter(lambda li: li['type'] == 'internal WMS', layer_info) # comma-separated string including the names of layers of the # requested theme layers = ','.join(reversed([li['name'] for li in layer_info])) # comma-separated string including the names of layers that # should visible by default in the map visible_layers = filter(lambda li: li['isChecked'] is True, layer_info) visible_layers = ','.join( reversed([li['name'] for li in visible_layers])) # comma-separated string including the feature types supported # by WFS service wfs_types, errors = self._internal_wfs_types() if len(errors) > 0: raise HTTPBadGateway('\n'.join(errors)) wfs_types = ','.join(wfs_types) # info includes various information that is not used by config.js, # but by other - private to the integrator - parts of the mobile # application. info = { 'username': user.username if user else '', 'publicLayersOnly': public_only } self.request.response.content_type = 'application/javascript' return { 'lang': self.lang, 'layers': layers, 'visible_layers': visible_layers, 'wfs_types': wfs_types, 'server_error': json.dumps(errors), 'info': json.dumps(info) }