Differences between revisions 3 and 4
Revision 3 as of 2008-09-04 21:38:52
Size: 3324
Editor: olaf-conradi
Comment: Forgot some stuff
Revision 4 as of 2008-09-04 21:55:58
Size: 3321
Editor: olaf-conradi
Comment:
Deletions are marked like this. Additions are marked like this.
Line 88: Line 88:
store_name = accountdb store_name = userdb

Using Storm with Pylons and Repoze.who

This example shows how to integrate Storm with Repoze.who in a Pylons application. Repoze.who is an identification and authentication framework for arbitrary WSGI applications. It acts as WSGI middleware.

$ paster create -t pylons WhoStorm

An repoze.who authenticator needs to be written to access a user table using ZStorm and validate a password.

This the authentication code (whostorm/lib/stormauth.py):

   1 from zope.interface import implements
   2 from repoze.who.interfaces import IAuthenticator
   3 from storm.zope.zstorm import global_zstorm
   4 
   5 from whostorm.model.users import User
   6 
   7 
   8 class StormAuthPlugin(object):
   9 
  10     implements(IAuthenticator)
  11 
  12     def __init__(self, store_name, store_uri):
  13         self.store_name = store_name
  14         self.store_uri = store_uri
  15 
  16     #IAuthenticatorPlugin
  17     def authenticate(self, environ, identity):
  18         try:
  19             login = unicode(identity['login'])
  20             password = unicode(identity['password'])
  21         except KeyError:
  22             return None
  23 
  24         store = global_zstorm.get(self.store_name, self.store_uri)
  25         user = store.find(User, User.name == login).one()
  26         if user is not None and user.validate_password(password):
  27             return user.id
  28         else:
  29             return None
  30 
  31     def __repr__(self):
  32         return '<%s %s>' % (self.__class__.__name__, id(self))
  33 
  34 
  35 def make_plugin(store_name=None, store_uri=None):
  36     if store_name is None:
  37         raise ValueError('store_name must be specified')
  38     if store_uri is None:
  39         raise ValueError('store_uri must be specified')
  40     return StormAuthPlugin(store_name, store_uri)

Provide a model which defines a User class (whostorm/model/users.py):

Change method validate_password to check against hashed passwords.

   1 from storm.locals import *
   2 
   3 class User(object):
   4     __storm_table__ = "Users"
   5     id = Int(primary=True)
   6     name = Unicode()
   7     password = Unicode()
   8 
   9     def validate_password(self, password):
  10         if self.password == password:
  11             return True
  12         return False

The example application will use basic HTTP authentication.

This is the repoze.who configuration file (who.ini):

[plugin:basicauth]
# identification and challenge
use = repoze.who.plugins.basicauth:make_plugin
realm = 'WhoStorm'

[plugin:stormauth]
# authentication using Storm ORM
use = whostorm.lib.stormauth:make_plugin
store_name = userdb
store_uri = sqlite:///%(here)s/whostorm/data/users.db

[general]
request_classifier = repoze.who.classifiers:default_request_classifier
challenge_decider = repoze.who.classifiers:default_challenge_decider

[identifiers]
plugins = basicauth

[authenticators]
plugins = stormauth

[challengers]
plugins = basicauth

A development.ini to tie it all together:

[app:whostorm]
use = egg:WhoStorm
full_stack = false

[filter:who]
use = egg:repoze.who#config
config_file = %(here)s/who.ini

[pipeline:main]
pipeline = egg:Paste#cgitb
           egg:Paste#httpexceptions
           who
           egg:repoze.who#authenticated
           whostorm

That's it.

PylonsRepoze.who (last edited 2008-09-04 21:55:58 by olaf-conradi)