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 22 and Version 23 of IdentityManagement


Ignore:
Timestamp:
03/29/06 07:37:22 (13 years ago)
Author:
fredlin
Comment:

make identity doc up-to-date

Legend:

Unmodified
Added
Removed
Modified
  • IdentityManagement

    v22 v23  
    11= Identity Management = 
    22 
    3   '''This was ripped from [http://metrocat.org/nerd/2005/10/identity-management-for-turbogears Jeff Watkins' blog].''' 
    4  
    5   ...with a little changes to play nice with latest svn [as of 9th Jan 2006] 
    6  
    7 I just committed the code for the TurboGears identity management support (revision 89). And because this is such new code, I thought it might be helpful to include a short How To for getting everything up and running. 
     3It's a short How To for getting TurboGears identity management support up and running. 
    84 
    95This How To is written from the perspective of a fresh quick-started project, but most everything applies for existing projects. 
     
    1814Name your project idtest and set the dburi in dev.cfg to point to a server and database you want to use. 
    1915 
    20 === Step 2 - Edit idtest.egg-info/sqlobject.txt === 
    21 {{{ 
    22 #!python 
    23 db_module=idtest.model,  turbogears.identity.soprovider 
    24 }}} 
    25  
    26 === Step 3 - Create login.kid template === 
    27  
    28 The login template and the controllers.py file are already created with up-to-date SVN quickstarts.  This was instituted sometime around SVN 485.  Here's the code in case you don't have it. 
    29  
    30 {{{ 
    31 #!text/html 
    32     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    33         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    34     <html xmlns="http://www.w3.org/1999/xhtml" 
    35         xmlns:py="http://purl.org/kid/ns#" 
    36         py:extends="'master.kid'"> 
    37  
    38     <head> 
    39         <meta content="text/html; charset=UTF-8" 
    40             http-equiv="content-type" py:replace="''"/> 
    41         <title>Login to TurboGears</title> 
    42     </head> 
    43  
    44     <body> 
    45         <h2>Login</h2> 
    46         <p>${message}</p> 
    47         <form action="${previous_url}" method="POST"> 
    48             <label for="user_name">User Name:</label> 
    49             <input type="text" id="user_name" name="user_name"/><br/> 
    50  
    51             <label for="password">Password:</label> 
    52             <input type="password" id="password" name="password"/><br/> 
    53  
    54             <input type="submit" value="Login"/> 
    55         </form> 
    56     </body> 
    57     </html> 
    58 }}} 
    59  
    60 === Step 4 - Create secured.kid template === 
    61 {{{ 
    62 #!text/html 
    63 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    64     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
    65 <html xmlns="http://www.w3.org/1999/xhtml" 
    66    xmlns:py="http://purl.org/kid/ns#" 
    67    py:extends="'master.kid'"> 
    68  
    69 <head> 
    70     <meta content="text/html; charset=UTF-8" 
    71         http-equiv="content-type" py:replace="''"/> 
    72    <title>Welcome to Secured TurboGears</title> 
    73 </head> 
    74  
    75 <body> 
    76     <h2>Secure!</h2> 
    77     <p>This page is secured.</p> 
    78 </body> 
    79 </html> 
    80 }}} 
    81  
    82 === Step 5 - edit controllers.py === 
    83 Ad this code to the top of the file: 
     16=== Step 2 - Edit project_name/config/app.cfg === 
     17Edit app.cfg. Under the "IDENTITY" heading (around line 68), uncomment and edit the following to turn on identity management. Edit the failure url as well. 
     18 
     19{{{ 
     20#!python 
     21visit.on=True 
     22identity.on = True 
     23identity.failure_url = "/login" 
     24}}} 
     25 
     26=== Step 3 - Testing the login === 
     27Start the project: 
     28{{{ 
     29#!python 
     30$ start-project_name 
     31}}} 
     32 
     33The 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. 
     34 
     35You can access any other pages without trouble, because we haven't "protect" those pages by identity decorator. 
     36 
     37=== Step 4 - protect your pages === 
     38Edit controllers.py,  
     39 
     40Add this code to the top of the file: 
     41 
    8442{{{ 
    8543#!python 
    8644from turbogears import identity 
    87 import cherrypy 
    88 }}} 
    89  
    90 Then add this inside the root controller class: 
    91  
    92 {{{ 
    93 #!python 
    94 @turbogears.expose( html="idtest.templates.login" ) 
    95 def login( self, *args, **kw ): 
    96     if hasattr(cherrypy.request,"identity_errors"): 
    97         msg= str(cherrypy.request.identity_errors) 
    98     else: 
    99         msg= "Please log in" 
    100     cherrypy.response.status=403 
    101     return dict( message=msg, previous_url=cherrypy.request.path ) 
    102     #to preserve the session you may want to return this instead: 
    103     #return dict( message = msg, previous_url = turbogears.url( cherrypy.request.path, cherrypy.request.paramMap ) ) 
    104  
    105 @turbogears.expose( html="idtest.templates.secured" ) 
    106 @identity.require( in_group="admin" ) 
    107 def secured( self ): 
    108     return dict() 
    109 }}} 
    110  
    111 Note: You may need to revise the above code for the @identity.require decorator. In a [http://groups.google.com/group/turbogears/browse_thread/thread/8dc90943e2cce3ce/42de9e3ae86f7aaf?q=identity&rnum=1#42de9e3ae86f7aaf recent mailing list post], Jeff Watkins writes the following.  
    112 {{{ 
    113 In the past you decorated your methods as such: 
    114  
    115      @turbogears.expose() 
    116      @identity.require( group="admin", permission="foo,bar" ) 
    117  
    118 The require decorator checked whether the visitor was a member of the   
    119 admin group AND had the permission foo AND had the permission bar. 
    120  
    121 Many people wanted something more flexible, and with revision 400,   
    122 any of the following are valid require decorators: 
    123  
    124      @identity.require( in_group( "admin" ) ) 
    125      @identity.require( in_all_groups( "admin", "editor" ) ) 
    126      @identity.require( in_any_group( "admin", "editor" ) ) 
    127      @identity.require( has_permission( "edit" ) ) 
    128      @identity.require( has_all_permissions( "edit", "delete",   
    129 "update" ) ) 
    130      @identity.require( has_any_permission( "edit", "delete",   
    131 "update" ) ) 
    132  
    133 But most importantly, you can use decorators like theses: 
    134  
    135      @identity.require( Any( in_group( "admin" ), has_permission 
    136 ( "edit" ) ) ) 
    137      @identity.require( All( from_host( "127.0.0.1" ), has_permission 
    138 ( "edit" ) ) ) 
    139      @identity.require( All( from_any_host( "127.0.0.1", "10.0.0.1" ), 
    140                         in_group( "editor" ) ) ) 
    141  
    142 You can also use these same predicates in your own code: 
    143  
    144      if in_group( "admin" ) and has_permission( "edit" ): 
    145          pass 
    146      else: 
    147          pass 
    148  
    149 I still haven't addressed the need for something like `is_owner`,   
    150 because that seems *so* model specific.  
    151 }}} 
    152  
    153 However, you may need to use the in_group, in_all_groups, etc. functions in the {{{identity}}} namespace. For example: 
    154 {{{ 
    155 @identity.require( in_group( "admin" ) ) 
    156 }}} 
    157 changes to 
    158 {{{ 
    159 @identity.require( identity.in_group( "admin" ) ) 
    160 }}} 
    161  
    162  
    163 === Step 6 - Turn on Identity management === 
    164 Edit dev.cfg. Under the "IDENTITY" heading (around line 68), uncomment and edit the following to turn on identity management. Edit the failure url as well. 
    165 {{{ 
    166 identity.on=True 
    167 identity.failure_url="/login" 
    168 }}} 
    169  
    170 === Step 7 - Create the database === 
    171 {{{ 
    172 $ tg-admin sql create 
    173 }}} 
    174  
    175 === Step 8 - Create a user and group === 
    176  
    177 Using Catwalk is probably the easiest way to create user/group/permissions.  Use this method if you can't get Catwalk set up. 
     45}}} 
     46 
     47If you want protect any page(a python method), add an identity decorator over the page. 
     48 
     49let's protect the index page: 
     50 
     51{{{ 
     52#!python 
     53    @turbogears.expose(template="omgears.templates.welcome") 
     54    @identity.require( identity.in_group( "admin" )) 
     55    def index(self): 
     56        .... 
     57}}} 
     58 
     59Let's visit the http://localhost:8080/, now the index page is protected. 
     60 
     61Note: You may need to revise the above code for the @identity.require decorator. In a [http://groups.google.com/group/turbogears/browse_thread/thread/8dc90943e2cce3ce/42de9e3ae86f7aaf?q=identity&rnum=1#42de9e3ae86f7aaf recent mailing list post], Jeff Watkins writes the most of usages.(see the end of the post)  
     62 
     63=== Step 5 - Create a user and group === 
     64 
     65We just learn howto protect our page, but now we can't access those pages any more. We need add some user/group/admission to login to the protected pages. 
     66 
     67Using Catwalk is probably the easiest way to create user/group/permissions(But it doen't work in 0.92a) Use this method if you can't get Catwalk set up. 
    17868 
    17969{{{ 
     
    19383}}} 
    19484 
    195 === Step 9 - Testing the login === 
    196 Start the project: 
    197 {{{ 
    198 #!python 
    199 $ ./idtest-start.py 
    200 }}} 
    201  
    202 and visit secured page http://localhost:8080/secured and login with the username and password you just created. It should fail with the message: 
    203 {{{ 
    204 Not member of group: admin 
    205 }}} 
    206  
    207 === Step 10 - Add the user to admin group === 
     85 
     86=== Step 6 - Add the user to admin group === 
    20887{{{ 
    20988$ tg-admin shell 
     
    222101}}} 
    223102 
    224 === Step 11 - Revisit secured page and login === 
    225  
    226 Browse to http://localhost:8080/secured again and login, this time you should see the content of secured.kid 
    227  
    228 ---- 
     103=== Step 7 - Revisit secured page and login === 
     104 
     105Browse to http://localhost:8080/ again and login, this time you should see the content of index page 
     106 
     107 
     108---- 
     109 
     110= Following contents haven't been re-processed yet = 
    229111 
    230112== Restricting Access to whole Subdirectory == 
     
    320202''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.'' 
    321203---- 
     204 
     205 
     206=== Note: Create the database === 
     207In stead of step 3, you can create database manually 
     208{{{ 
     209$ tg-admin sql sql 
     210}}} 
     211 
     212{{{ 
     213In the past you decorated your methods as such: 
     214 
     215     @turbogears.expose() 
     216     @identity.require( group="admin", permission="foo,bar" ) 
     217 
     218The require decorator checked whether the visitor was a member of the   
     219admin group AND had the permission foo AND had the permission bar. 
     220 
     221Many people wanted something more flexible, and with revision 400,   
     222any of the following are valid require decorators: 
     223 
     224     @identity.require( in_group( "admin" ) ) 
     225     @identity.require( in_all_groups( "admin", "editor" ) ) 
     226     @identity.require( in_any_group( "admin", "editor" ) ) 
     227     @identity.require( has_permission( "edit" ) ) 
     228     @identity.require( has_all_permissions( "edit", "delete",   
     229"update" ) ) 
     230     @identity.require( has_any_permission( "edit", "delete",   
     231"update" ) ) 
     232 
     233But most importantly, you can use decorators like theses: 
     234 
     235     @identity.require( Any( in_group( "admin" ), has_permission 
     236( "edit" ) ) ) 
     237     @identity.require( All( from_host( "127.0.0.1" ), has_permission 
     238( "edit" ) ) ) 
     239     @identity.require( All( from_any_host( "127.0.0.1", "10.0.0.1" ), 
     240                        in_group( "editor" ) ) ) 
     241 
     242You can also use these same predicates in your own code: 
     243 
     244     if in_group( "admin" ) and has_permission( "edit" ): 
     245         pass 
     246     else: 
     247         pass 
     248 
     249I still haven't addressed the need for something like `is_owner`,   
     250because that seems *so* model specific.  
     251}}} 
     252 
     253However, you may need to use the in_group, in_all_groups, etc. functions in the {{{identity}}} namespace. For example: 
     254{{{ 
     255@identity.require( in_group( "admin" ) ) 
     256}}} 
     257changes to 
     258{{{ 
     259@identity.require( identity.in_group( "admin" ) ) 
     260}}} 
     261 
     262 
     263 
     264  '''This post was originally ripped from [http://metrocat.org/nerd/2005/10/identity-management-for-turbogears Jeff Watkins' blog].''' 
     265 
     266  ...with a little changes to play nice with latest svn [as of 9th Jan 2006]