integration with aquarium: Progress III & merge master
authorSofia Papagiannaki <papagian@gmail.com>
Mon, 5 Mar 2012 09:52:53 +0000 (11:52 +0200)
committerSofia Papagiannaki <papagian@gmail.com>
Mon, 5 Mar 2012 09:52:53 +0000 (11:52 +0200)
Refs: #1824

15 files changed:
snf-astakos-app/Changelog
snf-astakos-app/README
snf-astakos-app/astakos/im/api.py
snf-astakos-app/astakos/im/backends.py
snf-astakos-app/astakos/im/models.py
snf-astakos-app/astakos/im/settings.py
snf-astakos-app/astakos/im/static/im/cloudbar/cloudbar.css
snf-astakos-app/astakos/im/static/im/cloudbar/cloudbar.less
snf-astakos-app/astakos/im/static/im/css/styles.css
snf-astakos-app/astakos/im/static/im/css/styles.less
snf-astakos-app/astakos/im/static/im/less/xtra.less
snf-astakos-app/astakos/im/templates/im/login.html
snf-astakos-app/astakos/im/urls.py
snf-astakos-app/astakos/im/views.py
snf-astakos-app/conf/20-snf-astakos-app-settings.conf

index f809174..2088c8d 100644 (file)
@@ -1,3 +1,12 @@
+v0.3.2
+======
+
+- improved styles of sign up button
+- do not send admin notification email if ASTAKOS_DEFAULT_ADMIN_EMAIL is not 
+  set 
+- updated cloudbar styles
+
+
 v0.3.1
 ======
 
index 92235da..f639196 100644 (file)
@@ -62,10 +62,17 @@ ASTAKOS_MODERATION_ENABLED          True
 ASTAKOS_BASEURL                     \http://pithos.dev.grnet.gr                                                     Astakos baseurl
 ASTAKOS_SITENAME                    GRNET Cloud                                                                     Service name that appears in emails
 ASTAKOS_CLOUD_SERVICES              ({'icon': 'home-icon.png', 'id': 'cloud', 'name': 'grnet cloud', 'url': '/'},   Cloud services appear in the horizontal bar
-                                    {'id': 'okeanos', 'name': '~okeanos', 'url': '/okeanos.html'},                  
+                                    {'id': 'okeanos', 'name': 'cyclades', 'url': '/okeanos.html'},                  
                                     {'id': 'pithos', 'name': 'pithos+', 'url': '/ui/'})                             
 ASTAKOS_RECAPTCHA_PUBLIC_KEY                                                                                        Recaptcha public key obtained after registration here: http://recaptcha.net
 ASTAKOS_RECAPTCHA_PRIVATE_KEY                                                                                       Recaptcha private key obtained after registration here: http://recaptcha.net
+ASTAKOS_RECAPTCHA_OPTIONS           {'theme': 'white'}                                                              Options for customizing reCAPTCHA look and feel
+                                                                                                                    (see: http://code.google.com/intl/el-GR/apis/recaptcha/docs/customization.html)
+ASTAKOS_LOGOUT_NEXT                                                                                                 Where the user should be redirected after logout
+                                                                                                                    (if not set and no next parameter is defined it renders login page with message)
+ASTAKOS_BILLING_FIELDS              ['id', 'is_active', 'provider', 'third_party_identifier']                       AstakosUser fields to propagate in the billing system
+ASTAKOS_QUEUE_CONNECTION                                                                                            The queue connection ex. 'rabbitmq://guest:guest@localhost:5672/astakos.userEvent.#'
+                                                                                                                    (if it is not set, it does not send messages)
 ==============================      =============================================================================   ===========================================================================================
 
 Administrator functions
index 4df9f84..d321046 100644 (file)
@@ -31,6 +31,8 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
+import logging
+
 from traceback import format_exc
 from time import time, mktime
 from urllib import quote
@@ -45,6 +47,8 @@ from astakos.im.faults import BadRequest, Unauthorized, InternalServerError
 from astakos.im.models import AstakosUser
 from astakos.im.settings import CLOUD_SERVICES, INVITATIONS_ENABLED
 
+logger = logging.getLogger(__name__)
+
 def render_fault(request, fault):
     if isinstance(fault, InternalServerError) and settings.DEBUG:
         fault.details = format_exc(fault)
@@ -94,6 +98,7 @@ def authenticate(request):
         response['Content-Length'] = len(response.content)
         return response
     except BaseException, e:
+        logger.exception(e)
         fault = InternalServerError('Unexpected error')
         return render_fault(request, fault)
 
@@ -119,23 +124,23 @@ def get_menu(request):
     index_url = absolute(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..."}]
+    l = [{ 'url': index_url, 'name': "Sign in"}]
     if request.user.is_authenticated():
         l = []
         l.append({ 'url': absolute(reverse('astakos.im.views.edit_profile')),
                   'name': request.user.email})
         l.append({ 'url': absolute(reverse('astakos.im.views.edit_profile')),
-                  'name': "view your profile..." })
+                  'name': "View your profile" })
         if request.user.password:
             l.append({ 'url': absolute(reverse('password_change')),
-                      'name': "change your password..." })
+                      'name': "Change your password" })
         if INVITATIONS_ENABLED:
             l.append({ 'url': absolute(reverse('astakos.im.views.invite')),
-                      'name': "invite some friends..." })
+                      'name': "Invite some friends" })
         l.append({ 'url': absolute(reverse('astakos.im.views.send_feedback')),
-                  'name': "feedback..." })
+                  'name': "Send feedback" })
         l.append({ 'url': absolute(reverse('astakos.im.views.logout')),
-                  'name': "logout..."})
+                  'name': "Sign out"})
 
     callback = request.GET.get('callback', None)
     data = json.dumps(tuple(l))
index fd69927..12e7037 100644 (file)
@@ -164,7 +164,10 @@ class InvitationsBackend(object):
                 message = _('Registration completed. You can now login.')
             else:
                 _send_notification(user, admin_email_template_name)
-                message = _('Registration completed. You will receive an email upon your account\'s activation.')
+                message = _('Your request for an account was successfully sent \
+                            and pending approval from our administrators. You \
+                            will be notified by email the next days. \
+                            Thanks for being patient, the GRNET team')
             status = messages.SUCCESS
         except Invitation.DoesNotExist, e:
             status = messages.ERROR
@@ -233,7 +236,10 @@ class SimpleBackend(object):
         if MODERATION_ENABLED:
             try:
                 _send_notification(user, admin_email_template_name)
-                message = _('Registration completed. You will receive an email upon your account\'s activation.')
+                message = _('Your request for an account was successfully sent \
+                            and pending approval from our administrators. You \
+                            will be notified by email the next days. \
+                            Thanks for being patient, the GRNET team')
             except (SMTPException, socket.error) as e:
                 status = messages.ERROR
                 name = 'strerror'
index de79fd7..d004b09 100644 (file)
@@ -41,7 +41,7 @@ from base64 import b64encode
 from django.db import models
 from django.contrib.auth.models import User, UserManager
 
-from astakos.im.settings import DEFAULT_USER_LEVEL, INVITATIONS_PER_LEVEL, AUTH_TOKEN_DURATION, BILLING_FIELDS, QUEUE_EXCHANGE
+from astakos.im.settings import DEFAULT_USER_LEVEL, INVITATIONS_PER_LEVEL, AUTH_TOKEN_DURATION, BILLING_FIELDS, QUEUE_CONNECTION
 from synnefo.lib.queue import exchange_connect, exchange_send, exchange_close, Receipt
 
 QUEUE_CLIENT_ID = 3 # Astakos.
@@ -162,12 +162,12 @@ def report_user_event(user):
                 return True
         return False
     
-    if QUEUE_EXCHANGE and should_send(user):
+    if QUEUE_CONNECTION and should_send(user):
         l = [[elem, str(user.__getattribute__(elem))] for elem in BILLING_FIELDS]
         details = dict(l)
         details['eventType'] = 'create' if not user.id else 'modify'
         body = Receipt(QUEUE_CLIENT_ID, user.email, '', 0, details).format()
-        conn = exchange_connect(QUEUE_EXCHANGE)
-        routing_key = QUEUE_EXCHANGE.replace('#', body['id'])
+        conn = exchange_connect(QUEUE_CONNECTION)
+        routing_key = QUEUE_CONNECTION.replace('#', body['id'])
         exchange_send(conn, routing_key, body)
         exchange_close(conn)
\ No newline at end of file
index 8706231..8d9c400 100644 (file)
@@ -50,7 +50,7 @@ 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':'/okeanos.html', 'name':'cyclades', 'id':'okeanos' },
         { 'url':'/ui/', 'name':'pithos+', 'id':'pithos' }))
 
 # Set recaptcha keys
@@ -62,4 +62,7 @@ RECAPTCHA_OPTIONS = getattr(settings, 'ASTAKOS_RECAPTCHA_OPTIONS', {'theme': 'wh
 BILLING_FIELDS = getattr(settings, 'ASTAKOS_BILLING_FIELDS', ['id', 'is_active', 'provider', 'third_party_identifier'])
 
 # Queue for billing.
-QUEUE_EXCHANGE = getattr(settings, 'ASTAKOS_QUEUE_EXCHANGE', None) # Example: 'rabbitmq://guest:guest@localhost:5672/astakos.userEvent.#'
\ No newline at end of file
+QUEUE_CONNECTION = getattr(settings, 'ASTAKOS_QUEUE_CONNECTION', None) # Example: 'rabbitmq://guest:guest@localhost:5672/astakos.userEvent.#'
+
+# Set where the user should be redirected after logout
+LOGOUT_NEXT = getattr(settings, 'ASTAKOS_LOGOUT_NEXT', '')
\ No newline at end of file
index efec625..baf2efa 100644 (file)
@@ -5,7 +5,7 @@
  * Snippets of reusable CSS to develop faster and keep code readable
  * ----------------------------------------------------------------- */
 .servicesbar {
-  font-family: arial, sans-serif;
+  font-family: arial, sans-serif !important;
   font-size: 13px !important;
   line-height: 13px;
   letter-spacing: 0px;
@@ -35,7 +35,8 @@
 }
 .servicesbar a {
   border: none !important;
-  font-size: inherit !important;
+  font-family: arial, sans-serif !important;
+  font-size: 13px !important;
   color: #e6e6e6;
   text-decoration: none;
   display: block;
@@ -48,6 +49,7 @@
 }
 .servicesbar a.active {
   font-weight: bold;
+  font-size: 13px !important;
   background-color: #333;
 }
 .servicesbar a img {
 .servicesbar .services:after {
   clear: both;
 }
+.servicesbar .services a {
+  font-size: 13px !important;
+  font-weight: bold;
+  color: #ccc;
+}
+.servicesbar .services a.active {
+  font-size: 13px !important;
+  color: #ffffff !important;
+}
+.servicesbar .services a:hover {
+  background-color: #444;
+}
 .servicesbar .profile {
   margin-top: -35px;
   zoom: 1;
 .servicesbar .profile:after {
   clear: both;
 }
+.servicesbar .profile .user > a {
+  font-weight: bold !important;
+  font-size: 12px !important;
+}
 .servicesbar .profile a {
   float: none;
 }
index 90a3e9e..4bf8d19 100644 (file)
@@ -10,7 +10,7 @@
     // mini reset
     ol, ul { list-style:none; margin:0; padding:0;}
     li {margin:0; padding:0;}
-    font-family: arial, sans-serif;
+    font-family: arial, sans-serif !important;
     font-size: 13px !important;
     line-height: 13px;
     letter-spacing: 0px;
@@ -23,7 +23,8 @@
 
     a {
         border: none !important;
-        font-size: inherit !important;
+        font-family: arial, sans-serif !important;
+        font-size: 13px !important;
         color: @toolbarColor;    
         text-decoration: none;
         display: block;
@@ -35,6 +36,7 @@
         }
         &.active {
             font-weight: bold;
+            font-size: 13px !important;
             background-color: #333;
         }
 
 
     .services {
         .clearfix();
+
+        a {
+            font-size: 13px !important;
+            font-weight: bold;
+            color: #ccc;
+
+            &.active {
+                font-size: 13px !important;    
+                color: @white !important;
+            }
+            &:hover {
+                background-color: #444;
+            }
+        }
     }    
 
     position: relative;
         text-align: right;
         min-width: 200px;
         width: 200px;
+
+        .user {
+            &> a {
+                font-weight: bold !important;
+                font-size: 12px !important;
+            }    
+        }
         a {
                     float: none;
         }
index 9525ca8..610ebd1 100644 (file)
@@ -194,7 +194,16 @@ textarea {
   font-weight: normal;
   line-height: 22px;
   letter-spacing: 1px;
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
   background-color: #3582ac;
+  -webkit-transition: background-color 0.15s linear;
+  transition: background-color 0.15s linear;
+  -webkit-transition: background-color 0.15s linear;
+  transition: background-color 0.15s linear;
   color: #ffffff;
   border: none;
   padding: 0.8em 22px;
@@ -203,6 +212,62 @@ textarea {
 .button:hover {
   background-color: #f89a1c;
 }
+.button a {
+  color: #ffffff !important;
+  text-decoration: none !important;
+  border: none !important;
+}
+a.button {
+  color: #ffffff !important;
+  text-decoration: none !important;
+  border: none !important;
+}
+.makeRow {
+  zoom: 1;
+  margin-left: -22px;
+}
+.makeRow:before, .makeRow:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.makeRow:after {
+  clear: both;
+}
+.button {
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
+  background-color: #3582ac;
+  -webkit-transition: background-color 0.15s linear;
+  transition: background-color 0.15s linear;
+  -webkit-transition: background-color 0.15s linear;
+  transition: background-color 0.15s linear;
+  color: #ffffff;
+  border: none;
+  padding: 0.8em 22px;
+  font-size: 1em;
+}
+.button:hover {
+  background-color: #f89a1c;
+}
+.button a {
+  color: #ffffff !important;
+  text-decoration: none !important;
+  border: none !important;
+}
+a.button {
+  color: #ffffff !important;
+  text-decoration: none !important;
+  border: none !important;
+}
 /*addon to style django forms rendered with as_p filter*/
 /*
  * Tables.less
@@ -411,6 +476,11 @@ body {
   font-weight: normal;
   line-height: 22px;
   letter-spacing: 1px;
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
 }
 .topbar {
   background-color: #cfcdc7;
@@ -588,6 +658,8 @@ ul.inline li {
 .page {
   zoom: 1;
   margin-left: -22px;
+  zoom: 1;
+  margin-left: -22px;
   margin-top: 42px;
   font-size: 1.1em;
 }
@@ -599,6 +671,14 @@ ul.inline li {
 .page:after {
   clear: both;
 }
+.page:before, .page:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.page:after {
+  clear: both;
+}
 .page .page-inner {
   position: relative;
 }
@@ -617,6 +697,8 @@ ul.inline li {
 .maincol.full {
   zoom: 1;
   margin-left: -22px;
+  zoom: 1;
+  margin-left: -22px;
   margin-left: 0;
   display: inline;
   float: left;
@@ -631,6 +713,14 @@ ul.inline li {
 .maincol.full:after {
   clear: both;
 }
+.maincol.full:before, .maincol.full:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.maincol.full:after {
+  clear: both;
+}
 .appbar {
   height: 30px;
   background-color: #3582ac;
@@ -682,6 +772,11 @@ input, textarea, .form-widget {
   font-weight: normal;
   line-height: 22px;
   letter-spacing: 1px;
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
   border: 1px solid #808080;
   margin-bottom: -1px;
   padding: 0.8em;
@@ -804,6 +899,11 @@ form input[type="password"] {
   font-weight: normal;
   line-height: 22px;
   letter-spacing: 1px;
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
   border: 1px solid #808080;
   margin-bottom: -1px;
   padding: 0.8em;
@@ -824,7 +924,35 @@ form input.submit, form input[type="submit"] {
   font-weight: normal;
   line-height: 22px;
   letter-spacing: 1px;
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
+  background-color: #3582ac;
+  -webkit-transition: background-color 0.15s linear;
+  transition: background-color 0.15s linear;
+  -webkit-transition: background-color 0.15s linear;
+  transition: background-color 0.15s linear;
+  color: #ffffff;
+  border: none;
+  padding: 0.8em 22px;
+  font-size: 1em;
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
+  font-family: 'Antic', sans-serif;
+  font-size: 14px;
+  font-weight: normal;
+  line-height: 22px;
+  letter-spacing: 1px;
   background-color: #3582ac;
+  -webkit-transition: background-color 0.15s linear;
+  transition: background-color 0.15s linear;
+  -webkit-transition: background-color 0.15s linear;
+  transition: background-color 0.15s linear;
   color: #ffffff;
   border: none;
   padding: 0.8em 22px;
@@ -833,6 +961,19 @@ form input.submit, form input[type="submit"] {
 form input.submit:hover, form input[type="submit"]:hover {
   background-color: #f89a1c;
 }
+form input.submit a, form input[type="submit"] a {
+  color: #ffffff !important;
+  text-decoration: none !important;
+  border: none !important;
+}
+form input.submit:hover, form input[type="submit"]:hover {
+  background-color: #f89a1c;
+}
+form input.submit a, form input[type="submit"] a {
+  color: #ffffff !important;
+  text-decoration: none !important;
+  border: none !important;
+}
 form .with-errors input, form .with-errors textarea, form .with-errors select {
   color: #9d261d;
 }
@@ -900,6 +1041,16 @@ table tr.consumed td.consumed {
 .row {
   zoom: 1;
   margin-left: -22px;
+  zoom: 1;
+  margin-left: -22px;
+}
+.row:before, .row:after {
+  display: table;
+  content: "";
+  zoom: 1;
+}
+.row:after {
+  clear: both;
 }
 .row:before, .row:after {
   display: table;
@@ -913,11 +1064,15 @@ table tr.consumed td.consumed {
   color: #808080 !important;
   -webkit-transition: color 0.15s linear;
   transition: color 0.15s linear;
+  -webkit-transition: color 0.15s linear;
+  transition: color 0.15s linear;
 }
 .footer a {
   color: #b3b3b3;
   -webkit-transition: color 0.15s linear;
   transition: color 0.15s linear;
+  -webkit-transition: color 0.15s linear;
+  transition: color 0.15s linear;
   text-decoration: none;
 }
 .footer a:hover {
index 60468c8..4a93e29 100644 (file)
@@ -1,4 +1,5 @@
 @import "../less/bootstrap.less";
+@import "../less/xtra.less";
 @import "../less/django_forms.less";
 @import "../less/tables.less";
 
index 362ca38..6ee580b 100644 (file)
@@ -16,6 +16,7 @@
 .button {
     #font.main();
     background-color: @buttonBg;
+    .transit(background-color);
     color: @buttonColor;
     border: none;
     padding: 0.8em @gridGutterWidth;
     &:hover {
         background-color: @linkColor;    
     }
+
+    a {
+        color: @white !important;
+        text-decoration: none !important;
+        border: none !important;
+    }
+}
+
+a.button {
+    color: @white !important;
+    text-decoration: none !important;
+    border: none !important;
 }
 
 
index a7aa102..d611ad2 100644 (file)
@@ -37,9 +37,13 @@ Login
             </div>
             {% endfor %}
         </div>
-            <div class="section">
-                <a href="{% url astakos.im.views.signup %}" class="action">SIGN UP</a>
+        {% block body.signup %}
+        <div class="section signup">
+            <br /><br />
+                <h2>NEW TO OKEANOS ?</h2>
+                <a class="button" href="{% url astakos.im.views.signup %}">CREATE ACCOUNT</a>
             </div>
         </div>
+        {% endblock %}
 
 {% endblock %}
index 2e8c876..52cb118 100644 (file)
@@ -33,7 +33,7 @@
 
 from django.conf.urls.defaults import patterns, include, url
 
-from astakos.im.forms import ExtendedPasswordResetForm
+from astakos.im.forms import ExtendedPasswordResetForm, LoginForm
 from astakos.im.settings import IM_MODULES, INVITATIONS_ENABLED
 
 urlpatterns = patterns('astakos.im.views',
@@ -41,8 +41,8 @@ urlpatterns = patterns('astakos.im.views',
     url(r'^login/?$', 'index'),
     url(r'^profile/?$', 'edit_profile'),
     url(r'^feedback/?$', 'send_feedback'),
-    url(r'^signup/?$', 'signup'),
-    url(r'^logout/?$', 'logout'),
+    url(r'^signup/?$', 'signup', {'on_success':'im/login.html', 'extra_context':{'form':LoginForm()}}),
+    url(r'^logout/?$', 'logout', {'template':'im/login.html', 'extra_context':{'form':LoginForm()}}),
     url(r'^activate/?$', 'activate')
 )
 
index aae8927..31011e6 100644 (file)
@@ -55,7 +55,7 @@ from astakos.im.models import AstakosUser, Invitation
 from astakos.im.backends import get_backend
 from astakos.im.util import get_context, prepare_response, set_cookie
 from astakos.im.forms import *
-from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, COOKIE_NAME, COOKIE_DOMAIN, IM_MODULES, SITENAME, BASEURL
+from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, COOKIE_NAME, COOKIE_DOMAIN, IM_MODULES, SITENAME, BASEURL, LOGOUT_NEXT
 from astakos.im.functions import invite as invite_func
 
 logger = logging.getLogger(__name__)
@@ -246,7 +246,6 @@ def edit_profile(request, template_name='im/profile.html', extra_context={}):
                            context_instance = get_context(request,
                                                           extra_context))
 
-@requires_anonymous
 def signup(request, on_failure='im/signup.html', on_success='im/signup_complete.html', extra_context={}, backend=None):
     """
     Allows a user to create a local account.
@@ -283,6 +282,8 @@ def signup(request, on_failure='im/signup.html', on_success='im/signup_complete.
     im/signup.html or ``on_failure`` keyword argument.
     im/signup_complete.html or ``on_success`` keyword argument. 
     """
+    if request.user.is_authenticated():
+        return HttpResponseRedirect(reverse('astakos.im.views.index'))
     try:
         if not backend:
             backend = get_backend(request)
@@ -305,7 +306,7 @@ def signup(request, on_failure='im/signup.html', on_success='im/signup_complete.
                         return prepare_response(request, user, next=next)
                     messages.add_message(request, status, message)
                     return render_response(on_success,
-                           context_instance=get_context(request, extra_context))
+                                           context_instance=get_context(request, extra_context))
     except (Invitation.DoesNotExist, ValueError), e:
         messages.add_message(request, messages.ERROR, e)
         for provider in IM_MODULES:
@@ -383,6 +384,11 @@ def logout(request, template='registration/logged_out.html', extra_context={}):
         response['Location'] = next
         response.status_code = 302
         return response
+    elif LOGOUT_NEXT:
+        response['Location'] = LOGOUT_NEXT
+        response.status_code = 301
+        return response
+    messages.add_message(request, messages.SUCCESS, _('You have successfully logged out.'))
     context = get_context(request, extra_context)
     response.write(render_to_string(template, context_instance=context))
     return response
index cd8d910..a1e4f27 100644 (file)
@@ -32,6 +32,7 @@
 
 #ASTAKOS_COOKIE_NAME = '_pithos2_a'
 #ASTAKOS_COOKIE_DOMAIN = None
+#ASTAKOS_COOKIE_SECURE = True
 
 #ASTAKOS_IM_STATIC_URL = '/im/static/im/'
 
 #ASTAKOS_SITENAME = 'GRNET Cloud'
 
 # Set cloud services appear in the horizontal bar
-#ASTAKOS_CLOUD_SERVICES = getattr(settings, 'ASTAKOS_CLOUD_SERVICES', (
+#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' }))
+#        { 'url':'/ui/', 'name':'pithos+', 'id':'pithos' })
 #
 
 # Set recaptcha keys