-
-
Save faddai/4223224 to your computer and use it in GitHub Desktop.
ACLs, context objects, and URL Dispatch in Pyramid
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment