def fromstring(text, root_tag=None): try: elem = lxml.etree.fromstring(text, parser) except lxml.etree.XMLSyntaxError as e: LOGGER.debug(e) raise XMLSyntaxError(e) cleanup_namespaces(elem) if root_tag is not None: # validate XML try: path = 'schema/%s.rng' % camel_to_snake(root_tag) with resource_stream(__name__, path) as rng: lxml.etree.RelaxNG(file=rng).assertValid(elem) except IOError as e: # Probably, the schema file doesn't exist. exc_type, exc_value, exc_traceback = sys.exc_info() LOGGER.error(e) raise exc_type, exc_value, exc_traceback except lxml.etree.DocumentInvalid as e: LOGGER.debug(e) raise DocumentInvalid(e) return elem
def wrapped(self, req): if not req.is_bucket_request: if err_resp: raise err_resp(msg=err_msg) LOGGER.debug('A key is specified for bucket API.') req.object_name = None return func(self, req)
def check_filter_order(pipeline, required_filters): """ Check that required filters are present in order in the pipeline. """ try: indexes = [pipeline.index(f) for f in required_filters] except ValueError as e: LOGGER.debug(e) return False return indexes == sorted(indexes)
def handle_request(self, req): LOGGER.debug('Calling Swift3 Middleware') LOGGER.debug(req.__dict__) controller = req.controller(self.app) if hasattr(controller, req.method): res = getattr(controller, req.method)(req) else: raise MethodNotAllowed(req.method, req.controller.resource_type()) return res
def handle_request(self, req): LOGGER.debug('Calling Swift3 Middleware') LOGGER.debug(req.__dict__) controller = req.controller(self.app) if hasattr(controller, req.method): handler = getattr(controller, req.method) if not getattr(handler, 'publicly_accessible', False): raise MethodNotAllowed(req.method, req.controller.resource_type()) res = handler(req) else: raise MethodNotAllowed(req.method, req.controller.resource_type()) return res
def decode_acl(resource, headers): """ Decode Swift metadata to an ACL instance. Given a resource type and HTTP headers, this method returns an ACL instance. """ value = '' key = sysmeta_header(resource, 'acl') if key in headers: value = headers[key] if value == '': # Fix me: In the case of value is empty or not dict instance, # I want an instance of Owner as None. # However, in the above process would occur error in reference # to an instance variable of Owner. return ACL(Owner(None, None), []) try: encode_value = json.loads(value) if not isinstance(encode_value, dict): return ACL(Owner(None, None), []) id = None name = None grants = [] if 'Owner' in encode_value: id = encode_value['Owner'] name = encode_value['Owner'] if 'Grant' in encode_value: for grant in encode_value['Grant']: grantee = None # pylint: disable-msg=E1101 for group in Group.__subclasses__(): if group.__name__ == grant['Grantee']: grantee = group() if not grantee: grantee = User(grant['Grantee']) permission = grant['Permission'] grants.append(Grant(grantee, permission)) return ACL(Owner(id, name), grants) except Exception as e: LOGGER.debug(e) pass raise InvalidSubresource((resource, 'acl', value))
def PUT(self, req): """ Handles PUT Bucket acl and PUT Object acl. """ if req.is_object_request: b_resp = req.get_response(self.app, 'HEAD', obj='', skip_check=True) o_resp = req.get_response(self.app, 'HEAD', permission='WRITE_ACP') req_acl = get_acl(req.headers, req.xml(ACL.max_xml_length), b_resp.bucket_acl.owner, o_resp.object_acl.owner) # Don't change the owner of the resource by PUT acl request. o_resp.object_acl.check_owner(req_acl.owner.id) for g in req_acl.grants: LOGGER.debug('Grant %s %s permission on the object /%s/%s' % (g.grantee, g.permission, req.container_name, req.object_name)) req.object_acl = req_acl headers = {} src_path = '/%s/%s' % (req.container_name, req.object_name) # object-sysmeta' can be updated by 'Copy' method, # but can not be by 'POST' method. # So headers['X-Copy-From'] for copy request is added here. headers['X-Copy-From'] = quote(src_path) headers['Content-Length'] = 0 req.get_response(self.app, 'PUT', headers=headers, skip_check=True) else: resp = req.get_response(self.app, 'HEAD', permission='WRITE_ACP') req_acl = get_acl(req.headers, req.xml(ACL.max_xml_length), resp.bucket_acl.owner) # Don't change the owner of the resource by PUT acl request. resp.bucket_acl.check_owner(req_acl.owner.id) for g in req_acl.grants: LOGGER.debug('Grant %s %s permission on the bucket /%s' % (g.grantee, g.permission, req.container_name)) req.bucket_acl = req_acl req.get_response(self.app, 'POST', skip_check=True) return HTTPOk()
def POST(self, app): if self.req.is_bucket_request: resp = self._handle_acl(app, 'HEAD', permission='WRITE_ACP') req_acl = get_acl(self.req.headers, self.req.xml(ACL.max_xml_length), resp.bucket_acl.owner) # Don't change the owner of the resource by PUT acl request. resp.bucket_acl.check_owner(req_acl.owner.id) for g in req_acl.grants: LOGGER.debug( 'Grant %s %s permission on the bucket /%s' % (g.grantee, g.permission, self.req.container_name)) self.req.bucket_acl = req_acl else: self._handle_acl(app, self.method)
def POST(self, app): if self.req.is_bucket_request: resp = self._handle_acl(app, 'HEAD', permission='WRITE_ACP') req_acl = get_acl(self.req.headers, self.req.xml(ACL.max_xml_length), resp.bucket_acl.owner) # Don't change the owner of the resource by PUT acl request. resp.bucket_acl.check_owner(req_acl.owner.id) for g in req_acl.grants: LOGGER.debug('Grant %s %s permission on the bucket /%s' % (g.grantee, g.permission, self.req.container_name)) self.req.bucket_acl = req_acl else: self._handle_acl(app, self.method)
def check_filter_order(pipeline, required_filters): """ Check that required filters are present in order in the pipeline. """ indexes = [] missing_filters = [] for filter in required_filters: try: indexes.append(pipeline.index(filter)) except ValueError as e: LOGGER.debug(e) missing_filters.append(filter) if missing_filters: raise ValueError('Invalid pipeline %r: missing filters %r' % (pipeline, missing_filters)) if indexes != sorted(indexes): raise ValueError('Invalid pipeline %r: expected filter %s' % (pipeline, ' before '.join(required_filters)))
def PUT(self, app): if self.req.is_object_request: b_resp = self.req.get_acl_response(app, 'HEAD', obj='') o_resp = self._handle_acl(app, 'HEAD', permission='WRITE_ACP') req_acl = get_acl(self.req.headers, self.req.xml(ACL.max_xml_length), b_resp.bucket_acl.owner, o_resp.object_acl.owner) # Remove Content-Type to avoid updating it self.req.environ.pop('CONTENT_TYPE', '') # Don't change the owner of the resource by PUT acl request. o_resp.object_acl.check_owner(req_acl.owner.id) for g in req_acl.grants: LOGGER.debug('Grant %s %s permission on the object /%s/%s' % (g.grantee, g.permission, self.req.container_name, self.req.object_name.decode('utf-8'))) self.req.object_acl = req_acl else: self._handle_acl(app, self.method)
def check_filter_order(pipeline, required_filters): """ Check that required filters are present in order in the pipeline. """ indexes = [] missing_filters = [] for filter in required_filters: try: indexes.append(pipeline.index(filter)) except ValueError as e: LOGGER.debug(e) missing_filters.append(filter) if missing_filters: raise ValueError('Invalid pipeline %r: missing filters %r' % ( pipeline, missing_filters)) if indexes != sorted(indexes): raise ValueError('Invalid pipeline %r: expected filter %s' % ( pipeline, ' before '.join(required_filters)))
def check_pipeline(self, conf): """ Check that proxy-server.conf has an appropriate pipeline for swift3. """ if conf.get('__file__', None) is None: return ctx = loadcontext(loadwsgi.APP, conf.__file__) pipeline = str(PipelineWrapper(ctx)).split(' ') # Add compatible with 3rd party middleware. if check_filter_order(pipeline, ['swift3', 'proxy-server']): auth_pipeline = pipeline[pipeline.index('swift3') + 1: pipeline.index('proxy-server')] # Check SLO middleware if 'slo' not in auth_pipeline: self.slo_enabled = False LOGGER.warning('swift3 middleware is required SLO middleware ' 'to support multi-part upload, please add it ' 'in pipline') if not conf.auth_pipeline_check: LOGGER.debug('Skip pipeline auth check.') return if 'tempauth' in auth_pipeline: LOGGER.debug('Use tempauth middleware.') return elif 'keystoneauth' in auth_pipeline: if check_filter_order(auth_pipeline, ['s3token', 'authtoken', 'keystoneauth']): LOGGER.debug('Use keystone middleware.') return elif len(auth_pipeline): LOGGER.debug('Use third party(unknown) auth middleware.') return raise ValueError('Invalid proxy pipeline: %s' % pipeline)
def check_pipeline(self, conf): """ Check that proxy-server.conf has an appropriate pipeline for swift3. """ if conf.get('__file__', None) is None: return ctx = loadcontext(loadwsgi.APP, conf.__file__) pipeline = str(PipelineWrapper(ctx)).split(' ') # Add compatible with 3rd party middleware. if check_filter_order(pipeline, ['swift3', 'proxy-server']): auth_pipeline = pipeline[pipeline.index('swift3') + 1:pipeline.index('proxy-server')] # Check SLO middleware if 'slo' not in auth_pipeline: self.slo_enabled = False LOGGER.warning('swift3 middleware is required SLO middleware ' 'to support multi-part upload, please add it ' 'in pipline') if not conf.auth_pipeline_check: LOGGER.debug('Skip pipeline auth check.') return if 'tempauth' in auth_pipeline: LOGGER.debug('Use tempauth middleware.') return elif 'keystoneauth' in auth_pipeline: if check_filter_order( auth_pipeline, ['s3token', 'authtoken', 'keystoneauth']): LOGGER.debug('Use keystone middleware.') return elif len(auth_pipeline): LOGGER.debug('Use third party(unknown) auth middleware.') return raise ValueError('Invalid proxy pipeline: %s' % pipeline)
def check_pipeline(self, conf): """ Check that proxy-server.conf has an appropriate pipeline for swift3. """ if conf.get('__file__', None) is None: return ctx = loadcontext(loadwsgi.APP, conf.__file__) pipeline = str(PipelineWrapper(ctx)).split(' ') # Add compatible with 3rd party middleware. check_filter_order(pipeline, ['swift3', 'proxy-server']) auth_pipeline = pipeline[pipeline.index('swift3') + 1:pipeline.index('proxy-server')] # Check SLO middleware if self.slo_enabled and 'slo' not in auth_pipeline: self.slo_enabled = False LOGGER.warning('swift3 middleware requires SLO middleware ' 'to support multi-part upload, please add it ' 'in pipeline') # Check IAM middleware position: when enabled, must be before swift3 if 'iam' in pipeline: check_filter_order(pipeline, ['iam', 'swift3']) if not conf.auth_pipeline_check: LOGGER.debug('Skip pipeline auth check.') return if 'tempauth' in auth_pipeline: LOGGER.debug('Use tempauth middleware.') elif 'keystoneauth' in auth_pipeline: check_filter_order(auth_pipeline, ['s3token', 'keystoneauth']) LOGGER.debug('Use keystone middleware.') elif len(auth_pipeline): LOGGER.debug('Use third party(unknown) auth middleware.') else: raise ValueError('Invalid pipeline %r: expected auth between ' 'swift3 and proxy-server ' % pipeline)