Hello, Tim.

On 15/02/10 22:06, Tim Hoffman wrote:
> Hi Gustavo
>
> Yeah I have thought about writing custom Predicates.
>
> The main problem I saw with it was it appears I would have to pass in
> the object to be checked at
> predicate instantiation time, rather than at evaluation time.
>
> evaluate only takes environ and credentials.
> Which means I would have to somehow stuff the entity into the wsgi
> environ or I would be retrieving the object
> a second time inside the evaluate predicate, when I already have it.
> And that would seem expensive (I am running on App Engine).
>
> So using your example from the docs.
>
> It would look something like.
>
>
> from repoze.what.predicates import Predicate
>
> class is_author(Predicate):
>    message = 'Only %(author)s can manage post %(post_id)s'
>
>    def __init__(self,context,**kwargs):
>        super(is_author,self).__init__(kwargs)
>        self.context = context
>
>    def evaluate(self, environ, credentials):
>        
>        if self.context.author != credentials.get('repoze.what.userid'):
>            self.unmet(post_id=post_id, author=post.author_userid)
>

I use the wsgiorg.routing_args variable
(environ['wsgiorg.routing_args']) to store the objects for the resource
in the URL, like this:

====
class BasePostPredicate(Predicate):
    def _get_blog_post(self, environ):
        if "post" not in environ['wsgiorg.routing_args'][1]:
            post_id = environ['wsgiorg.routing_args'][1]['post_id']
            environ['wsgiorg.routing_args'][1]['post'] =
gimme_the_post(post_id)
        return environ['wsgiorg.routing_args'][1]['post']

class IsAuthor(BasePostPredicate):
    def evaluate(self, environ, credentials):
        post = self._get_blog_post(environ)
        if post.author != credentials.get('repoze.what.userid'):
        self.unmet('Only %(author)s can manage post %(post_id)s',
                   author=post.author, post_id=post.id)

class IsEditor(BasePostPredicate):
    def evaluate(self, environ, credentials):
        post = self._get_blog_post(environ)
        if credentials.get('repoze.what.userid') not in post.editors:
        self.unmet('Only editors can manage post %(post_id)s',
                   post_id=post.id)
====

BasePostPredicate looks ugly because of the environ dict. Starting with
v1.1, we're going to use the pythonic WebOb request objects and thus it
will look like this:
====
class BasePostPredicate(Predicate):

    def _get_blog_post(self, request):
        if "post" not in request.urlvars:
            request.urlvars['post'] =
gimme_the_post(request.urlvars['post_id'])
        return request.urlvars['post']
====

> And then
>
> # Can the user edit the post?  (must be site manager or owner)
>
> from repoze.what.predicates import Any, has_permission
> p =  Any(has_permission('site_manager'),is_author(context))
>

Right. But with the predicate above, you wouldn't pass the context:
   p = Any(has_permission('site_manager'),IsAuthor())

HTH,

 - Gustavo.

>
> On Tue, Feb 16, 2010 at 5:41 AM, Gustavo Narea <m...@gustavonarea.net
> <mailto:m...@gustavonarea.net>> wrote:
> > Hello, Tim.
> >
> > The groups/permissions functionality is just something basic and
> > optional, to help people get started, although for some smaller projects
> > it may be good enough. For finer-grained control, you may want to check
> > this:
> >
> http://what.repoze.org/docs/1.0/Manual/Predicates/Writing.html#creating-a-predicate-checker-more-sensitive-to-the-request
> >
> > I've never really wanted to offer a similar functionality
> > out-of-the-box. I've given some thought to this, and never came up with
> > non-intrusive way of addressing this kind of situations. But I'm always
> > open to hear alternatives.
> >
> > I hope this is what you were looking for.
> >
> >  - Gustavo.
> >
> >
> > On 15/02/10 15:19, Tim Hoffman wrote:
> >> Hi
> >>
> >> I am trying to work out how I could protect a specific resource/entity
> >> using repoze.what.
> >>
> >> For instance I have a specific "Record", owned by a specific
> "User", and
> >> only a user with the "Owner" permission can "Edit" the record.
> >>
> >> I can't work out how you would assign "Owner" permission to the
> user only when
> >> accessing "Record".  i.e the user in question would not be owner of
> >> any other record.
> >>
> >> It seems the group source and permission source act on a global basis
> >> and aren't context aware.  And predicates check_authorization() calls
> >> only take a environ
> >> and therefore you can only protect things like URL's not entities.
> >>
> >> Am I trying to do something not possible/intended for repoze.what.
> >>
> >> I suppose I am looking for functionality similiar to zope2
> >> permissions/roles etc...
> >>
> >> T
> >> _______________________________________________
> >> Repoze-dev mailing list
> >> Repoze-dev@lists.repoze.org <mailto:Repoze-dev@lists.repoze.org>
> >> http://lists.repoze.org/listinfo/repoze-dev
> >>
> >
> >
> > --
> > Gustavo Narea <xri://=Gustavo>.
> >
> >
>


-- 
Gustavo Narea <xri://=Gustavo>.

_______________________________________________
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev

Reply via email to