Ejemplo n.º 1
0
    def dispatch_request(self, request):
        adapter = self.urls.bind_to_environ(request.environ)
        try:
            endpoint, values = adapter.match()
            cors_enabled = endpoint in self.cors_endpoints
            if not request.method in self.methods[endpoint]:

                if not cors_is_valid(request, self.methods):
                    raise E.MethodNotAllowed()

            resp = self.endpoints[endpoint](request, *(), **values)

            if cors_enabled:
                origin_present = "Access-Control-Allow-Origin" in resp.headers
                headers_present = "Access-Control-Allow-Headers" in resp.headers
                if not origin_present:
                    resp.headers["Access-Control-Allow-Origin"] = "*"
                if not headers_present:
                    resp.headers[
                        "Access-Control-Allow-Headers"] = "Content-Type, Accept"

            return resp
        except E.HTTPException as e:
            return Response(status=e.code,
                            response=e.get_body(),
                            mimetype="application/xml",
                            content_type="application/xml")
Ejemplo n.º 2
0
def patch_node(node_id):
    # Parse the request
    node_id = str2id(node_id)
    patch = request.get_json()

    # Find the node type.
    node = mongo.find_one_or_404('nodes', node_id, projection={'node_type': 1})
    try:
        node_type = node['node_type']
    except KeyError:
        msg = 'Node %s has no node_type property' % node_id
        log.warning(msg)
        raise wz_exceptions.InternalServerError(msg)
    log.debug('User %s wants to PATCH %s node %s',
              authentication.current_user_id(), node_type, node_id)

    # Find the PATCH handler for the node type.
    try:
        patch_handler = custom.patch_handlers[node_type]
    except KeyError:
        log.info('No patch handler for node type %r', node_type)
        raise wz_exceptions.MethodNotAllowed(
            'PATCH on node type %r not allowed' % node_type)

    # Let the PATCH handler do its thing.
    return patch_handler(node_id, patch)
Ejemplo n.º 3
0
 def test_special_exceptions(self):
     exc = exceptions.MethodNotAllowed(['GET', 'HEAD', 'POST'])
     h = dict(exc.get_headers({}))
     self.assert_equal(h['Allow'], 'GET, HEAD, POST')
     self.assert_('The method DELETE is not allowed' in exc.get_description({
         'REQUEST_METHOD': 'DELETE'
     }))
Ejemplo n.º 4
0
def test_special_exceptions():
    """Special HTTP exceptions"""
    exc = exceptions.MethodNotAllowed(['GET', 'HEAD', 'POST'])
    h = dict(exc.get_headers({}))
    assert h['Allow'] == 'GET, HEAD, POST'
    assert 'The method DELETE is not allowed' in exc.get_description({
        'REQUEST_METHOD': 'DELETE'
    })
Ejemplo n.º 5
0
    def dispatch_request(self, *args, **kwargs):
        method = request.method.lower()

        if method == 'get':
            if self.pk in kwargs and kwargs[self.pk] is not None:
                return self.get(*args, **kwargs)

        raise exceptions.MethodNotAllowed()
Ejemplo n.º 6
0
 def entrypoint(self, *args, **kwargs):
     allowed_methods = self.get_allowed_methods()
     try:
         method = allowed_methods[self.request.method]
     except KeyError:
         valid_methods = list(allowed_methods.keys())
         raise exceptions.MethodNotAllowed(valid_methods)
     return method(*args, **kwargs)
Ejemplo n.º 7
0
    def _validate_readonly_access(obj):
        """Return 405 MethodNotAllowed if object is marked as read-only"""
        if not isinstance(obj, WithReadOnlyAccess):
            return

        if obj.readonly:
            raise exceptions.MethodNotAllowed(
                "The object is in a read-only mode and is dedicated for SOX needs"
            )
Ejemplo n.º 8
0
    def __init__(self, limit):
        self.limit = limit

        # Set defaults
        self.code = 429
        self.body = self.get_body()
        self.headers = self.get_headers()

        # Get the description
        if limit.error_message:
            self.description = limit.error_message if not callable(
                limit.error_message) else limit.error_message()
        else:
            self.description = text_type(limit.limit)

        # If error is given, get body & headers
        if self.limit.error_code:
            self.code = limit.error_code
            exception = exceptions.HTTPException(description=self.description)

            # Some common error codes, can add more here
            if self.code == 400:
                exception = exceptions.BadRequest()
            elif self.code == 401:
                exception = exceptions.Unauthorized()
            elif self.code == 403:
                exception = exceptions.Forbidden()
            elif self.code == 404:
                exception = exceptions.NotFound()
            elif self.code == 405:
                exception = exceptions.MethodNotAllowed()
            elif self.code == 406:
                exception = exceptions.NotAcceptable()
            elif self.code == 418:
                exception = exceptions.ImATeapot()  # <3
            elif self.code == 500:
                exception = exceptions.InternalServerError()
            elif self.code == 501:
                exception = exceptions.NotImplemented()

            # Update body & headers
            self.body = exception.get_body()
            self.headers = exception.get_headers()
        else:
            exception = exceptions.TooManyRequests(
                description=self.description)

            # Update body & headers
            self.body = exception.get_body()
            self.headers = exception.get_headers()
        super(RateLimitExceeded,
              self).__init__(description=self.description,
                             response=Response(self.body, self.code,
                                               self.headers))
Ejemplo n.º 9
0
    def dispatch_request(self):
        # type: () -> Response
        """Method that handles request verification and routing.

        This method can be used as a function to register on the URL
        rule. The request is verified through the registered list of
        verifiers, before invoking the request handlers. The method
        returns a JSON response for the Alexa service to respond to the
        request.

        :return: The skill response for the input request
        :rtype: flask.Response
        :raises: :py:class:`werkzeug.exceptions.MethodNotAllowed` if the
            method is invoked for other than HTTP POST request.
            :py:class:`werkzeug.exceptions.BadRequest` if the
            verification fails.
            :py:class:`werkzeug.exceptions.InternalServerError` for any
            internal exception.
        """
        if flask_request.method != "POST":
            raise exceptions.MethodNotAllowed()

        if self._webservice_handler is None:
            raise AskSdkException("app not configured with skill handlers")

        try:
            content = flask_request.data.decode(
                verifier_constants.CHARACTER_ENCODING)
            response = self._webservice_handler.verify_request_and_dispatch(
                http_request_headers=typing.cast(typing.Dict[str, typing.Any],
                                                 flask_request.headers),
                http_request_body=content)

            return jsonify(response)
        except VerificationException:
            current_app.logger.error("Request verification failed",
                                     exc_info=True)
            raise exceptions.BadRequest(
                description="Incoming request failed verification")
        except AskSdkException:
            current_app.logger.error("Skill dispatch exception", exc_info=True)
            raise exceptions.InternalServerError(
                description="Exception occurred during skill dispatch")
Ejemplo n.º 10
0
def validate_object_type_ggrcq(mapper, content, target):
  """Validate object_type actions for GGRCQ."""
  from ggrc import login as login_module
  from ggrc.models import get_model
  from ggrc.models.mixins import synchronizable

  model = get_model(target.object_type)
  user = login_module.get_current_user(False)

  if not user or user.is_anonymous():
    return

  should_prevent = all([
      issubclass(model, synchronizable.Synchronizable),
      not login_module.is_external_app_user()
  ])

  if should_prevent:
    raise exceptions.MethodNotAllowed()
Ejemplo n.º 11
0
def validate_definition_type_ecad(mapper, content, target):
  """Validate actions for eCAD object with definition_type."""
  from ggrc import login as login_module
  from ggrc.models import get_model
  del mapper, content

  model = get_model(target.definition_type)
  user = login_module.get_current_user(False)

  if not user or user.is_anonymous():
    return

  should_prevent = (
      not login_module.is_external_app_user() or
      issubclass(model, mixins.CustomAttributable)
  )

  if should_prevent:
    raise exceptions.MethodNotAllowed()
Ejemplo n.º 12
0
    def on_proxy(self, request, user_token, url):
        proxy_tile = self.proxy_url_and_coords(url)
        if not proxy_tile:
            raise exceptions.BadRequest('unknown proxy url')

        if request.method not in ('GET', 'HEAD'):
            raise exceptions.MethodNotAllowed(valid_methods=['GET', 'HEAD'])

        try:
            if not self.tile_coverages.is_permitted(user_token, proxy_tile.layer, proxy_tile.tile_coord):
                raise exceptions.Forbidden()

        except InvalidUserToken:
            raise exceptions.Unauthorized()

        headers = end_to_end_headers(request.headers)

        try:
            resp = requests.request(request.method, proxy_tile.url, headers=headers, stream=True)
        except requests.exceptions.RequestException, ex:
            raise exceptions.BadGateway('source returned: %s' % ex)
Ejemplo n.º 13
0
def test_method_not_allowed_methods():
    exc = exceptions.MethodNotAllowed(["GET", "HEAD", "POST"])
    h = dict(exc.get_headers({}))
    assert h["Allow"] == "GET, HEAD, POST"
    assert "The method is not allowed" in exc.get_description()
Ejemplo n.º 14
0
def test_basic_errors():

    assert UseCaseError(CustomUseCaseError()).to_dict() == {
        TITLE_KEY: 'Custom Use Case Error',
        STATUS_KEY: 'Bad Request',
        CODE_KEY: 'use-case-error',
        DETAIL_KEY: CustomUseCaseError.detail,
        SOURCE_KEY: CustomUseCaseError.source
    }

    assert ValidationError(**ERROR_KWARGS).to_dict() == {
        STATUS_KEY: 'Bad Request',
        CODE_KEY: 'validation-error',
        TITLE_KEY: 'Validation Error',
        **ERROR_KWARGS
    }

    assert MissingAttributesError(['1', '2', '3']).to_dict() == {
        TITLE_KEY: 'Missing Attributes Error',
        CODE_KEY: 'missing-attributes-error',
        STATUS_KEY: 'Bad Request',
        DETAIL_KEY: "Missing required attributes: ['1', '2', '3'].",
        SOURCE_KEY: ['1', '2', '3']
    }

    assert InternalServerError(Exception('Test')).to_dict() == {
        STATUS_KEY: 'Internal Server Error',
        CODE_KEY: 'internal-server-error',
        TITLE_KEY: 'Internal Server Error',
        SOURCE_KEY: [{
            'type': Exception.__name__,
            'str': str(Exception('Test'))
        }],
        DETAIL_KEY: 'Unexpected server error occured.'
    }

    # testing generation of required fields using werkzeug.exceptions
    # used for error handler generic http excetions formatting
    assert GenericHTTPError(exceptions.MethodNotAllowed()).to_dict() == {
        STATUS_KEY: 'Method Not Allowed',
        CODE_KEY: 'generic-http-error',
        TITLE_KEY: 'Method Not Allowed'
    }

    # testing equality between 3 different creation methods
    assert GenericHTTPError(
        exceptions.NotFound()).to_dict() == GenericHTTPError(404).to_dict()
    assert GenericHTTPError(
        exceptions.NotFound()).to_dict() == GenericHTTPError(
            StatusCode.NOT_FOUND).to_dict()
    # testing exception cases
    with pytest.raises(ValueError) as e:
        GenericHTTPError(0)
        assert str(
            e
        ) == 'Non generic HTTP exception. Can\'t find class for status: "0"'
    with pytest.raises(TypeError) as e:
        GenericHTTPError("Not Found")
        assert str(e) == (
            'GenericHTTPError "exception" kwarg must be the instance of:' +
            "['werkzeug.exceptions.HTTPException', 'http.HTTPStatus', 'int']")
    # testing extension of standard errors
    not_found_extended_dict = GenericHTTPError(exceptions.NotFound(),
                                               detail='Something',
                                               source=['Something']).to_dict()

    assert not_found_extended_dict == {
        STATUS_KEY: 'Not Found',
        CODE_KEY: 'generic-http-error',
        TITLE_KEY: 'Not Found',
        DETAIL_KEY: 'Something',
        SOURCE_KEY: ['Something']
    }
    # this way of creation is my favorite
    assert not_found_extended_dict == GenericHTTPError(StatusCode.NOT_FOUND,
                                                       detail='Something',
                                                       source=['Something'
                                                               ]).to_dict()
    # this one is ok, but it's always better to use constants
    assert not_found_extended_dict == GenericHTTPError(404,
                                                       detail='Something',
                                                       source=['Something'
                                                               ]).to_dict()

    # using enum item object
    assert not_found_extended_dict == GenericHTTPError(StatusCode(404),
                                                       detail='Something',
                                                       source=['Something'
                                                               ]).to_dict()

    with pytest.raises(ValueError) as e:
        ErrorsList(Exception('Hello'), GenericHTTPError(404))
    assert str(e.value) == 'All errors should be the instance of BaseError'
Ejemplo n.º 15
0
    def patch(self, **kwargs):
        self._audit_before()

        raise http_exception.MethodNotAllowed(description='Unable to update/replace every resource in the entire collection')
Ejemplo n.º 16
0
 def get(self):
     # GET is not allowed, however flask restful doesn't handle "GET" not
     # being allowed cleanly. Here we explicitly mark is as not allowed. All
     # other methods not defined would raise a method NotAllowed error and
     # this would not be needed.
     raise exceptions.MethodNotAllowed(valid_methods=['POST'])
Ejemplo n.º 17
0
def test_special_exceptions():
    exc = exceptions.MethodNotAllowed(['GET', 'HEAD', 'POST'])
    h = dict(exc.get_headers({}))
    assert h['Allow'] == 'GET, HEAD, POST'
    assert 'The method is not allowed' in exc.get_description()
Ejemplo n.º 18
0
 def get(self):
     # SPECIAL CASE: GET is not allowed, raise METHOD_NOT_ALLOWED
     raise exceptions.MethodNotAllowed(valid_methods=['POST'])
Ejemplo n.º 19
0
 def get(self, user_id):
     # Special case, GET is not allowed.
     raise exceptions.MethodNotAllowed(valid_methods=['POST'])
Ejemplo n.º 20
0
def raise_method_is_not_allowed(*args, **kwargs):
  """Raise MethodNotAllowed exception for use with sa.event.listen"""
  del args, kwargs
  raise exceptions.MethodNotAllowed()
Ejemplo n.º 21
0
    def delete(self, **kwargs):
        self._audit_before()

        return http_exception.MethodNotAllowed(description='Unable to delete the whole collection')
Ejemplo n.º 22
0
 def test_special_exceptions(self):
     exc = exceptions.MethodNotAllowed(['GET', 'HEAD', 'POST'])
     h = dict(exc.get_headers({}))
     self.assert_equal(h['Allow'], 'GET, HEAD, POST')
     self.assert_true('The method is not allowed' in exc.get_description())
Ejemplo n.º 23
0
  def call(self, path=None, query=None, data=None, method='GET'):
    # this avoids the request being sent as a GET when there is no data..
    if method == 'POST' and (data is None or len(data) < 1):
      data = '{}'
    result = '{}'
    status = 200
    request = Request(self._url(self.app.base_url + path, query),
      data=data, headers={
        'Content-Type': 'application/json',
        'Authorization': 'bearer ' + self.access_token})
    rate_limit = 0
    rate_limit_remaining = 0
    user_scopes = []
    accepted_scopes = []
    try:
      response = urlopen(request)
      result = response.read()
      response.close()
      status = response.code
      # parse info from github api response headers..
      rate_limit = int(response.headers.dict.get(
        'x-ratelimit-limit', 0))
      rate_limit_remaining = int(response.headers.dict.get(
        'x-ratelimit-remaining', 0))
      user_scopes = response.headers.dict.get(
        'x-oauth-scopes', '').split(',')
      accepted_scopes = response.headers.dict.get(
        'x-accepted-oauth-scopes', '').split(',')
      print 'rate_limit: %s' % (rate_limit)
      print 'rate_limit_remaining: %s' % (rate_limit_remaining)
      print 'user_scopes: %s' % (user_scopes)
      print 'accepted_scopes: %s' % (accepted_scopes)
    except:
      import traceback
      print 'HttpError: %s' % traceback.format_exc()

    # response = self.app.request(self._url(path, query),
    #   method=method, data=data, content_type='application/json',
    #   headers={
    #     'Accept': 'application/json',
    #     'Authorization': self.access_token},
    #   token=self.access_token)
    # result = dumps({'response': response.data})
    # todo: i need a root node.. i don't knot if i can serialize anonymous
    # root lists.. so i'm serializing, adding root node, then encoding back
    # to a json str.. sorry for the waste.
    # status = response.status

    if status == 401:
      raise exceptions.Unauthorized('''Error with Github api request:
        401, user is not authorized: %s.''' % result)
    elif status == 403:
      raise exceptions.MethodNotAllowed('''Error with Github api request:
        403, user is authenticated, but doesn't have permissions.''')
    elif status == 404:
      raise exceptions.NotFound('''Error with Github api request:
        404, data not found: %s''' % result)
    elif status > 299:
      raise exceptions.BadRequest(
        'Error with github api request: %s, %s' % (status, result))
    return '{"response": ' + result + '}'