On Wed, Mar 11, 2009 at 10:31 AM, Gustavo Narea <[email protected]> wrote:
> Hello,
>
Moving this bit out front as I think it's very important.

> By the way, in your subject you talk about tgext.crud and repoze.what
> integration, but I couldn't find anything in your email which talks about such
> integration. Did you forget to include something?
>
huh? the whole email is about using tgext.crud, all the things you
said "you are doing" all that is tgext.crud doing. Everything except
the custom predicate. All the things "I am doing" are simply to make
both packages speak to each other, which IMO is either

a- a limitation in the way they interact
b- user error and I don't understand one or the other or both.
c- tgext.crud or repoze.what, is assuming the other package should
behave in a way it is wasn't supposed to behave.

I think you are limiting your responses to b without looking into a or c

> On Wednesday March 11, 2009 13:53:48 Jorge Vargas wrote:
>> I sat down today to do a real registration page for codemill and
>> (possibly the start of tgext.registation)
>>
>> here is what I got so far http://paste.turbogears.org/paste/38205
>>
>> which is very disappointing :(
>> 71 LOC and some very cryptic ones.
>
> Definitely. And that predicate has to be made over, I'd suggest you check the
> repoze.what docs.
>
actually I did I wrote that based on
http://static.repoze.org/whatdocs/Manual/Predicates/Writing.html#creating-a-predicate-checker-more-sensitive-to-the-request

> I'd do:
> class self_user(Predicate):
>    message = "Only %(user) can access her own info"
>
>    def evaluate(self, environ, credentials):
>        vars = self.parse_variables(environ)
>        # Assuming you have routes like "/users/:username:/:action:"
>        req_user = vars.named_args.get('username')
>        if req_user != credentials.get('repoze.what.userid'):
>            self.unmet(user=req_user)
>
> Note that in this situation there's no reason to use the database.
>
ok two things
1- why you say "you" this is tgext.crud doing, I'm not supposed to
know its implementation details. The way crud works
http://www.turbogears.org/2.0/docs/main/Extensions/Crud/index.html#crud-operations
I don't get access to the username in the URL, My predicate is simply
trying to figure out if the record being edited is the one for the
current user. (ie: you can edit your own user info but not others,
unless you are admin)

2- routes? why will you have to drop down to routes from TG for auth?

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

Is there a way to declare the controller method somewhere and decorate
it with auth in a second stage?

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

>
>> 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.
>
>> 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)

I know r.what is supposed to be backend independent and not all
backends will have user_id defined but I think we should either
a- rename repoze.what.userid -> repoze.what.username
b- store a not-user friendly value in repoze.what.userid, and provide
an additioan repoze.what.username with the user-friendly name.

Also related, what will happen here if the user changes his username?
I know most webapps assume this will never happen and it's a mistake
as sometimes external pressures demand a change in username,

for example due to a limitation in our interface to one of our
connecting systems
- they demand a certain field to be username_var, where the whole
string needs to be 16 chars max and they have to be unique. We have
been asked by older users to trim down their usernames as some of them
with very long usernames where reduced to 1 letter variables in the
"var" part. not nice if you need 10 of them ;)

sightly related didn't we used to have repoze.what.user (the whole db
user instance) stored in the environ? shouldn't we be using that
instead of repoze.what.userid for comparations?

>
>> 4.2- there was to be a better way to know if the current user is able
>> to edit the current resource
>
> There is, and all that is documented.

it is? I guess you added that in the last flew days. I remember from
our last conversation you said it will be in r.what v2

I don't see it here
http://static.repoze.org/whatdocs/Manual/Predicates/Builtin.html

> That'd be the self_user predicate above,
> in your situation.
>
>
>> 4.3- my code is very very ugly and will probably break in a very easy
>> way. like going to (http://localhost:8080/register/edit)
>
> That's up to your routing settings, it has nothing to do with repoze.what.
>
again why you are talking routes here? this is all "Restul URLs" and
in fact your solution will also break if that predicate is used in a
URL that does not expose the "username" arg, but I guess that need to
be check with a
if var:
     ....
else:
    self.unmet(...)

>
>> 6- I couldn't think of a sane way of doing
>> if user = admin:
>>     edit_form = full_user_form
>> elif user = current:
>>     edit_form = limited_user_form
>> else:
>>     abort(403)
>
> For example,
> """
> @expose('coolpackage.cooltemplate')
> @require(Any(is_user('admin'), self_user()))
> def edit(self, username):
>    if 'admin' == request.identity.get('repoze.who.userid'):
>        c.edit_form = full_user_form
>    else:
>        c.edit_form = limited_user_form
>    return {'username': username}
> """
>
> or,
> """
> @expose('coolpackage.cooltemplate')
> @require(Any(in_group('admins'), self_user()))
> def edit(self, username):
>    if in_group('admins').is_met(request.environ):
>        c.edit_form = full_user_form
>    else:
>        c.edit_form = limited_user_form
>    return {'username': username}
> """
>
again I think you missed the point here. You are assuming this is "my
code" and I'm writing this from scratch all this is done by tgext.crud
I'm just "using it" your first codeblock translated into how crud
wants items should be something like (I haven't tested it)

@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.

PS: remember c is deprecated we should use tmpl_context

> Saludos!
> --
> Gustavo Narea <http://gustavonarea.net/>.
>
> Get rid of unethical constraints! Get freedomware:
> http://www.getgnulinux.org/
>

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