Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
        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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
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))
Ejemplo n.º 9
0
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))
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
    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()
Ejemplo n.º 12
0
    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()
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
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)))
Ejemplo n.º 16
0
    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)
Ejemplo n.º 17
0
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)))
Ejemplo n.º 18
0
    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)
Ejemplo n.º 19
0
    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)
Ejemplo n.º 20
0
    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)