Commit bc81bc73 authored by Giorgos Korfiatis's avatar Giorgos Korfiatis Committed by Ilias Tsitsimpis

astakos: Remove call GET /authenticate

Use POST /tokens to authenticate. Delete AstakosClient.get_user_info()
and replace its uses by AstakosClient.authenticate().
parent 005d6796
......@@ -49,6 +49,9 @@ Astakos
Re-registration with `snf-component-register' affects both the base and
the ui URL.
* Remove API call GET /account/v1.0/authenticate in favor of
POST /identity/v2.0/tokens.
* Management commands:
* Introduced new commands:
* component-show
......
......@@ -169,10 +169,6 @@ class AstakosClient(object):
def ui_prefix(self):
return self._get_value('_ui_prefix')
@property
def api_authenticate(self):
return join_urls(self.account_prefix, "authenticate")
@property
def api_usercatalogs(self):
return join_urls(self.account_prefix, "user_catalogs")
......@@ -285,17 +281,6 @@ class AstakosClient(object):
self.logger.error(msg % (data, str(err)))
raise InvalidResponse(str(err), data)
# ------------------------
# do a GET to ``API_AUTHENTICATE``
def get_user_info(self):
"""Authenticate user and get user's info as a dictionary
In case of success return user information (json parsed format).
Otherwise raise an AstakosClientException.
"""
return self._call_astakos(self.api_authenticate)
# ----------------------------------
# do a POST to ``API_USERCATALOGS`` (or ``API_SERVICE_USERCATALOGS``)
# with {'uuids': uuids}
......
......@@ -40,8 +40,8 @@ demonstrates how to get user's info using ``astakosclient``.
client = AstakosClient("UQpYas7ElzWGD5yCcEXtjw",
"https://accounts.example.com")
user_info = client.get_user_info()
print user_info['username']
user_info = client.authenticate()
print user_info['access']['user']['id']
Another example where we ask for the username of a user with UUID:
``b3de8eb0-3958-477e-als9-789af8dd352c``
......@@ -79,10 +79,6 @@ retry=0, use_pool=False, pool_size=8, logger=None\ **)**
their token as well as the service endpoints one can access. In
case of error, it raises an AstakosClientException exception.
**get_user_info()**
It returns a dict with the corresponding user's info. In case of
error, it raises an AstakosClientException exception.
**get_usernames(**\ uuids\ **)**
Given a list of UUIDs it returns a uuid_catalog, that is a dictionary
with the given UUIDs as keys and the corresponding user names as
......
......@@ -20,6 +20,7 @@ Document Revisions
========================= ================================
Revision Description
========================= ================================
0.15 (October 29, 2013) Remove GET /authenticate in favor of POST /tokens
0.14 (June 03, 2013) Remove endpoint listing
0.14 (May 28, 2013) Extend token api with authenticate call
0.14 (May 23, 2013) Extend api to list endpoints
......@@ -79,71 +80,11 @@ Example reply if request user is authenticated:
User API Operations
--------------------
The operations described in this chapter allow users to authenticate themselves, send feedback and get user uuid/displayname mappings.
The operations described in this chapter allow users to send feedback and
get user uuid/displayname mappings.
All the operations require a valid user token.
.. _authenticate-api-label:
Authenticate
^^^^^^^^^^^^
Authenticate API requests require a token. An application that wishes to connect to Astakos, but does not have a token, should redirect the user to ``/login``. (see :ref:`authentication-label`)
============================== ========= ==================
Uri Method Description
============================== ========= ==================
``/account/v1.0/authenticate`` GET Authenticate user using token
============================== ========= ==================
|
==================== ===========================
Request Header Name Value
==================== ===========================
X-Auth-Token User authentication token
==================== ===========================
Extended information on the user serialized in the json format will be returned:
=========================== ============================
Name Description
=========================== ============================
displayname User displayname
uuid User unique identifier
email List with user emails
name User full name
auth_token_created Token creation date
auth_token_expires Token expiration date
=========================== ============================
Example reply:
::
{"id": "12",
"displayname": "user@example.com",
"uuid": "a9dc21d2-bcb2-4104-9a9e-402b7c70d6d8",
"email": "[user@example.com]",
"name": "Firstname Lastname",
"auth_token_created": "Wed, 30 May 2012 10:03:37 GMT",
"auth_token_expires": "Fri, 29 Jun 2012 10:03:37 GMT"}
|
=========================== =====================
Return Code Description
=========================== =====================
204 (No Content) The request succeeded
400 (Bad Request) Method not allowed or no user found
401 (Unauthorized) Missing token or inactive user or penging approval terms
500 (Internal Server Error) The request cannot be completed because of an internal error
=========================== =====================
.. warning:: The service is also available under ``/ui/authenticate``.
It will be removed in the next version.
Send feedback
^^^^^^^^^^^^^
......@@ -310,12 +251,12 @@ Tokens API Operations
Authenticate
^^^^^^^^^^^^
Fallback call which receives the user token or the user uuid/token pair and
returns back the token as well as information about the token holder and the
services he/she can access.
If not request body is provided (the request content length is missing or
equals to 0) the response contains only non authentication protected
information (the service catalog).
This call takes the user token or the user uuid/token pair, authenticates
the user and returns information about the token, its holder as well as
a list of services the user can access.
If no request body is provided (the request content length is missing or
equals to 0), the call operates in public mode, attempts no authentication
and returns only the service catalog.
========================================= ========= ==================
Uri Method Description
......
......@@ -50,7 +50,6 @@ astakos_account_v1_0 += patterns(
'astakos.api.user',
url(r'^feedback/?$', 'send_feedback'),
url(r'^user_catalogs/?$', 'get_uuid_displayname_catalogs'),
url(r'^authenticate/?$', 'authenticate'),
)
astakos_account_v1_0 += patterns(
......
......@@ -31,14 +31,8 @@
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
from django.http import HttpResponse
from django.utils import simplejson as json
from django.views.decorators.csrf import csrf_exempt
from snf_django.lib import api
from snf_django.lib.api import faults
from astakos.im.util import epoch
from .util import (
get_uuid_displayname_catalogs as get_uuid_displayname_catalogs_util,
......@@ -49,36 +43,6 @@ import logging
logger = logging.getLogger(__name__)
@api.api_method(http_method="GET", token_required=True, user_required=False,
logger=logger)
@user_from_token # Authenticate user!!
def authenticate(request):
# Normal Response Codes: 200
# Error Response Codes: internalServerError (500)
# badRequest (400)
# unauthorised (401)
user = request.user
if not user:
raise faults.BadRequest('No user')
response = HttpResponse()
user_info = {
'id': user.id,
'username': user.username,
'uuid': user.uuid,
'email': [user.email],
'name': user.realname,
'groups': list(user.groups.all().values_list('name', flat=True)),
'auth_token': request.META.get('HTTP_X_AUTH_TOKEN'),
'auth_token_created': epoch(user.auth_token_created),
'auth_token_expires': epoch(user.auth_token_expires)}
response.content = json.dumps(user_info)
response['Content-Type'] = 'application/json; charset=UTF-8'
response['Content-Length'] = len(response.content)
return response
@csrf_exempt
@api.api_method(http_method="POST", token_required=True, user_required=False,
logger=logger)
......
# Copyright 2011-2012 GRNET S.A. All rights reserved.
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
......@@ -184,7 +184,3 @@ urlpatterns += patterns(
'astakos.im.views',
url(r'^get_menu/?$', 'get_menu'),
url(r'^get_services/?$', 'get_services'))
urlpatterns += patterns(
'astakos.api.user',
url(r'^authenticate/?$', 'authenticate'))
# Copyright 2011 GRNET S.A. All rights reserved.
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
......@@ -83,13 +83,42 @@ def get_user_mock(request, *args, **kwargs):
request.user = None
if request.META.get('HTTP_X_AUTH_TOKEN', None) == '0000':
request.user_uniq = 'test'
request.user = {'uniq': 'test', 'auth_token': '0000'}
request.user = {"access": {
"token": {
"expires": "2013-06-19T15:23:59.975572+00:00",
"id": "0000",
"tenant": {
"id": "test",
"name": "Firstname Lastname"
}
},
"serviceCatalog": [],
"user": {
"roles_links": [],
"id": "test",
"roles": [{"id": 1, "name": "default"}],
"name": "Firstname Lastname"}}
}
if request.META.get('HTTP_X_AUTH_TOKEN', None) == '0001':
request.user_uniq = 'test'
request.user = {'uniq': 'test', 'groups': ['default',
'helpdesk'],
'auth_token': '0001'}
request.user = {"access": {
"token": {
"expires": "2013-06-19T15:23:59.975572+00:00",
"id": "0001",
"tenant": {
"id": "test",
"name": "Firstname Lastname"
}
},
"serviceCatalog": [],
"user": {
"roles_links": [],
"id": "test",
"roles": [{"id": 1, "name": "default"},
{"id": 2, "name": "helpdesk"}],
"name": "Firstname Lastname"}}
}
@mock.patch("astakosclient.AstakosClient", new=AstakosClientMock)
@mock.patch("snf_django.lib.astakos.get_user", new=get_user_mock)
......
# Copyright 2012 GRNET S.A. All rights reserved.
# Copyright 2012, 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
......@@ -95,8 +95,13 @@ def token_check(func):
raise PermissionDenied
token = request.POST.get('token', None)
if token and token == request.user.get('auth_token', None):
return func(request, *args, **kwargs)
if token:
try:
req_token = request.user["access"]["token"]["id"]
if token == req_token:
return func(request, *args, **kwargs)
except KeyError:
pass
raise PermissionDenied
......@@ -117,7 +122,8 @@ def helpdesk_user_required(func, permitted_groups=PERMITTED_GROUPS):
astakos.get_user(request, settings.ASTAKOS_AUTH_URL,
fallback_token=token, logger=logger)
if hasattr(request, 'user') and request.user:
groups = request.user.get('groups', [])
groups = request.user['access']['user']['roles']
groups = [g["name"] for g in groups]
if not groups:
logger.error("Failed to access helpdesk view. User: %r",
......@@ -181,7 +187,7 @@ def account(request, search_query):
is_uuid = UUID_SEARCH_REGEX.match(search_query)
is_vm = VM_SEARCH_REGEX.match(search_query)
account_name = search_query
auth_token = request.user.get('auth_token')
auth_token = request.user['access']['token']['id']
if is_ip:
try:
......@@ -258,7 +264,7 @@ def account(request, search_query):
'vms': vms,
'show_deleted': show_deleted,
'account_name': account_name,
'token': request.user['auth_token'],
'token': request.user['access']['token']['id'],
'networks': networks,
'HELPDESK_MEDIA_URL': HELPDESK_MEDIA_URL,
'UI_MEDIA_URL': UI_MEDIA_URL
......
# Copyright 2011 GRNET S.A. All rights reserved.
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
......@@ -50,7 +50,6 @@ from synnefo_branding import settings as snf_settings
from synnefo.util.version import get_component_version
from synnefo.lib import join_urls
from snf_django.lib.astakos import get_user
from synnefo import cyclades_settings
from synnefo.ui import settings as uisettings
......
# Copyright 2011 GRNET S.A. All rights reserved.
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
......@@ -46,9 +46,22 @@ from synnefo.userdata.models import PublicKeyPair
def get_user_mock(request, *args, **kwargs):
if request.META.get('HTTP_X_AUTH_TOKEN', None) == '0000':
request.user_uniq = 'test'
request.user = {'id': 'id',
'username': 'username',
'uuid': 'test'}
request.user = {"access": {
"token": {
"expires": "2013-06-19T15:23:59.975572+00:00",
"id": "token",
"tenant": {
"id": "test",
"name": "Firstname Lastname"
}
},
"serviceCatalog": [],
"user": {
"roles_links": [],
"id": "test",
"roles": [{"id": 1, "name": "default"}],
"name": "Firstname Lastname"}}
}
class AaiClient(Client):
......
......@@ -109,8 +109,8 @@ def api_method(http_method=None, token_required=True, user_required=True,
use_pool=True,
retry=2,
logger=logger)
user_info = astakos.get_user_info()
request.user_uniq = user_info["uuid"]
user_info = astakos.authenticate()
request.user_uniq = user_info["access"]["user"]["id"]
request.user = user_info
# Get the response object
......
# Copyright 2011-2012 GRNET S.A. All rights reserved.
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the following
......@@ -44,7 +44,7 @@ def user_for_token(token, astakos_auth_url, logger=None):
client = AstakosClient(token, astakos_auth_url,
retry=2, use_pool=True, logger=logger)
try:
return client.get_user_info()
return client.authenticate()
except Unauthorized:
return None
......@@ -65,11 +65,8 @@ def get_user(request, astakos_auth_url, fallback_token=None, logger=None):
if not user:
return None
# use user uuid, instead of email, keep email/displayname reference
# to user_id
request.user_uniq = user['uuid']
request.user_uniq = user['access']['user']['id']
request.user = user
request.user_id = user.get('displayname')
return user
......
......@@ -132,8 +132,24 @@ def astakos_user(user):
"""
with patch("snf_django.lib.api.get_token") as get_token:
get_token.return_value = "DummyToken"
with patch('astakosclient.AstakosClient.get_user_info') as m2:
m2.return_value = {"uuid": text.udec(user, 'utf8')}
with patch('astakosclient.AstakosClient.authenticate') as m2:
m2.return_value = {"access": {
"token": {
"expires": "2013-06-19T15:23:59.975572+00:00",
"id": "DummyToken",
"tenant": {
"id": text.udec(user, 'utf8'),
"name": "Firstname Lastname"
}
},
"serviceCatalog": [],
"user": {
"roles_links": [],
"id": text.udec(user, 'utf8'),
"roles": [{"id": 1, "name": "default"}],
"name": "Firstname Lastname"}}
}
with patch('astakosclient.AstakosClient.get_quotas') as m3:
m3.return_value = {
"system": {
......
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