def update(self, req, id, body): """ Updates the server name or password """ if len(req.body) == 0: raise exc.HTTPUnprocessableEntity() if not body: return wsgi.Fault(exc.HTTPUnprocessableEntity()) ctxt = req.environ['engine.context'] update_dict = {} if 'name' in body['server']: name = body['server']['name'] self._validate_server_name(name) update_dict['display_name'] = name.strip() if 'description' in body['server']: description = body['server']['description'] update_dict['display_description'] = description.strip() self._parse_update(ctxt, id, body, update_dict) try: self.compute_api.update(ctxt, id, **update_dict) except exception.NotFound: return wsgi.Fault(exc.HTTPNotFound()) return exc.HTTPNoContent()
def __call__(self, req): if not self.has_authentication(req): return self.authenticate(req) user_id = self.get_user_by_authentication(req) if not user_id: token = req.headers["X-Auth-Token"] msg = _("%(user_id)s could not be found with token '%(token)s'") LOG.warn(msg % locals()) return wsgi.Fault(webob.exc.HTTPUnauthorized()) # Get all valid projects for the user projects = self.auth.get_projects(user_id) if not projects: return wsgi.Fault(webob.exc.HTTPUnauthorized()) project_id = "" path_parts = req.path.split('/') # TODO(wwolf): this v1.1 check will be temporary as # keystone should be taking this over at some point if len(path_parts) > 1 and path_parts[1] in ('v1.1', 'v2'): project_id = path_parts[2] # Check that the project for project_id exists, and that user # is authorized to use it try: self.auth.get_project(project_id) except exception.ProjectNotFound: return wsgi.Fault(webob.exc.HTTPUnauthorized()) if project_id not in [p.id for p in projects]: return wsgi.Fault(webob.exc.HTTPUnauthorized()) else: # As a fallback, set project_id from the headers, which is the v1.0 # behavior. As a last resort, be forgiving to the user and set # project_id based on a valid project of theirs. try: project_id = req.headers["X-Auth-Project-Id"] except KeyError: project_id = projects[0].id is_admin = self.auth.is_admin(user_id) remote_address = getattr(req, 'remote_address', '127.0.0.1') if FLAGS.use_forwarded_for: remote_address = req.headers.get('X-Forwarded-For', remote_address) ctx = context.RequestContext(user_id, project_id, is_admin=is_admin, remote_address=remote_address) req.environ['engine.context'] = ctx if not is_admin and not self.auth.is_project_member( user_id, project_id): msg = _("%(user_id)s must be an admin or a " "member of %(project_id)s") LOG.warn(msg % locals()) return wsgi.Fault(webob.exc.HTTPUnauthorized()) return self.application
def __call__(self, req): try: return req.get_response(self.application) except Exception as ex: LOG.exception(_("Caught error: %s"), unicode(ex)) exc = webob.exc.HTTPInternalServerError() return wsgi.Fault(exc)
def test_xml_serializer(self): """Ensure that a v1.1 request responds with a v1.1 xmlns""" request = webob.Request.blank('/v1.1', headers={"Accept": "application/xml"}) fault = wsgi.Fault(webob.exc.HTTPBadRequest(explanation='scram')) response = request.get_response(fault) self.assertTrue(common.XML_NS_V11 in response.body) self.assertEqual(response.content_type, "application/xml") self.assertEqual(response.status_int, 400)
def authenticate(self, req): # Unless the request is explicitly made against /<version>/ don't # honor it path_info = req.path_info if len(path_info) > 1: msg = _("Authentication requests must be made against a version " "root (e.g. /v2).") LOG.warn(msg) return wsgi.Fault(webob.exc.HTTPUnauthorized(explanation=msg)) def _get_auth_header(key): """Ensures that the KeyError returned is meaningful.""" try: return req.headers[key] except KeyError as ex: raise KeyError(key) try: username = _get_auth_header('X-Auth-User') key = _get_auth_header('X-Auth-Key') except KeyError as ex: msg = _("Could not find %s in request.") % ex LOG.warn(msg) return wsgi.Fault(webob.exc.HTTPUnauthorized(explanation=msg)) token, user = self._authorize_user(username, key, req) if user and token: res = webob.Response() res.headers['X-Auth-Token'] = token['token_hash'] res.headers['X-Server-Management-Url'] = \ token['server_management_url'] res.headers['X-Storage-Url'] = token['storage_url'] res.headers['X-CDN-Management-Url'] = token['cdn_management_url'] res.content_type = 'text/plain' res.status = '204' LOG.debug(_("Successfully authenticated '%s'") % username) return res else: return wsgi.Fault(webob.exc.HTTPUnauthorized())
def rate_limited_request(self, req, application): """Rate limit the request. If the request should be rate limited, return a 413 status with a Retry-After header giving the time when the request would succeed. """ action_name = self.get_action_name(req) if not action_name: # Not rate limited return application delay = self.get_delay(action_name, req.environ['engine.context'].user_id) if delay: # TODO(gundlach): Get the retry-after format correct. exc = webob.exc.HTTPRequestEntityTooLarge( explanation=('Too many requests.'), headers={'Retry-After': time.time() + delay}) raise os_wsgi.Fault(exc) return application
def test_400_fault_json(self): """Test fault serialized to JSON via file-extension and/or header.""" requests = [ webob.Request.blank('/.json'), webob.Request.blank('/', headers={"Accept": "application/json"}), ] for request in requests: fault = wsgi.Fault(webob.exc.HTTPBadRequest(explanation='scram')) response = request.get_response(fault) expected = { "badRequest": { "message": "scram", "code": 400, }, } actual = json.loads(response.body) self.assertEqual(response.content_type, "application/json") self.assertEqual(expected, actual)
def test_413_fault_json(self): """Test fault serialized to JSON via file-extension and/or header.""" requests = [ webob.Request.blank('/.json'), webob.Request.blank('/', headers={"Accept": "application/json"}), ] for request in requests: exc = webob.exc.HTTPRequestEntityTooLarge fault = wsgi.Fault( exc(explanation='sorry', headers={'Retry-After': 4})) response = request.get_response(fault) expected = { "overLimit": { "message": "sorry", "code": 413, "retryAfter": 4, }, } actual = json.loads(response.body) self.assertEqual(response.content_type, "application/json") self.assertEqual(expected, actual)
def test_fault_has_status_int(self): """Ensure the status_int is set correctly on faults""" fault = wsgi.Fault(webob.exc.HTTPBadRequest(explanation='what?')) self.assertEqual(fault.status_int, 400)
def raiser(req): raise wsgi.Fault(webob.exc.HTTPNotFound(explanation='whut?'))