[Twisted-web] Finer-Grained Security System for Twisted Web/Nevow?

Jeff Rush jeff at taupro.com
Mon Apr 20 06:08:56 EDT 2009


Michal Pasternak wrote:
> 2009/4/19 Jeff Rush <jeff at taupro.com>:
> [...]
>> 2) Alternatively, one could dynamically generate a custom tree of
>>                        pages/resources within the realm object, returning a
>> different tree depending                           upon the
>> identity/permissions of the user.
> 
> I think this is the preferred approach ATM.
> 
>>  This would seem to make it
>>                 complicated to (a) guarantee that all visitors see the exact
>> same URL                                   structure and,
> 
> You can share the same URL mapper between all users of you site.

Hmmm, I'm not aware of a centralized URL mapper in the Twisted framework as
there is in other Python frameworks that use regular expression mappers.
AFAIK, in Twisted, the URL tree is constructed piece by piece using a series
of .putChild('segment', resource) calls (or child_XXX class attributes) which
if you construct a complex tree with lots of conditionals based on the access
rights of the user, can be messy.



>> (b) consume more
>> time/memory with constructing duplicate page/resource trees when thousands of
>> users may be visiting the site, with a mix of permissions.
> 
> You don't have to duplicate page resources; you can create a single
> resource and return it for as many users as you want.

WHile users with identical roles can share resource trees, it seems you'd need
a unique tree for each 'kind' of user.


>> I'm thinking I'll have to write something like decorators for page resources
>> that front-end the locateChild method (for access control over traversal),
>> and perhaps the renderHTTP method (for access control over page delivery) with
>>                         permissions checking logic.
> 
> What is your permission model exactly? What kind of limitations of
> current guard implementation would you like to solve?

It is role-based, where a user can possess a mix of multiple roles, such as
user A is (member, ), user B is (member, instructor), user C is (admin, ).
For that scenario I'd need three resource trees that include/exclude different
things.  I could pre-build trees for all possible combinations of roles, or
build on demand and cache the last N trees keyed by role combination.  Not
very elegant though.

Instead I'm looking for something more like:

  @access('instructor')
  class StudentRosterPage(rend.Page):
     ...

where after traversal ends, a page's renderHTTP() method does:

  if request.user.session.role in self.page_roles:
     ...return content


> I think I like the current approach... Once you learn how to use it
> and how to set it up properly (this is a key phrase here), it will
> take a few things off your head. Even if setting it up is cumbersome,
> the idea of web resource wrapping an avatar object is pretty cool,

It is pretty cool - and that is why I'm asking because Twisted has always
introduced me to new ideas and ways of doing things.  Perhaps there is
significant security leverage already in there I'm not understanding, or maybe
most people using Twisted roll their own web security mechanisms.  The avatar
approach certainly is a perfect fit for guarding SSH, IMAP, POP3 and such
services.  It just seems a bit awkward for fine-grained websites with a mix of
access.


> as
> you don't have to put access control logic into web resource objects
> -- you just enable these and these resources for that level of
> privleges, which in fact gives you fine-grained security model. If you
> look for a tool, that handles setting up such things for you and lets
> you just concentrate on the code, there's Divmod Mantissa;
> unfortunatley, it is not a very well documented piece of software.

I can see both sides of the issue of whether to place your access control
logic into resources or centralize it into the part that builds up your
website (realm/avatar) ie. a .tac file.  Centralization permits tighter
control over customization of use, but makes it harder to write pluggable
subsystems reusable across different applications.

My experiments so far are something along the lines of:

  class SiteSession(guard.SessionWrapper, membership.SessionMixin):

    # mixin adds new access-testing methods for current user

  # construct resource tree
  root = FrontDoor()
  membership.add_ResourcePages(root)
  return appserver.NevowSite(resource=root)



In my case, after many years with other web frameworks like Zope I'm playing
with Twisted to see how hard it is to write such a subsystem for membership
management.  Basically a drop-in for user registration, forgotten-password
emails, generic user profile editing, login/logout panel to place into any
page, and have it as easy to use as adding an entry to a buildout.cfg and a
couple of lines to a .tac to choose your cred checkers and user info
persistence stores, and poof, a membership-based website.  I can see how to
write it but I'd rather learn from others in the Twisted community if it has
already been done.

Besides security, I'm looking for examples of smart ways to build up a complex
website from parts developed and packaged by others, without a lot of messy
wiring logic.

-Jeff



More information about the Twisted-web mailing list