Revision bd93595d
b/docs/astakos-api-guide.rst | ||
---|---|---|
350 | 350 |
} |
351 | 351 |
|
352 | 352 |
|
353 |
The tenantName in the above requests is optional. |
|
354 |
|
|
353 | 355 |
The response is json formatted unless it is requested otherwise via format |
354 | 356 |
request parameter or Accept header. |
355 | 357 |
|
... | ... | |
364 | 366 |
'publicURL': 'https://node1.example.com/v1', |
365 | 367 |
'region': 'cyclades'}], |
366 | 368 |
'name': 'cyclades', |
367 |
'type': compute},
|
|
369 |
'type': 'compute'},
|
|
368 | 370 |
{'endpoints': [{'SNF:uiURL': 'https://node2.example.com/ui/', |
369 | 371 |
'adminURL': 'https://node2.example.com/v1', |
370 | 372 |
'internalUrl': 'https://node2.example.com/v1', |
371 | 373 |
'publicURL': 'https://node2.example.com/v1', |
372 | 374 |
'region': 'pithos'}], |
373 | 375 |
'name': 'pithos', |
374 |
'type': storage},
|
|
376 |
'type': 'storage'}],
|
|
375 | 377 |
'token': {'expires': '2013-06-19T15:23:59.975572+00:00', |
376 | 378 |
'id': 'CDEe2k0T/HdiJWBMMbHyOA==', |
377 | 379 |
'tenant': {'id': 'c18088be-16b1-4263-8180-043c54e22903', |
b/snf-astakos-app/astakos/api/tokens.py | ||
---|---|---|
36 | 36 |
from django.http import urlencode |
37 | 37 |
from django.views.decorators.csrf import csrf_exempt |
38 | 38 |
|
39 |
from snf_django.lib.api import faults, utils, api_method, get_token
|
|
39 |
from snf_django.lib.api import faults, utils, api_method |
|
40 | 40 |
|
41 | 41 |
from astakos.im.models import Service, AstakosUser |
42 |
from .util import user_from_token, json_response, xml_response |
|
42 |
from .util import user_from_token, json_response, xml_response, validate_user
|
|
43 | 43 |
|
44 | 44 |
import logging |
45 | 45 |
logger = logging.getLogger(__name__) |
... | ... | |
49 | 49 |
logger=logger) |
50 | 50 |
@user_from_token # Authenticate user!! |
51 | 51 |
def get_endpoints(request, token): |
52 |
if token != get_token(request):
|
|
52 |
if token != request.user.auth_token:
|
|
53 | 53 |
raise faults.Forbidden() |
54 | 54 |
|
55 | 55 |
belongsTo = request.GET.get('belongsTo') |
... | ... | |
92 | 92 |
|
93 | 93 |
uuid = None |
94 | 94 |
try: |
95 |
tenant = req['auth']['tenantName'] |
|
96 | 95 |
token_id = req['auth']['token']['id'] |
97 | 96 |
except KeyError: |
98 | 97 |
try: |
... | ... | |
109 | 108 |
except AstakosUser.DoesNotExist: |
110 | 109 |
raise faults.Unauthorized('Invalid token') |
111 | 110 |
|
112 |
if tenant != user.uuid: |
|
113 |
raise faults.Unauthorized('Invalid tenant') |
|
111 |
validate_user(user) |
|
114 | 112 |
|
115 | 113 |
if uuid is not None: |
116 | 114 |
if user.uuid != uuid: |
b/snf-astakos-app/astakos/api/util.py | ||
---|---|---|
89 | 89 |
return all(map(is_integer, lst)) |
90 | 90 |
|
91 | 91 |
|
92 |
def validate_user(user): |
|
93 |
# Check if the user is active. |
|
94 |
if not user.is_active: |
|
95 |
raise faults.Unauthorized('User inactive') |
|
96 |
|
|
97 |
# Check if the token has expired. |
|
98 |
if user.token_expired(): |
|
99 |
raise faults.Unauthorized('Authentication expired') |
|
100 |
|
|
101 |
# Check if the user has accepted the terms. |
|
102 |
if not user.signed_terms: |
|
103 |
raise faults.Unauthorized('Pending approval terms') |
|
104 |
|
|
105 |
|
|
92 | 106 |
def user_from_token(func): |
93 | 107 |
@wraps(func) |
94 | 108 |
def wrapper(request, *args, **kwargs): |
... | ... | |
105 | 119 |
except AstakosUser.DoesNotExist: |
106 | 120 |
raise faults.Unauthorized('Invalid X-Auth-Token') |
107 | 121 |
|
108 |
# Check if the user is active. |
|
109 |
if not user.is_active: |
|
110 |
raise faults.Unauthorized('User inactive') |
|
111 |
|
|
112 |
# Check if the token has expired. |
|
113 |
if user.token_expired(): |
|
114 |
raise faults.Unauthorized('Authentication expired') |
|
115 |
|
|
116 |
# Check if the user has accepted the terms. |
|
117 |
if not user.signed_terms: |
|
118 |
raise faults.Unauthorized('Pending approval terms') |
|
122 |
validate_user(user) |
|
119 | 123 |
|
120 | 124 |
request.user = user |
121 | 125 |
return func(request, *args, **kwargs) |
b/snf-astakos-app/astakos/im/tests/api.py | ||
---|---|---|
471 | 471 |
self.assertEqual(body['unauthorized']['message'], |
472 | 472 |
'Invalid credentials') |
473 | 473 |
|
474 |
# Check inconsistent tenant |
|
475 |
url = '/astakos/api/tokens' |
|
476 |
post_data = """{"auth":{"passwordCredentials":{"username":"%s", |
|
477 |
"password":"%s"}, |
|
478 |
"tenantName":"%s"}}""" % ( |
|
479 |
self.user1.uuid, self.user1.auth_token, self.user2.uuid) |
|
480 |
r = client.post(url, post_data, content_type='application/json') |
|
481 |
self.assertEqual(r.status_code, 401) |
|
482 |
body = json.loads(r.content) |
|
483 |
self.assertEqual(body['unauthorized']['message'], |
|
484 |
'Invalid tenant') |
|
485 |
|
|
486 | 474 |
# Check invalid json data |
487 | 475 |
url = '/astakos/api/tokens' |
488 | 476 |
r = client.post(url, "not json", content_type='application/json') |
... | ... | |
577 | 565 |
r = client.get(url, **headers) |
578 | 566 |
self.assertEqual(r.status_code, 403) |
579 | 567 |
|
568 |
# Check belongsTo BadRequest |
|
569 |
url = '/astakos/api/tokens/%s/endpoints?belongsTo=%s' % ( |
|
570 |
quote(self.user1.auth_token), quote(self.user2.uuid)) |
|
571 |
headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token} |
|
572 |
r = client.get(url, **headers) |
|
573 |
self.assertEqual(r.status_code, 400) |
|
574 |
|
|
575 |
# Check successful request |
|
580 | 576 |
url = '/astakos/api/tokens/%s/endpoints' % quote(self.user1.auth_token) |
581 | 577 |
headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token} |
582 | 578 |
r = client.get(url, **headers) |
... | ... | |
589 | 585 |
endpoints = body.get('endpoints') |
590 | 586 |
self.assertEqual(len(endpoints), 3) |
591 | 587 |
|
592 |
# Check belongsTo BadRequest |
|
593 |
url = '/astakos/api/tokens/%s/endpoints?belongsTo=%s' % ( |
|
594 |
quote(self.user1.auth_token), quote(self.user2.uuid)) |
|
595 |
headers = {'HTTP_X_AUTH_TOKEN': self.user1.auth_token} |
|
596 |
r = client.get(url, **headers) |
|
597 |
self.assertEqual(r.status_code, 400) |
|
598 |
|
|
599 | 588 |
# Check xml serialization |
600 | 589 |
url = '/astakos/api/tokens/%s/endpoints?format=xml' %\ |
601 | 590 |
quote(self.user1.auth_token) |
Also available in: Unified diff