Пример #1
0
    def test_storlet_acl_get_success(self):
        headers = {'X-Run-Storlet': self.storlet_name}
        headers.update(self.additional_headers)
        exc_pattern = '^.*403 Forbidden.*$'
        with self.assertRaisesRegexp(ClientException, exc_pattern):
            swift_client.get_object(self.member_url,
                                    self.member_token,
                                    self.container,
                                    'test_object',
                                    headers=headers)

        headers = {
            'X-Storlet-Container-Read': self.conf.member_user,
            'X-Storlet-Name': self.storlet_name
        }
        swift_client.post_container(self.url, self.token, self.container,
                                    headers)
        swift_client.head_container(self.url, self.token, self.container)
        headers = {'X-Run-Storlet': self.storlet_name}
        headers.update(self.additional_headers)
        resp_dict = dict()
        swift_client.get_object(self.member_url,
                                self.member_token,
                                self.container,
                                'test_object',
                                response_dict=resp_dict,
                                headers=headers)
        self.assertEqual(200, resp_dict['status'])
Пример #2
0
    def test_symlink_target(self):
        if 'symlink' not in self.cluster_info:
            raise unittest.SkipTest("Symlink not enabled in proxy; can't test "
                                    "symlink to reserved name")
        int_client = self.make_internal_client()

        # create link container first, ensure account gets created too
        client.put_container(self.url, self.token, 'c1')

        # Create reserve named container
        tgt_cont = get_reserved_name('container-%s' % uuid4())
        int_client.create_container(self.account, tgt_cont)

        # sanity, user can't get to reserved name
        with self.assertRaises(ClientException) as cm:
            client.head_container(self.url, self.token, tgt_cont)
        self.assertEqual(412, cm.exception.http_status)

        tgt_obj = get_reserved_name('obj-%s' % uuid4())
        int_client.upload_object(BytesIO(b'target object'), self.account,
                                 tgt_cont, tgt_obj)
        metadata = int_client.get_object_metadata(self.account, tgt_cont,
                                                  tgt_obj)
        etag = metadata['etag']

        # users can write a dynamic symlink that targets a reserved
        # name object
        client.put_object(self.url,
                          self.token,
                          'c1',
                          'symlink',
                          headers={
                              'X-Symlink-Target':
                              '%s/%s' % (tgt_cont, tgt_obj),
                              'Content-Type': 'application/symlink',
                          })

        # but can't read the symlink
        with self.assertRaises(ClientException) as cm:
            client.get_object(self.url, self.token, 'c1', 'symlink')
        self.assertEqual(412, cm.exception.http_status)

        # user's can't create static symlink to reserved name
        with self.assertRaises(ClientException) as cm:
            client.put_object(self.url,
                              self.token,
                              'c1',
                              'static-symlink',
                              headers={
                                  'X-Symlink-Target':
                                  '%s/%s' % (tgt_cont, tgt_obj),
                                  'X-Symlink-Target-Etag': etag,
                                  'Content-Type': 'application/symlink',
                              })
        self.assertEqual(412, cm.exception.http_status)

        # clean-up
        client.delete_object(self.url, self.token, 'c1', 'symlink')
        int_client.delete_object(self.account, tgt_cont, tgt_obj)
        int_client.delete_container(self.account, tgt_cont)
Пример #3
0
    def test_storlet_acl_get_success(self):
        headers = {'X-Run-Storlet': self.storlet_name}
        headers.update(self.additional_headers)
        exc_pattern = '^.*403 Forbidden.*$'
        with self.assertRaisesRegexp(ClientException, exc_pattern):
            swift_client.get_object(self.member_url, self.member_token,
                                    'myobjects', 'test_object',
                                    headers=headers)

        headers = {'X-Storlet-Container-Read': self.conf.member_user,
                   'X-Storlet-Name': self.storlet_name}
        swift_client.post_container(self.url,
                                    self.token,
                                    'myobjects',
                                    headers)
        swift_client.head_container(self.url,
                                    self.token,
                                    'myobjects')
        headers = {'X-Run-Storlet': self.storlet_name}
        headers.update(self.additional_headers)
        resp_dict = dict()
        swift_client.get_object(self.member_url,
                                self.member_token,
                                'myobjects', 'test_object',
                                response_dict=resp_dict,
                                headers=headers)
        self.assertEqual(resp_dict['status'], 200)
 def test_server_error(self):
     body = "c" * 60
     c.http_connection = self.fake_http_connection(500, body=body)
     self.assertRaises(c.ClientException, c.head_container, "http://www.test.com", "asdf", "asdf")
     try:
         c.head_container("http://www.test.com", "asdf", "asdf")
     except c.ClientException as e:
         self.assertEqual(e.http_response_content, body)
Пример #5
0
 def getMember(self, name):
     try:
         client.head_container(self.storage_url,
                               self.auth_token,
                               container=name,
                               http_conn=self.http_connection)
         return ObjectCollection(name, self.environ, path=self.path)
     except client.ClientException as ex:
         if '404' in ex:
             raise dav_error.DAVError(dav_error.HTTP_NOT_FOUND)
Пример #6
0
 def test_server_error(self):
     body = 'c' * 60
     c.http_connection = self.fake_http_connection(500, body=body)
     self.assertRaises(c.ClientException, c.head_container,
                       'http://www.test.com', 'asdf', 'asdf',
                       )
     try:
         c.head_container('http://www.test.com', 'asdf', 'asdf')
     except c.ClientException as e:
         self.assertEqual(e.http_response_content, body)
 def test_server_error(self):
     body = 'c' * 60
     c.http_connection = self.fake_http_connection(500, body=body)
     self.assertRaises(c.ClientException, c.head_container,
                       'http://www.test.com', 'asdf', 'asdf',
                       )
     try:
         c.head_container('http://www.test.com', 'asdf', 'asdf')
     except c.ClientException as e:
         self.assertEquals(e.http_response_content, body)
Пример #8
0
 def getMember(self, name):
     try:
         client.head_container(self.storage_url,
                               self.auth_token,
                               container=name,
                               http_conn=self.http_connection)
         return ObjectCollection(name, self.environ, path=self.path)
     except client.ClientException as ex:
         if '404' in ex:
             raise dav_error.DAVError(dav_error.HTTP_NOT_FOUND)
Пример #9
0
def create_thumbnail(request, account, original_container_name, container,
                     objectname):
    """ Creates a thumbnail for an image. """
    storage_url = request.session.get('storage_url', '')
    auth_token = request.session.get('auth_token', '')

    try:
        client.head_container(storage_url, auth_token,
                              account)
    except client.ClientException:
        try:
            client.put_container(
                storage_url,
                auth_token,
                account)
        except client.ClientException as e:
            logger.error("Cannot put container %s. Error: %s "
                         % (container, str(e)))
            return None
    try:
        headers, content = client.get_object(
            storage_url,
            auth_token,
            container,
            objectname)

        im = Image.open(StringIO(content))
        im.thumbnail(settings.THUMBNAIL_SIZE, Image.ANTIALIAS)
        output = StringIO()
        mimetype = headers['content-type'].split('/')[-1]
        im.save(output, format=mimetype)
        content = output.getvalue()
        headers = {'X-Delete-After': settings.THUMBNAIL_DURABILITY}
        try:
            client.put_object(
                storage_url,
                auth_token,
                account,
                "%s_%s" % (original_container_name, objectname),
                content,
                headers=headers)
        except client.ClientException as e:
            logger.error("Cannot create thumbnail for image %s."
                         "Could not put thumbnail to storage: %s"
                         % (objectname, str(e)))
        output.close()
    except client.ClientException as e:
        logger.error("Cannot create thumbnail for image %s."
                     "Could not retrieve the image from storage: %s"
                     % (objectname, str(e)))
    except IOError as e:
        logger.error("Cannot create thumbnail for image %s."
                     "An IOError occured: %s" % (objectname, e.strerror))
Пример #10
0
    def test_simple_crud(self):
        int_client = self.make_internal_client()

        # Create reserve named container
        user_cont = 'container-%s' % uuid4()
        reserved_cont = get_reserved_name('container-%s' % uuid4())
        client.put_container(self.url, self.token, user_cont)
        int_client.create_container(self.account, reserved_cont)

        # Check that we can list both reserved and non-reserved containers
        self.assertEqual(
            [reserved_cont, user_cont],
            [c['name'] for c in int_client.iter_containers(self.account)])

        # sanity, user can't get to reserved name
        with self.assertRaises(ClientException) as cm:
            client.head_container(self.url, self.token, reserved_cont)
        self.assertEqual(412, cm.exception.http_status)

        user_obj = 'obj-%s' % uuid4()
        reserved_obj = get_reserved_name('obj-%s' % uuid4())

        # InternalClient can write & read reserved names fine
        int_client.upload_object(BytesIO(b'data'), self.account, reserved_cont,
                                 reserved_obj)
        int_client.get_object_metadata(self.account, reserved_cont,
                                       reserved_obj)
        _, _, app_iter = int_client.get_object(self.account, reserved_cont,
                                               reserved_obj)
        self.assertEqual(b''.join(app_iter), b'data')
        self.assertEqual([reserved_obj], [
            o['name']
            for o in int_client.iter_objects(self.account, reserved_cont)
        ])

        # But reserved objects must be in reserved containers, and
        # user objects must be in user containers (at least for now)
        int_client.upload_object(BytesIO(b'data'),
                                 self.account,
                                 reserved_cont,
                                 user_obj,
                                 acceptable_statuses=(400, ))

        int_client.upload_object(BytesIO(b'data'),
                                 self.account,
                                 user_cont,
                                 reserved_obj,
                                 acceptable_statuses=(400, ))

        # Make sure we can clean up, too
        int_client.delete_object(self.account, reserved_cont, reserved_obj)
        int_client.delete_container(self.account, reserved_cont)
Пример #11
0
    def wrapper(*args, **kw):

        storage_url = args[0].session.get('storage_url', '')
        auth_token = args[0].session.get('auth_token', '')
        username = args[0].session.get('username', '')
        password = args[0].session.get('password', '')

        # If the following variables are available, attempt to get an
        # auth token
        if (storage_url and auth_token and username and password):

             # If the user has no role, head the container to valid the token
            if args[0].session.get('norole'):

                storage_url = args[0].session.get('default_storage_url', '')
                auth_token = args[0].session.get('default_auth_token', '')

                #Attempt to get a new auth token
                try:
                    client.head_container(
                        storage_url, auth_token, args[0].session.get('user'))
                    return fn(*args, **kw)
                except:
                    # Failure to get an auth token, tell the user the session
                    # has expiredself.
                    messages.error(args[0], _("Session expired."))

            # A regular user's token is validated by heading the account.
            else:
                try:
                    client.head_account(storage_url, auth_token)
                    return fn(*args, **kw)
                except:

                    #Attempt to get a new auth token
                    try:
                        auth_version = settings.SWIFT_AUTH_VERSION or 1
                        (storage_url, auth_token) = client.get_auth(
                            settings.SWIFT_AUTH_URL, username, password,
                            auth_version=auth_version)
                        args[0].session['auth_token'] = auth_token
                        args[0].session['storage_url'] = storage_url
                        return fn(*args, **kw)
                    except:
                        # Failure to get an auth token, tell the user the
                        # session has expired.
                        messages.error(args[0], _("Session expired."))
        return redirect(swiftbrowser.views.login)
Пример #12
0
 def get_container_metadata(self, swift_url, swift_container):
     swift_connection = swift.HTTPConnection(url=swift_url, insecure=True)
     return swift.head_container(swift_url,
                                 self.keystone.get_token('id'),
                                 swift_container,
                                 http_conn=(swift_connection.parsed_url,
                                            swift_connection))
Пример #13
0
def toggle_public(request, container):
    """ Sets/unsets '.r:*,.rlistings' container read ACL """

    storage_url = request.session.get('storage_url', '')
    auth_token = request.session.get('auth_token', '')

    try:
        meta = client.head_container(storage_url, auth_token, container)
    except client.ClientException:
        traceback.print_exc()
        messages.add_message(request, messages.ERROR, _("Access denied."))
        return redirect(containerview)

    read_acl = meta.get('x-container-read', '')
    if '.rlistings' and '.r:*' in read_acl:
        read_acl = read_acl.replace('.r:*', '')
        read_acl = read_acl.replace('.rlistings', '')
        read_acl = read_acl.replace(',,', ',')
    else:
        read_acl += '.r:*,.rlistings'
    headers = {'X-Container-Read': read_acl, }

    try:
        client.post_container(storage_url, auth_token, container, headers)
    except client.ClientException:
        traceback.print_exc()
        messages.add_message(request, messages.ERROR, _("Access denied."))

    return redirect(objectview, container=container)
Пример #14
0
def toggle_public(request, container):
    """ Sets/unsets '.r:*,.rlistings' container read ACL """

    storage_url = request.session.get('storage_url', '')
    auth_token = request.session.get('auth_token', '')

    try:
        meta = client.head_container(storage_url, auth_token, container)
    except client.ClientException:
        messages.add_message(request, messages.ERROR, _("Access denied."))
        return redirect(containerview)

    read_acl = meta.get('x-container-read', '')
    if '.rlistings' and '.r:*' in read_acl:
        read_acl = read_acl.replace('.r:*', '')
        read_acl = read_acl.replace('.rlistings', '')
        read_acl = read_acl.replace(',,', ',')
    else:
        read_acl += '.r:*,.rlistings'
    headers = {
        'X-Container-Read': read_acl,
    }

    try:
        client.post_container(storage_url, auth_token, container, headers)
    except client.ClientException:
        messages.add_message(request, messages.ERROR, _("Access denied."))

    return redirect(objectview, container=container)
Пример #15
0
def object_versioning(request, container, prefix=None):
    storage_url = get_endpoint(request, 'adminURL')
    auth_token = get_token_id(request)
    public_url = get_endpoint(request, 'publicURL') + '/' + container
    http_conn = client.http_connection(storage_url,
                                       insecure=settings.SWIFT_INSECURE)

    objects = []

    page = request.GET.get('page', 1)

    if request.method == 'GET':
        headers = client.head_container(storage_url,
                                auth_token,
                                container,
                                http_conn=http_conn)

        version_location = headers.get('x-versions-location', None)

        if version_location:
            try:
                _, objects = client.get_container(storage_url,
                                                  auth_token,
                                                  version_location,
                                                  prefix=prefix,
                                                  delimiter='/',
                                                  http_conn=http_conn)
            except client.ClientException:
                pass

        prefixes = prefix_list(prefix)
        object_list = pseudofolder_object_list(objects, prefix, public_url)

        context = utils.update_default_context(request, {
            'container': container,
            'objects': utils.generic_pagination(object_list, page),
            'version_location': version_location,
            'prefix': prefix,
            'prefixes': prefixes,
        })

        return render_to_response('container_versioning.html',
                                  dictionary=context,
                                  context_instance=RequestContext(request))

    if request.method == 'POST':

        action = request.POST.get('action', None)

        if action == 'enable':
            enable_versioning(request, container)
            actionlog.log(request.user.username, "enable", 'Versioning. Container: %s' % container)
        elif action == 'disable':
            disable_versioning(request, container)
            actionlog.log(request.user.username, "disable", 'Versioning. Container: %s' % container)
        else:
            messages.add_message(request, messages.ERROR, ugettext('Action is required.'))

        return redirect(object_versioning, container=container)
Пример #16
0
def get_acls(storage_url, auth_token, container, http_conn):
    """ Returns ACLs of given container. """
    acls = client.head_container(storage_url,
                                 auth_token,
                                 container,
                                 http_conn=http_conn)

    readers = acls.get('x-container-read', '')
    writers = acls.get('x-container-write', '')
    return (readers, writers)
Пример #17
0
def get_acls(storage_url, auth_token, container, http_conn):
    """ Returns ACLs of given container. """
    acls = client.head_container(storage_url,
                                auth_token,
                                container,
                                http_conn=http_conn)

    readers = acls.get('x-container-read', '')
    writers = acls.get('x-container-write', '')
    return (readers, writers)
Пример #18
0
def get_cors(storage_url, auth_token, container, http_conn):
    """ Returns CORS header of given container. """
    headers = client.head_container(storage_url,
                                    auth_token,
                                    container,
                                    http_conn=http_conn)

    cors = headers.get('x-container-meta-access-control-allow-origin', '')

    return cors
Пример #19
0
def get_cors(storage_url, auth_token, container, http_conn):
    """ Returns CORS header of given container. """
    headers = client.head_container(storage_url,
                                    auth_token,
                                    container,
                                    http_conn=http_conn)

    cors = headers.get('x-container-meta-access-control-allow-origin', '')

    return cors
Пример #20
0
    def test_skip_sync_when_misconfigured(self):
        source_container, dest_container = self._setup_synced_containers()

        container_name = 'versioned-%s' % uuid.uuid4()
        version_hdr = {'X-Versions-Enabled': 'true'}

        client.put_container(self.url, self.token, container_name,
                             headers=version_hdr)

        # some sanity checks
        object_name = 'object-%s' % uuid.uuid4()
        client.put_object(self.url, self.token, container_name, object_name,
                          'version1')
        client.put_object(self.url, self.token, container_name, object_name,
                          'version2')

        resp_headers, listing = client.get_container(
            self.url, self.token, container_name,
            query_string='versions')

        self.assertEqual(2, len(listing))

        sync_headers = {}
        sync_to = '//%s/%s/%s/%s' % (self.realm, self.cluster, self.account,
                                     dest_container)
        sync_headers['X-Container-Sync-To'] = sync_to
        sync_headers['X-Container-Sync-Key'] = 'secret'

        # use internal client to set container-sync headers
        # since it doesn't have container_sync middleware in pipeline
        # allowing us to bypass checks
        int_client = self.make_internal_client()
        # TODO: what a terrible hack, maybe we need to extend internal
        # client to allow caller to become a swift_owner??
        int_client.app.app.app.app.swift_owner_headers = []
        int_client.set_container_metadata(self.account, container_name,
                                          metadata=sync_headers)

        headers = client.head_container(self.url, self.token,
                                        container_name)

        # This should never happen, but if it does because of eventual
        # consistency or a messed up pipeline, container-sync should
        # skip syncing container.
        self.assertEqual('True', headers.get('x-versions-enabled'))
        self.assertEqual('secret', headers.get('x-container-sync-key'))
        self.assertEqual(sync_to, headers.get('x-container-sync-to'))

        # cycle container-sync
        Manager(['container-sync']).once()

        with self.assertRaises(ClientException) as cm:
            client.get_object(
                self.url, self.token, dest_container, object_name)
        self.assertEqual(404, cm.exception.http_status)  # sanity check
Пример #21
0
def get_acls(request, container):
    """ Read and return the Read and Write ACL of the given container. """

    storage_url = request.session.get("storage_url", "")
    auth_token = request.session.get("auth_token", "")

    cont = client.head_container(storage_url, auth_token, container)
    readers = split_acl(cont.get("x-container-read", ""))
    writers = split_acl(cont.get("x-container-write", ""))

    return JsonResponse({"read_acl": readers, "write_acl": writers})
Пример #22
0
    def container_status(url, token, container_name):
        """
        Returns status of container.

        :param url: storage url.
        :param token: auth token from keystone.
        :param container_name: name of container to return status.
        :return: dict of information on specified container.
        """
        status = sc.head_container(url, token, container_name)
        return status
Пример #23
0
    def container_status(url, token, container_name):
        """
        Returns status of container.

        :param url: storage url.
        :param token: auth token from keystone.
        :param container_name: name of container to return status.
        :return: dict of information on specified container.
        """
        status = sc.head_container(url, token, container_name)
        return status
Пример #24
0
    def cache_set(self, context, plan_name, key, contents):
        """Stores an object

        Allows the storage of jsonable objects except for None
        Storing None equals to a cache delete.

        """

        swift_client = self.get_object_client(context)
        if contents is None:
            self.cache_delete(context, plan_name, key)
            return

        try:
            swift_client.head_container(constants.TRIPLEO_CACHE_CONTAINER)
        except swiftexceptions.ClientException:
            swift_client.put_container(constants.TRIPLEO_CACHE_CONTAINER)

        swift_client.put_object(constants.TRIPLEO_CACHE_CONTAINER,
                                self._cache_key(plan_name, key),
                                zlib.compress(json.dumps(contents).encode()))
Пример #25
0
def check_incomplete_slo(request, storage_url, auth_token, container,
                         prefix=None):
    '''Check the header 'x-container-meta-slo' for the names of SLO that are
    incomplete. Return a list of the names of objects and the percentage
    it is complete.'''

    incomplete_slo = []

    try:
        headers = client.head_container(storage_url, auth_token, container)
    except client.ClientException, e:
        return HttpResponse(e, status=500)
Пример #26
0
def limited_users_login(request):
    """ Get and parse the list of containers the user has access to. """

    storage_url = request.session.get('storage_url', '')
    auth_token = request.session.get('auth_token', '')
    user = request.session.get('user', '')

    # Get list of containers the user has access to in
    # "X-Container-Meta-container-list" of the container that matches the
    # user's username.
    try:
        meta = client.head_container(storage_url, auth_token, user)

        # Save the storage_url and auth_token as the default
        # These values will be the ones reused to validate the session in
        # session_valid.
        request.session["default_storage_url"] = storage_url
        request.session["default_auth_token"] = auth_token
    except client.ClientException:

        # The user may belong to more than one tenant and so the user's
        # container my be in another tenant. Switch to the next tenant
        # in the tenant list.
        for i, tenant in enumerate(request.session["tenants"]):
            if tenant == request.session["tenant_name"]:
                if i + 1 <= len(request.session["tenants"]):
                    return redirect(
                        swiftbrowser.views.main.switch_tenant,
                        request.session["tenants"][i + 1], True)
                else:
                    # We've tried all the tenants, no container exists
                    messages.add_message(
                        request, messages.ERROR,
                        _("Unable to find container {0} in any tenant."
                            .format(user)))
                    break

        return redirect(swiftbrowser.views.main.login)

    # List of containers
    if not "x-container-meta-container-list" in meta:
        # User does not have access to any container but it's own
        containers = request.session["tenant_name"] + ":" + user
    else:
        containers = meta["x-container-meta-container-list"]

    # Save the mapping of tenants and containers the user has access to.
    if not request.session.get('container_mapping', ''):
        request.session['container_mapping'] = get_tenant_container_mapping(
            containers)

    return redirect(limited_users_containerview)
Пример #27
0
    def cache_set(self, context, plan_name, key, contents):
        """Stores an object

        Allows the storage of jsonable objects except for None
        Storing None equals to a cache delete.

        """

        swift_client = self.get_object_client(context)
        if contents is None:
            self.cache_delete(context, plan_name, key)
            return

        try:
            swift_client.head_container(constants.TRIPLEO_CACHE_CONTAINER)
        except swiftexceptions.ClientException:
            swift_client.put_container(constants.TRIPLEO_CACHE_CONTAINER)

        swift_client.put_object(
            constants.TRIPLEO_CACHE_CONTAINER,
            self._cache_key(plan_name, key),
            zlib.compress(json.dumps(contents).encode()))
Пример #28
0
    def copyMoveSingle(self, destPath, isMove):
        src = '/'.join(self.path.split('/')[2:])
        dst = '/'.join(destPath.split('/')[2:])
        src_cont = self.path.split('/')[1]
        dst_cont = destPath.split('/')[1]

        headers = {'X-Copy-From': self.path}

        try:
            client.head_container(self.storage_url,
                                  self.auth_token,
                                  dst_cont,
                                  headers=headers,
                                  http_conn=self.http_connection)
        except client.ClientException as ex:
            client.put_container(self.storage_url,
                                 self.auth_token,
                                 dst_cont,
                                 headers=headers,
                                 http_conn=self.http_connection)

        try:
            client.put_object(self.storage_url,
                              self.auth_token,
                              dst_cont,
                              dst,
                              headers=headers,
                              http_conn=self.http_connection)

            if isMove:
                client.delete_object(self.storage_url,
                                     self.auth_token,
                                     src_cont,
                                     src,
                                     http_conn=self.http_connection)
        except client.ClientException:
            pass
Пример #29
0
    def copyMoveSingle(self, destPath, isMove):
        src = '/'.join(self.path.split('/')[2:])
        dst = '/'.join(destPath.split('/')[2:])
        src_cont = self.path.split('/')[1]
        dst_cont = destPath.split('/')[1]

        headers = {'X-Copy-From': self.path}

        try:
            client.head_container(self.storage_url,
                              self.auth_token,
                              dst_cont,
                              headers=headers,
                              http_conn=self.http_connection)
        except client.ClientException as ex:
            client.put_container(self.storage_url,
                              self.auth_token,
                              dst_cont,
                              headers=headers,
                              http_conn=self.http_connection)

        try:
            client.put_object(self.storage_url,
                              self.auth_token,
                              dst_cont,
                              dst,
                              headers=headers,
                              http_conn=self.http_connection)

            if isMove:
                client.delete_object(self.storage_url,
                                     self.auth_token,
                                     src_cont,
                                     src,
                                     http_conn=self.http_connection)
        except client.ClientException:
            pass
Пример #30
0
def get_fine_grained_temp_key(storage_url, auth_token, container_name=None):
    """ 
    Tries to get meta-temp-url key from account or container.
    If not set, generate tempurl and save it.
    """

    logging.debug('  in get_fine_grained_temp_key: container_name:%s, \
        storage_url:%s ' % 
        (container_name, storage_url) )

    try:
        if container_name:
            container = client.head_container(storage_url, auth_token, 
                container_name)
            key = container.get('x-container-meta-temp-url-key')
            logging.debug(' key in get_fine_grained_temp_key container: %s ' % key)
        else:
            account = client.head_account(storage_url, auth_token)
            key = account.get('x-account-meta-temp-url-key')
            logging.debug(' key in get_fine_grained_temp_key account: %s ' % key)
    except client.ClientException:
        return None
    # logging.debug(' account or container in get_temp_key: %s ' 
    #     % account or container)

    if not key:
        chars = string.ascii_lowercase + string.digits
        key = ''.join(random.choice(chars) for x in range(32))
        if container_name:
            headers = {'x-container-meta-temp-url-key': key}
            try:
                client.post_container(storage_url, auth_token, container_name, 
                    headers)
                logging.debug(' post_container')

            except client.ClientException:
                return None
            raise ValueError('cannot get key, have no account rights to \
                get account key!')
        else:
            
            headers = {'x-account-meta-temp-url-key': key}
            try:
                client.post_account(storage_url, auth_token, headers)
                logging.debug(' post_account')

            except client.ClientException:
                return None
    return key
Пример #31
0
def get_original_account(storage_url, auth_token, container):
    try:
        headers = client.head_container(storage_url, auth_token, container)
        msp = headers.get('x-container-meta-storage-path')
        if msp is None:
            account = storage_url.split('/')[-1]
            original_container_name = container
        else:
            account = msp.split('/')[2]
            original_container_name = '_'.join(container.split('_')[2:])
    except client.ClientException as e:
        logger.error("Cannot head container %s . Error: %s "
                     % (container, str(e)))
        return (None, None)

    return (account, original_container_name)
def get_tempurl_key():
    (storage_url, auth_token) = client.get_auth(
        settings.SWIFT_AUTH_URL, settings.SWIFT_USER, settings.SWIFT_PASSWORD)

    try:
        meta = client.head_container(storage_url, auth_token,
                                     settings.SWIFT_CONTAINER)
        key = meta.get('x-container-meta-temp-url-key')
    except client.ClientException:
        client.put_container(storage_url, auth_token, settings.SWIFT_CONTAINER)
        key = None

    if not key:
        key = random_key()
        headers = {'x-container-meta-temp-url-key': key}
        client.post_container(storage_url, auth_token,
                              settings.SWIFT_CONTAINER, headers)

    return storage_url, key
Пример #33
0
def limited_users_containerview(request):
    """ Display the containers the user has access to within the current
    tenant."""

    storage_url = request.session.get('storage_url', '')
    auth_token = request.session.get('auth_token', '')

    container_list = []
    keys = {}

    container_mapping = request.session.get('container_mapping', '')

    if not container_mapping:
        messages.add_message(
            request, messages.ERROR, _("No container mapping."))
        return redirect(swiftbrowser.views.main.login)

    # Get keys for all the containers
    for container_name in container_mapping[request.session["tenant_name"]]:

        # Make sure user has access to the container
        try:
            meta = client.head_container(
                storage_url, auth_token, container_name)

        except client.ClientException:
            messages.add_message(
                request, messages.ERROR,
                _("Failed to head container {0}.".format(container_name)))
            return redirect(swiftbrowser.views.main.login)

        container_list.append({"name": container_name})
        keys[container_name] = meta.get('x-container-meta-temp-url-key', '')

    # Store the keys for later use
    request.session["keys"] = keys

    return render_to_response('limited_containerview.html', {
        'containers': container_list,
        'session': request.session,
    }, context_instance=RequestContext(request))
Пример #34
0
def disable_versioning(request, container):
    """ Enable/Disable versioning in container. """

    storage_url = get_endpoint(request, 'adminURL')
    auth_token = get_token_id(request)
    http_conn = client.http_connection(storage_url,
                                       insecure=settings.SWIFT_INSECURE)

    try:
        headers = client.head_container(storage_url,
                                    auth_token,
                                    container,
                                    http_conn=http_conn)
    except client.ClientException as err:
        log.exception('Exception: {0}'.format(err))
        messages.add_message(request, messages.ERROR, _('Access denied.'))
        return False

    version_location = headers.get('x-versions-location', None)

    if version_location:
        try:
            client.post_container(storage_url,
                                  auth_token,
                                  container,
                                  headers={'x-versions-location': ''},
                                  http_conn=http_conn)
            actionlog.log(request.user.username, "update", container)

        except client.ClientException as err:
            log.exception('{}{}'.format(_('Exception:').encode('UTF-8'), err))
            messages.add_message(request, messages.ERROR, _('Access denied.'))
            return False

        deleted = delete_container(request=request, container=version_location)
        if not deleted:
            return False

    messages.add_message(request, messages.SUCCESS, _('Versioning disabled.'))

    return True
Пример #35
0
def disable_versioning(request, container):
    """ Enable/Disable versioning in container. """

    storage_url = get_endpoint(request, 'adminURL')
    auth_token = get_token_id(request)
    http_conn = client.http_connection(storage_url,
                                       insecure=settings.SWIFT_INSECURE)

    try:
        headers = client.head_container(storage_url,
                                        auth_token,
                                        container,
                                        http_conn=http_conn)
    except client.ClientException as err:
        log.exception('Exception: {0}'.format(err))
        messages.add_message(request, messages.ERROR, _('Access denied.'))
        return False

    version_location = headers.get('x-versions-location', None)

    if version_location:
        try:
            client.post_container(storage_url,
                                  auth_token,
                                  container,
                                  headers={'x-versions-location': ''},
                                  http_conn=http_conn)
            actionlog.log(request.user.username, "update", container)

        except client.ClientException as err:
            log.exception('{}{}'.format(_('Exception:').encode('UTF-8'), err))
            messages.add_message(request, messages.ERROR, _('Access denied.'))
            return False

        deleted = delete_container(request=request, container=version_location)
        if not deleted:
            return False

    messages.add_message(request, messages.SUCCESS, _('Versioning disabled.'))

    return True
Пример #36
0
    def test_set_acl(self):
        headers = {'X-Container-Read': 'adam'}
        swift_client.post_container(self.url,
                                    self.token,
                                    self.container,
                                    headers)

        headers = {'X-Storlet-Container-Read': 'john',
                   'X-Storlet-Name': 'mystorlet-1.0.jar'}
        swift_client.post_container(self.url,
                                    self.token,
                                    self.container,
                                    headers)

        headers = swift_client.head_container(self.url,
                                              self.token,
                                              self.container)
        read_acl = headers['x-container-read']
        expected_acl = ('adam,.r:storlets'
                        '.john_mystorlet-1.0.jar')
        self.assertEqual(expected_acl, read_acl)
Пример #37
0
    def test_set_acl(self):
        headers = {'X-Container-Read': 'adam'}
        swift_client.post_container(self.url,
                                    self.token,
                                    self.container,
                                    headers)

        headers = {'X-Storlet-Container-Read': 'john',
                   'X-Storlet-Name': 'mystorlet-1.0.jar'}
        swift_client.post_container(self.url,
                                    self.token,
                                    self.container,
                                    headers)

        headers = swift_client.head_container(self.url,
                                              self.token,
                                              self.container)
        read_acl = headers['x-container-read']
        expected_acl = ('adam,.r:storlets'
                        '.john_mystorlet-1.0.jar')
        self.assertEqual(read_acl, expected_acl)
Пример #38
0
    def test_enable_syncing_while_versioned(self):
        source_container, dest_container = self._setup_synced_containers()

        container_name = 'versioned-%s' % uuid.uuid4()
        version_hdr = {'X-Versions-Enabled': 'true'}

        client.put_container(self.url, self.token, container_name,
                             headers=version_hdr)

        # fails to configure as a container-sync source
        sync_headers = {'X-Container-Sync-Key': 'secret'}
        sync_to = '//%s/%s/%s/%s' % (self.realm, self.cluster, self.account,
                                     dest_container)
        sync_headers['X-Container-Sync-To'] = sync_to
        with self.assertRaises(ClientException) as cm:
            client.post_container(self.url, self.token, container_name,
                                  headers=sync_headers)
        self.assertEqual(400, cm.exception.http_status)  # sanity check

        # but works if it's just a container-sync destination
        sync_headers = {'X-Container-Sync-Key': 'secret'}
        client.post_container(self.url, self.token, container_name,
                              headers=sync_headers)

        headers = client.head_container(self.url, self.token,
                                        container_name)
        self.assertEqual('True', headers.get('x-versions-enabled'))
        self.assertEqual('secret', headers.get('x-container-sync-key'))

        # update source header to sync to versioned container
        source_headers = {'X-Container-Sync-Key': 'secret'}
        sync_to = '//%s/%s/%s/%s' % (self.realm, self.cluster, self.account,
                                     container_name)
        source_headers['X-Container-Sync-To'] = sync_to
        client.post_container(self.url, self.token, source_container,
                              headers=source_headers)

        self._test_syncing(source_container, container_name)
Пример #39
0
    def test_enable_versioning_while_syncing_container(self):

        source_container, dest_container = self._setup_synced_containers()
        version_hdr = {'X-Versions-Enabled': 'true'}

        # Cannot enable versioning on source container
        with self.assertRaises(ClientException) as cm:
            client.post_container(self.url, self.token, source_container,
                                  headers=version_hdr)
        self.assertEqual(400, cm.exception.http_status)  # sanity check
        self.assertEqual(b'Cannot enable object versioning on a container '
                         b'configured as source of container syncing.',
                         cm.exception.http_response_content)

        # but destination is ok!
        client.post_container(self.url, self.token, dest_container,
                              headers=version_hdr)

        headers = client.head_container(self.url, self.token,
                                        dest_container)
        self.assertEqual('True', headers.get('x-versions-enabled'))
        self.assertEqual('secret', headers.get('x-container-sync-key'))

        self._test_syncing(source_container, dest_container)
Пример #40
0
def object_versioning(request, container, prefix=None):
    storage_url = get_endpoint(request, 'adminURL')
    auth_token = get_token_id(request)
    public_url = get_endpoint(request, 'publicURL') + '/' + container
    http_conn = client.http_connection(storage_url,
                                       insecure=settings.SWIFT_INSECURE)

    objects = []

    page = request.GET.get('page', 1)

    if request.method == 'GET':
        headers = client.head_container(storage_url,
                                        auth_token,
                                        container,
                                        http_conn=http_conn)

        version_location = headers.get('x-versions-location', None)

        if version_location:
            try:
                _, objects = client.get_container(storage_url,
                                                  auth_token,
                                                  version_location,
                                                  prefix=prefix,
                                                  delimiter='/',
                                                  http_conn=http_conn)
            except client.ClientException:
                pass

        prefixes = prefix_list(prefix)
        object_list = pseudofolder_object_list(objects, prefix, public_url)

        context = utils.update_default_context(
            request, {
                'container': container,
                'objects': utils.generic_pagination(object_list, page),
                'version_location': version_location,
                'prefix': prefix,
                'prefixes': prefixes,
            })

        return render_to_response('container_versioning.html',
                                  dictionary=context,
                                  context_instance=RequestContext(request))

    if request.method == 'POST':

        action = request.POST.get('action', None)

        if action == 'enable':
            enable_versioning(request, container)
            actionlog.log(request.user.username, "enable",
                          'Versioning. Container: %s' % container)
        elif action == 'disable':
            disable_versioning(request, container)
            actionlog.log(request.user.username, "disable",
                          'Versioning. Container: %s' % container)
        else:
            messages.add_message(request, messages.ERROR,
                                 ugettext('Action is required.'))

        return redirect(object_versioning, container=container)
Пример #41
0
 def get_container_metadata(self, swift_url, swift_container):
     swift_connection = swift.HTTPConnection(url=swift_url, insecure=True)
     return swift.head_container(swift_url, self.keystone.get_token('id'), swift_container,
                                 http_conn=(swift_connection.parsed_url, swift_connection))
Пример #42
0
def objectview(request, container, prefix=None):
    """ Returns list of all objects in current container. """

    storage_url = request.session.get("storage_url", "")
    auth_token = request.session.get("auth_token", "")

    # Users with no role use container keys
    if request.session.get("norole"):

        container_object = client.head_container(storage_url, auth_token, container)
        key = container_object.get("x-container-meta-temp-url-key", "")

    # Regular users use account keys
    else:

        account = client.head_account(storage_url, auth_token)
        key = account.get("x-account-meta-temp-url-key", "")

    request.session["container"] = container
    request.session["prefix"] = prefix
    request.session["key"] = key

    redirect_url = get_base_url(request)
    redirect_url += reverse("objectview", kwargs={"container": container})

    try:
        meta, objects = client.get_container(storage_url, auth_token, container, delimiter="/", prefix=prefix)

    except client.ClientException:
        messages.add_message(request, messages.ERROR, _("Access denied."))
        return redirect(containerview)

    # Check CORS header - BASE_URL should be in there. Do not perform this
    # check for users with no role. No role users will not be accessing
    # containers in any way except for swiftbrowser. Hence their container has
    # the proper headers. Norole users are unable to set the header anyways.
    if meta.get("x-container-meta-access-control-allow-origin") != settings.BASE_URL and not request.session.get(
        "norole", False
    ):

        # Add CORS headers so user can upload to this container.
        headers = {
            "X-Container-Meta-Access-Control-Expose-Headers": "Access-Control-Allow-Origin",
            "X-Container-Meta-Access-Control-Allow-Origin": settings.BASE_URL,
        }

        try:
            client.put_container(storage_url, auth_token, container, headers)

        except client.ClientException:
            messages.add_message(request, messages.ERROR, _("Access denied, unable to set CORS header."))
            return redirect(containerview)

    prefixes = prefix_list(prefix)
    pseudofolders, objs = pseudofolder_object_list(objects, prefix)
    base_url = get_base_url(request)
    account = storage_url.split("/")[-1]

    read_acl = meta.get("x-container-read", "").split(",")
    public = False
    required_acl = [".r:*", ".rlistings"]

    swift_url = storage_url + "/" + container + "/"
    swift_slo_url = storage_url + "/" + container + "_segments/"
    if prefix:
        swift_url += prefix
        swift_slo_url += prefix
        redirect_url += prefix

    signature = create_formpost_signature(swift_url, key)
    slo_signature = create_formpost_signature(swift_slo_url, key)

    if [x for x in read_acl if x in required_acl]:
        public = True

    return render_to_response(
        "objectview.html",
        {
            "swift_url": swift_url,
            "swift_slo_url": swift_slo_url,
            "signature": signature,
            "slo_signature": slo_signature,
            "redirect_url": redirect_url,
            "container": container,
            "objects": objs,
            "folders": pseudofolders,
            "session": request.session,
            "prefix": prefix,
            "prefixes": prefixes,
            "base_url": base_url,
            "account": account,
            "public": public,
            "max_file_size": 5368709120,
            "max_file_count": 1,
            "expires": int(time.time() + 60 * 60 * 2),
        },
        context_instance=RequestContext(request),
    )
Пример #43
0
    def test_account_listing(self):
        versions_header_key = 'X-Versions-Enabled'

        # Create container1
        container_name = 'container1'
        obj_name = 'object1'
        client.put_container(self.url, self.token, container_name)

        # Assert account level sees it
        self._assert_account_level(container_name,
                                   hdr_cont_count='1',
                                   hdr_obj_count='0',
                                   hdr_bytes='0',
                                   cont_count=0,
                                   cont_bytes=0)

        # Enable versioning
        hdrs = {versions_header_key: 'True'}
        client.post_container(self.url, self.token, container_name, hdrs)

        # write multiple versions of same obj
        client.put_object(self.url, self.token, container_name, obj_name,
                          'version1')
        client.put_object(self.url, self.token, container_name, obj_name,
                          'version2')

        # Assert account level doesn't see object data yet, but it
        # does see the update for the hidden container
        self._assert_account_level(container_name,
                                   hdr_cont_count='2',
                                   hdr_obj_count='0',
                                   hdr_bytes='0',
                                   cont_count=0,
                                   cont_bytes=0)

        # Get to final state
        self.get_to_final_state()

        # Assert account level now sees updated values
        # N.B: Note difference in values between header and container listing
        # header object count is counting both symlink + object versions
        # listing count is counting only symlink (in primary container)
        self._assert_account_level(container_name,
                                   hdr_cont_count='2',
                                   hdr_obj_count='3',
                                   hdr_bytes='16',
                                   cont_count=1,
                                   cont_bytes=16)

        client.delete_object(self.url, self.token, container_name, obj_name)
        _headers, current_versions = client.get_container(
            self.url, self.token, container_name)
        self.assertEqual(len(current_versions), 0)
        _headers, all_versions = client.get_container(self.url,
                                                      self.token,
                                                      container_name,
                                                      query_string='versions')
        self.assertEqual(len(all_versions), 3)

        # directly delete primary container to leave an orphan hidden
        # container
        self.direct_delete_container(container=container_name)

        # Get to final state
        self.get_to_final_state()

        # The container count decreases, as well as object count. But bytes
        # do not. The discrepancy between header object count, container
        # object count and bytes should indicate orphan hidden container is
        # still around consuming storage
        self._assert_account_level(container_name,
                                   hdr_cont_count='1',
                                   hdr_obj_count='3',
                                   hdr_bytes='16',
                                   cont_count=0,
                                   cont_bytes=16)

        # Can't HEAD or list anything, though
        with self.assertRaises(client.ClientException) as caught:
            client.head_container(self.url, self.token, container_name)
        self.assertEqual(caught.exception.http_status, 404)
        with self.assertRaises(client.ClientException) as caught:
            client.get_container(self.url, self.token, container_name)
        self.assertEqual(caught.exception.http_status, 404)
        with self.assertRaises(client.ClientException) as caught:
            client.get_container(self.url,
                                 self.token,
                                 container_name,
                                 query_string='versions')
        self.assertEqual(caught.exception.http_status, 404)
        with self.assertRaises(client.ClientException) as caught:
            client.get_object(self.url,
                              self.token,
                              container_name,
                              all_versions[1]['name'],
                              query_string='version-id=%s' %
                              all_versions[1]['version_id'])
        # A little funny -- maybe this should 404 instead?
        self.assertEqual(caught.exception.http_status, 400)

        # Fix isn't too bad -- just make the container again!
        client.put_container(self.url, self.token, container_name)
        _headers, current_versions = client.get_container(
            self.url, self.token, container_name)
        self.assertEqual(len(current_versions), 0)
        _headers, all_versions = client.get_container(self.url,
                                                      self.token,
                                                      container_name,
                                                      query_string='versions')
        self.assertEqual(len(all_versions), 3)

        # ... but to actually *access* the versions, you have to enable
        # versioning again
        with self.assertRaises(client.ClientException) as caught:
            client.get_object(self.url,
                              self.token,
                              container_name,
                              all_versions[1]['name'],
                              query_string='version-id=%s' %
                              all_versions[1]['version_id'])
        self.assertEqual(caught.exception.http_status, 400)
        self.assertIn(b'version-aware operations require',
                      caught.exception.http_response_content)
        client.post_container(self.url,
                              self.token,
                              container_name,
                              headers={'X-Versions-Enabled': 'true'})
        client.get_object(self.url,
                          self.token,
                          container_name,
                          all_versions[1]['name'],
                          query_string='version-id=%s' %
                          all_versions[1]['version_id'])
Пример #44
0
 def get_container_metadata(self, swift_url, swift_container):
     return swift.head_container(swift_url, self.keystone.get_token('id'), swift_container)
Пример #45
0
def objectview(request, container, prefix=None):
    """ Returns list of all objects in current container. """

    storage_url = request.session.get('storage_url', '')
    auth_token = request.session.get('auth_token', '')

    # Users with no role use container keys
    if request.session.get('norole'):
        key = request.session.get("keys")[container]

    # Regular users use account keys
    else:

        account = client.head_account(storage_url, auth_token)
        key = account.get('x-account-meta-temp-url-key', '')

    request.session['container'] = container
    request.session['prefix'] = prefix
    request.session["key"] = key

    try:
        meta = client.head_container(
            storage_url, auth_token, container,
            headers={"X-Forwarded-For": request.META.get('REMOTE_ADDR')})

    except client.ClientException:
        messages.add_message(request, messages.ERROR, _("Access denied."))
        return redirect(containerview)

    # Check CORS header - BASE_URL should be in there. Do not perform this
    # check for users with no role. No role users will not be accessing
    # containers in any way except for swiftbrowser. Hence their container has
    # the proper headers. Norole users are unable to set the header anyways.
    if meta.get(
        'x-container-meta-access-control-allow-origin'
    ) != settings.BASE_URL and not request.session.get('norole', False):

        # Add CORS headers so user can upload to this container.
        headers = {
            'X-Container-Meta-Access-Control-Expose-Headers':
            'Access-Control-Allow-Origin',
            'X-Container-Meta-Access-Control-Allow-Origin': settings.BASE_URL,
        }

        try:
            client.put_container(
                storage_url, auth_token, container, headers)

        except client.ClientException:
            messages.add_message(request, messages.ERROR, _(
                "Access denied, unable to set CORS header."))
            return redirect(containerview)

    prefixes = prefix_list(prefix)

    base_url = get_base_url(request)
    account = storage_url.split('/')[-1]

    read_acl = meta.get('x-container-read', '').split(',')
    public = False
    required_acl = ['.r:*', '.rlistings']

    # The swifturl is the URL that the browser can send posts to upload files.
    swift_url = storage_url + '/' + container + '/'
    swift_slo_url = storage_url + '/' + container + '_segments/'
    if prefix:
        swift_url += prefix
        swift_slo_url += prefix

    # Posts from the browser to swift need a valid signature that's created
    # from the tempurl key
    signature = create_formpost_signature(swift_url, key)
    slo_signature = create_formpost_signature(swift_slo_url, key)

    if [x for x in read_acl if x in required_acl]:
        public = True

    return render_to_response(
        "objectview.html",
        {
            'swift_url': swift_url,
            'swift_slo_url': swift_slo_url,
            'signature': signature,
            'slo_signature': slo_signature,
            'container': container,
            'session': request.session,
            'prefix': prefix,
            'prefixes': prefixes,
            'base_url': base_url,
            'account': account,
            'public': public,
            'max_file_size': 5368709120,
            'max_file_count': 1,
            'expires': int(time.time() + 60 * 60 * 2),
        },
        context_instance=RequestContext(request)
    )