Αγαπητέ/η {{ user.realname }},
-Ο λογαρισμός σας για την υπηρεσία {{ site_name }} της ΕΔΕΤκατά την Alpha (πιλοτική)
+Ο λογαρισμός σας για την υπηρεσία {{ site_name }} της ΕΔΕΤ κατά την Alpha (πιλοτική)
φάση λειτουργίας της έχει ενεργοποιηθεί.
Για να συνδεθείτε, χρησιμοποιήστε τον παρακάτω σύνδεσμο:
If the ``request.user`` is not a superuser redirects to login page.
"""
- form = AdminProfileForm(request.POST)
+ user = AstakosUser.objects.get(id = user_id)
+ form = AdminProfileForm(request.POST, instance=user)
if form.is_valid():
form.save()
return redirect(users_info, user.id, template_name, extra_context)
context_instance = get_context(request, extra_context,**kwargs))
def _send_greeting(request, user, template_name):
- url = reverse('astakos.im.views.index')
subject = _('Welcome to %s' %settings.SERVICE_NAME)
site = Site.objects.get_current()
baseurl = request.build_absolute_uri('/').rstrip('/')
message = render_to_string(template_name, {
'user': user,
- 'url': url,
+ 'url': site.domain,
'baseurl': baseurl,
'site_name': site.name,
'support': settings.DEFAULT_CONTACT_EMAIL})
response = HttpResponse()
response.status=204
user_info = {'uniq':user.username,
+ 'email':user.email,
'auth_token':user.auth_token,
'auth_token_created':user.auth_token_created.isoformat(),
'auth_token_expires':user.auth_token_expires.isoformat()}
from django.conf import settings
from django.contrib.auth.backends import ModelBackend
-#from django.core.exceptions import ImproperlyConfigured
-#from django.db.models import get_model
+from django.core.validators import email_re
from astakos.im.models import AstakosUser
-class AstakosUserModelCredentialsBackend(ModelBackend):
+class TokenBackend(ModelBackend):
"""
- AuthenticationBackend used to authenticate user creadentials
+ AuthenticationBackend used to authenticate using token instead
"""
- def authenticate(self, username=None, password=None):
+ def authenticate(self, email=None, auth_token=None):
try:
- user = AstakosUser.objects.get(username=username)
- if user.check_password(password):
+ user = AstakosUser.objects.get(email=email)
+ if user.auth_token == auth_token:
return user
except AstakosUser.DoesNotExist:
return None
return AstakosUser.objects.get(pk=user_id)
except AstakosUser.DoesNotExist:
return None
-
- #@property
- #def user_class(self):
- # if not hasattr(self, '_user_class'):
- # #self._user_class = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2))
- # self._user_class = get_model('astakos.im', 'astakosuser')
- # print '#', self._user_class
- # if not self._user_class:
- # raise ImproperlyConfigured('Could not get custom user model')
- # return self._user_class
-class AstakosUserModelTokenBackend(ModelBackend):
+class EmailBackend(ModelBackend):
"""
- AuthenticationBackend used to authenticate using token instead
+ If the ``username`` parameter is actually an email uses email to authenticate
+ the user else tries the username.
+
+ Used from ``astakos.im.forms.LoginForm`` to authenticate.
"""
- def authenticate(self, username=None, auth_token=None):
- try:
- user = AstakosUser.objects.get(username=username)
- if user.auth_token == auth_token:
- return user
- except AstakosUser.DoesNotExist:
- return None
-
+ def authenticate(self, username=None, password=None):
+ #If username is an email address, then try to pull it up
+ if email_re.search(username):
+ try:
+ user = AstakosUser.objects.get(email=username)
+ except AstakosUser.DoesNotExist:
+ return None
+ else:
+ #We have a non-email address username we
+ #should try username
+ try:
+ user = AstakosUser.objects.get(username=username)
+ except AstakosUser.DoesNotExist:
+ return None
+ if user.check_password(password):
+ return user
+
def get_user(self, user_id):
try:
return AstakosUser.objects.get(pk=user_id)
from django.contrib.auth.forms import UserCreationForm
from django.contrib.sites.models import Site
from django.contrib import messages
+from django.shortcuts import redirect
from smtplib import SMTPException
from urllib import quote
from astakos.im.models import AstakosUser, Invitation
from astakos.im.forms import ExtendedUserCreationForm, InvitedExtendedUserCreationForm
-def get_backend():
+import socket
+import logging
+
+def get_backend(request):
"""
Return an instance of a registration backend,
according to the INVITATIONS_ENABLED setting
backend_class = getattr(mod, backend_class_name)
except AttributeError:
raise ImproperlyConfigured('Module "%s" does not define a registration backend named "%s"' % (module, attr))
- return backend_class()
+ return backend_class(request)
class InvitationsBackend(object):
"""
account is created and the user is going to receive an email as soon as an
administrator activates his/her account.
"""
- def get_signup_form(self, request):
+ def __init__(self, request):
+ self.request = request
+ self.invitation = None
+ self.set_invitation()
+
+ def set_invitation(self):
+ code = self.request.GET.get('code', '')
+ if not code:
+ code = self.request.POST.get('code', '')
+ if code:
+ self.invitation = Invitation.objects.get(code=code)
+ if self.invitation.is_consumed:
+ raise Exception('Invitation has beeen used')
+
+ def get_signup_form(self):
"""
Returns the necassary registration form depending the user is invited or not
Throws Invitation.DoesNotExist in case ``code`` is not valid.
"""
- code = request.GET.get('code', '')
+ request = self.request
formclass = 'ExtendedUserCreationForm'
initial_data = None
if request.method == 'GET':
- if code:
+ if self.invitation:
formclass = 'Invited%s' %formclass
- self.invitation = Invitation.objects.get(code=code)
- if self.invitation.is_consumed:
- raise Exception('Invitation has beeen used')
initial_data = {'username':self.invitation.username,
'email':self.invitation.username,
'realname':self.invitation.realname}
inviter = AstakosUser.objects.get(username=self.invitation.inviter)
initial_data['inviter'] = inviter.realname
+ initial_data['level'] = inviter.level + 1
else:
initial_data = request.POST
return globals()[formclass](initial_data)
It should be called after ``get_signup_form`` which sets invitation if exists.
"""
- invitation = getattr(self, 'invitation') if hasattr(self, 'invitation') else None
+ invitation = self.invitation
if not invitation:
return False
- if invitation.username == user.username and not invitation.is_consumed:
+ if invitation.username == user.email and not invitation.is_consumed:
+ invitation.consume()
return True
return False
- def signup(self, request):
+ def signup(self, form):
"""
- Creates a incative user account. If the user is preaccepted (has a valid
- invitation code) the user is activated and if the request param ``next``
- is present redirects to it.
+ Initially creates an inactive user account. If the user is preaccepted
+ (has a valid invitation code) the user is activated and if the request
+ param ``next`` is present redirects to it.
In any other case the method returns the action status and a message.
"""
kwargs = {}
- form = self.get_signup_form(request)
user = form.save()
-
try:
if self._is_preaccepted(user):
user.is_active = True
user.save()
message = _('Registration completed. You can now login.')
- next = request.POST.get('next')
- if next:
- return redirect(next)
else:
message = _('Registration completed. You will receive an email upon your account\'s activation')
status = messages.SUCCESS
supplies the necessary registation information, an incative user account is
created and receives an email in order to activate his/her account.
"""
- def get_signup_form(self, request):
+ def __init__(self, request):
+ self.request = request
+
+ def get_signup_form(self):
"""
Returns the UserCreationForm
"""
+ request = self.request
initial_data = request.POST if request.method == 'POST' else None
- return UserCreationForm(initial_data)
+ return ExtendedUserCreationForm(initial_data)
- def signup(self, request, email_template_name='activation_email.txt'):
+ def signup(self, form, email_template_name='activation_email.txt'):
"""
Creates an inactive user account and sends a verification email.
* DEFAULT_FROM_EMAIL: from email
"""
kwargs = {}
- form = self.get_signup_form(request)
user = form.save()
status = messages.SUCCESS
try:
- _send_verification(request, user, email_template_name)
+ _send_verification(self.request, user, email_template_name)
message = _('Verification sent to %s' % user.email)
except (SMTPException, socket.error) as e:
status = messages.ERROR
message = getattr(e, name) if hasattr(e, name) else e
return status, message
- def _send_verification(request, user, template_name):
- site = Site.objects.get_current()
- baseurl = request.build_absolute_uri('/').rstrip('/')
- url = settings.ACTIVATION_LOGIN_TARGET % (baseurl,
- quote(user.auth_token),
- quote(baseurl))
- message = render_to_string(template_name, {
- 'user': user,
- 'url': url,
- 'baseurl': baseurl,
- 'site_name': site.name,
- 'support': settings.DEFAULT_CONTACT_EMAIL})
- sender = settings.DEFAULT_FROM_EMAIL
- send_mail('Pithos account activation', message, sender, [user.email])
- logging.info('Sent activation %s', user)
+def _send_verification(request, user, template_name):
+ site = Site.objects.get_current()
+ baseurl = request.build_absolute_uri('/').rstrip('/')
+ url = settings.ACTIVATION_LOGIN_TARGET % (baseurl,
+ quote(user.auth_token),
+ quote(baseurl))
+ message = render_to_string(template_name, {
+ 'user': user,
+ 'url': url,
+ 'baseurl': baseurl,
+ 'site_name': site.name,
+ 'support': settings.DEFAULT_CONTACT_EMAIL})
+ sender = settings.DEFAULT_FROM_EMAIL
+ send_mail('Pithos account activation', message, sender, [user.email])
+ logging.info('Sent activation %s', user)
"fields": {
"level": 1,
"invitations": 2,
- "updated": "2012-01-24"
+ "auth_token": "0000",
+ "auth_token_created": "2011-04-07 09:17:14",
+ "auth_token_expires": "2015-04-07 09:17:14",
+ "updated": "2011-02-06"
}
}
]
from django import forms
from django.utils.translation import ugettext as _
-from django.contrib.auth.forms import UserCreationForm
+from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.conf import settings
+from django.core.validators import email_re
+
from hashlib import new as newhasher
from astakos.im.models import AstakosUser
from astakos.im.util import get_or_create_user
import logging
+import uuid
class UniqueUserEmailField(forms.EmailField):
"""
Extends the built in UserCreationForm in several ways:
* Adds an email field, which uses the custom UniqueUserEmailField.
- * The username field isn't visible and it is assigned the email value.
+ * The username field isn't visible and it is assigned a generated id.
* first_name and last_name fields are added.
+ * User is created not active.
"""
- username = forms.CharField(required = False, max_length = 30)
- email = UniqueUserEmailField(required = True, label = 'Email address')
- first_name = forms.CharField(required = False, max_length = 30)
- last_name = forms.CharField(required = False, max_length = 30)
-
class Meta:
model = AstakosUser
- fields = ("username",)
+ fields = ("email", "first_name", "last_name")
def __init__(self, *args, **kwargs):
"""
self.fields.keyOrder = ['email', 'first_name', 'last_name',
'password1', 'password2']
- def clean(self, *args, **kwargs):
- """
- Normal cleanup + username generation.
- """
- cleaned_data = super(ExtendedUserCreationForm, self).clean(*args, **kwargs)
- if cleaned_data.has_key('email'):
- cleaned_data['username'] = cleaned_data['email']
- return cleaned_data
-
def save(self, commit=True):
"""
Saves the email, first_name and last_name properties, after the normal
save behavior is complete.
"""
user = super(ExtendedUserCreationForm, self).save(commit=False)
+ user.username = uuid.uuid4().hex[:30]
+ user.is_active = False
user.renew_token()
user.save()
logging.info('Created user %s', user)
return user
-class InvitedExtendedUserCreationForm(UserCreationForm):
+class InvitedExtendedUserCreationForm(ExtendedUserCreationForm):
"""
- Extends the built in UserCreationForm in several ways:
-
- * Adds an email field, which uses the custom UniqueUserEmailField.
- * The username field isn't visible and it is assigned the email value.
- * first_name and last_name fields are added.
+ Extends the ExtendedUserCreationForm: adds an inviter readonly field.
"""
- username = forms.CharField(required = False, max_length = 30)
- email = UniqueUserEmailField(required = True, label = 'Email address')
- first_name = forms.CharField(required = False, max_length = 30)
- last_name = forms.CharField(required = False, max_length = 30)
inviter = forms.CharField(widget=forms.TextInput(), label=_('Inviter Real Name'))
+ level = forms.IntegerField(widget=forms.TextInput(), label=_('Level'))
class Meta:
model = AstakosUser
- fields = ("username",)
+ fields = ("email", "first_name", "last_name")
def __init__(self, *args, **kwargs):
"""
Changes the order of fields, and removes the username field.
"""
super(InvitedExtendedUserCreationForm, self).__init__(*args, **kwargs)
- self.fields.keyOrder = ['email', 'inviter', 'first_name', 'last_name',
- 'password1', 'password2']
+ self.fields.keyOrder = ['email', 'inviter', 'level', 'first_name',
+ 'last_name', 'password1', 'password2']
#set readonly form fields
self.fields['inviter'].widget.attrs['readonly'] = True
+ self.fields['level'].widget.attrs['readonly'] = True
self.fields['email'].widget.attrs['readonly'] = True
self.fields['username'].widget.attrs['readonly'] = True
-
- def clean(self, *args, **kwargs):
- """
- Normal cleanup + username generation.
- """
- cleaned_data = super(UserCreationForm, self).clean(*args, **kwargs)
- if cleaned_data.has_key('email'):
- cleaned_data['username'] = cleaned_data['email']
- return cleaned_data
-
- def save(self, commit=True):
- """
- Saves the email, first_name and last_name properties, after the normal
- save behavior is complete.
- """
- user = super(InvitedExtendedUserCreationForm, self).save(commit=False)
- user.renew_token()
- user.save()
- logging.info('Created user %s', user)
- return user
+
+class LoginForm(AuthenticationForm):
+ username = forms.EmailField(label=_("Email"))
class ProfileForm(forms.ModelForm):
"""
"""
class Meta:
model = AstakosUser
- exclude = ('groups', 'user_permissions')
+ exclude = ('is_active', 'is_superuser', 'is_staff', 'is_verified', 'groups', 'user_permissions')
def __init__(self, *args, **kwargs):
super(ProfileForm, self).__init__(*args, **kwargs)
instance = getattr(self, 'instance', None)
ro_fields = ('username','date_joined', 'updated', 'auth_token',
'auth_token_created', 'auth_token_expires', 'invitations',
- 'level', 'last_login', 'email', 'is_active', 'is_superuser',
- 'is_staff')
+ 'level', 'last_login', 'email', )
if instance and instance.id:
for field in ro_fields:
if isinstance(self.fields[field].widget, forms.CheckboxInput):
label=u'Message', required=False)
feedback_data = forms.CharField(widget=forms.Textarea(),
label=u'Data', required=False)
+
+class SendInvitationForm(forms.Form):
+ """
+ Form for sending an invitations
+ """
+
+ email = forms.EmailField(required = True, label = 'Email address')
+ first_name = forms.EmailField(label = 'First name')
+ last_name = forms.EmailField(label = 'Last name')
from django.conf import settings
from django.db import models
from django.contrib.auth.models import User, UserManager
+from django.utils.translation import ugettext_lazy as _
from astakos.im.interface import get_quota, set_quota
# Use UserManager to get the create_user method, etc.
objects = UserManager()
- affiliation = models.CharField('Affiliation', max_length=255, default='')
- provider = models.CharField('Provider', max_length=255, default='')
+ affiliation = models.CharField('Affiliation', max_length=255, blank=True)
+ provider = models.CharField('Provider', max_length=255, blank=True)
#for invitations
level = models.IntegerField('Inviter level', default=4)
invitation.inviter.level + 1)
# in order to login the user we must call authenticate first
- authenticate(username=user.username, auth_token=user.auth_token)
+ authenticate(email=user.email, auth_token=user.auth_token)
next = request.GET.get('next')
return prepare_response(request, user, next, 'renew' in request.GET)
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib.auth import authenticate
-from django.contrib.auth.forms import AuthenticationForm
from django.contrib import messages
from django.utils.translation import ugettext as _
from astakos.im.target.util import prepare_response
from astakos.im.models import AstakosUser
-
+from astakos.im.forms import LoginForm
from urllib import unquote
from hashlib import new as newhasher
"""
on_failure: whatever redirect accepts as to
"""
- form = AuthenticationForm(data=request.POST)
+ form = LoginForm(data=request.POST)
if not form.is_valid():
return render_to_response(on_failure,
{'form':form},
user.is_active = True
user.save()
- return prepare_response(request, user, next, renew=True)
+ return prepare_response(request, user, next, renew=True, skip_login=True)
<div class="span4">
<h4>Local account</h4>
<form action="{% url astakos.im.target.local.login %}" method="post" class="form-stacked">{% csrf_token %}
- {{ form.non_field_errors }}
- {% for field in form %}
- <div class="field-wrapper">
- <div class="label-wrapper">
- {% if field.name == "username" %}
- Email address or Username
- {% else %}
- {{ field.label_tag }}
- {% endif %}
- </div>
- <div class="value-wrapper">
- {{ field }}
- {{ field.errors }}
- </div>
- </div>
- {% endfor %}
+ {{ form.as_p }}
<div>
<a href="{% url django.contrib.auth.views.password_reset %}">Forgot your password?</a>
</div>
<div class="container">
<h3>You have {{ user.invitations }} invitation{{ user.invitations|pluralize }} left.</h3>
- <!--{% if message %}
- <br />
- <div class="alert-message {{ status }}">
- <p>{{ message }}</p>
- </div>
- {% endif %}-->
-
{% if user.invitations %}
<br />
<h4>Invite someone else:</h4>
from django.utils.http import urlencode
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
-from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.models import AnonymousUser
from django.contrib.auth.decorators import login_required
from django.contrib.sites.models import Site
from astakos.im.models import AstakosUser, Invitation
from astakos.im.util import isoformat, get_or_create_user, get_context
from astakos.im.backends import get_backend
-from astakos.im.forms import ProfileForm, FeedbackForm
+from astakos.im.forms import ProfileForm, FeedbackForm, LoginForm
def render_response(template, tab=None, status=200, context_instance=None, **kwargs):
"""
"""
return render_response(template_name,
- form = AuthenticationForm(),
+ form = LoginForm(),
context_instance = get_context(request, extra_context))
def _generate_invitation_code():
"""
status = None
message = None
- inviter = request.user
-
+ inviter = AstakosUser.objects.get(username = request.user.username)
+
if request.method == 'POST':
username = request.POST.get('uniq')
realname = request.POST.get('realname')
signup.html or ``template_name`` keyword argument.
"""
if not backend:
- backend = get_backend()
+ backend = get_backend(request)
try:
- form = backend.get_signup_form(request)
+ form = backend.get_signup_form()
if request.method == 'POST':
if form.is_valid():
- status, message = backend.signup(request)
+ status, message = backend.signup(form)
# rollback incase of error
if status == messages.ERROR:
transaction.rollback()
else:
transaction.commit()
- next = request.POST.get('next')
- if next:
- return redirect(next)
+ next = request.POST.get('next')
+ if next:
+ return redirect(next)
messages.add_message(request, status, message)
- except (Invitation.DoesNotExist, Exception), e:
+ except Invitation.DoesNotExist, e:
messages.add_message(request, messages.ERROR, e)
return render_response(template_name,
form = form if 'form' in locals() else UserCreationForm(),
'astakos.im.context_processors.code',
'astakos.im.context_processors.invitations')
-AUTHENTICATION_BACKENDS = (
- 'astakos.im.auth_backends.AstakosUserModelCredentialsBackend',
- 'astakos.im.auth_backends.AstakosUserModelTokenBackend',
-)
+AUTHENTICATION_BACKENDS = ('astakos.im.auth_backends.EmailBackend',
+ 'astakos.im.auth_backends.TokenBackend')
CUSTOM_USER_MODEL = 'astakos.im.AstakosUser'