Merge "Correctly handle auth_url/token authentication"
This commit is contained in:
		@@ -157,7 +157,7 @@ class HTTPClient(object):
 | 
			
		||||
            self.project_domain_id = self.auth_ref.project_domain_id
 | 
			
		||||
            self.auth_url = self.auth_ref.auth_url[0]
 | 
			
		||||
            self._management_url = self.auth_ref.management_url[0]
 | 
			
		||||
            self.auth_token = self.auth_ref.auth_token
 | 
			
		||||
            self.auth_token_from_user = self.auth_ref.auth_token
 | 
			
		||||
            self.trust_id = self.auth_ref.trust_id
 | 
			
		||||
            if self.auth_ref.has_service_catalog():
 | 
			
		||||
                self.region_name = self.auth_ref.service_catalog.region_name
 | 
			
		||||
@@ -219,6 +219,7 @@ class HTTPClient(object):
 | 
			
		||||
            self._endpoint = endpoint.rstrip('/')
 | 
			
		||||
        if region_name:
 | 
			
		||||
            self.region_name = region_name
 | 
			
		||||
        self._auth_token = None
 | 
			
		||||
 | 
			
		||||
        if not session:
 | 
			
		||||
            verify = cacert or True
 | 
			
		||||
@@ -252,20 +253,28 @@ class HTTPClient(object):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def auth_token(self):
 | 
			
		||||
        if self.auth_token_from_user:
 | 
			
		||||
            return self.auth_token_from_user
 | 
			
		||||
        if self._auth_token:
 | 
			
		||||
            return self._auth_token
 | 
			
		||||
        if self.auth_ref:
 | 
			
		||||
            if self.auth_ref.will_expire_soon(self.stale_duration):
 | 
			
		||||
                self.authenticate()
 | 
			
		||||
            return self.auth_ref.auth_token
 | 
			
		||||
        if self.auth_token_from_user:
 | 
			
		||||
            return self.auth_token_from_user
 | 
			
		||||
 | 
			
		||||
    @auth_token.setter
 | 
			
		||||
    def auth_token(self, value):
 | 
			
		||||
        self.auth_token_from_user = value
 | 
			
		||||
        """Override the auth_token.
 | 
			
		||||
 | 
			
		||||
        If an application sets auth_token explicitly then it will always be
 | 
			
		||||
        used and override any past or future retrieved token.
 | 
			
		||||
        """
 | 
			
		||||
        self._auth_token = value
 | 
			
		||||
 | 
			
		||||
    @auth_token.deleter
 | 
			
		||||
    def auth_token(self):
 | 
			
		||||
        del self.auth_token_from_user
 | 
			
		||||
        self._auth_token = None
 | 
			
		||||
        self.auth_token_from_user = None
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def service_catalog(self):
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ import json
 | 
			
		||||
import httpretty
 | 
			
		||||
 | 
			
		||||
from keystoneclient import exceptions
 | 
			
		||||
from keystoneclient.openstack.common import jsonutils
 | 
			
		||||
from keystoneclient.openstack.common import timeutils
 | 
			
		||||
from keystoneclient.tests.v2_0 import utils
 | 
			
		||||
from keystoneclient.v2_0 import client
 | 
			
		||||
@@ -157,6 +158,27 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
 | 
			
		||||
        self.assertFalse('serviceCatalog' in cs.service_catalog.catalog)
 | 
			
		||||
        self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_auth_url_token_authentication(self):
 | 
			
		||||
        fake_token = 'fake_token'
 | 
			
		||||
        fake_url = '/fake-url'
 | 
			
		||||
        fake_resp = {'result': True}
 | 
			
		||||
 | 
			
		||||
        self.stub_auth(json=self.TEST_RESPONSE_DICT)
 | 
			
		||||
        self.stub_url('GET', [fake_url], json=fake_resp,
 | 
			
		||||
                      base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)
 | 
			
		||||
 | 
			
		||||
        cl = client.Client(auth_url=self.TEST_URL,
 | 
			
		||||
                           token=fake_token)
 | 
			
		||||
        body = jsonutils.loads(httpretty.last_request().body)
 | 
			
		||||
        self.assertEqual(body['auth']['token']['id'], fake_token)
 | 
			
		||||
 | 
			
		||||
        resp, body = cl.get(fake_url)
 | 
			
		||||
        self.assertEqual(fake_resp, body)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
 | 
			
		||||
                         self.TEST_TOKEN)
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_authenticate_success_token_scoped(self):
 | 
			
		||||
        del self.TEST_REQUEST_BODY['auth']['passwordCredentials']
 | 
			
		||||
@@ -206,3 +228,45 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
 | 
			
		||||
                         self.TEST_RESPONSE_DICT["access"]["token"]["id"])
 | 
			
		||||
        self.assertFalse('serviceCatalog' in cs.service_catalog.catalog)
 | 
			
		||||
        self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_allow_override_of_auth_token(self):
 | 
			
		||||
        fake_url = '/fake-url'
 | 
			
		||||
        fake_token = 'fake_token'
 | 
			
		||||
        fake_resp = {'result': True}
 | 
			
		||||
 | 
			
		||||
        self.stub_auth(json=self.TEST_RESPONSE_DICT)
 | 
			
		||||
        self.stub_url('GET', [fake_url], json=fake_resp,
 | 
			
		||||
                      base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)
 | 
			
		||||
 | 
			
		||||
        cl = client.Client(username='exampleuser',
 | 
			
		||||
                           password='password',
 | 
			
		||||
                           tenant_name='exampleproject',
 | 
			
		||||
                           auth_url=self.TEST_URL)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(cl.auth_token, self.TEST_TOKEN)
 | 
			
		||||
 | 
			
		||||
        # the token returned from the authentication will be used
 | 
			
		||||
        resp, body = cl.get(fake_url)
 | 
			
		||||
        self.assertEqual(fake_resp, body)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
 | 
			
		||||
                         self.TEST_TOKEN)
 | 
			
		||||
 | 
			
		||||
        # then override that token and the new token shall be used
 | 
			
		||||
        cl.auth_token = fake_token
 | 
			
		||||
 | 
			
		||||
        resp, body = cl.get(fake_url)
 | 
			
		||||
        self.assertEqual(fake_resp, body)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
 | 
			
		||||
                         fake_token)
 | 
			
		||||
 | 
			
		||||
        # if we clear that overriden token then we fall back to the original
 | 
			
		||||
        del cl.auth_token
 | 
			
		||||
 | 
			
		||||
        resp, body = cl.get(fake_url)
 | 
			
		||||
        self.assertEqual(fake_resp, body)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
 | 
			
		||||
                         self.TEST_TOKEN)
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,8 @@ class UnauthenticatedTestCase(utils.TestCase):
 | 
			
		||||
 | 
			
		||||
class TestCase(UnauthenticatedTestCase):
 | 
			
		||||
 | 
			
		||||
    TEST_ADMIN_IDENTITY_ENDPOINT = "http://127.0.0.1:35357/v2.0"
 | 
			
		||||
 | 
			
		||||
    TEST_SERVICE_CATALOG = [{
 | 
			
		||||
        "endpoints": [{
 | 
			
		||||
            "adminURL": "http://cdn.admin-nets.local:8774/v1.0",
 | 
			
		||||
@@ -60,7 +62,7 @@ class TestCase(UnauthenticatedTestCase):
 | 
			
		||||
        "name": "glance"
 | 
			
		||||
    }, {
 | 
			
		||||
        "endpoints": [{
 | 
			
		||||
            "adminURL": "http://127.0.0.1:35357/v2.0",
 | 
			
		||||
            "adminURL": TEST_ADMIN_IDENTITY_ENDPOINT,
 | 
			
		||||
            "region": "RegionOne",
 | 
			
		||||
            "internalURL": "http://127.0.0.1:5000/v2.0",
 | 
			
		||||
            "publicURL": "http://127.0.0.1:5000/v2.0"
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@
 | 
			
		||||
import httpretty
 | 
			
		||||
 | 
			
		||||
from keystoneclient import exceptions
 | 
			
		||||
from keystoneclient.openstack.common import jsonutils
 | 
			
		||||
from keystoneclient.tests.v3 import utils
 | 
			
		||||
from keystoneclient.v3 import client
 | 
			
		||||
 | 
			
		||||
@@ -224,6 +225,27 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
 | 
			
		||||
        self.assertFalse('catalog' in cs.service_catalog.catalog)
 | 
			
		||||
        self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_auth_url_token_authentication(self):
 | 
			
		||||
        fake_token = 'fake_token'
 | 
			
		||||
        fake_url = '/fake-url'
 | 
			
		||||
        fake_resp = {'result': True}
 | 
			
		||||
 | 
			
		||||
        self.stub_auth(json=self.TEST_RESPONSE_DICT)
 | 
			
		||||
        self.stub_url('GET', [fake_url], json=fake_resp,
 | 
			
		||||
                      base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)
 | 
			
		||||
 | 
			
		||||
        cl = client.Client(auth_url=self.TEST_URL,
 | 
			
		||||
                           token=fake_token)
 | 
			
		||||
        body = jsonutils.loads(httpretty.last_request().body)
 | 
			
		||||
        self.assertEqual(body['auth']['identity']['token']['id'], fake_token)
 | 
			
		||||
 | 
			
		||||
        resp, body = cl.get(fake_url)
 | 
			
		||||
        self.assertEqual(fake_resp, body)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
 | 
			
		||||
                         self.TEST_TOKEN)
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_authenticate_success_token_domain_scoped(self):
 | 
			
		||||
        ident = self.TEST_REQUEST_BODY['auth']['identity']
 | 
			
		||||
@@ -301,3 +323,45 @@ class AuthenticateAgainstKeystoneTests(utils.TestCase):
 | 
			
		||||
                         self.TEST_RESPONSE_HEADERS["X-Subject-Token"])
 | 
			
		||||
        self.assertFalse('catalog' in cs.service_catalog.catalog)
 | 
			
		||||
        self.assertRequestBodyIs(json=self.TEST_REQUEST_BODY)
 | 
			
		||||
 | 
			
		||||
    @httpretty.activate
 | 
			
		||||
    def test_allow_override_of_auth_token(self):
 | 
			
		||||
        fake_url = '/fake-url'
 | 
			
		||||
        fake_token = 'fake_token'
 | 
			
		||||
        fake_resp = {'result': True}
 | 
			
		||||
 | 
			
		||||
        self.stub_auth(json=self.TEST_RESPONSE_DICT)
 | 
			
		||||
        self.stub_url('GET', [fake_url], json=fake_resp,
 | 
			
		||||
                      base_url=self.TEST_ADMIN_IDENTITY_ENDPOINT)
 | 
			
		||||
 | 
			
		||||
        cl = client.Client(username='exampleuser',
 | 
			
		||||
                           password='password',
 | 
			
		||||
                           tenant_name='exampleproject',
 | 
			
		||||
                           auth_url=self.TEST_URL)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(cl.auth_token, self.TEST_TOKEN)
 | 
			
		||||
 | 
			
		||||
        # the token returned from the authentication will be used
 | 
			
		||||
        resp, body = cl.get(fake_url)
 | 
			
		||||
        self.assertEqual(fake_resp, body)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
 | 
			
		||||
                         self.TEST_TOKEN)
 | 
			
		||||
 | 
			
		||||
        # then override that token and the new token shall be used
 | 
			
		||||
        cl.auth_token = fake_token
 | 
			
		||||
 | 
			
		||||
        resp, body = cl.get(fake_url)
 | 
			
		||||
        self.assertEqual(fake_resp, body)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
 | 
			
		||||
                         fake_token)
 | 
			
		||||
 | 
			
		||||
        # if we clear that overriden token then we fall back to the original
 | 
			
		||||
        del cl.auth_token
 | 
			
		||||
 | 
			
		||||
        resp, body = cl.get(fake_url)
 | 
			
		||||
        self.assertEqual(fake_resp, body)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(httpretty.last_request().headers.get('X-Auth-Token'),
 | 
			
		||||
                         self.TEST_TOKEN)
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,8 @@ class UnauthenticatedTestCase(utils.TestCase):
 | 
			
		||||
 | 
			
		||||
class TestCase(UnauthenticatedTestCase):
 | 
			
		||||
 | 
			
		||||
    TEST_ADMIN_IDENTITY_ENDPOINT = "http://127.0.0.1:35357/v3"
 | 
			
		||||
 | 
			
		||||
    TEST_SERVICE_CATALOG = [{
 | 
			
		||||
        "endpoints": [{
 | 
			
		||||
            "url": "http://cdn.admin-nets.local:8774/v1.0/",
 | 
			
		||||
@@ -105,7 +107,7 @@ class TestCase(UnauthenticatedTestCase):
 | 
			
		||||
            "region": "RegionOne",
 | 
			
		||||
            "interface": "internal"
 | 
			
		||||
        }, {
 | 
			
		||||
            "url": "http://127.0.0.1:35357/v3",
 | 
			
		||||
            "url": TEST_ADMIN_IDENTITY_ENDPOINT,
 | 
			
		||||
            "region": "RegionOne",
 | 
			
		||||
            "interface": "admin"
 | 
			
		||||
        }],
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user