Authentication module for web.py 0.3

51 views
Skip to first unread message

Juan Pablo Scaletti

unread,
Oct 22, 2008, 8:30:42 AM10/22/08
to web.py
I've made a cookie-based authentication module for web.py 0.3
The module allows you to:

* Limit access to pages based on if the user is logged in, if is
authorized (by checking against a table of permissions) or meet
certain conditions.
* Generate and manage password hashes. Sha1, sha512 and bcrypt are
supported.
* Authenticate a user by checking a login and password against a
database of users.
* Generate and validate tokens for passwords resets.

It also includes default pages to login, generate a password-reset
token, email the token and set a new password after the token is
validated.

Documentation: http://jpscaletti.com/webpy_auth/

Download: http://jpscaletti.com/static/webpy_auth.zip

Brent Pedersen

unread,
Oct 22, 2008, 11:57:26 AM10/22/08
to we...@googlegroups.com
this is excellent. thanks.

Juan Pablo Scaletti

unread,
Oct 22, 2008, 12:31:04 PM10/22/08
to web.py
:D Any question | suggestion | angry rant?

On 22 oct, 10:57, "Brent Pedersen" <bpede...@gmail.com> wrote:
> this is excellent. thanks.
>
> On Wed, Oct 22, 2008 at 5:30 AM, Juan Pablo Scaletti
>

Brent Pedersen

unread,
Oct 22, 2008, 12:47:12 PM10/22/08
to we...@googlegroups.com
i just looked at source briefly, i like the auth.* decorators and the
ability to add a custom test. i'll be using it in next couple weeks
instead of my own hacked up version.

if i were to nitpick:
1) where's the tests? auth is pretty important... shoudl have some tests.
2) what's with user.user_id, permission.permission_code_name , etc.
including the table name in the column is redundant. (or is that
preferred style now?)

also, did i miss it or where does one set the salt? i was looking for
that in the config

-brent

Message has been deleted
Message has been deleted

Juan Pablo Scaletti

unread,
Oct 22, 2008, 1:36:02 PM10/22/08
to web.py
> 1) where's the tests? auth is pretty important... shoudl have some tests.

You're totally right. I'll check that.

> 2) what's with user.user_id, permission.permission_code_name , etc.
> including the table name in the column is redundant. (or is that
> preferred style now?)

Humm... I used the style because of another project I was working on.
Maybe I should just use user.id, etc.
What do people think?

> also, did i miss it or where does one set the salt? i was looking for
> that in the config

The salt isn't system wide but randomly generated per user and stored
with the hash.
The user_password is a string in this format:

$hashtype$repetitions$salt$hash

(When bcrypt is the hash function, the format is actually $hashtype
$repetitions$salthash because the algorithm itself takes care of the
salting).

Storing the salts this way isn't weaknesses because their only
function
is to prevent a precalculated hashes attack.

By storing the hashtype you can easily change the hash function and
the "old" passwords will continue to work (they'll be converted
automatically to the new style the first time check_password() works
correctly for a given user).

--JPS


On 22 oct, 11:47, "Brent Pedersen" <bpede...@gmail.com> wrote:
> i just looked at source briefly, i like the auth.* decorators and the
> ability to add a custom test. i'll be using it in next couple weeks
> instead of my own hacked up version.
>
> if i were to nitpick:
> 1) where's the tests? auth is pretty important... shoudl have some tests.
> 2) what's with user.user_id, permission.permission_code_name , etc.
> including the table name in the column is redundant. (or is that
> preferred style now?)
>
> also, did i miss it or where does one set the salt? i was looking for
> that in the config
>
> -brent
>
> On Wed, Oct 22, 2008 at 9:31 AM, Juan Pablo Scaletti
>

rkm...@gmail.com

unread,
Oct 22, 2008, 8:00:58 PM10/22/08
to we...@googlegroups.com
On Wed, Oct 22, 2008 at 10:36 AM, Juan Pablo Scaletti <juanpablo...@gmail.com> wrote:



> 2) what's with user.user_id, permission.permission_code_name , etc.
> including the table name in the column is redundant. (or is that
> preferred style now?)

Humm... I used the style because of another project I was working on.
Maybe I should just use user.id, etc.
What do people think?
user.id should definitely be used.. 

Jeffrey

unread,
Nov 3, 2008, 3:19:58 AM11/3/08
to we...@googlegroups.com
hi, it looks like the document is not available now. 404 error
there is one instead?
--
Yours
Faithfully

Jeffrey Hsu

Juan Pablo Scaletti

unread,
Nov 4, 2008, 10:33:16 AM11/4/08
to web.py
fixed

On Nov 3, 3:19 am, Jeffrey <jeffre...@gmail.com> wrote:
> hi, it looks like the document is not available now. 404 error
> there is one instead?
>

dbpatterson

unread,
Dec 30, 2008, 2:37:00 PM12/30/08
to web.py
I'm trying to incorporate this into a project of mine, but with web.py
0.31, at least using sqlite as the db backend, it throws errors.

Specifically, the first time I ran into it was trying to do
createPermission in DBAuth - the db.select on line 371 returns an
IterBetter, but on 376 you try to call len() on it, which doesn't
work. however, going through the code, the results of a select are
treated as lists everywhere.

I am unsure if this is an sqlite specific thing, or if this is a
change across the board with web.py - my instinct is that it is the
latter (as web.py wouldnt return different types of object for
different db backends, at least I hope it wouldnt!). if so, the simple
solution is pretty easy - I've done it on my local install, simply
add .list() at the end of every self._db.select(), so you get what you
were expecting.

otherwise, I'm excited to try this out; I was about to write a real
authentication module to replace my hacked together solution when I
found this, and I'm glad not to have to!

daniel


On Nov 4, 10:33 am, Juan Pablo Scaletti <juanpablo.scale...@gmail.com>

dbpatterson

unread,
Dec 30, 2008, 2:41:49 PM12/30/08
to web.py
another bug - line 315, it is written:
del user[user_password]
when it should be
del user["user_password"]

On Nov 4, 10:33 am, Juan Pablo Scaletti <juanpablo.scale...@gmail.com>

mathew wong

unread,
Dec 30, 2008, 8:50:04 PM12/30/08
to we...@googlegroups.com
Hi Daniel,
How did you manage to get the module working? Unlike you I'm having a devil of a time getting it to work. For one thing after applying the decorators on my index class. My app keeps redirecting to a unknown "/login" url. The docs aren't very clear on what you should do afterwards. Could you please lend me a hand on this? I'm pretty sure I missed something...

Mathew

dbpatterson

unread,
Dec 30, 2008, 11:06:19 PM12/30/08
to web.py
continuing to try to make this thing work: in views.py, the relative
path to the templates wont work (at least on my machine), it reads
(line 11):
render = web.template.render('web/contrib/auth/templates/')

so for now I've hard coded it in, I'm sure there is a way to get the
filename (some __variable or something) but I am wondering if there is
another way it is supposed to be working... input would be welcome.

mathew wong

unread,
Dec 31, 2008, 2:07:48 AM12/31/08
to we...@googlegroups.com
I tried editing the views.py the way you mentioned but it still continues to persist to go to 127.0.0.1:40/login with a "not found" error (127.0.0.1:40 being the url I use for the development server.). Anybody here who have encountered the same problem that I have? Please let me know...

Thanks,
Mathew

dbpatterson

unread,
Jan 1, 2009, 1:58:47 AM1/1/09
to web.py
Sorry I didnt post back; further debugging/clunking around was
necessary. The short answer is, in order for this to work, you need
autoreload=False in your app definitions. In mine, it looks like:

app = web.application(urls, locals(), autoreload=False)

This is because through some strangeness (not sure if this is
intentional; it shouldnt be!) web.py doesnt use dynamically added
mappings (via app.add_mapping()) if you dont set that when you create
the app.

With that final hurdle, the auth module is working for me (and I'm
quite happy with it... even with all this debugging, it still saved a
lot of time)... I'm currently working on an app creation tool similar
to those included with django or rails (from an outline of url
structure, users, and data descriptions, it will write the framework
of an app, create all the database tables, users with permissions
based on what data they can edit, and a functioning (though primitive)
admin interface), which I may publish if it ever gets to a state that
it isnt an embarrassing mess of code.

Hope all this helps, and that the changes necessary to make it work
get incorporated into the code... (and that the whole thing gets
incorporated into web.py!)

Daniel


On Dec 31 2008, 2:07 am, "mathew wong" <wrm...@gmail.com> wrote:
> I tried editing the views.py the way you mentioned but it still continues to
> persist to go to 127.0.0.1:40/login with a "not found" error
> (127.0.0.1:40being the url I use for the development server.). Anybody

Mathew

unread,
Jan 1, 2009, 5:51:44 AM1/1/09
to web.py
Thank you! I finally managed to make it work! Agreed it took a little
debugging but because of your effort it saved me a lot of time. My
comment is that the module author should have taken down the bugs and
work arounds that have to be implemented. Happy New Year to all!

Mathew

Jan

unread,
Jan 26, 2009, 6:19:18 AM1/26/09
to web.py
Hey guys. After i did a bit of debugging i got it to run acceptable,
here is my very minimal code.py:
http://pastie.org/370909

I doesn't spit any errors out, but it doesn't work as expected either:
When i use the standard "/login", to login as an existing user, i get
redirected
to "/", there i do perform a check for the current user:
currentuser = auth.getUser(login=None)
but it never returns an user object, whatever i do. :( Seems like its
not properly stored in the session or something.
The webpy session works flawlessly (included the counter example from
the cookbook).

I know that if i get this to work, i have a pretty good auth system :)

Greetings,
Jan
Reply all
Reply to author
Forward
0 new messages