On Apr 20, 2009, at 4:05 AM, Jeff Rush wrote:

Drew Perttula wrote:
Jeff Rush wrote:

I did openid logins as a mixin class that replaces locateChild:

http://bigasterisk.com/darcs/?r=exchangeMeeting;a=headblob;f=/nevowopenid.py

Draw (and Glyph with his suggestion of Mantissa's approach), thanks for the mentions of source I can study to better understand how I might wrap the web
delivery mechanism.


http://files.twisted.it/stiq_at_europython07.pdf

This is a presentation I gave at europython 07 about some of the practices, that
I consider best, in developing with Nevow.

Basically I define a function that touches the database for some reason, then
I append that function to a role (or a set of roles) using a decorator:

@forRoles('admin')
def deleteUser(avatar, email):
    @transact
    def _(email):
        return users.delete(users.c.email==email).execute()
    return _(email)

@forRoles('anonymous', 'user', 'admin')
def findUser(avatar, email):
    @transact
    def _(email):
        return users.select(sq.and_(users.c.email==email,
users.c.enabled==True)).execute().fetchone()
    return _(email)

This is one example of such a thing. The avatar object is exactly what's returned
by cred/guard and it's defined in the following way:

import zope.interface as z

class Avatar(object):
    z.implements(IAvatar)
    def __init__(self, behavior, *args, **kw):
        self.username = None
        self.email = None
        self.role = None
        self.password = None
        self.conf = None
        super(Avatar, self).__init__(*args, **kw)
        self._actions = dict(((f.__name__, f) for f in behavior))

    def __getattr__(self, name):
        try:
            fun = self._actions[name]
        except KeyError:
            raise NoPermission(name)
        return lambda *args, **kwargs: fun(self, *args, **kwargs)


So that it takes a set of methods that it knows and allows you to call them,
if a method is not present you probably don't have enough permissions
(or you made a mistake in writing it).

This is paired with some clever use of patterns:

 <nevow:invisible nevow:render="optional">
             <nevow:invisible nevow:pattern="None">
               Login to upload images.
             </nevow:invisible>

             <nevow:invisible nevow:pattern="default">
               <nevow:invisible nevow:render="form upload" />
             </nevow:invisible>
</nevow:invisible>

The optional (bad name I know) checks for the role of the current avatar, if it's None it means that the user is not logged in, otherwise you can use
a specific role or default for 'all the others':

This is how it's implemented:

def render_optional(self, ctx, data):
    iq = inevow.IQ(ctx)
    try:
        t = iq.onePattern(str(self.avatar.role))
    except stan.NodeNotFound:
        try:
            t = iq.onePattern('default')
        except stan.NodeNotFound:
            t = ''
    return ctx.tag[t]

I'm not sure it's still usable though with newer nevow versions, although
it might still be.

The other part (navigating in the tree) should be solvable by using
another decorator that could look like this:

def requiresRole(role, loginPage=LoginPage):
    def _f(fun):
        def __f(avatar, *args, **kwargs):
            if role not in avatar.roles:
                 return loginPage(avatar)
            return fun(avatar, *args, **kwargs)
       return __f
    return _f

Or something similar (this is not tested).

It's been a while since I last used this code but it's concept is still good.

--
Valentino Volonghi aka Dialtone
Now running MacOS X 10.5
Home Page: http://www.twisted.it
http://www.adroll.com

Attachment: PGP.sig
Description: This is a digitally signed message part

_______________________________________________
Twisted-web mailing list
[email protected]
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-web

Reply via email to