* 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.
* 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).
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
==================== ========= ==================
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..."}]
+
+
+
+
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:
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
# 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
*/
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
var services = $('<div class="services"></div>');
var profile = $('<div class="profile"></div>');
-
// create services links and set the active class to the current service
- $.each(SERVICES_LINKS, function(i, el){
- var slink = $("<a>");
- if (el.icon) {
- slink.append($('<img src="'+cssloc+el.icon+'"/>'));
- } 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 = $('<div class="user"></div>');
- var username = $('<a href="#"></a>');
- username.text(USERNAME);
+ $.getJSON('/im/get_services/', function(data) {
+ $.each(data, function(i, el){
+ var slink = $("<a>");
+ if (el.icon) {
+ slink.append($('<img src="'+cssloc+el.icon+'"/>'));
+ } 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 = $('<div class="user"></div>');
+ var username = $('<a href="#"></a>');
var usermenu = $("<ul>");
- $.each(PROFILE_LINKS, function(i,el) {
- if (!LOGGED_IN && el.auth) { return }
- if (LOGGED_IN && !el.auth) { return }
- var li = $("<li />");
- var link = $("<a />");
- link.text(el.name);
- link.attr({href:el.url});
- li.append(link);
- if (el.visible == false) {
- li.hide();
- }
- usermenu.append(li);
+ $.getJSON('/im/get_menu/?location='.concat(window.location.toString()), function(data) {
+ $.each(data, function(i,el) {
+ if (i == 0){
+ username.text(el.name);
+ username.attr('href', el.url);
+ }else{
+ var link = $("<a />");
+ link.text(el.name);
+ link.attr({href:el.url});
+ var li = $("<li />");
+ li.append(link);
+ usermenu.append(li);
+ }
+ });
});
-
+
//profile.filter(".user a").attr("href",
//profile.find("li a").get(0).attr("href"))
-
-
user.append(username);
user.append(usermenu);
profile.append(user);
url(r'^local/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$',
'password_reset_confirm'),
url(r'^local/password/reset/complete/$', 'password_reset_complete'),
- url(r'^password/?$', 'password_change', {'post_change_redirect':'profile'})
+ url(r'^password/?$', 'password_change', {'post_change_redirect':'profile'}, name='password_change')
)
if INVITATIONS_ENABLED:
)
urlpatterns += patterns('astakos.im.api',
- url(r'^authenticate/?$', 'authenticate')
+ url(r'^authenticate/?$', 'authenticate'),
+ url(r'^get_services/?$', 'get_services'),
+ url(r'^get_menu/?$', 'get_menu'),
)