There is an argument to be made for not using force_bytes, but there is also a semantic difference between “force” and “to”. I wouldn’t think it would be possible to change force_bytes to throw an exception without serious compatibility issues - str() is how lazy objects are resolved IIRC, and there are numerous other places it is called with arguments that need to be cast to a string.
The behavior of the make_password method is quite surprising to be honest, and maybe the advantages of being able to pass any object into the method is entirely academic because nobody passes anything but strings on purpose. On the other hand this is the first post I can remember about this. On Thursday, 12 March 2020 19:55:46 UTC, Dawid Czeluśniak wrote: > > Tom, > > I believe that I found the root cause of this issue. Let's take a closer > look at force_bytes > <https://github.com/django/django/blob/master/django/utils/encoding.py#L82> > function from Django and to_bytes > <https://github.com/pallets/werkzeug/blob/master/src/werkzeug/_compat.py#L195> > > function from Werkzeug (just for comparison). There is one *fundamental* > difference > between these: force_bytes from Django fallbacks to string representation > of the object whereas to_bytes from Werkzeug raises TypeError if it can't > cast the value to bytes. That's why when calling make_password with > object that can't be "easily" cast to bytes returns a generated hash: > > In [1]: from django.contrib.auth.hashers import make_password > > In [2]: make_password([1, 2, 3]) > Out[2]: > 'pbkdf2_sha256$180000$Y9azq0uVWSoh$E7O13LefzP1I4MylXfFYKDkgCnZen6tf+FAblnBYssQ=' > > whereas generate_password_hash from Werkzeug raises TypeError: > > In [16]: from werkzeug.security import generate_password_hash > > In [17]: generate_password_hash([1, 2, 3]) > TypeError: Expected bytes > > IMHO throwing an exception is a more reasonable approach. > > Anyway, thank you for your help :) > Dawid > > On Thursday, 12 March 2020 19:17:15 UTC+1, Tom Forbes wrote: >> >> In this context it means that you shouldn’t encrypt, hash or otherwise >> manipulate the password before passing it into the method. >> >> Django, many other packages and Python itself will accept objects that >> can be coerced into a string (via __str__) rather than throw an exception. >> We’re all consenting adults here - if you want to pass a non-string object >> into “make_password” then that’s up to you. >> >> The question really is if this is a common enough mistake to warrant a >> guard against strange input. I’d say no, however a small change to the >> documentation might be in order. >> >> Tom >> >> On 12 Mar 2020, at 17:41, Dawid Czeluśniak <czelusn...@gmail.com> wrote: >> >> Adam, >> >> If it's perfectly fine to pass almost any not-None object to >> make_password function and it returns correctly generated hash then why >> does the documentation say: >> >> make_password(password, salt=None, hasher='default') >>> Creates a hashed password in the format used by this application. It >>> takes one mandatory argument: the password in *plain-text*. >> >> >> >> https://docs.djangoproject.com/en/3.0/topics/auth/passwords/#django.contrib.auth.hashers.make_password >> >> What does "plain-text" mean there? >> >> Thanks, >> Dawid >> >> >> >> On Thursday, 12 March 2020 18:18:59 UTC+1, Adam Johnson wrote: >>> >>> User provided passwords are validated already: >>> https://docs.djangoproject.com/en/3.0/topics/auth/passwords/#module-django.contrib.auth.password_validation >>> >>> When using set_password directly, you as the programmer are responsible >>> for ensuring the value you use for password is valid. Normally this means >>> calling the functions detailed in "Integrating validation" beforehand. >>> >>> -- >>> Adam >>> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Django developers (Contributions to Django itself)" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to django-d...@googlegroups.com. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/django-developers/bda75e4c-2dae-42ef-91f3-c3054031c800%40googlegroups.com >> >> <https://groups.google.com/d/msgid/django-developers/bda75e4c-2dae-42ef-91f3-c3054031c800%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> >> >> -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/c36ce153-4464-4fac-b620-a2c9a2d80e2f%40googlegroups.com.