Commit 4887b310 authored by Sofia Papagiannaki's avatar Sofia Papagiannaki

merge with origin 0.6.4

parent a5001143
......@@ -6,16 +6,51 @@ next
- Setting ASTAKOS_DEFAULT_ADMIN_EMAIL has been deprecated. Use ADMINS django setting instead.
- Setting ASTAKOS_DEFAULT_FROM_EMAIL has been deprecated. Use SERVER_EMAIL django setting instead.
0.7.3
^^^^
v0.7.5
^^^^^^
- Include user email in registered/activated notification mails subject
v0.7.4
^^^^^^
- Configurable subjects for all emails send by astakos app. Introduced settings
* ASTAKOS_INVITATION_EMAIL_SUBJECT
* ASTAKOS_GREETING_EMAIL_SUBJECT
* ASTAKOS_FEEDBACK_EMAIL_SUBJECT
* ASTAKOS_VERIFICATION_EMAIL_SUBJECT
* ASTAKOS_ADMIN_NOTIFICATION_EMAIL_SUBJECT
* ASTAKOS_HELPDESK_NOTIFICATION_EMAIL_SUBJECT
* ASTAKOS_EMAIL_CHANGE_EMAIL_SUBJECT
* ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT
v0.7.3
^^^^^^
- Use https for google webfonts
- Fix anonymoususer logout
v0.7.1
^^^^^^
- ASTAKOS_*_MESSAGES settings changed from dict to tuple lists
- Theme changes (new colors, new font)
v0.7.0
^^^^^^
- Rename management commands
- Optionally renew token on password change
- Preserve local password for users switched to shibboleth
- Send notification to DEFAULT_CONTACT_EMAIL on account activation
- Send notification to ASTAKOS_DEFAULT_CONTACT_EMAIL on account activation
- Fix unusable password issue
- Extend user_update command by enabling provider modification and password renewal
- Check for email absence before querying the database for retrieving the user in get menu call
- Set is_verified in profile view even if the user do not post the form
- New html/css theme
- Database updated.
Use::
$ snf-manage syncdb
$ snf-manage migrate
to migrate your database.
v0.6.2
^^^^^^
......
......@@ -108,4 +108,4 @@ showuser Show user info
To update user credibility from the billing system (Aquarium), enable the queue, install snf-pithos-tools and use ``pithos-dispatcher``::
pithos-dispatcher --exchange=aquarium --callback=astakos.im.endpoints.aquarium.consumer.on_creditevent
\ No newline at end of file
pithos-dispatcher --exchange=aquarium --callback=astakos.im.endpoints.aquarium.consumer.on_creditevent
......@@ -62,8 +62,21 @@ def media(request):
def custom_messages(request):
EXTRA_MESSAGES_SET = bool(GLOBAL_MESSAGES or SIGNUP_MESSAGES or
LOGIN_MESSAGES or PROFILE_MESSAGES)
global GLOBAL_MESSAGES, SIGNUP_MESSAGES, LOGIN_MESSAGES, PROFILE_MESSAGES
# keep backwards compatibility with dict settings
if type(GLOBAL_MESSAGES) == dict:
GLOBAL_MESSAGES = GLOBAL_MESSAGES.items()
if type(SIGNUP_MESSAGES) == dict:
SIGNUP_MESSAGES = SIGNUP_MESSAGES.items()
if type(LOGIN_MESSAGES) == dict:
LOGIN_MESSAGES = LOGIN_MESSAGES.items()
if type(PROFILE_MESSAGES) == dict:
PROFILE_MESSAGES = PROFILE_MESSAGES.items()
EXTRA_MESSAGES_SET = bool(GLOBAL_MESSAGES or SIGNUP_MESSAGES or \
LOGIN_MESSAGES or PROFILE_MESSAGES)
return {
'GLOBAL_MESSAGES': GLOBAL_MESSAGES,
'SIGNUP_MESSAGES': SIGNUP_MESSAGES,
......
......@@ -55,6 +55,7 @@ from astakos.im.settings import (INVITATIONS_PER_LEVEL, BASEURL, SITENAME,
RECAPTCHA_PRIVATE_KEY, RECAPTCHA_ENABLED, DEFAULT_CONTACT_EMAIL,
LOGGING_LEVEL
)
from astakos.im.widgets import DummyWidget, RecaptchaWidget
from astakos.im.functions import send_change_email
......@@ -176,7 +177,7 @@ class InvitedLocalUserCreationForm(LocalUserCreationForm):
ro = ('email', 'username',)
for f in ro:
self.fields[f].widget.attrs['readonly'] = True
def save(self, commit=True):
user = super(InvitedLocalUserCreationForm, self).save(commit=False)
level = user.invitation.inviter.level + 1
......@@ -193,7 +194,7 @@ class ThirdPartyUserCreationForm(forms.ModelForm):
model = AstakosUser
fields = ("email", "first_name", "last_name",
"third_party_identifier", "has_signed_terms")
def __init__(self, *args, **kwargs):
"""
Changes the order of fields, and removes the username field.
......@@ -218,7 +219,7 @@ class ThirdPartyUserCreationForm(forms.ModelForm):
% (reverse('latest_terms'), _("the terms"))
self.fields['has_signed_terms'].label = \
mark_safe("I agree with %s" % terms_link_html)
def clean_email(self):
email = self.cleaned_data['email']
if not email:
......@@ -273,7 +274,7 @@ class InvitedThirdPartyUserCreationForm(ThirdPartyUserCreationForm):
class ShibbolethUserCreationForm(ThirdPartyUserCreationForm):
additional_email = forms.CharField(
widget=forms.HiddenInput(), label='', required=False)
def __init__(self, *args, **kwargs):
super(ShibbolethUserCreationForm, self).__init__(*args, **kwargs)
self.fields.keyOrder.append('additional_email')
......@@ -282,7 +283,7 @@ class ShibbolethUserCreationForm(ThirdPartyUserCreationForm):
field = self.fields[name]
self.initial['additional_email'] = self.initial.get(name,
field.initial)
def clean_email(self):
email = self.cleaned_data['email']
for user in AstakosUser.objects.filter(email=email):
......@@ -304,7 +305,7 @@ class LoginForm(AuthenticationForm):
recaptcha_challenge_field = forms.CharField(widget=DummyWidget)
recaptcha_response_field = forms.CharField(
widget=RecaptchaWidget, label='')
def __init__(self, *args, **kwargs):
was_limited = kwargs.get('was_limited', False)
request = kwargs.get('request', None)
......@@ -322,7 +323,7 @@ class LoginForm(AuthenticationForm):
if was_limited and RECAPTCHA_ENABLED:
self.fields.keyOrder.extend(['recaptcha_challenge_field',
'recaptcha_response_field', ])
def clean_recaptcha_response_field(self):
if 'recaptcha_challenge_field' in self.cleaned_data:
self.validate_captcha()
......@@ -340,7 +341,7 @@ class LoginForm(AuthenticationForm):
if not check.is_valid:
raise forms.ValidationError(
_('You have not entered the correct words'))
def clean(self):
super(LoginForm, self).clean()
if self.user_cache and self.user_cache.provider not in ('local', ''):
......
......@@ -195,7 +195,7 @@ def send_greeting(user, email_template_name='im/welcome_email.txt'):
Raises SMTPException, socket.error
"""
subject = _('Welcome to %s alpha2 testing' % SITENAME)
subject = _(GREETING_EMAIL_SUBJECT)
message = render_to_string(email_template_name, {
'user': user,
'url': urljoin(BASEURL, reverse('index')),
......@@ -214,7 +214,7 @@ def send_greeting(user, email_template_name='im/welcome_email.txt'):
def send_feedback(msg, data, user, email_template_name='im/feedback_mail.txt'):
subject = _("Feedback from %s alpha2 testing" % SITENAME)
subject = _(FEEDBACK_EMAIL_SUBJECT)
from_email = user.email
recipient_list = [DEFAULT_CONTACT_EMAIL]
content = render_to_string(email_template_name, {
......
......@@ -69,19 +69,19 @@ RE_USER_EMAIL_PATTERNS = getattr(
# Messages to display on login page header
# e.g. {'warning': 'This warning message will be displayed on the top of login page'}
LOGIN_MESSAGES = getattr(settings, 'ASTAKOS_LOGIN_MESSAGES', {})
LOGIN_MESSAGES = getattr(settings, 'ASTAKOS_LOGIN_MESSAGES', [])
# Messages to display on login page header
# e.g. {'warning': 'This warning message will be displayed on the top of signup page'}
SIGNUP_MESSAGES = getattr(settings, 'ASTAKOS_SIGNUP_MESSAGES', {})
SIGNUP_MESSAGES = getattr(settings, 'ASTAKOS_SIGNUP_MESSAGES', [])
# Messages to display on login page header
# e.g. {'warning': 'This warning message will be displayed on the top of profile page'}
PROFILE_MESSAGES = getattr(settings, 'ASTAKOS_PROFILE_MESSAGES', {})
PROFILE_MESSAGES = getattr(settings, 'ASTAKOS_PROFILE_MESSAGES', [])
# Messages to display on all pages
# e.g. {'warning': 'This warning message will be displayed on the top of every page'}
GLOBAL_MESSAGES = getattr(settings, 'ASTAKOS_GLOBAL_MESSAGES', {})
GLOBAL_MESSAGES = getattr(settings, 'ASTAKOS_GLOBAL_MESSAGES', [])
# messages to display as extra actions in account forms
# e.g. {'https://cms.okeanos.grnet.gr/': 'Back to ~okeanos'}
......@@ -107,3 +107,21 @@ QUOTA_HOLDER_URL = getattr(settings, 'ASTAKOS_QUOTA_HOLDER_URL', '')
# Set the billing URI
AQUARIUM_URL = getattr(settings, 'ASTAKOS_AQUARIUM_URL', '')
# Configurable email subjects
INVITATION_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_INVITATION_EMAIL_SUBJECT',
'Invitation to %s alpha2 testing' % SITENAME)
GREETING_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_GREETING_EMAIL_SUBJECT',
'Welcome to %s alpha2 testing' % SITENAME)
FEEDBACK_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_FEEDBACK_EMAIL_SUBJECT',
'Feedback from %s alpha2 testing' % SITENAME)
VERIFICATION_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_VERIFICATION_EMAIL_SUBJECT',
'%s alpha2 testing account activation is needed' % SITENAME)
ADMIN_NOTIFICATION_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_ADMIN_NOTIFICATION_EMAIL_SUBJECT',
'%s alpha2 testing account created (%%(user)s)' % SITENAME)
HELPDESK_NOTIFICATION_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_HELPDESK_NOTIFICATION_EMAIL_SUBJECT',
'%s alpha2 testing account activated (%%(user)s)' % SITENAME)
EMAIL_CHANGE_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_EMAIL_CHANGE_EMAIL_SUBJECT',
'Email change on %s alpha2 testing' % SITENAME)
PASSWORD_RESET_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT',
'Password reset on %s alpha2 testing' % SITENAME)
......@@ -48,11 +48,11 @@ Example
.. codeblock:: javascript
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
var CLOUDBAR_COOKIE_NAME = '_pithos2_a';
var CLOUDBAR_ACTIVE_SERVICE = 'cloud';
var CLOUDBAR_LOCATION = "http://accounts.cloud.grnet.gr/cloudbar/";
var CLOUDBAR_LOCATION = "https://accounts.cloud.grnet.gr/cloudbar/";
$(document).ready(function(){
$.getScript(CLOUDBAR_LOC + 'cloudbar.js');
......
......@@ -44,7 +44,7 @@ $(document).ready(function(){
}
var root = $('body');
var bar = $('<div class="cloudbar clearfix"></div>');
var bar = $('<div class="cloudbar servicesbar clearfix"></div>');
var services = $('<ul class="services"></ul>');
var profile = $('<div class="profile"></div>');
......
......@@ -30,6 +30,12 @@ img.right { margin:0 0 1em 1em; float:right;}
.top-msg +.mainlogo { margin-top:-73px;}
.top-msg .close { position:absolute; bottom:20px; right:20px; font-size:1.3em; font-weight:bold; border:0 none; color:#fff; text-decoration:none;}
.top-msg .close:hover { color:#000;}
.top-msg.success { background-color:#77C596; color: #fff}
.top-msg.error { background-color:#EF4F54; color: #fff}
.top-msg.warning { background-color:#F6921E; color: #fff}
.top-msg.info { background-color:#C3C3B9; color: #fff}
.top-msg.warning a { color: #3582AC}
.top-msg.info a { color: #222}
/* container */
.container .wrapper { padding-bottom:100px;}
......@@ -317,6 +323,7 @@ dl.alt-style dt:nth-child(2n) { background:black; }
.billing .resource-cat-2.filter-item a:hover { color:#4085A5 }
.table_sorting tr th { cursor:pointer; }
.table_sorting tr th:hover { text-decoration:underline }
table.alt-style tr.tr1 td,
......@@ -330,4 +337,4 @@ table.alt-style tr td a.more-info:hover { background-image:url(../images/plus-
table.alt-style tr td a.open { background-position:-16px 0}
.projects .details a.edit { float:right; }
.projects .editable form textarea { width:70%; height:50px; max-width:70%;}
.projects .editable form textarea { width:70%; height:50px; max-width:70%;}
\ No newline at end of file
......@@ -116,34 +116,10 @@ $(document).ready(function() {
$('select').dropkick();
$('.top-msg .success').parents('.top-msg').css(
{
backgroundColor: '#77C596',
color: '#fff'
}
);
$('.top-msg .error').parents('.top-msg').css(
{
backgroundColor: '#EF4F54',
color: '#fff'
}
);
$('.top-msg .warning').parents('.top-msg').css(
{
backgroundColor: '#F6921E',
color: '#fff'
}
);
$('.top-msg .info').parents('.top-msg').css(
{
backgroundColor: '#C3C3B9',
color: '#fff'
}
);
$('.top-msg .success').parents('.top-msg').addClass('success');
$('.top-msg .error').parents('.top-msg').addClass('error');
$('.top-msg .warning').parents('.top-msg').addClass('warning');
$('.top-msg .info').parents('.top-msg').addClass('info');
// clouds homepage animation
$('#animation a').hover(
......@@ -227,4 +203,4 @@ $(window).resize(function() {
$('.widjets li div').equalHeights();
}
});
\ No newline at end of file
});
\ No newline at end of file
{% extends "im/base.html" %}
{% block extra_messages %}
{% if not messages %}
{% for msg_type, msg in GLOBAL_MESSAGES.items %}
<div class="{{ msg_type }}">{{ msg|safe }}</div>
{% endfor %}
{% for msg_type, msg in PROFILE_MESSAGES.items %}
<div class="{{ msg_type }}">{{ msg|safe }}</div>
{% endfor %}
{% endif %}
{% endblock %}
{% load filters %}
{% block page.title %}Profile{% endblock %}
......
<!doctype html>
{% load astakos_tags %}<!doctype html>
<head>
{% block starthead %}{% endblock starthead %}
<meta charset="UTF-8">
......@@ -77,20 +77,12 @@
<body>
<div class="container">
<div class="wrapper">
{% if messages or EXTRA_MESSAGES_SET %}
<div class="top-msg active">
{% block extra_messages %}{% endblock %}
{% for message in messages %}
<div{% if message.tags %}
class="msg {{ message.tags }}"{% endif %}>
{{ message|safe }}</div>
{% endfor %}
<a href="#" title="close" class="close">X</a>
</div>
{% endif %}
<div class="wrapper">
{% display_messages %}
<div class="mainlogo">
<a href="/im/">
<a href="{% url astakos.im.views.index %}">
<img src="{{ IM_STATIC_URL }}images/accounts-logo.png" alt="accounts" />
</a>
</div>
......
{% extends 'im/base_two_cols.html'%}
{% block extra_messages %}
{% if not messages %}
{% for msg_type, msg in GLOBAL_MESSAGES.items %}
<li class="{{ msg_type }}">{{ msg|safe }}</li>
{% endfor %}
{% for msg_type, msg in LOGIN_MESSAGES.items %}
<li class="{{ msg_type }}">{{ msg|safe }}</li>
{% endfor %}
{% endif %}
{% endblock %}
{% block signup_class %}hidden{% endblock %}
{% block page.title %}{% endblock %}
......@@ -58,4 +47,4 @@
</div>
{% endblock body.signup %}
{% endblock body.right%}
\ No newline at end of file
{% endblock body.right%}
{% extends 'im/base_two_cols.html' %}
{% block extra_messages %}
{% if not messages %}
{% for msg_type, msg in GLOBAL_MESSAGES.items %}
<li class="{{ msg_type }}">{{ msg|safe }}</li>
{% endfor %}
{% for msg_type, msg in SIGNUP_MESSAGES.items %}
<li class="{{ msg_type }}">{{ msg|safe }}</li>
{% endfor %}
{% endif %}
{% endblock %}
{% block page.title %}
Signup
{% endblock %}
......
from django import template
from django.core.urlresolvers import reverse, resolve
from django.conf import settings
register = template.Library()
MESSAGES_VIEWS_MAP = getattr(settings, 'ASTAKOS_MESSAGES_VIEWS_MAP', {
'astakos.im.views.index': 'LOGIN_MESSAGES',
'astakos.im.views.logout': 'LOGIN_MESSAGES',
'astakos.im.views.login': 'LOGIN_MESSAGES',
'astakos.im.views.signup': 'SIGNUP_MESSAGES',
'astakos.im.views.edit_profile': 'PROFILE_MESSAGES',
'astakos.im.views.change_password': 'PROFILE_MESSAGES',
'astakos.im.views.invite': 'PROFILE_MESSAGES',
'astakos.im.views.feedback': 'PROFILE_MESSAGES',
})
@register.tag(name='display_messages')
def display_messages(parser, token):
return MessagesNode()
class DummyMessage(object):
def __init__(self, type, msg):
self.message = msg
self.tags = type
def __repr__(self):
return "%s: %s" % (self.tags, self.message)
class MessagesNode(template.Node):
def get_view_messages(self, context):
messages = list(context['GLOBAL_MESSAGES'])
try:
view = resolve(context['request'].get_full_path())[0]
view_name = "%s.%s" % (view.__module__, view.func_name)
messages += context[MESSAGES_VIEWS_MAP.get(view_name)]
return messages
except Exception, e:
return messages
def render(self, context):
if self not in context.render_context:
messages = list(context['messages'])
if context['EXTRA_MESSAGES_SET']:
view_messages = self.get_view_messages(context)
for msg_object in view_messages:
messages.append(DummyMessage(msg_object[0], msg_object[1]))
if not messages:
return ""
cls = messages[-1].tags
content = '<div class="top-msg active %s">' % cls
for msg in messages:
content += '<div class="msg %s">%s</div>' % (msg.tags, msg.message)
content += '<a href="#" title="close" class="close">X</a>'
content += '</div>'
context.render_context[self] = content
return context.render_context[self]
......@@ -68,24 +68,24 @@
#ASTAKOS_RE_USER_EMAIL_PATTERNS = []
# Messages to display on login page header
# e.g. {'warning': 'This warning message will be displayed on the top of login page'}
#ASTAKOS_LOGIN_MESSAGES = {}
# e.g. [('warning', 'This warning message will be displayed on the top of login page')]
#ASTAKOS_LOGIN_MESSAGES = []
# Messages to display on signup page header
# e.g. {'warning': 'This warning message will be displayed on the top of signup page'}
#ASTAKOS_SIGNUP_MESSAGES = {}
# e.g. [('warning', 'This warning message will be displayed on the top of signup page')]
#ASTAKOS_SIGNUP_MESSAGES = []
# Messages to display on profile page header
# e.g. {'warning': 'This warning message will be displayed on the top of profile pages'}
#ASTAKOS_PROFILE_MESSAGES = {}
# e.g. [('warning', 'This warning message will be displayed on the top of profile pages')]
#ASTAKOS_PROFILE_MESSAGES = []
# Messages to display on global page header
# e.g. {'warning': 'This warning message will be displayed on the top of all pages'}
#ASTAKOS_GLOBAL_MESSAGES = {}
# e.g. [('warning', 'This warning message will be displayed on the top of all pages')]
#ASTAKOS_GLOBAL_MESSAGES = []
# messages to display as extra actions in account forms
# e.g. {'https://cms.okeanos.grnet.gr/': 'Back to ~okeanos'}
#ASTAKOS_PROFILE_EXTRA_LINKS = {}
#ASTAKOS_PROFILE_EXTRA_LINKS = []
# The number of unsuccessful login requests per minute allowed for a specific email
#ASTAKOS_RATELIMIT_RETRIES_ALLOWED = 3
......@@ -104,4 +104,15 @@
#ASTAKOS_QUOTA_HOLDER_URL = ''
# Set the billing URI
#ASTAKOS_AQUARIUM_URL = ''
\ No newline at end of file
#ASTAKOS_AQUARIUM_URL = ''
# Email subjects configuration. For admin/helper notification emails %(user)s
# maps to registered/activated user email.
#ASTAKOS_INVITATION_EMAIL_SUBJECT = 'Invitation to %s alpha2 testing' % SITENAME
#ASTAKOS_GREETING_EMAIL_SUBJECT = 'Welcome to %s alpha2 testing' % SITENAME
#ASTAKOS_FEEDBACK_EMAIL_SUBJECT = 'Feedback from %s alpha2 testing' % SITENAME
#ASTAKOS_VERIFICATION_EMAIL_SUBJECT = '%s alpha2 testing account activation is needed' % SITENAME
#ASTAKOS_ADMIN_NOTIFICATION_EMAIL_SUBJECT = '%s alpha2 testing account created (%%(user)s)' % SITENAME
#ASTAKOS_HELPDESK_NOTIFICATION_EMAIL_SUBJECT = '%s alpha2 testing account activated (%%(user)s)' % SITENAME
#ASTAKOS_EMAIL_CHANGE_EMAIL_SUBJECT = 'Email change on %s alpha2 testing' % SITENAME
#ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT = 'Password reset on %s alpha2 testing' % SITENAME
\ No newline at end of file
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