Authentication and Authorization

TurboGears uses repoze.who and repoze.what to provide identity services. To enable Authentication and Authorization select the appropriate option during quickstart.

repoze.who

Authentication is provided by repoze.who. It includes several plugins for different login mechanisms. If successfully logged in repoze.who creates a identity object containing a user object.

A user may be member of several groups, which may have several permissions associated with. A user’s permissions are defined as the set of permissions provided by all groups he has membership in. The quickstart template automatically sets up appropriate SQLAlchemy objects as a layer to the database. Alternatively repoze.who can use flat files or http authorization.

repoze.what

Repoze.what acts as a configuration layer for repoze.who. It also provides methods for authorization.

Configuration

Repoze.what is configured by setting values in app_cfg.py. You can initialize the sqlalchemy authentication plugin by setting:

base_config.auth_backend = 'sqlalchemy'

There are several options which influence the behavior of this plugin.

There are three options which control the urls used during the login process.

  • base_config.sa_auth.login_url - The path to the login form. Must be implemented in controller.
  • base_config.sa_auth.login_handler - Performs the login. Implemented by Repoze.who.
  • base_config.sa_auth.post_login_url - The path where users should be redirected to after login.

Similiar options exist for the logout.

  • base_config.sa_auth.logout_handler - Performs the logout. Implemented by Repoze.who.
  • base_config.sa_auth.post_logout_url - The path where users should be redirected to after logout.

The handler actions are processed by the authentication middleware based on a WSGI request and never reach the application layer.

Usage

Repoze.what allows you to control access to single exposed methods or whole controllers. The easiest way to secure a controller is to specify a predicate:

from repoze.what.predicates import has_permission

class controller(BaseController):
    allow_only = has_permission('manage', msg=l_('Only for users with the "manage" permission'))

These predicates extend to any subcontrollers.

Alternatively you can secure methods by using the require decorator:

from tg import require

class controller(BaseController):
    @require(has_permission('manage', msg=l_('Only for users with the "manage" permission')))
    @expose()
    def method(self):
        pass

Users without the appropriate permissions get redirected to a login form to provide valid credentials.

Other common predicates include:

not_anonymous
is_user
in_group

It’s possible to test predicates programmatically using:

is_manager = bool(has_permission('manage'))

if has_permission('manage'):
    pass