comparison pydershell/pydershell.py @ 24:dace90a7f5e3

Added a 'jsexposed' decorator and, for security purposes, required that __jsexposed__ be True on all callables passed into JS-land as well.
author Atul Varma <varmaa@toolness.com>
date Mon, 07 Sep 2009 16:53:41 -0700
parents 35ab0ad3c294
children b7037cd0f375
comparison
equal deleted inserted replaced
23:35ab0ad3c294 24:dace90a7f5e3
192 pass 192 pass
193 js_stack = js_stack['caller'] 193 js_stack = js_stack['caller']
194 lines.insert(0, "Traceback (most recent call last):") 194 lines.insert(0, "Traceback (most recent call last):")
195 return '\n'.join(lines) 195 return '\n'.join(lines)
196 196
197 def jsexposed(name=None, on=None):
198 """
199 Decorator used to expose the decorated function or method to
200 untrusted JS.
201
202 'name' is an optional alternative name for the function.
203
204 'on' is an optional SafeJsObjectWrapper that the function can be
205 automatically attached as a property to.
206 """
207
208 if callable(name):
209 func = name
210 func.__jsexposed__ = True
211 return func
212
213 def make_exposed(func):
214 if name:
215 func.__name__ = name
216 func.__jsexposed__ = True
217 if on:
218 on[func.__name__] = func
219 return func
220 return make_exposed
221
197 class JsExposedObject(object): 222 class JsExposedObject(object):
198 """ 223 """
199 Trivial base/mixin class for any Python classes that choose to 224 Trivial base/mixin class for any Python classes that choose to
200 expose themselves to JS code. 225 expose themselves to JS code.
201 """ 226 """
335 return value 360 return value
336 if isinstance(value, SafeJsObjectWrapper): 361 if isinstance(value, SafeJsObjectWrapper):
337 # It's already wrapped, just unwrap it. 362 # It's already wrapped, just unwrap it.
338 return value.wrapped_jsobject 363 return value.wrapped_jsobject
339 elif callable(value): 364 elif callable(value):
365 if not (hasattr(value, '__jsexposed__') and
366 value.__jsexposed__):
367 raise ValueError("Callable isn't configured for exposure "
368 "to untrusted JS code")
340 return self.__wrap_pycallable(value) 369 return self.__wrap_pycallable(value)
341 elif isinstance(value, JsExposedObject): 370 elif isinstance(value, JsExposedObject):
342 return self.__wrap_pyinstance(value) 371 return self.__wrap_pyinstance(value)
343 else: 372 else:
344 raise TypeError("Can't expose objects of type '' to JS." % 373 raise TypeError("Can't expose objects of type '' to JS." %