models.PasswordField

2,915 views
Skip to first unread message

stefan...@gmail.com

unread,
Sep 30, 2006, 9:30:28 PM9/30/06
to Django developers
Hello.

I just started playing around with django and immediately stumbled
across a minor issue that I'd like to hear your views on.

The problem is that I'd like to define one of my fields in a model as a
password field and have the administration interface handle that
properly.

I took a look at the code and got well on my way implementing this
myself but then ran into some problems (I'm a beginner at python too
and I've never ever done any HTML work).

So here's my PasswordField I added to the
django/db/models/fields/__init__.py:
------------------------
import sha, md5, hmac
...
class PasswordField(CharField):
def __init__(self, algorithm=None, *args, **kwargs):
kwargs['maxlength'] = 75
self.algorithm = algorithm
CharField.__init__(self, *args, **kwargs)

def get_internal_type(self):
return "CharField"

def get_manipulator_field_objs(self):
return [forms.PasswordField]

def get_db_prep_save(self, value):
hvalue={
None:lambda x: x,
'sha1':lambda x: sha.new(x).hexdigest(),
'md5':lambda x: md5.new(x).hexdigest(),
'hmac':lambda x: hmac.new(x).hexdigest()
}[self.algorithm](value)
return Field.get_db_prep_save(self, hvalue)
----------------------
So the idea here is that you could create a password field in your
model where it would optionally be automatically hashed for you into
the database if you supply a valid value for "algorithm".

This pretty much works... if I add a new "user" object and type in a
password, the password will appear in a password dialog in the admin
interface now.

But there are some issues:
1) The value of the hashed password is read back into the password
field when editing a user. This is a big no-no since the password hash
is actually viewable by doing "view page source". Besides... this will
result in an endless loop of saving the hashed hash of the password if
you update a user. So there is a major problem with updating in the
above code.
2) I was having problems with Firefox and this layout... firefox seemed
to "remember" values to put into these fields which effectively
overwrote the values that were actually supposed to be there (I always
got the same username filled into that field if I wanted to update a
user).
3) As I gather, python 2.5 has deprecated the way that I use to
calculate the hash values in favor of using "hashlib.md5('text to
hash').hexdigest()". I doubt this is a problem but I don't know what
policy (if any) you guys have on deprecated API.

Possible solutions:
1) Don't read the password back into a password field when updating.
Instead, have two password fields (one for confirmation) and handle
updates in such a way that if both of these password fields have
something typed in them and the content matches, update the password.
If they are both empty, do nothing (keep the old password). If either
of them has something typed in and it doesn't match, fail on validation
pointing out that the passwords don't match.
2) Turn off autocompletion for this somehow... as I said, I have no
HTML experience and so I don't know how best to handle this.

Any thoughts, comments or discussion would be appreciated on this one.
I personally feel that adding this type of a field type would be very
beneficial (much more so than the american phone number validation or
the US state field... and yes, I'm bias... I'm european ;-)

Oh, and be gentle... I only just started to look at django (yesterday)
and my python skills are very rusty... so there are probably things
that I'm doing wrong in the above code.

Kind regards, Stefan Freyr.

James Bennett

unread,
Sep 30, 2006, 9:47:58 PM9/30/06
to django-d...@googlegroups.com
On 9/30/06, stefan...@gmail.com <stefan...@gmail.com> wrote:
> The problem is that I'd like to define one of my fields in a model as a
> password field and have the administration interface handle that
> properly.

The model system doesn't have a password field, but the manipulator
system does, which means you can represent a password field in a form
-- which is the only place that the special handling matters -- and
store it as a normal CharField in the model.

For hints on handling hashed password generation, you might also want
to look at the CreateUserForm manipulator in
django.contrib.auth.forms, and the 'create_user' method of the custom
manager class for django.contrib.auth.models.User. Additionally, the
view the admin app uses to create users provides a good example of how
to build your own custom view+manipulator and integrate them into the
admin.

--
"May the forces of evil become confused on the way to your house."
-- George Carlin

stefan...@gmail.com

unread,
Oct 1, 2006, 9:23:14 AM10/1/06
to Django developers
Hi and thanks for your quick reply.

I should note that I haven't tried what you suggested and to be honest
it sounds a bit complicated, but as I mentioned earlier I'm a django
newbie so I shouldn't really be debating this.

It just seems to me that something like a password field (in the model)
has just as much right to exist as a date field or a usstate field (if
not more).

My main point was that the admin interface is so damn good already that
I don't have any need for creating a different view on top of my data.
What I need is just a web page to allow people to manage users and
retrieve a list. The data will be used by an apache server so there's
no "public view" that I need to create. Well... except the password
field. The handling of that is not good enough so I will need to create
a completely new view just because of that... and it's a bit
frustrating to be that close ;-)

You mentioned the admin interface for creating users. Well, the
password field there is a plain text field with a string in a specific
form ('[algo]$[salt]$[hexdigest]'). That may work for developers but
I'd never want to ask a "regular" user to use that.

The CreateUserForm does look promising but as I said, I haven't tried
this... will do that right now. But it is my understanding that if
there was a model PasswordField I wouldn't even have to mess with this
form.

Anyways... thanks for a great product and keep up the good work. I will
be keeping at it and probably coming back to you guys with other
(invalid) feature requests and perhaps even bug reports ;-)

Kind regards, Stefan Freyr.

James Bennett

unread,
Oct 1, 2006, 4:53:43 PM10/1/06
to django-d...@googlegroups.com
On 10/1/06, stefan...@gmail.com <stefan...@gmail.com> wrote:
> You mentioned the admin interface for creating users. Well, the
> password field there is a plain text field with a string in a specific
> form ('[algo]$[salt]$[hexdigest]'). That may work for developers but
> I'd never want to ask a "regular" user to use that.

That has changed; if you're using an SVN checkout from anytime in the
last couple months, you'll see a special-case view has been inserted
for user creation.

SmileyChris

unread,
Oct 2, 2006, 11:37:46 PM10/2/06
to Django developers
Unfortunately it has only changed for creating new users, not editing
the password of existing ones.

Reply all
Reply to author
Forward
0 new messages