login

https://gitlab.com/kb/login

Password

Brute Force

django-axes will lock out repeated attempts from the same IP address.

To configure:

Add django-axes to requirements/base.txt

Add axes to THIRD_PARTY_APPS in settings/base.py:

THIRD_PARTY_APPS = (
    'axes',

Configure in settings/base.py:

from datetime import timedelta
AXES_COOLOFF_TIME = timedelta(minutes=15)
AXES_FAILURE_LIMIT = 5
AXES_LOCKOUT_TEMPLATE = 'login/axes_lockout_template.html',
AXES_PASSWORD_FORM_FIELD = 'password1'

Note

AXES_COOLOFF_TIME configures a 15 minute cooling off period before the next login attempt can be made.

Note

The axes_lockout_template.html is in the login app.

To administer Axes, the admin app has a list of Access attempts and Access logs at /admin/axes/.

Reset all lockouts and access records:

django-admin.py axes_reset

Clear lockout/records for an ip address:

django-admin.py axes_reset ip

Reset

When a user (or non-user) attemps to reset their password, the Notify users are emailed. For logic, see: https://gitlab.com/kb/login/blob/master/login/forms.py

I think this is a potential risk for a DOS attack. If we get a DOS attack then we could use the PasswordResetAudit model to limit the number of notification emails we send: https://gitlab.com/kb/login/blob/master/login/models.py

To see an audit of password reset attempts, browse to /accounts/password/reset/audit/report/

Validation

Tip

Unit tests for this feature are in the login app.

To add password validators, just add them to this list in settings/base.py.

We have these validators working on a live project:

AUTH_PASSWORD_VALIDATORS = [
    {
       'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'OPTIONS': {
            'min_length': 8,
        }
    },
]

For documentation, see Enabling password validation

Register

If you want to allow users to register on your site, add the following to urls.py:

from login.views import RegisterCreateView

url(regex=r'^accounts/register/$',
    view=RegisterCreateView.as_view(),
    name='register'
    ),

Staff

If you want a member of staff to be able to update user names and passwords for other users:

Create a couple of views in views.py. This will allow you to set the success URL for your project:

from login.views import (
    UpdateUserNameView,
    UpdateUserPasswordView,
)

class MyUpdateUserNameView(UpdateUserNameView):

    def get_success_url(self):
        return reverse('example.test')

class MyUpdateUserPasswordView(UpdateUserPasswordView):

    def get_success_url(self):
        return reverse('example.test')

Add the views to urls.py:

from .views import (
    MyUpdateUserNameView,
    MyUpdateUserPasswordView,
)

url(regex=r'^accounts/user/(?P<pk>\d+)/username/$',
    view=MyUpdateUserNameView.as_view(),
    name='update_user_name',
    ),
url(regex=r'^accounts/user/(?P<pk>\d+)/password/$',
    view=MyUpdateUserPasswordView.as_view(),
    name='update_user_password',
    ),

You can use these views in your project as follows:

<td>
  <a href="{% url 'update_user_name' u.pk %}">
    <i class="fa fa-edit"></i>
    {{ u.username }}
  </a>
</td>
<td>
  <a href="{% url 'update_user_password' u.pk %}">
    <i class="fa fa-edit"></i>
    ********
  </a>
</td>