diff --git a/ckan/logic/auth/create.py b/ckan/logic/auth/create.py index e9082fc6b77..a14bb15d381 100644 --- a/ckan/logic/auth/create.py +++ b/ckan/logic/auth/create.py @@ -9,11 +9,17 @@ def package_create(context, data_dict=None): user = context['user'] if new_authz.auth_is_anon_user(context): - check1 = new_authz.check_config_permission('anon_create_dataset') + check1 = all(new_authz.check_config_permission(p) for p in ( + 'anon_create_dataset', + 'create_dataset_if_not_in_organization', + 'create_unowned_dataset', + )) else: - check1 = new_authz.check_config_permission('create_dataset_if_not_in_organization') \ - or new_authz.check_config_permission('create_unowned_dataset') \ - or new_authz.has_user_permission_for_some_org(user, 'create_dataset') + check1 = all(new_authz.check_config_permission(p) for p in ( + 'create_dataset_if_not_in_organization', + 'create_unowned_dataset', + )) or new_authz.has_user_permission_for_some_org( + user, 'create_dataset') if not check1: return {'success': False, 'msg': _('User %s not authorized to create packages') % user} diff --git a/ckan/logic/auth/update.py b/ckan/logic/auth/update.py index 176c333a5ff..ac416bbcb93 100644 --- a/ckan/logic/auth/update.py +++ b/ckan/logic/auth/update.py @@ -23,11 +23,18 @@ def package_update(context, data_dict): ) else: # If dataset is not owned then we can edit if config permissions allow - if not new_authz.auth_is_anon_user(context): - check1 = new_authz.check_config_permission( - 'create_dataset_if_not_in_organization') + if new_authz.auth_is_anon_user(context): + check1 = all(new_authz.check_config_permission(p) for p in ( + 'anon_create_dataset', + 'create_dataset_if_not_in_organization', + 'create_unowned_dataset', + )) else: - check1 = new_authz.check_config_permission('anon_create_dataset') + check1 = all(new_authz.check_config_permission(p) for p in ( + 'create_dataset_if_not_in_organization', + 'create_unowned_dataset', + )) or new_authz.has_user_permission_for_some_org( + user, 'create_dataset') if not check1: return {'success': False, 'msg': _('User %s not authorized to edit package %s') % diff --git a/ckan/new_tests/helpers.py b/ckan/new_tests/helpers.py index e6799fe0ece..3b8f33722a3 100644 --- a/ckan/new_tests/helpers.py +++ b/ckan/new_tests/helpers.py @@ -17,12 +17,14 @@ This module is reserved for these very useful functions. ''' -import pylons.config as config import webtest +from pylons import config +import nose.tools import ckan.config.middleware import ckan.model as model import ckan.logic as logic +import ckan.new_authz as new_authz def reset_db(): @@ -137,3 +139,39 @@ def _get_test_app(): app = ckan.config.middleware.make_app(config['global_conf'], **config) app = webtest.TestApp(app) return app + + +def change_config(key, value): + '''Decorator to temporarily changes Pylons' config to a new value + + This allows you to easily create tests that need specific config values to + be set, making sure it'll be reverted to what it was originally, after your + test is run. + + Usage:: + + @helpers.change_config('ckan.site_title', 'My Test CKAN') + def test_ckan_site_title(self): + assert pylons.config['ckan.site_title'] == 'My Test CKAN' + + :param key: the config key to be changed, e.g. ``'ckan.site_title'`` + :type key: string + + :param value: the new config key's value, e.g. ``'My Test CKAN'`` + :type value: string + ''' + def decorator(func): + def wrapper(*args, **kwargs): + _original_config = config.copy() + config[key] = value + new_authz.clear_auth_functions_cache() + + return_value = func(*args, **kwargs) + + config.clear() + config.update(_original_config) + new_authz.clear_auth_functions_cache() + + return return_value + return nose.tools.make_decorator(func)(wrapper) + return decorator diff --git a/ckan/new_tests/logic/auth/test_create.py b/ckan/new_tests/logic/auth/test_create.py index f5ced243ed0..030ebed5f0c 100644 --- a/ckan/new_tests/logic/auth/test_create.py +++ b/ckan/new_tests/logic/auth/test_create.py @@ -5,10 +5,82 @@ import mock import nose +import ckan.model as core_model import ckan.new_tests.helpers as helpers import ckan.new_tests.factories as factories +import ckan.logic.auth.create as auth_create logic = helpers.logic +assert_equals = nose.tools.assert_equals + + +class TestCreateDatasetAnonymousSettings(object): + def test_anon_cant_create(self): + response = auth_create.package_create({'user': None}, None) + assert_equals(response['success'], False) + + @helpers.change_config('ckan.auth.anon_create_dataset', True) + def test_anon_can_create(self): + response = auth_create.package_create({'user': None}, None) + assert_equals(response['success'], True) + + @helpers.change_config('ckan.auth.anon_create_dataset', True) + @helpers.change_config('ckan.auth.create_dataset_if_not_in_organization', + False) + def test_cdnio_overrides_acd(self): + response = auth_create.package_create({'user': None}, None) + assert_equals(response['success'], False) + + @helpers.change_config('ckan.auth.anon_create_dataset', True) + @helpers.change_config('ckan.auth.create_unowned_dataset', False) + def test_cud_overrides_acd(self): + response = auth_create.package_create({'user': None}, None) + assert_equals(response['success'], False) + + +class TestCreateDatasetLoggedInSettings(object): + def setup(self): + helpers.reset_db() + + def test_no_org_user_can_create(self): + user = factories.User() + response = auth_create.package_create({'user': user['name']}, None) + assert_equals(response['success'], True) + + @helpers.change_config('ckan.auth.anon_create_dataset', True) + @helpers.change_config('ckan.auth.create_dataset_if_not_in_organization', + False) + def test_no_org_user_cant_create_if_cdnio_false(self): + user = factories.User() + response = auth_create.package_create({'user': user['name']}, None) + assert_equals(response['success'], False) + + @helpers.change_config('ckan.auth.anon_create_dataset', True) + @helpers.change_config('ckan.auth.create_unowned_dataset', False) + def test_no_org_user_cant_create_if_cud_false(self): + user = factories.User() + response = auth_create.package_create({'user': user['name']}, None) + assert_equals(response['success'], False) + + def test_same_org_user_can_create(self): + user = factories.User() + org_users = [{'name': user['name'], 'capacity': 'editor'}] + org = factories.Organization(users=org_users) + dataset = {'name': 'same-org-user-can-create', 'owner_org': org['id']} + context = {'user': user['name'], 'model': core_model} + response = auth_create.package_create(context, dataset) + assert_equals(response['success'], True) + + def test_different_org_user_cant_create(self): + user = factories.User() + org_users = [{'name': user['name'], 'capacity': 'editor'}] + org1 = factories.Organization(users=org_users) + org2 = factories.Organization() + dataset = {'name': 'different-org-user-cant-create', + 'owner_org': org2['id']} + context = {'user': user['name'], 'model': core_model} + response = auth_create.package_create(context, dataset) + assert_equals(response['success'], False) class TestCreate(object):