Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Version 41 (modified by fredlin, 13 years ago) (diff)


Identity Management

Work Version: > 0.92a2

TurboGears identity management architecture was originally from  Jeff Watkins, Here is a Tutorial for getting TurboGears identity management support up and running.

Identity Management can be used in either controller or templates.

For better understanding, The document has been split to 3 part, and covers following topics

Use Identity in Controller
Restrict Access
Identity Management API
Use Identity in Template
Restrict Group Access
Customize ORM classes
Retrieve logged users' identity infomation

This Tutorial is written from the perspective of a fresh quick-started project, but most everything applies for existing projects.


Use Identity in Controller

Step 1 - Create new project

$ tg-admin quickstart 

Name your project as your "project_name" and set the database uri in "project_name/dev.cfg" to point to a server and database you want to use. refer  here

Step 2 - Edit project_name/config/app.cfg

Edit app.cfg. uncomment and edit the following to turn on identity management. Edit the failure url as well.

# visit.on=False

# identity.on=False
identity.on = True

# identity.failure_url=None
identity.failure_url = "/login"

Step 3 - Testing the login

Start the project:

$ start-project_name

The database will be created by this commands, visit login page  http://localhost:8080/login and login with any username and password. It should fail with the message since you haven't add user/group/permision.

You can access any other pages without trouble, because we haven't "protect" those pages by identity decorator.

Step 4 - protect your pages

You can protect your pages by using identity decorator(decorator usage is as the expose decorator "@turbogears.expose()" you've learned)

1. Edit

Add this code on the top of the file:

from turbogears import identity

2. Protect Pages

If you want to protect any method(page is just a python method), add an identity decorator over the method.

The following example use "@identity.require()" to protect the index page:

    @identity.require( identity.in_group( "admin" ))
    def index(self):

The decorator checked whether the visitor was a member of the admin group.

Let's visit the  http://localhost:8080/, now the index page is protected.

There are many @identity.require decorator parameters for you to fit your identity requirements.

See the API section below.

Step 5 - Create a user and group

We just learn howto protect our page, but for now we can't access those protected pages any more.

Since we haven't specify any user or groups for permissions, we need to add some user/group/admission to login to the protected pages.

$ tg-admin shell

>>> from turbogears.identity.soprovider import *
>>> hub.begin()
>>> u=TG_User( userId="jeff", emailAddress="",
            displayName="Jeff Watkins", password="xxxxx" )
>>> g=TG_Group( groupId="admin", displayName="Administrators" )
>>> hub.commit()

Step 6 - Add the user to admin group

$ tg-admin shell

>>> from turbogears.identity.model.somodel import *
>>> hub.begin()
>>> u=TG_User.get(1)
>>> g=TG_Group.get(1)
>>> u.addTG_Group(g)
>>> hub.commit()

Step 7 - Revisit protected page and login

Browse to  http://localhost:8080/ again and login, this time you should see the content of index page

#TODO using SQLAlchemy instead of SQLObject #TODO LdapIdentityProvider?


Single Permission Control

You need to use the permission control functions in the identity namespace. For example:

Restrict access groups

@identity.require( identity.in_group( "admin" ) )

Many people wanted something more flexible, any of the following are valid require decorators:

@identity.require( identity.in_all_groups( "admin", "editor" ) )

@identity.require( identity.in_any_group( "admin", "editor" ) )

@identity.require( identity.not_anonymous() )

Restrict access permissions

@identity.require( identity.has_permission( "edit" ) )

@identity.require( identity.has_all_permissions( "edit", "delete", "update" ) )

@identity.require( identity.has_any_permission( "edit", "delete", "update" ) )

Restrict access host

@identity.require( identity.from_host( "" ))

@identity.require( identity.from_any_host( , , ))

Combination Permission Control

You can combine several permissions by "Any" or "All":

     @identity.require( Any( identity.in_group( "admin" ), identity.has_permission( "edit" ) ) )

The require decorator checked whether the visitor was a member of the "admin" group or had the "edit" permission.

     @identity.require( All( identity.from_host( "" ), identity.has_permission( "edit" ) ) )

     @identity.require( All( identity.from_any_host( "", "", identity.in_group("editor" ) ) )


Use Identity in templates

Identity checks can also be used in kid templates to control the present of stricted areas or links(within any html element).

Step 1. Import turbogears.identity

Make sure you import turbogears.identity in your template (anywhere before you call the turbogears.identity)

<?python from turbogears import identity ?>

Step 2. Control the stricted areas

We Control the stricted areas by using "py:if" statements:

Restrict access groups

<a py:if="'admin' in identity.current.groups" href="/test">This is a link for admin</a>

Restrict access permissions

<div py:if="'write' in identity.current.permissions">This is a write permissions area</div>

Restrict the group Access

There are three ways to Strict the group Access:

1. Protect your sub-directory

To turn on identity login for an entire controller(restrict access to whole subdirectory), you should be able to derive your Controller from identity.SecureResource? and define a require attribute at the class level.

class MySecureController( turbogears.Controller,  identity.SecureResource ):
        require= identity.in_group( "admin" )

        # etc... 

You can apply whatever decorators you want on the methods of the Toxicologia instance. So each method could have additional restrictions. And Toxicologia could have SecureObjects? as well. However, access to exposed methods of Toxicologia and any SecureObjects? would have to satisfy the authorisation requirements for Toxicologia.

2. Check the permissions explicitly

Derive your Controller from identity.SecureResource? and define a require attribute at the method level

class MyController( controllers.Controller, identity.SecureResource ):

     @turbogears.expose( html="mytemplate" )
     def myFunction( self ):
         if not ("admin" in identity.current.groups or \
                 "super" in identity.current.groups):
             raise identity.GroupMembershipRequiredException( ("admin", "super") )

This will work because SecureResource? wraps all exposed methods with code that checks permissions and traps IdentityExceptions?. So if your code throws, er, raises an IdentityException?, everything will be handled correctly.

Of course, you can then pull your authorisation logic out into a function that you call rather than copying and pasting into each function that requires it.

You can also use these similar predicates in your own code:

     if identity.in_group( "admin" ) and identity.has_permission( "edit" ):

3. Write your own decorator function

This is not for the faint at heart. But it gives you absolute flexibility.

Take a look at the decorators in turbogears/identity/ They'll give you a head-start on what you'll have to do.


Customize ORM classes

You can use your own class to access database on Identity Management.

1. Create SQL tables

Run the application as Step 3. All TG_* tables will be created

2. Edit project_name/config/app.cfg

Edit app.cfg, remove the comments from "identity.soprovider" lines.

# The classes you wish to use for your Identity model. Leave these commented out
# to use the default classes for SqlObjectIdentityProvider. Or set them to the
# classes in your model. NOTE: These aren't TG_* because the TG prefix is
# reserved for classes created by TurboGears.

Change model."User", "Group", "Permission" to whatever you prefer.

3. Run the application

Run the application again as in Step 3. Then you can use your classes to manipulate TurboGear? Identity Management.

Retrieve logged users' identity infomation

Retrieve user identity infomation

We can access the entire User object by accessing "turbogears.identity.current.user" to get user identity infomation. This gives you access to the userId, displayName, emailAddress, and creation date.

Retrieve users’ group identity infomation

There are two ways to access the group information.

1. Via the current identity object:

from turbogears import identity
if 'admin' in identity.current.groups:

2. Via the user object on the current identity:

from turbogears import identity
if 'admin' in [g.groupId for g in identity.current.user.groups]:

Option number 2 only works if your using a Model that supports groups on the user object. So, with the default model you’ll be set. Other models might not work so well.


Setting identity by config has not implement yet.

Using Catwalk is probably the easiest way to create user/group/permissions(But it doen't work in 0.92) Use this method if you can't get Catwalk set up.

Using tg-admin shell to add identity user/group is not work under 0.9a2. patch is  here