- August 26, 2007
- password hash crypt
- 0 (after 0 ratings)
This snippet uses signals to replace the
contrib.auth.models.User.set_password() function with one that uses crypt instead of sha1 to hash the password.
Crypt is of course cryptographically inferior to sha1, but this may be useful for interoperability with legacy systems e.g. when sharing a user authentication database with unix, a MTA etc.
For some reason the
User class doesn't emit a
class_prepared signal, which would otherwise be a better choice here. That's why I had to resort to patching each
User instance separately.
A clean way to deploy this snippet is to place it in the
models.py of an otherwise empty app, and add the app in
settings.INSTALLED_APPS. The order of
INSTALLED_APPS doesn't matter since we're patching instances, not classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# Place an otherwise blank app in settings.INSTALLED_APPS # and add the following into the app's models.py: from django.db.models import signals from django.dispatch import dispatcher from django.contrib.auth import models as auth_app import new, crypt, random, string from django.utils.encoding import smart_str def set_password_crypt(self, raw_password): algo = 'crypt' saltchars = string.ascii_letters + string.digits + './' salt = ''.join(random.choice(saltchars) for i in range(2)) hsh = crypt.crypt(smart_str(raw_password), salt) self.password = '%s$%s$%s' % (algo, salt, hsh) def replace_set_password(instance=None): instance.set_password = new.instancemethod( set_password_crypt, instance, instance.__class__) dispatcher.connect(replace_set_password, sender=auth_app.User, signal=signals.post_init)