Hi everyone.
Jorge said:
> On Sat, Jun 13, 2009 at 10:35 AM, Gustavo Narea<[email protected]> wrote:
> > Hello,
> >
> > Jorge said:
> >> My goal is to make the "booleanize" stuff work by default. Where teh
> >> predicate will return true/false if it's called from allow_only or
> >> @protect (sorry if that's not the name of the decorator) then
> >>
> >> result = predicate()
> >> if not result:
> >> raise NotAuthorized
> >
> > Where would that code be? In the user's controller or inside @require?
> > Either way, that's already the way things work. Give it a try.
>
> in "repoze.what"
>
> >> which means the predicate is simply a function,
> >
> > Just to return a Python bool, instead of another class instance?
>
> yes,
>
> > Anyway, that function would be anything but a predicate. It won't be
> > reusable, it won't be stateless.
>
> why it has to be stateless? why not reusable? you are assuming we'll
> keep doing allow_only = not_autorized() that of course is dumb.
> something like this could do the job.
> http://wiki.python.org/moin/PythonDecoratorLibrary#Countingfunctioncalls
It must be stateless just because it must be reusable across requests and
threads. Isn't that reason enough?
If it's a function that returns True or False, then its result is obviously
not stateless.
> > As a consequence, its result could not be used in
> > @require or .allow_only -- it will be True or False forever, whatever the
> > requests, because it would be evaluated when the module is loaded and
> > will remain constant from there on.
>
> not really. If you make a decorator that will evaluate on each call it
> will serve the same purpose. Although I agree the syntax will need to
> be changed.
What are you going to evaluate, if what is left is a bool? (see below)
> > The other similar thing would be to wrap the predicates around functions
> > which return True/False. But it wouldn't be a good idea either:
> > 1.- You'd need one of those functions per predicate.
>
> why? first of all the predicate will be become the functions instead
> of the class. Second with just one decorator you can do this. Remember
> a decorator can keep state
>
> > 2.- It could be dangerous. They should only be used *inside* the
> > controller action (i.e., inside the method, never outside) or in the
> > templates. This is, they must not be used in .allow_only or @require, for
> > example.
>
> see below
>
> > 3.- You'd have to instantiate them on each function call, which would be
> > inefficient:
> > """
> > def has_permission(permission):
> > predicate = repoze.what.predicates.has_permission(permission)
> > return predicate.is_met(request.environ)
> > """
>
> if it's a function it doesn't needs to be instantiated, seems like you
> missed the point a predicate will be a function not a class and you
> will have 3-4 decorators that will provide the "is_met", "allow_only"
> and "require" functionality.
What you propose is simply unrealistic:
If you replace predicates with functions that return True or False, what the
decorator will receive will be a True or False. The decorator won't be able to
evaluate anything.
The closest thing you could do, is to use it as callable in the @require and
call it in the controllers:
"""
@require(predicate1)
def my_action(self,):
if predicate2():
pass
"""
And that would be wrong too, because then predicates won't be able to receive
arguments:
"""
@require(has_permission("foo")) # <-- @require received True or False when
# the module was loaded and this value
# won't ever change
def my_action(self, ):
if predicate_foo(): # here it will work
pass
"""
Now let's imagine that somehow it's possible what you say, that the predicate
could keep track of the status:
1.- You'll end up with a method that is not stateless, in spite of it being
most likely shared by several threads.
2.- It just cannot receive a bool. It must receive an instance of some class
-- an object which could verify that the condition is met. And that's what
predicate checkers already do.
Whoever experiments to work around this, will either:
- Give up soon enough.
- Come up with a horribly complex and unreliable solution.
Because there's nothing sane we could do about it.
> > 4.- You can already do "if my_predicate(): do_something()", thanks to
> > the booleanize_predicates() monkey-patch enabled by default in TG2.
>
> which you totally trash as a "hack" in the documentation and point out
> it's dangerous because you are injecting (monkey-patch) the function
> instead of making it the default, which is only dangerous because of
> the monkey-patch.
No. Even if __non_zero__ was implemented by default (which is absolutely
impossible!), it'd be the *exact* *same* thing.
> Last please keep in mind this is an experiment and I'm not entirely
> sure I can accomplish the same API with predicates as functions. But
> in the case I do go back to classes I think we should rethink the API
> (which is my original goal) because as I pointed out in here
> http://groups.google.com/group/turbogears/browse_thread/thread/c2aa4cb5ed07
>f52d, the current API is completely horrible
"Completely horrible" sounds quite excessive, IMHO.
I do believe the API *partially* sucks, though, but for other reason which has
nothing to do with predicate evaluation: It's highly influenced by TG1
Identity and AuthKit, two authz frameworks defective by design because they
reinvented the wheel in the authorization model used, instead of implementing
and possibly extending *proven* authorization mechanisms (such as _real_
ACLs).
There was no need to reinvent the wheel in the authorization field, what we
lack is working implementations. repoze.what 2 will be an attempt to amend
this mistake.
Cheers,
--
Gustavo Narea <xri://=Gustavo>.
| Tech blog: =Gustavo/(+blog)/tech ~ About me: =Gustavo/about |
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"TurboGears Trunk" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/turbogears-trunk?hl=en
-~----------~----~----~----~------~----~------~--~---