Swift fails to authenticate user by token

Bug #1483254 reported by Vitalii
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
python-swiftclient
New
Undecided
Unassigned

Bug Description

Ther'a 2 issues with authentication.

1. Consider the following code.
"""
        client = swift_api_client.Connection(
            user=keystone.user.username,
            preauthurl=url,
            preauthtoken=keystone.user.token.id,
            tenant_name=keystone.user.tenant_name,
            insecure=insecure,
            cacert=cacert)
"""

Since ther's no ``auth_version`` specified, 1 used by default.
In this case swiftclient will try to use ``get_auth_1_0``:
"""
        storage_url, token = get_auth_1_0(auth_url,
                                          user,
                                          key,
                                          kwargs.get('snet'),
                                          insecure=insecure)
"""

As you can see, no keystone token passed to that function, therefore authentication fails.
Furthermore, swiftclient will fail miserably with exception:
"""
Traceback (most recent call last):
  File "./test_keystone.py", line 22, in <module>
    t.run('blah', user_id=483)
  File "/home/testproject/src/testproject_dev/stack/swift_task.py", line 75, in run
    return self.test(swift_client)
  File "/home/testproject/src/testproject_dev/stack/swift_task.py", line 45, in test
    swift_client.get_capabilities()
  File "/home/testproject/.virtualenvs/testproject/local/lib/python2.7/site-packages/swiftclient/client.py", line 1386, in get_capabilities
    url, _ = self.get_auth()
  File "/home/testproject/.virtualenvs/testproject/local/lib/python2.7/site-packages/swiftclient/client.py", line 1210, in get_auth
    insecure=self.insecure)
  File "/home/testproject/.virtualenvs/testproject/local/lib/python2.7/site-packages/swiftclient/client.py", line 377, in get_auth
    insecure=insecure)
  File "/home/testproject/.virtualenvs/testproject/local/lib/python2.7/site-packages/swiftclient/client.py", line 255, in get_auth_1_0
    parsed, conn = http_connection(url, insecure=insecure)
  File "/home/testproject/.virtualenvs/testproject/local/lib/python2.7/site-packages/swiftclient/client.py", line 249, in http_connection
    conn = HTTPConnection(*arg, **kwarg)
  File "/home/testproject/.virtualenvs/testproject/local/lib/python2.7/site-packages/swiftclient/client.py", line 156, in __init__
    self.parsed_url = urlparse(url)
  File "/usr/lib/python2.7/urlparse.py", line 143, in urlparse
    tuple = urlsplit(url, scheme, allow_fragments)
  File "/usr/lib/python2.7/urlparse.py", line 182, in urlsplit
    i = url.find(':')
AttributeError: 'NoneType' object has no attribute 'find'

"""

2. If you specify auth_version = 2, the following code will be executed.
"""
    elif auth_version in AUTH_VERSIONS_V2 + AUTH_VERSIONS_V3:
        # We are allowing to specify a token/storage-url to re-use
        # without having to re-authenticate.
        if (os_options.get('object_storage_url') and
                os_options.get('auth_token')):
            return (os_options.get('object_storage_url'),
                    os_options.get('auth_token'))
"""

It checks if there are ``object_storage_url`` and ``auth_token`` argumens were provided.
Of course they were absent, since initial values were: os_options or {}

So in order to get it working, you have to specify those options manually:
"""
        client.os_options = {
            'object_storage_url': url,
            'auth_token': keystone.user.token.id,
        }
"""

Conclusion. The only way to use swift client with existing tokens is the following:
"""
    def get_swift_client(self, keystone):
        insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
        cacert = getattr(settings, 'OPENSTACK_SSL_CACERT', None)
        url = keystone.url_for('object-store')

        client = swift_api_client.Connection(
            user=keystone.user.username,
            preauthurl=url,
            preauthtoken=keystone.user.token.id,
            tenant_name=keystone.user.tenant_name,
            insecure=insecure,
            cacert=cacert,
            auth_version=2)

        client.os_options = {
            'object_storage_url': url,
            'auth_token': keystone.user.token.id,
        }
        return client
"""

I think you should fix version handling or reflect the way it works in documentation.

Vitalii (vb-d)
affects: nova → python-swiftclient
description: updated
Revision history for this message
Tim Burke (1-tim-z) wrote :

I'm confused. If we already have a storage URL and token, why are we calling get_auth()? The _retry function (which nearly all client operations use) should only be calling it if url or token are missing, but we're explicitly passing it in. Also, couldn't the constructor call be reduced to something like this?

    client = swift_api_client.Connection(
        preauthurl=url,
        preauthtoken=keystone.user.token.id,
        insecure=insecure,
        cacert=cacert)

Why do we need user/tenant_name?

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.