Remove use of auth_token for REST API

* User username/password for each individual request
* Stop using single auth_token for authorizing multiple requests.

Closes-launchpad-Bug: #1302828
This commit is contained in:
Rohan Kanade
2014-04-08 10:35:34 +02:00
parent 626460aa55
commit ecfec61737
4 changed files with 15 additions and 97 deletions

View File

@@ -49,8 +49,6 @@ class HTTPClient(object):
self.times = [] # [("item", starttime, endtime), ...]
self.auth_token = None
self._logger = logging.getLogger(__name__)
if self.http_log_debug and not self._logger.handlers:
# Logging level is already set on the root logger
@@ -67,10 +65,6 @@ class HTTPClient(object):
# requests within the same session can reuse TCP connections from pool
self.http = requests.Session()
def unauthenticate(self):
"""Forget all of our authentication information."""
self.auth_token = None
def get_timings(self):
return self.times
@@ -150,39 +144,16 @@ class HTTPClient(object):
return resp, body
def _cs_request(self, url, method, **kwargs):
if self.auth_token:
if method in ['GET', 'DELETE']:
url = "%s?username=%s&password=%s" % (url, self.user,
self.password)
else:
kwargs.setdefault('body', {})['authtoken'] = self.auth_token
if method in ['GET', 'DELETE']:
url = "%s?username=%s&password=%s" % (url, self.user,
self.password)
else:
kwargs.setdefault('body', {}).update({'username': self.user,
'password': self.password})
# Perform the request once. If we get a 401 back then it
# might be because the auth token expired, so try to
# re-authenticate and try again. If it still fails, bail.
try:
resp, body = self._time_request(self.api_endpoint + url, method,
**kwargs)
return resp, body
except (exceptions.Unauthorized, exceptions.BadRequest) as e:
try:
# first discard auth token, to avoid the possibly expired
# token being re-used in the re-authentication attempt
self.unauthenticate()
self.authenticate()
if method in ['GET', 'DELETE']:
url = "%s?username=%s&password=%s" % (url, self.user,
self.password)
else:
kwargs.setdefault(
'body', {})['authtoken'] = self.auth_token
resp, body = self._time_request(self.api_endpoint + url,
method, **kwargs)
return resp, body
except exceptions.Unauthorized:
raise e
resp, body = self._time_request(self.api_endpoint + url, method,
**kwargs)
return resp, body
def get(self, url, **kwargs):
return self._cs_request(url, 'GET', **kwargs)
@@ -196,41 +167,6 @@ class HTTPClient(object):
def delete(self, url, **kwargs):
return self._cs_request(url, 'DELETE', **kwargs)
def authenticate(self):
auth_url = self.auth_url
if self.version == "v2.0": # FIXME(rk): This should be better.
self._v2_auth(auth_url)
def _v2_auth(self, url):
"""Authenticate against a v2.0 auth service."""
if self.auth_token:
return
else:
body = {"username": self.user, "password": self.password}
return self._authenticate(url, body)
def _authenticate(self, url, body, **kwargs):
"""Authenticate and extract the service catalog."""
method = "POST"
token_url = url + "/login"
# Make sure we follow redirects when trying to reach Keystone
resp, respbody = self._time_request(
token_url,
method,
body=body,
allow_redirects=True,
**kwargs)
return self._extract_auth_token(url, resp, respbody)
def _extract_auth_token(self, url, resp, body):
if resp.status_code == 200 or resp.status_code == 201:
if 'OpaqueRef' not in body:
raise exceptions.AuthorizationFailure()
self.auth_token = body
def get_client_class(version):
version_map = {

View File

@@ -14,8 +14,6 @@
# under the License.
import mock
import seamicroclient.client
from seamicroclient.tests import utils
import seamicroclient.v2.client
@@ -33,10 +31,3 @@ class ClientTest(utils.TestCase):
def test_get_client_class_v2(self):
output = seamicroclient.client.get_client_class('2')
self.assertEqual(output, seamicroclient.v2.client.Client)
@mock.patch.object(seamicroclient.client.HTTPClient, 'authenticate')
def test_authenticate_call_v2(self, mock_authenticate):
cs = seamicroclient.v2.client.Client("user", "password",
auth_url="foo/v2")
cs.authenticate()
self.assertTrue(mock_authenticate.called)

View File

@@ -68,7 +68,8 @@ class ClientTest(utils.TestCase):
'User-Agent': 'python-seamicroclient'}
mock_request.assert_called_with(
"GET",
"http://example.com/hi?username=%s&password=%s" % (cl.user, cl.password),
"http://example.com/hi?username=%s&password=%s" % (cl.user,
cl.password),
headers=headers)
# Automatic JSON parsing
self.assertEqual(body, {"hi": "there"})
@@ -93,16 +94,6 @@ class ClientTest(utils.TestCase):
test_post_call()
def test_auth_failure(self):
cl = get_client()
# response must not have x-server-management-url header
@mock.patch.object(requests.Session, "request", mock_request)
def test_auth_call():
self.assertRaises(exceptions.AuthorizationFailure, cl.authenticate)
test_auth_call()
def test_connection_refused(self):
cl = get_client()

View File

@@ -12,17 +12,17 @@
# under the License.
from seamicroclient import client
from seamicroclient.v2 import servers
from seamicroclient.v2 import pools
from seamicroclient.v2 import volumes
from seamicroclient.v2 import disks
from seamicroclient.v2 import chassis
from seamicroclient.v2 import disks
from seamicroclient.v2 import fantrays
from seamicroclient.v2 import interfaces
from seamicroclient.v2 import pools
from seamicroclient.v2 import powersupplies
from seamicroclient.v2 import scards
from seamicroclient.v2 import servers
from seamicroclient.v2 import smcards
from seamicroclient.v2 import system
from seamicroclient.v2 import volumes
class Client(object):