def login(self): request = self.request username = request.params.get('username', None) password = request.params.get('password', None) # logger.info('LOGIN: i parametri di INPUT sono {username}, {password}'.format(username=username, logger.info('LOGIN: i parametri di INPUT sono {username}'.format(username=username)) if username is not None and username != '': if password is not None and password != '': result = AuthenticationController.login(request, request.dbsession, username, password) if result['code'] == self.success_request: logger.info('LOGIN COMPLETATA! Reindirizzamento alla home.') return make_response('Success', 302, url=request.route_url('dashboard')) elif result['code'] == self.not_acceptable_request: logger.error('LOGIN FALLITA: {}'.format(result['message'])) return HTTPNotAcceptable(body=result['message']) elif result['code'] == self.conflict_request: logger.error('LOGIN FALLITA: {}'.format(result['message'])) return HTTPConflict(body=result['message']) else: logger.error(result) return HTTPInternalServerError(body='Errore inaspettato. Ci scusiamo per il disagio!') else: logger.error('LOGIN FALLITA perché manca il parametro PASSWORD') return HTTPNotAcceptable(body='Manca la PASSWORD! Controlla.') else: logger.error('LOGIN FALLITA perché manca il parametro USERNAME') return HTTPNotAcceptable(body='Manca USERNAME! Controlla.')
def ogcproxy(request): url = request.params.get("url") if url is None: return HTTPBadRequest() # check for full url parsed_url = urlparse(url) if not parsed_url.netloc or parsed_url.scheme not in ("http", "https"): raise HTTPBadRequest() # forward request to target (without Host Header) http = Http(disable_ssl_certificate_validation=True) h = dict(request.headers) h.pop("Host", h) try: resp, content = http.request(url, method=request.method, body=request.body, headers=h) except: raise HTTPBadGateway() # All content types are allowed if "content-type" in resp: ct = resp["content-type"] if resp["content-type"] == "application/vnd.google-earth.kmz": zipfile = None try: zipurl = urlopen(url) zipfile = ZipFile(StringIO(zipurl.read())) content = '' for line in zipfile.open(zipfile.namelist()[0]).readlines(): content = content + line ct = 'application/vnd.google-earth.kml+xml' except: raise HTTPBadGateway() finally: if zipfile: zipurl.close() else: raise HTTPNotAcceptable() if content.find('encoding=') > 0: m = re.search("encoding=\"(.*?)\\\"", content) try: data = content.decode(m.group(1)) except Exception: raise HTTPNotAcceptable() content = data.encode('utf-8') content = content.replace(m.group(1), 'utf-8') response = Response(content, status=resp.status, headers={"Content-Type": ct}) return response
def list_csv(self): """ The CSV view - Allow download of the data as CSV """ if not self.enable_csv: return HTTPNotAcceptable(detail="CSV download disabled") csv_buffer = StringIO() csv_writer = csv.writer(csv_buffer) all_records = False if "y" == self.request.GET.get("all", "n"): all_records = True records = self._list_csv_common_code(return_only_records=True, return_all_records=all_records) if 0 == records.count(): return HTTPNotAcceptable(detail="No data") columns = self._get_list_columns() heading_row = [] for column in columns: if ( self.field_translations and column in self.field_translations and "header" in self.field_translations[column] ): heading_row.append(self.field_translations[column]["header"]) else: heading_row.append(column.replace("_", " ").title()) csv_writer.writerow(heading_row) for R in records: data_row = [] for column in columns: if column in self.list_field_args and "display_field" in self.list_field_args[column]: data_row.append(self._get_col_value(self.list_field_args[column]["display_field"], R)) else: col_value = getattr(R, column) if self.field_translations and column in self.field_translations: col_value = self.field_translations[column]["translator"](col_value) data_row.append(col_value) csv_writer.writerow(data_row) headers = {} headers["Content-Description"] = self.friendly_name headers["Content-Disposition"] = 'attachment; filename="{}.csv"'.format(self.friendly_name) headers["Content-Type"] = "text/csv" return Response(body=csv_buffer.getvalue(), headers=headers)
def langdoccomplexquery(request): res = { 'dt': None, 'doctypes': DBSession.query(Doctype).order_by(Doctype.id), 'macroareas': DBSession.query(Macroarea).order_by(Macroarea.id), 'ms': {} } for name, cls, kw in [ ('languoids', LanguoidsMultiSelect, dict(url=request.route_url('glottolog.childnodes'))), ('macroareas', MultiSelect, dict(collection=res['macroareas'])), ('doctypes', MultiSelect, dict(collection=res['doctypes'])), ]: res['ms'][name] = cls(request, name, 'ms' + name, **kw) res['params'], reqparams = get_params(request.params, **res) res['refs'] = getRefs(res['params']) if res['refs']: res['dt'] = Refs(request, Source, cq=1, **reqparams) fmt = request.params.get('format') if fmt: db = bibtex.Database([ref.bibtex() for ref in res['refs']]) for name, adapter in request.registry.getAdapters([db], IRepresentation): if name == fmt: return adapter.render_to_response(db, request) return HTTPNotAcceptable() return res
def get_engine_factory(self, request, filename=False): """Return engine factory (class) for request. If ``filename`` is ``True`` (defaults to ``False``), then return the engine to render filenames. It may differ from the engine to render files. """ # Try engine from request's GET. try: engine_slug = request.GET['engine'] except KeyError: engine_type = 'diecutter.filename_engine' if filename \ else 'diecutter.engine' engine_slug = request.registry.settings[engine_type] if not hasattr(request, 'cache'): request.cache = {} if filename: request.cache['diecutter_filename_engine_slug'] = engine_slug else: request.cache['diecutter_engine_slug'] = engine_slug try: engine_path_setting = 'diecutter.engine.{0}'.format(engine_slug) engine_path = request.registry.settings[engine_path_setting] except KeyError: raise HTTPNotAcceptable( 'Supported template engines: %s' % ', '.join(sorted(supported_engines(request)))) config = Configurator(request.registry.settings) engine_factory = config.maybe_dotted(engine_path) return engine_factory
def get_validated_fields(self, schema, **kwargs): try: return schema.load(self.request.json_body, **kwargs) except JSONDecodeError: raise HTTPNotAcceptable() except ValidationError as error: raise HTTPBadRequest(json=error.messages)
def unapi(req): """implements the server side of the unAPI spec. """ id_ = req.params.get('id') if id_: obj = req.ctx_for_url(id_) if not obj: return HTTPNotFound() format_ = req.params.get('format') if not format_: kw = {'content_type': 'application/xml'} if id_: formats = [a for n, a in get_adapters(IMetadata, obj, req)] kw['status'] = '300 Multiple Choices' else: formats = [] body = render('unapiformats.mako', { 'formats': formats, 'identifier': id_ }, request=req) return Response(body, **kw) if not id_: return HTTPNotFound() adapter = None for _n, _a in get_adapters(IMetadata, obj, req): if _a.unapi_name == format_: adapter = _a break if not adapter: return HTTPNotAcceptable() return HTTPFound(location=req.resource_url(obj, ext=adapter.extension))
def get_writers(self, request, resource, context): """Return iterable of writers.""" if resource.is_file: return [file_response] else: accepted_mime_types = diecutter.utils.accepted_types(request) # Reference. mime_map = { 'application/zip': [zip_directory_response], 'application/gzip': [targz_directory_response], } # Aliases. mime_map['application/x-gzip'] = mime_map['application/gzip'] # Fallback. settings = request.registry.settings try: default_type = settings['diecutter.default_archive_type'] except KeyError: default_type = 'application/gzip' if default_type not in mime_map.keys(): raise ConfigurationError( 'Cannot use "{type}" as "default_archive_type". Supported ' 'types are: {supported}'.format(type=default_type, supported=','.join( mime_map.keys()))) mime_map['*/*'] = mime_map[default_type] for accepted_mime_type in accepted_mime_types: try: return mime_map[accepted_mime_type] except KeyError: pass raise HTTPNotAcceptable('Supported mime types: %s' % ', '.join(sorted(mime_map.keys())))
def _fallback_view(request): # Maybe we failed to match any definitions for the request method? if request.method not in service.defined_methods: response = HTTPMethodNotAllowed() response.allow = service.defined_methods return response # Maybe we failed to match an acceptable content-type? # First search all the definitions to find the acceptable types. # XXX: precalculate this like the defined_methods list? acceptable = [] for method, _, args in service.definitions: if method != request.method: continue if 'accept' in args: acceptable.extend( service.get_acceptable(method, filter_callables=True)) if 'acceptable' in request.info: for content_type in request.info['acceptable']: if content_type not in acceptable: acceptable.append(content_type) # Now check if that was actually the source of the problem. if not request.accept.best_match(acceptable): response = HTTPNotAcceptable() response.content_type = "application/json" response.body = json.dumps(acceptable) return response # In the absence of further information about what went wrong, # let upstream deal with the mismatch. raise PredicateMismatch(service.name)
def is1111process_view(request): VP = views_processor.ViewProcessor() if "fastafile" not in request.POST or "fastaentry" not in request.POST: raise HTTPNotFound() filename = "" process_ID = uuid.uuid4().hex try: filename = request.POST["fastafile"].filename except: pass if filename is not "": inputfile = request.POST["fastafile"].file file_path = VP.create_file_from_fastafile(inputfile, process_ID, "sole") else: sequence = memoryview(request.POST["fastaentry"].encode("utf-8")) file_path = VP.create_file_from_fastaentry(sequence, process_ID) command = VP.create_epcr_command(file_path, process_ID, "sole", "is1111") subprocess.call(command) try: is1111_dict = VP.extract_is1111_values(process_ID, "sole") except: raise HTTPNotAcceptable() submission_dict = { "ID": process_ID, "AnalysisType": "is1111 Insilico typing", "IPaddress": request.remote_addr, } session = request.db2_session session.execute(insert(models.SubmissionTable).values([submission_dict])) session.execute(insert(models.is1111Profile).values([is1111_dict])) session.commit() url = request.route_url("resis1111", ID=process_ID) return HTTPFound(location=url)
def registration(self): request = self.request nome = request.params.get('nome', None) cognome = request.params.get('cognome', None) password = request.params.get('password', None) username = request.params.get('username', None) logger.info('REGISTRATION INPUT sono: {nome}, {cognome}, {password}, {username}'.format(nome=nome, cognome=cognome, password=password, username=username)) if nome is not None and nome != '': if cognome is not None and cognome != '': if password is not None and password != '': if username is not None and username != '': # controller result = AuthenticationController.registration(request.dbsession, nome, cognome, password, username) logger.info('REGISTRATION OUTPUT é: {}'.format(json.dumps(result))) if result['code'] == self.success_request: logger.info('REGISTRATION COMPLETATA!') return HTTPOk(body='Registrazione completata con successo!') elif result['code'] == self.not_acceptable_request: logger.error('REGISTRATION FALLITA: {}'.format(result['message'])) return HTTPNotAcceptable(body=result['message']) elif result['code'] == self.conflict_request: logger.error('REGISTRATION FALLITA: {}'.format(result['message'])) return HTTPConflict(body=result['message']) else: logger.error('REGISTRATION FALLITA: errore inaspettato.') logger.error('{}'.format(result['message'])) return HTTPInternalServerError(body='Errore inaspettato. Ci scusiamo per il disagio!') else: logger.error('REGISTRATION FALLITA perché manca il parametro USERNAME') return HTTPNotAcceptable('Manca lo USERNAME! Controlla.') else: logger.error('REGISTRATION FALLITA perché manca il parametro PASSWORD') return HTTPNotAcceptable('Manca la PASSWORD! Controlla.') else: logger.error('REGISTRATION FALLITA perché manca il parametro COGNOME') return HTTPNotAcceptable('Manca il COGNOME! Controlla.') else: logger.error('REGISTRATION FALLITA perché manca il parametro NOME') return HTTPNotAcceptable('Manca il NOME! Controlla.')
def handle_new_request(event): settings = event.request.registry.settings event.request.handle_cors() if settings["enforce_https"] and event.request.scheme != "https": raise HTTPNotAcceptable("SSL is required") if settings["http_scheme"]: event.request.scheme = settings["http_scheme"]
def wrapper(context, request): # If Accept has been set if request.accept: # At least one of the media types in Accept must be known to the app if not any([t in valid_media_types() for t in request.accept]): # If no Accept media types are known, convert to a 406 error context = HTTPNotAcceptable("Not acceptable") response = wrapped(context, request) return response
def submit_job(request, reference, tags=None): # type: (Request, Union[Service, Process], Optional[List[str]]) -> JSON """ Generates the job submission from details retrieved in the request. .. seealso:: :func:`submit_job_handler` to provide elements pre-extracted from requests or from other parsing. """ # validate body with expected JSON content and schema if CONTENT_TYPE_APP_JSON not in request.content_type: raise HTTPBadRequest(json={ "code": "InvalidHeaderValue", "name": "Content-Type", "description": "Request 'Content-Type' header other than '{}' not supported.".format(CONTENT_TYPE_APP_JSON), "value": str(request.content_type) }) try: json_body = request.json_body except Exception as ex: raise HTTPBadRequest("Invalid JSON body cannot be decoded for job submission. [{}]".format(ex)) # validate context if needed later on by the job for early failure context = get_wps_output_context(request) provider_id = None # None OK if local process_id = None # None OK if remote, but can be found as well if available from WPS-REST path tags = tags or [] lang = request.accept_language.header_value # can only preemptively check if local process if isinstance(reference, Process): service_url = reference.processEndpointWPS1 process_id = reference.id visibility = reference.visibility is_workflow = reference.type == PROCESS_WORKFLOW is_local = True tags += "local" if lang and request.accept_language.best_match(ACCEPT_LANGUAGES) is None: raise HTTPNotAcceptable("Requested language [{}] is not in supported languages [{}].".format( lang, ", ".join(ACCEPT_LANGUAGES) )) elif isinstance(reference, Service): service_url = reference.url provider_id = reference.id process_id = request.matchdict.get("process_id") visibility = VISIBILITY_PUBLIC is_workflow = False is_local = False tags += "remote" else: LOGGER.error("Expected process/service, got: %s", type(reference)) raise TypeError("Invalid process or service reference to execute job.") tags = request.params.get("tags", "").split(",") + tags user = request.authenticated_userid headers = dict(request.headers) settings = get_settings(request) return submit_job_handler(json_body, settings, service_url, provider_id, process_id, is_workflow, is_local, visibility, language=lang, auth=headers, tags=tags, user=user, context=context)
def view(interface, ctx, req): """renders a resource as pyramid response using the most appropriate adapter for the accept header sent. """ adapter = get_adapter(interface, ctx, req, ext=req.matchdict and req.matchdict.get('ext')) if not adapter: raise HTTPNotAcceptable() return adapter.render_to_response(ctx, req)
def get_file_header(request): ctx = request.context document = ctx._instance f = File.get(document.id) if f.infected: raise HTTPNotAcceptable("Infected with a virus") handoff_to_nginx = asbool(config.get('handoff_to_nginx', False)) return Response( content_length=f.size, content_type=str(f.mime_type), last_modified=f.creation_date, expires=datetime.now() + timedelta(days=365), accept_ranges="bytes" if handoff_to_nginx else "none", )
def as_mind_map(request): for mimetype in request.GET.getall('mimetype'): mimetype = mimetype.encode('utf-8') if mimetype in pygraphviz_formats: break else: mimetype = request.accept.best_match(pygraphviz_formats.keys()) if not mimetype: raise HTTPNotAcceptable("Not known to pygraphviz: " + mimetype) discussion = request.context._instance G = discussion.as_mind_map() G.layout(prog='twopi') io = StringIO() G.draw(io, format=pygraphviz_formats[mimetype]) io.seek(0) return Response(body_file=io, content_type=mimetype)
def _get_response_representer(self): """ Creates a representer for this view. :raises: :class:`pyramid.httpexceptions.HTTPNotAcceptable` if the MIME content type(s) the client specified can not be handled by the view. :returns: :class:`everest.representers.base.ResourceRepresenter` """ view_name = self.request.view_name if view_name != '': mime_type = get_registered_mime_type_for_name(view_name) rpr = as_representer(self.context, mime_type) else: mime_type = None acc = None for acc in self.request.accept: if acc == '*/*': # The client does not care; use the default. mime_type = self.__get_default_response_mime_type() break try: mime_type = \ get_registered_mime_type_for_string(acc.lower()) except KeyError: pass else: break if mime_type is None: if not acc is None: # The client specified a MIME type we can not handle; this # is a 406 exxception. We supply allowed MIME content # types in the body of the response. headers = \ [('Location', self.request.path_url), ('Content-Type', TextPlainMime.mime_type_string), ] mime_strings = get_registered_mime_strings() exc = HTTPNotAcceptable( 'Requested MIME content type(s) ' 'not acceptable.', body=','.join(mime_strings), headers=headers) raise exc mime_type = self.__get_default_response_mime_type() rpr = as_representer(self.context, mime_type) return rpr
def getqrcode(self): url = self.request.params.get('url', '') if len(url) == 0: return HTTPBadRequest() if not self.regex.match(url): return HTTPNotAcceptable( "not a valid url for this QR code generator") qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=3, border=0) qr.add_data(url) qr.make(fit=True) im = qr.make_image() output = BytesIO() im.save(output) headers = {"Content-Type": 'image/png'} return Response(output.getvalue(), headers=headers)
def get_file(request): # TODO: Add a route that enables the call to have the filename # appended to the end. This is so that gmail can read the services # Read more here: # http://stackoverflow.com/questions/20903967/gmails-new-image-caching-is-breaking-image-links-in-newsletter ctx = request.context document = ctx._instance f = File.get(document.id) if f.infected: raise HTTPNotAcceptable("Infected with a virus") escaped_double_quotes_filename = (f.title .replace(u'"', u'\\"') .encode('iso-8859-1', 'replace')) url_quoted_utf8_filename = url_quote(f.title.encode('utf-8')) handoff_to_nginx = asbool(config.get('handoff_to_nginx', False)) if handoff_to_nginx: kwargs = dict(body='') else: if 'Range' in request.headers: raise HTTPRequestRangeNotSatisfiable() fs = open(f.path, 'rb') app_iter = None environ = request.environ if 'wsgi.file_wrapper' in environ: app_iter = environ['wsgi.file_wrapper'](fs, _BLOCK_SIZE) if app_iter is None: app_iter = FileIter(fs, _BLOCK_SIZE) kwargs=dict(app_iter=app_iter) r = Response( content_length=f.size, content_type=str(f.mime_type), last_modified=f.creation_date, expires=datetime.now()+timedelta(days=365), accept_ranges="bytes" if handoff_to_nginx else "none", content_disposition= 'attachment; filename="%s"; filename*=utf-8\'\'%s' # RFC 6266 % (escaped_double_quotes_filename, url_quoted_utf8_filename), **kwargs ) if handoff_to_nginx: r.headers[b'X-Accel-Redirect'] = f.handoff_url return r
def delete(self): """ The record delete view TODO: * Later may need to add support for composite primary keys here. """ R = self._get_rec_from_pk_val() try: self.db_session.delete(R) self.db_session.flush() except IntegrityError as exp: return HTTPNotAcceptable(detail="Cannot delete category as it has dependent records\n" + str(exp)) self.request.session.flash(self.friendly_name + " deleted successfully!") # return HTTPFound(location=os.path.dirname(os.path.dirname(self.request.current_route_url()))) return self._redirect(os.path.dirname(os.path.dirname(self.request.current_route_url())) + "/")
def ogcproxy(request): url = request.params.get("url") if url is None: return HTTPBadRequest("Missing url in the query string") # check for full url parsed_url = urlparse(url) if not parsed_url.netloc or parsed_url.scheme not in ("http", "https"): return HTTPBadRequest("Wrong scheme") # forward request to target (without Host Header) http = Http(disable_ssl_certificate_validation=True, proxy_info=proxy_info) headers = { h: request.headers[h] for h in forwarded_headers if h in request.headers } try: resp, content = http.request(url, method=request.method, body=request.body, headers=headers) except: return HTTPBadGateway() # check for allowed content types if "content-type" in resp: ct = resp["content-type"] if not ct.split(";")[0] in allowed_content_types: # allow any content type from allowed hosts (any port) if parsed_url.netloc not in allowed_hosts: return HTTPForbidden("Wrong returned content type") else: return HTTPNotAcceptable("No returned content type") response = Response(content, status=resp.status, headers={"Content-Type": ct}) return response
def ogcproxy(request): if "url" not in request.params: return HTTPBadRequest() url = request.params["url"] # check for full url parsed_url = urlparse(url) if not parsed_url.netloc or parsed_url.scheme not in ("http", "https"): return HTTPBadRequest() # get method method = request.method # get body body = request.body if method in ("POST", "PUT") else None # forward request to target (without Host Header) http = Http() h = dict(request.headers) h.pop("Host", h) try: resp, content = http.request(url, method=method, body=body, headers=h) except: return HTTPBadGateway() # check for allowed content types if resp.has_key("content-type"): ct = resp["content-type"] if not ct.split(";")[0] in allowed_content_types: # allow any content type from allowed hosts (any port) if not parsed_url.netloc in allowed_hosts: return HTTPForbidden() else: return HTTPNotAcceptable() response = Response(content, status=resp.status, headers={"Content-Type": ct}) return response
def upload_manuals(self): file_upload = self.request.params.get('file', None) md5 = self.request.params.get('md5', None) if file_upload is not None: result = ManualController.upload(self.request, file_upload, md5) if result["code"] == self.success_request: return HTTPOk(body=result["message"]) elif result["code"] == self.not_acceptable_request: return HTTPNotAcceptable(body=result["message"]) elif result["code"] == self.conflict_request: return HTTPConflict(body=result["message"]) elif result["code"] == self.internal_server_error: return HTTPInternalServerError(body=result["message"]) elif result["code"] == self.memory_error: return HTTPInsufficientStorage(body=result["message"]) else: return HTTPInternalServerError(body="Stiamo riscontrando un'anomalia a livello di sistema. Ci scusiamo " "per l'inconveniente!") else: return HTTPBadRequest(body="Selezionare un file.")
def get_file(request): # TODO: Add a route that enables the call to have the filename # appended to the end. This is so that gmail can read the services # Read more here: # http://stackoverflow.com/questions/20903967/gmails-new-image-caching-is-breaking-image-links-in-newsletter if request.method == 'HEAD': # GET view_config captures HEAD... return get_file_header(request) ctx = request.context document = ctx._instance f = File.get(document.id) if f.infected: raise HTTPNotAcceptable("Infected with a virus") handoff_to_nginx = asbool(config.get('handoff_to_nginx', False)) if handoff_to_nginx: kwargs = dict(body='') else: if 'Range' in request.headers: raise HTTPRequestRangeNotSatisfiable() fs = f.file_stream app_iter = None environ = request.environ if 'wsgi.file_wrapper' in environ and f.path: app_iter = environ['wsgi.file_wrapper'](fs, _BLOCK_SIZE) if app_iter is None: app_iter = FileIter(fs, _BLOCK_SIZE) kwargs = dict(app_iter=app_iter) r = Response( content_length=f.file_size, content_type=str(f.mime_type), last_modified=f.creation_date, expires=datetime.now() + timedelta(days=365), accept_ranges="bytes" if handoff_to_nginx else "none", content_disposition=disposition(f.title), # RFC 6266 **kwargs ) if handoff_to_nginx: r.headers[b'X-Accel-Redirect'] = f.handoff_url return r
def _fallback_view(self, request): """Fallback view for this service, called when nothing else matches. This method provides the view logic to be executed when the request does not match any explicitly-defined view. Its main responsibility is to produce an accurate error response, such as HTTPMethodNotAllowed or HTTPNotAcceptable. """ # Maybe we failed to match any definitions for the request method? if request.method not in self.defined_methods: response = HTTPMethodNotAllowed() response.allow = self.defined_methods return response # Maybe we failed to match an acceptable content-type? # First search all the definitions to find the acceptable types. # XXX: precalculate this like the defined_methods list? acceptable = [] for api_kwargs in self.definitions: if api_kwargs['request_method'] != request.method: continue if 'accept' in api_kwargs: accept = to_list(api_kwargs.get('accept')) acceptable.extend(a for a in accept if not callable(a)) if 'acceptable' in request.info: for content_type in request.info['acceptable']: if content_type not in acceptable: acceptable.append(content_type) # Now check if that was actually the source of the problem. if not request.accept.best_match(acceptable): response = HTTPNotAcceptable() response.content_type = "application/json" response.body = json.dumps(acceptable) return response # In the absence of further information about what went wrong, # let upstream deal with the mismatch. raise PredicateMismatch(self.name)
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 ogcproxy(self): url = self.request.params.get("url") if url is None: return HTTPBadRequest() # check for full url parsed_url = urlparse(url) if not parsed_url.netloc or parsed_url.scheme not in ("http", "https"): raise HTTPBadRequest() # forward request to target (without Host Header) http = Http(disable_ssl_certificate_validation=True) h = dict(self.request.headers) h.pop("Host", h) try: resp, content = http.request(url, method=self.request.method, body=self.request.body, headers=h) except: raise HTTPBadGateway() # All content types are allowed if "content-type" in resp: ct = resp["content-type"] if resp["content-type"] == "application/vnd.google-earth.kmz": zipfile = None try: zipurl = urlopen(url) zipfile = ZipFile(StringIO(zipurl.read())) content = '' for line in zipfile.open( zipfile.namelist()[0]).readlines(): content = content + line ct = 'application/vnd.google-earth.kml+xml' except: raise HTTPBadGateway() finally: if zipfile: zipurl.close() else: raise HTTPNotAcceptable() if content.find('encoding=') > 0: m = re.search("encoding=[\\\"|\"|\'](.*?)[\\\"|\"|\']", content) doc_encoding = m.group(1) if doc_encoding.lower() != DEFAULT_ENCODING: try: data = content.decode(doc_encoding, "replace") except Exception: raise HTTPNotAcceptable( "Cannot decode requested content from advertized encoding: %s into unicode." % doc_encoding) content = data.encode(DEFAULT_ENCODING) content = content.replace(doc_encoding, DEFAULT_ENCODING) response = Response(content, status=resp.status, headers={"Content-Type": ct}) return response
def categories_view(request): "Categories custom CRUD interface" action = request.GET.get('action', 'add') category = None if 'add' == action and 'POST' == request.method: category = Category(name=request.POST['name'], slug=request.POST['slug'], description=request.POST['description']) if '' != request.POST.get('parent_category', ''): category.parent_category = int(request.POST['parent_category']) db.add(category) request.session.flash( "category {name} added!".format(name=category.name)) elif 'edit' == action and 'GET' == request.method: try: category = _get_record(item_type='category', item_id=None, request=request, msg="Cannot edit, category not found.") except HTTPNotFound as exp: return exp elif 'edit' == action and 'POST' == request.method: action = 'add' try: category = _get_record(item_type='category', item_id=None, request=request, msg="Cannot update, category not found.") category.name = request.POST['name'] category.slug = request.POST['slug'] category.description = request.POST['description'] if '' != request.POST.get('parent_category', ''): category.parent_category = int(request.POST['parent_category']) request.session.flash( "category {name} updated!".format(name=category.name)) except HTTPNotFound as exp: return exp elif 'delete' == action: try: category = _get_record(item_type='category', item_id=None, request=request, msg="Cannot delete, category not found.") db.delete(category) db.flush() request.session.flash( "category {name} deleted!".format(name=category.name)) except HTTPNotFound as exp: return exp except IntegrityError: return HTTPNotAcceptable( detail="Cannot delete category as it has dependent records\n") categories = Category.get_tree() log.debug(categories) return { 'APP_BASE': APP_BASE, 'APP_NAME': APP_NAME, 'categories': categories, 'action': action, 'category': category }
def posts_view(request): "Blog posts custom CRUD interface" action = request.GET.get('action', 'add') post = None if 'add' == action and 'POST' == request.method: post = Post(title=request.POST['title'], slug=request.POST['slug'], keywords=request.POST['keywords']) if 'y' != request.POST.get('comments_allowed', 'n'): post.comments_allowed = False if '' != request.POST.get('category_id', ''): post.category_id = int(request.POST['category_id']) db.add(post) request.session.flash("post {name} added!".format(name=post.title)) elif 'edit' == action and 'GET' == request.method: try: post = _get_record(item_type='post', item_id=None, request=request, msg="Cannot edit, post not found.") except HTTPNotFound as exp: return exp elif 'edit' == action and 'POST' == request.method: action = 'add' try: post = _get_record(item_type='post', item_id=None, request=request, msg="Cannot update, post not found.") post.name = request.POST['name'] post.slug = request.POST['slug'] post.description = request.POST['description'] if '' != request.POST.get('parent_post', ''): post.parent_post = int(request.POST['parent_post']) request.session.flash( "post {name} updated!".format(name=post.name)) except HTTPNotFound as exp: return exp elif 'delete' == action: try: post = _get_record(item_type='post', item_id=None, request=request, msg="Cannot delete, post not found.") db.delete(post) db.flush() request.session.flash( "post {name} deleted!".format(name=post.name)) except HTTPNotFound as exp: return exp except IntegrityError: return HTTPNotAcceptable( detail="Cannot delete post as it has dependent records\n") categories = Category.get_tree() posts = db.query(Post).order_by(Post.updated.desc()) return { 'APP_BASE': APP_BASE, 'APP_NAME': APP_NAME, 'posts': posts, 'categories': categories, 'action': action, 'post': post }