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

Changes between Version 50 and Version 51 of IdentityManagement


Ignore:
Timestamp:
04/09/06 08:42:00 (13 years ago)
Author:
oefe
Comment:

Major clean up: restructured, improved language, and added explanations

Legend:

Unmodified
Added
Removed
Modified
  • IdentityManagement

    v50 v51  
    11= Identity Management = 
    22 
    3 Version: 0.92a4 
    4  
    5 TurboGears identity management architecture was originally from [http://metrocat.org/nerd/2005/10/identity-management-for-turbogears Jeff Watkins], Here is a Tutorial for getting TurboGears identity management support up and running. 
    6  
    7 Identity Management can be used in either controller or templates. 
    8  
    9 For better understanding, The document has been split to 3 part, and covers following topics 
    10  
    11 PART 1 
    12 {{{ 
    13 Add identity user and group 
    14 Use Identity in Controller 
    15 Identity Management API 
    16 }}} 
    17  
    18 PART 2 
    19 {{{ 
    20 Use Identity in Template 
    21 Restrict Group Access 
    22 }}} 
    23  
    24 PART 3 
    25 {{{ 
    26 Customize ORM classes 
    27 Retrieve logged users' identity infomation 
    28 }}} 
    29  
    30 This Tutorial is written from the perspective of a fresh quick-started project, but most everything applies for existing projects. 
    31  
    32 == PART 1 == 
    33  
    34 == Add identity user and group == 
    35  
    36 There are two ways to add identity user and group. 
    37  
    38  * Add user and group by Catwalk  
    39  * Add user and group by tg-admin shell 
    40  
    41 Using Catwalk is probably the easiest way to create user/group/permissions.  
    42  
    43 We'll show you this way to add User/Group, and append "Add user and group by tg-admin shell" on the button of PART 1. 
    44  
    45 === Step 1 - Create new project ===  
     3Work Version: > 0.92a4 
     4 
     5The TurboGears identity management architecture was originally designed and written by [http://metrocat.org/nerd/2005/10/identity-management-for-turbogears Jeff Watkins]. 
     6 
     7Identity Management can be used in controllers and in templates: 
     8* In ''controllers'' to implement access restrictions 
     9* In ''templates'' to adapt the appearance depending on the user's identity 
     10 
     11Here is a Tutorial for getting TurboGears identity management support up and running. It consists of 3 parts: 
     12 
     13[[PageOutline(2)]] 
     14 
     15This Tutorial is written from the perspective of a fresh quick-started project, but almost everything applies for existing projects as well. 
     16 
     17To begin with the tutorial, let's quick-start a learning project. Of course, everything you learn in the tutorial applies to existing projects as well. 
    4618{{{ 
    4719#!python 
    4820$ tg-admin quickstart  
    4921}}} 
    50 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 [http://www.turbogears.org/docs/wiki20/ here] 
    51  
    52 === Step 2 - Edit project_name/config/app.cfg === 
    53 Edit app.cfg. uncomment and edit the following to turn on identity management. Edit the failure url as well. 
     22Name your project "identity_tutorial" and set the database uri in "identity_tutorial/dev.cfg" to point to a server and database you want to use. 
     23Refer to the [http://www.turbogears.org/docs/wiki20/ Wiki in 20 Minutes Tutorial] for details. 
     24 
     25= Part I: Identity Basics = 
     26 
     27== A. Setting up Identity == 
     28 
     29=== Step 1: Enabling Identity === 
     30 
     31By default, Identity is turned off in quickstarted templates. The first step is therefore to edit your app.cfg file to turn on identity management: 
     32 
     33Edit identity_tutorial/config/app.cfg to turn on visit and identity. Edit the failure url as well: 
    5434 
    5535{{{ 
     
    6646}}} 
    6747 
    68 === Step 3 - Testing the login === 
    69 Start the project: 
    70 {{{ 
    71 #!python 
    72 $ start-project_name 
    73 }}} 
    74  
    75 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. 
    76  
    77 You can access any other pages without trouble, because we haven't "protect" those pages by identity decorator. 
    78  
    79  
    80 === Step 4 - Create user and group === 
    81  
    82 We just learn howto protect our page, but for now we can't access those protected pages any more.  
    83  
    84 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. 
    85  
    86  
    87 ==== 1. Import identity models ==== 
    88 Modify the project_name/model.py 
     48=== Step 2 - Testing the login === 
     49Now let's check whether we have all set up correctly so far. Start the project as usual: 
     50{{{ 
     51#!python 
     52$ start-identity_tutorial 
     53}}} 
     54 
     55Visit the login page http://localhost:8080/login. You should see a pretty login page with username and password fields. Try to log in. It should fail with an error message since you haven't added any users/groups/permisions yet. 
     56 
     57You can access any other page without trouble, because we haven't protected those pages yet. 
     58 
     59=== Step 3 - Import the identity models === 
     60Identity uses three tables to store user, group, and permission information. 
     61We need to import these tables into our model. 
     62 
     63Modify identity_tutorial/model.py to import the TG_User, TG_Group, TG_Permission model classes: 
    8964 
    9065{{{ 
     
    9469}}} 
    9570 
    96 to import the TG_User, TG_Group, TG_Permission model classes. 
    97  
    98 ==== 2. Use Catwalk to create user and group ==== 
     71=== Step 4 - Adding an initial user and group === 
     72 
     73Of course, we will need at least one group and one user account to work with. Let's create these with CatWalk 
    9974 
    10075Start {{{Turbogears}}} toolbox 
     
    10479}}} 
    10580 
    106 Enter catwalk, Now you can see TG_Group, TG_Permission, TG_User classes in left side. 
    107 use following steps to add proper group and user: 
    108  
    109 ===== 1. Add Group ===== 
    110 Select TG_Group. 
    111  
    112 Click "Add TG_Group+" button. 
    113  
    114 Then add the display_name and group_name 
    115  
    116 {{{ 
    117 ex:  
    118 group_name :admin 
    119 display_name : Administrators 
    120 }}} 
    121  
    122 Press "Save" button 
    123  
    124 ===== 2. Add a new User ===== 
    125 Select TG_User. 
    126  
    127 Click "Add TG_User+" button. 
    128  
    129 Then add user infomations 
    130  
    131 {{{ 
    132 ex:  
    133 user_name : root 
    134 email_address : ooo@xxx.oo 
    135 display_name : Fred Lin 
    136 password : ooxx 
    137 }}} 
    138  
    139 Press "Save" button 
    140  
    141 ===== 3. Add the user to admin group ===== 
    142 Now we are in the "Browse" tag, click the arrow sign in front of "groups".  
    143  
    144 It will show a drop down list. In example, click "Manage Relations" to select the "administrators" group from right field to the "root" user.  
    145  
    146 Click "Add Selected" to move selected group from right to left. Then click "Save" to confirm the process. 
     81Enter CatWalk. You should see the TG_Group, TG_Permission, and TG_User classes on the left side. 
     82 
     83==== a) Create a user ==== 
     84Select TG_User. Click the "Add TG_User+" button, then enter the user information. For example: 
     85 
     86{{{ 
     87displayName : Jane Doe 
     88userId : jdoe 
     89emailAddress : jdoe@example.com 
     90password : xxx 
     91}}} 
     92 
     93Click "Save". 
     94 
     95==== b) Create an admin group ==== 
     96Select TG_Group. Click the "Add TG_Group+" button. Enter the displayName and groupId, for example: 
     97 
     98{{{ 
     99displayName : Administrators 
     100groupId :admin 
     101}}} 
     102 
     103Click "Save". 
     104 
     105==== c) Add the new user to the admin group ==== 
     106Note that we are now in the "Browse" tab, with the new group displayed. 
     107Click the expansion triangle in front of "groups". This will reveal a "Manage Relations" link. Click on it. CatWalk will display two lists. Select the new user on the right list and click on "Add Selected" to move it to the left list. Then click "Save" to confirm the change. 
     108 
     109== B. Using Identity in the Controller == 
     110 
     111If you want to protect any method, add an {{{@identity.require(...)}}} decorator to the method. This decorator has a single argument, the ''predicate'', which specifies the conditions to check. The identity module provides many predicates that you can use. 
     112 
     113For example to protect the index page so that only members of the admin group can access it, we can use the {{{identity.in_group("admin")}}} predicate: 
     114 
     115{{{ 
     116#!python 
     117    @turbogears.expose(template=".templates.welcome") 
     118    @identity.require(identity.in_group("admin")) 
     119    def index(self): 
     120        ... 
     121}}} 
     122 
     123Let's try this now. Visit  http://localhost:8080/. As the index page is protected, you will be redirected to the login page. Log in using the name and password of the account which you previosly created. Now you should see the index page. 
     124 
     125Note that identity has added a small "Welcome, Jane Doe. Logout" at the top of the page. 
     126 
     127== C. Identity Predicates == 
     128 
     129=== Single Permission Checks === 
     130 
     131==== Checking that the user is logged in ==== 
     132{{{ 
     133#!python 
     134@identity.require(identity.not_anonymous()) 
     135}}} 
     136 
     137 
     138==== Checking access groups ==== 
     139{{{ 
     140#!python 
     141@identity.require(identity.in_group("admin")) 
     142}}} 
     143 
     144Many people wanted something more flexible, any of the following are valid require decorators: 
     145 
     146{{{ 
     147#!python 
     148@identity.require(identity.in_all_groups("admin", "editor")) 
     149 
     150@identity.require(identity.in_any_group("admin", "editor")) 
     151}}} 
     152 
     153==== Checking access permissions ==== 
     154 
     155{{{ 
     156#!python 
     157@identity.require(identity.has_permission("edit")) 
     158 
     159@identity.require(identity.has_all_permissions("edit", "delete", "update")) 
     160 
     161@identity.require(identity.has_any_permission("edit", "delete", "update")) 
     162}}} 
     163 
     164==== Checking hosts ==== 
     165{{{ 
     166#!python 
     167@identity.require(identity.from_host("127.0.0.1")) 
     168 
     169@identity.require(identity.from_any_host("127.0.0.1", "10.0.0.1")) 
     170}}} 
     171 
     172=== Combining Predicates === 
     173 
     174You can combine several predicates using {{{identity.Any}}} and {{{identity.All}}}: 
     175 
     176{{{ 
     177#!python 
     178     @identity.require(identity.Any(identity.in_group("admin"), identity.has_permission("edit"))) 
     179}}} 
     180 
     181This decorator grants acces to members of the "admin" group as well as any user who has the "edit" permission. 
     182 
     183{{{ 
     184#!python 
     185     @identity.require(identity.All(identity.from_host("127.0.0.1"), identity.has_permission("edit"))) 
     186 
     187     @identity.require(identity.All(identity.from_any_host("127.0.0.1", "10.0.0.1"), identity.in_group("editor"))) 
     188}}} 
     189 
    147190 
    148191---- 
    149192 
    150 == Use Identity in Controller == 
    151  
    152 === Step 1 - protect your pages === 
    153 You can protect your pages by using identity decorator(decorator usage is as the expose decorator "@turbogears.expose()" you've learned) 
    154  
    155 '''1.''' Edit controllers.py 
    156  
    157 Add this code on the top of the file: 
    158  
     193 
     194 
     195= Part II: Fine-Tuning Identity = 
     196 
     197== A. Using Identity in Templates == 
     198Identity checks can also be used in kid templates to customize the appearance of the page depending on the user's identity. For example, you might show links to administrative functions only if the user is an administrator. 
     199 
     200'''Note''':  Identity checks in the template don't provide any security, as it is always possible to enter URLs directly.  
     201Therefore you shouldn't rely on identity checks in the template for your site's security. Always check the identity in the controller as described above. 
     202 
     203=== Step 1. Import turbogears.identity === 
     204 
     205Make sure you import turbogears.identity in your template (anywhere before you call the turbogears.identity) 
     206 
     207{{{ 
     208<?python from turbogears import identity ?> 
     209}}} 
     210 
     211===  Step 2. Conditional display  === 
     212 
     213Now we can use for example "py:if" attributes to display parts of the page depending on identity information: 
     214 
     215==== Using access groups ==== 
     216{{{ 
     217<a py:if="'admin' in identity.current.groups" href="/admin">This is a link for admin</a> 
     218}}} 
     219 
     220==== Using access permissions ==== 
     221{{{ 
     222<div py:if="'write' in identity.current.permissions">This is a write permissions area</div> 
     223}}} 
     224 
     225#TODO: Describe how to display user information 
     226 
     227===  Step 3. Displaying user information  === 
     228 
     229 
     230== B. More Access Checking Options == 
     231 
     232Sometimes, just restricting access to individual methods (pages) isn't enough. 
     233For example, you might want to protect an entire controller, or maybe your access permissions depend on the data viewed. 
     234 
     235=== 1. Protect your sub-directory === 
     236 
     237To restrict access to an entire controller (subdirectory), derive your Controller from identity.SecureResource and add a require attribute at the class level. 
     238 
     239{{{ 
     240#!python 
     241class MySecureController(turbogears.Controller, identity.SecureResource): 
     242    require = identity.in_group("admin") 
     243 
     244    # etc. ...  
     245}}} 
     246 
     247You can apply whatever decorators you want on the methods of the MySecureController instance. So each method could have additional restrictions. And MySecureController could have SecureObjects as well. However, access to exposed methods of MySecureController and any SecureObjects would have to satisfy the authorisation requirements for MySecureController. 
     248 
     249 
     250=== 2. Check the permissions explicitly === 
     251 
     252Let's say you are creating a web site where users can add their own content, like a blogging tool or a photo sharing site. Users should be able to edit their own content, but not the content added by other users. 
     253You can't do these checks in a decorator, as you need access to the actual data, which is only loaded in the method body. (And you don't want to load the data twice.) 
     254So you'll have to perform the identity checks in the method body. 
     255 
     256Again, derive your controller from identity.SecureResource. Perform your identity check at the method level. If the user doesn't have the required permissions, throw a suitable IdentityException:  
     257 
     258{{{ 
     259#!python 
     260class MyController(controllers.Controller, identity.SecureResource): 
     261 
     262     @turbogears.expose(html="mytemplate") 
     263     def myFunction(self): 
     264         if not ("admin" in identity.current.groups or 
     265                 "super" in identity.current.groups): 
     266             raise identity.GroupMembershipRequiredException(("admin", "super")) 
     267}}} 
     268 
     269This will work because SecureResource wraps all exposed methods with code that checks permissions and traps IdentityExceptions. So if your code, raises an IdentityException, everything will be handled correctly. 
     270 
     271Of course, you can then pull your authorisation logic out into a function that you call rather than copying and pasting it into each function that requires it. 
     272 
     273You can also use the identity predicates in your own code: 
     274{{{ 
     275#!python 
     276     if identity.in_group("admin") and identity.has_permission("edit"): 
     277         pass 
     278     else: 
     279         pass 
     280 
     281}}} 
     282 
     283 
     284=== 3. Write your own decorator function === 
     285 
     286This is not for the faint at heart. But it gives you absolute flexibility.  
     287 
     288Take a look at the decorators in turbogears/identity/conditions.py. They'll give you a head-start on what you'll have to do. 
     289 
     290---- 
     291 
     292 
     293= Part III: Advanced Identity = 
     294 
     295== A. Using a Custom Identity Model == 
     296 
     297Sometimes, you want to use or own classes for users, groups, and/or permissions. 
     298This could be a subclass -- maybe you want to a few attributes to the user class, say an image of the user and a phone number -- or even a complete replacement. 
     299 
     300=== 1. Create SQL tables === 
     301 
     302If you are going to ''inherit'' the standard Identity classes, make sure that you run the application once before you implement your own classes.  
     303This will create the TG_* tables. 
     304 
     305=== 2. Edit identity_tutorial/config/app.cfg === 
     306 
     307Edit app.cfg, remove the comments from "identity.soprovider" lines.  
     308 
     309{{{ 
     310#!python 
     311# The classes you wish to use for your Identity model. Leave these commented out 
     312# to use the default classes for SqlObjectIdentityProvider. Or set them to the 
     313# classes in your model. NOTE: These aren't TG_* because the TG prefix is 
     314# reserved for classes created by TurboGears. 
     315identity.soprovider.model.user="identity_tutorial.model.User" 
     316identity.soprovider.model.group="identity_tutorial.model.Group" 
     317identity.soprovider.model.permission="identity_tutorial.model.Permission" 
     318}}} 
     319 
     320Change model."User", "Group", "Permission" to whatever you prefer.  
     321 
     322=== 3. Run the application === 
     323 
     324Run the application 
     325 
     326{{{ 
     327#!python 
     328$ start-identity_tutorial 
     329}}} 
     330 
     331Then you can use your classes to manipulate TurboGears Identity Management. 
     332 
     333 * refer [http://groups.google.com/group/turbogears/browse_thread/thread/37fc2c8a1a2155ed/be061d37b3f1ba4c#be061d37b3f1ba4c  here] and refer [http://groups.google.com/group/turbogears/browse_thread/thread/6073ff1ceb3ba9c9/0ccbeead93a80f3a#0ccbeead93a80f3a here](conclusion)  
     334---- 
     335== Retrieve logged users' identity infomation == 
     336 
     337=== Retrieve user identity infomation === 
     338 
     339We can access the entire User object by accessing "turbogears.identity.current.user" to get user identity infomation. This gives you access to the user_name, display_name, email_address, and creation date. 
     340 
     341=== Retrieve users’ group identity infomation === 
     342 
     343There are two ways to access the group information. 
     344 
     345'''1'''. Via the current identity object: 
    159346{{{ 
    160347#!python 
    161348from turbogears import identity 
    162 }}} 
    163  
    164 '''2.''' Protect Pages 
    165  
    166 If you want to protect any method(page is just a python method), add an identity decorator over the method. 
    167  
    168 The following example use "@identity.require()" to protect the index page: 
    169  
    170 {{{ 
    171 #!python 
    172     @turbogears.expose(template=".templates.welcome") 
    173     @identity.require( identity.in_group( "admin" )) 
    174     def index(self): 
    175         .... 
    176 }}} 
    177  
    178 The decorator checked whether the visitor was a member of the   
    179 admin group. 
    180  
    181 Let's visit the http://localhost:8080/, now the index page is protected. 
    182  
    183 There are many @identity.require decorator parameters for you to fit your identity requirements.  
    184  
    185 See the API section below.  
    186  
    187   
    188 === Step 2 - Revisit protected page and login === 
    189  
    190 Browse to http://localhost:8080/ again and login, this time you should see the content of index page 
    191  
     349if 'admin' in identity.current.groups: 
     350    pass 
     351}}} 
     352 
     353'''2'''. Via the user object on the current identity: 
     354{{{ 
     355#!python 
     356from turbogears import identity 
     357if 'admin' in [g.group_name for g in identity.current.user.groups]: 
     358    pass 
     359}}} 
     360 
     361''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.'' 
    192362---- 
    193363 
    194 == API == 
    195  
    196 === Single Permission Control === 
    197  
    198 You need to use the permission control functions in the {{{identity}}} namespace. For example: 
    199  
    200 ==== Restrict access groups ==== 
    201 {{{ 
    202 #!python 
    203 @identity.require( identity.in_group( "admin" ) ) 
    204 }}} 
    205  
    206 Many people wanted something more flexible, any of the following are valid require decorators: 
    207  
    208 {{{ 
    209 #!python 
    210 @identity.require( identity.in_all_groups( "admin", "editor" ) ) 
    211  
    212 @identity.require( identity.in_any_group( "admin", "editor" ) ) 
    213  
    214 @identity.require( identity.not_anonymous() ) 
    215  
    216 }}} 
     364== Notes == 
     365Setting identity by config has not implement yet. 
     366 
     367Using tg-admin shell to add identity user/group is not work under 0.9a2. patch is [http://groups.google.com/group/turbogears/browse_thread/thread/e1cd7e5e8cb26bba/9f8ae06fbe07bd5a here] 
    217368 
    218369---- 
    219370 
    220 ==== Restrict access permissions ==== 
    221  
    222 {{{ 
    223 #!python 
    224 @identity.require( identity.has_permission( "edit" ) ) 
    225  
    226 @identity.require( identity.has_all_permissions( "edit", "delete", "update" ) ) 
    227  
    228 @identity.require( identity.has_any_permission( "edit", "delete", "update" ) ) 
    229 }}} 
    230  
    231 ==== Restrict access host ==== 
    232 {{{ 
    233 #!python 
    234 @identity.require( identity.from_host( "127.0.0.1" )) 
    235  
    236 @identity.require( identity.from_any_host( , , )) 
    237 }}} 
    238  
    239 === Combination Permission Control === 
    240  
    241 You can combine several permissions by "Any" or "All": 
    242  
    243 {{{ 
    244 #!python 
    245      @identity.require( Any( identity.in_group( "admin" ), identity.has_permission( "edit" ) ) ) 
    246 }}} 
    247  
    248 The require decorator checked whether the visitor was a member of the "admin" group or had the "edit" permission. 
    249  
    250 {{{ 
    251 #!python 
    252      @identity.require( All( identity.from_host( "127.0.0.1" ), identity.has_permission( "edit" ) ) ) 
    253  
    254      @identity.require( All( identity.from_any_host( "127.0.0.1", "10.0.0.1"), identity.in_group("editor" ) ) ) 
    255 }}} 
    256  
     371 
     372 
     373#TODO using SQLAlchemy instead of SQLObject 
     374 
     375#TODO LdapIdentityProvider 
    257376 
    258377== Add user and group by tg-admin shell == 
     
    266385>>> from turbogears.identity.soprovider import * 
    267386>>> hub.begin() 
    268 >>> u=TG_User( user_name="jeff", email_address="jeff@metrocat.org", 
    269             display_name="Jeff Watkins", password="xxxxx" ) 
    270 >>> g=TG_Group( group_name="admin", display_name="Administrators" ) 
     387>>> u=TG_User(userId="jeff", emailAddress="jeff@metrocat.org", 
     388            displayName="Jeff Watkins", password="xxxxx") 
     389>>> g=TG_Group(groupId="admin", displayName="Administrators") 
    271390>>> hub.commit() 
    272391>>> 
     
    288407 
    289408 
    290 ---- 
    291  
    292  
    293  
    294 == PART 2 == 
    295  
    296 == Use Identity in templates == 
    297 Identity checks can also be used in kid templates to control the present of stricted areas or links(within any html element). 
    298  
    299 === Step 1. Import turbogears.identity === 
    300  
    301 Make sure you import turbogears.identity in your template (anywhere before you call the turbogears.identity) 
    302  
    303 {{{ 
    304 <?python from turbogears import identity ?> 
    305 }}} 
    306  
    307 ===  Step 2. Control the stricted areas === 
    308  
    309 We Control the stricted areas by using "py:if" statements: 
    310  
    311 ==== Restrict access groups ==== 
    312 {{{ 
    313 <a py:if="'admin' in identity.current.groups" href="/test">This is a link for admin</a> 
    314 }}} 
    315  
    316 ==== Restrict access permissions ==== 
    317 {{{ 
    318 <div py:if="'write' in identity.current.permissions">This is a write permissions area</div> 
    319 }}} 
    320  
    321 ---- 
    322  
    323 == Restrict the group Access == 
    324  
    325 There are three ways to Strict the group Access: 
    326  
    327 === 1. Protect your sub-directory === 
    328  
    329 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. 
    330  
    331 {{{ 
    332 #!python 
    333 class MySecureController( turbogears.Controller,  identity.SecureResource ): 
    334         require= identity.in_group( "admin" ) 
    335  
    336         # etc...  
    337 }}} 
    338  
    339 You can apply whatever decorators you want on the methods of the MySecureController instance. So each method could have additional restrictions. And MySecureController could have SecureObjects as well. However, access to exposed methods of MySecureController and any SecureObjects would have to satisfy the authorisation requirements for MySecureController. 
    340  
    341 === 2. Check the permissions explicitly === 
    342  
    343 Derive your Controller from identity.SecureResource and define a require attribute at the method level 
    344  
    345 {{{ 
    346 #!python 
    347 class MyController( controllers.Controller, identity.SecureResource ): 
    348  
    349      @turbogears.expose( html="mytemplate" ) 
    350      def myFunction( self ): 
    351          if not ("admin" in identity.current.groups or \ 
    352                  "super" in identity.current.groups): 
    353              raise identity.GroupMembershipRequiredException( ("admin", "super") ) 
    354 }}} 
    355  
    356 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. 
    357  
    358 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. 
    359  
    360 You can also use these similar predicates in your own code: 
    361 {{{ 
    362 #!python 
    363      if identity.in_group( "admin" ) and identity.has_permission( "edit" ): 
    364          pass 
    365      else: 
    366          pass 
    367  
    368 }}} 
    369  
    370 === 3. Write your own decorator function === 
    371  
    372 This is not for the faint at heart. But it gives you absolute flexibility.  
    373  
    374 Take a look at the decorators in turbogears/identity/conditions.py. They'll give you a head-start on what you'll have to do. 
    375  
    376 ---- 
    377  
    378  
    379 == PART 3 == 
    380  
    381 == Modify Identity classes or updating Identity-related tables == 
    382 You can use your own class to access database on Identity Management. 
    383  
    384  
    385 === 1. Create SQL tables === 
    386  
    387 Run the application as Step 3. All TG_* tables will be created 
    388  
    389 === 2. Edit project_name/config/app.cfg === 
    390  
    391 Edit app.cfg, remove the comments from "identity.soprovider" lines.  
    392  
    393 {{{ 
    394 #!python 
    395 # The classes you wish to use for your Identity model. Leave these commented out 
    396 # to use the default classes for SqlObjectIdentityProvider. Or set them to the 
    397 # classes in your model. NOTE: These aren't TG_* because the TG prefix is 
    398 # reserved for classes created by TurboGears. 
    399 identity.soprovider.model.user="project_name.model.User" 
    400 identity.soprovider.model.group="project_name.model.Group" 
    401 identity.soprovider.model.permission="project_name.model.Permission" 
    402 }}} 
    403  
    404 Change model."User", "Group", "Permission" to whatever you prefer.  
    405  
    406 === 3. Run the application === 
    407  
    408 Run the application 
    409  
    410 {{{ 
    411 #!python 
    412 $ start-project_name 
    413 }}} 
    414  
    415 Then you can use your classes to manipulate TurboGear Identity Management. 
    416  
    417  * refer [http://groups.google.com/group/turbogears/browse_thread/thread/37fc2c8a1a2155ed/be061d37b3f1ba4c#be061d37b3f1ba4c  here] and refer [http://groups.google.com/group/turbogears/browse_thread/thread/6073ff1ceb3ba9c9/0ccbeead93a80f3a#0ccbeead93a80f3a here](conclusion) 
    418  
    419 ---- 
    420 == Retrieve logged users' identity infomation == 
    421  
    422 === Retrieve user identity infomation === 
    423  
    424 We can access the entire User object by accessing "turbogears.identity.current.user" to get user identity infomation. This gives you access to the user_name, display_name, email_address, and creation date. 
    425  
    426 === Retrieve users’ group identity infomation === 
    427  
    428 There are two ways to access the group information. 
    429  
    430 '''1'''. Via the current identity object: 
    431 {{{ 
    432 #!python 
    433 from turbogears import identity 
    434 if 'admin' in identity.current.groups: 
    435     pass 
    436 }}} 
    437  
    438 '''2'''. Via the user object on the current identity: 
    439 {{{ 
    440 #!python 
    441 from turbogears import identity 
    442 if 'admin' in [g.group_name for g in identity.current.user.groups]: 
    443     pass 
    444 }}} 
    445  
    446 ''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.'' 
    447 ---- 
    448  
    449 == Notes == 
    450 Setting identity by config has not implement yet. 
    451  
    452 Using tg-admin shell to add identity user/group is not working under 0.9a2. patch is [http://groups.google.com/group/turbogears/browse_thread/thread/e1cd7e5e8cb26bba/9f8ae06fbe07bd5a here] 
    453  
    454 ---- 
    455  
    456 #TODO using SQLAlchemy instead of SQLObject 
    457  
    458 #TODO LdapIdentityProvider