def __call__(self, req, resp): """ the router for all requests. Everything comes through here. Based on the method, we route requests to the appropriate handler. :param req: falcon.Request :param resp: falcon.Response :return: None """ method = req.method if method == 'GET': return self.on_get(req, resp) elif method == 'HEAD': return self.on_head(req, resp) elif method == 'PATCH': return self.on_patch(req, resp) elif method == 'DELETE': return self.on_delete(req, resp) elif method == 'PUT': return self.on_post(req, resp) elif method == 'POST': return self.on_post(req, resp) else: raise falcon.HTTPMethodNotAllowed( allowed_methods=self.allowed_methods)
def on_post(self, request, response, **kwargs): if kwargs and hasattr(self, 'update'): return self.update(request, response, **kwargs) elif not kwargs and hasattr(self, 'create'): return self.create(request, response) raise falcon.HTTPMethodNotAllowed(self.get_allowed_methods(**kwargs))
def on_get(self, request, resp): """ direct user to POST the login details """ allowed = self.allowed_methods msg = "GET method not allowed, Please POST credentials to 'login'" raise falcon.HTTPMethodNotAllowed(allowed, description=msg)
def process_resource(self, request, response, resource, params): # pylint: disable=unused-argument bravado_request = _BravadoRequest(request, params) get_op = functools.partial( self._spec.get_op_for_request, path_pattern=request.uri_template, ) operation = get_op(request.method) if not operation: # The URI exists but the method is wrong. # So we are going to reply with an error 405. # Error 405 requires we provide the list of allowed methods # for this URI. If None is found, then we produce a 404 error. allowed = [m for m in falcon.HTTP_METHODS if get_op(m)] if allowed: raise falcon.HTTPMethodNotAllowed(allowed) raise falcon.HTTPNotFound try: validated = unmarshal_request(bravado_request, operation) except ValidationError as e: raise _HTTPBadRequest(e) else: body = validated.pop('body', None) if body: validated.update(body) params.clear() params.update(validated)
def on_get(self, request, response, **kwargs): if kwargs and hasattr(self, 'retrieve'): return self.retrieve(request, response, **kwargs) elif not kwargs and hasattr(self, 'list'): return self.list(request, response) raise falcon.HTTPMethodNotAllowed(self.get_allowed_methods(**kwargs))
def on_patch(self, req, resp, **params): """Overwrites BaseResource.on_patch to disable it. """ raise falcon.HTTPMethodNotAllowed( ('POST', 'GET', 'DELETE'), description=f'{req.method} method is not allowed for {self.resource_name} resources.' )
def __call__(self, req, resp): path = self.base_url + '/v0/' + '/'.join(req.path.split('/')[4:]) if req.query_string: path += '?%s' % req.query_string try: if req.method == 'POST': body = b'' if req.context['body']: body = req.context['body'] result = self.iris_client.post(path, body) elif req.method == 'GET': result = self.iris_client.get(path) elif req.method == 'OPTIONS': return else: raise falcon.HTTPMethodNotAllowed( ['GET', 'POST', 'PUT', 'DELETE']) except MaxRetryError as e: logger.error(e.reason) raise falcon.HTTPInternalServerError( 'Internal Server Error', 'Max retry error, api unavailable') if result.status_code == 400: raise falcon.HTTPBadRequest('Bad Request', '') elif str(result.status_code)[0] != '2': raise falcon.HTTPInternalServerError( 'Internal Server Error', 'Unknown response from the api') else: resp.status = falcon.HTTP_200 resp.content_type = result.headers['Content-Type'] resp.body = result.content
def scan_or_raise(self, uri, http_method): if uri: path = self._data_root / uri else: path = self._data_root debug_log.debug('PATH: %s', path) file_name = http_method + '.json' debug_log.debug('FILE_NAME: %s', file_name) if not path.exists(): raise falcon.HTTPNotFound() file_path = path / file_name debug_log.debug('FILE_PATH: %s', file_path) if not file_path.is_file(): file_list = [] for file in file_path.parent.glob('*.json'): file = str(file.parts[-1]).rstrip('.json') file_list.append(file) if len(file_list) > 0: raise falcon.HTTPMethodNotAllowed(file_list) else: raise falcon.HTTPNotFound() with file_path.open() as f: data = json.load(f) return data
def dispatch(self, method, req, resp, **kwargs): self.authenticate(method, req, resp, **kwargs) mapped_method = self.reverse_method_map[method] assert mapped_method in ('list', 'retrieve', 'update', 'create', 'destroy') if mapped_method not in self.allowed_actions: raise falcon.HTTPMethodNotAllowed( allowed_methods=self.get_allowed_methods(req, **kwargs)) #: update methods, make sure we can retrieve an object from the url if method in ('retrieve', 'update', 'destroy'): if self.obj_lookup_kwarg not in kwargs: raise falcon.HTTPBadRequest( title=_('Lookup ID not found'), description=_('{obj_lookup_kwarg} not passed for lookup'). format(obj_lookup_kwarg=self.obj_lookup_kwarg)) self.check_permissions(req, **kwargs) if mapped_method == 'list' and self.obj_lookup_kwarg in kwargs: mapped_method = 'retrieve' if not hasattr(self, mapped_method): raise falcon.HttpBadReqeust( title=_('Operation not supported'), description=_( 'The operation {operation} is not supported ' 'at this endpoint.').format(operation=mapped_method)) getattr(self, mapped_method)(req, resp, **kwargs) resp.body = self.render(method, req, resp, resp.body, **kwargs)
def __call__(self, req, resp): path = '/'.join(req.path.split('/')[4:]) if req.query_string: path += '?%s' % req.query_string try: if req.method == 'POST': body = '' if req.context['body']: body = ujson.loads(req.context['body']) result = self.mobile_client.post(path, body) elif req.method == 'GET': result = self.mobile_client.get(path) else: raise falcon.HTTPMethodNotAllowed() except MaxRetryError as e: logger.error(e.reason) raise falcon.HTTPInternalServerError( 'Internal Server Error', 'Max retry error, api unavailable') if result.status == 400: raise falcon.HTTPBadRequest('Bad Request', '') elif str(result.status)[0] != '2': raise falcon.HTTPInternalServerError( 'Internal Server Error', 'Unknown response from the api') else: resp.status = falcon.HTTP_200 resp.content_type = result.headers['Content-Type'] resp.body = result.data
def process_resource(self, req, resp, resource, params): if not isinstance(resource, self.resource): return allowed_methods = ['POST'] if req.method not in allowed_methods: raise falcon.HTTPMethodNotAllowed(allowed_methods) # TODO: Validate application ID if intended for this service. if self.validate: body = req.context.get('doc') or util._get_json_body(req) valid_cert = self.validate_request_certificate(req, body) valid_ts = self.validate_request_timestamp(body) if not valid_cert or not valid_ts: logger.error('Failed to validate request.') raise falcon.HTTPForbidden() welcome = getattr(resource, 'welcome', None) req.context['welcome'] = welcome intent_maps = getattr(resource, 'intent_maps', None) if intent_maps is None: logger.error('Missing attribute "intent_maps" in resource.') raise falcon.HTTPInternalServerError() req.context['intent_maps'] = intent_maps
def on_patch(self, req, resp, id=None): """Handle PATCH """ if id is None: raise falcon.HTTPMethodNotAllowed(('GET', 'POST')) todo = self._db.get(eid=int(id)) if todo is None: raise falcon.HTTPNotFound() body = json.loads(req.stream.read()) if not body: raise falcon.HTTPBadRequest( 'Missing parameters', 'Parameters must include `title` or `completed`') title = body.get('title', self._db.get(eid=int(id))['title']) completed = body.get('completed', self._db.get(eid=int(id))['completed']) order = body.get('order', self._db.get(eid=int(id))['order']) eid = self._db.update( { 'title': title, 'completed': completed, 'order': order }, eids=[int(id)]) resp.body = self._make_todo(self._db.get(eid=eid[0]))
def __getattr__(self, key): if key in self.methods: return self._call_func elif key in ('post', 'put', 'patch', 'delete', 'get'): raise falcon.HTTPMethodNotAllowed( [m.upper() for m in self.methods]) raise AttributeError(key)
def _validate_method(self, req, **kwargs): if req.method.upper() not in self.allowed_methods: raise falcon.HTTPMethodNotAllowed( allowed_methods=self.allowed_methods, headers=header, title="method error", description="method not allowed", code=405)
def generic_error_handler(ex, req, resp, params): if isinstance(ex, falcon.HTTPNotFound): raise falcon.HTTPNotFound(description='Not Found') elif isinstance(ex, falcon.HTTPMethodNotAllowed): raise falcon.HTTPMethodNotAllowed(falcon.HTTP_405, description='Method Not Allowed') else: raise
def on_delete(self, req, resp, session): if not self.is_dev_environment: raise falcon.HTTPMethodNotAllowed() self.user_repo.delete_all() self.sound_repo.delete_all() self.annotation_repo.delete_all() resp.status = falcon.HTTP_NO_CONTENT
def test_405_without_body_with_extra_headers(self, client): client.app.add_route('/405', MethodNotAllowedResourceWithHeaders()) response = client.simulate_request(path='/405') assert response.status == falcon.HTTP_405 assert response.content == falcon.HTTPMethodNotAllowed([]).to_json() assert response.headers['allow'] == 'PUT' assert response.headers['x-ping'] == 'pong'
def test_405_without_body(self, client): client.app.add_route('/405', MethodNotAllowedResource()) response = client.simulate_request(path='/405') assert response.status == falcon.HTTP_405 assert response.content == falcon.HTTPMethodNotAllowed(['PUT']).to_json() assert response.json == {'title': falcon.HTTP_METHOD_NOT_ALLOWED} assert response.headers['allow'] == 'PUT'
def test_405_without_body_with_extra_headers_double_check(self, client): client.app.add_route('/405', MethodNotAllowedResourceWithHeadersWithAccept()) response = client.simulate_request(path='/405') assert response.status == falcon.HTTP_405 assert response.json == falcon.HTTPMethodNotAllowed([]).to_dict() assert response.headers['allow'] == 'PUT' assert response.headers['allow'] != 'GET,PUT' assert response.headers['allow'] != 'GET' assert response.headers['x-ping'] == 'pong'
def on_get(self, request, resp, **kwargs): """ direct user to POST the login details """ session_user = auth.get_user_id(request) with warehouse.get_source_model_session() as dwsupport_model: if not management_auth.is_management_permitted(session_user, dwsupport_model): msg = 'Warehouse management not authorized' raise falcon.HTTPUnauthorized(title='401', description=msg) allowed = self.allowed_methods msg = "GET method not allowed, Please POST new table parameters to 'copy'" raise falcon.HTTPMethodNotAllowed(allowed, description = msg)
def on_patch(self, req: falcon.Request, res: falcon.Response): # todo: use salted password if self.auth_error: raise self.auth_error nickname = req.get_param('nickname') if not nickname: raise falcon.HTTPMethodNotAllowed(ERROR_INVALID_REQUEST) if self.user and self.user['nickname'] == nickname: result = r.db(DB_NAME).table(DB_TABLE_USERS).update( self.data).run(conn) res.body = json.dumps(result) else: raise falcon.HTTPUnauthorized('Unauthorized Error', ERROR_INVALID_REQUEST)
def on_post(self, req, resp, id=None): """Handle POST """ if id is not None: raise falcon.HTTPMethodNotAllowed(('PATCH', )) body = json.loads(req.stream.read()) if not body or 'title' not in body: raise falcon.HTTPBadRequest( 'Missing title', 'POST request body must include title') eid = self._db.insert({ 'title': body['title'], 'completed': body.get('completed', False), 'order': body.get('order', 10) }) resp.body = self._make_todo(self._db.get(eid=eid))
def on_post(self, req, resp, pid, dsid): """ Ingest new datastream. """ try: self._create_datastream(req, pid, dsid) logger.info('Created DS %s on %s.', dsid, pid) except ObjectDoesNotExistError: logger.info(('Did not create datastream %s on %s as the object ' 'did not exist.'), dsid, pid) _send_object_404(pid, resp) except DatastreamExistsError as e: logger.info(('Did not create datasteam %s on %s as it already ' 'exists.'), dsid, pid) raise falcon.HTTPMethodNotAllowed(['PUT', 'HEAD', 'GET', 'DELETE']) from e resp.status = falcon.HTTP_201 self._datastream_to_response(pid, dsid, resp)
def dispatch(self, method, req, resp, **kwargs): """Route the request to the appropriate method. Also runs through the permissions (if there are any) and checks them against the current user. Args: method (str): The HTTP method, can be one of ``get``, ``put``, ``patch``, ``post``, ``delete``. """ if method not in self.get_allowed_methods(req, **kwargs): raise falcon.HTTPMethodNotAllowed( allowed_methods=self.allowed_methods()) self.authenticate(method, req, resp, **kwargs) self.check_permissions(req, **kwargs) getattr(self, method)(req, resp, **kwargs) resp.content_type = 'application/json'
def on_get(self, req, resp): raise falcon.HTTPMethodNotAllowed(['PUT'], description='Not Allowed')
def on_get(self, req, resp): raise falcon.HTTPMethodNotAllowed(['PUT'], headers={ 'x-ping': 'pong', 'accept': 'GET,PUT' })
def on_get(self, req, resp): raise falcon.HTTPMethodNotAllowed(['PUT'])
def __call__(self, req, resp): try: if req.method == "GET": _, _, _, tail = req.path.split("/", 3) body = b64decode(tail) elif req.method == "POST": body = req.stream.read(req.content_length or 0) else: raise falcon.HTTPMethodNotAllowed() ocsp_req = ocsp.OCSPRequest.load(body) except ValueError: raise falcon.HTTPBadRequest() fh = open(config.AUTHORITY_CERTIFICATE_PATH, "rb") # TODO: import from authority server_certificate = asymmetric.load_certificate(fh.read()) fh.close() now = datetime.now(timezone.utc) response_extensions = [] try: for ext in ocsp_req["tbs_request"]["request_extensions"]: if ext["extn_id"].native == "nonce": response_extensions.append( ocsp.ResponseDataExtension({ 'extn_id': "nonce", 'critical': False, 'extn_value': ext["extn_value"] })) except ValueError: # https://github.com/wbond/asn1crypto/issues/56 pass responses = [] for item in ocsp_req["tbs_request"]["request_list"]: serial = item["req_cert"]["serial_number"].native assert serial > 0, "Serial number correctness check failed" try: link_target = os.readlink( os.path.join(config.SIGNED_BY_SERIAL_DIR, "%x.pem" % serial)) assert link_target.startswith("../") assert link_target.endswith(".pem") path, buf, cert, signed, expires = self.authority.get_signed( link_target[3:-4]) if serial != cert.serial_number: logger.error( "Certificate store integrity check failed, %s refers to certificate with serial %x" % (link_target, cert.serial_number)) raise EnvironmentError("Integrity check failed") status = ocsp.CertStatus(name='good', value=None) except EnvironmentError: try: path, buf, cert, signed, expires, revoked = self.authority.get_revoked( serial) status = ocsp.CertStatus(name='revoked', value={ 'revocation_time': revoked, 'revocation_reason': "key_compromise", }) except EnvironmentError: status = ocsp.CertStatus(name="unknown", value=None) responses.append({ 'cert_id': { 'hash_algorithm': { 'algorithm': "sha1" }, 'issuer_name_hash': server_certificate.asn1.subject.sha1, 'issuer_key_hash': server_certificate.public_key.asn1.sha1, 'serial_number': serial, }, 'cert_status': status, 'this_update': now, 'single_extensions': [] }) response_data = ocsp.ResponseData({ 'responder_id': ocsp.ResponderId(name='by_key', value=server_certificate.public_key.asn1.sha1), 'produced_at': now, 'responses': responses, 'response_extensions': response_extensions }) resp.body = ocsp.OCSPResponse({ 'response_status': "successful", 'response_bytes': { 'response_type': "basic_ocsp_response", 'response': { 'tbs_response_data': response_data, 'certs': [server_certificate.asn1], 'signature_algorithm': { 'algorithm': "sha1_ecdsa" if self.authority.public_key.algorithm == "ec" else "sha1_rsa" }, 'signature': (asymmetric.ecdsa_sign if self.authority.public_key.algorithm == "ec" else asymmetric.rsa_pkcs1v15_sign)(self.authority.private_key, response_data.dump(), "sha1") } } }).dump()
def on_options(self, req, resp): raise falcon.HTTPMethodNotAllowed( self.methods_allowed, description="OPTIONS method is not allowed. Methods allowed are {}" .format(self.methods_allowed))
def on_post(self, req, resp): raise falcon.HTTPMethodNotAllowed( self.methods_allowed, description="POST method is not allowed. Methods allowed are {}". format(self.methods_allowed))