Question

im running into this problem as i try to run a piece of django code on my osX10.7 , python2.7 django1.4 system. how do i obtain get_hexdigest? do i download it from somewhere?

Kinnovates-MacBook-Pro:platformsite Kinnovate$ sudo python manage.py runserver
Running in development mode.
Running in development mode.
Running in development mode.
Running in development mode.
Validating models...

HACKUING USER MODEL
Unhandled exception in thread started by <bound method Command.inner_run of <django.contrib.staticfiles.management.commands.runserver.Command object at 0x1016bc050>>
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/commands/runserver.py", line 91, in inner_run
    self.validate(display_num_errors=True)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/base.py", line 266, in validate
    num_errors = get_validation_errors(s, app)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/validation.py", line 30, in get_validation_errors
    for (app_name, error) in get_app_errors().items():
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/loading.py", line 158, in get_app_errors
    self._populate()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/loading.py", line 67, in _populate
    self.load_app(app_name)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/loading.py", line 88, in load_app
    models = import_module('.models', app_name)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django_sha2-0.4-py2.7.egg/django_sha2/models.py", line 2, in <module>
    from django_sha2 import auth
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django_sha2-0.4-py2.7.egg/django_sha2/auth.py", line 96, in <module>
    monkeypatch()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django_sha2-0.4-py2.7.egg/django_sha2/auth.py", line 42, in monkeypatch
    from django_sha2 import bcrypt_auth
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django_sha2-0.4-py2.7.egg/django_sha2/bcrypt_auth.py", line 10, in <module>
    from django.contrib.auth.models import get_hexdigest
ImportError: cannot import name get_hexdigest
Was it helpful?

Solution

You are using dev version of Django (1.4), and there is no get_hexdigest method in corresponding module.

Solutions:

  • use 1.3 version (it's the last stable at the moment)
  • implement get_hexdigest yourself (it can be copypasted from here)
  • use another tool (that doesn't have compatibility problems) to solve your task

OTHER TIPS

implement the method yourself (using hashlib instead of hashcompat):

import hashlib
from django.utils.encoding import smart_str


def get_hexdigest(algorithm, salt, raw_password):
    """
    Returns a string of the hexdigest of the given plaintext password and salt
    using the given algorithm ('md5', 'sha1' or 'crypt').
    """
    raw_password, salt = smart_str(raw_password), smart_str(salt)
    if algorithm == 'crypt':
        try:
            import crypt
        except ImportError:
            raise ValueError('"crypt" password algorithm not supported in this environment')
        return crypt.crypt(raw_password, salt)

    if algorithm == 'md5':
        return hashlib.md5(salt + raw_password).hexdigest()
    elif algorithm == 'sha1':
        return hashlib.sha1(salt + raw_password).hexdigest()
    raise ValueError("Got unknown password algorithm type in password.")

Odds are you are using it to encrypt passwords for comparison. Turns out Django 1.5 ( Also 1.4 ? ) is now offering a better utility function:

https://docs.djangoproject.com/en/dev/topics/auth/passwords/#auth-password-storage

Specifically:

check_password(password, encoded) If you’d like to manually authenticate a user by comparing a plain-text password to the hashed password in the database, use the convenience function check_password(). It takes two arguments: the plain-text password to check, and the full value of a user’s password field in the database to check against, and returns True if they match, False otherwise.

make_password(password[, salt, hashers]) Creates a hashed password in the format used by this application. It takes one mandatory argument: the password in plain-text. Optionally, you can provide a salt and a hashing algorithm to use, if you don’t want to use the defaults (first entry of PASSWORD_HASHERS setting). Currently supported algorithms are: 'pbkdf2_sha256', 'pbkdf2_sha1', 'bcrypt_sha256' (see Using bcrypt with Django), 'bcrypt', 'sha1', 'md5', 'unsalted_md5' (only for backward compatibility) and 'crypt' if you have the crypt library installed. If the password argument is None, an unusable password is returned (a one that will be never accepted by check_password()).

is_password_usable(encoded_password) Checks if the given string is a hashed password that has a chance of being verified against check_password().

Legacy Code

def check_master_password(raw_password):
  from django.conf import settings
  from django.contrib.auth.models import get_hexdigest

  enc_password = getattr(settings, 'MASTER_PASSWORD', None)
  if enc_password:
    algo, salt, hsh = enc_password.split('$')
    return hsh == get_hexdigest(algo, salt, raw_password)

New 1.5 Code

def check_master_password(raw_password):
  from django.conf import settings
  from django.contrib.auth.hashers import check_password
  return check_password(raw_password, getattr(settings, 'MASTER_PASSWORD', None))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top