controlling method execution

Michele Simionato mis6 at pitt.edu
Thu Nov 20 23:16:13 EST 2003


"mic" <aldo123 at onet.pl> wrote in message news:<bphufr$1iaf$1 at news.atman.pl>...
> Is it possible to control method exectution using similiar mechanism as with
> get/setatrribute special methods for attributes? I'd like to have every (or
> some of ) method of class instance run common code defined outside the class
> without making any explicit references to it.
> To give an example, I'd like to prepare secure environment, in which users
> could execute only methods that can be accessed by them. IMO the most
> universal way to do it would be to run automatically authorisation routine
> before every method execution.
> 
> Regards,
> 
> Michal

setattr/getattr work with methods just as with attributes, provided you
define your setattr/getattr in the right place, i.e. in the metaclass.
Google for "simionato frozen" in c.l.py (first hit) and you will see
an example of how to make methods "safe" under accidental overriding
with this trick. Also, you may want to look at properties. 
For what concern your problem (securing method execution) here I show 
you another metaclass based solution, which is the less intrusive solution 
(i.e. you don't change the original class). 
Of course, the password mechanism I show in this example is ridicolous from
the point of view of security, but you can replace the password
step with any kind of "secure" identification mechanism you want.
Needless to say, security goes to zero if people have access to Python
and they know how to use its dynamical capabilities. Still, the method may
prevent accidental method calls: 

### protecting methods from execution ####

PASSWD="xxx"
class ProtectionError(Exception): pass

def securecall(func,*args):
    know_the_passwd=raw_input("Password required to use this method:")==PASSWD
    if know_the_passwd: return func(*args)
    else: raise ProtectionError("Wrong password given")
    
class Secure(type):
    def __init__(cls,n,b,d):
        for k,v in d.iteritems():
            if hasattr(v,"__doc__") and v.__doc__=='protected':
                setattr(cls,k,lambda self,*args: securecall(v,self,*args))
                
class C(object):
    __metaclass__=Secure
    def f(self,*args):
        "protected"
        print "Doing something if the user know the password"

C().f()

# END

Here you protect your methods by using a docstring containing the word
"protected". It is easy to try variations of this idea.

HTH,

                        Michele




More information about the Python-list mailing list