From 1ae97c8361d555007891ec6e7aaf045d1249e28a Mon Sep 17 00:00:00 2001 From: Sofia Papagiannaki Date: Sat, 25 Feb 2012 21:57:54 +0200 Subject: [PATCH] change cloudbar to contain dynamic links --- docs/source/devguide.rst | 58 +++++++++++- snf-astakos-app/astakos/im/api.py | 32 +++++++ snf-astakos-app/astakos/im/settings.py | 6 ++ .../astakos/im/static/im/cloudbar/cloudbar.js | 100 +++++++------------- snf-astakos-app/astakos/im/urls.py | 6 +- 5 files changed, 128 insertions(+), 74 deletions(-) diff --git a/docs/source/devguide.rst b/docs/source/devguide.rst index 77177cc..ec96ded 100644 --- a/docs/source/devguide.rst +++ b/docs/source/devguide.rst @@ -12,7 +12,7 @@ Users in astakos can be authenticated via several identity providers: * Twitter * Shibboleth -It provides also an administrative interface for managing user accounts. +It provides also a command line tool for managing user accounts. It is build over django and extends its authentication mechanism. @@ -102,7 +102,7 @@ Logged on users can perform a number of actions: * send feedback for grnet services via: ``/im/send_feedback`` * logout (and delete cookie) via: ``/im/logout`` -User entries can also be modified/added via the administrative interface available at ``/im/admin``. +User entries can also be modified/added via the ``snf-manage activateuser`` command. A superuser account can be created the first time you run the ``manage.py syncdb`` django command and then loading the extra user data from the ``admin_user`` fixture. At a later date, the ``manage.py createsuperuser`` command line utility can be used (as long as the extra user data for Astakos is added with a fixture or by hand). @@ -126,15 +126,15 @@ Finally, backend systems having acquired a token can use the :ref:`authenticate- The Astakos API --------------- -All 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`) - .. _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 +Uri Method Description ==================== ========= ================== ``/im/authenticate`` GET Authenticate user using token ==================== ========= ================== @@ -179,3 +179,51 @@ Return Code Description 401 (Unauthorized) Missing token or inactive user 500 (Internal Server Error) The request cannot be completed because of an internal error =========================== ===================== + +Get Services +^^^^^^^^^^^^ + +Returns a json formatted list containing information about the supported cloud services. + +==================== ========= ================== +Uri Method Description +==================== ========= ================== +``/im/get_services`` GET Get cloud services +==================== ========= ================== + +Example reply: + +:: + +[{"url": "/", "icon": "home-icon.png", "name": "grnet cloud", "id": "cloud"}, + {"url": "/okeanos.html", "name": "~okeanos", "id": "okeanos"}, + {"url": "/ui/", "name": "pithos+", "id": "pithos"}] + +Get Menu +^^^^^^^^ + +Returns a json formatted list containing the cloud bar links. + +==================== ========= ================== +Uri Method Description +==================== ========= ================== +``/im/get_menu`` GET Get cloud bar menu +==================== ========= ================== + +Example reply if request user is not authenticated: + +:: + +[{"url": "/im/login?next=", "name": "login..."}] + +Example reply if request user is authenticated: + +[{"url": "/im/profile", "name": "spapagian@grnet.gr"}, + {"url": "/im/profile", "name": "view your profile..."}, + {"url": "/im/password", "name": "change your password..."}, + {"url": "/im/feedback", "name": "feedback..."}, + {"url": "/im/logout", "name": "logout..."}] + + + + diff --git a/snf-astakos-app/astakos/im/api.py b/snf-astakos-app/astakos/im/api.py index e6ad5f4..f570b28 100644 --- a/snf-astakos-app/astakos/im/api.py +++ b/snf-astakos-app/astakos/im/api.py @@ -33,12 +33,17 @@ from traceback import format_exc from time import time, mktime +from urllib import quote +from urlparse import urlparse + from django.conf import settings from django.http import HttpResponse from django.utils import simplejson as json +from django.core.urlresolvers import reverse from astakos.im.faults import BadRequest, Unauthorized, InternalServerError from astakos.im.models import AstakosUser +from astakos.im.settings import CLOUD_SERVICES, INVITATIONS_ENABLED def render_fault(request, fault): if isinstance(fault, InternalServerError) and settings.DEBUG: @@ -91,3 +96,30 @@ def authenticate(request): except BaseException, e: fault = InternalServerError('Unexpected error') return render_fault(request, fault) + +def get_services(request): + if request.method != 'GET': + raise BadRequest('Method not allowed.') + data = json.dumps(CLOUD_SERVICES) + return HttpResponse(content=data, mimetype="application/json") + +def get_menu(request): + if request.method != 'GET': + raise BadRequest('Method not allowed.') + location = request.GET.get('location', '') + index_url = reverse('astakos.im.views.index') + if urlparse(location).query.rfind('next=') == -1: + index_url = '%s?next=%s' % (index_url, quote(location)) + l = [{ 'url': index_url, 'name': "login..."}] + if request.user.is_authenticated(): + l = [] + l.append({ 'url': reverse('astakos.im.views.edit_profile'), 'name': request.user.email}) + l.append({ 'url': reverse('astakos.im.views.edit_profile'), 'name': "view your profile..." }) + if request.user.password: + l.append({ 'url': reverse('password_change'), 'name': "change your password..." }) + if INVITATIONS_ENABLED: + l.append({ 'url': reverse('astakos.im.views.invite'), 'name': "invite some friends..." }) + l.append({ 'url': reverse('astakos.im.views.send_feedback'), 'name': "feedback..." }) + l.append({ 'url': reverse('astakos.im.views.logout'), 'name': "logout..."}) + data = json.dumps(tuple(l)) + return HttpResponse(content=data, mimetype="application/json") \ No newline at end of file diff --git a/snf-astakos-app/astakos/im/settings.py b/snf-astakos-app/astakos/im/settings.py index 9a67892..1093a96 100644 --- a/snf-astakos-app/astakos/im/settings.py +++ b/snf-astakos-app/astakos/im/settings.py @@ -47,3 +47,9 @@ BASEURL = getattr(settings, 'ASTAKOS_BASEURL', 'http://pithos.dev.grnet.gr') # Set service name SITENAME = getattr(settings, 'ASTAKOS_SITENAME', 'GRNET Cloud') + +# Set cloud services appear in the horizontal bar +CLOUD_SERVICES = getattr(settings, 'ASTAKOS_CLOUD_SERVICES', ( + { 'url':'/', 'name':'grnet cloud', 'id':'cloud', 'icon':'home-icon.png' }, + { 'url':'/okeanos.html', 'name':'~okeanos', 'id':'okeanos' }, + { 'url':'/ui/', 'name':'pithos+', 'id':'pithos' })) \ No newline at end of file diff --git a/snf-astakos-app/astakos/im/static/im/cloudbar/cloudbar.js b/snf-astakos-app/astakos/im/static/im/cloudbar/cloudbar.js index 64ddf25..def84d1 100644 --- a/snf-astakos-app/astakos/im/static/im/cloudbar/cloudbar.js +++ b/snf-astakos-app/astakos/im/static/im/cloudbar/cloudbar.js @@ -5,21 +5,6 @@ $(document).ready(function(){ */ var PROFILE_URL = "https://accounts.cloud.grnet.gr"; - var SERVICES_LINKS = window.CLOUDBAR_SERVICES_LINKS || { - 'cloud': { url:'/', name:'grnet cloud', id:'cloud', icon:'home-icon.png' }, - 'okeanos': { url:'/okeanos.html', name:'~okeanos', id:'okeanos' }, - 'pithos': { url:'/ui/', name:'pithos+', id:'pithos' } - }; - - var PROFILE_LINKS = window.CLOUDBAR_PROFILE_LINKS || { - 'login': { url: '/im/login?next=' + window.location.toString(), auth:false, name: "login...", visible:false }, - 'profile': { url: '/im/profile', auth:true, name: "view your profile..." }, - 'password': { url: '/im/password', auth:true, name: "change your password..." }, - 'invitations': { url: '/im/invite', auth:true, name: "invite some friends..." }, - 'feedback': { url: '/im/feedback', auth:true, name: "feedback..." }, - 'logout': { url: '/im/logout', auth:true, name: "logout..." } - }; - // cookie plugin https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js // * Copyright (c) 2010 Klaus Hartl, @carhartl @@ -51,66 +36,47 @@ $(document).ready(function(){ var services = $('
'); var profile = $('
'); - // create services links and set the active class to the current service - $.each(SERVICES_LINKS, function(i, el){ - var slink = $(""); - if (el.icon) { - slink.append($('')); - } else { - slink.text(el.name); - } - slink.attr('href', el.url); - slink.attr('title', el.name); - services.append(slink); - if (el.id == ACTIVE_MENU) { - slink.addClass("active"); - } - }); - - var USERNAME, LOGGED_IN; - var authcookie = cookie(COOKIE_NAME); - var anonymous = {'user': 'Login...', 'logged_in': false}; - - if (authcookie && authcookie.indexOf("|") > -1) { - USER_DATA.logged_in = true; - USER_DATA.user = authcookie.split("|")[0]; - } else { - USER_DATA = anonymous; - } - - USERNAME = USER_DATA.user; - LOGGED_IN = USER_DATA.logged_in; - - // clear username - USERNAME = USERNAME.replace(/\\'/g,''); - USERNAME = USERNAME.replace(/\"/g,''); - - var user = $('
'); - var username = $('
'); - username.text(USERNAME); + $.getJSON('/im/get_services/', function(data) { + $.each(data, function(i, el){ + var slink = $(""); + if (el.icon) { + slink.append($('')); + } else { + slink.text(el.name); + } + slink.attr('href', el.url); + slink.attr('title', el.name); + services.append(slink); + if (el.id == ACTIVE_MENU) { + slink.addClass("active"); + } + }); + }); // create profile links + var user = $('
'); + var username = $('
'); var usermenu = $("