Exemple #1
0
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)}
Exemple #2
0
 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
Exemple #4
0
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())
Exemple #6
0
    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)
Exemple #7
0
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()
Exemple #8
0
    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
Exemple #11
0
    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')
Exemple #12
0
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()
Exemple #13
0
    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())
Exemple #15
0
 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)