On Thu, Mar 12, 2009 at 6:59 AM, Gustavo Narea <[email protected]> wrote:
> Hola, Jorge.
>
<snip>

<snip> moved to another thread.

>
>> >> 2- We need a better way to attach a predicate to a exposed method, +4
>> >> LOC for each one is not fun.
>> >
>> > I have no idea what you mean by that. What 4 LOC per exposed action?
>>
>> in order to overwrite the functionality of CRC to allow a different
>> require decorator you have this 4 lines
>>
>>     @require(in_group('managers'))
>>     @expose()
>>     def get_all(self,*args,**kw):
>>         return super(RegistrationController,self).get_all(*args,**kw)
>>
>> I guess you could fetch the method from the parent class and decorate
>> it but I find that more cryptic than the 4 lines above. In general
>> this question should be.
>
> Ahh, right, I see what you mean!
>
> Yes, I was afraid that'd be true.
>
> Well, to make things easier in the Rest controller, I can make repoze.what-
> pylons support an alternative to the @ActionProtector decorator (@require's
> parent), so that you could have:
>    decorate_with_require(RegistrationController.get_all,
>                          in_group('managers'))

that seems less ugly but it doesn't fits with the class dispatch
stuff, where will that line go? at the class? or outside of it?

> instead of:
>    RegistrationController.get_all = require(in_group('managers'))\
>                                     (RegistrationController.get_all)
>
> But I'm not too fond of this solution because it's not simple enough, I think
> it's possibly better to handle it in the Rest controller itself, somehow.
>
well the simplest solution will be to provide a hook like it's done
for the forms. so you will do something like.

class RegistrationController(CrudRestController):
    ...
    edit_require = All(editor_is_current(),in_group('managers'))

And internally CRC will do @require(edit_require)

>
>> Is there a way to declare the controller method somewhere and decorate
>> it with auth in a second stage?
>
> I guess
>    RegistrationController.get_all = require(in_group('managers'))\
>                                     (RegistrationController.get_all)
> would work.
>
> But it's ugly.
>
I think this is something we have to look after specially for TG2.1
when we plan to have re-distributable component. I can totally see
someone wanting to get auth working in a different way than what the
original author intended too. For example imagine someone writes
tgext.wiki, which is open to the world to read but you need to login
to write, and I want to use that wiki to keep my personal items and
let some people see some pages, I'll have to basically subclass each
controller in the tgext.wiki package to modify it's auth. I find that
is a horrible bloat.

>
>> >> 3- why repoze.what made All ? can't we use any/all from python we have
>> >> plenty of ways of providing that in the TG1 codebase
>> >
>> > There's no way to do that. They need the environ to be evaluated.
>>
>> seriously? you can't do this with __call__. according to help(all) it
>> simply calls bool(x) so I assume there has to be a way to stick that
>> in there.
>
> bool(predicate) is not a valid option. It assumes that the Predicate class has
> been monkey patched with the buggy trick of __nonzero__.
>
is not? I assumed that was the solution for
http://trac.turbogears.org/ticket/2205

>
>> >> 4- look at how awful is that custom predicate to simply figure out if
>> >> the current user is the one trying to be edited, I have left the
>> >> pprint in there to give you an idea of how horrible it was for me to
>> >> find out how to query for him.
>> >
>> > (Answered above)
>>
>> I think you oversimplified the problem, there is no "User.user_name"
>> in the url. therefore i need to fetch that record and compare it to
>> the current user.
>
> If you're using the artificial key "user_id" in the URL, yes, you have to use
> it, unless you tell repoze.what.plugins.sql to pass User.user_id as the user
> identifier.
>
aritficial key? huh? please stop thinking about auth for a minute :)
this is REST in rest resources have a key, keys for convenience are
numeric and unique, the fact that this key happens to refer to the
user is a mere coincidence.

>
>> >> 4.1- why is repoze.what.userid == User.user_name ??
>> >
>> > Don't ask me, you wrote it ;-) I don't even know you used the DB =)
>>
>> huh? repoze.what.userid is loaded by repoze.what from the "user_name"
>> field, it is inconsistent as the User.user_id attribute is a number
>> (autogenerated index) while repoze.what.userid is a string (stored in
>> User.user_name)
>
> Inconsistent? repoze.what doesn't have to be "consistent" with TG.
>
oh rly?

> "userid" is _the_ _right_ name, since it's valid for strings and numbers.
> "user_name" is a wrong name, since it's limited to strings.
>
I'm not talking about the name but you are totally right. you are
loading the "userid" with the "user_name" why?

> And as far as repoze.what is concerned, the user identifier can be anything
> (e.g., a binary value, an ASCII string, an Unicode string, a number), not just
> a name (i.e., an ASCII or Unicode string).
>
This is great, but why is it loaded from username instead of user id?
is this simply for legacy reasons?

> That TG2 seem to prefer artificial keys over natural keys is another subject,
> but I think those models should've been using natural keys since day 1; you
> wouldn't be concerned about this otherwise.
>
Assuming you mean "natural" as "human readable" I have to disagree.
You have a ton of issues with non-sequencial primary keys in any
environment. You almost always need a UUID that is "artificial" to
ensure data integrity and (formerly speed). Even the most "modern"
storage engines support some sort of "artificial" key because history
has proven you need them.

If what you are saying is that the default TG identity model should
drop all the id keys for User,Group and Permission. That will cause a
big set of issues, not because of backwards compatibility but because
it will collide with how databases work. Sure you can get away with
non int primary keys but it is not how a lot of stuff works.

Are you suggesting we go with slug for keys for everything? you can't
make URLs support all types of keys URLs have a very limited charset,
not to mention casesensitive issues and .... well all the problems
slugs have.

Last but not least not everyone gets to work on a cool 2009 project,
and enough people with legacy systems depend on "artificial keys"

> It doesn't make any sense for an authorization software to have two have
> identifiers for the same user.
>
> Nevertheless, repoze.what v2 will support credential loaders (repoze.who MD
> provider-like stuff) for developers who want to load additional credentials to
> use them in their custom predicate checkers -- but of course the built-in
> predicate checkers will only use built-in credentials (this is, is_user will
> continue using repoze.what.userid).
>
>> Also related, what will happen here if the user changes his username?
>
> Nothing interesting, if you wrote your custom predicates correctly (i.e., in a
> future-proof way).
>
please enlighten us with future-proof predicate that depend on the
content of a now variable.

>> sightly related didn't we used to have repoze.what.user (the whole db
>> user instance) stored in the environ?
>
> No, never. The user object is in the repoze.who identity dict.
>
right, but we can't use that because you are getting rid of it for
r.what v2 correct?

>
>> shouldn't we be using that
>> instead of repoze.what.userid for comparations?
>
> That'd be ugly for obvious reasons. In a nutshell: You'd be limiting part of
> your authorization system to a _particular_ setup of your identification
> system.

I'm totally lost here, you are saying to me that my "authorization"
system should only look for one key (the "natural" id). and that I
have no "permission" to query my system for it's group or permission
because I'll be limiting myself to my authentication system? the whole
point of having the userid somewhere is for me to LOOK for what he can
do.

>> @expose('coolpackage.cooltemplate')
>> @require(Any(is_user('admin'), self_user()))
>> def edit(self, username):
>>     if 'admin' == request.identity.get('repoze.who.userid'):
>>         RegistrationController.edit_form = full_user_form
>>     else:
>>         RegistrationController.edit_form = limited_user_form
>>     return {'username': username}
>>
>> which is really odd not to mention will probably cause a big havoc. As
>> swapping that widget on the fly may be an issue.
>
> You're talking about validators? Yeah, that may be a problem in Rest
> controllers.
>
I'm talking about how limited this seems. from both point not looking
who to blame but where to solve this.

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to