Introduction
Getting UsersFromDatabase authentication working with AuthKit 0.4 and SQLAlchemy 0.4 is hard to figure out, as I learned. Hopefully this will make it easier.
AuthKit 0.4 uses an experimental SQLAlchemy middleware package called SQLAlchemyManager. I don't see any reason why you can't let AuthKit use SQLAlchemyManager, and go on using normal Pylons SQLAlchemy stuff everywhere else in your app. But I haven't really verified that it works perfectly like that.
References
Project base
I started out with the authtest project from http://wiki.pylonshq.com/display/pysbook/Authentication+and+Authorization
as a base for this. You should go through that tutorial and build that project before continuing here.
Install prerequisites
Install AuthKit 0.4.1 r143 from SVN
Check out AuthKit from subversion, get r143, as r144 broke form based authentication. Build the egg and install it.
Install SQLAlchemyManager
Edit files
development.ini
Put something like this in [app:main] in development.ini
I'm not sure about the wisdom of using sqlalchemy.url instead of sqlalchemy.default.url, someone please chime in.
model/__init__.py
edit model/__init__.py to look like this
1
2 | def setup_model(model, metadata, **p):
pass
|
If you want to use SQLAlchemyManager for other stuff in your project you can set up the models in there.
websetup.py
Edit your websetup.py file like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 | """Setup the authtest application"""
import logging
from paste.deploy import appconfig
from pylons import config
from authtest.config.environment import load_environment
from authtest.model import setup_model
from sqlalchemymanager import SQLAlchemyManager
import authkit.users.sqlalchemy_04_driver
log = logging.getLogger(__name__)
def setup_config(command, filename, section, vars):
"""Place any commands to setup authtest here"""
conf = appconfig('config:' + filename)
load_environment(conf.global_conf, conf.local_conf)
manager = SQLAlchemyManager(None, conf.local_conf,
[setup_model, authkit.users.sqlalchemy_04_driver.setup_model])
manager.create_all()
connection = manager.engine.connect()
session = manager.session_maker(bind=connection)
try:
environ = {}
environ['sqlalchemy.session'] = session
environ['sqlalchemy.model'] = manager.model
users = authkit.users.sqlalchemy_04_driver.UsersFromDatabase(environ)
users.group_create("pylons")
users.user_create("james", password="password1", group="pylons")
session.flush()
session.commit()
finally:
session.close()
connection.close()
|
I'm unhappy about explicitly setting up the environ variable. Somebody please find a better way!
You should now be able to run
middleware.py
Edit middleware.py to look like this
1
2
3
4
5
6
7
8 | ...
from authkit.users import sqlalchemy_04_driver
import authkit.authenticate
from authtest.model import setup_model
from sqlalchemymanager import SQLAlchemyManager
...
|
and later this
1
2
3
4
5 | ...
# AuthKit
app = authkit.authenticate.middleware(app, app_conf)
app = SQLAlchemyManager(app, app_conf, [setup_model, sqlalchemy_04_driver.setup_model])
...
|
auth.py
Now edit auth.py to look like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | import logging
from authtest.lib.base import *
from authkit.authorize.pylons_adaptors import authorize, authorized
from authkit.permissions import RemoteUser, ValidAuthKitUser
log = logging.getLogger(__name__)
class AuthController(BaseController):
def index(self):
return 'hello world'
@authorize(ValidAuthKitUser())
def private(self):
return 'You are authenticated'
def signout(self):
return 'Signed out.'
|
Test
Now serve the app with paster serve --reload development.ini and point your browser at http://localhost:5000/auth/private
. You should see the AuthKit sign in form. Sign in with james and password1 and you should see the words You are authenticated. Thus everything is working. If it doesn't work, then find the problem, fix it, and update this page accordingly 
Hi,
Thanks for this automagic tutorial.
Log in works, but signout not really.
Module authkit.authenticate.cookie:441 in logout_user_cookie
environ[self.session_middleware]['authkit.cookie.user'] = None
<type 'exceptions.KeyError'>: 'beaker.session'