Commit 65961db6 authored by Ilias Tsitsimpis's avatar Ilias Tsitsimpis

astakosclient: Fix url paths

Fix some Astakos' urls paths that were broken.
Remove get_endpoints and rename get_user_info_with_endpoints
to get_endpoints.
Fix tests.
parent 1c7274c1
......@@ -56,12 +56,13 @@ def join_urls(a, b):
# --------------------------------------------------------------------
# Astakos API urls
UI_PREFIX = get_path(astakos_services, 'astakos_ui.prefix')
ACCOUNTS_PREFIX = get_path(astakos_services, 'astakos_account.prefix')
ACCOUNTS_PREFIX = join_urls(ACCOUNTS_PREFIX, 'v1.0')
API_AUTHENTICATE = join_urls(ACCOUNTS_PREFIX, "authenticate")
API_USERCATALOGS = join_urls(ACCOUNTS_PREFIX, "user_catalogs")
API_SERVICE_USERCATALOGS = join_urls(ACCOUNTS_PREFIX, "service/user_catalogs")
API_GETSERVICES = join_urls(ACCOUNTS_PREFIX, "get_services")
API_GETSERVICES = join_urls(UI_PREFIX, "get_services")
API_RESOURCES = join_urls(ACCOUNTS_PREFIX, "resources")
API_QUOTAS = join_urls(ACCOUNTS_PREFIX, "quotas")
API_SERVICE_QUOTAS = join_urls(ACCOUNTS_PREFIX, "service_quotas")
......@@ -72,8 +73,8 @@ API_FEEDBACK = join_urls(ACCOUNTS_PREFIX, "feedback")
# --------------------------------------------------------------------
# Astakos Keystone API urls
IDENTITY_PREFIX = get_path(astakos_services, 'astakos_identity.prefix')
IDENTITY_PREFIX = join_urls(IDENTITY_PREFIX, "v2.0")
API_TOKENS = join_urls(IDENTITY_PREFIX, "tokens")
TOKENS_ENDPOINTS = join_urls(API_TOKENS, "endpoints")
# --------------------------------------------------------------------
......@@ -361,41 +362,9 @@ class AstakosClient():
{'feedback_msg': message, 'feedback_data': data})
self._call_astakos(token, path, None, req_body, "POST")
# ----------------------------------
# do a GET to ``API_TOKENS``/<user_token>/``TOKENS_ENDPOINTS``
def get_endpoints(self, token, belongs_to=None, marker=None, limit=None):
"""Request registered endpoints from astakos
keyword arguments:
token -- user's token (string)
belongs_to -- user's uuid (string)
marker -- return endpoints whose ID is higher than marker's (int)
limit -- maximum number of endpoints to return (int)
Return a json formatted dictionary containing information
about registered endpoints.
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
get_user_info_with_endpoints instead.
"""
params = {}
if belongs_to is not None:
params['belongsTo'] = str(belongs_to)
if marker is not None:
params['marker'] = str(marker)
if limit is not None:
params['limit'] = str(limit)
path = API_TOKENS + "/" + token + "/" + \
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):
def get_endpoints(self, token, uuid=None):
""" Fallback call for authenticate
Keyword arguments:
......
......@@ -40,6 +40,7 @@ the astakos client library
"""
import re
import sys
import socket
import simplejson
......@@ -116,19 +117,23 @@ def _request_status_400(conn, method, url, **kwargs):
def _request_ok(conn, method, url, **kwargs):
"""This request behaves like original Astakos does"""
if url.startswith(astakosclient.API_AUTHENTICATE):
if re.match('/?' + astakosclient.API_AUTHENTICATE, url) is not None:
print "here 1"
return _req_authenticate(conn, method, url, **kwargs)
elif url.startswith(astakosclient.API_USERCATALOGS):
elif re.match('/?' + astakosclient.API_USERCATALOGS, url) is not None:
print "here 2"
return _req_catalogs(conn, method, url, **kwargs)
elif url.startswith(astakosclient.API_RESOURCES):
elif re.match('/?' + astakosclient.API_RESOURCES, url) is not None:
print "here 3"
return _req_resources(conn, method, url, **kwargs)
elif url.startswith(astakosclient.API_QUOTAS):
elif re.match('/?' + astakosclient.API_QUOTAS, url) is not None:
return _req_quotas(conn, method, url, **kwargs)
elif url.startswith(astakosclient.API_COMMISSIONS):
elif re.match('/?' + astakosclient.API_COMMISSIONS, url) is not None:
return _req_commission(conn, method, url, **kwargs)
elif url.startswith(astakosclient.API_TOKENS):
elif re.match('/?' + astakosclient.API_TOKENS, url) is not None:
return _req_endpoints(conn, method, url, **kwargs)
else:
print "here 4"
return _request_status_404(conn, method, url, **kwargs)
......@@ -242,7 +247,7 @@ def _req_commission(conn, method, url, **kwargs):
if 'body' not in kwargs:
return _request_status_400(conn, method, url, **kwargs)
body = simplejson.loads(unicode(kwargs['body']))
if url == astakosclient.API_COMMISSIONS:
if re.match('/?'+astakosclient.API_COMMISSIONS+'$', url) is not None:
# Issue Commission
# Check if we have enough resources to give
if body['provisions'][1]['quantity'] > 420000000:
......@@ -270,12 +275,12 @@ def _req_commission(conn, method, url, **kwargs):
return ("", "", 200)
elif method == "GET":
if url == astakosclient.API_COMMISSIONS:
if re.match('/?'+astakosclient.API_COMMISSIONS+'$', url) is not None:
# Return pending commission
return ("", simplejson.dumps(pending_commissions), 200)
else:
# Return commissions's description
serial = url[25:]
serial = re.sub('/?' + astakosclient.API_COMMISSIONS, '', url)[1:]
if serial == str(57):
return ("", simplejson.dumps(commission_description), 200)
else:
......@@ -291,29 +296,20 @@ def _req_endpoints(conn, method, url, **kwargs):
# Check input
if conn.__class__.__name__ != "HTTPSConnection":
return _request_status_302(conn, method, url, **kwargs)
if method != "POST":
return _request_status_400(conn, method, url, **kwargs)
token_head = kwargs['headers'].get('X-Auth-Token')
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)
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)
if method != "POST":
return _request_status_400(conn, method, url, **kwargs)
body = simplejson.loads(kwargs['body'])
token_body = body['auth']['token']['id']
if token_head != token_body:
return _request_status_403(conn, method, url, **kwargs)
if token_body != token_1:
return _request_status_401(conn, method, url, **kwargs)
# Return
return ("", simplejson.dumps(user_info_endpoints), 200)
# ----------------------------
......@@ -409,26 +405,6 @@ resources = {
"description": "Virtual machine memory",
"service": "cyclades"}}
endpoints = {
"endpoints": [
{"name": "cyclades",
"region": "cyclades",
"internalURL": "https://node1.example.com/ui/",
"adminURL": "https://node1.example.com/v1/",
"type": None,
"id": 5,
"publicURL": "https://node1.example.com/ui/"},
{"name": "pithos",
"region": "pithos",
"internalURL": "https://node2.example.com/ui/",
"adminURL": "https://node2.example.com/v1",
"type": None,
"id": 6,
"publicURL": "https://node2.example.com/ui/"}],
"endpoint_links": [
{"href": "/astakos/api/tokens/0000/endpoints?marker=4&limit=10000",
"rel": "next"}]}
user_info_endpoints = \
{'serviceCatalog': [
{'endpoints': [{
......@@ -1178,38 +1154,11 @@ class TestEndPoints(unittest.TestCase):
# ----------------------------------
def test_get_endpoints(self):
"""Test function call of get_endpoints"""
global token_1, endpoints
_mock_request([_request_ok])
try:
client = AstakosClient("https://example.com")
response = client.get_endpoints(token_1)
except Exception as err:
self.fail("Shouldn't raise Exception %s" % err)
self.assertEqual(response, endpoints)
# ----------------------------------
def test_get_endpoints_wrong_token(self):
"""Test function call of get_endpoints with wrong token"""
global token_2, endpoints
_mock_request([_request_ok])
try:
client = AstakosClient("https://example.com")
client.get_endpoints(token_2, marker=2, limit=100)
except Unauthorized:
pass
except Exception as err:
self.fail("Shouldn't raise Exception %s" % err)
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)
response = client.get_endpoints(token_1)
except Exception as err:
self.fail("Shouldn't raise Exception %s" % err)
self.assertEqual(response, user_info_endpoints)
......
......@@ -129,21 +129,7 @@ retry=0, use_pool=False, pool_size=8, logger=None\ **)**
In case of success returns nothing.
Otherwise raise an AstakosClientException exception.
**get_endpoints(**\ token, belongs_to, marker, limit\ **)**
Given a user's authentication token, request registered
endpoints from astakos service. If belongs_to is given (uuid)
check that the token belongs to this user. If marker is given
(int) return endpoints (ordered by ID) whose ID is higher than
the marker. Limit (int) specifies the maximum number of
endpoints to return. Return a json formatted dictionary containing
information about registered endpoints.
.. 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). Use
get_user_info_with_endpoints instead.
**get_user_info_with_endpoints(**\ token, uuid=None\ **)**
**get_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.
......
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