I have a standard Pyramid application. In the __init__.py
main method, I have a config.add_request_method(AuthHelper.get_user, 'user', reify=True)
to set up a globally accessible user object.
I store all users in a user
table, and I access the current, logged-in user via the self.request.user
. My problem is that I would like to create an admin portal, completely separate from the rest of the application, and I would like those "admins" to be stored in a table called admin
. These admins are not users – they have a separate login page, and should have no relation to the user table.
I am having trouble setting up Authorization for admins. For instance, in the remember(self.request, admin.id, max_age=...
there is no way to differentiate between a successfully logged in user vs. a successfully logged in admin, as far as the authentication goes. A User.id = 1
could access the admin portal for an Admin.id == 1
, even though they logged in with different credentials on different views.
I thought about using an Admin.username
in the remember
method, but it still clashes with the config.add_request_method(AuthHelper.get_user...)
(understandably so), which takes a User.id
.
How can I set up an Authorization policy such that if you logged in successfully from the Admin portal login, your authorization is separate from a regular user who logged in from the main index page, and vice versa?
I feel like this is a relatively basic need, so I must be missing a simple way to implement this. Thank you.
For an "admin portal, completely separate from the rest of the application" one option would be to set up a separate WSGI application, which would have a separate request
object, authentication policy etc.
Then you can assemble two applications together with a WSGI "composite" so your "normal" application is mounted on /
and your admin is on, say, /admin
.
You can still import the same code (models and even views) from your admin app - basically it's a matter of adding another "startup" file (the one which contains return config.make_wsgi_app()
) and configuring the .ini
file.
If you change the cookie name in the admin app you'll be even able to be logged in as a User in your "main" app and as an Admin in your "admin portal":
authn_policy = AuthTktAuthenticationPolicy(
...
cookie_name='admin_auth_tkt',
...)
authz_policy = ACLAuthorizationPolicy()
config.set_authentication_policy(authn_policy)
config.set_authorization_policy(authz_policy)
You'll need to define an entry point in your setup.py
file:
entry_points="""\
[paste.app_factory]
main = MyApp:main_app
admin = MyApp:admin_app
"""
( main_app
and admin_app
should be functions importable from myapp
, which return respective WSGI applications).
Then you can assemble a composite:
[composite:main]
use = egg:Paste#urlmap
/ = mainapp
/files = adminapp
[app:mainapp]
use = egg:MyApp#main
[app:adminapp]
use = egg:MyApp#admin