Making Django 1.5 compatible with django-bcrypt

Last night I took the opportunity to upgrade all of getsentry.com to
Django 1.5. While most things were fairly trivial to sort out, we hit one less obvious (and pretty critical) bug
during the migration surrounding django-bcrypt.

This bug would only present itself if you’ve transitioned from older versions of Django, and therefore have passwords
in the database using the custom algorithm. Specifically, you’ll have passwords in your user’s table that look something
like bc$$somestring$12$somestring.

The fix is actually fairly simple, and just requires you to define a slightly custom legacy backend for django-bcrypt:

from django.contrib.auth.hashers import BCryptPasswordHasher


class DjangoBCryptPasswordHasher(BCryptPasswordHasher):
    """
    Handles legacy passwords which were hashed with the 'bc$' algorithm via
    django-bcrypt.
    """
    algorithm = "bc"

Once you’ve defined the backend, the rest is as simple as adding it to your list of password hashers:

PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.BCryptPasswordHasher',
    'getsentry.utils.auth.DjangoBCryptPasswordHasher',
    'django.contrib.auth.hashers.SHA1PasswordHasher',
    'django.contrib.auth.hashers.MD5PasswordHasher',
)

Update: As pointed out by @chrisstreeter it’s also fairly trivial to do a data migration: https://gist.github.com/streeter/5534008

Original Source

Leave a comment