summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt13
-rw-r--r--docs/narr/security.rst21
-rw-r--r--pyramid/authorization.py3
3 files changed, 37 insertions, 0 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 85dd3be2a..ae2cafba4 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,16 @@
+next release
+============
+
+Features
+--------
+
+- ``ACLAuthorizationPolicy`` supports ``__acl__`` as a callable. This
+ removes the ambiguity between the potential ``AttributeError`` that would
+ be raised on the ``context`` when the property was not defined and the
+ ``AttributeError`` that could be raised from any user-defined code within
+ a dynamic property. It is recommended to define a dynamic ACL as a callable
+ to avoid this ambiguity. See https://github.com/Pylons/pyramid/issues/735.
+
1.4 (2012-12-18)
================
diff --git a/docs/narr/security.rst b/docs/narr/security.rst
index 5b79edd19..36c888559 100644
--- a/docs/narr/security.rst
+++ b/docs/narr/security.rst
@@ -270,6 +270,27 @@ resource instances with an ACL (as opposed to just decorating their class) in
applications such as "CMS" systems where fine-grained access is required on
an object-by-object basis.
+Dynamic ACLs are also possible by turning the ACL into a callable on the
+resource. This may allow the ACL to dynamically generate rules based on
+properties of the instance.
+
+.. code-block:: python
+ :linenos:
+
+ from pyramid.security import Allow
+ from pyramid.security import Everyone
+
+ class Blog(object):
+ def __acl__(self):
+ return [
+ (Allow, Everyone, 'view'),
+ (Allow, self.owner, 'edit'),
+ (Allow, 'group:editors', 'edit'),
+ ]
+
+ def __init__(self, owner):
+ self.owner = owner
+
.. index::
single: ACE
single: access control entry
diff --git a/pyramid/authorization.py b/pyramid/authorization.py
index 943f8bd00..1fd05e244 100644
--- a/pyramid/authorization.py
+++ b/pyramid/authorization.py
@@ -80,6 +80,9 @@ class ACLAuthorizationPolicy(object):
except AttributeError:
continue
+ if acl and callable(acl):
+ acl = acl()
+
for ace in acl:
ace_action, ace_principal, ace_permissions = ace
if ace_principal in principals: