Package: pyramid_simpleauth
[![Build Status](https://travis-ci.org/thruflo/pyramid_simpleauth.svg?branch=master)](https://travis-ci.org/thruflo/pyramid_simpleauth)[pyramid_simpleauth][] is a package that implements session based authenticationand role based security for a [Pyramid][] web application.There are many other auth implementations for Pyramid, including [apex][] and[pyramid_signup][] and you can, of course, easily roll your own, for examplefollowing the excellent [pyramid_auth_demo][].  This package aims to be:* relatively simple: with a limited feature set* extensible: with event hooks and overrideable templates* performant: minimising db queries# FeaturesIf you install the package and include it in your Pyramid application, it willlock down your application and expose views at:* /auth/signup* /auth/login* /auth/authenticate (login via AJAX)* /auth/logout* /auth/change\_username* /auth/change\_password* /auth/confirm (email confirmation)* /auth/prefer\_email (set email as the user's preferred email)You get a `user` instance and an `is_authenticated` flag added to the `request`:# e.g.: in a view callableif request.is_authenticated:display = request.user.usernamePlus `UserSignedUp`, `UserloggedIn`, `UserLoggedOut`, `UserChangedPassword`,`UserChangedUsername`, `EmailPreferred` and `EmailAddressConfirmed` events tosubscribe to:@subscriber(UserSignedUp)def my_event_handler(event):request = event.requestuser = event.user# e.g.: send confirmation emailFlags at `request.is_post_login` and `request.is_post_signup`, stored in the session,that allow you to test whether the current request is immediately after a login orsignup event.  And a `request.user_json` property (useful to write into a templateto pass data to the client side).`model.get_confirmation_link(request, email)` returns a `confirmation_link`that will be accepted by `/auth/confirm` and that can typically be included inan email sent to a user who wish to validate an email address.The `EmailAddressConfirmed` and `EmailPreferred` events give you access to the`Email` object as `event.data['email']`, eg:@subscriber(EmailAddressConfirmed)def email_address_confirmed(event):email_address = event.data['email'].addresssession = event.request.sessionsession.flash("%s has been confirmed successfully" % email_address)# InstallInstall using `pip` or `easy_install`, e.g.:pip install pyramid_simpleauth# ConfigureInclude the package along with a session factory, `pyramid_tm` and `pyramid_basemodel`in the configuration portion of your Pyramid app:# Configure a session factory, here, we're using `pyramid_beaker`.config.include('pyramid_beaker')config.set_session_factory(session_factory_from_settings(settings))# Either include `pyramid_tm` or deal with committing transactions yourself.config.include('pyramid_tm')# Either include `pyramid_basemodel` and provide an `sqlalchemy.url` in your# `.ini` settings, or bind the SQLAlchemy models and scoped `Session` to a# database engine yourself.config.include('pyramid_basemodel')# Include the package.config.include('pyramid_simpleauth')The signup and login forms inherit from a base layout template.  You can overridethis base layout template by writing your own, e.g.:# my_package:my_templates/layout.mako<!DOCTYPE HTML><html><head><title>${self.subtitle()}</title><link href="my_great.css" rel="stylesheet" type="text/css" /></head><body><div class="my-great-markup">${next.body()}</duv></body></html>Then in your main app factory / package configuration use, e.g.:config.override_asset(to_override='pyramid_simpleauth:templates/layout.mako',override_with='my_package:my_templates/layout.mako')Or you can nuke the signup and login templates directly, e.g.:config.override_asset(to_override='pyramid_simpleauth:templates/signup.mako',override_with='my_package:my_templates/foo.mako')config.override_asset(to_override='pyramid_simpleauth:templates/login.mako',override_with='my_package:my_templates/bar.mako')To change the url path for the authentication views, specify a`simpleauth.url_prefix` in your application's `.ini` configuration:# defaults to 'auth', resulting in urls that start with `/auth/...`simpleauth.url_prefix = 'another'You can also specify where to redirect to after signup, login, logout, usernamechange, password change, email confirmation or preferred email selection. Theseare all configured using *route names*, with the route being provided theadditional traversal information of the user's username and an optional viewname.  (This means you can expose a simple named route, or a hybrid route, asyou prefer.  The hybrid route will attempt traversal on the username).To redirect to a different named route after signup / login or logout use:simpleauth.after_signup_route = 'another' # defaults to 'users'simpleauth.after_login_route = 'another' # defaults to 'index'simpleauth.after_logout_route = 'another' # defaults to 'index'Note that a `next` parameter passed to the login page, passwordchange page, username change page, email confirmation page or preferred emailselection page will take precedence over the specific routes.To redirect to a different route and view after login, password change, usernamechange, email confirmation or preferred email selection, use configurationdirectives such as:simpleauth.after_confirm_email_route = 'basepath' # defaults to 'users'simpleauth.after_confirm_email_view = 'viewname', # defaults to 'account'This would redirect user bob to `/basepath/bob/viewname`. Redirect configurationdirectives for each of those views are named following the patterns`simpleauth.after_<view_name>_route` and `simpleauth.after_<view_name>_view`,where `<view_name>` can be any of `login`, `change_username`,`change_password`, `confirm_email` and `prefer_email`.Be careful in the case of username change because if your `next` URL contains ausername, it won't be valid anymore after the username has changed, eg. if youinstruct the username change page to redirect to `/basepath/bob/viewname` butthe username changes to become alice, the redirect will cause a "page not found"error. In this case, if you want to include a username in your custom redirect,you should use the configuration-based redirect location will take into accountthe new username.By default the app redirects after signup to a route named 'users'.  This isnot exposed by `pyramid_simpleauth` by default but the package does provide a`.tree.UserRoot` root factory that looks up `.model.User`s by username and adefault `__acl__` property on the `.model.User` class.  These are entirelyoptional: you can choose instead to use a different named route, or exposea simple named route using, e.g.:config.add_route('users', 'some/path')However, if you want to use the machinery provided, with the baked in securityand traversal, you can expose a user profile view, or perhaps a welcome page at`/users/:username` using, e.g.:config.add_route('users', 'users/*traverse', factory=UserRoot,use_global_views=True)To avoid configuring the authorisation and authentication policies (e.g.: if you'regoing to set these up yourself) use:simpleauth.set_auth_policies = falseTo avoid locking down your app to require a 'view' permission for all views bydefault (secure but perhaps draconian):simpleauth.set_default_permission = False# TestsI've only tested the package under Python 2.6 and 2.7 atm.  It should work underPython 3 but I have problems installing the `passlib` dependency (or any decentpassword encryption library) under Python 3.You'll need `nose`, `coverage`, `mock` and `WebTest`.  Then, e.g.:$ nosetests --cover-package=pyramid_simpleauth --cover-tests --with-doctest --with-coverage..........................................Name                        Stmts   Miss  Cover   Missing---------------------------------------------------------pyramid_simpleauth             19      0   100%pyramid_simpleauth.events      26      0   100%pyramid_simpleauth.hooks       13      0   100%pyramid_simpleauth.model       56      0   100%pyramid_simpleauth.schema      83      0   100%pyramid_simpleauth.tests      197      0   100%pyramid_simpleauth.tree        18      0   100%pyramid_simpleauth.view        76      0   100%---------------------------------------------------------TOTAL                         488      0   100%----------------------------------------------------------------------Ran 42 tests in 16.408sOK[apex]: https://github.com/cd34/apex[pyramid]: http://pyramid.readthedocs.org[pyramid_auth_demo]: https://github.com/mmerickel/pyramid_auth_demo[pyramid_signup]: https://github.com/sontek/pyramid_signup[pyramid_simpleauth]: http://github.com/thruflo/pyramid_simpleauth