[Twisted-web] Finer-Grained Security System for Twisted Web/Nevow?
Valentino Volonghi
dialtone at gmail.com
Mon Apr 20 15:17:31 EDT 2009
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 194 bytes
Desc: This is a digitally signed message part
Url : http://twistedmatrix.com/pipermail/twisted-web/attachments/20090420/bc5ad838/PGP.pgp
More information about the Twisted-web
mailing list