diff --git a/ckan/lib/navl/dictization_functions.py b/ckan/lib/navl/dictization_functions.py index 4e8fb8031f5..30f10afb3a7 100644 --- a/ckan/lib/navl/dictization_functions.py +++ b/ckan/lib/navl/dictization_functions.py @@ -167,7 +167,7 @@ def convert(converter, key, converted_data, errors, context): return except TypeError, e: ## hack to make sure the type error was caused by the wrong - ## number of arguements given. + ## number of arguments given. if not converter.__name__ in str(e): raise except Invalid, e: @@ -182,7 +182,7 @@ def convert(converter, key, converted_data, errors, context): return except TypeError, e: ## hack to make sure the type error was caused by the wrong - ## number of arguements given. + ## number of arguments given. if not converter.__name__ in str(e): raise diff --git a/ckan/logic/schema.py b/ckan/logic/schema.py index 44693429694..9ec6244c3be 100644 --- a/ckan/logic/schema.py +++ b/ckan/logic/schema.py @@ -19,7 +19,8 @@ tag_name_validator, tag_string_convert, duplicate_extras_key, - ignore_not_admin, + ignore_not_package_admin, + ignore_not_group_admin, no_http, tag_not_uppercase, user_name_validator, @@ -95,7 +96,7 @@ def default_package_schema(): 'notes': [ignore_missing, unicode], 'url': [ignore_missing, unicode],#, URL(add_http=False)], 'version': [ignore_missing, unicode, package_version_validator], - 'state': [ignore_not_admin, ignore_missing], + 'state': [ignore_not_package_admin, ignore_missing], '__extras': [ignore], '__junk': [empty], 'resources': default_resource_schema(), @@ -158,7 +159,7 @@ def default_group_schema(): 'name': [not_empty, unicode, name_validator, group_name_validator], 'title': [ignore_missing, unicode], 'description': [ignore_missing, unicode], - 'state': [ignore], + 'state': [ignore_not_group_admin, ignore_missing], 'created': [ignore], 'extras': default_extras_schema(), '__extras': [ignore], diff --git a/ckan/logic/validators.py b/ckan/logic/validators.py index 9635563167a..08aba5fdf8a 100644 --- a/ckan/logic/validators.py +++ b/ckan/logic/validators.py @@ -213,6 +213,11 @@ def tag_string_convert(key, data, errors, context): tag_name_validator(tag, context) def ignore_not_admin(key, data, errors, context): + # Deprecated in favour of ignore_not_package_admin + return ignore_not_package_admin(key, data, errors, context) + +def ignore_not_package_admin(key, data, errors, context): + '''Ignore if the user is not allowed to administer the package specified.''' model = context['model'] user = context.get('user') @@ -234,6 +239,29 @@ def ignore_not_admin(key, data, errors, context): data.pop(key) +def ignore_not_group_admin(key, data, errors, context): + '''Ignore if the user is not allowed to administer for the group specified.''' + + model = context['model'] + user = context.get('user') + + if user and Authorizer.is_sysadmin(user): + return + + authorized = False + group = context.get('group') + if group: + try: + check_access('group_change_state',context) + authorized = True + except NotAuthorized: + authorized = False + + if (user and group and authorized): + return + + data.pop(key) + def user_name_validator(key, data, errors, context): model = context["model"] session = context["session"] diff --git a/ckan/templates/group/read.html b/ckan/templates/group/read.html index 7bb0f85a378..cc52728e4f5 100644 --- a/ckan/templates/group/read.html +++ b/ckan/templates/group/read.html @@ -23,6 +23,7 @@

Administrators

+

State: ${c.group['state']}

${c.group_description_formatted}
diff --git a/ckan/tests/functional/test_group.py b/ckan/tests/functional/test_group.py index 69679e5227c..d08944c8e1c 100644 --- a/ckan/tests/functional/test_group.py +++ b/ckan/tests/functional/test_group.py @@ -242,6 +242,30 @@ def test_edit_non_existent(self): offset = url_for(controller='group', action='edit', id=name) res = self.app.get(offset, status=404) + def test_delete(self): + group_name = 'deletetest' + CreateTestData.create_groups([{'name': group_name, + 'packages': [self.packagename]}], + admin_user_name='russianfan') + + group = model.Group.by_name(group_name) + offset = url_for(controller='group', action='edit', id=group_name) + res = self.app.get(offset, status=200, extra_environ={'REMOTE_USER': 'russianfan'}) + main_res = self.main_div(res) + assert 'Edit: %s' % group.title in main_res, main_res + assert 'value="active" selected' in main_res, main_res + + # delete + form = res.forms['group-edit'] + form['state'] = 'deleted' + res = form.submit('save', status=302, extra_environ={'REMOTE_USER': 'russianfan'}) + + group = model.Group.by_name(group_name) + assert_equal(group.state, 'deleted') + res = self.app.get(offset, status=302) + res = res.follow() + assert res.request.url.startswith('/user/login'), res.request.url + class TestNew(FunctionalTestCase): groupname = u'david'