Revision 5ed6816e

b/astakos/im/admin/templates/welcome_email.txt
2 2

  
3 3
Αγαπητέ/η {{ user.realname }},
4 4

  
5
Ο λογαρισμός σας για την υπηρεσία {{ site_name }} της ΕΔΕΤκατά την Alpha (πιλοτική)
5
Ο λογαρισμός σας για την υπηρεσία {{ site_name }} της ΕΔΕΤ κατά την Alpha (πιλοτική)
6 6
φάση λειτουργίας της έχει ενεργοποιηθεί.
7 7

  
8 8
Για να συνδεθείτε, χρησιμοποιήστε τον παρακάτω σύνδεσμο:
b/astakos/im/admin/views.py
223 223
    
224 224
    If the ``request.user`` is not a superuser redirects to login page.
225 225
    """
226
    form = AdminProfileForm(request.POST)
226
    user = AstakosUser.objects.get(id = user_id)
227
    form = AdminProfileForm(request.POST, instance=user)
227 228
    if form.is_valid():
228 229
        form.save()
229 230
        return redirect(users_info, user.id, template_name, extra_context)
......
307 308
                            context_instance = get_context(request, extra_context,**kwargs))
308 309

  
309 310
def _send_greeting(request, user, template_name):
310
    url = reverse('astakos.im.views.index')
311 311
    subject = _('Welcome to %s' %settings.SERVICE_NAME)
312 312
    site = Site.objects.get_current()
313 313
    baseurl = request.build_absolute_uri('/').rstrip('/')
314 314
    message = render_to_string(template_name, {
315 315
                'user': user,
316
                'url': url,
316
                'url': site.domain,
317 317
                'baseurl': baseurl,
318 318
                'site_name': site.name,
319 319
                'support': settings.DEFAULT_CONTACT_EMAIL})
b/astakos/im/api.py
83 83
        response = HttpResponse()
84 84
        response.status=204
85 85
        user_info = {'uniq':user.username,
86
                     'email':user.email,
86 87
                     'auth_token':user.auth_token,
87 88
                     'auth_token_created':user.auth_token_created.isoformat(),
88 89
                     'auth_token_expires':user.auth_token_expires.isoformat()}
b/astakos/im/auth_backends.py
1 1
from django.conf import settings
2 2
from django.contrib.auth.backends import ModelBackend
3
#from django.core.exceptions import ImproperlyConfigured
4
#from django.db.models import get_model
3
from django.core.validators import email_re
5 4

  
6 5
from astakos.im.models import AstakosUser
7 6

  
8
class AstakosUserModelCredentialsBackend(ModelBackend):
7
class TokenBackend(ModelBackend):
9 8
    """
10
    AuthenticationBackend used to authenticate user creadentials
9
    AuthenticationBackend used to authenticate using token instead
11 10
    """
12
    def authenticate(self, username=None, password=None):
11
    def authenticate(self, email=None, auth_token=None):
13 12
        try:
14
            user = AstakosUser.objects.get(username=username)
15
            if user.check_password(password):
13
            user = AstakosUser.objects.get(email=email)
14
            if user.auth_token == auth_token:
16 15
                return user
17 16
        except AstakosUser.DoesNotExist:
18 17
            return None
......
22 21
            return AstakosUser.objects.get(pk=user_id)
23 22
        except AstakosUser.DoesNotExist:
24 23
            return None
25
    
26
    #@property
27
    #def user_class(self):
28
    #    if not hasattr(self, '_user_class'):
29
    #        #self._user_class = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2))
30
    #        self._user_class = get_model('astakos.im', 'astakosuser')
31
    #        print '#', self._user_class
32
    #        if not self._user_class:
33
    #            raise ImproperlyConfigured('Could not get custom user model')
34
    #    return self._user_class
35 24

  
36
class AstakosUserModelTokenBackend(ModelBackend):
25
class EmailBackend(ModelBackend):
37 26
    """
38
    AuthenticationBackend used to authenticate using token instead
27
    If the ``username`` parameter is actually an email uses email to authenticate
28
    the user else tries the username.
29
    
30
    Used from ``astakos.im.forms.LoginForm`` to authenticate.
39 31
    """
40
    def authenticate(self, username=None, auth_token=None):
41
        try:
42
            user = AstakosUser.objects.get(username=username)
43
            if user.auth_token == auth_token:
44
                return user
45
        except AstakosUser.DoesNotExist:
46
            return None
47

  
32
    def authenticate(self, username=None, password=None):
33
        #If username is an email address, then try to pull it up
34
        if email_re.search(username):
35
            try:
36
                user = AstakosUser.objects.get(email=username)
37
            except AstakosUser.DoesNotExist:
38
                return None
39
        else:
40
            #We have a non-email address username we
41
            #should try username
42
            try:
43
                user = AstakosUser.objects.get(username=username)
44
            except AstakosUser.DoesNotExist:
45
                return None
46
        if user.check_password(password):
47
            return user
48
    
48 49
    def get_user(self, user_id):
49 50
        try:
50 51
            return AstakosUser.objects.get(pk=user_id)
b/astakos/im/backends/__init__.py
40 40
from django.contrib.auth.forms import UserCreationForm
41 41
from django.contrib.sites.models import Site
42 42
from django.contrib import messages
43
from django.shortcuts import redirect
43 44

  
44 45
from smtplib import SMTPException
45 46
from urllib import quote
......
48 49
from astakos.im.models import AstakosUser, Invitation
49 50
from astakos.im.forms import ExtendedUserCreationForm, InvitedExtendedUserCreationForm
50 51

  
51
def get_backend():
52
import socket
53
import logging
54

  
55
def get_backend(request):
52 56
    """
53 57
    Return an instance of a registration backend,
54 58
    according to the INVITATIONS_ENABLED setting
......
69 73
        backend_class = getattr(mod, backend_class_name)
70 74
    except AttributeError:
71 75
        raise ImproperlyConfigured('Module "%s" does not define a registration backend named "%s"' % (module, attr))
72
    return backend_class()
76
    return backend_class(request)
73 77

  
74 78
class InvitationsBackend(object):
75 79
    """
......
79 83
    account is created and the user is going to receive an email as soon as an
80 84
    administrator activates his/her account.
81 85
    """
82
    def get_signup_form(self, request):
86
    def __init__(self, request):
87
        self.request = request
88
        self.invitation = None
89
        self.set_invitation()
90
    
91
    def set_invitation(self):
92
        code = self.request.GET.get('code', '')
93
        if not code:
94
            code = self.request.POST.get('code', '')
95
        if code:
96
            self.invitation = Invitation.objects.get(code=code)
97
            if self.invitation.is_consumed:
98
                    raise Exception('Invitation has beeen used')
99
    
100
    def get_signup_form(self):
83 101
        """
84 102
        Returns the necassary registration form depending the user is invited or not
85 103
        
86 104
        Throws Invitation.DoesNotExist in case ``code`` is not valid.
87 105
        """
88
        code = request.GET.get('code', '')
106
        request = self.request
89 107
        formclass = 'ExtendedUserCreationForm'
90 108
        initial_data = None
91 109
        if request.method == 'GET':
92
            if code:
110
            if self.invitation:
93 111
                formclass = 'Invited%s' %formclass
94
                self.invitation = Invitation.objects.get(code=code)
95
                if self.invitation.is_consumed:
96
                    raise Exception('Invitation has beeen used')
97 112
                initial_data = {'username':self.invitation.username,
98 113
                                'email':self.invitation.username,
99 114
                                'realname':self.invitation.realname}
100 115
                inviter = AstakosUser.objects.get(username=self.invitation.inviter)
101 116
                initial_data['inviter'] = inviter.realname
117
                initial_data['level'] = inviter.level + 1
102 118
        else:
103 119
            initial_data = request.POST
104 120
        return globals()[formclass](initial_data)
......
110 126
        
111 127
        It should be called after ``get_signup_form`` which sets invitation if exists.
112 128
        """
113
        invitation = getattr(self, 'invitation') if hasattr(self, 'invitation') else None
129
        invitation = self.invitation
114 130
        if not invitation:
115 131
            return False
116
        if invitation.username == user.username and not invitation.is_consumed:
132
        if invitation.username == user.email and not invitation.is_consumed:
133
            invitation.consume()
117 134
            return True
118 135
        return False
119 136
    
120
    def signup(self, request):
137
    def signup(self, form):
121 138
        """
122
        Creates a incative user account. If the user is preaccepted (has a valid
123
        invitation code) the user is activated and if the request param ``next``
124
        is present redirects to it.
139
        Initially creates an inactive user account. If the user is preaccepted
140
        (has a valid invitation code) the user is activated and if the request
141
        param ``next`` is present redirects to it.
125 142
        In any other case the method returns the action status and a message.
126 143
        """
127 144
        kwargs = {}
128
        form = self.get_signup_form(request)
129 145
        user = form.save()
130
        
131 146
        try:
132 147
            if self._is_preaccepted(user):
133 148
                user.is_active = True
134 149
                user.save()
135 150
                message = _('Registration completed. You can now login.')
136
                next = request.POST.get('next')
137
                if next:
138
                    return redirect(next)
139 151
            else:
140 152
                message = _('Registration completed. You will receive an email upon your account\'s activation')
141 153
            status = messages.SUCCESS
......
150 162
    supplies the necessary registation information, an incative user account is
151 163
    created and receives an email in order to activate his/her account.
152 164
    """
153
    def get_signup_form(self, request):
165
    def __init__(self, request):
166
        self.request = request
167
    
168
    def get_signup_form(self):
154 169
        """
155 170
        Returns the UserCreationForm
156 171
        """
172
        request = self.request
157 173
        initial_data = request.POST if request.method == 'POST' else None
158
        return UserCreationForm(initial_data)
174
        return ExtendedUserCreationForm(initial_data)
159 175
    
160
    def signup(self, request, email_template_name='activation_email.txt'):
176
    def signup(self, form, email_template_name='activation_email.txt'):
161 177
        """
162 178
        Creates an inactive user account and sends a verification email.
163 179
        
......
178 194
        * DEFAULT_FROM_EMAIL: from email
179 195
        """
180 196
        kwargs = {}
181
        form = self.get_signup_form(request)
182 197
        user = form.save()
183 198
        
184 199
        status = messages.SUCCESS
185 200
        try:
186
            _send_verification(request, user, email_template_name)
201
            _send_verification(self.request, user, email_template_name)
187 202
            message = _('Verification sent to %s' % user.email)
188 203
        except (SMTPException, socket.error) as e:
189 204
            status = messages.ERROR
......
191 206
            message = getattr(e, name) if hasattr(e, name) else e
192 207
        return status, message
193 208

  
194
    def _send_verification(request, user, template_name):
195
        site = Site.objects.get_current()
196
        baseurl = request.build_absolute_uri('/').rstrip('/')
197
        url = settings.ACTIVATION_LOGIN_TARGET % (baseurl,
198
                                                  quote(user.auth_token),
199
                                                  quote(baseurl))
200
        message = render_to_string(template_name, {
201
                'user': user,
202
                'url': url,
203
                'baseurl': baseurl,
204
                'site_name': site.name,
205
                'support': settings.DEFAULT_CONTACT_EMAIL})
206
        sender = settings.DEFAULT_FROM_EMAIL
207
        send_mail('Pithos account activation', message, sender, [user.email])
208
        logging.info('Sent activation %s', user)
209
def _send_verification(request, user, template_name):
210
    site = Site.objects.get_current()
211
    baseurl = request.build_absolute_uri('/').rstrip('/')
212
    url = settings.ACTIVATION_LOGIN_TARGET % (baseurl,
213
                                              quote(user.auth_token),
214
                                              quote(baseurl))
215
    message = render_to_string(template_name, {
216
            'user': user,
217
            'url': url,
218
            'baseurl': baseurl,
219
            'site_name': site.name,
220
            'support': settings.DEFAULT_CONTACT_EMAIL})
221
    sender = settings.DEFAULT_FROM_EMAIL
222
    send_mail('Pithos account activation', message, sender, [user.email])
223
    logging.info('Sent activation %s', user)
b/astakos/im/fixtures/test_user.json
14 14
        "fields": {
15 15
            "level": 1,
16 16
            "invitations": 2,
17
            "updated": "2012-01-24"
17
            "auth_token": "0000",
18
            "auth_token_created": "2011-04-07 09:17:14",
19
            "auth_token_expires": "2015-04-07 09:17:14",
20
            "updated": "2011-02-06"
18 21
   	}
19 22
    }
20 23
]
b/astakos/im/forms.py
33 33

  
34 34
from django import forms
35 35
from django.utils.translation import ugettext as _
36
from django.contrib.auth.forms import UserCreationForm
36
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
37 37
from django.conf import settings
38
from django.core.validators import email_re
39

  
38 40
from hashlib import new as newhasher
39 41

  
40 42
from astakos.im.models import AstakosUser
41 43
from astakos.im.util import get_or_create_user
42 44

  
43 45
import logging
46
import uuid
44 47

  
45 48
class UniqueUserEmailField(forms.EmailField):
46 49
    """
......
61 64
    Extends the built in UserCreationForm in several ways:
62 65
    
63 66
    * Adds an email field, which uses the custom UniqueUserEmailField.
64
    * The username field isn't visible and it is assigned the email value.
67
    * The username field isn't visible and it is assigned a generated id.
65 68
    * first_name and last_name fields are added.
69
    * User is created not active. 
66 70
    """
67 71
    
68
    username = forms.CharField(required = False, max_length = 30)
69
    email = UniqueUserEmailField(required = True, label = 'Email address')
70
    first_name = forms.CharField(required = False, max_length = 30)
71
    last_name = forms.CharField(required = False, max_length = 30)
72
    
73 72
    class Meta:
74 73
        model = AstakosUser
75
        fields = ("username",)
74
        fields = ("email", "first_name", "last_name")
76 75
    
77 76
    def __init__(self, *args, **kwargs):
78 77
        """
......
82 81
        self.fields.keyOrder = ['email', 'first_name', 'last_name',
83 82
                                'password1', 'password2']
84 83
    
85
    def clean(self, *args, **kwargs):
86
        """
87
        Normal cleanup + username generation.
88
        """
89
        cleaned_data = super(ExtendedUserCreationForm, self).clean(*args, **kwargs)
90
        if cleaned_data.has_key('email'):
91
            cleaned_data['username'] = cleaned_data['email']
92
        return cleaned_data
93
        
94 84
    def save(self, commit=True):
95 85
        """
96 86
        Saves the email, first_name and last_name properties, after the normal
97 87
        save behavior is complete.
98 88
        """
99 89
        user = super(ExtendedUserCreationForm, self).save(commit=False)
90
        user.username = uuid.uuid4().hex[:30]
91
        user.is_active = False
100 92
        user.renew_token()
101 93
        user.save()
102 94
        logging.info('Created user %s', user)
103 95
        return user
104 96

  
105
class InvitedExtendedUserCreationForm(UserCreationForm):
97
class InvitedExtendedUserCreationForm(ExtendedUserCreationForm):
106 98
    """
107
    Extends the built in UserCreationForm in several ways:
108
    
109
    * Adds an email field, which uses the custom UniqueUserEmailField.
110
    * The username field isn't visible and it is assigned the email value.
111
    * first_name and last_name fields are added.
99
    Extends the ExtendedUserCreationForm: adds an inviter readonly field.
112 100
    """
113 101
    
114
    username = forms.CharField(required = False, max_length = 30)
115
    email = UniqueUserEmailField(required = True, label = 'Email address')
116
    first_name = forms.CharField(required = False, max_length = 30)
117
    last_name = forms.CharField(required = False, max_length = 30)
118 102
    inviter = forms.CharField(widget=forms.TextInput(), label=_('Inviter Real Name'))
103
    level = forms.IntegerField(widget=forms.TextInput(), label=_('Level'))
119 104
    
120 105
    class Meta:
121 106
        model = AstakosUser
122
        fields = ("username",)
107
        fields = ("email", "first_name", "last_name")
123 108
    
124 109
    def __init__(self, *args, **kwargs):
125 110
        """
126 111
        Changes the order of fields, and removes the username field.
127 112
        """
128 113
        super(InvitedExtendedUserCreationForm, self).__init__(*args, **kwargs)
129
        self.fields.keyOrder = ['email', 'inviter', 'first_name', 'last_name',
130
                                'password1', 'password2']
114
        self.fields.keyOrder = ['email', 'inviter', 'level', 'first_name',
115
                                'last_name', 'password1', 'password2']
131 116
        #set readonly form fields
132 117
        self.fields['inviter'].widget.attrs['readonly'] = True
118
        self.fields['level'].widget.attrs['readonly'] = True
133 119
        self.fields['email'].widget.attrs['readonly'] = True
134 120
        self.fields['username'].widget.attrs['readonly'] = True
135
    
136
    def clean(self, *args, **kwargs):
137
        """
138
        Normal cleanup + username generation.
139
        """
140
        cleaned_data = super(UserCreationForm, self).clean(*args, **kwargs)
141
        if cleaned_data.has_key('email'):
142
            cleaned_data['username'] = cleaned_data['email']
143
        return cleaned_data
144
        
145
    def save(self, commit=True):
146
        """
147
        Saves the email, first_name and last_name properties, after the normal
148
        save behavior is complete.
149
        """
150
        user = super(InvitedExtendedUserCreationForm, self).save(commit=False)
151
        user.renew_token()
152
        user.save()
153
        logging.info('Created user %s', user)
154
        return user
121

  
122
class LoginForm(AuthenticationForm):
123
    username = forms.EmailField(label=_("Email"))
155 124

  
156 125
class ProfileForm(forms.ModelForm):
157 126
    """
......
163 132
    """
164 133
    class Meta:
165 134
        model = AstakosUser
166
        exclude = ('groups', 'user_permissions')
135
        exclude = ('is_active', 'is_superuser', 'is_staff', 'is_verified', 'groups', 'user_permissions')
167 136
    
168 137
    def __init__(self, *args, **kwargs):
169 138
        super(ProfileForm, self).__init__(*args, **kwargs)
170 139
        instance = getattr(self, 'instance', None)
171 140
        ro_fields = ('username','date_joined', 'updated', 'auth_token',
172 141
                     'auth_token_created', 'auth_token_expires', 'invitations',
173
                     'level', 'last_login', 'email', 'is_active', 'is_superuser',
174
                     'is_staff')
142
                     'level', 'last_login', 'email', )
175 143
        if instance and instance.id:
176 144
            for field in ro_fields:
177 145
                if isinstance(self.fields[field].widget, forms.CheckboxInput):
......
194 162
                                label=u'Message', required=False)
195 163
    feedback_data = forms.CharField(widget=forms.Textarea(),
196 164
                                label=u'Data', required=False)
165

  
166
class SendInvitationForm(forms.Form):
167
    """
168
    Form for sending an invitations
169
    """
170
    
171
    email = forms.EmailField(required = True, label = 'Email address')
172
    first_name = forms.EmailField(label = 'First name')
173
    last_name = forms.EmailField(label = 'Last name')
197 174
    
b/astakos/im/models.py
41 41
from django.conf import settings
42 42
from django.db import models
43 43
from django.contrib.auth.models import User, UserManager
44
from django.utils.translation import ugettext_lazy as _
44 45

  
45 46
from astakos.im.interface import get_quota, set_quota
46 47

  
......
51 52
    # Use UserManager to get the create_user method, etc.
52 53
    objects = UserManager()
53 54
    
54
    affiliation = models.CharField('Affiliation', max_length=255, default='')
55
    provider = models.CharField('Provider', max_length=255, default='')
55
    affiliation = models.CharField('Affiliation', max_length=255, blank=True)
56
    provider = models.CharField('Provider', max_length=255, blank=True)
56 57
    
57 58
    #for invitations
58 59
    level = models.IntegerField('Inviter level', default=4)
b/astakos/im/target/invitation.py
62 62
                              invitation.inviter.level + 1)
63 63
    
64 64
    # in order to login the user we must call authenticate first 
65
    authenticate(username=user.username, auth_token=user.auth_token)
65
    authenticate(email=user.email, auth_token=user.auth_token)
66 66
    next = request.GET.get('next')
67 67
    
68 68
    return prepare_response(request, user, next, 'renew' in request.GET)
b/astakos/im/target/local.py
37 37
from django.shortcuts import render_to_response
38 38
from django.template import RequestContext
39 39
from django.contrib.auth import authenticate
40
from django.contrib.auth.forms import AuthenticationForm
41 40
from django.contrib import messages
42 41
from django.utils.translation import ugettext as _
43 42

  
44 43
from astakos.im.target.util import prepare_response
45 44
from astakos.im.models import AstakosUser
46

  
45
from astakos.im.forms import LoginForm
47 46
from urllib import unquote
48 47

  
49 48
from hashlib import new as newhasher
......
52 51
    """
53 52
    on_failure: whatever redirect accepts as to
54 53
    """
55
    form = AuthenticationForm(data=request.POST)
54
    form = LoginForm(data=request.POST)
56 55
    if not form.is_valid():
57 56
        return render_to_response(on_failure,
58 57
                                  {'form':form},
......
84 83
    
85 84
    user.is_active = True
86 85
    user.save()
87
    return prepare_response(request, user, next, renew=True)
86
    return prepare_response(request, user, next, renew=True, skip_login=True)
b/astakos/im/templates/index.html
12 12
      <div class="span4">
13 13
        <h4>Local account</h4>
14 14
        <form action="{% url astakos.im.target.local.login %}" method="post" class="form-stacked">{% csrf_token %}
15
          {{ form.non_field_errors }}
16
          {% for field in form %}
17
            <div class="field-wrapper">
18
              <div class="label-wrapper">
19
                {% if field.name == "username" %}
20
                  Email address or Username
21
                {% else %}
22
                  {{ field.label_tag }}
23
                {% endif %}
24
              </div>
25
              <div class="value-wrapper">
26
                {{ field }}
27
                {{ field.errors }}
28
              </div>
29
            </div>
30
          {% endfor %}
15
          {{ form.as_p }}
31 16
         <div>
32 17
            <a href="{% url django.contrib.auth.views.password_reset %}">Forgot your password?</a>
33 18
         </div>
b/astakos/im/templates/invitations.html
6 6
<div class="container">
7 7
  <h3>You have {{ user.invitations }} invitation{{ user.invitations|pluralize }} left.</h3>
8 8

  
9
  <!--{% if message %}
10
  <br />
11
  <div class="alert-message {{ status }}">
12
    <p>{{ message }}</p>
13
  </div>
14
  {% endif %}-->
15

  
16 9
  {% if user.invitations %}
17 10
  <br />
18 11
  <h4>Invite someone else:</h4>
b/astakos/im/views.py
54 54
from django.utils.http import urlencode
55 55
from django.utils.translation import ugettext as _
56 56
from django.core.urlresolvers import reverse
57
from django.contrib.auth.forms import AuthenticationForm
58 57
from django.contrib.auth.models import AnonymousUser
59 58
from django.contrib.auth.decorators import login_required
60 59
from django.contrib.sites.models import Site
......
66 65
from astakos.im.models import AstakosUser, Invitation
67 66
from astakos.im.util import isoformat, get_or_create_user, get_context
68 67
from astakos.im.backends import get_backend
69
from astakos.im.forms import ProfileForm, FeedbackForm
68
from astakos.im.forms import ProfileForm, FeedbackForm, LoginForm
70 69

  
71 70
def render_response(template, tab=None, status=200, context_instance=None, **kwargs):
72 71
    """
......
99 98
    
100 99
    """
101 100
    return render_response(template_name,
102
                           form = AuthenticationForm(),
101
                           form = LoginForm(),
103 102
                           context_instance = get_context(request, extra_context))
104 103

  
105 104
def _generate_invitation_code():
......
164 163
    """
165 164
    status = None
166 165
    message = None
167
    inviter = request.user
168

  
166
    inviter = AstakosUser.objects.get(username = request.user.username)
167
    
169 168
    if request.method == 'POST':
170 169
        username = request.POST.get('uniq')
171 170
        realname = request.POST.get('realname')
......
287 286
    signup.html or ``template_name`` keyword argument.
288 287
    """
289 288
    if not backend:
290
            backend = get_backend()
289
            backend = get_backend(request)
291 290
    try:
292
        form = backend.get_signup_form(request)
291
        form = backend.get_signup_form()
293 292
        if request.method == 'POST':
294 293
            if form.is_valid():
295
                status, message = backend.signup(request)
294
                status, message = backend.signup(form)
296 295
                # rollback incase of error
297 296
                if status == messages.ERROR:
298 297
                    transaction.rollback()
299 298
                else:
300 299
                    transaction.commit()
301
                next = request.POST.get('next')
302
                if next:
303
                    return redirect(next)
300
                    next = request.POST.get('next')
301
                    if next:
302
                        return redirect(next)
304 303
                messages.add_message(request, status, message)
305
    except (Invitation.DoesNotExist, Exception), e:
304
    except Invitation.DoesNotExist, e:
306 305
        messages.add_message(request, messages.ERROR, e)
307 306
    return render_response(template_name,
308 307
                           form = form if 'form' in locals() else UserCreationForm(),
b/astakos/settings.d/00-apps.conf
41 41
                               'astakos.im.context_processors.code',
42 42
                               'astakos.im.context_processors.invitations')
43 43

  
44
AUTHENTICATION_BACKENDS = (
45
    'astakos.im.auth_backends.AstakosUserModelCredentialsBackend',
46
    'astakos.im.auth_backends.AstakosUserModelTokenBackend',
47
)
44
AUTHENTICATION_BACKENDS = ('astakos.im.auth_backends.EmailBackend',
45
                            'astakos.im.auth_backends.TokenBackend')
48 46

  
49 47
CUSTOM_USER_MODEL = 'astakos.im.AstakosUser'
50 48

  

Also available in: Unified diff