def sign_app(request): if request.registry.settings['trunion.we_are_signing'] != 'apps': raise HTTPUnsupportedMediaType() fname = os.path.splitext(request.POST['file'].filename)[0] pkcs7 = crypto.sign_app(request.POST['file'].file.read()) return {fname + '.rsa': b64encode(pkcs7)}
def _get_request_representer(self): try: mime_type = \ get_registered_mime_type_for_string(self.request.content_type) except KeyError: # The client requested a content type we do not support (415). raise HTTPUnsupportedMediaType() return as_representer(self.context, mime_type)
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 415 error context = HTTPUnsupportedMediaType("Unsupported media type") response = wrapped(context, request) return response
def parse_content(request=None, # type: Optional[AnyRequestType] content=None, # type: Optional[Union[JSON, str]] content_schema=None, # type: Optional[colander.SchemaNode] content_type=sd.RequestContentTypeHeader.default, # type: Optional[ContentType] content_type_schema=sd.RequestContentTypeHeader, # type: Optional[colander.SchemaNode] ): # type: (...) -> Union[JSON, CWL] """ Load the request content with validation of expected content type and their schema. """ if request is None and content is None: # pragma: no cover # safeguard for early detect invalid implementation raise HTTPInternalServerError(json={ "title": "Internal Server Error", "type": "InternalServerError", "detail": "Cannot parse undefined contents.", "status": HTTPInternalServerError.code, "cause": "Request content and content argument are undefined.", }) try: if request is not None: content = request.text content_type = request.content_type if content_type is not None and content_type_schema is not None: content_type = content_type_schema().deserialize(content_type) if isinstance(content, str): content = yaml.safe_load(content) if not isinstance(content, dict): raise TypeError("Not a valid JSON body for process deployment.") except colander.Invalid as exc: raise HTTPUnsupportedMediaType(json={ "title": "Unsupported Media Type", "type": "UnsupportedMediaType", "detail": str(exc), "status": HTTPUnsupportedMediaType.code, "cause": {"Content-Type": None if content_type is None else str(content_type)}, }) except Exception as exc: raise HTTPBadRequest(json={ "title": "Bad Request", "type": "BadRequest", "detail": "Unable to parse contents.", "status": HTTPBadRequest.code, "cause": str(exc), }) try: if content_schema is not None: content = content_schema().deserialize(content) except colander.Invalid as exc: raise HTTPUnprocessableEntity(json={ "type": "InvalidParameterValue", "title": "Failed schema validation.", "status": HTTPUnprocessableEntity.code, "error": colander.Invalid.__name__, "cause": exc.msg, "value": repr_json(exc.value, force_string=False), }) return content
def insert_oil(request): logger.info('POST /oils') try: json_obj = ujson.loads(request.body) if not isinstance(json_obj, dict): raise ValueError('JSON dict is the only acceptable payload') except Exception as e: logger.error(e) raise HTTPBadRequest("Error parsing oil JSON") try: oil_obj = get_oil_from_json_req(json_obj) except Exception as e: logger.error(f'Validation Error: {e}') raise HTTPBadRequest("Error validating oil JSON") try: logger.info('oil.name: {}'.format(oil_obj['metadata']['name'])) if 'oil_id' not in oil_obj: oil_obj['oil_id'] = request.adb_session.new_oil_id() try: oil = validate_json(oil_obj) set_completeness(oil) except Exception as e: log_traceback(e, oil_obj) raise if is_temp_id(oil.oil_id): logger.info(f"Temporary oil with ID: {oil.oil_id}, " "persisting in memory, not the database.") oil_json = oil.py_json() oil_json['_id'] = oil.oil_id temp_oils[oil.oil_id] = oil_json else: logger.info('permanent ID...') mongo_id = request.adb_session.insert_one(oil) logger.info(f'Insert oil with mongo ID: {mongo_id}, ' f'oil ID: {oil.oil_id}') except DuplicateKeyError as e: logger.error(e) raise HTTPConflict('Insert failed: Duplicate Key') except Exception as e: logger.error(e) raise HTTPUnsupportedMediaType("Unknown Error") return generate_jsonapi_response_from_oil(oil.py_json())
def _get_request_representer(self): """ Returns a representer for the content type specified in the request. :raises HTTPUnsupportedMediaType: If the specified content type is not supported. """ try: mime_type = \ get_registered_mime_type_for_string(self.request.content_type) except KeyError: # The client sent a content type we do not support (415). raise HTTPUnsupportedMediaType() return as_representer(self.context, mime_type)
def get_object(request, implemented_types): '''Returns a Gnome object in JSON.''' obj_id = obj_id_from_url(request) if not obj_id: return get_specifications(request, implemented_types) else: obj = get_session_object(obj_id, request.session) if obj: if ObjectImplementsOneOf(obj, implemented_types): return obj.serialize() else: raise HTTPUnsupportedMediaType() else: raise HTTPNotFound()
def check_content_type(self, data, **_): """ Check the request has content type 'application/json'. :raise HTTPUnsupportedMediaType: If the content type is wrong """ content_type = self.context["request"].content_type if content_type != "application/json": raise HTTPUnsupportedMediaType( f"Unexpected content type. Expected 'application/json' but found '{content_type}'", ) return data
def put_key(request): """Uploads new key-retrieval information.""" # Validate that the request is text/<something> if request.content_type: if not request.content_type.startswith("text/"): raise HTTPUnsupportedMediaType() # Validate that the request is not too big if request.content_length is None: raise HTTPLengthRequired() if request.content_length > 8 * 1024: raise HTTPRequestEntityTooLarge() # Store the uploaded data. username = request.matchdict["username"] store = request.registry.getUtility(IKeyRetrievalStorage) store.set(username, request.body) return Response(status=204)
def deserialize_request_body(self, request): content_type = request.content_type deserialized = None request.response.headers.extend(self.accept_headers) if content_type in self.deserializers: try: deserialized = self.deserializers[content_type](request) except HTTPException as http_exc: http_exc.headers.extend(self.accept_headers) raise else: raise HTTPUnsupportedMediaType(content_type, headers=self.accept_headers) return deserialized
def security_tween(request): login = None expected_user = request.headers.get('X-If-Match-User') if expected_user is not None: login = request.authenticated_userid if login != 'mailto.' + expected_user: detail = 'X-If-Match-User does not match' raise HTTPPreconditionFailed(detail) # wget may only send credentials following a challenge response. auth_challenge = asbool(request.headers.get('X-Auth-Challenge', False)) if auth_challenge or request.authorization is not None: login = request.authenticated_userid if login is None: raise HTTPUnauthorized(headerlist=forget(request)) if request.method in ('GET', 'HEAD'): return handler(request) if request.content_type != 'application/json': detail = "%s is not 'application/json'" % request.content_type raise HTTPUnsupportedMediaType(detail) token = request.headers.get('X-CSRF-Token') if token is not None: # Avoid dirtying the session and adding a Set-Cookie header # XXX Should consider if this is a good idea or not and timeouts if token == dict.get(request.session, '_csrft_', None): return handler(request) raise CSRFTokenError('Incorrect CSRF token') # NOTE: cutting out CSRF protection here ... why protect against CSRF if you provide an # unathenticated endpoint that will delivery the CSRF token? I'm looking at you /session. # this should be revisted, either embed the csrf token in the index.html as part of the # rendering subprocess somehow, or return it from the login view and let the client store it # but of course that sounds a lot like JWT... return handler(request) if login is None: login = request.authenticated_userid if login is not None: namespace, userid = login.split('.', 1) if namespace not in ('mailto', 'persona'): return handler(request) raise CSRFTokenError('Missing CSRF token')
def create_or_update_object(request, implemented_types): '''Creates or Updates a Gnome object.''' json_request = json.loads(request.body) if not JSONImplementsOneOf(json_request, implemented_types): raise HTTPNotImplemented() obj = get_session_object(obj_id_from_url(request), request.session) if obj: try: UpdateObject(obj, json_request) except ValueError as e: # TODO: We might want to log this message somewhere, as the # response is a bit vague raise HTTPUnsupportedMediaType(e) else: obj = CreateObject(json_request, request.session['objects']) set_session_object(obj, request.session) return obj.serialize()
def security_tween(request): login = None expected_user = request.headers.get('X-If-Match-User') if expected_user is not None: login = request.authenticated_userid if login != 'mailto.' + expected_user: detail = 'X-If-Match-User does not match' raise HTTPPreconditionFailed(detail) # wget may only send credentials following a challenge response. auth_challenge = asbool(request.headers.get('X-Auth-Challenge', False)) if auth_challenge or request.authorization is not None: login = request.authenticated_userid if login is None: raise HTTPUnauthorized(headerlist=forget(request)) if request.method in ('GET', 'HEAD'): return handler(request) if request.content_type != 'application/json': detail = "%s is not 'application/json'" % request.content_type raise HTTPUnsupportedMediaType(detail) token = request.headers.get('X-CSRF-Token') if token is not None: # Avoid dirtying the session and adding a Set-Cookie header # XXX Should consider if this is a good idea or not and timeouts if token == dict.get(request.session, '_csrft_', None): return handler(request) raise CSRFTokenError('Incorrect CSRF token') if login is None: login = request.authenticated_userid if login is not None: namespace, userid = login.split('.', 1) if namespace not in ('mailto', 'persona'): return handler(request) raise CSRFTokenError('Missing CSRF token')
def update_oil(request): # ember JSON serializer PUTs the id of the object in the URL obj_id = obj_id_from_url(request) logger.info('PUT /oils: id: {}'.format(obj_id)) try: json_obj = ujson.loads(request.body) if not isinstance(json_obj, dict): raise ValueError('JSON dict is the only acceptable payload') except Exception: raise HTTPBadRequest('Could not parse oil JSON') try: oil_obj = get_oil_from_json_req(json_obj) try: oil = validate_json(oil_obj) set_completeness(oil) except Exception as e: log_traceback(e, oil_obj) raise if is_temp_id(oil.oil_id): logger.info(f"Temporary oil with ID: {oil.oil_id}, " "update it in memory, not the database.") temp_oils[oil.oil_id] = oil.py_json() else: request.adb_session.replace_one(oil) memoized_results.pop(oil.oil_id, None) logger.info(f'Update oil with ID: {oil.oil_id}') except Exception as e: logger.error(e) raise HTTPUnsupportedMediaType() return generate_jsonapi_response_from_oil(oil.py_json())
def set_item(self, request): """Upload a new item by ID.""" # Validate the incoming data. if request.content_type not in ("application/json", None): msg = "Unsupported Media Type: %s" % (request.content_type, ) raise HTTPUnsupportedMediaType(msg) if len(request.body) > MAX_ITEM_SIZE: raise HTTPRequestEntityTooLarge() try: data = json.loads(request.body) except ValueError: raise HTTPJsonBadRequest(ERROR_MALFORMED_JSON) item = self._parse_item(request, data) # Check that we're putting it with the right id. # Unfortunately we have to *return* the error response here # rather than raise it, because raising HTTPForbidden will # trigger pyramid's prompt-for-credentials handlers. if request.matchdict["item"] != item.get_id(): return HTTPForbidden("Item ID does not match origin") # Pass through to storage. # Requires another round-trip through JSON; yuck. request.body = json.dumps({"payload": json.dumps(item)}) return self.controller.set_item(request)