First, to me, this is not obviously a 'very small feature'.
Second, is there any reason it has to be in core? Ideally it could be
implemented in 3rd party library. At that point it would be useful to
you, and we could assess whether it is general enough to be in core.
If it can't be implemented as a 3rd party solution, then it requires
some invasive change to Django itself, which means it is very definitely
not a small feature, and would require much more discussion about how it
would be configured etc. It is much less likely to be accepted if it is
being forced on everyone, or if it requires some new setting to control it.
Third, the need for things like checking password strength means there
probably isn't going to a one-size-fits-all solution. I think this
should be a 3rd party library.
Luke
--
"If we could just get everyone to close their eyes and visualise
world peace for an hour, imagine how serene and quiet it would be
until the looting started" -- Anon
Luke Plant || http://lukeplant.me.uk/
django.auth already provides a password reset mechanism, where users
can get a password reset link.
So, woudn't this work for you?:
1) Create users with a large random password. Destroy every copy of the password
2) Use the reset password feature with their email to force it to set
an initial value
That way you never send them actual passwords, and the only passwords
they can use are the ones they set.
all of this works with no additional support needed from django
D.
That would work, and I'd recommend using the provided
set_unusable_password method instead of setting a random password for
additional security.
django.auth already provides a password reset mechanism, where users
can get a password reset link.
So, woudn't this work for you?:
1) Create users with a large random password. Destroy every copy of the password
2) Use the reset password feature with their email to force it to set
an initial value
That way you never send them actual passwords, and the only passwords
they can use are the ones they set.
all of this works with no additional support needed from django
> How so do you find it an invasive change? I think it could be solved
> easily, even without being backwards incompatible.
I didn't say it was invasive. I said that if it's *not* invasive then it
can be implemented as a 3rd party library. If that was done, we could
assess and see if it was general enough to be used in contrib.
> This type of login behavior is standard in Google Apps, which is why I
> find it not to be something I've made up just for my own needs!
>
> Here's a way to do it:
>
> When a user has never been logged in, User.last_login is the same as
> User.date_joined -- so we actually do not need a new model field! We
> can rely on this behavior as a sort of "intended" logical derivation
> from the fact that they are equal :) Furthermore, I would propose of
> course to make the behavior configurable and turned off by default.
>
> The whole conditional redirect could easily be put in
> django.contrib.auth.views - all we need to do is put 4 lines of code
> on each side of auth_login(request, user) in the login(...) view -
> like 'dis:
What you have suggested here **is** an invasive change, because it
requires changes to existing code paths. A setting is not a good way to
make something configurable here. A keyword argument here *would* be an
acceptable solution.
However, I don't think it would be that useful, because if it was off by
default, and controlled by a keyword argument, then the admin login view
wouldn't use it. I think this needs more thought.
Again, I should mention that features like this get implemented by the
community. If you need it, the way to do it is to build it, and then
persuade us to use it - not to try to persuade *us* to build it :-)
The logic can be implemented as 3rd party view than people can plug into
their projects.
> def login(request, template_name='registration/login.html',
> redirect_field_name=REDIRECT_FIELD_NAME,
> authentication_form=AuthenticationForm,
> current_app=None, extra_context=None):
> """
> Displays the login form and handles the login action.
> """
>
> (...)
>
> if form.is_valid():
>
> (...)
>
> # The form is valid... and now I would propose inserting
> something like:
> user = form.get_user()
> force_password_reset = False
> if settings.AUTH_FORCE_USER_PASSWORD_RESET and
> user.last_login == user.date_joined:
> force_password_reset = True
>
> # Okay, security checks complete. Log the user in.
> auth_login(request, user)
>
> if force_password_reset:
> # Manipulate last_login so that the user will be
> consistently redirected on each login, until the password is reset.
> user.last_login = user.date_joined
> user.save()
> redirect_to =
> reverse('django.contrib.auth.views.password_reset'))
>
BTW - this doesn't actually force the password reset - it logs them in
and then asks them to change their password. If they don't they are
still logged in.