Commit 43343554 authored by Ilias Tsitsimpis's avatar Ilias Tsitsimpis

astakosclient: Implement get_user_info_with_endpoints

This function uses the keystone alike authentication API of Astakos
parent a2d29d67
......@@ -123,8 +123,8 @@ class AstakosClient():
# ----------------------------------
@retry
def _call_astakos(self, token, request_path,
headers=None, body=None, method="GET"):
def _call_astakos(self, token, request_path, headers=None,
body=None, method="GET", log_body=True):
"""Make the actual call to Astakos Service"""
if token is not None:
hashed_token = hashlib.sha1()
......@@ -134,7 +134,8 @@ class AstakosClient():
using_token = "without using token"
self.logger.debug(
"Make a %s request to %s %s with headers %s and body %s"
% (method, request_path, using_token, headers, body))
% (method, request_path, using_token, headers,
body if log_body else "(not logged)"))
# Check Input
if headers is None:
......@@ -362,7 +363,8 @@ class AstakosClient():
WARNING: This api call encodes the user's token inside the url.
It's thoughs security unsafe to use it (both astakosclient and
nginx tend to log requested urls).
Avoid the use of get_endpoints method and use *** instead.
Avoid the use of get_endpoints method and use
get_user_info_with_endpoints instead.
"""
params = {}
......@@ -376,6 +378,29 @@ class AstakosClient():
TOKENS_ENDPOINTS + "?" + urllib.urlencode(params)
return self._call_astakos(token, path)
# ----------------------------------
# do a POST to ``API_TOKENS``
def get_user_info_with_endpoints(self, token, uuid=None):
""" Fallback call for authenticate
Keyword arguments:
token -- user's token (string)
uuid -- user's uniq id
It returns back the token as well as information about the token
holder and the services he/she can acess (in json format).
In case of error raise an AstakosClientException.
"""
req_path = copy(API_TOKENS)
req_headers = {'content-type': 'application/json'}
body = {'auth': {'token': {'id': token}}}
if uuid is not None:
body['auth']['tenantName'] = uuid
req_body = parse_request(body, self.logger)
return self._call_astakos(token, req_path, req_headers,
req_body, "POST", False)
# ----------------------------------
# do a GET to ``API_QUOTAS``
def get_quotas(self, token):
......
......@@ -291,19 +291,29 @@ def _req_endpoints(conn, method, url, **kwargs):
# Check input
if conn.__class__.__name__ != "HTTPSConnection":
return _request_status_302(conn, method, url, **kwargs)
if method != "GET":
return _request_status_400(conn, method, url, **kwargs)
token_head = kwargs['headers'].get('X-Auth-Token')
url_split = url[len(astakosclient.API_TOKENS):].split('/')
token_url = url_split[1]
if token_head != token_url:
return _request_status_403(conn, method, url, **kwargs)
if token_url != token_1:
return _request_status_401(conn, method, url, **kwargs)
if url == astakosclient.API_TOKENS:
if method != "POST":
return _request_status_400(conn, method, url, **kwargs)
body = simplejson.loads(kwargs['body'])
token = body['auth']['token']['id']
if token != token_1:
return _request_status_401(conn, method, url, **kwargs)
# Return
return ("", simplejson.dumps(user_info_endpoints), 200)
# Return
return ("", simplejson.dumps(endpoints), 200)
else:
if method != "GET":
return _request_status_400(conn, method, url, **kwargs)
url_split = url[len(astakosclient.API_TOKENS):].split('/')
token_url = url_split[1]
if token_head != token_url:
return _request_status_403(conn, method, url, **kwargs)
if token_url != token_1:
return _request_status_401(conn, method, url, **kwargs)
# Return
return ("", simplejson.dumps(endpoints), 200)
# ----------------------------
......@@ -419,6 +429,36 @@ endpoints = {
{"href": "/astakos/api/tokens/0000/endpoints?marker=4&limit=10000",
"rel": "next"}]}
user_info_endpoints = \
{'serviceCatalog': [
{'endpoints': [{
'SNF:uiURL': 'https://node1.example.com/ui/',
'adminURL': 'https://node1.example.com/v1',
'internalUrl': 'https://node1.example.com/v1',
'publicURL': 'https://node1.example.com/v1',
'region': 'cyclades'}],
'name': 'cyclades',
'type': 'compute'},
{'endpoints': [{
'SNF:uiURL': 'https://node2.example.com/ui/',
'adminURL': 'https://node2.example.com/v1',
'internalUrl': 'https://node2.example.com/v1',
'publicURL': 'https://node2.example.com/v1',
'region': 'pithos'}],
'name': 'pithos',
'type': 'storage'}],
'token': {
'expires': '2013-06-19T15:23:59.975572+00:00',
'id': token_1,
'tenant': {
'id': user_1,
'name': 'Firstname Lastname'}},
'user': {
'id': user_1,
'name': 'Firstname Lastname',
'roles': [{'id': 1, 'name': 'default'}],
'roles_links': []}}
quotas = {
"system": {
"cyclades.ram": {
......@@ -1162,6 +1202,18 @@ class TestEndPoints(unittest.TestCase):
else:
self.fail("Should have raised Unauthorized Exception")
# ----------------------------------
def test_get_user_info_with_endpoints(self):
"""Test function call of get_user_info_with_endpoints"""
global token_1, user_info_endpoints
_mock_request([_request_ok])
try:
client = AstakosClient("https://example.com")
response = client.get_user_info_with_endpoints(token_1)
except Exception as err:
self.fail("Shouldn't raise Exception %s" % err)
self.assertEqual(response, user_info_endpoints)
# ----------------------------
# Run tests
......
......@@ -140,7 +140,14 @@ retry=0, use_pool=False, pool_size=8, logger=None\ **)**
.. warning:: *get_endpoints* api call encodes the user's token inside
the url. It's security unsafe to use it (both astakosclient
and nginx tend to log requested urls).
and nginx tend to log requested urls). Use
get_user_info_with_endpoints instead.
**get_user_info_with_endpoints(**\ token, uuid=None\ **)**
Fallback call which receives the user token or the user uuid/token
and returns back the token as well as information about the token
holder and the services he/seh can access.
In case of error raise an AstakosClientException exception.
**get_quotas(**\ token\ **)**
Given a user's authentication token return user's
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment