diff options
| author | Chris McDonough <chrism@agendaless.com> | 2010-09-09 17:46:49 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2010-09-09 17:46:49 +0000 |
| commit | e25a70a7d1c2016eaeff9c630df9109e715bba3b (patch) | |
| tree | 520508b0bb66600e50b46db46c0a85ef05f0690c /repoze/bfg/configuration.py | |
| parent | 6ae0139d3682730e44a3b2330f83d10b31ebbc95 (diff) | |
| download | pyramid-e25a70a7d1c2016eaeff9c630df9109e715bba3b.tar.gz pyramid-e25a70a7d1c2016eaeff9c630df9109e715bba3b.tar.bz2 pyramid-e25a70a7d1c2016eaeff9c630df9109e715bba3b.zip | |
Features
--------
- In support of making it easier to configure applications which are
"secure by default", a default permission feature was added. If
supplied, the default permission is used as the permission string to
all view registrations which don't otherwise name a permission.
These APIs are in support of that:
- A new constructor argument was added to the Configurator:
``default_permission``.
- A new method was added to the Configurator:
``set_default_permission``.
- A new ZCML directive was added: ``default_permission``.
Documentation
-------------
- Added documentation for the ``default_permission`` ZCML directive.
- Added documentation for the ``default_permission`` constructor value
and the ``set_default_permission`` method in the Configurator API
documentation.
- Added a new section to the "security" chapter named "Setting a
Default Permission".
- Document ``renderer_globals_factory`` and ``request_factory``
arguments to Configurator constructor.
Diffstat (limited to 'repoze/bfg/configuration.py')
| -rw-r--r-- | repoze/bfg/configuration.py | 86 |
1 files changed, 81 insertions, 5 deletions
diff --git a/repoze/bfg/configuration.py b/repoze/bfg/configuration.py index 06115abf7..f8fdcca07 100644 --- a/repoze/bfg/configuration.py +++ b/repoze/bfg/configuration.py @@ -20,6 +20,7 @@ from repoze.bfg.interfaces import IAuthenticationPolicy from repoze.bfg.interfaces import IAuthorizationPolicy from repoze.bfg.interfaces import IChameleonTranslate from repoze.bfg.interfaces import IDebugLogger +from repoze.bfg.interfaces import IDefaultPermission from repoze.bfg.interfaces import IDefaultRootFactory from repoze.bfg.interfaces import IExceptionViewClassifier from repoze.bfg.interfaces import ILocaleNegotiator @@ -85,6 +86,8 @@ DEFAULT_RENDERERS = ( ('string', renderers.string_renderer_factory), ) +_marker = object() + class Configurator(object): """ A Configurator is used to configure a :mod:`repoze.bfg` @@ -160,7 +163,31 @@ class Configurator(object): negotiator` implementation or a :term:`dotted Python name` to same. See :ref:`custom_locale_negotiator`. + If ``request_factory`` is passed, it should be a :term:`request + factory` implementation or a :term:`dotted Python name` to same. + See :ref:`custom_request_factory`. By default it is ``None``, + which means use the default request factory. + + If ``renderer_globals_factory`` is passed, it should be a + :term:`renderer globals` factory implementation or a :term:`dotted + Python name` to same. See :ref:`custom_renderer_globals_factory`. + By default, it is ``None``, which means use no renderer globals + factory. + + If ``default_permission`` is passed, it should be a + :term:`permission` string to be used as the default permission for + all view configuration registrations performed against this + Configurator. An example of a permission string:``'view'``. + Adding a default permission makes it unnecessary to protect each + view configuration with an explicit permission, unless your + application policy requires some exception for a particular view. + By default, ``default_permission`` is ``None``, meaning that view + configurations which do not explicitly declare a permission will + always be executable by entirely anonymous users (any + authorization policy in effect is ignored). See also + :ref:`setting_a_default_permission`. """ + manager = manager # for testing injection venusian = venusian # for testing injection def __init__(self, @@ -174,7 +201,8 @@ class Configurator(object): debug_logger=None, locale_negotiator=None, request_factory=None, - renderer_globals_factory=None): + renderer_globals_factory=None, + default_permission=None): if package is None: package = caller_package() name_resolver = DottedNameResolver(package) @@ -194,7 +222,8 @@ class Configurator(object): debug_logger=debug_logger, locale_negotiator=locale_negotiator, request_factory=request_factory, - renderer_globals_factory=renderer_globals_factory + renderer_globals_factory=renderer_globals_factory, + default_permission=default_permission, ) def _set_settings(self, mapping): @@ -326,7 +355,8 @@ class Configurator(object): authentication_policy=None, authorization_policy=None, renderers=DEFAULT_RENDERERS, debug_logger=None, locale_negotiator=None, request_factory=None, - renderer_globals_factory=None): + renderer_globals_factory=None, + default_permission=None): """ When you pass a non-``None`` ``registry`` argument to the :term:`Configurator` constructor, no initial 'setup' is performed against the registry. This is because the registry @@ -371,6 +401,8 @@ class Configurator(object): if renderer_globals_factory: renderer_globals_factory=self.maybe_dotted(renderer_globals_factory) self.set_renderer_globals_factory(renderer_globals_factory) + if default_permission: + self.set_default_permission(default_permission) # getSiteManager is a unit testing dep injection def hook_zca(self, getSiteManager=None): @@ -598,7 +630,7 @@ class Configurator(object): self.manager.pop() return self.registry - def add_view(self, view=None, name="", for_=None, permission=None, + def add_view(self, view=None, name="", for_=None, permission=_marker, request_type=None, route_name=None, request_method=None, request_param=None, containment=None, attr=None, renderer=None, wrapper=None, xhr=False, accept=None, @@ -629,7 +661,17 @@ class Configurator(object): The name of a :term:`permission` that the user must possess in order to invoke the :term:`view callable`. See :ref:`view_security_section` for more information about view - security and permissions. + security and permissions. If ``permission`` is omitted, a + *default* permission may be used for this view registration + if one was named as the + :class:`repoze.bfg.configuration.Configurator` constructor's + ``default_permission`` argument, or if + :meth:`repoze.bfg.configuration.Configurator.set_default_permission` + was used prior to this view registration. Pass ``None`` as + the permission to explicitly indicate that the view should + always be executable by entirely anonymous users, regardless + of the default permission, bypassing any + :term:`authorization policy` that may be in effect. attr @@ -894,6 +936,10 @@ class Configurator(object): containment=containment, request_type=request_type, custom=custom_predicates) + if permission is _marker: + # intent: will be None if no default permission is registered + permission = self.registry.queryUtility(IDefaultPermission) + derived_view = self._derive_view(view, permission, predicates, attr, renderer, wrapper, name, accept, order, phash) @@ -1610,6 +1656,36 @@ class Configurator(object): negotiator = self.maybe_dotted(negotiator) self.registry.registerUtility(negotiator, ILocaleNegotiator) + def set_default_permission(self, permission): + """ + Set the default permission to be used by all subsequent + :term:`view configuration` registrations. ``permission`` + should be a :term:`permission` string to be used as the + default permission. An example of a permission + string:``'view'``. Adding a default permission makes it + unnecessary to protect each view configuration with an + explicit permission, unless your application policy requires + some exception for a particular view. + + If a default permission is *not* set, views represented by + view configuration registrations which do not explicitly + declare a permission will be executable by entirely anonymous + users (any authorization policy is ignored). + + Later calls to this method override earlier calls; there can + be only one default permission active at a time within an + application. + + See also :ref:`setting_a_default_permission`. + + .. note: This API is new as of :mod:`repoze.bfg` version 1.3. + + .. note:: Using the ``default_permission`` argument to the + :class:`repoze.bfg.configuration.Configurator` constructor + can be used to achieve the same purpose. + """ + self.registry.registerUtility(permission, IDefaultPermission) + def add_translation_dirs(self, *specs): """ Add one or more :term:`translation directory` paths to the current configuration state. The ``specs`` argument is a |
