ASTAKOS_HELPDESK_NOTIFICATION_EMAIL_SUBJECT '%s alpha2 testing account activated (%%(user)s)' % SITENAME Account activation helpdesk notification email subject
ASTAKOS_EMAIL_CHANGE_EMAIL_SUBJECT 'Email change on %s alpha2 testing' % SITENAME Email change subject
ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT 'Password reset on %s alpha2 testing' % SITENAME Password change email subject
++
+ASTAKOS_QUOTA_HOLDER_URL '' The quota holder URI
+ e.g. ``http://localhost:8080/api/quotaholder/v``
+ASTAKOS_SERVICES {'cyclades': {'url':'https://node1.example.com/ui/', 'quota': {'vm': 2}}, Cloud service default url and quota
+ 'pithos+': {'url':'https://node2.example.com/ui/', 'quota': {
+ 'diskspace': 50 * 1024 * 1024 * 1024}}})
+ASTAKOS_AQUARIUM_URL '' The billing (aquarium) URI
+ e.g. ``http://localhost:8888/user``
+ASTAKOS_PAGINATE_BY 10 Number of object to be displayed per page
++
+ ASTAKOS_NEWPASSWD_INVALIDATE_TOKEN True Enforce token renewal on password change/reset. If set to False, user can optionally decide
+ whether to renew the token or not.
=========================================== ============================================================================= ===========================================================================================
Administrator functions
from django import forms
from django.utils.translation import ugettext as _
-from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, \
- PasswordResetForm, PasswordChangeForm, SetPasswordForm
+from django.contrib.auth.forms import (UserCreationForm, AuthenticationForm,
- PasswordResetForm, PasswordChangeForm
- )
++ PasswordResetForm, PasswordChangeForm,
++ SetPasswordForm)
from django.core.mail import send_mail
from django.contrib.auth.tokens import default_token_generator
from django.template import Context, loader
from django.utils.http import int_to_base36
from django.core.urlresolvers import reverse
-from django.utils.functional import lazy
from django.utils.safestring import mark_safe
-from django.contrib import messages
from django.utils.encoding import smart_str
-
-from astakos.im.models import AstakosUser, Invitation, get_latest_terms, EmailChange
-from astakos.im.settings import INVITATIONS_PER_LEVEL, DEFAULT_FROM_EMAIL, \
- BASEURL, SITENAME, RECAPTCHA_PRIVATE_KEY, DEFAULT_CONTACT_EMAIL, \
- RECAPTCHA_ENABLED, LOGGING_LEVEL, PASSWORD_RESET_EMAIL_SUBJECT, \
- NEWPASSWD_INVALIDATE_TOKEN
+from django.forms.extras.widgets import SelectDateWidget
+from django.conf import settings
+
+from astakos.im.models import (AstakosUser, EmailChange, AstakosGroup,
+ Invitation, Membership, GroupKind, Resource,
+ get_latest_terms)
+from astakos.im.settings import (INVITATIONS_PER_LEVEL, BASEURL, SITENAME,
+ RECAPTCHA_PRIVATE_KEY, RECAPTCHA_ENABLED,
+ DEFAULT_CONTACT_EMAIL, LOGGING_LEVEL,
- PASSWORD_RESET_EMAIL_SUBJECT)
-
++ PASSWORD_RESET_EMAIL_SUBJECT,
++ NEWPASSWD_INVALIDATE_TOKEN)
from astakos.im.widgets import DummyWidget, RecaptchaWidget
from astakos.im.functions import send_change_email
user.save()
return user
+
+class AstakosGroupCreationForm(forms.ModelForm):
+ kind = forms.ModelChoiceField(
+ queryset=GroupKind.objects.all(),
+ label="",
+ widget=forms.HiddenInput()
+ )
+ name = forms.URLField()
+ moderation_enabled = forms.BooleanField(
+ help_text="Check if you want to approve members participation manually",
+ required=False
+ )
+
+ class Meta:
+ model = AstakosGroup
+
+ def __init__(self, *args, **kwargs):
+ try:
+ resources = kwargs.pop('resources')
+ except KeyError:
+ resources = {}
+ super(AstakosGroupCreationForm, self).__init__(*args, **kwargs)
+ self.fields.keyOrder = ['kind', 'name', 'homepage', 'desc', 'issue_date',
+ 'expiration_date', 'estimated_participants',
+ 'moderation_enabled']
+ for id, r in resources.iteritems():
+ self.fields['resource_%s' % id] = forms.IntegerField(
+ label=r,
+ required=False,
+ help_text=_('Leave it blank for no additional quota.')
+ )
+
+ def resources(self):
+ for name, value in self.cleaned_data.items():
+ prefix, delimiter, suffix = name.partition('resource_')
+ if suffix:
+ # yield only those having a value
+ if not value:
+ continue
+ yield (suffix, value)
+
+class AstakosGroupUpdateForm(forms.ModelForm):
+ class Meta:
+ model = AstakosGroup
+ fields = ('homepage', 'desc')
+
+class AddGroupMembersForm(forms.Form):
+ q = forms.CharField(max_length=800, widget=forms.Textarea, label=_('Search users'),
+ help_text=_('Add comma separated user emails'),
+ required=True)
+
+ def clean(self):
+ q = self.cleaned_data.get('q') or ''
+ users = q.split(',')
+ users = list(u.strip() for u in users if u)
+ db_entries = AstakosUser.objects.filter(email__in=users)
+ unknown = list(set(users) - set(u.email for u in db_entries))
+ if unknown:
+ raise forms.ValidationError(
+ _('Unknown users: %s' % ','.join(unknown)))
+ self.valid_users = db_entries
+ return self.cleaned_data
+
+ def get_valid_users(self):
+ """Should be called after form cleaning"""
+ try:
+ return self.valid_users
+ except:
+ return ()
+
+
+class AstakosGroupSearchForm(forms.Form):
+ q = forms.CharField(max_length=200, label='Search group')
+
+class TimelineForm(forms.Form):
+# entity = forms.CharField(
+# widget=forms.HiddenInput(), label='')
+ entity = forms.ModelChoiceField(
+ queryset=AstakosUser.objects.filter(is_active = True)
+ )
+ resource = forms.ModelChoiceField(
+ queryset=Resource.objects.all()
+ )
+ start_date = forms.DateTimeField()
+ end_date = forms.DateTimeField()
+ details = forms.BooleanField(required=False, label="Detailed Listing")
+ operation = forms.ChoiceField(
+ label = 'Charge Method',
+ choices = ( ('', '-------------'),
+ ('charge_usage', 'Charge Usage'),
+ ('charge_traffic', 'Charge Traffic'), )
+ )
+ def clean(self):
+ super(TimelineForm, self).clean()
+ d = self.cleaned_data
+ if 'resource' in d:
+ d['resource'] = str(d['resource'])
+ if 'start_date' in d:
+ d['start_date'] = d['start_date'].strftime("%Y-%m-%dT%H:%M:%S.%f")[:24]
+ if 'end_date' in d:
+ d['end_date'] = d['end_date'].strftime("%Y-%m-%dT%H:%M:%S.%f")[:24]
+ if 'entity' in d:
+ d['entity'] = d['entity'].email
+ return d
+
+class AstakosGroupSortForm(forms.Form):
+ sort_by = forms.ChoiceField(label='Sort by',
+ choices=(('groupname', 'Name'),
+ ('kindname', 'Type'),
+ ('issue_date', 'Issue Date'),
+ ('expiration_date', 'Expiration Date'),
+ ('approved_members_num', 'Participants'),
+ ('is_enabled', 'Status'),
+ ('moderation_enabled', 'Moderation'),
+ ('membership_status','Enrollment Status')
+ ),
+ required=False)
+
+class MembersSortForm(forms.Form):
+ sort_by = forms.ChoiceField(label='Sort by',
+ choices=(('person__email', 'User Id'),
+ ('person__first_name', 'Name'),
+ ('date_joined', 'Status')
+ ),
+ required=False)
+
+class PickResourceForm(forms.Form):
+ resource = forms.ModelChoiceField(
+ queryset=Resource.objects.select_related().all()
+ )
- resource.widget.attrs["onchange"]="this.form.submit()"
++ resource.widget.attrs["onchange"]="this.form.submit()"
++
+ class ExtendedSetPasswordForm(SetPasswordForm):
+ """
+ Extends SetPasswordForm by enabling user
+ to optionally renew also the token.
+ """
+ if not NEWPASSWD_INVALIDATE_TOKEN:
+ renew = forms.BooleanField(label='Renew token', required=False,
+ initial=True,
+ help_text='Unsetting this may result in security risk.')
+
+ def __init__(self, user, *args, **kwargs):
+ super(ExtendedSetPasswordForm, self).__init__(user, *args, **kwargs)
+
+ def save(self, commit=True):
+ user = super(ExtendedSetPasswordForm, self).save(commit=False)
+ if NEWPASSWD_INVALIDATE_TOKEN or self.cleaned_data.get('renew'):
+ try:
+ user = AstakosUser.objects.get(id=user.id)
+ except AstakosUser.DoesNotExist:
+ pass
+ else:
+ user.renew_token()
+ if commit:
+ user.save()
+ return user
PASSWORD_RESET_EMAIL_SUBJECT = getattr(settings, 'ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT',
'Password reset on %s alpha2 testing' % SITENAME)
- # 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)
-
+# Set the quota holder component URI
+QUOTA_HOLDER_URL = getattr(settings, 'ASTAKOS_QUOTA_HOLDER_URL', '')
+
+# Set the cloud service properties
+SERVICES = getattr(settings, 'ASTAKOS_SERVICES',
+ {'cyclades': {'url':'https://node1.example.com/ui/',
+ 'quota': {'vm': 2}},
+ 'pithos+': {'url':'https://node2.example.com/ui/',
+ 'quota': {'diskspace': 50 * 1024 * 1024 * 1024}}})
+
+# Set the billing URI
+AQUARIUM_URL = getattr(settings, 'ASTAKOS_AQUARIUM_URL', '')
+
+# Set how many objects should be displayed per page
- PAGINATE_BY = getattr(settings, 'ASTAKOS_PAGINATE_BY', 8)
++PAGINATE_BY = getattr(settings, 'ASTAKOS_PAGINATE_BY', 8)
++
+ # Enforce token renewal on password change/reset
+ NEWPASSWD_INVALIDATE_TOKEN = getattr(settings, 'ASTAKOS_NEWPASSWD_INVALIDATE_TOKEN', True)
from ratelimit.decorators import ratelimit
-retries = RATELIMIT_RETRIES_ALLOWED-1
-rate = str(retries)+'/m'
+retries = RATELIMIT_RETRIES_ALLOWED - 1
+rate = str(retries) + '/m'
+
+ @require_http_methods(["GET", "POST"])
@csrf_exempt
@requires_anonymous
@ratelimit(field='username', method='POST', rate=rate)
from django.contrib.auth import authenticate
from django.http import HttpResponse, HttpResponseBadRequest
from django.core.exceptions import ValidationError
+ from django.views.decorators.http import require_http_methods
-from urllib import quote
-from urlparse import urlunsplit, urlsplit, urlparse, parse_qsl
+from urlparse import urlunsplit, urlsplit, parse_qsl
from astakos.im.settings import COOKIE_NAME, COOKIE_DOMAIN
from astakos.im.util import set_cookie
logger = logging.getLogger(__name__)
+
+ @require_http_methods(["GET", "POST"])
def login(request):
"""
If there is no ``next`` request parameter redirects to astakos index page
from django.utils.translation import ugettext as _
from django.contrib import messages
from django.template import RequestContext
+ from django.views.decorators.http import require_http_methods
-from astakos.im.util import prepare_response, get_context, get_invitation
+from astakos.im.util import prepare_response, get_context
from astakos.im.views import requires_anonymous, render_response
-from astakos.im.settings import DEFAULT_USER_LEVEL
-from astakos.im.models import AstakosUser, Invitation, AdditionalMail
+from astakos.im.models import AstakosUser
from astakos.im.forms import LoginForm
from astakos.im.activation_backends import get_backend, SimpleBackend
SHIB_SESSION_ID = "HTTP_SHIB_SESSION_ID"
SHIB_MAIL = "HTTP_SHIB_MAIL"
+
+ @require_http_methods(["GET", "POST"])
@requires_anonymous
-def login(request, backend=None, on_login_template='im/login.html', on_creation_template='im/third_party_registration.html', extra_context={}):
+def login(request, backend=None, on_login_template='im/login.html',
+ on_creation_template='im/third_party_registration.html',
+ extra_context=None
+ ):
tokens = request.META
-
+
try:
eppn = tokens[Tokens.SHIB_EPPN]
except KeyError:
realname = tokens[Tokens.SHIB_NAME] + ' ' + tokens[Tokens.SHIB_SURNAME]
else:
return HttpResponseBadRequest("Missing user name in request")
-
+
affiliation = tokens.get(Tokens.SHIB_EP_AFFILIATION, '')
email = tokens.get(Tokens.SHIB_MAIL, None)
-
+
try:
- user = AstakosUser.objects.get(provider='shibboleth', third_party_identifier=eppn)
+ user = AstakosUser.objects.get(provider='shibboleth',
- third_party_identifier=eppn
- )
++ third_party_identifier=eppn)
if user.is_active:
return prepare_response(request,
user,
try:
if not backend:
backend = get_backend(request)
- form = backend.get_signup_form(provider='shibboleth', instance=user)
+ form = backend.get_signup_form(
+ provider='shibboleth', instance=user)
except Exception, e:
- form = SimpleBackend(request).get_signup_form(provider='shibboleth', instance=user)
- messages.add_message(request, messages.ERROR, e)
+ form = SimpleBackend(request).get_signup_form(
+ provider='shibboleth',
- instance=user
- )
++ instance=user)
+ messages.error(request, e)
return render_response(on_creation_template,
- signup_form = form,
- provider = 'shibboleth',
- context_instance=get_context(request, extra_context))
+ signup_form=form,
+ provider='shibboleth',
- context_instance=get_context(
- request,
- extra_context
- )
- )
++ context_instance=get_context(request,
++ extra_context))
# interpreted as representing official policies, either expressed
# or implied, of GRNET S.A.
-from django.conf.urls.defaults import patterns, include, url
-from django.contrib.auth.views import password_change
+from django.conf.urls.defaults import patterns, url
- from astakos.im.forms import ExtendedPasswordResetForm, ExtendedPasswordChangeForm, LoginForm
+ from astakos.im.forms import (ExtendedPasswordResetForm,
+ ExtendedPasswordChangeForm,
+ ExtendedSetPasswordForm, LoginForm)
from astakos.im.settings import IM_MODULES, INVITATIONS_ENABLED, EMAILCHANGE_ENABLED
urlpatterns = patterns('astakos.im.views',
if 'local' in IM_MODULES:
urlpatterns += patterns('astakos.im.target',
- url(r'^local/?$', 'local.login')
- )
+ url(r'^local/?$', 'local.login')
+ )
urlpatterns += patterns('django.contrib.auth.views',
- url(r'^local/password_reset/?$', 'password_reset',
- {'email_template_name': 'registration/password_email.txt',
- 'password_reset_form': ExtendedPasswordResetForm}),
- url(r'^local/password_reset_done/?$',
- 'password_reset_done'),
- 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_change/?$', 'password_change', {'post_change_redirect': 'profile',
- 'password_change_form': ExtendedPasswordChangeForm})
- )
+ url(r'^local/password_reset/?$', 'password_reset',
+ {'email_template_name':'registration/password_email.txt',
+ 'password_reset_form':ExtendedPasswordResetForm}),
+ url(r'^local/password_reset_done/?$', 'password_reset_done'),
+ url(r'^local/reset/confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/?$',
+ 'password_reset_confirm', {'set_password_form':ExtendedSetPasswordForm}),
+ url(r'^local/password/reset/complete/?$', 'password_reset_complete'),
+ url(r'^password_change/?$', 'password_change', {'post_change_redirect':'profile',
+ 'password_change_form':ExtendedPasswordChangeForm})
+ )
if INVITATIONS_ENABLED:
urlpatterns += patterns('astakos.im.views',
# or implied, of GRNET S.A.
import logging
-import socket
+import calendar
-from smtplib import SMTPException
from urllib import quote
from functools import wraps
+from datetime import datetime, timedelta
+from collections import defaultdict
-from django.core.mail import send_mail
-from django.http import HttpResponse, HttpResponseBadRequest
-from django.shortcuts import redirect
-from django.template.loader import render_to_string
-from django.utils.translation import ugettext as _
-from django.core.urlresolvers import reverse
-from django.contrib.auth.decorators import login_required
from django.contrib import messages
-from django.db import transaction
-from django.utils.http import urlencode
-from django.http import HttpResponseRedirect, HttpResponseBadRequest
-from django.db.utils import IntegrityError
+from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import password_change
-from django.core.exceptions import ValidationError
+from django.core.urlresolvers import reverse
+from django.db import transaction
from django.db.models import Q
++<<<<<<< HEAD
+from django.db.utils import IntegrityError
+from django.forms.fields import URLField
+from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, \
+ HttpResponseRedirect, HttpResponseBadRequest, Http404
+from django.shortcuts import redirect
+from django.template import RequestContext, loader as template_loader
+from django.utils.http import urlencode
+from django.utils.translation import ugettext as _
+from django.views.generic.create_update import (create_object, delete_object,
+ get_model_and_form_class)
+from django.views.generic.list_detail import object_list, object_detail
+from django.http import HttpResponseBadRequest
+from django.core.xheaders import populate_xheaders
+
+from astakos.im.models import (
+ AstakosUser, ApprovalTerms, AstakosGroup, Resource,
+ EmailChange, GroupKind, Membership, AstakosGroupQuota)
+ from django.views.decorators.http import require_http_methods
+
-from astakos.im.models import AstakosUser, Invitation, ApprovalTerms
from astakos.im.activation_backends import get_backend, SimpleBackend
from astakos.im.util import get_context, prepare_response, set_cookie, get_query
-from astakos.im.forms import *
-from astakos.im.functions import send_greeting, send_feedback, SendMailError, \
- invite as invite_func, logout as auth_logout, activate as activate_func, switch_account_to_shibboleth
-from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, COOKIE_NAME, COOKIE_DOMAIN, IM_MODULES, SITENAME, LOGOUT_NEXT, LOGGING_LEVEL
+from astakos.im.forms import (LoginForm, InvitationForm, ProfileForm,
+ FeedbackForm, SignApprovalTermsForm,
+ ExtendedPasswordChangeForm, EmailChangeForm,
+ AstakosGroupCreationForm, AstakosGroupSearchForm,
+ AstakosGroupUpdateForm, AddGroupMembersForm,
+ AstakosGroupSortForm, MembersSortForm,
+ TimelineForm, PickResourceForm)
+from astakos.im.functions import (send_feedback, SendMailError,
+ invite as invite_func, logout as auth_logout,
+ activate as activate_func,
+ switch_account_to_shibboleth,
+ send_admin_notification,
+ SendNotificationError)
+from astakos.im.endpoints.quotaholder import timeline_charge
+from astakos.im.settings import (
+ COOKIE_NAME, COOKIE_DOMAIN, SITENAME, LOGOUT_NEXT,
+ LOGGING_LEVEL, PAGINATE_BY)
+from astakos.im.tasks import request_billing
logger = logging.getLogger(__name__)
return func(request, *args, **kwargs)
return wrapper
+
+ @require_http_methods(["GET", "POST"])
@signed_terms_required
-def index(request, login_template_name='im/login.html', profile_template_name='im/profile.html', extra_context={}):
+def index(request, login_template_name='im/login.html', extra_context=None):
"""
If there is logged on user renders the profile page otherwise renders login page.
"""
template_name = login_template_name
if request.user.is_authenticated():
- return HttpResponseRedirect(reverse('astakos.im.views.edit_profile'))
+ return HttpResponseRedirect(reverse('edit_profile'))
return render_response(template_name,
- login_form = LoginForm(request=request),
- context_instance = get_context(request, extra_context))
+ login_form=LoginForm(request=request),
+ context_instance=get_context(request, extra_context))
+
+ @require_http_methods(["GET", "POST"])
@login_required
@signed_terms_required
@transaction.commit_manually
sent = [{'email': inv.username,
'realname': inv.realname,
'is_consumed': inv.is_consumed}
- for inv in request.user.invitations_sent.all()]
+ for inv in request.user.invitations_sent.all()]
kwargs = {'inviter': inviter,
- 'sent':sent}
+ 'sent': sent}
context = get_context(request, extra_context, **kwargs)
return render_response(template_name,
- invitation_form = form,
- context_instance = context)
+ invitation_form=form,
+ context_instance=context)
+
+ @require_http_methods(["GET", "POST"])
@login_required
@signed_terms_required
-def edit_profile(request, template_name='im/profile.html', extra_context={}):
+def edit_profile(request, template_name='im/profile.html', extra_context=None):
"""
Allows a user to edit his/her profile.
next = request.POST.get('next')
if next:
return redirect(next)
- msg = _('<p>Profile has been updated successfully</p>')
- messages.add_message(request, messages.SUCCESS, msg)
+ msg = _('Profile has been updated successfully')
+ messages.success(request, msg)
except ValueError, ve:
- messages.add_message(request, messages.ERROR, ve)
+ messages.success(request, ve)
elif request.method == "GET":
- request.user.is_verified = True
- request.user.save()
+ if not request.user.is_verified:
+ request.user.is_verified = True
+ request.user.save()
return render_response(template_name,
- reset_cookie = reset_cookie,
- profile_form = form,
- context_instance = get_context(request,
- extra_context))
+ reset_cookie=reset_cookie,
+ profile_form=form,
+ context_instance=get_context(request,
+ extra_context))
+
+@transaction.commit_manually
+ @require_http_methods(["GET", "POST"])
-def signup(request, template_name='im/signup.html', on_success='im/signup_complete.html', extra_context={}, backend=None):
+def signup(request, template_name='im/signup.html', on_success='im/signup_complete.html', extra_context=None, backend=None):
"""
Allows a user to create a local account.
return render_response(on_success,
context_instance=get_context(request, extra_context))
except SendMailError, e:
- status = messages.ERROR
message = e.message
- messages.add_message(request, status, message)
+ messages.error(request, message)
+ transaction.rollback()
except BaseException, e:
- status = messages.ERROR
message = _('Something went wrong.')
- messages.add_message(request, status, message)
+ messages.error(request, message)
logger.exception(e)
+ transaction.rollback()
return render_response(template_name,
- signup_form = form,
- provider = provider,
+ signup_form=form,
+ provider=provider,
context_instance=get_context(request, extra_context))
+
+ @require_http_methods(["GET", "POST"])
@login_required
@signed_terms_required
-def feedback(request, template_name='im/feedback.html', email_template_name='im/feedback_mail.txt', extra_context={}):
+def feedback(request, template_name='im/feedback.html', email_template_name='im/feedback_mail.txt', extra_context=None):
"""
Allows a user to send feedback.
try:
send_feedback(msg, data, request.user, email_template_name)
except SendMailError, e:
- message = e.message
- status = messages.ERROR
+ messages.error(request, message)
else:
message = _('Feedback successfully sent')
- status = messages.SUCCESS
- messages.add_message(request, status, message)
+ messages.success(request, message)
return render_response(template_name,
- feedback_form = form,
- context_instance = get_context(request, extra_context))
+ feedback_form=form,
+ context_instance=get_context(request, extra_context))
+
+ @require_http_methods(["GET", "POST"])
-def logout(request, template='registration/logged_out.html', extra_context={}):
+@signed_terms_required
+def logout(request, template='registration/logged_out.html', extra_context=None):
"""
Wraps `django.contrib.auth.logout` and delete the cookie.
"""
response['Location'] = LOGOUT_NEXT
response.status_code = 301
return response
- messages.add_message(request, messages.SUCCESS, _('<p>You have successfully logged out.</p>'))
+ messages.success(request, _('You have successfully logged out.'))
context = get_context(request, extra_context)
- response.write(render_to_string(template, context_instance=context))
+ response.write(template_loader.render_to_string(template, context_instance=context))
return response
+
+ @require_http_methods(["GET", "POST"])
@transaction.commit_manually
-def activate(request, greeting_email_template_name='im/welcome_email.txt', helpdesk_email_template_name='im/helpdesk_notification.txt'):
+def activate(request, greeting_email_template_name='im/welcome_email.txt',
+ helpdesk_email_template_name='im/helpdesk_notification.txt'):
"""
Activates the user identified by the ``auth`` request parameter, sends a welcome email
and renews the user token.
transaction.rollback()
return index(request)
+
+ @require_http_methods(["GET", "POST"])
-def approval_terms(request, term_id=None, template_name='im/approval_terms.html', extra_context={}):
+def approval_terms(request, term_id=None, template_name='im/approval_terms.html', extra_context=None):
term = None
terms = None
if not term_id:
return HttpResponseRedirect(next)
else:
form = None
- if request.user.is_authenticated() and not request.user.signed_terms():
+ if request.user.is_authenticated() and not request.user.signed_terms:
form = SignApprovalTermsForm(instance=request.user)
return render_response(template_name,
- terms = terms,
- approval_terms_form = form,
- context_instance = get_context(request, extra_context))
+ terms=terms,
+ approval_terms_form=form,
+ context_instance=get_context(request, extra_context))
+
+ @require_http_methods(["GET", "POST"])
@signed_terms_required
def change_password(request):
return password_change(request,
- post_change_redirect=reverse('astakos.im.views.edit_profile'),
- password_change_form=ExtendedPasswordChangeForm)
+ post_change_redirect=reverse('edit_profile'),
+ password_change_form=ExtendedPasswordChangeForm)
-
- @signed_terms_required
+ @require_http_methods(["GET", "POST"])
@login_required
+ @signed_terms_required
@transaction.commit_manually
def change_email(request, activation_key=None,
email_template_name='registration/email_change_email.txt',
#ASTAKOS_EMAIL_CHANGE_EMAIL_SUBJECT = 'Email change on %s alpha2 testing' % SITENAME
#ASTAKOS_PASSWORD_RESET_EMAIL_SUBJECT = 'Password reset on %s alpha2 testing' % SITENAME
+# Set the quota holder component URI
+#ASTAKOS_QUOTA_HOLDER_URL = ''
+
+# Set the cloud service properties
+# SERVICES = getattr(settings, 'ASTAKOS_SERVICES',
+# {'cyclades': {'url':'https://node1.example.com/ui/',
+# 'quota': {'vm': 2}},
+# 'pithos+': {'url':'https://node2.example.com/ui/',
+# 'quota': {'diskspace': 50 * 1024 * 1024 * 1024}}})
+
+# Set the billing URI
+#ASTAKOS_AQUARIUM_URL = ''
+
+# Set how many objects should be displayed per page
- #PAGINATE_BY = getattr(settings, 'ASTAKOS_PAGINATE_BY', 10)
++#PAGINATE_BY = getattr(settings, 'ASTAKOS_PAGINATE_BY', 10)
++
+ # Enforce token renewal on password change/reset
+ NEWPASSWD_INVALIDATE_TOKEN = getattr(settings, 'ASTAKOS_NEWPASSWD_INVALIDATE_TOKEN', True)