[Zope-Checkins] CVS: Zope3/lib/python/Zope/Security - IChecker.py:1.1.2.10 _Proxy.c:1.1.2.10

Guido van Rossum guido@python.org
Thu, 18 Apr 2002 16:03:13 -0400


Update of /cvs-repository/Zope3/lib/python/Zope/Security
In directory cvs.zope.org:/tmp/cvs-serv32227

Modified Files:
      Tag: SecurityProxy-branch
	IChecker.py _Proxy.c 
Log Message:
Refactor the check_foo(ob) calls into check(ob, "__foo__").

=== Zope3/lib/python/Zope/Security/IChecker.py 1.1.2.9 => 1.1.2.10 ===
     operation return values, via the proxy method.
 
-    There are individual check_* methods for checking individual
-    operations.
+    There are check_getattr() and check_setattr() methods for checking
+    getattr and setattr, and a check() method for all other operations.
 
-    The check_* methods may raise errors.  They return no value.
+    The check methods may raise errors.  They return no value.
 
-           checker.check_getitem(ob)
-           return checker.proxy(ob[key])
+    Example (for __getitem__):
 
-    Note that two different naming conventions are used to separate
-    the individual operation checkers from other methods.
+           checker.check(ob, "__getitem__")
+           return checker.proxy(ob[key])
     """
 
     def check_getattr(ob, name):
@@ -44,56 +43,12 @@
         """Check whether attribute assignment is allowed.
         """
 
-    def check_getitem(ob):
-        """Check whether item access is allowed.
-        """
-
-    def check_setitem(ob):
-        """Check whether item assignment is allowed.
-        """
-
-    def check_call(ob):
-        """Check whether the object can be called.
-        """
-
-    def check_richcompare(ob):
-        """Check whether the object can be rich-compared.
-        """
-
-    def check_iter(ob):
-        """Check whether ob.__iter__ can be called.
-        """
-
-    def check_compare(ob):
-        """Check whether the object can be 3way-compared.
-        """
-
-    def check_hash(ob):
-        """Check whether the object can be hashed.
-        """
-
-    # XXX (More numeric ops should go here)
-
-    def check_nonzero(ob):
-        """Check whether the object can be truth-tested.
-        """
+    def check(ob, operation):
+        """Check whether operation is allowed.
 
-    def check_len(ob):
-        """Check whether the object's length can be taken.
+        The operation name is the Python special method name,
+        e.g. "__getitem__".
         """
-
-    def check_slice(ob):
-        """Check whether the object can be sliced.
-        """
-
-    def check_setslice(ob):
-        """Check whether a slice of the object can be assigned.
-        """
-
-    def check_contains(ob):
-        """Check whether 'x in ob' is allowed
-        """.
-
 
     def proxy(value):
         """Return a security proxy for the value.


=== Zope3/lib/python/Zope/Security/_Proxy.c 1.1.2.9 => 1.1.2.10 ===
 
 static int
-check(PyObject *checker, char *check_method, PyObject *object)
+check(PyObject *checker, char *opname, PyObject *object)
 {
 	PyObject *checked;
 
-	checked = PyObject_CallMethod(checker, check_method, "(O)", object);
+	checked = PyObject_CallMethod(checker, "check", "(Os)",
+				      object, opname);
 	if (checked == NULL)
 		return 0;
 	Py_DECREF(checked);
@@ -43,7 +44,7 @@
 }
 
 static int
-checkName(PyObject *checker, char *check_method,
+checkattr(PyObject *checker, char *check_method,
 	  PyObject *object, PyObject *name)
 {
 	PyObject *checked;
@@ -57,25 +58,17 @@
 }
 
 static PyObject *
-check1(ProxyObject *self, char *check_method, function1 operation)
+check1(ProxyObject *self, char *opname, function1 operation)
 {
 	PyObject *result = NULL;
 	PyObject *object = self->proxy_object;
 	PyObject *checker = self->proxy_checker;
-	PyObject *value;
 
-	/*
-	 * checker.check_method(object)
-	 * value = operation(object)
-	 * return checker.proxy(value)
-	 */
-	if (check(checker, check_method, object)) {
-		value = operation(object);
-		if (value != NULL) {
+	if (check(checker, opname, object)) {
+		result = operation(object);
+		if (result != NULL)
 			result = PyObject_CallMethod(checker, "proxy",
-						     "(O)", value);
-			Py_DECREF(value);
-		}
+						     "(N)", result);
 	}
 	return result;
 }
@@ -124,26 +117,29 @@
 	return err;
 }
 
+
+/* Map rich comparison operators to their __xx__ namesakes */
+static char *name_op[] = {
+	"__lt__",
+	"__le__",
+	"__eq__",
+	"__ne__",
+	"__gt__",
+	"__ge__",
+};
+
 static PyObject *
 proxy_richcompare(PyObject* self, PyObject* other, int op)
 {
 	PyObject *result = NULL;
 	PyObject *object = Proxy_GetObject(self);
 	PyObject *checker = Proxy_GetChecker(self);
-	PyObject *value;
 
-	/*
-	 * checker.check_richcompare(object)
-	 * value = object <op> other
-	 * return checker.proxy(value)
-	 */
-	if (check(checker, "check_richcompare", object)) {
-		value = PyObject_RichCompare(object, other, op);
-		if (value != NULL) {
+	if (check(checker, name_op[op], object)) {
+		result = PyObject_RichCompare(object, other, op);
+		if (result != NULL)
 			result = PyObject_CallMethod(
-				checker, "proxy", "(N)", value);
-			/*Py_DECREF(value);*/
-		}
+				checker, "proxy", "(N)", result);
 	}
 	return result;
 }
@@ -161,20 +157,12 @@
 	PyObject *result = NULL;
 	PyObject *object = Proxy_GetObject(self);
 	PyObject *checker = Proxy_GetChecker(self);
-	PyObject *value;
 
-	/*
-	 * checker.check_getattr(object, name)
-	 * value = getattr(object, name)
-	 * return checker.proxy(value)
-	 */
-	if (checkName(checker, "check_getattr", object, name)) {
-		value = PyObject_GetAttr(object, name);
-		if (value != NULL) {
+	if (checkattr(checker, "check_getattr", object, name)) {
+		result = PyObject_GetAttr(object, name);
+		if (result != NULL)
 			result = PyObject_CallMethod(
-				checker, "proxy", "(O)", value);
-			Py_DECREF(value);
-		}
+				checker, "proxy", "(N)", result);
 	}
 	return result;
 }
@@ -185,11 +173,7 @@
 	PyObject *object = Proxy_GetObject(self);
 	PyObject *checker = Proxy_GetChecker(self);
 
-	/*
-	 * checker.check_setattr(object, name)
-	 * setattr(object, name, value)
-	 */
-	if (checkName(checker, "check_setattr", object, name))
+	if (checkattr(checker, "check_setattr", object, name))
 		return PyObject_SetAttr(object, name, value);
 	return -1;
 }
@@ -197,13 +181,13 @@
 static PyObject *
 proxy_str(PyObject *self)
 {
-	return check1((ProxyObject *)self, "check_str", PyObject_Str);
+	return check1((ProxyObject *)self, "__str__", PyObject_Str);
 }
 
 static PyObject *
 proxy_repr(PyObject *self)
 {
-	return check1((ProxyObject *)self, "check_repr", PyObject_Repr);
+	return check1((ProxyObject *)self, "__repr__", PyObject_Repr);
 }
 
 static int
@@ -226,20 +210,12 @@
 	PyObject *result = NULL;
 	PyObject *object = Proxy_GetObject(self);
 	PyObject *checker = Proxy_GetChecker(self);
-	PyObject *value;
 
-	/*
-	 * checker.check_call(object)
-	 * value = object(*args, **kwds)
-	 * return checker.proxy(value)
-	 */
-	if (check(checker, "check_call", object)) {
-		value = PyObject_Call(object, args, kwds);
-		if (value != NULL) {
+	if (check(checker, "__call__", object)) {
+		result = PyObject_Call(object, args, kwds);
+		if (result != NULL)
 			result = PyObject_CallMethod(
-				checker, "proxy", "(O)", value);
-			Py_DECREF(value);
-		}
+				checker, "proxy", "(N)", result);
 	}
 	return result;
 }
@@ -300,20 +276,12 @@
 	PyObject *result = NULL;
 	PyObject *object = Proxy_GetObject(self);
 	PyObject *checker = Proxy_GetChecker(self);
-	PyObject *value;
 
-	/*
-	 * checker.check_getitem(object, key)
-	 * value = object[key]
-	 * return checker.proxy(value)
-	 */
-	if (check(checker, "check_getitem", object)) {
-		value = PyObject_GetItem(object, key);
-		if (value != NULL) {
+	if (check(checker, "__getitem__", object)) {
+		result = PyObject_GetItem(object, key);
+		if (result != NULL)
 			result = PyObject_CallMethod(
-				checker, "proxy", "(O)", value);
-			Py_DECREF(value);
-		}
+				checker, "proxy", "(N)", result);
 	}
 	return result;
 }
@@ -324,11 +292,7 @@
 	PyObject *object = Proxy_GetObject(self);
 	PyObject *checker = Proxy_GetChecker(self);
 
-	/*
-	 * checker.check_setitem(object, key)
-	 * object[key] = value
-	 */
-	if (check(checker, "check_setitem", object))
+	if (check(checker, "__setitem__", object))
 		return PyObject_SetItem(object, key, value);
 	return -1;
 }