Hello,

This is my fist post, so I'm not fully aware of any posting policies you 
have, but at least I'll try to present my ideas in clear way.

*Very brief description of what I suggest:*

Optionally delegate password change and password reset to authentication 
backend.

*Motivation:*

Django framework is very popular and widely used not only for public, but 
for private projects too. To make it clear, by private I mean not only 
personal, but mostly corporate intranet projects.

One of the important part of any corporate project is some kind of single 
sing on (SSO) or, at least, integration with external authentication 
backend. From my experience it may be any service able to validate 
credentials. LDAP is most often used for authentication purposes, however, 
it is not the only available choice. I had projects with authentication 
delegated to custom HTTP web-services, SMTP, POP3 and IMAP servers, and so 
on. Corporate intranet you have to deal with may be a zoo of unbelievably 
non-standard software. Also, even if we’ll talk about LDAP, it may be a 
few, more than one, LDAP servers you have to try authentication against, 
like Active Directory and OpenLDAP.

Current implementation of User model as well as standard forms, delegates 
to backend authentication only, but not password reset or change. This 
forces to reimplementation of user model and/or reimplementation of 
standard forms for very common tasks, high coupling and bad architecture. 
Also, if left as is, behavior is very inconsistent, since user is 
authenticated against one password database (LDAP), but changes or resets 
password in another (relational model database). And while LDAP may be 
administered externally by standard web tools, this is not a good option 
too, since means inconsistent user experience. And custom HTTP services 
cannot be administered by standard tools at all.

*Implementation:*

As far as I can see User model is already annotated with backend field
https://github.com/django/django/blob/master/django/contrib/auth/__init__.py#L75
 
so it is possible, and looks simple, to delegate password change and reset 
to backend, if backend support these operations, which means 
AbstractBaseUser.set_password method
https://github.com/django/django/blob/master/django/contrib/auth/models.py#L226 

should be refactored to two methods: reset_password and change_password 
instead of one set_password, and these two method should delegate operation 
to backend if supported. (set_password may be left as alias of 
reset_password). Signatures will be

def reset_password(self, new_password)
def change_password(self, old_password, new_password)

Also authentication forms
https://github.com/django/django/blob/master/django/contrib/auth/models.py#L226 

should be refactored to use these new reset_password and change_password 
methods. There must be two methods, as change_password and reset_password 
may not be both available, also change_password requires old password as 
backend may require it. Returning to LDAP, there may be various policies 
which should be respected, like not to change password too often, but reset 
whenever you want, so we need two separate methods.

*Backward compatibility:*

As far as I can see change is backwards compatible. Authentication backends 
not providing extra operations will behave old way without any change.

*Patch:*

I wanted my design to be reviewed before I’ll try to provide any patch. 
I'mm pretty sure I've missed something, so discussion is welcome. Also, 
this will be my first code for Django project, so I'll probably break some 
rules and will need some help.
With best regards,
Roman

-- 
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/280b8270-19b7-4ad4-840c-7f716564102d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to