[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