diff --git a/ckanext/fortify/logic/__init__.py b/ckanext/fortify/logic/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ckanext/fortify/logic/auth/__init__.py b/ckanext/fortify/logic/auth/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ckanext/fortify/logic/auth/create.py b/ckanext/fortify/logic/auth/create.py new file mode 100644 index 0000000..ea1e875 --- /dev/null +++ b/ckanext/fortify/logic/auth/create.py @@ -0,0 +1,18 @@ +import ckan.plugins.toolkit as toolkit + +from ckanext.fortify.logic.auth import helpers + + +@toolkit.chained_auth_function +def fortify_group_create(next_auth, context, data_dict): + return helpers.disallow_non_image_uploads(next_auth, context, data_dict) + + +@toolkit.chained_auth_function +def fortify_organization_create(next_auth, context, data_dict): + return helpers.disallow_non_image_uploads(next_auth, context, data_dict) + + +@toolkit.chained_auth_function +def fortify_user_create(next_auth, context, data_dict): + return helpers.disallow_non_image_uploads(next_auth, context, data_dict) diff --git a/ckanext/fortify/logic/auth/helpers.py b/ckanext/fortify/logic/auth/helpers.py new file mode 100644 index 0000000..98313d9 --- /dev/null +++ b/ckanext/fortify/logic/auth/helpers.py @@ -0,0 +1,23 @@ +import logging + +from ckan.common import _, request + +log = logging.getLogger(__name__) +invalid_filetype_response = {'success': False, 'msg': _('Invalid filetype')} + + +def disallow_non_image_uploads(next_auth, context, data_dict): + try: + if request.files: + files_dict = dict(request.files) + image_upload = files_dict.get('image_upload') + if image_upload and image_upload.mimetype and 'image' not in image_upload.mimetype: + log.error('User {0} upload attempt blocked - file: {1}'.format( + context['user'], + image_upload + )) + return invalid_filetype_response + except Exception as e: + log.error(str(e)) + + return next_auth(context, data_dict) diff --git a/ckanext/fortify/logic/auth/update.py b/ckanext/fortify/logic/auth/update.py new file mode 100644 index 0000000..900cab8 --- /dev/null +++ b/ckanext/fortify/logic/auth/update.py @@ -0,0 +1,18 @@ +import ckan.plugins.toolkit as toolkit + +from ckanext.fortify.logic.auth import helpers + + +@toolkit.chained_auth_function +def fortify_group_update(next_auth, context, data_dict): + return helpers.disallow_non_image_uploads(next_auth, context, data_dict) + + +@toolkit.chained_auth_function +def fortify_organization_update(next_auth, context, data_dict): + return helpers.disallow_non_image_uploads(next_auth, context, data_dict) + + +@toolkit.chained_auth_function +def fortify_user_update(next_auth, context, data_dict): + return helpers.disallow_non_image_uploads(next_auth, context, data_dict) diff --git a/ckanext/fortify/plugin.py b/ckanext/fortify/plugin.py index f4e6471..62bd1b3 100644 --- a/ckanext/fortify/plugin.py +++ b/ckanext/fortify/plugin.py @@ -4,6 +4,10 @@ import logging from ckanext.fortify import helpers, validators, blueprint +from ckanext.fortify.logic.auth import ( + create as auth_create, + update as auth_update +) from ckan.lib.uploader import ALLOWED_UPLOAD_TYPES config = toolkit.config @@ -37,6 +41,8 @@ def create(self, entity): if asbool(config.get('ckan.fortify.block_html_resource_uploads', False)): plugins.implements(plugins.IUploader, inherit=True) + plugins.implements(plugins.IAuthFunctions) + # IUploader def get_resource_uploader(self, data_dict): @@ -47,6 +53,20 @@ def get_resource_uploader(self, data_dict): # Returning None will make sure it uses the CKAN default uploader ResourceUpload return None + # IAuthFunctions + + def get_auth_functions(self): + return { + # Create auth function overrides + 'group_create': auth_create.fortify_group_create, + 'organization_create': auth_create.fortify_organization_create, + 'user_create': auth_create.fortify_user_create, + # Update auth function overrides + 'group_update': auth_update.fortify_group_update, + 'organization_update': auth_update.fortify_organization_update, + 'user_update': auth_update.fortify_user_update, + } + if asbool(config.get('ckan.fortify.enable_anti_csrf_tokens', False)) \ or asbool(config.get('ckan.fortify.enable_password_policy', False)) \ or asbool(config.get('ckan.fortify.force_html_resource_downloads', False)):