i've been working on a project - a web site - which i figured i would
try a simpler approach for.

it's using the pyjs.org website.py codebase (yay) but it needs a
database for the back-end, and it needs to be editable, online.  so,
that's the reason why i got RichTextEdit up-and-running (if anyone was
wondering).

anyway, there are a couple of components that i needed to work on:

* KirbyBase - it's a "flat file" based database.  sits somewhere
between sqlite, csv files and apparently gadfly (whatever that is)

* jsonrpclib (again).  i can't stand not having proper unit tests for
back-end server code, and in this case because i'm not using *any*
back-end "framework" (it's cgi-based for now) i had to add in
authentication (cookies).  that mean that i had to bludgeon jsonrpclib
into shape to understand cookies.  the version of jsonrpclib i found
online which says "it supports cookies!" er... didn't work.  oops.

the two libraries, if anyone wants them, can be accessed as:

* git clone git://pyjs.org/git/jsonrpclib.git
* git clone git://pyjs.org/git/kirbybase.git


also, in case anyone's actually interested, here's a quick code
snippet of a validation-version of the jsonremote decorator that's in
pyjs.jsonrpc.  you use it instead of @jsonremote(svc) you do
@jsonremote(svc, ["admin", "operator"])

you can see that the roles need to be in the database (users.tbl) as a
comma-separated list, below.  it requires adaptation, obviously, if
you were to use this for some other purpose, but the hard part (for
me) was working out how to tie all the voodoo magic together on the
decorator stuff.

you actually have to "daisy-chain" the functions, believe it or not
(just like the good-old interrrupt vector tables in assembly days....)

l.

class Validate:
    def __init__(self, roles, fn):
        self.roles = roles
        self.fn = fn

    def _validate(self):
        if self.roles == 'all':
            return
        if not svc._cookies.has_key('session'):
            raise Exception("no session key")
        session = svc._cookies['session'].value
        if not session:
            raise Exception("no session key")
        u = getdb().select('users.tbl', {'session': session})
        if not u:
            raise Exception("session key not valid")
        if self.roles == 'loggedin':
            return
        u_roles = u[0].roles.split(",")
        for r in self.roles:
            if r in u_roles:
                return
        raise Exception("permission denied")

    def validate(self, *args, **kwargs):
        self._validate()
        return self.fn(*args, **kwargs)

def jsonremote_check(service, roles):
    def remotify(func):
        v = Validate(roles, func)
        service.add_method(func.__name__, v.validate)
        return v.validate
    return remotify

Reply via email to