-
-
Save inklesspen/4222841 to your computer and use it in GitHub Desktop.
# A worked example based on http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/narr/urldispatch.html#using-pyramid-security-with-url-dispatch | |
# in your configuration section (typically in myapp/__init__.py) | |
config.add_route('articles.edit', 'article/{id}/edit', factory='myapp.acl.ArticleACL') | |
# in myapp/acl.py | |
class ArticleACL(object): | |
def __init__(self, request): | |
# First, we assume this ACL object is used only in routes that provide an article id; if need be, you can add some sanity checking here, or some if/else branching | |
assert request.matched_route.name == 'articles.edit' | |
# Now, if all articles can be edited by the same group of people, you could do like this: | |
self.__acl__ = [(pyramid.security.Allow, 'group:editors', 'edit')] | |
# This means that any user with the principal 'group:editors' has the edit permission. You would have your authentication policy add the 'group:editors' principal on your editor users. | |
# But what if each article can only be edited by the person who created it? | |
# First, let's load in the article, and set it on self; that'll come in handy later | |
try: | |
self.article = myapp.model.Article.find_by_id(request.matchdict['id']) | |
except NoResultFound, e: | |
# This is a SQLAlchemy exception, but you can use whatever method of catching nonexistant articles you like | |
# Since the article doesn't exist, we'll trigger a 404 Not Found. You might like to return 403 Forbidden on missing articles as well, to avoid giving an idea of which article ids exist and which do not. Up to you. | |
raise pyramid.httpexceptions.HTTPNotFound() | |
# This assumes that the article has an editor_id property which matches a principal provided by your auth policy. | |
self.__acl__ = [(pyramid.security.Allow, self.article.editor_id, 'edit')] | |
# finally, your view: | |
@view_config(route_name='articles.edit', permission='edit') | |
def article_edit(request): | |
# the instance of ArticleACL that had self.article set on it is available on the request. | |
article = request.context.article | |
# Now, do whatever's necessary to render the editing form. | |
return render_editing_form(article) |
Actually, there's two examples there; one where anyone can edit anything, and one where only the person whose id is stored in the record can edit it.
Basically you calculate ACLs based on who you want to have access. If you're using the SessionAuthenticationPolicy, there's a callback you need to provide where you look up the user based on whatever ID you stored, and then return a list of principals. So Alice from Org A could have ['user:alice', 'group:Aeditors'] as principals. Then when you set acls, you would do self.acl = [(Allow, 'group:Aeditors', 'edit')].
Basically Pyramid looks at all the principals set for the currently logged in user and then checks to see if there's an ACL that grants the needed privilege for any of those principals.
According to this example,
An editor from org A can edit content by an editor from org B. How do I go around that?