Changeset 5613
- Timestamp:
- 10/25/08 08:09:34 (3 months ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
docs/2.0/docs/main/Extensions/Authorization/index.rst
r5605 r5613 7 7 .. moduleauthor:: Agendaless Consulting and Contributors 8 8 9 :Status: Work in progress 9 :Status: Official 10 11 12 This document introduces :mod:`tgext.authorization` and also explains how to 13 get started. For more information about :mod:`tgext.authorization`, you may 14 want to check the `advanced topics`_. 15 16 .. contents:: Table of Contents 17 :depth: 2 10 18 11 19 … … 67 75 ~~~~~~~~~~~~~~ 68 76 Below are the contents of a mock ``.htgroups`` file that defines the groups of 69 yourTG2 application. In other words, such a file is a :term:`group source` of77 a TG2 application. In other words, such a file is a :term:`group source` of 70 78 type ``htgroups``:: 71 79 … … 73 81 admins: rms, linus 74 82 users: gustavo, maribel 75 83 84 It has three sections and five items: "developers" (made up of the items "rms", 85 "linus" and "guido"), "admins" (made up of the items "rms" and "linus") and 86 "users (made up of the items "gustavo" and "maribel"). 87 76 88 And below are the contents of a mock ``.ini`` file that defines the permissions 77 of the groups in yourTG2 application. In other words, such a file is a89 of the groups in a TG2 application. In other words, such a file is a 78 90 :term:`permission source` of type ``Ini``:: 79 91 … … 81 93 admins 82 94 [release-software] 83 developers84 [add-users]85 95 admins 86 96 developers … … 88 98 users 89 99 100 It has four sections and three items: "manage-site" (made up one item, 101 "admins"), "release-software" (made up of the items "admins" and "developers") 102 and "contact-us" (made up of the item "users"). 103 90 104 If you use a database to store your users, groups and permissions, then such a 91 105 database is both the group and permission source: … … 97 111 98 112 99 Implementing authorization 100 -------------------------- 101 To implement authorization in your TurboGears project, you need to add some 113 .. _add-auth-middleware: 114 115 Setting up authentication and authorization 116 ------------------------------------------- 117 118 To enable authorization in your TurboGears project, you need to add some 102 119 WSGI middleware to your application, which is automatically done for you if 103 120 you are using the quickstart (:mod:`tgext.authorization.quickstart`). 104 121 122 When you enable authorization with :mod:`tgext.authorization`, authentication 123 with :mod:`repoze.who` is automatically enabled. 124 125 .. note:: 126 The `quickstart` is enabled when in ``{yourproject}.config.app_cfg`` you 127 have ``base_config.auth_backend`` set. To disable it, it's enough to 128 remove that line -- and you may also want to delete those like 129 ``base_config.sa_auth.*``. 130 131 105 132 Using authentication and authorization without the quickstart 106 133 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 134 107 135 If you're not using the quickstart, then you have to add the required 108 136 middleware in your application. This gives you more flexibility, such as being … … 117 145 from repoze.who.plugins.htpasswd import HTPasswdPlugin, crypt_check 118 146 from tgext.authorization.middleware import setup_auth 119 # Please note that the plugins below have not been created ; want to147 # Please note that the plugins below have not been created yet; want to 120 148 # jump in? 121 149 from tgext.authorization.plugins.htgroups import HtgroupsAdapter 122 150 from tgext.authorization.plugins.ini import IniPermissionAdapter 123 151 124 # Defining the group adapters; you may add as much as you want:152 # Defining the group adapters; you may add as much as you need: 125 153 groups = {'all_groups': HtgroupsAdapter('/path/to/groups.htgroups')} 126 154 127 # Defining the permission adapters; you may add as much as you want:155 # Defining the permission adapters; you may add as much as you need: 128 156 permissions = {'all_perms': IniPermissionAdapter('/path/to/perms.ini')} 129 157 130 # repoze.who authenticators :158 # repoze.who authenticators; you may add as much as you need: 131 159 htpasswd_auth = HTPasswdPlugin('/path/to/users.htpasswd', crypt_check) 132 160 authenticators = [('htpasswd', htpasswd_auth)] … … 140 168 return app_with_auth 141 169 142 Of course, there are other things you may customize ; such as adding repoze.who143 identifiers, more authenticators, challengers and metadata providers, which 144 is explained later in this documentation. 170 Of course, there are other things you may customize, such as adding 171 :mod:`repoze.who` identifiers, more authenticators, challengers and metadata 172 providers -- read on! 145 173 146 174 Now you're ready to add the middleware. Go to ``{yourproject}.config.middleware`` … … 149 177 def make_app(global_conf, full_stack=True, **app_conf): 150 178 app = make_base_app(global_conf, full_stack=True, **app_conf) 151 # Wrap your base turbogears app with custom middleware179 # Wrap your base turbogears app with custom middleware 152 180 app = add_auth(app, config) 153 181 return app 154 182 155 183 156 Action-level authorization 157 ~~~~~~~~~~~~~~~~~~~~~~~~~~ 158 @TODO: Improve these contents. 159 160 Add the following methods to your controllers.root:RootController class:: 161 162 @expose('yourproject.templates.about') 163 @authorize.require(authorize.has_permission('manage')) 164 def manage_permission_only(self, **kw): 165 return dict(now=now, page='about') 166 167 @expose('yourproject.templates.about') 168 @authorize.require(authorize.is_user('editor')) 169 def editor_user_only(self, **kw): 170 return dict(now=now, page='about') 171 172 @expose('yourproject.templates.login') 173 def login(self, **kw): 174 came_from = kw.get('came_from', '/') 175 return dict(now=now, page='login', header=lambda *arg: None, 176 footer=lambda *arg: None, came_from=came_from) 177 178 The important code to look at here is the @authorize.require decorator, which 179 checks that the currently logged in user is logged in user is 'editor'. 180 181 182 Controller-level authorization 183 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 184 If you want that all the actions from a given controller meet a common 185 authorization criteria, then you may define the ``require`` attribute of 186 your controller class:: 187 188 class Admin(SecureController): 189 require = authorize.has_permission('manage') 190 191 @expose('yourproject.templates.index') 192 def index(self): 193 flash(_("Secure Controller here")) 194 return dict(page='index') 195 196 @expose('yourproject.templates.index') 197 def some_where(self): 198 """This are is protected too. 199 200 Only those with "manage" permissions may access. 201 202 """ 203 return dict() 204 205 Where your ``SecureController`` class may look like this:: 206 207 class SecureController(BaseController): 208 """SecureController implementation for the tgext.authorization extension. 209 210 it will permit to protect whole controllers with a single predicate 211 placed at the controller level. 212 The only thing you need to have is a 'require' attribute which must 213 be a callable. This callable will only be authorized to return True 214 if the user is allowed and False otherwise. This may change to convey info 215 when securecontroller is fully debugged... 216 """ 217 218 def check_security(self): 219 errors = [] 220 environ = request.environ 221 identity = environ.get('repoze.who.identity') 222 if not hasattr(self, "require") or \ 223 self.require is None or \ 224 self.require.eval_with_object(identity, errors): 225 return True 226 227 # if we did not return this is an error :) 228 # TODO: do something with the errors variable like informing our user... 229 return False 230 231 If you enabled authentication/authorization in your project when it was created, 232 then this class is defined in ``{yourproject}.lib.base``. 233 234 Predicates 235 ~~~~~~~~~~ 236 237 @TODO: Elaborate more on them (more importantly, explain what they are first). 238 239 There authorize module contains various predicate checker functions: 240 241 * is_user -- checks to see that the logged in user IS the specified user 242 * in_group -- checks to see that the logged in user is in the specified group 243 * in_all_groups -- is the user is all the groups specified 244 * in_any_group -- is the user in any of these groups 245 * not_anonymous -- any logged in user will do 246 * has_permission -- logged in user has the specified permission 247 * has_all_permissions -- has all the permissions listed 248 * has_any_permission -- has any of the listed permissions 249 250 There are also a couple of predicates you can use to aggregate the above 251 permissions. 252 253 * All -- used to combine the above predicate checks requiring that all of them 254 are true. 255 * Any -- same as All, but only requires that one of the checks return true. 256 257 If a user is not logged in or does not have the proper permissions the 258 predicate checks throw a 403 (HTTP Not Authorized) which is caught by the 259 tgext.authorization middleware which displays the login page allowing the user 260 to login, and redirecting the user back to the proper page when they are done. 261 262 263 Plugins 264 ------- 265 266 Plugins extend the functionality of :mod:`tgext.authorization` and the most 267 common type of plugins are those that add support for more type of group and 268 permission sources. 269 270 Groups handling adapters 271 ~~~~~~~~~~~~~~~~~~~~~~~~ 272 @TODO 273 274 Permissions handling adapters 275 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 276 @TODO 184 What's next? 185 ------------ 186 187 Once your application includes the required WSGI middleware for authentication 188 and authorization, as explained in :ref:`add-auth-middleware`, you are ready 189 to implement authorization in your controllers with 190 :mod:`tgext.authorization.authorize`. 277 191 278 192 … … 283 197 :maxdepth: 2 284 198 199 Authorize 285 200 Quickstart 286 201 Plugins 287 202 ManagingSources 288 203 WritingSourceAdapters 204 InnerWorkings