Latest Version: 0.9.6.2
  Dashboard > Pylons Book > Home > Authentication and Authorization
  Pylons Book Log In | Sign Up   View a printable version of the current page.  
  Authentication and Authorization
Added by James Gardner, last edited by James Gardner on Jul 14, 2008  (view change)
Labels: 
(None)

This page has now been updated. The latest version can be found on the Pylons Book website at http://pylonsbook.com/alpha1/authentication_and_authorization

To make this work with Elixir.0.4.0.dev I've created the following UsersFromDatabase:

----- myproject/users/elixir_driver.py -----

from sqlalchemy import *
from authkit.users import *
from elixir import *
from authkit.users import sqlalchemy_driver

class UsersFromDatabase(sqlalchemy_driver.UsersFromDatabase):
"""
Database Version
"""
def _init_(self, model, encrypt=None):
sqlalchemy_driver.UsersFromDatabase._init_(self, model, encrypt)

def update_model(self, model):
class User(Entity):
has_field("uid", Integer, primary_key=True)
has_field("username", String(255), unique=True, nullable=False)
has_field("password", String(255), nullable=False)
belongs_to('group', of_kind='Group', colname='group_uid')
using_options(tablename='users')

def _repr_(self):
return "User(%(username)s)" % self._dict_

class Group(Entity):
has_field('uid', Integer, primary_key=True)
has_field("name", String(255), unique=True, nullable=False)
using_options(tablename='groups')

def _repr_(self):
return "Group(%(name)s)" % self._dict_

class Role(Entity):
Column("uid", Integer, primary_key=True),
Column("name", String(255), unique=True, nullable=False),
using_options(tablename='roles')

class UserRole(Entity):
belongs_to('user', of_kind='User', colname="user_uid")
belongs_to('role', of_kind='Role', colname="role_uid")
using_options(tablename='users_roles')

model.User = User
model.Group = Group
model.Role = Role
return model

----- myproject/users/_init_.py ------

import elixir_driver

----- development.ini -----------

[app:main]
authkit.setup.method = form, cookie
authkit.form.authenticate.user.type = myblog.users.elixir_driver:UsersFromDatabase
authkit.form.authenticate.user.data = myblog.model
authkit.cookie.secret = secret string
authkit.cookie.signoutpath = /auth/signout

Posted by tristan straub at Oct 06, 2007 14:58 | Permalink | Reply To This

Ok, so I stuffed up the indenting, and forgot to modify Role,.. so here it is again. 

---- myproject/users/elixir_driver.py ----

from sqlalchemy import *
from authkit.users import *
from elixir import *
from authkit.users import sqlalchemy_driver

class UsersFromDatabase(sqlalchemy_driver.UsersFromDatabase):
    """
    Database Version
    """
    def _init_(self, model, encrypt=None):
        sqlalchemy_driver.UsersFromDatabase._init_(self, model, encrypt)

    def update_model(self, model):
        class User(Entity):
            has_field("uid", Integer, primary_key=True)
            has_field("username", String(255), unique=True, nullable=False)
            has_field("password", String(255), nullable=False)
            belongs_to('group', of_kind='Group', colname='group_uid')
            using_options(tablename='users')

            def _repr_(self):
                return "User(%(username)s)" % self._dict_

        class Group(Entity):
            has_field('uid', Integer, primary_key=True)
            has_field("name", String(255), unique=True, nullable=False)
            using_options(tablename='groups')

            def _repr_(self):
                return "Group(%(name)s)" % self._dict_

        class Role(Entity):
            has_field("uid", Integer, primary_key=True)
            has_field("name", String(255), unique=True, nullable=False)
            using_options(tablename='roles')

        class UserRole(Entity):
            belongs_to('user', of_kind='User', colname="user_uid")
            belongs_to('role', of_kind='Role', colname="role_uid")
            using_options(tablename='users_roles')

        model.User = User
        model.Group = Group
        model.Role = Role
        return model

---- myproject/users/_init_.py -----

import elixir_driver

---- development.ini ----------

authkit.setup.method = form, cookie
authkit.form.authenticate.user.type = myblog.users.elixir_driver:UsersFromDatabase
authkit.form.authenticate.user.data = myblog.model
authkit.cookie.secret = secret string
authkit.cookie.signoutpath = /auth/signout

Posted by tristan straub at Oct 06, 2007 15:01 | Permalink | Reply To This

First, thanks for the documentation effort.

I'm fairly new to pylons but I think this tutorial needs a serious cleanup and does not quite work with the newest versions of pylons (0.9.6.1) and authkit (0.4).

Here are some examples:

  • The controller methods return Response objects which are deprecated (see release 0.9.6 announcement here: http://groups.google.com/group/pylons-discuss/browse_thread/thread/f22de9e48ac45102)
  • In the homegrown example, there is some html code in the controller which is a bad practice. It would be better to add a mako template in the views and render it from the controller.
  • authkit.pylons_adaptors is deprecated, authkit.authorize.pylons_adaptor should be used instead
  • The user_in parameter in the ValidAUthKitUser Permission constructor does not work in authkit 0.4: ValidAuthKitUser(user_in=["visitor"])
Posted by Julien Boeuf at Oct 09, 2007 10:30 | Permalink | Reply To This

Instead of using @authorize(ValidAuthKitUser(user_in=["visitor"])), you can import UserIn() from authkit.permissions instead and do @authorize(UserIn(["visitor"])).

Posted by Anonymous at Nov 27, 2007 18:09 | Permalink | Reply To This

The section copied below, needs to be removed from this document!  Doing this can cause concurrent requests to your application to fail, because the same controller will be reused to handle requests.  Thanks!

You can use a similar technique to restrict access to an individual controller. Since all Pylons controllers are valid WSGI applications you can also use the same authentication middleware to wrap the controller.

Modifying the auth controller we created earlier, first import the authorize middleware:

1 from authkit.authorize import middleware

Then right at the end of the file wrap your instantiated controller class in the authorization middleware so that it looks like this:

1 AuthController = middleware(AuthController(), RemoteUser())

# XXX Does this work? How can Pylons recreate the controller on each request of # you do this????

Posted by David Snopek at Nov 28, 2007 13:19 | Permalink | Reply To This

I was not getting the things done. I did use AuthKit 4.0 and Pylons 9.6. I got the "You are not authenticated" message but I couldn't see any sign-up form.

Posted by Anonymous at Dec 01, 2007 03:34 | Permalink | Reply To This

I can see where you are trying to go with the chapter, but if I could suggest a different tack (as an author, and a programmer).

I came to this chapter online specifically to see how to use authkit. I wanted to get up and running, right now. What I found with the chapter was that I had to wade through first a homegrown solution that's nothing to do with authkit, and then wade through some very limited examples that seem to embed usernames and passwords in source files - I might be missing something here but by the time I finally got to the authkit bit I was admittedly bored and skimming for anything with a bit of meat on it.

Can I suggest that the chapter formats should be to first get a user up and running with a real world, bare bones example. Most readers have a database, and they want to add a user, recover a password, and log in. I'd kick off the chapter with all those three scenarios first. Someone in a hurry can then get up to speed really fast, then return later to unlock the subtleties. I would suspect that the bulk of the readers of the book, online or not, have a very specific task in mind when they came to pylons and I believe each chapter should help them accomplish that task as quickly as possible, before diving into exposition.

Posted by Anonymous at Dec 08, 2007 20:18 | Permalink | Reply To This

I came to this chapter wanting to learn both about AuthKit and about how users are implemented in websites in general. The homegrown solution section was very helpful in regard to the latter and took just a few minutes to code up as I went along.

Posted by Anonymous at Jan 16, 2008 18:25 | Permalink | Reply To This

++ AuthKit should call the template() function

Should read:

AuthKit should call the make_template() function

Posted by Graham Higgins at Dec 09, 2007 22:24 | Permalink | Reply To This

I've been trying to make this latest example work:
http://authkit.org/trac/browser/AuthKit/trunk/examples/user/database/app.py

But all I get is:
Traceback (most recent call last):
File "app.py", line 83, in <module>
cookie_signoutpath = '/signout',
File "/usr/lib/python2.5/site-packages/AuthKit-0.4.0-py2.5.egg/authkit/authenticate/_init_.py", line 452, in middleware
prefix=prefix_,
File "/usr/lib/python2.5/site-packages/AuthKit-0.4.0-py2.5.egg/authkit/authenticate/form.py", line 131, in make_form_handler
prefix='authkit.method.form',
File "/usr/lib/python2.5/site-packages/AuthKit-0.4.0-py2.5.egg/authkit/authenticate/form.py", line 114, in load_form_config
format='basic'
File "/usr/lib/python2.5/site-packages/AuthKit-0.4.0-py2.5.egg/authkit/authenticate/_init_.py", line 191, in get_authenticate_function
users = user_object(user_conf['data'], encrypt)
KeyError: 'data'

Does any one can please tell me what is wrong?

I have sqlalchemy_04_driver and sqlalchemynamager 0.1.0 installed.

Posted by Anonymous at Jan 21, 2008 15:40 | Permalink | Reply To This

The solution is to specify form_authenticate_user_data when adding new middleware:

app = middleware(
    app,
    setup_method='form,cookie',
    cookie_secret='secret encryption string',
    form_authenticate_user_type = "authkit.users.sqlalchemy_04_driver:UsersFromDatabase",
    form_authenticate_user_data = "app.model",
    cookie_signoutpath = '/signout',
    # setup_intercept = "401, 403",
)

Posted by Igor Yatsenko at Feb 29, 2008 19:09 | Permalink | Reply To This

Found a typo in the first section of the page: "secutiry".

Posted by Eric Ongerth at Mar 15, 2008 21:33 | Permalink | Reply To This

In the User Management API section, it says to add the following lines to your config file:

authkit.form.authenticate.user.object = authkit.users:UsersFromFile
authkit.form.authenticate.user.data = C:/users_information.txt

As far as I can tell, this is incorrect. Line 187 of authenticate/_init_.py says that it is looking for a key "type" in the config, not a key "object". Consequently, the correct lines to add to the config would be:

authkit.form.authenticate.user.type = authkit.users:UsersFromFile
authkit.form.authenticate.user.data = C:/users_information.txt

Posted by Anonymous at Mar 17, 2008 03:31 | Permalink | Reply To This
Site running on a free Atlassian Confluence Open Source Project License granted to Pylons. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.3 Build:#645 Feb 13, 2007) - Bug/feature request - Contact Administrators
Top