[ckan-changes] commit/ckan: thejimmyg: [authz] Created a new plugin architecture for overriding auths in extensions for the logic layer

Bitbucket commits-noreply at bitbucket.org
Tue Jun 21 14:21:07 UTC 2011


1 new changeset in ckan:

http://bitbucket.org/okfn/ckan/changeset/7347d5ef6750/
changeset:   7347d5ef6750
branch:      feature-1094-authz
user:        thejimmyg
date:        2011-06-21 16:20:10
summary:     [authz] Created a new plugin architecture for overriding auths in extensions for the logic layer
affected #:  7 files (3.6 KB)

--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ckan/logic/auth/create.py	Tue Jun 21 15:20:10 2011 +0100
@@ -0,0 +1,3 @@
+def package_create(data_dict, context):
+    raise Exception('asdada')
+    return True


--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ckan/new_authz.py	Tue Jun 21 15:20:10 2011 +0100
@@ -0,0 +1,89 @@
+"""\
+New auth system based around logic layer authorization
+
+Used like this:
+
+::
+
+    from ckan.new_authz import is_authorized
+
+    def logic_layer_function(...):
+        if not is_authorized('package_create', data_dict, context):
+            # Handle here
+            return
+        # Continue as normal
+"""
+from logging import getLogger
+from ckan.plugins import implements, SingletonPlugin
+from ckan.plugins import IAuthFunctions
+
+log = getLogger(__name__)
+
+
+def return_false(data_dict, context):
+    return False
+
+# XXX Bug in the plugin system, the plugin is loaded just becasue it is 
+#     imported, without it being explicitly loaded in setup.py
+#class DefaultAuthFunctions(SingletonPlugin):
+class OverrideAuthFunctions():
+    """
+    Emit a log line when objects are inserted into the database
+    """
+
+    implements(IAuthFunctions, inherit=True)
+
+    def get_auth_functions(self):
+        raise Exception('not being runi at all')
+        return {
+            'package_create': return_false
+        }
+
+from ckan.plugins import PluginImplementations
+
+# This is a private cache used by get_auth_function() and should never
+# be accessed directly
+_fetched_auth_functions = None
+
+def is_authorized(logic_function_name, data_dict, context):
+    auth_function = _get_auth_function(logic_function_name)
+    return auth_function(data_dict, context)
+
+def _get_auth_function(logic_function_name):
+    if _fetched_auth_functions is not None:
+        return _fetched_auth_functions[logic_function_name]
+    # Otherwise look in all the plugins to resolve all possible
+    global _fetched_auth_functions
+    # First get the default ones in the ckan/logic/auth directory
+    default_auth_functions = {}
+    # Rather than writing them out in full will use __import__
+    # to load anything from ckan.auth that looks like it might
+    # be an authorisation function
+    for auth_module_name in ['get', 'create', 'update']:
+        module_path = 'ckan.logic.auth.'+auth_module_name
+        module = __import__(module_path)
+        for part in module_path.split('.')[1:]:
+            module = getattr(module, part)
+        for k, v in module.__dict__.items():
+            if not k.startswith('_'):
+                default_auth_functions[k] = v
+    # Then overwrite them with any specific ones in the plugins:
+    resolved_auth_function_plugins = {}
+    _fetched_auth_functions = {}
+    for plugin in PluginImplementations(IAuthFunctions):
+        for name, auth_function in plugin.get_auth_functions().items():
+            if name in resolved_auth_function_plugins:
+                raise Exception(
+                    'The auth function %r is already implemented in %r' % (
+                        name,
+                        resolved_auth_function_plugins[name]
+                    )
+                )
+            else:
+                log.debug('Auth function %r was inserted', plugin.name)
+                resolved_auth_function_plugins[name] = plugin.name
+                _fetched_auth_functions[name] = auth_function
+    # Use the updated ones in preference to the originals.
+    _fetched_auth_functions.update(default_auth_functions)
+    return _fetched_auth_functions[logic_function_name]
+


--- a/ckan/plugins/interfaces.py	Mon Jun 20 01:01:11 2011 +0100
+++ b/ckan/plugins/interfaces.py	Tue Jun 21 15:20:10 2011 +0100
@@ -8,6 +8,7 @@
     'IGenshiStreamFilter', 'IRoutes',
     'IMapper', 'ISession',
     'IMiddleware',
+    'IAuthFunctions',
     'IDomainObjectModification', 'IGroupController', 
     'IPackageController', 'IPluginObserver',
     'IConfigurable', 'IConfigurer', 'IAuthorizer'
@@ -273,7 +274,7 @@
         :param config: ``pylons.config`` object
         """
 
-
+# Note: This is now deprecated
 class IAuthorizer(Interface):
     """
     Allow customisation of default Authorization implementation
@@ -300,4 +301,13 @@
         other Authorizers to run; True will shortcircuit and return.
         """
         
+class IAuthFunctions(Interface):
+    """
+    Allow customisation of default Authorization implementation
+    """
+    def get_auth_functions(self):
+        """
+        Returns a dict of all the authorization functions which the
+        implementation overrides
+        """
 


--- a/setup.py	Mon Jun 20 01:01:11 2011 +0100
+++ b/setup.py	Tue Jun 21 15:20:10 2011 +0100
@@ -82,6 +82,7 @@
 
     [ckan.system_plugins]
     domain_object_mods = ckan.model.modification:DomainObjectModificationExtension
+    #override_auth_functions = ckan.new_authz:OverrideAuthFunctions
     """,
     # setup.py test command needs a TestSuite so does not work with py.test
     # test_suite = 'nose.collector',

Repository URL: https://bitbucket.org/okfn/ckan/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.




More information about the ckan-changes mailing list