web-dev-qa-db-fra.com

Utilisateurs dans le montage de données initial

Je crée quelques utilisateurs par défaut dans mon fixtures/initial_data.json afin d'avoir des "sujets" de test. Le problème que je rencontre est la génération de mot de passe. Je pourrais définir le mot de passe dans les "champs", mais cela ne générera pas de mot de passe haché:

[
    { "model": "auth.user",
        "pk": 1,
        "fields": {
            "username": "user1",
            "password": "password"
        }
    }
]

J'ai besoin d'un moyen de générer le mot de passe de l'utilisateur. Dois-je le faire manuellement et générer une chaîne comme {hash_method}${salt}${hashed_password} comme Django fait?

51
Naftuli Kay

Ce qui pourrait être plus facile dans ce cas (et si vous n'avez besoin que de quelques utilisateurs) est de créer de faux comptes d'utilisateurs via l'administrateur (y compris les mots de passe), puis de vider les utilisateurs dans un fichier d'installation à l'aide de dumpdata :

$ python manage.py dumpdata auth.User --indent 4 > users.json

qui créera automatiquement les appareils pour vous et pourra être utilisé plus tard avec loaddata

(Vous pouvez simplement créer un faux compte et utiliser le hachage dans le reste de vos appareils si vous avez besoin de beaucoup d'utilisateurs de test)

https://docs.djangoproject.com/en/dev/ref/Django-admin/#dumpdata-appname-appname-appname-model

92
Timmy O'Mahony

D'accord, je suis d'accord avec les réponses, mais permettez-moi de répondre aux questions originales.

Comment obtenir le mot de passe "comme Django l'aurait haché"?

Regardons le fichier Django/contrib/auth/hashers.py:

def make_password(password, salt=None, hasher='default'):
    """
    Turn a plain-text password into a hash for database storage

    Same as encode() but generates a new random salt.  If
    password is None or blank then UNUSABLE_PASSWORD will be
    returned which disallows logins.
    """
    # ...

Voir cet exemple de session:

./manage.py Shell

>>> from Django.contrib.auth.hashers import make_password, HASHERS
>>> make_password('test')
'pbkdf2_sha256$10000$vkRy7QauoLLj$ry+3xm3YX+YrSXbri8s3EcXDIrx5ceM+xQjtpLdw2oE='

# fix salt:
>>> make_password('test', 'abc')
'pbkdf2_sha256$10000$abc$MqJS5OAgSmf9SD9mfoY8fgLo8sSKmEcef0AjjMp1Q7w='

# use different (maybe faster, maybe unsafe!) hasher

In [12]: HASHERS
Out[12]:
{'bcrypt': <Django.contrib.auth.hashers.BCryptPasswordHasher object at 0x29c6d50>,
 'crypt': <Django.contrib.auth.hashers.CryptPasswordHasher object at 0x29c6f50>,
 'md5': <Django.contrib.auth.hashers.MD5PasswordHasher object at 0x29c6e10>,
 'pbkdf2_sha1': <Django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher object at 0x29c6bd0>,
 'pbkdf2_sha256': <Django.contrib.auth.hashers.PBKDF2PasswordHasher object at 0x29c6cd0>,
 'sha1': <Django.contrib.auth.hashers.SHA1PasswordHasher object at 0x29c6dd0>,
 'unsalted_md5': <Django.contrib.auth.hashers.UnsaltedMD5PasswordHasher object at 0x29c6ed0>,
 'unsalted_sha1': <Django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher object at 0x29c6e50>}

In [14]: [make_password('test', hasher=name) for name in HASHERS]
Out[14]:
['sha1$LdKsAbJRjlVP$2eb2346387cc510f576f2f11eebdfe18b20d1be1',
 'pbkdf2_sha256$10000$Ck8gtWQJnJ9x$M/OqP548d5KcPqFuVRgXb84unjYbYDH6oyimbDndE3k=',
 'pbkdf2_sha1$10000$BJqRu5OwylVF$hUvMLIzBujt9kPbML/dei1vLiMQ=',
 'crypt$$d9grSeqDhMFek',
 '098f6bcd4621d373cade4e832627b4f6',
 'sha1$$a94a8fe5ccb19ba61c4c0873d391e987982fbbd3',
 'bcrypt$$2a$12$WlJP5zm2lmdJ4g/pSE1xF.d/8w.XRT5mo/vGlkKdglBtzcxKw7XJS',
 'md5$txHYmSYJKhD4$69286d4a1abd348fbddc9df7687e2ed4']

Vous pouvez également utiliser manuellement la méthode encode du hash, mais la fonction utilitaire ci-dessus vous a couvert de manière plus simple.

18
Tomasz Gandor

Je suis tombé sur le même problème lors de l'écriture d'appareils pour les tests. Voici comment je gère cela dans les tests unitaires.

Créer des données à partir de l'admin et les vider dans des fixtures fonctionne mais je n'aime pas trop être dépendant de le faire manuellement. Alors, voici ce que je fais -

Créez le luminaire comme vous l'avez fait, puis dans la méthode setUp, set_passwords pour les utilisateurs.

ser_fixture.json

[
    { "model": "auth.user",
        "pk": 1,
        "fields": {
            "username": "user1",
            "password": "password"
        }
    }
]

test_user.py

def setUp(self):
    self.User = get_user_model()

    # Fix the passwords of fixtures
    for user in self.User.objects.all():
        user.set_password(user.password)
        user.save()

De cette façon, je peux écrire proprement les mots de passe dans le luminaire et y faire référence lorsque j'en ai besoin et créer plus de luminaires simplement en éditant le fichier du luminaire.

12
Gaurav Butola

Pour ajouter à la réponse de @GauravButola, j'ai créé une commande de gestion personnalisée pour charger le luminaire et corriger les mots de passe en une seule étape. Ceci est utile lorsque vous n'utilisez pas de framework de test pour effectuer la configuration des mots de passe. L'exemple fonctionne avec Django 1.11 et probablement les versions antérieures.

Dans votre application fournissant le luminaire, ajoutez votre commande de gestion (c'est python3 fois, j'ai donc omis l'init pys):

yourapp/
    models.py
    fixtures/
        initial_data.json
    management/
        commands/
            initdata.py

Avec initdata.py ressemblant à ceci:

from Django.core.management import BaseCommand, call_command
from Django.contrib.auth.models import User
# from yourapp.models import User # if you have a custom user


class Command(BaseCommand):
    help = "DEV COMMAND: Fill databasse with a set of data for testing purposes"

    def handle(self, *args, **options):
        call_command('loaddata','initial_data')
        # Fix the passwords of fixtures
        for user in User.objects.all():
            user.set_password(user.password)
            user.save()

Vous pouvez maintenant charger vos données_initiales et avoir des mots de passe valides en appelant:

./manage.py initdata
4
itsafire

Vider les informations des utilisateurs à partir de DataBase:

$ python manage.py dumpdata auth.User --indent 4 > users.json

Importer/charger des données spécifiques au dispositif JSON:

$ python manage.py loaddata users.json
2
Cubiczx

à peu près sûr que vous le faites. ça ne devrait pas être si difficile. la manière la plus simple serait de regarder la fonction user.set_password je pense que oui, et regardez comment ils le font. vous pouvez probablement appeler la fonction depuis un terminal python puis la copier dans vos données initiales!

0
mpen