Inline Permission Definitions
-----------------------------

One of the features provided by this package is the definition of
permissions together with the class definition. This is done
through the requires() decorator.

Then it's possible to create a class with inline definitions:

  >>> from canonical.security.protect import requires, requires_advisor

  >>> @requires_advisor
  ... class Stub(object):
  ...     requires("test.GlobalGet", "test.GlobalSet")
  ...     requires("test.Get", "test.Set", ["a", "b"])
  ...
  ...     def method1(self):
  ...         pass
  ...
  ...     @requires("test.CustomGet")
  ...     def method2(self):
  ...         pass


Inspecting the class checker will show that the requested
definitions are in place.

  >>> from zope.security.checker import getCheckerForInstancesOf
  >>> from pprint import pprint
  >>> checker = getCheckerForInstancesOf(Stub)

  >>> pprint(checker.get_permissions)
  {'a': 'test.Get',
   'b': 'test.Get',
   'method1': 'test.GlobalGet',
   'method2': 'test.CustomGet'}

  >>> pprint(checker.set_permissions)
  {'a': 'test.Set', 'b': 'test.Set'}

  >>> checker is Stub.__Security_checker__
  True


The requires decorator can also operate at module level to define
permissions in the module checker.

Let's prepare a real module to show this (it doesn't work well with
doctests since they're exec'd).

  >>> import tempfile
  >>> import sys, os
  >>> temp_dir = tempfile.mkdtemp()
  >>> sys.path.insert(0, temp_dir)
  >>> module_path = os.path.join(temp_dir, "requires_test_module.py")
  >>> module_file = open(module_path, "w")
  >>> module_file.write("""
  ...
  ... from canonical.security.protect import requires
  ...
  ... @requires("Get1")
  ... def func1():
  ...     pass
  ...
  ... @requires("Get2", "Set2")
  ... def func2():
  ...     pass
  ...
  ... """)
  141

  >>> module_file.close()

  >>> import requires_test_module
  >>> checker = getCheckerForInstancesOf(requires_test_module)

  >>> sorted((checker.get_permissions.items()))
  [('func1', 'Get1'), ('func2', 'Get2')]

  >>> pprint(checker.set_permissions)
  {'func2': 'Set2'}


  >>> import shutil
  >>> shutil.rmtree(temp_dir)
  >>> del sys.path[0]
  >>> del sys.modules["requires_test_module"]


vim:ts=4:sw=4:et:ft=doctest
