Skip to content

Commit b849fcd

Browse files
committed
fixes and improvements
* security fixes * logging confirmation method * protection for login_confirmation view * totp name settings * pep8 * translation * registration phone require fix
1 parent a80338e commit b849fcd

File tree

16 files changed

+253
-66
lines changed

16 files changed

+253
-66
lines changed

README.rst

+5-5
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ Open settings:
2525
$ vim demo/settings.py
2626
2727
28-
Replace Twilio credentials in ``AUTH_SMS_BACKEND_AUTH`` to your demo account settings.
28+
Replace Twilio credentials in ``AUTH_SMS_BACKEND_AUTH`` to your demo account settings or change SMS_FORCE to False.
2929

30-
Run RabbitMQ server and Celery daemon(or remove 'djcelery' from ``INSTALLED_APPS``):
30+
Run Redis server and Celery daemon(or remove 'djcelery' from ``INSTALLED_APPS``):
3131

3232
.. code-block:: bash
3333
34-
$ rabbitmq-server -detached
35-
$ python manage.py celeryd --loglevel=info >& /dev/null &
34+
$ redis-server >& /dev/null &
35+
$ python manage.py celeryd --loglevel=info >& /tmp/celery.log &
3636
3737
3838
Run test server:
@@ -45,7 +45,7 @@ Run test server:
4545
Now you can open http://127.0.0.1:8000/accounts/register/ and register
4646
new account and setup all available authentication methods.
4747

48-
*Note: activation link will be output on console.*
48+
*Note: activation link will be output to console.*
4949

5050

5151
Screenshots

demo/demo/settings.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
'django_extensions',
8484
#'debug_toolbar',
8585
'bootstrap',
86-
# 'djcelery',
86+
'djcelery',
8787
'django_tables2',
8888
'registration',
8989
'south',
@@ -120,7 +120,7 @@
120120
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
121121

122122
# IMPORTANT: django-secure-auth required configs
123-
AUTH_SMS_FORCE = False
123+
AUTH_SMS_FORCE = True
124124
AUTH_SMS_BACKEND = 'Twilio'
125125

126126
# You can register new account on https://www.twilio.com/ and enter

demo/demo/templates/base.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ <h2>{% block title %}{% endblock %}</h2>
9595

9696
<hr>
9797
<footer>
98-
<p>&copy; django-secure-auth 2013</p>
98+
<p>&copy; django-secure-auth 2014</p>
9999
</footer>
100100
</div>
101101

demo/demo/templates/registration/activate.html

+6-13
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,10 @@
44
{% block title %}{% trans 'Registration' %}{% endblock %}
55

66
{% block content %}
7-
8-
{% if account %}
9-
10-
<p>{% trans "Account successfully activated" %}</p>
11-
12-
<p><a href="{% url 'auth_login' %}">{% trans "Log in" %}</a></p>
13-
14-
{% else %}
15-
16-
<p>{% trans "Account activation failed" %}</p>
17-
18-
{% endif %}
19-
7+
{% if account %}
8+
<p>{% trans "Account successfully activated" %}</p>
9+
<p><a href="{% url 'auth_login' %}">{% trans "Log in" %}</a></p>
10+
{% else %}
11+
<p>{% trans "Account activation failed" %}</p>
12+
{% endif %}
2013
{% endblock %}

secureauth/auth_forms.py

+3-10
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,7 @@
77

88
from defaults import CAPTCHA_ATTEMPT, CAPTCHA_ENABLED
99
from captcha.fields import CaptchaField
10-
11-
12-
AUTH_TYPES = (
13-
('', '---'),
14-
('code', _('by code')),
15-
('token', _('by token')),
16-
('phone', _('by sms')),
17-
('question', _('by question')),
18-
)
10+
from models import AUTH_TYPES
1911

2012

2113
def get_available_auth_methods(user):
@@ -55,12 +47,13 @@ def clean(self):
5547

5648
if auth_type and code:
5749
from secureauth.backend import AuthBackend
50+
5851
backend = AuthBackend()
5952
self.user_cache = backend.auth(self.credentials, auth_type, code)
6053
if self.user_cache is None:
6154
raise forms.ValidationError(_("Please enter correct code"))
6255
elif not self.user_cache.is_active:
63-
raise forms.ValidationError(_("This account is inactive."))
56+
raise forms.ValidationError(_("This account is inactive"))
6457
return self.cleaned_data
6558

6659
def get_user(self):

secureauth/defaults.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,38 @@
11
# -*- coding: utf-8 -*-
22

3+
from django.utils.translation import ugettext as _
34
from django.conf import settings
45

56

67
def get_settings(key, default):
78
return getattr(settings, key, default)
89

10+
911
SMS_FORCE = get_settings('AUTH_SMS_FORCE', False)
1012
SMS_BACKEND = get_settings('AUTH_SMS_BACKEND', 'Twilio')
1113
SMS_BACKEND_AUTH = get_settings('AUTH_SMS_BACKEND_AUTH', [
1214
'ACc73704107c6a5426b2157e279c485d32', 'a2949613dc22aa3df58ea813a6e0747f'
1315
])
1416
SMS_FROM = get_settings('AUTH_SMS_FROM', '+12242315966')
15-
SMS_MESSAGE = get_settings('AUTH_SMS_MESSAGE', 'Your code is: %s')
17+
SMS_MESSAGE = get_settings('AUTH_SMS_MESSAGE', _('Your code is: %s'))
1618
SMS_CODE_LEN = get_settings('AUTH_SMS_CODE_LEN', 4)
1719
SMS_AGE = get_settings('AUTH_SMS_AGE', 60)
1820
SMS_ASCII = get_settings('AUTH_SMS_ASCII', False)
1921
CODE_RANGES = get_settings('AUTH_CODE_RANGES', 20)
2022
CODE_LEN = get_settings('AUTH_CODE_LEN', 6)
23+
TOTP_NAME = get_settings('AUTH_TOTP_NAME', "%(username)s@%(domain)s")
2124

2225
# Available: code, token, phone, question
2326
DEFAULT_AUTH_TYPE = get_settings('AUTH_DEFAULT_TYPE', 'phone')
2427

2528
# Notification when user is authenticated on site
2629
SMS_NOTIFICATION_SUBJECT = get_settings(
27-
'AUTH_SMS_NOTIFICATION_SUBJECT', 'Auth activity')
30+
'AUTH_SMS_NOTIFICATION_SUBJECT', _('Auth activity'))
2831
CODES_SUBJECT = get_settings(
29-
'AUTH_CODES_SUBJECT', 'Your security codes')
32+
'AUTH_CODES_SUBJECT', _('Your security codes'))
3033
SMS_NOTIFICATION_MESSAGE = get_settings(
3134
'AUTH_SMS_NOTIFICATION_MESSAGE',
32-
"Authorization was made. If it's not you, then contact with us.")
35+
_("Authorization was made. If it's not you, then contact with us."))
3336

3437
USE_CELERY = get_settings(
3538
'AUTH_USE_CELERY', 'djcelery' in settings.INSTALLED_APPS)

secureauth/forms.py

+17-11
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def __init__(self, request, model, *args, **kwargs):
3535
def clean_current_password(self):
3636
current_password = self.cleaned_data.get('current_password', '')
3737
if not self.request.user.check_password(current_password):
38-
raise forms.ValidationError(_(u'Invalid password!'))
38+
raise forms.ValidationError(_(u'Invalid password'))
3939

4040
def save(self):
4141
if not self.user:
@@ -101,26 +101,32 @@ class QuestionForm(BasicForm):
101101
question = forms.CharField(label=_('Question'), required=True)
102102
code = forms.CharField(label=_('code'), required=True, max_length=16)
103103

104-
def __init__(self, *args, **kwargs):
104+
def __init__(self, request, *args, **kwargs):
105105
self.decrypt('code', **kwargs)
106106
self.decrypt('question', **kwargs)
107-
super(QuestionForm, self).__init__(*args, **kwargs)
107+
super(QuestionForm, self).__init__(request, *args, **kwargs)
108108

109-
if kwargs.get('initial') or (args[2] and args[2].get('code')):
110-
self.fields['code'].widget = forms.HiddenInput()
111109
self.fields['code'].label = _('Answer')
112110

111+
try:
112+
UserAuthQuestion.objects.get(user=request.user)
113+
self.fields.pop('code')
114+
except UserAuthQuestion.DoesNotExist:
115+
pass
116+
113117
def save(self):
114118
model = super(QuestionForm, self).save()
115119
return model.set_data(
116120
self.cleaned_data.get('question'), self.cleaned_data.get('code'))
117121

118122

119-
class PasswordCheckForm(forms.ModelForm):
123+
class BaseSettingsForm(forms.ModelForm):
124+
enabled = forms.BooleanField(label=_('Enabled'), required=False)
125+
120126
def __init__(self, request, *args, **kwargs):
121127
self.request = request
122128

123-
super(PasswordCheckForm, self).__init__(*args, **kwargs)
129+
super(BaseSettingsForm, self).__init__(*args, **kwargs)
124130

125131
if CHECK_PASSWORD is True:
126132
self.fields['current_password'] = forms.CharField(
@@ -129,16 +135,16 @@ def __init__(self, request, *args, **kwargs):
129135
def clean_current_password(self):
130136
current_password = self.cleaned_data.get('current_password', '')
131137
if not self.request.user.check_password(current_password):
132-
raise forms.ValidationError(_(u'Invalid password!'))
138+
raise forms.ValidationError(_(u'Invalid password'))
133139

134140

135-
class NotificationForm(PasswordCheckForm):
141+
class NotificationForm(BaseSettingsForm):
136142
class Meta:
137143
model = UserAuthNotification
138144
exclude = ('user',)
139145

140146

141-
class LoggingForm(PasswordCheckForm):
147+
class LoggingForm(BaseSettingsForm):
142148
class Meta:
143149
model = UserAuthLogging
144150
exclude = ('user',)
@@ -184,7 +190,7 @@ def get_status(model):
184190
def clean_current_password(self):
185191
current_password = self.cleaned_data.get('current_password', '')
186192
if not self._request.user.check_password(current_password):
187-
raise forms.ValidationError(_(u'Invalid password!'))
193+
raise forms.ValidationError(_(u'Invalid password'))
188194

189195
def save(self):
190196
def set_status(model, key):
981 Bytes
Binary file not shown.

secureauth/locale/ru/LC_MESSAGES/django.po

+40-4
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ msgstr ""
99
"Project-Id-Version: PACKAGE VERSION\n"
1010
"Report-Msgid-Bugs-To: \n"
1111
"POT-Creation-Date: 2013-11-24 04:00+0400\n"
12-
"PO-Revision-Date: 2013-11-24 21:43+0230\n"
12+
"PO-Revision-Date: 2014-06-04 13:04+0230\n"
1313
"Last-Translator: <[email protected]>\n"
1414
"Language-Team: LANGUAGE <[email protected]>\n"
1515
"MIME-Version: 1.0\n"
1616
"Content-Type: text/plain; charset=UTF-8\n"
1717
"Content-Transfer-Encoding: 8bit\n"
1818
"Language: \n"
1919
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
20-
"X-Translated-Using: django-rosetta 0.7.3\n"
20+
"X-Translated-Using: django-rosetta 0.7.4\n"
2121

2222
msgid "Russian"
2323
msgstr "Русский"
@@ -125,7 +125,7 @@ msgstr "код"
125125
msgid "Please enter correct code"
126126
msgstr "Пожалуйста, введите правильный код"
127127

128-
msgid "This account is inactive."
128+
msgid "This account is inactive"
129129
msgstr "Эта учетная запись неактивна."
130130

131131
msgid "Enabled"
@@ -373,7 +373,7 @@ msgid "SMS was sent!"
373373
msgstr "Код был выслан к Вам на мобильный телефон"
374374

375375
msgid "Default backend can not be removed"
376-
msgstr "Нельзя удалить настройки"
376+
msgstr "Нельзя удалить настройки по умолчанию"
377377

378378
msgid "Auth method was disabled"
379379
msgstr "Один из методов аутентификации был отключен"
@@ -395,3 +395,39 @@ msgstr "Уведомления отключены. Если это не Вы, п
395395

396396
msgid "Answer"
397397
msgstr "Ответ"
398+
399+
msgid "Current password:"
400+
msgstr "Текущий пароль:"
401+
402+
msgid "Logging settings"
403+
msgstr "Настройка логирования"
404+
405+
msgid "Confirm Method"
406+
msgstr "Метод подтверждения"
407+
408+
msgid "Invalid password"
409+
msgstr "Неверный пароль"
410+
411+
msgid "Successfully saved"
412+
msgstr "Успешно сохранено"
413+
414+
msgid "Your settings has changed"
415+
msgstr "Настройки изменились"
416+
417+
msgid "Codes were sent to the email"
418+
msgstr "Коды отправлены на email"
419+
420+
msgid "Send codes to email"
421+
msgstr "Отправить коды на почту"
422+
423+
msgid "Your code is: %s"
424+
msgstr "Ваш код: %s"
425+
426+
msgid "Auth activity"
427+
msgstr "Код авторизации"
428+
429+
msgid "Your security codes"
430+
msgstr "Ваши коды безопасности"
431+
432+
msgid "Authorization was made. If it's not you, then contact with us."
433+
msgstr "Был произведен вход. Если это не Вы, то свяжитесь с нами."

0 commit comments

Comments
 (0)