[Zope3-dev] Protecting class methods
Steve Alexander
steve@cat-box.net
Mon, 14 Jul 2003 20:56:45 +0300
> <content class="myclass">
> <require
> permission="zope.ManageContent"
> attributes="new" />
> </content>
>
> and
>
> <class class="myclass">
> <require
> permission="zope.ManageContent"
> attributes="new" />
> </class>
>
> But none of them seemed to take effect. Is there anything I can do to
> assign a permission to this classmethod? Or am I better making an
> instance method that calls it and protecting the instance method?
Both the <class> and <content> directives make security declarations
about the instances of a class, not about a class itself.
There could be a separate directive to make declarations directly for a
class.
Unfortunately, the checker machinery looks up a checker for an object's
class and not for the object itself. So, you can't register a checker
for your class like that.
What you can do is provide a __Security_checker__ attribute for your
class that is a NamesChecker that allows access to 'new'.
You don't want to provide this checker for instances, just for the
class. So, you need to use a descriptor that stores and retrieves a
different value for the class from the value for an object.
Something like this:
__metaclass__ = type
class ClassObjDescriptor:
def __init__(self, name, class_value):
self.name = name
self.class_value = class_value
def __get__(self, inst, cls=None):
if inst is None:
# being called for the class
return self.class_value
try:
return inst.__dict__[self.name]
except KeyError:
raise AttributeError, self.name
def __set__(self, inst, value):
inst.__dict__[self.name] = value
def __delete__(self, inst):
try:
del inst.__dict__[self.name]
except KeyError:
raise AttributeError, self.name
class MyClass:
__Security_checker__ = ClassObjDescriptor('__Security_checker__',
NamesChecker(['new']))
def new(cls):
return whatever
new = classmethod(new)
--
Steve Alexander