Skip to content

Commit

Permalink
fixes and improvements
Browse files Browse the repository at this point in the history
* security fixes
* logging confirmation method
* protection for login_confirmation view
* totp name settings
* pep8
* translation
* registration phone require fix
  • Loading branch information
gotlium committed Jun 4, 2014
1 parent a80338e commit b849fcd
Show file tree
Hide file tree
Showing 16 changed files with 253 additions and 66 deletions.
10 changes: 5 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ Open settings:
$ vim demo/settings.py
Replace Twilio credentials in ``AUTH_SMS_BACKEND_AUTH`` to your demo account settings.
Replace Twilio credentials in ``AUTH_SMS_BACKEND_AUTH`` to your demo account settings or change SMS_FORCE to False.

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

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

*Note: activation link will be output on console.*
*Note: activation link will be output to console.*


Screenshots
Expand Down
4 changes: 2 additions & 2 deletions demo/demo/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
'django_extensions',
#'debug_toolbar',
'bootstrap',
# 'djcelery',
'djcelery',
'django_tables2',
'registration',
'south',
Expand Down Expand Up @@ -120,7 +120,7 @@
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

# IMPORTANT: django-secure-auth required configs
AUTH_SMS_FORCE = False
AUTH_SMS_FORCE = True
AUTH_SMS_BACKEND = 'Twilio'

# You can register new account on https://www.twilio.com/ and enter
Expand Down
2 changes: 1 addition & 1 deletion demo/demo/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ <h2>{% block title %}{% endblock %}</h2>

<hr>
<footer>
<p>&copy; django-secure-auth 2013</p>
<p>&copy; django-secure-auth 2014</p>
</footer>
</div>

Expand Down
19 changes: 6 additions & 13 deletions demo/demo/templates/registration/activate.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,10 @@
{% block title %}{% trans 'Registration' %}{% endblock %}

{% block content %}

{% if account %}

<p>{% trans "Account successfully activated" %}</p>

<p><a href="{% url 'auth_login' %}">{% trans "Log in" %}</a></p>

{% else %}

<p>{% trans "Account activation failed" %}</p>

{% endif %}

{% if account %}
<p>{% trans "Account successfully activated" %}</p>
<p><a href="{% url 'auth_login' %}">{% trans "Log in" %}</a></p>
{% else %}
<p>{% trans "Account activation failed" %}</p>
{% endif %}
{% endblock %}
13 changes: 3 additions & 10 deletions secureauth/auth_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,7 @@

from defaults import CAPTCHA_ATTEMPT, CAPTCHA_ENABLED
from captcha.fields import CaptchaField


AUTH_TYPES = (
('', '---'),
('code', _('by code')),
('token', _('by token')),
('phone', _('by sms')),
('question', _('by question')),
)
from models import AUTH_TYPES


def get_available_auth_methods(user):
Expand Down Expand Up @@ -55,12 +47,13 @@ def clean(self):

if auth_type and code:
from secureauth.backend import AuthBackend

backend = AuthBackend()
self.user_cache = backend.auth(self.credentials, auth_type, code)
if self.user_cache is None:
raise forms.ValidationError(_("Please enter correct code"))
elif not self.user_cache.is_active:
raise forms.ValidationError(_("This account is inactive."))
raise forms.ValidationError(_("This account is inactive"))
return self.cleaned_data

def get_user(self):
Expand Down
11 changes: 7 additions & 4 deletions secureauth/defaults.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
# -*- coding: utf-8 -*-

from django.utils.translation import ugettext as _
from django.conf import settings


def get_settings(key, default):
return getattr(settings, key, default)


SMS_FORCE = get_settings('AUTH_SMS_FORCE', False)
SMS_BACKEND = get_settings('AUTH_SMS_BACKEND', 'Twilio')
SMS_BACKEND_AUTH = get_settings('AUTH_SMS_BACKEND_AUTH', [
'ACc73704107c6a5426b2157e279c485d32', 'a2949613dc22aa3df58ea813a6e0747f'
])
SMS_FROM = get_settings('AUTH_SMS_FROM', '+12242315966')
SMS_MESSAGE = get_settings('AUTH_SMS_MESSAGE', 'Your code is: %s')
SMS_MESSAGE = get_settings('AUTH_SMS_MESSAGE', _('Your code is: %s'))
SMS_CODE_LEN = get_settings('AUTH_SMS_CODE_LEN', 4)
SMS_AGE = get_settings('AUTH_SMS_AGE', 60)
SMS_ASCII = get_settings('AUTH_SMS_ASCII', False)
CODE_RANGES = get_settings('AUTH_CODE_RANGES', 20)
CODE_LEN = get_settings('AUTH_CODE_LEN', 6)
TOTP_NAME = get_settings('AUTH_TOTP_NAME', "%(username)s@%(domain)s")

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

# Notification when user is authenticated on site
SMS_NOTIFICATION_SUBJECT = get_settings(
'AUTH_SMS_NOTIFICATION_SUBJECT', 'Auth activity')
'AUTH_SMS_NOTIFICATION_SUBJECT', _('Auth activity'))
CODES_SUBJECT = get_settings(
'AUTH_CODES_SUBJECT', 'Your security codes')
'AUTH_CODES_SUBJECT', _('Your security codes'))
SMS_NOTIFICATION_MESSAGE = get_settings(
'AUTH_SMS_NOTIFICATION_MESSAGE',
"Authorization was made. If it's not you, then contact with us.")
_("Authorization was made. If it's not you, then contact with us."))

USE_CELERY = get_settings(
'AUTH_USE_CELERY', 'djcelery' in settings.INSTALLED_APPS)
Expand Down
28 changes: 17 additions & 11 deletions secureauth/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(self, request, model, *args, **kwargs):
def clean_current_password(self):
current_password = self.cleaned_data.get('current_password', '')
if not self.request.user.check_password(current_password):
raise forms.ValidationError(_(u'Invalid password!'))
raise forms.ValidationError(_(u'Invalid password'))

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

def __init__(self, *args, **kwargs):
def __init__(self, request, *args, **kwargs):
self.decrypt('code', **kwargs)
self.decrypt('question', **kwargs)
super(QuestionForm, self).__init__(*args, **kwargs)
super(QuestionForm, self).__init__(request, *args, **kwargs)

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

try:
UserAuthQuestion.objects.get(user=request.user)
self.fields.pop('code')
except UserAuthQuestion.DoesNotExist:
pass

def save(self):
model = super(QuestionForm, self).save()
return model.set_data(
self.cleaned_data.get('question'), self.cleaned_data.get('code'))


class PasswordCheckForm(forms.ModelForm):
class BaseSettingsForm(forms.ModelForm):
enabled = forms.BooleanField(label=_('Enabled'), required=False)

def __init__(self, request, *args, **kwargs):
self.request = request

super(PasswordCheckForm, self).__init__(*args, **kwargs)
super(BaseSettingsForm, self).__init__(*args, **kwargs)

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


class NotificationForm(PasswordCheckForm):
class NotificationForm(BaseSettingsForm):
class Meta:
model = UserAuthNotification
exclude = ('user',)


class LoggingForm(PasswordCheckForm):
class LoggingForm(BaseSettingsForm):
class Meta:
model = UserAuthLogging
exclude = ('user',)
Expand Down Expand Up @@ -184,7 +190,7 @@ def get_status(model):
def clean_current_password(self):
current_password = self.cleaned_data.get('current_password', '')
if not self._request.user.check_password(current_password):
raise forms.ValidationError(_(u'Invalid password!'))
raise forms.ValidationError(_(u'Invalid password'))

def save(self):
def set_status(model, key):
Expand Down
Binary file modified secureauth/locale/ru/LC_MESSAGES/django.mo
Binary file not shown.
44 changes: 40 additions & 4 deletions secureauth/locale/ru/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-11-24 04:00+0400\n"
"PO-Revision-Date: 2013-11-24 21:43+0230\n"
"PO-Revision-Date: 2014-06-04 13:04+0230\n"
"Last-Translator: <[email protected]>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"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"
"X-Translated-Using: django-rosetta 0.7.3\n"
"X-Translated-Using: django-rosetta 0.7.4\n"

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

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

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

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

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

msgid "Answer"
msgstr "Ответ"

msgid "Current password:"
msgstr "Текущий пароль:"

msgid "Logging settings"
msgstr "Настройка логирования"

msgid "Confirm Method"
msgstr "Метод подтверждения"

msgid "Invalid password"
msgstr "Неверный пароль"

msgid "Successfully saved"
msgstr "Успешно сохранено"

msgid "Your settings has changed"
msgstr "Настройки изменились"

msgid "Codes were sent to the email"
msgstr "Коды отправлены на email"

msgid "Send codes to email"
msgstr "Отправить коды на почту"

msgid "Your code is: %s"
msgstr "Ваш код: %s"

msgid "Auth activity"
msgstr "Код авторизации"

msgid "Your security codes"
msgstr "Ваши коды безопасности"

msgid "Authorization was made. If it's not you, then contact with us."
msgstr "Был произведен вход. Если это не Вы, то свяжитесь с нами."
Loading

0 comments on commit b849fcd

Please sign in to comment.