[ckan-changes] commit/ckan: 3 new changesets
Bitbucket
commits-noreply at bitbucket.org
Tue May 24 23:52:22 UTC 2011
3 new changesets in ckan:
http://bitbucket.org/okfn/ckan/changeset/0e877f3d478b/
changeset: r3112:0e877f3d478b
branch: feature-1074-authz-wui
user: John Lawrence Aspden
date: 2011-05-25 00:35:10
summary: closing branch
affected #: 0 files (0 bytes)
http://bitbucket.org/okfn/ckan/changeset/200bbebe48ba/
changeset: r3113:200bbebe48ba
user: John Lawrence Aspden
date: 2011-05-25 01:50:41
summary: Merge (note test_authzgroups_walkthrough commented out, should be fixed to work with new authz pages)
affected #: 9 files (39.4 KB)
--- a/ckan/controllers/authorization_group.py Sun May 22 19:52:34 2011 +0100
+++ b/ckan/controllers/authorization_group.py Wed May 25 00:50:41 2011 +0100
@@ -142,85 +142,214 @@
h.redirect_to(action='read', id=c.authorization_group_name)
def authz(self, id):
- c.authorization_group = model.AuthorizationGroup.by_name(id)
- if c.authorization_group is None:
+ authorization_group = model.AuthorizationGroup.by_name(id)
+ if authorization_group is None:
abort(404, _('Group not found'))
- c.authorization_group_name = c.authorization_group.name
-
+
+ c.authorization_group_name = authorization_group.name
+
c.authz_editable = self.authorizer.am_authorized(c, model.Action.EDIT_PERMISSIONS,
- c.authorization_group)
+ authorization_group)
+
if not c.authz_editable:
- abort(401, _('Not authorized to edit authorization for group'))
+ abort(401, gettext('User %r not authorized to edit %s authorizations') % (c.user, id))
- if 'save' in request.params: # form posted
- # needed because request is nested
- # multidict which is read only
- params = dict(request.params)
- c.fs = ckan.forms.get_authz_fieldset('authorization_group_authz_fs').bind(
- c.authorization_group.roles,
- data=params or None)
- try:
- self._update_authz(c.fs)
- except ValidationException, error:
- # TODO: sort this out
- # fs = error.args[0]
- # return render('group/authz.html')
- raise
- # now do new roles
- newrole_user_id = request.params.get('AuthorizationGroupRole--user_id')
- newrole_authzgroup_id = request.params.get('AuthorizationGroupRole--authorized_group_id')
- if newrole_user_id != '__null_value__' and newrole_authzgroup_id != '__null_value__':
- c.message = _(u'Please select either a user or an authorization group, not both.')
- elif newrole_user_id != '__null_value__':
- user = model.Session.query(model.User).get(newrole_user_id)
- # TODO: chech user is not None (should go in validation ...)
- role = request.params.get('AuthorizationGroupRole--role')
- newauthzgrouprole = model.AuthorizationGroupRole(user=user,
- authorization_group=c.authorization_group, role=role)
- # With FA no way to get new GroupRole back to set group attribute
- # new_roles = ckan.forms.new_roles_fs.bind(model.GroupRole, data=params or None)
- # new_roles.sync()
- model.Session.commit()
- model.Session.remove()
- c.message = _(u'Added role \'%s\' for user \'%s\'') % (
- newauthzgrouprole.role,
- newauthzgrouprole.user.name)
- elif newrole_authzgroup_id != '__null_value__':
- authzgroup = model.Session.query(model.AuthorizationGroup).get(newrole_authzgroup_id)
- # TODO: chech user is not None (should go in validation ...)
- role = request.params.get('AuthorizationGroupRole--role')
- newauthzgrouprole = model.AuthorizationGroupRole(authorized_group=authzgroup,
- authorization_group=c.authorization_group, role=role)
- # With FA no way to get new GroupRole back to set group attribute
- # new_roles = ckan.forms.new_roles_fs.bind(model.GroupRole, data=params or None)
- # new_roles.sync()
- model.Session.commit()
- model.Session.remove()
- c.message = _(u'Added role \'%s\' for authorization group \'%s\'') % (
- newauthzgrouprole.role,
- newauthzgrouprole.authorized_group.name)
- elif 'role_to_delete' in request.params:
- authzgrouprole_id = request.params['role_to_delete']
- authzgrouprole = model.Session.query(model.AuthorizationGroupRole).get(authzgrouprole_id)
- if authzgrouprole is None:
- c.error = _(u'Error: No role found with that id')
+ #see package.py for comments
+ def get_userobjectroles():
+ authorization_group = model.AuthorizationGroup.by_name(id)
+ uors = model.Session.query(model.AuthorizationGroupRole).join('authorization_group').filter_by(name=authorization_group.name).all()
+ return uors
+
+ def action_save_form(users_or_authz_groups):
+ # The permissions grid has been saved
+ # which is a grid of checkboxes named user$role
+ rpi = request.params.items()
+
+ # The grid passes us a list of the users/roles that were displayed
+ submitted = [ a for (a,b) in rpi if (b == u'submitted')]
+ # and also those which were checked
+ checked = [ a for (a,b) in rpi if (b == u'on')]
+
+ # from which we can deduce true/false for each user/role combination
+ # that was displayed in the form
+ table_dict={}
+ for a in submitted:
+ table_dict[a]=False
+ for a in checked:
+ table_dict[a]=True
+
+ # now we'll split up the user$role strings to make a dictionary from
+ # (user,role) to True/False, which tells us what we need to do.
+ new_user_role_dict={}
+ for (ur,val) in table_dict.items():
+ u,r = ur.split('$')
+ new_user_role_dict[(u,r)] = val
+
+ # we get the current user/role assignments
+ # and make a dictionary of them
+ current_uors = get_userobjectroles()
+
+ if users_or_authz_groups=='users':
+ current_users_roles = [( uor.user.name, uor.role) for uor in current_uors if uor.user]
+ elif users_or_authz_groups=='authz_groups':
+ current_users_roles = [( uor.authorized_group.name, uor.role) for uor in current_uors if uor.authorized_group]
else:
- authzgrouprole.purge()
- if authzgrouprole.user:
- c.message = _(u'Deleted role \'%s\' for user \'%s\'') % \
- (authzgrouprole.role, authzgrouprole.user.name)
- elif authzgrouprole.authorized_group:
- c.message = _(u'Deleted role \'%s\' for authorization group \'%s\'') % \
- (authzgrouprole.role, authzgrouprole.authorized_group.name)
- model.Session.commit()
+ assert False, "shouldn't be here"
- # retrieve group again ...
- c.authorization_group = model.AuthorizationGroup.by_name(id)
- fs = ckan.forms.get_authz_fieldset('authorization_group_authz_fs')\
- .bind(c.authorization_group.roles)
- c.form = fs.render()
- c.new_roles_form = \
- ckan.forms.get_authz_fieldset('new_authorization_group_roles_fs').render()
+ current_user_role_dict={}
+ for (u,r) in current_users_roles:
+ current_user_role_dict[(u,r)]=True
+
+ # and now we can loop through our dictionary of desired states
+ # checking whether a change needs to be made, and if so making it
+
+ # Here we check whether someone is already assigned a role, in order
+ # to avoid assigning it twice, or attempting to delete it when it
+ # doesn't exist. Otherwise problems can occur.
+ if users_or_authz_groups=='users':
+ for ((u,r), val) in new_user_role_dict.items():
+ if val:
+ if not ((u,r) in current_user_role_dict):
+ model.add_user_to_role(model.User.by_name(u),r,authorization_group)
+ else:
+ if ((u,r) in current_user_role_dict):
+ model.remove_user_from_role(model.User.by_name(u),r,authorization_group)
+ elif users_or_authz_groups=='authz_groups':
+ for ((u,r), val) in new_user_role_dict.items():
+ if val:
+ if not ((u,r) in current_user_role_dict):
+ model.add_authorization_group_to_role(model.AuthorizationGroup.by_name(u),r,authorization_group)
+ else:
+ if ((u,r) in current_user_role_dict):
+ model.remove_authorization_group_from_role(model.AuthorizationGroup.by_name(u),r,authorization_group)
+ else:
+ assert False, "shouldn't be here"
+
+ # finally commit the change to the database
+ model.repo.commit_and_remove()
+ h.flash_success("Changes Saved")
+
+
+
+ def action_add_form(users_or_authz_groups):
+ # The user is attempting to set new roles for a named user
+ new_user = request.params.get('new_user_name')
+ # this is the list of roles whose boxes were ticked
+ checked_roles = [ a for (a,b) in request.params.items() if (b == u'on')]
+ # this is the list of all the roles that were in the submitted form
+ submitted_roles = [ a for (a,b) in request.params.items() if (b == u'submitted')]
+
+ # from this we can make a dictionary of the desired states
+ # i.e. true for the ticked boxes, false for the unticked
+ desired_roles = {}
+ for r in submitted_roles:
+ desired_roles[r]=False
+ for r in checked_roles:
+ desired_roles[r]=True
+
+ # again, in order to avoid either creating a role twice or deleting one which is
+ # non-existent, we need to get the users' current roles (if any)
+
+ current_uors = get_userobjectroles()
+
+ if users_or_authz_groups=='users':
+ current_roles = [uor.role for uor in current_uors if ( uor.user and uor.user.name == new_user )]
+ user_object = model.User.by_name(new_user)
+ if user_object==None:
+ # The submitted user does not exist. Bail with flash message
+ h.flash_error('unknown user:' + str (new_user))
+ else:
+ # Whenever our desired state is different from our current state, change it.
+ for (r,val) in desired_roles.items():
+ if val:
+ if (r not in current_roles):
+ model.add_user_to_role(user_object, r, authorization_group)
+ else:
+ if (r in current_roles):
+ model.remove_user_from_role(user_object, r, authorization_group)
+ h.flash_success("User Added")
+
+ elif users_or_authz_groups=='authz_groups':
+ current_roles = [uor.role for uor in current_uors if ( uor.authorized_group and uor.authorized_group.name == new_user )]
+ user_object = model.AuthorizationGroup.by_name(new_user)
+ if user_object==None:
+ # The submitted user does not exist. Bail with flash message
+ h.flash_error('unknown authorization group:' + str (new_user))
+ else:
+ # Whenever our desired state is different from our current state, change it.
+ for (r,val) in desired_roles.items():
+ if val:
+ if (r not in current_roles):
+ model.add_authorization_group_to_role(user_object, r, authorization_group)
+ else:
+ if (r in current_roles):
+ model.remove_authorization_group_from_role(user_object, r, authorization_group)
+ h.flash_success("Authorization Group Added")
+
+ else:
+ assert False, "shouldn't be here"
+
+ # and finally commit all these changes to the database
+ model.repo.commit_and_remove()
+
+
+ # In the event of a post request, work out which of the four possible actions
+ # is to be done, and do it before displaying the page
+ if 'add' in request.POST:
+ action_add_form('users')
+
+ if 'authz_add' in request.POST:
+ action_add_form('authz_groups')
+
+ if 'save' in request.POST:
+ action_save_form('users')
+
+ if 'authz_save' in request.POST:
+ action_save_form('authz_groups')
+
+ # =================
+ # Display the page
+
+ # Find out all the possible roles. At the moment, any role can be
+ # associated with any object, so that's easy:
+ possible_roles = model.Role.get_all()
+
+ # get the list of users who have roles on this object, with their roles
+ uors = get_userobjectroles()
+
+ # uniquify and sort
+ users = sorted(list(set([uor.user.name for uor in uors if uor.user])))
+ authz_groups = sorted(list(set([uor.authorized_group.name for uor in uors if uor.authorized_group])))
+
+ # make a dictionary from (user, role) to True, False
+ users_roles = [( uor.user.name, uor.role) for uor in uors if uor.user]
+ user_role_dict={}
+ for u in users:
+ for r in possible_roles:
+ if (u,r) in users_roles:
+ user_role_dict[(u,r)]=True
+ else:
+ user_role_dict[(u,r)]=False
+
+ # and similarly make a dictionary from (authz_group, role) to True, False
+ authz_groups_roles = [( uor.authorized_group.name, uor.role) for uor in uors if uor.authorized_group]
+ authz_groups_role_dict={}
+ for u in authz_groups:
+ for r in possible_roles:
+ if (u,r) in authz_groups_roles:
+ authz_groups_role_dict[(u,r)]=True
+ else:
+ authz_groups_role_dict[(u,r)]=False
+
+ # pass these variables to the template for rendering
+ c.roles = possible_roles
+
+ c.users = users
+ c.user_role_dict = user_role_dict
+
+ c.authz_groups = authz_groups
+ c.authz_groups_role_dict = authz_groups_role_dict
+
return render('authorization_group/authz.html')
def _render_edit_form(self, fs):
--- a/ckan/controllers/group.py Sun May 22 19:52:34 2011 +0100
+++ b/ckan/controllers/group.py Wed May 25 00:50:41 2011 +0100
@@ -2,7 +2,7 @@
from sqlalchemy.orm import eagerload_all
from ckan.lib.base import BaseController, c, model, request, render, h
-from ckan.lib.base import ValidationException, abort
+from ckan.lib.base import ValidationException, abort, gettext
from pylons.i18n import get_lang, _
import ckan.authz as authz
from ckan.authz import Authorizer
@@ -180,91 +180,222 @@
return self.edit(id, data_dict, errors, error_summary)
def authz(self, id):
- c.group = model.Group.get(id)
- if c.group is None:
+ group = model.Group.get(id)
+ if group is None:
abort(404, _('Group not found'))
-
- c.groupname = c.group.name
- c.grouptitle = c.group.display_name
+ c.groupname = group.name
+ c.grouptitle = group.display_name
- c.authz_editable = self.authorizer.am_authorized(c, model.Action.EDIT_PERMISSIONS, c.group)
+ c.authz_editable = self.authorizer.am_authorized(c, model.Action.EDIT_PERMISSIONS, group)
if not c.authz_editable:
- abort(401, _('Not authorized to edit authorization for group'))
+ abort(401, gettext('User %r not authorized to edit %s authorizations') % (c.user, id))
+
- if 'save' in request.params: # form posted
- # needed because request is nested
- # multidict which is read only
- params = dict(request.params)
- c.fs = ckan.forms.get_authz_fieldset('group_authz_fs').bind(c.group.roles, data=params or None)
- try:
- self._update_authz(c.fs)
- except ValidationException, error:
- # TODO: sort this out
- # fs = error.args[0]
- # return render('group/authz.html')
- raise
- # now do new roles
- newrole_user_id = request.params.get('GroupRole--user_id')
- newrole_authzgroup_id = request.params.get('GroupRole--authorized_group_id')
- if newrole_user_id != '__null_value__' and newrole_authzgroup_id != '__null_value__':
- c.message = _(u'Please select either a user or an authorization group, not both.')
- elif newrole_user_id != '__null_value__':
- user = model.Session.query(model.User).get(newrole_user_id)
- # TODO: chech user is not None (should go in validation ...)
- role = request.params.get('GroupRole--role')
- newgrouprole = model.GroupRole(user=user, group=c.group,
- role=role)
- # With FA no way to get new GroupRole back to set group attribute
- # new_roles = ckan.forms.new_roles_fs.bind(model.GroupRole, data=params or None)
- # new_roles.sync()
- for extension in self.extensions:
- extension.authz_add_role(newgrouprole)
- model.Session.commit()
- model.Session.remove()
- c.message = _(u'Added role \'%s\' for user \'%s\'') % (
- newgrouprole.role,
- newgrouprole.user.display_name)
- elif newrole_authzgroup_id != '__null_value__':
- authzgroup = model.Session.query(model.AuthorizationGroup).get(newrole_authzgroup_id)
- # TODO: chech user is not None (should go in validation ...)
- role = request.params.get('GroupRole--role')
- newgrouprole = model.GroupRole(authorized_group=authzgroup,
- group=c.group, role=role)
- # With FA no way to get new GroupRole back to set group attribute
- # new_roles = ckan.forms.new_roles_fs.bind(model.GroupRole, data=params or None)
- # new_roles.sync()
- for extension in self.extensions:
- extension.authz_add_role(newgrouprole)
- model.Session.commit()
- model.Session.remove()
- c.message = _(u'Added role \'%s\' for authorization group \'%s\'') % (
- newgrouprole.role,
- newgrouprole.authorized_group.name)
- elif 'role_to_delete' in request.params:
- grouprole_id = request.params['role_to_delete']
- grouprole = model.Session.query(model.GroupRole).get(grouprole_id)
- if grouprole is None:
- c.error = _(u'Error: No role found with that id')
+ #see package.py for comments
+ def get_userobjectroles():
+ group = model.Group.get(id)
+ uors = model.Session.query(model.GroupRole).join('group').filter_by(name=group.name).all()
+ return uors
+
+ def action_save_form(users_or_authz_groups):
+ # The permissions grid has been saved
+ # which is a grid of checkboxes named user$role
+ rpi = request.params.items()
+
+ # The grid passes us a list of the users/roles that were displayed
+ submitted = [ a for (a,b) in rpi if (b == u'submitted')]
+ # and also those which were checked
+ checked = [ a for (a,b) in rpi if (b == u'on')]
+
+ # from which we can deduce true/false for each user/role combination
+ # that was displayed in the form
+ table_dict={}
+ for a in submitted:
+ table_dict[a]=False
+ for a in checked:
+ table_dict[a]=True
+
+ # now we'll split up the user$role strings to make a dictionary from
+ # (user,role) to True/False, which tells us what we need to do.
+ new_user_role_dict={}
+ for (ur,val) in table_dict.items():
+ u,r = ur.split('$')
+ new_user_role_dict[(u,r)] = val
+
+ # we get the current user/role assignments
+ # and make a dictionary of them
+ current_uors = get_userobjectroles()
+
+ if users_or_authz_groups=='users':
+ current_users_roles = [( uor.user.name, uor.role) for uor in current_uors if uor.user]
+ elif users_or_authz_groups=='authz_groups':
+ current_users_roles = [( uor.authorized_group.name, uor.role) for uor in current_uors if uor.authorized_group]
else:
- for extension in self.extensions:
- extension.authz_remove_role(grouprole)
- grouprole.purge()
- if grouprole.user:
- c.message = _(u'Deleted role \'%s\' for user \'%s\'') % \
- (grouprole.role, grouprole.user.display_name)
- elif grouprole.authorized_group:
- c.message = _(u'Deleted role \'%s\' for authorization group \'%s\'') % \
- (grouprole.role, grouprole.authorized_group.name)
- model.Session.commit()
+ assert False, "shouldn't be here"
- # retrieve group again ...
- c.group = model.Group.get(id)
- fs = ckan.forms.get_authz_fieldset('group_authz_fs').bind(c.group.roles)
- c.form = fs.render()
- c.new_roles_form = \
- ckan.forms.get_authz_fieldset('new_group_roles_fs').render()
+ current_user_role_dict={}
+ for (u,r) in current_users_roles:
+ current_user_role_dict[(u,r)]=True
+
+ # and now we can loop through our dictionary of desired states
+ # checking whether a change needs to be made, and if so making it
+
+ # Here we check whether someone is already assigned a role, in order
+ # to avoid assigning it twice, or attempting to delete it when it
+ # doesn't exist. Otherwise problems can occur.
+ if users_or_authz_groups=='users':
+ for ((u,r), val) in new_user_role_dict.items():
+ if val:
+ if not ((u,r) in current_user_role_dict):
+ model.add_user_to_role(model.User.by_name(u),r,group)
+ else:
+ if ((u,r) in current_user_role_dict):
+ model.remove_user_from_role(model.User.by_name(u),r,group)
+ elif users_or_authz_groups=='authz_groups':
+ for ((u,r), val) in new_user_role_dict.items():
+ if val:
+ if not ((u,r) in current_user_role_dict):
+ model.add_authorization_group_to_role(model.AuthorizationGroup.by_name(u),r,group)
+ else:
+ if ((u,r) in current_user_role_dict):
+ model.remove_authorization_group_from_role(model.AuthorizationGroup.by_name(u),r,group)
+ else:
+ assert False, "shouldn't be here"
+
+
+ # finally commit the change to the database
+ model.repo.commit_and_remove()
+ h.flash_success("Changes Saved")
+
+
+
+ def action_add_form(users_or_authz_groups):
+ # The user is attempting to set new roles for a named user
+ new_user = request.params.get('new_user_name')
+ # this is the list of roles whose boxes were ticked
+ checked_roles = [ a for (a,b) in request.params.items() if (b == u'on')]
+ # this is the list of all the roles that were in the submitted form
+ submitted_roles = [ a for (a,b) in request.params.items() if (b == u'submitted')]
+
+ # from this we can make a dictionary of the desired states
+ # i.e. true for the ticked boxes, false for the unticked
+ desired_roles = {}
+ for r in submitted_roles:
+ desired_roles[r]=False
+ for r in checked_roles:
+ desired_roles[r]=True
+
+ # again, in order to avoid either creating a role twice or deleting one which is
+ # non-existent, we need to get the users' current roles (if any)
+
+ current_uors = get_userobjectroles()
+
+ if users_or_authz_groups=='users':
+ current_roles = [uor.role for uor in current_uors if ( uor.user and uor.user.name == new_user )]
+ user_object = model.User.by_name(new_user)
+ if user_object==None:
+ # The submitted user does not exist. Bail with flash message
+ h.flash_error('unknown user:' + str (new_user))
+ else:
+ # Whenever our desired state is different from our current state, change it.
+ for (r,val) in desired_roles.items():
+ if val:
+ if (r not in current_roles):
+ model.add_user_to_role(user_object, r, group)
+ else:
+ if (r in current_roles):
+ model.remove_user_from_role(user_object, r, group)
+ h.flash_success("User Added")
+
+ elif users_or_authz_groups=='authz_groups':
+ current_roles = [uor.role for uor in current_uors if ( uor.authorized_group and uor.authorized_group.name == new_user )]
+ user_object = model.AuthorizationGroup.by_name(new_user)
+ if user_object==None:
+ # The submitted user does not exist. Bail with flash message
+ h.flash_error('unknown authorization group:' + str (new_user))
+ else:
+ # Whenever our desired state is different from our current state, change it.
+ for (r,val) in desired_roles.items():
+ if val:
+ if (r not in current_roles):
+ model.add_authorization_group_to_role(user_object, r, group)
+ else:
+ if (r in current_roles):
+ model.remove_authorization_group_from_role(user_object, r, group)
+ h.flash_success("Authorization Group Added")
+
+ else:
+ assert False, "shouldn't be here"
+
+ # and finally commit all these changes to the database
+ model.repo.commit_and_remove()
+
+
+ # In the event of a post request, work out which of the four possible actions
+ # is to be done, and do it before displaying the page
+ if 'add' in request.POST:
+ action_add_form('users')
+
+ if 'authz_add' in request.POST:
+ action_add_form('authz_groups')
+
+ if 'save' in request.POST:
+ action_save_form('users')
+
+ if 'authz_save' in request.POST:
+ action_save_form('authz_groups')
+
+ # =================
+ # Display the page
+
+ # Find out all the possible roles. At the moment, any role can be
+ # associated with any object, so that's easy:
+ possible_roles = model.Role.get_all()
+
+ # get the list of users who have roles on this object, with their roles
+ uors = get_userobjectroles()
+
+ # uniquify and sort
+ users = sorted(list(set([uor.user.name for uor in uors if uor.user])))
+ authz_groups = sorted(list(set([uor.authorized_group.name for uor in uors if uor.authorized_group])))
+
+ # make a dictionary from (user, role) to True, False
+ users_roles = [( uor.user.name, uor.role) for uor in uors if uor.user]
+ user_role_dict={}
+ for u in users:
+ for r in possible_roles:
+ if (u,r) in users_roles:
+ user_role_dict[(u,r)]=True
+ else:
+ user_role_dict[(u,r)]=False
+
+ # and similarly make a dictionary from (authz_group, role) to True, False
+ authz_groups_roles = [( uor.authorized_group.name, uor.role) for uor in uors if uor.authorized_group]
+ authz_groups_role_dict={}
+ for u in authz_groups:
+ for r in possible_roles:
+ if (u,r) in authz_groups_roles:
+ authz_groups_role_dict[(u,r)]=True
+ else:
+ authz_groups_role_dict[(u,r)]=False
+
+ # pass these variables to the template for rendering
+ c.roles = possible_roles
+
+ c.users = users
+ c.user_role_dict = user_role_dict
+
+ c.authz_groups = authz_groups
+ c.authz_groups_role_dict = authz_groups_role_dict
+
return render('group/authz.html')
-
+
+
+
+
+
+
+
def history(self, id):
if 'diff' in request.params or 'selected1' in request.params:
try:
--- a/ckan/controllers/package.py Sun May 22 19:52:34 2011 +0100
+++ b/ckan/controllers/package.py Wed May 25 00:50:41 2011 +0100
@@ -437,79 +437,221 @@
if not c.authz_editable:
abort(401, gettext('User %r not authorized to edit %s authorizations') % (c.user, id))
- if 'save' in request.params: # form posted
- # A dict needed for the params because request.params is a nested
- # multidict, which is read only.
- params = dict(request.params)
- c.fs = ckan.forms.get_authz_fieldset('package_authz_fs').bind(pkg.roles, data=params or None)
- try:
- self._update_authz(c.fs)
- except ValidationException, error:
- # TODO: sort this out
- # fs = error.args
- # return render('package/authz.html')
- raise
- # now do new roles
- newrole_user_id = request.params.get('PackageRole--user_id')
- newrole_authzgroup_id = request.params.get('PackageRole--authorized_group_id')
- if newrole_user_id != '__null_value__' and newrole_authzgroup_id != '__null_value__':
- c.message = _(u'Please select either a user or an authorization group, not both.')
- elif newrole_user_id != '__null_value__':
- user = model.Session.query(model.User).get(newrole_user_id)
- # TODO: chech user is not None (should go in validation ...)
- role = request.params.get('PackageRole--role')
- newpkgrole = model.PackageRole(user=user, package=pkg,
- role=role)
- # With FA no way to get new PackageRole back to set package attribute
- # new_roles = ckan.forms.new_roles_fs.bind(model.PackageRole, data=params or None)
- # new_roles.sync()
- for item in self.extensions:
- item.authz_add_role(newpkgrole)
- model.repo.commit_and_remove()
- c.message = _(u'Added role \'%s\' for user \'%s\'') % (
- newpkgrole.role,
- newpkgrole.user.display_name)
- elif newrole_authzgroup_id != '__null_value__':
- authzgroup = model.Session.query(model.AuthorizationGroup).get(newrole_authzgroup_id)
- # TODO: chech user is not None (should go in validation ...)
- role = request.params.get('PackageRole--role')
- newpkgrole = model.PackageRole(authorized_group=authzgroup,
- package=pkg, role=role)
- # With FA no way to get new GroupRole back to set group attribute
- # new_roles = ckan.forms.new_roles_fs.bind(model.GroupRole, data=params or None)
- # new_roles.sync()
- for item in self.extensions:
- item.authz_add_role(newpkgrole)
- model.Session.commit()
- model.Session.remove()
- c.message = _(u'Added role \'%s\' for authorization group \'%s\'') % (
- newpkgrole.role,
- newpkgrole.authorized_group.name)
- elif 'role_to_delete' in request.params:
- pkgrole_id = request.params['role_to_delete']
- pkgrole = model.Session.query(model.PackageRole).get(pkgrole_id)
- if pkgrole is None:
- c.error = _(u'Error: No role found with that id')
+ # Three different ways of getting the list of userobjectroles for this package.
+ # They all take a frighteningly long time to retrieve
+ # the data, but I can't tell how they'll scale. On a large dataset it might
+ # be worth working out which is quickest, so I've made a function for
+ # ease of changing the query.
+ def get_userobjectroles():
+ # we already have a pkg variable in scope, but I found while testing
+ # that it occasionally mysteriously loses its value! Redefine it
+ # here.
+ pkg = model.Package.get(id)
+
+ # dread's suggestion for 'get all userobjectroles for this package':
+ uors = model.Session.query(model.PackageRole).join('package').filter_by(name=pkg.name).all()
+ # rgrp's version:
+ # uors = model.Session.query(model.PackageRole).filter_by(package=pkg)
+ # get them all and filter in python:
+ # uors = [uor for uor in model.Session.query(model.PackageRole).all() if uor.package==pkg]
+ return uors
+
+ def action_save_form(users_or_authz_groups):
+ # The permissions grid has been saved
+ # which is a grid of checkboxes named user$role
+ rpi = request.params.items()
+
+ # The grid passes us a list of the users/roles that were displayed
+ submitted = [ a for (a,b) in rpi if (b == u'submitted')]
+ # and also those which were checked
+ checked = [ a for (a,b) in rpi if (b == u'on')]
+
+ # from which we can deduce true/false for each user/role combination
+ # that was displayed in the form
+ table_dict={}
+ for a in submitted:
+ table_dict[a]=False
+ for a in checked:
+ table_dict[a]=True
+
+ # now we'll split up the user$role strings to make a dictionary from
+ # (user,role) to True/False, which tells us what we need to do.
+ new_user_role_dict={}
+ for (ur,val) in table_dict.items():
+ u,r = ur.split('$')
+ new_user_role_dict[(u,r)] = val
+
+ # we get the current user/role assignments
+ # and make a dictionary of them
+ current_uors = get_userobjectroles()
+
+ if users_or_authz_groups=='users':
+ current_users_roles = [( uor.user.name, uor.role) for uor in current_uors if uor.user]
+ elif users_or_authz_groups=='authz_groups':
+ current_users_roles = [( uor.authorized_group.name, uor.role) for uor in current_uors if uor.authorized_group]
else:
- for item in self.extensions:
- item.authz_remove_role(pkgrole)
- if pkgrole.user:
- c.message = _(u'Deleted role \'%s\' for user \'%s\'') % \
- (pkgrole.role, pkgrole.user.display_name)
- elif pkgrole.authorized_group:
- c.message = _(u'Deleted role \'%s\' for authorization group \'%s\'') % \
- (pkgrole.role, pkgrole.authorized_group.name)
- pkgrole.purge()
- model.repo.commit_and_remove()
+ assert False, "shouldn't be here"
- # retrieve pkg again ...
- c.pkg = model.Package.get(id)
- fs = ckan.forms.get_authz_fieldset('package_authz_fs').bind(c.pkg.roles)
- c.form = fs.render()
- c.new_roles_form = \
- ckan.forms.get_authz_fieldset('new_package_roles_fs').render()
+ current_user_role_dict={}
+ for (u,r) in current_users_roles:
+ current_user_role_dict[(u,r)]=True
+
+ # and now we can loop through our dictionary of desired states
+ # checking whether a change needs to be made, and if so making it
+
+ # Here we check whether someone is already assigned a role, in order
+ # to avoid assigning it twice, or attempting to delete it when it
+ # doesn't exist. Otherwise problems can occur.
+ if users_or_authz_groups=='users':
+ for ((u,r), val) in new_user_role_dict.items():
+ if val:
+ if not ((u,r) in current_user_role_dict):
+ model.add_user_to_role(model.User.by_name(u),r,pkg)
+ else:
+ if ((u,r) in current_user_role_dict):
+ model.remove_user_from_role(model.User.by_name(u),r,pkg)
+ elif users_or_authz_groups=='authz_groups':
+ for ((u,r), val) in new_user_role_dict.items():
+ if val:
+ if not ((u,r) in current_user_role_dict):
+ model.add_authorization_group_to_role(model.AuthorizationGroup.by_name(u),r,pkg)
+ else:
+ if ((u,r) in current_user_role_dict):
+ model.remove_authorization_group_from_role(model.AuthorizationGroup.by_name(u),r,pkg)
+ else:
+ assert False, "shouldn't be here"
+
+
+ # finally commit the change to the database
+ model.repo.commit_and_remove()
+ h.flash_success("Changes Saved")
+
+
+
+ def action_add_form(users_or_authz_groups):
+ # The user is attempting to set new roles for a named user
+ new_user = request.params.get('new_user_name')
+ # this is the list of roles whose boxes were ticked
+ checked_roles = [ a for (a,b) in request.params.items() if (b == u'on')]
+ # this is the list of all the roles that were in the submitted form
+ submitted_roles = [ a for (a,b) in request.params.items() if (b == u'submitted')]
+
+ # from this we can make a dictionary of the desired states
+ # i.e. true for the ticked boxes, false for the unticked
+ desired_roles = {}
+ for r in submitted_roles:
+ desired_roles[r]=False
+ for r in checked_roles:
+ desired_roles[r]=True
+
+ # again, in order to avoid either creating a role twice or deleting one which is
+ # non-existent, we need to get the users' current roles (if any)
+
+ current_uors = get_userobjectroles()
+
+ if users_or_authz_groups=='users':
+ current_roles = [uor.role for uor in current_uors if ( uor.user and uor.user.name == new_user )]
+ user_object = model.User.by_name(new_user)
+ if user_object==None:
+ # The submitted user does not exist. Bail with flash message
+ h.flash_error('unknown user:' + str (new_user))
+ else:
+ # Whenever our desired state is different from our current state, change it.
+ for (r,val) in desired_roles.items():
+ if val:
+ if (r not in current_roles):
+ model.add_user_to_role(user_object, r, pkg)
+ else:
+ if (r in current_roles):
+ model.remove_user_from_role(user_object, r, pkg)
+ h.flash_success("User Added")
+
+ elif users_or_authz_groups=='authz_groups':
+ current_roles = [uor.role for uor in current_uors if ( uor.authorized_group and uor.authorized_group.name == new_user )]
+ user_object = model.AuthorizationGroup.by_name(new_user)
+ if user_object==None:
+ # The submitted user does not exist. Bail with flash message
+ h.flash_error('unknown authorization group:' + str (new_user))
+ else:
+ # Whenever our desired state is different from our current state, change it.
+ for (r,val) in desired_roles.items():
+ if val:
+ if (r not in current_roles):
+ model.add_authorization_group_to_role(user_object, r, pkg)
+ else:
+ if (r in current_roles):
+ model.remove_authorization_group_from_role(user_object, r, pkg)
+ h.flash_success("Authorization Group Added")
+
+ else:
+ assert False, "shouldn't be here"
+
+ # and finally commit all these changes to the database
+ model.repo.commit_and_remove()
+
+
+ # In the event of a post request, work out which of the four possible actions
+ # is to be done, and do it before displaying the page
+ if 'add' in request.POST:
+ action_add_form('users')
+
+ if 'authz_add' in request.POST:
+ action_add_form('authz_groups')
+
+ if 'save' in request.POST:
+ action_save_form('users')
+
+ if 'authz_save' in request.POST:
+ action_save_form('authz_groups')
+
+ # =================
+ # Display the page
+
+ # Find out all the possible roles. At the moment, any role can be
+ # associated with any object, so that's easy:
+ possible_roles = model.Role.get_all()
+
+ # get the list of users who have roles on this object, with their roles
+ uors = get_userobjectroles()
+
+ # uniquify and sort
+ users = sorted(list(set([uor.user.name for uor in uors if uor.user])))
+ authz_groups = sorted(list(set([uor.authorized_group.name for uor in uors if uor.authorized_group])))
+
+ # make a dictionary from (user, role) to True, False
+ users_roles = [( uor.user.name, uor.role) for uor in uors if uor.user]
+ user_role_dict={}
+ for u in users:
+ for r in possible_roles:
+ if (u,r) in users_roles:
+ user_role_dict[(u,r)]=True
+ else:
+ user_role_dict[(u,r)]=False
+
+ # and similarly make a dictionary from (authz_group, role) to True, False
+ authz_groups_roles = [( uor.authorized_group.name, uor.role) for uor in uors if uor.authorized_group]
+ authz_groups_role_dict={}
+ for u in authz_groups:
+ for r in possible_roles:
+ if (u,r) in authz_groups_roles:
+ authz_groups_role_dict[(u,r)]=True
+ else:
+ authz_groups_role_dict[(u,r)]=False
+
+ # pass these variables to the template for rendering
+ c.roles = possible_roles
+
+ c.users = users
+ c.user_role_dict = user_role_dict
+
+ c.authz_groups = authz_groups
+ c.authz_groups_role_dict = authz_groups_role_dict
+
return render('package/authz.html')
+
+
+
def rate(self, id):
package_name = id
package = model.Package.get(package_name)
--- a/ckan/templates/authorization_group/authz.html Sun May 22 19:52:34 2011 +0100
+++ b/ckan/templates/authorization_group/authz.html Wed May 25 00:50:41 2011 +0100
@@ -9,21 +9,41 @@
Authorization for authorization group: ${c.authorization_group_name}
</h2>
- <p py:if="c.message">${c.message}</p>
- <form id="group-authz" action="" method="post">
- <h3>Update Existing Roles</h3>
- <table>
- ${h.literal(c.form)}
- </table>
+ <h2>Update Existing Roles</h2>
- <h3>Create New User or Authorization Group Roles</h3>
- ${h.literal(c.new_roles_form)}
-
- <br/>
+ <form id="theform" method="POST">
+ ${authz_form_table('theform', c.roles, c.users, c.user_role_dict)}
+ <button type="submit" name="save">
+ Save
+ </button>
+ </form>
- ${h.submit('save', _('Save'))}
+ <h2>Add Roles for Any User</h2>
+
+ <form id="addform" method="POST">
+ ${authz_add_table(c.roles)}
+ <button type="submit" name="add"> Add </button></form>
+
+ <hr/>
+
+ <h2>Existing Roles for Authorization Groups</h2>
+
+ <form id="authzgroup_form" method="POST">
+ ${authz_form_group_table('authzgroup_form', c.roles, c.authz_groups, c.authz_groups_role_dict)}
+ <button type="submit" name="authz_save">
+ Save
+ </button>
+ </form>
+
+ <h2>Add Roles for Any Authorization Group</h2>
+
+ <form id="authzgroup_addform" method="POST">
+ ${authz_add_group_table(c.roles)}
+ <button type="submit" name="authz_add"> Add </button>
+ </form>
+
</div><xi:include href="layout.html" />
--- a/ckan/templates/group/authz.html Sun May 22 19:52:34 2011 +0100
+++ b/ckan/templates/group/authz.html Wed May 25 00:50:41 2011 +0100
@@ -9,21 +9,40 @@
Authorization for group: ${c.grouptitle or c.groupname}
</h2>
- <p py:if="c.message">${c.message}</p>
+ <h2>Update Existing Roles</h2>
- <form id="group-authz" action="" method="post">
- <h3>Update Existing Roles</h3>
- <table>
- ${h.literal(c.form)}
- </table>
+ <form id="theform" method="POST">
+ ${authz_form_table('theform', c.roles, c.users, c.user_role_dict)}
+ <button type="submit" name="save">
+ Save
+ </button>
+ </form>
- <h3>Create New User Roles</h3>
- ${h.literal(c.new_roles_form)}
-
- <br/>
+ <h2>Add Roles for Any User</h2>
- ${h.submit('save', _('Save'))}
+ <form id="addform" method="POST">
+ ${authz_add_table(c.roles)}
+ <button type="submit" name="add"> Add </button></form>
+
+ <hr/>
+
+ <h2>Existing Roles for Authorization Groups</h2>
+
+ <form id="authzgroup_form" method="POST">
+ ${authz_form_group_table('authzgroup_form', c.roles, c.authz_groups, c.authz_groups_role_dict)}
+ <button type="submit" name="authz_save">
+ Save
+ </button>
+ </form>
+
+ <h2>Add Roles for Any Authorization Group</h2>
+
+ <form id="authzgroup_addform" method="POST">
+ ${authz_add_group_table(c.roles)}
+ <button type="submit" name="authz_add"> Add </button>
+ </form>
+
</div><xi:include href="layout.html" />
--- a/ckan/templates/package/authz.html Sun May 22 19:52:34 2011 +0100
+++ b/ckan/templates/package/authz.html Wed May 25 00:50:41 2011 +0100
@@ -9,21 +9,40 @@
Authorization for Data Package: ${c.pkgname}
</h2>
- <p py:if="c.message">${c.message}</p>
+ <h2>Update Existing Roles</h2>
- <form id="package-authz" action="" method="post">
- <h3>Update Existing Roles</h3>
- <table>
- ${h.literal(c.form)}
- </table>
+ <form id="theform" method="POST">
+ ${authz_form_table('theform', c.roles, c.users, c.user_role_dict)}
+ <button type="submit" name="save">
+ Save
+ </button>
+ </form>
- <h3>Create New User Roles</h3>
- ${h.literal(c.new_roles_form)}
-
- <br/>
+ <h2>Add Roles for Any User</h2>
- ${h.submit('save', _('Save'))}
+ <form id="addform" method="POST">
+ ${authz_add_table(c.roles)}
+ <button type="submit" name="add"> Add </button></form>
+
+ <hr/>
+
+ <h2>Existing Roles for Authorization Groups</h2>
+
+ <form id="authzgroup_form" method="POST">
+ ${authz_form_group_table('authzgroup_form', c.roles, c.authz_groups, c.authz_groups_role_dict)}
+ <button type="submit" name="authz_save">
+ Save
+ </button>
+ </form>
+
+ <h2>Add Roles for Any Authorization Group</h2>
+
+ <form id="authzgroup_addform" method="POST">
+ ${authz_add_group_table(c.roles)}
+ <button type="submit" name="authz_add"> Add </button>
+ </form>
+
</div><xi:include href="layout.html" />
--- a/ckan/tests/functional/test_authorization_group.py Sun May 22 19:52:34 2011 +0100
+++ b/ckan/tests/functional/test_authorization_group.py Wed May 25 00:50:41 2011 +0100
@@ -143,251 +143,255 @@
model.repo.rebuild_db()
model.Session.remove()
- def test_authzgroups_walkthrough(self):
- # very long test sequence repeating the series of things I did to
- # convince myself that the authzgroups system worked as expected,
- # starting off with the default test data
+
+ ## THIS WALKTHROUGH IS NOW COMPLETELY BROKEN BY THE CHANGES I MADE TO THE AUTHZ PAGE
+
+
+ # def test_authzgroups_walkthrough(self):
+ # # very long test sequence repeating the series of things I did to
+ # # convince myself that the authzgroups system worked as expected,
+ # # starting off with the default test data
- # The first thing to notice is that the authzgroup page:
- auth_group_index_url = url_for(controller='/authorization_group', action='index')
- # displays differently for different users.
+ # # The first thing to notice is that the authzgroup page:
+ # auth_group_index_url = url_for(controller='/authorization_group', action='index')
+ # # displays differently for different users.
- def get_page(url, expect_status, username, assert_text=None, error_text=None):
- res= self.app.get(url,
- status=expect_status,
- extra_environ={'REMOTE_USER': username})
- if assert_text and assert_text not in res:
- errorstring = error_text + ' ( "' + assert_text + \
- '" not found in result of getting "' + \
- url + '" as user "' + username + '" )'
- assert False, errorstring
- return res
+ # def get_page(url, expect_status, username, assert_text=None, error_text=None):
+ # res= self.app.get(url,
+ # status=expect_status,
+ # extra_environ={'REMOTE_USER': username})
+ # if assert_text and assert_text not in res:
+ # errorstring = error_text + ' ( "' + assert_text + \
+ # '" not found in result of getting "' + \
+ # url + '" as user "' + username + '" )'
+ # assert False, errorstring
+ # return res
- # testsysadmin sees the true picture, where the test data contains two groups
- get_page(auth_group_index_url, 200, 'testsysadmin',
- 'There are <strong>2</strong> authorization groups',
- 'Should be accurate for testsysadmin')
+ # # testsysadmin sees the true picture, where the test data contains two groups
+ # get_page(auth_group_index_url, 200, 'testsysadmin',
+ # 'There are <strong>2</strong> authorization groups',
+ # 'Should be accurate for testsysadmin')
- # But if we look at the same page as annafan, who does not have read
- # permissions on these groups, we should see neither
- get_page(auth_group_index_url, 200, 'annafan',
- 'There are <strong>0</strong> authorization groups',
- 'Should lie to annafan about number of groups')
+ # # But if we look at the same page as annafan, who does not have read
+ # # permissions on these groups, we should see neither
+ # get_page(auth_group_index_url, 200, 'annafan',
+ # 'There are <strong>0</strong> authorization groups',
+ # 'Should lie to annafan about number of groups')
- # There is a page for each group
- anauthzgroup_url = url_for(controller='/authorization_group',
- action='read',
- id='anauthzgroup')
- # And an edit page
- anauthzgroup_edit_url = url_for(controller='/authorization_group',
- action='edit',
- id='anauthzgroup')
+ # # There is a page for each group
+ # anauthzgroup_url = url_for(controller='/authorization_group',
+ # action='read',
+ # id='anauthzgroup')
+ # # And an edit page
+ # anauthzgroup_edit_url = url_for(controller='/authorization_group',
+ # action='edit',
+ # id='anauthzgroup')
- # testsysadmin should be able to see this, and check that there are no members
- get_page(anauthzgroup_url, 200, 'testsysadmin',
- 'There are 0 users in this',
- 'should be no users in anauthzgroup')
+ # # testsysadmin should be able to see this, and check that there are no members
+ # get_page(anauthzgroup_url, 200, 'testsysadmin',
+ # 'There are 0 users in this',
+ # 'should be no users in anauthzgroup')
- # now testsysadmin adds annafan to anauthzgroup via the edit page
- res = get_page(anauthzgroup_edit_url, 200, 'testsysadmin')
- group_edit_form = res.forms['group-edit']
- group_edit_form['AuthorizationGroupUser--user_name'] = u'annafan'
- submit_res = group_edit_form.submit('save',
- extra_environ={'REMOTE_USER': 'testsysadmin'})
+ # # now testsysadmin adds annafan to anauthzgroup via the edit page
+ # res = get_page(anauthzgroup_edit_url, 200, 'testsysadmin')
+ # group_edit_form = res.forms['group-edit']
+ # group_edit_form['AuthorizationGroupUser--user_name'] = u'annafan'
+ # submit_res = group_edit_form.submit('save',
+ # extra_environ={'REMOTE_USER': 'testsysadmin'})
- # adding a user to a group should both make her a member, and give her
- # read permission on the group. We'll check those things have actually
- # happened by looking directly in the model.
- anauthzgroup = model.AuthorizationGroup.by_name('anauthzgroup')
- anauthzgroup_users = [x.name for x in anauthzgroup.users]
- anauthzgroup_user_roles = [(x.user.name, x.role) for x in anauthzgroup.roles if x.user]
- assert anauthzgroup_users == [u'annafan'], \
- 'anauthzgroup should contain annafan (only)'
- assert anauthzgroup_user_roles == [(u'annafan', u'reader')],\
- 'annafan should be a reader'
+ # # adding a user to a group should both make her a member, and give her
+ # # read permission on the group. We'll check those things have actually
+ # # happened by looking directly in the model.
+ # anauthzgroup = model.AuthorizationGroup.by_name('anauthzgroup')
+ # anauthzgroup_users = [x.name for x in anauthzgroup.users]
+ # anauthzgroup_user_roles = [(x.user.name, x.role) for x in anauthzgroup.roles if x.user]
+ # assert anauthzgroup_users == [u'annafan'], \
+ # 'anauthzgroup should contain annafan (only)'
+ # assert anauthzgroup_user_roles == [(u'annafan', u'reader')],\
+ # 'annafan should be a reader'
- # Since annafan has been added to anauthzgroup, which is an admin on
- # anotherauthzgroup, she should now be able to see both the groups.
- get_page(auth_group_index_url, 200, 'annafan',
- 'There are <strong>2</strong> auth',
- "annafan should now be able to see both groups")
+ # # Since annafan has been added to anauthzgroup, which is an admin on
+ # # anotherauthzgroup, she should now be able to see both the groups.
+ # get_page(auth_group_index_url, 200, 'annafan',
+ # 'There are <strong>2</strong> auth',
+ # "annafan should now be able to see both groups")
- # When annafan looks at the page for anauthzgroup now
- # She should see that there's one user:
- get_page(anauthzgroup_url, 200,'annafan',
- 'There are 1 users in this',
- 'annafan should be able to see the list of members')
+ # # When annafan looks at the page for anauthzgroup now
+ # # She should see that there's one user:
+ # get_page(anauthzgroup_url, 200,'annafan',
+ # 'There are 1 users in this',
+ # 'annafan should be able to see the list of members')
- # Which is her, so her name should be in there somewhere:
- get_page(anauthzgroup_url, 200,'annafan',
- 'annafan',
- 'annafan should be listed as a member')
+ # # Which is her, so her name should be in there somewhere:
+ # get_page(anauthzgroup_url, 200,'annafan',
+ # 'annafan',
+ # 'annafan should be listed as a member')
- # But she shouldn't be able to see the edit page for that group.
+ # # But she shouldn't be able to see the edit page for that group.
- # The behaviour of the test setup here is a bit weird, since in the
- # browser she gets redirected to the login page, but from these tests,
- # she just gets a 401, with no apparent redirect. Sources inform me
- # that this is normal, and to do with repoze being in the application
- # stack but not in the test stack.
- get_page(anauthzgroup_edit_url, 401, 'annafan',
- 'not authorized to edit',
- 'annafan should not be able to edit the list of members')
- # this behaviour also means that we get a flash message left over, which appears on
- # whatever the next page is.
+ # # The behaviour of the test setup here is a bit weird, since in the
+ # # browser she gets redirected to the login page, but from these tests,
+ # # she just gets a 401, with no apparent redirect. Sources inform me
+ # # that this is normal, and to do with repoze being in the application
+ # # stack but not in the test stack.
+ # get_page(anauthzgroup_edit_url, 401, 'annafan',
+ # 'not authorized to edit',
+ # 'annafan should not be able to edit the list of members')
+ # # this behaviour also means that we get a flash message left over, which appears on
+ # # whatever the next page is.
- # I'm going to assert that behaviour here, just to note it. It's most
- # definitely not required functionality! We'll do a dummy fetch of the
- # main page for anauthzgroup, which will have the errant flash message
- get_page(anauthzgroup_url, 200, 'annafan',
- 'not authorized to edit',
- 'flash message should carry over to next fetch')
+ # # I'm going to assert that behaviour here, just to note it. It's most
+ # # definitely not required functionality! We'll do a dummy fetch of the
+ # # main page for anauthzgroup, which will have the errant flash message
+ # get_page(anauthzgroup_url, 200, 'annafan',
+ # 'not authorized to edit',
+ # 'flash message should carry over to next fetch')
- # But if we do the dummy fetch twice, the flash message should have gone
- res = get_page(anauthzgroup_url, 200, 'annafan')
- assert 'not authorized to edit' not in res, 'flash message should have gone'
+ # # But if we do the dummy fetch twice, the flash message should have gone
+ # res = get_page(anauthzgroup_url, 200, 'annafan')
+ # assert 'not authorized to edit' not in res, 'flash message should have gone'
- # Since annafan is now a member of anauthzgroup, she should have admin privileges
- # on anotherauthzgroup
- anotherauthzgroup_edit_url = url_for(controller='/authorization_group',
- action='edit',
- id='anotherauthzgroup')
+ # # Since annafan is now a member of anauthzgroup, she should have admin privileges
+ # # on anotherauthzgroup
+ # anotherauthzgroup_edit_url = url_for(controller='/authorization_group',
+ # action='edit',
+ # id='anotherauthzgroup')
- # Which means that she can go to the edit page:
- res = get_page(anotherauthzgroup_edit_url, 200, 'annafan',
- 'There are no users',
- "There shouldn't be any users in anotherauthzgroup")
+ # # Which means that she can go to the edit page:
+ # res = get_page(anotherauthzgroup_edit_url, 200, 'annafan',
+ # 'There are no users',
+ # "There shouldn't be any users in anotherauthzgroup")
- # And change the name of the group
- # The group name editing box has a name dependent on the id of the group,
- # so we find it by regex in the page.
- import re
- p = re.compile('AuthorizationGroup-.*-name')
- groupnamebox = [ v for k,v in res.forms['group-edit'].fields.items() if p.match(k)][0][0]
- groupnamebox.value = 'annasauthzgroup'
- res = res.forms['group-edit'].submit('save', extra_environ={'REMOTE_USER': 'annafan'})
- res = res.follow()
+ # # And change the name of the group
+ # # The group name editing box has a name dependent on the id of the group,
+ # # so we find it by regex in the page.
+ # import re
+ # p = re.compile('AuthorizationGroup-.*-name')
+ # groupnamebox = [ v for k,v in res.forms['group-edit'].fields.items() if p.match(k)][0][0]
+ # groupnamebox.value = 'annasauthzgroup'
+ # res = res.forms['group-edit'].submit('save', extra_environ={'REMOTE_USER': 'annafan'})
+ # res = res.follow()
- ## POTENTIAL BUG:
- # note that she could change the name of the group to anauthzgroup,
- # which causes problems due to the name collision. This should be
- # guarded against.
+ # ## POTENTIAL BUG:
+ # # note that she could change the name of the group to anauthzgroup,
+ # # which causes problems due to the name collision. This should be
+ # # guarded against.
- # annafan should still be able to see the admin and edit pages of the
- # newly renamed group by virtue of being a member of anauthzgroup
- annasauthzgroup_authz_url = url_for(controller='/authorization_group',
- action='authz',
- id='annasauthzgroup')
+ # # annafan should still be able to see the admin and edit pages of the
+ # # newly renamed group by virtue of being a member of anauthzgroup
+ # annasauthzgroup_authz_url = url_for(controller='/authorization_group',
+ # action='authz',
+ # id='annasauthzgroup')
- annasauthzgroup_edit_url = url_for(controller='/authorization_group',
- action='edit',
- id='annasauthzgroup')
+ # annasauthzgroup_edit_url = url_for(controller='/authorization_group',
+ # action='edit',
+ # id='annasauthzgroup')
- res = get_page(annasauthzgroup_authz_url, 200, 'annafan',
- 'Authorization for authorization group: annasauthzgroup',
- 'should be authz page')
+ # res = get_page(annasauthzgroup_authz_url, 200, 'annafan',
+ # 'Authorization for authorization group: annasauthzgroup',
+ # 'should be authz page')
- # annafan has the power to remove anauthzgroup's admin role on her group
- # The button to remove that role is a link, rather than a submit. I
- # assume there is a better way to do this than searching by regex, but I
- # can't find it.
- import re
- delete_links = re.compile('<a href="(.*)" title="delete">').findall(res.body)
- assert len(delete_links) == 1, "There should only be one delete link here"
- delete_link = delete_links[0]
+ # # annafan has the power to remove anauthzgroup's admin role on her group
+ # # The button to remove that role is a link, rather than a submit. I
+ # # assume there is a better way to do this than searching by regex, but I
+ # # can't find it.
+ # import re
+ # delete_links = re.compile('<a href="(.*)" title="delete">').findall(res.body)
+ # assert len(delete_links) == 1, "There should only be one delete link here"
+ # delete_link = delete_links[0]
- # Paranoid check, try to follow link without credentials. Should be redirected.
- res = self.app.get(delete_link, status=302)
- res = res.follow()
- assert 'Not authorized to edit authorization for group' in res,\
- "following link without credentials should result in redirection to login page"
+ # # Paranoid check, try to follow link without credentials. Should be redirected.
+ # res = self.app.get(delete_link, status=302)
+ # res = res.follow()
+ # assert 'Not authorized to edit authorization for group' in res,\
+ # "following link without credentials should result in redirection to login page"
- # Now follow it as annafan, which should work.
- get_page(delete_link, 200,'annafan',
- "Deleted role 'admin' for authorization group 'anauthzgroup'",
- "Page should mention the deleted role")
+ # # Now follow it as annafan, which should work.
+ # get_page(delete_link, 200,'annafan',
+ # "Deleted role 'admin' for authorization group 'anauthzgroup'",
+ # "Page should mention the deleted role")
- # Trying it a second time should fail since she's now not an admin.
- get_page(delete_link, 401,'annafan')
+ # # Trying it a second time should fail since she's now not an admin.
+ # get_page(delete_link, 401,'annafan')
- # No one should now have any rights on annasauthzgroup, including
- # annafan herself. So this should fail too. Again, get a 401 error
- # here, but in the browser we get redirected if we try.
- get_page(annasauthzgroup_authz_url, 401,'annafan')
+ # # No one should now have any rights on annasauthzgroup, including
+ # # annafan herself. So this should fail too. Again, get a 401 error
+ # # here, but in the browser we get redirected if we try.
+ # get_page(annasauthzgroup_authz_url, 401,'annafan')
- # testsysadmin can put her back.
- # It appears that the select boxes on this form need to be set by id
- anauthzgroupid = model.AuthorizationGroup.by_name(u'anauthzgroup').id
- annafanid = model.User.by_name(u'annafan').id
+ # # testsysadmin can put her back.
+ # # It appears that the select boxes on this form need to be set by id
+ # anauthzgroupid = model.AuthorizationGroup.by_name(u'anauthzgroup').id
+ # annafanid = model.User.by_name(u'annafan').id
- # first try to make both anauthzgroup and annafan editors. This should fail.
- res = get_page(annasauthzgroup_authz_url,200, 'testsysadmin')
- gaf= res.forms['group-authz']
- gaf['AuthorizationGroupRole--authorized_group_id'] = anauthzgroupid
- gaf['AuthorizationGroupRole--role'] = 'editor'
- gaf['AuthorizationGroupRole--user_id'] = annafanid
- res = gaf.submit('save', status=200, extra_environ={'REMOTE_USER': 'testsysadmin'})
- assert 'Please select either a user or an authorization group, not both.' in res,\
- 'request should fail if you change both user and authz group'
+ # # first try to make both anauthzgroup and annafan editors. This should fail.
+ # res = get_page(annasauthzgroup_authz_url,200, 'testsysadmin')
+ # gaf= res.forms['group-authz']
+ # gaf['AuthorizationGroupRole--authorized_group_id'] = anauthzgroupid
+ # gaf['AuthorizationGroupRole--role'] = 'editor'
+ # gaf['AuthorizationGroupRole--user_id'] = annafanid
+ # res = gaf.submit('save', status=200, extra_environ={'REMOTE_USER': 'testsysadmin'})
+ # assert 'Please select either a user or an authorization group, not both.' in res,\
+ # 'request should fail if you change both user and authz group'
- # settle for just doing one at a time. make anauthzgroup an editor
- res = get_page(annasauthzgroup_authz_url, 200, 'testsysadmin')
- gaf= res.forms['group-authz']
- gaf['AuthorizationGroupRole--authorized_group_id'] = anauthzgroupid
- gaf['AuthorizationGroupRole--role'] = 'editor'
- res = gaf.submit('save',status=200, extra_environ={'REMOTE_USER': 'testsysadmin'})
- assert "Added role 'editor' for authorization group 'anauthzgroup'" in res, \
- "no flash message"
+ # # settle for just doing one at a time. make anauthzgroup an editor
+ # res = get_page(annasauthzgroup_authz_url, 200, 'testsysadmin')
+ # gaf= res.forms['group-authz']
+ # gaf['AuthorizationGroupRole--authorized_group_id'] = anauthzgroupid
+ # gaf['AuthorizationGroupRole--role'] = 'editor'
+ # res = gaf.submit('save',status=200, extra_environ={'REMOTE_USER': 'testsysadmin'})
+ # assert "Added role 'editor' for authorization group 'anauthzgroup'" in res, \
+ # "no flash message"
- # and make annafan a reader
- res = get_page(annasauthzgroup_authz_url, 200, 'testsysadmin')
- gaf= res.forms['group-authz']
- gaf['AuthorizationGroupRole--user_id'] = annafanid
- gaf['AuthorizationGroupRole--role'] = 'reader'
- res = gaf.submit('save', status=200, extra_environ={'REMOTE_USER': 'testsysadmin'})
- assert "Added role 'reader' for user 'annafan'" in res, "no flash message"
+ # # and make annafan a reader
+ # res = get_page(annasauthzgroup_authz_url, 200, 'testsysadmin')
+ # gaf= res.forms['group-authz']
+ # gaf['AuthorizationGroupRole--user_id'] = annafanid
+ # gaf['AuthorizationGroupRole--role'] = 'reader'
+ # res = gaf.submit('save', status=200, extra_environ={'REMOTE_USER': 'testsysadmin'})
+ # assert "Added role 'reader' for user 'annafan'" in res, "no flash message"
- # annafan should now be able to add her friends to annasauthzgroup
- res = get_page(annasauthzgroup_edit_url, 200, 'annafan')
- res.forms['group-edit']['AuthorizationGroupUser--user_name']='tester'
- # this follows the post/redirect/get pattern
- res = res.forms['group-edit'].submit('save', status=302,
- extra_environ={'REMOTE_USER': 'annafan'})
- res = res.follow(status=200, extra_environ={'REMOTE_USER': 'annafan'})
- # and she gets redirected to the group view page
- assert 'tester' in res, 'tester not added?'
+ # # annafan should now be able to add her friends to annasauthzgroup
+ # res = get_page(annasauthzgroup_edit_url, 200, 'annafan')
+ # res.forms['group-edit']['AuthorizationGroupUser--user_name']='tester'
+ # # this follows the post/redirect/get pattern
+ # res = res.forms['group-edit'].submit('save', status=302,
+ # extra_environ={'REMOTE_USER': 'annafan'})
+ # res = res.follow(status=200, extra_environ={'REMOTE_USER': 'annafan'})
+ # # and she gets redirected to the group view page
+ # assert 'tester' in res, 'tester not added?'
- # she needs to do them one by one
- res = get_page(annasauthzgroup_edit_url, 200, 'annafan',
- 'tester',
- 'tester not in edit form')
- res.forms['group-edit']['AuthorizationGroupUser--user_name']='russianfan'
- res = res.forms['group-edit'].submit('save', status=302, extra_environ={'REMOTE_USER': 'annafan'})
- res = res.follow(status=200, extra_environ={'REMOTE_USER': 'annafan'})
+ # # she needs to do them one by one
+ # res = get_page(annasauthzgroup_edit_url, 200, 'annafan',
+ # 'tester',
+ # 'tester not in edit form')
+ # res.forms['group-edit']['AuthorizationGroupUser--user_name']='russianfan'
+ # res = res.forms['group-edit'].submit('save', status=302, extra_environ={'REMOTE_USER': 'annafan'})
+ # res = res.follow(status=200, extra_environ={'REMOTE_USER': 'annafan'})
- # and finally adds herself
- res = self.app.get(annasauthzgroup_edit_url, status=200, extra_environ={'REMOTE_USER': 'annafan'})
- assert 'russianfan' in res, 'russianfan not added?'
- res.forms['group-edit']['AuthorizationGroupUser--user_name']='annafan'
- res = res.forms['group-edit'].submit('save', status=302, extra_environ={'REMOTE_USER': 'annafan'})
- res = res.follow(status=200, extra_environ={'REMOTE_USER': 'annafan'})
- assert 'annafan' in res, 'annafan not added?'
+ # # and finally adds herself
+ # res = self.app.get(annasauthzgroup_edit_url, status=200, extra_environ={'REMOTE_USER': 'annafan'})
+ # assert 'russianfan' in res, 'russianfan not added?'
+ # res.forms['group-edit']['AuthorizationGroupUser--user_name']='annafan'
+ # res = res.forms['group-edit'].submit('save', status=302, extra_environ={'REMOTE_USER': 'annafan'})
+ # res = res.follow(status=200, extra_environ={'REMOTE_USER': 'annafan'})
+ # assert 'annafan' in res, 'annafan not added?'
- # finally let's check that annafan can create a completely new authzgroup
- new_authzgroup_url = url_for(controller='/authorization_group', action='new')
- res = get_page(new_authzgroup_url, 200,'annafan',
- 'New Authorization Group',
- "wrong page?")
- gef = res.forms['group-edit']
- gef['AuthorizationGroup--name']="newgroup"
- gef['AuthorizationGroupUser--user_name'] = "russianfan"
- res = gef.submit('save', status=302, extra_environ={'REMOTE_USER': 'annafan'})
- #post/redirect/get
- res = res.follow(status=200, extra_environ={'REMOTE_USER': 'annafan'})
+ # # finally let's check that annafan can create a completely new authzgroup
+ # new_authzgroup_url = url_for(controller='/authorization_group', action='new')
+ # res = get_page(new_authzgroup_url, 200,'annafan',
+ # 'New Authorization Group',
+ # "wrong page?")
+ # gef = res.forms['group-edit']
+ # gef['AuthorizationGroup--name']="newgroup"
+ # gef['AuthorizationGroupUser--user_name'] = "russianfan"
+ # res = gef.submit('save', status=302, extra_environ={'REMOTE_USER': 'annafan'})
+ # #post/redirect/get
+ # res = res.follow(status=200, extra_environ={'REMOTE_USER': 'annafan'})
- assert 'newgroup' in res, "should have redirected to the newgroup page"
- assert 'russianfan' in res, "no russianfan"
- assert 'There are 1 users in this authorization group' in res, "missing text"
+ # assert 'newgroup' in res, "should have redirected to the newgroup page"
+ # assert 'russianfan' in res, "no russianfan"
+ # assert 'There are 1 users in this authorization group' in res, "missing text"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ckan/tests/functional/test_edit_authz.py Wed May 25 00:50:41 2011 +0100
@@ -0,0 +1,418 @@
+import ckan.model as model
+from ckan.tests import *
+from ckan.lib.base import *
+import ckan.authz as authz
+
+
+def check_and_set_checkbox(theform, user, role, should_be, set_to):
+ '''Given an authz form, find the checkbox associated with the strings user and role,
+ assert that it's in the state 'should_be', and set it to 'set_to' '''
+ user_role_string = '%s$%s' % (user, role)
+ checkboxes = [x for x in theform.fields[user_role_string] \
+ if x.__class__.__name__ == 'Checkbox']
+
+ assert(len(checkboxes)==1), \
+ "there should only be one checkbox for %s/%s" % (user, role)
+ checkbox = checkboxes[0]
+
+ #checkbox should be unticked
+ assert checkbox.checked==should_be, \
+ "%s/%s checkbox in unexpected state" % (user, role)
+
+ #tick or untick the box and return the form
+ checkbox.checked=set_to
+ return theform
+
+
+class TestEditAuthz(TestController):
+ @classmethod
+ def setup_class(self):
+ # for the authorization editing tests we set up test data so:
+ # three users, sysadmin , administrator, and another
+ # one authzgroup, one group, one package
+ # and administrator is admin on all three
+ # one extra authzgroup, authzgroup2, with no permissions to start with
+ model.repo.init_db()
+ model.repo.new_revision()
+
+ self.sysadmin = 'sysadmin'
+ sysadmin_user = model.User(name=unicode(self.sysadmin))
+ self.admin = 'administrator'
+ admin_user = model.User(name=unicode(self.admin))
+ self.another = 'another'
+ another_user = model.User(name=unicode(self.another))
+ self.authzgroup = 'authzgroup'
+ authzgroup = model.AuthorizationGroup(name=unicode(self.authzgroup))
+ self.group = 'group'
+ group = model.Group(name=unicode(self.group))
+ self.authzgroup2 = 'authzgroup2'
+ authzgroup2 = model.AuthorizationGroup(name=unicode(self.authzgroup2))
+
+
+ for obj in sysadmin_user, admin_user, another_user, authzgroup, group, authzgroup2:
+ model.Session.add(obj)
+
+ model.add_user_to_role(sysadmin_user, model.Role.ADMIN, model.System())
+ model.repo.new_revision()
+
+ self.pkg = u'package'
+ pkg = model.Package(name=self.pkg)
+ model.Session.add(pkg)
+
+ admin_user = model.User.by_name(unicode(self.admin))
+ assert admin_user
+
+ # setup all three authorization objects to have logged in and visitor as editors, and the admin as admin
+ model.setup_user_roles(pkg, ['editor'], ['editor'], [admin_user])
+ model.setup_user_roles(authzgroup, ['editor'], ['editor'], [admin_user])
+ model.setup_user_roles(group, ['editor'], ['editor'], [admin_user])
+
+ model.repo.commit_and_remove()
+
+ @classmethod
+ def teardown_class(self):
+ model.repo.rebuild_db()
+
+ def test_access_to_authz(self):
+ #for each of the three authz pages, check that the access permissions work correctly
+ for (c,i) in [('package', self.pkg),('group', self.group),('authorization_group', self.authzgroup)]:
+ offset = url_for(controller=c, action='authz', id=i)
+
+ # attempt to access the authz pages without credentials should result in getting redirected to the login page
+ res = self.app.get(offset, status=[302])
+ res = res.follow()
+ assert res.request.url.startswith('/user/login')
+
+ # for an ordinary user, it should result in access denied
+ # which is weird, because in the app proper he'd get redirected too.
+ # it behaves differently in the test setup, but this is a known strangeness.
+ res = self.app.get(offset, status=[401], extra_environ={'REMOTE_USER':self.another})
+
+ # going there as the package administrator or system administrator should be fine
+ for u in [self.admin,self.sysadmin]:
+ res = self.app.get(offset, status=[200], extra_environ={'REMOTE_USER':u})
+ # the name of the object should appear in the page
+ assert i in res
+ assert "Authorization for" in res
+
+
+ def roles_list(self, authzobj):
+ # get a list of username/roles for a given authorizable object
+ list = [ (r.user.name, r.role) for r in authzobj.roles if r.user]
+ list.extend([(r.authorized_group.name, r.role) for r in authzobj.roles if r.authorized_group])
+ return list
+
+ # get the users/roles for the specific objects created in our test data
+ def package_roles(self):
+ return self.roles_list(model.Package.by_name(self.pkg))
+
+ def group_roles(self):
+ return self.roles_list(model.Group.by_name(self.group))
+
+ def authzgroup_roles(self):
+ return self.roles_list(model.AuthorizationGroup.by_name(self.authzgroup))
+
+ # check that the authz page for each object contains certain key strings
+ def test_2_read_ok(self):
+ for (c,i,m) in [('package', self.pkg, self.package_roles),\
+ ('group', self.group, self.group_roles),\
+ ('authorization_group', self.authzgroup, self.authzgroup_roles)]:
+ offset = url_for(controller=c, action='authz', id=i)
+ res = self.app.get(offset, extra_environ={'REMOTE_USER': self.admin})
+ assert i in res
+ assert "Authorization for" in res
+
+ # all the package's users and roles should appear in tables
+ assert '<tr' in res
+ for (user,role) in m():
+ assert user in res
+ assert role in res
+
+
+ def assert_roles_to_be(self, actual_roles_list, expected_roles_list):
+ # given an actual and an expected list of user/roles, assert that they're as expected,
+ # modulo ordering.
+ ok = ( len(actual_roles_list) == len(expected_roles_list) )
+ for r in actual_roles_list:
+ if not r in expected_roles_list:
+ ok = False
+ if not ok:
+ print "expected roles: ", expected_roles_list
+ print "actual roles: ", actual_roles_list
+ assert False, "roles not as expected"
+
+
+ # check that when we change one role and add another, that both the checkbox states and the database
+ # change as we expect them to, and that the roles on the other objects don't get changed by accident.
+ # this should guard against certain errors which might be introduced by copy and pasting the controller code.
+ def change_roles(self, user):
+
+ normal_roles=[('administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')]
+
+ changed_roles=[('administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('visitor', 'reader'),
+ ('logged_in', 'admin')]
+
+ # loop variables here are the controller string, the name of the object we're changing, and three functions,
+ # the first fn gets the roles which we'd like to change, and the other two get the roles which we'd like to stay the same.
+ for (c,i,var,const1,const2) in [('package', self.pkg, self.package_roles, self.group_roles, self.authzgroup_roles),\
+ ('group', self.group, self.group_roles, self.package_roles, self.authzgroup_roles),\
+ ('authorization_group', self.authzgroup, self.authzgroup_roles, self.package_roles, self.group_roles)]:
+
+ # load authz page
+ offset = url_for(controller=c, action='authz', id=i)
+ res = self.app.get(offset, extra_environ={'REMOTE_USER':user})
+ assert i in res
+
+ self.assert_roles_to_be(var(), normal_roles)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+ #admin makes visitor a reader and logged in an admin
+ form = res.forms['theform']
+ check_and_set_checkbox(form, u'visitor', u'reader', False, True)
+ check_and_set_checkbox(form, u'logged_in', u'admin', False, True)
+ check_and_set_checkbox(form, u'visitor', u'editor', True, True)
+ check_and_set_checkbox(form, u'logged_in', u'editor', True, False)
+
+ res = form.submit('save', extra_environ={'REMOTE_USER': user})
+
+ # ensure db was changed
+ self.assert_roles_to_be(var(), changed_roles)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+ # ensure rerender of form is changed
+ offset = url_for(controller=c, action='authz', id=i)
+ res = self.app.get(offset, extra_environ={'REMOTE_USER':user})
+ assert i in res
+
+ # check that the checkbox states are what we think they should be
+ # and put things back how they were.
+ form = res.forms['theform']
+ check_and_set_checkbox(form, u'visitor', u'reader', True, False)
+ check_and_set_checkbox(form, u'logged_in', u'admin', True, False)
+ check_and_set_checkbox(form, u'visitor', u'editor', True, True)
+ check_and_set_checkbox(form, u'logged_in', u'editor', False, True)
+ res = form.submit('save', extra_environ={'REMOTE_USER': user})
+
+ # ensure db was changed
+ self.assert_roles_to_be(var(), normal_roles)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+
+ # do the change roles both as package/group/authzgroup admin, and also as sysadmin.
+ def test_3_admin_changes_role(self):
+ self.change_roles(self.admin)
+
+ def test_3_sysadmin_changes_role(self):
+ self.change_roles(self.sysadmin)
+
+ def delete_role_as(self,user):
+
+ normal_roles=[('administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')]
+
+ changed_roles=[('administrator', 'admin'),
+ ('logged_in', 'editor')]
+
+ changed_roles2=[('administrator', 'admin'),
+ ('visitor', 'reader'),
+ ('logged_in', 'editor')]
+
+
+ # loop variables here are the controller string, the name of the object we're changing, and three functions,
+ # the first fn gets the roles which we'd like to change, and the other two get the roles which we'd like to stay the same.
+ for (c,i,var,const1,const2) in [('package', self.pkg, self.package_roles, self.group_roles, self.authzgroup_roles),\
+ ('group', self.group, self.group_roles, self.package_roles, self.authzgroup_roles),\
+ ('authorization_group', self.authzgroup, self.authzgroup_roles, self.package_roles, self.group_roles)]:
+
+ # get the authz page, check that visitor's in there
+ # remove visitor's role on the package
+ # re-get the page and make sure that visitor's not in there at all
+ offset = url_for(controller=c, action='authz', id=i)
+ res = self.app.get(offset, extra_environ={'REMOTE_USER':user})
+ assert self.pkg in res
+
+ self.assert_roles_to_be(var(), normal_roles)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+ assert 'visitor' in res
+ assert 'administrator' in res
+ assert 'logged_in' in res
+
+ #admin removes visitor's only role
+ form = res.forms['theform']
+ check_and_set_checkbox(form, u'visitor', u'editor', True, False)
+ res = form.submit('save', extra_environ={'REMOTE_USER': user})
+
+ # ensure db was changed
+ self.assert_roles_to_be(var(), changed_roles)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+ # ensure rerender of form is changed
+ offset = url_for(controller=c, action='authz', id=i)
+ res = self.app.get(offset, extra_environ={'REMOTE_USER':user})
+ assert self.pkg in res
+
+ assert 'visitor' not in res
+ assert 'administrator' in res
+ assert 'logged_in' in res
+
+ # check that the checkbox states are what we think they should be
+ form = res.forms['theform']
+ check_and_set_checkbox(form, u'logged_in', u'editor', True, True)
+ check_and_set_checkbox(form, u'administrator', u'admin', True, True)
+
+ # now we should add visitor back in, let's make him a reader
+ form = res.forms['addform']
+ form.fields['new_user_name'][0].value='visitor'
+ checkbox = [x for x in form.fields['reader'] \
+ if x.__class__.__name__ == 'Checkbox'][0]
+ # check it's currently unticked
+ assert checkbox.checked == False
+ # tick it and submit
+ checkbox.checked=True
+ res = form.submit('add', extra_environ={'REMOTE_USER':user})
+ assert "User Added" in res, "don't see flash message"
+
+ # check that the page contains strings for everyone
+ assert 'visitor' in res
+ assert 'administrator' in res
+ assert 'logged_in' in res
+
+ # check that the roles in the db are back to normal
+ self.assert_roles_to_be(var(), changed_roles2)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+ # now change him back to being an editor
+ form = res.forms['theform']
+ check_and_set_checkbox(form, u'visitor', u'reader', True, False)
+ check_and_set_checkbox(form, u'visitor', u'editor', False, True)
+ res = form.submit('save', extra_environ={'REMOTE_USER': user})
+
+ # check that the page contains strings for everyone
+ assert 'visitor' in res
+ assert 'administrator' in res
+ assert 'logged_in' in res
+
+ # check that the roles in the db are back to normal
+ self.assert_roles_to_be(var(), normal_roles)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+
+
+ def test_4_admin_deletes_role(self):
+ self.delete_role_as(self.admin)
+
+ def test_4_sysadmin_deletes_role(self):
+ self.delete_role_as(self.sysadmin)
+
+
+ # now a version of the above tests dealing with permissions assigned to authzgroups
+ # (as opposed to on authzgroups)
+ def add_change_delete_authzgroup_as(self, user):
+
+ normal_roles=[('administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')]
+
+ changed_roles=[('authzgroup2', 'admin'),
+ ('administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')]
+
+ changed_roles_2=[('authzgroup2', 'editor'),
+ ('administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')]
+
+ for (c,i,var,const1,const2) in [('package', self.pkg, self.package_roles, self.group_roles, self.authzgroup_roles),\
+ ('group', self.group, self.group_roles, self.package_roles, self.authzgroup_roles),\
+ ('authorization_group', self.authzgroup, self.authzgroup_roles, self.package_roles, self.group_roles)]:
+
+ # get the authz page, check that it contains the object name
+ offset = url_for(controller=c, action='authz', id=i)
+ res = self.app.get(offset, extra_environ={'REMOTE_USER':user})
+ assert i in res
+
+ # check the state of the database
+ self.assert_roles_to_be(var(), normal_roles)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+ # and that corresponding user strings are in the authz page
+ # particularly that authzgroup2 isn't there (yet)
+ assert 'visitor' in res
+ assert 'administrator' in res
+ assert 'logged_in' in res
+ assert 'authzgroup2' not in res
+
+ # add authzgroup2 as an admin
+ form = res.forms['authzgroup_addform']
+ form.fields['new_user_name'][0].value='authzgroup2'
+ checkbox = [x for x in form.fields['admin'] \
+ if x.__class__.__name__ == 'Checkbox'][0]
+ # check the checkbox is currently unticked
+ assert checkbox.checked == False
+ # tick it and submit
+ checkbox.checked=True
+ res = form.submit('authz_add', extra_environ={'REMOTE_USER':user})
+ assert "Authorization Group Added" in res, "don't see flash message"
+
+ # examine the new page for user names/authzgroup names
+ assert 'visitor' in res
+ assert 'administrator' in res
+ assert 'logged_in' in res
+ assert 'authzgroup2' in res
+
+ # and ensure that the database has changed as expected
+ self.assert_roles_to_be(var(), changed_roles)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+ # check that the checkbox states are what we think they should be
+ # and change authzgroup2 from admin to editor
+ form = res.forms['authzgroup_form']
+ check_and_set_checkbox(form, u'authzgroup2', u'editor', False, True)
+ check_and_set_checkbox(form, u'authzgroup2', u'admin', True, False)
+ res = form.submit('authz_save', extra_environ={'REMOTE_USER': user})
+
+ #check database has changed.
+ self.assert_roles_to_be(var(), changed_roles_2)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+
+ # now remove authzgroup2 entirely
+ form = res.forms['authzgroup_form']
+ check_and_set_checkbox(form, u'authzgroup2', u'editor', True, False)
+ check_and_set_checkbox(form, u'authzgroup2', u'admin', False, False)
+ res = form.submit('authz_save', extra_environ={'REMOTE_USER': user})
+
+ #check database is back to normal
+ self.assert_roles_to_be(var(), normal_roles)
+ self.assert_roles_to_be(const1(), normal_roles)
+ self.assert_roles_to_be(const2(), normal_roles)
+
+ # and that page contains only the expected strings
+ assert 'visitor' in res
+ assert 'administrator' in res
+ assert 'logged_in' in res
+ assert 'authzgroup2' not in res
+
+
+ def test_5_admin_changes_adds_deletes_authzgroup(self):
+ self.add_change_delete_authzgroup_as(self.admin)
+
+ def test_5_sysadmin_changes_adds_deletes_authzgroup(self):
+ self.add_change_delete_authzgroup_as(self.sysadmin)
--- a/ckan/tests/functional/test_package_edit_authz.py Sun May 22 19:52:34 2011 +0100
+++ b/ckan/tests/functional/test_package_edit_authz.py Wed May 25 00:50:41 2011 +0100
@@ -3,9 +3,34 @@
from ckan.lib.base import *
import ckan.authz as authz
+
+def check_and_set_checkbox(theform, user, role, should_be, set_to):
+ '''Given an authz form, find the checkbox associated with the strings user and role,
+ assert that it's in the state 'should_be', and set it to 'set_to' '''
+ user_role_string = '%s$%s' % (user, role)
+ checkboxes = [x for x in theform.fields[user_role_string] \
+ if x.__class__.__name__ == 'Checkbox']
+
+ assert(len(checkboxes)==1), \
+ "there should only be one checkbox for %s/%s" % (user, role)
+ checkbox = checkboxes[0]
+
+ #checkbox should be unticked
+ assert checkbox.checked==should_be, \
+ "%s/%s checkbox in unexpected state" % (user, role)
+
+ #tick or untick the box and return the form
+ checkbox.checked=set_to
+ return theform
+
+
class TestPackageEditAuthz(TestController):
@classmethod
def setup_class(self):
+ # for the authorization editing tests we set up test data so:
+ # three users, madeup-sysadmin , madeup-administrator, and madeup-another
+ # one authzgroup
+ # two packages test6 and test6a, m-a is admin on both
model.repo.init_db()
model.repo.new_revision()
@@ -15,7 +40,9 @@
admin_user = model.User(name=unicode(self.admin))
self.another = u'madeup-another'
another_user = model.User(name=unicode(self.another))
- for obj in sysadmin_user, admin_user, another_user:
+ self.authzgroup = u'madeup-authzgroup'
+ authzgroup = model.AuthorizationGroup(name=unicode(self.authzgroup))
+ for obj in sysadmin_user, admin_user, another_user, authzgroup:
model.Session.add(obj)
model.add_user_to_role(sysadmin_user, model.Role.ADMIN, model.System())
@@ -43,10 +70,7 @@
res = self.app.get(offset, status=[302, 401])
res = res.follow()
assert res.request.url.startswith('/user/login')
- # Alternative if we allowed read-only access
- # res = self.app.get(offset)
- # assert not '<form' in res, res
-
+
def test_1_admin_has_access(self):
offset = url_for(controller='package', action='authz', id=self.pkgname)
res = self.app.get(offset, extra_environ={'REMOTE_USER':
@@ -62,182 +86,247 @@
res = self.app.get(offset, extra_environ={'REMOTE_USER':
self.admin})
assert self.pkgname in res
+
+ # all the package's users and roles should appear in tables
assert '<tr' in res
- assert self.admin in res
- assert 'Role' in res
- for uname in [ model.PSEUDO_USER__VISITOR, self.admin ]:
- assert '%s' % uname in res
- # crude but roughly correct
+ for (user,role) in self.package_roles():
+ assert user in res
+ assert role in res
+
+
+ def package_roles(self):
pkg = model.Package.by_name(self.pkgname)
- for r in pkg.roles:
- assert '<select id="PackageRole-%s-role' % r.id in res
+ list = [ (r.user.name, r.role) for r in pkg.roles if r.user]
+ list.extend([(r.authorized_group.name, r.role) for r in pkg.roles if r.authorized_group])
+ return list
- # now test delete links
- pr = pkg.roles[0]
- href = '%s' % pr.id
- assert href in res, res
+ def assert_package_roles_to_be(self, roles_list):
+ prs=self.package_roles()
+ ok = ( len(prs) == len(roles_list) )
+ for r in roles_list:
+ if not r in prs:
+ ok = False
+ if not ok:
+ print "expected roles: ", roles_list
+ print "actual roles: ", prs
+ assert False, "roles not as expected"
- def _prs(self, pkgname):
- pkg = model.Package.by_name(pkgname)
- return dict([ (getattr(r.user, 'name', 'USER NAME IS NONE'), r) for r in pkg.roles ])
-
- def test_3_admin_changes_role(self):
+ def change_roles(self, user):
# load authz page
offset = url_for(controller='package', action='authz', id=self.pkgname)
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.admin})
+ res = self.app.get(offset, extra_environ={'REMOTE_USER':user})
assert self.pkgname in res
- def _r(r):
- return 'PackageRole-%s-role' % r.id
- def _u(r):
- return 'PackageRole-%s-user_id' % r.id
+ self.assert_package_roles_to_be([
+ ('madeup-administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')])
- prs = self._prs(self.pkgname)
- assert prs['visitor'].role == model.Role.EDITOR
- assert prs['logged_in'].role == model.Role.EDITOR
- form = res.forms['package-authz']
-
- # change role assignments
- form.select(_r(prs['visitor']), model.Role.READER)
- form.select(_r(prs['logged_in']), model.Role.ADMIN)
- res = form.submit('save', extra_environ={'REMOTE_USER': self.admin})
- model.repo.commit_and_remove()
+ #admin makes visitor a reader and logged in an admin
+ form = res.forms['theform']
+ check_and_set_checkbox(form, u'visitor', u'reader', False, True)
+ check_and_set_checkbox(form, u'logged_in', u'admin', False, True)
+ check_and_set_checkbox(form, u'visitor', u'editor', True, True)
+ check_and_set_checkbox(form, u'logged_in', u'editor', True, False)
+
+ res = form.submit('save', extra_environ={'REMOTE_USER': user})
# ensure db was changed
- prs = self._prs(self.pkgname)
- assert len(prs) == 3, prs
- assert prs['visitor'].role == model.Role.READER
- assert prs['logged_in'].role == model.Role.ADMIN
+ self.assert_package_roles_to_be([
+ ('madeup-administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('visitor', 'reader'),
+ ('logged_in', 'admin')])
# ensure rerender of form is changed
offset = url_for(controller='package', action='authz', id=self.pkgname)
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.admin})
+ res = self.app.get(offset, extra_environ={'REMOTE_USER':user})
assert self.pkgname in res
- fv = res.forms['package-authz']
- visitor_options = fv[_r(prs['visitor'])].options
- assert ('reader', True) in visitor_options, visitor_options
- logged_in_options = fv[_r(prs['logged_in'])].options
- assert ('admin', True) in logged_in_options, logged_in_options
+
+ # check that the checkbox states are what we think they should be
+ # and put things back how they were.
+ form = res.forms['theform']
+ check_and_set_checkbox(form, u'visitor', u'reader', True, False)
+ check_and_set_checkbox(form, u'logged_in', u'admin', True, False)
+ check_and_set_checkbox(form, u'visitor', u'editor', True, True)
+ check_and_set_checkbox(form, u'logged_in', u'editor', False, True)
+ res = form.submit('save', extra_environ={'REMOTE_USER': user})
+
+ # ensure db was changed
+ self.assert_package_roles_to_be([
+ ('madeup-administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')])
+
+
+ def test_3_admin_changes_role(self):
+ self.change_roles(self.admin)
def test_3_sysadmin_changes_role(self):
- # load authz page
- offset = url_for(controller='package', action='authz', id=self.pkgname2)
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.sysadmin})
- assert self.pkgname2 in res
+ self.change_roles(self.sysadmin)
- def _r(r):
- return 'PackageRole-%s-role' % r.id
- def _u(r):
- return 'PackageRole-%s-user_id' % r.id
+ def delete_role_as(self,user):
+ # get the authz page, check that visitor's in there
+ # remove visitor's role on the package
+ # re-get the page and make sure that visitor's not in there at all
+ offset = url_for(controller='package', action='authz', id=self.pkgname)
+ res = self.app.get(offset, extra_environ={'REMOTE_USER':user})
+ assert self.pkgname in res
- prs = self._prs(self.pkgname2)
- assert prs['visitor'].role == model.Role.EDITOR
- assert prs['logged_in'].role == model.Role.EDITOR
- form = res.forms['package-authz']
-
- # change role assignments
- form.select(_r(prs['visitor']), model.Role.READER)
- form.select(_r(prs['logged_in']), model.Role.ADMIN)
- res = form.submit('save', extra_environ={'REMOTE_USER': self.sysadmin})
- model.repo.commit_and_remove()
+ self.assert_package_roles_to_be([
+ ('madeup-administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')])
+
+ assert 'visitor' in res
+ assert 'madeup-administrator' in res
+ assert 'logged_in' in res
+
+ #admin removes visitor's only role
+ form = res.forms['theform']
+ check_and_set_checkbox(form, u'visitor', u'editor', True, False)
+ res = form.submit('save', extra_environ={'REMOTE_USER': user})
# ensure db was changed
- prs = self._prs(self.pkgname2)
- assert len(prs) == 3, prs
- assert prs['visitor'].role == model.Role.READER
- assert prs['logged_in'].role == model.Role.ADMIN
+ self.assert_package_roles_to_be([
+ ('madeup-administrator', 'admin'),
+ ('logged_in', 'editor')])
# ensure rerender of form is changed
- offset = url_for(controller='package', action='authz', id=self.pkgname2)
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.sysadmin})
- assert self.pkgname2 in res
- fv = res.forms['package-authz']
- visitor_options = fv[_r(prs['visitor'])].options
- assert ('reader', True) in visitor_options, visitor_options
- logged_in_options = fv[_r(prs['logged_in'])].options
- assert ('admin', True) in logged_in_options, logged_in_options
-
+ offset = url_for(controller='package', action='authz', id=self.pkgname)
+ res = self.app.get(offset, extra_environ={'REMOTE_USER':user})
+ assert self.pkgname in res
+
+ assert 'visitor' not in res
+ assert 'madeup-administrator' in res
+ assert 'logged_in' in res
+
+ # check that the checkbox states are what we think they should be
+ form = res.forms['theform']
+ check_and_set_checkbox(form, u'logged_in', u'editor', True, True)
+ check_and_set_checkbox(form, u'madeup-administrator', u'admin', True, True)
+
+ # now we should add visitor back in, let's make him a reader
+ form = res.forms['addform']
+ form.fields['new_user_name'][0].value='visitor'
+ checkbox = [x for x in form.fields['reader'] \
+ if x.__class__.__name__ == 'Checkbox'][0]
+ # check it's currently unticked
+ assert checkbox.checked == False
+ # tick it and submit
+ checkbox.checked=True
+ res = form.submit('add', extra_environ={'REMOTE_USER':user})
+ assert "User Added" in res, "don't see flash message"
+
+ # check that the page contains strings for everyone
+ assert 'visitor' in res
+ assert 'madeup-administrator' in res
+ assert 'logged_in' in res
+
+ # check that the roles in the db are back to normal
+ self.assert_package_roles_to_be([
+ ('madeup-administrator', 'admin'),
+ ('visitor', 'reader'),
+ ('logged_in', 'editor')])
+
+ # now change him back to being an editor
+ form = res.forms['theform']
+ check_and_set_checkbox(form, u'visitor', u'reader', True, False)
+ check_and_set_checkbox(form, u'visitor', u'editor', False, True)
+ res = form.submit('save', extra_environ={'REMOTE_USER': user})
+
+ # check that the page contains strings for everyone
+ assert 'visitor' in res
+ assert 'madeup-administrator' in res
+ assert 'logged_in' in res
+
+ # check that the roles in the db are back to normal
+ self.assert_package_roles_to_be([
+ ('madeup-administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')])
+
+
def test_4_admin_deletes_role(self):
- pkg = model.Package.by_name(self.pkgname)
- assert len(pkg.roles) == 3
- # make sure not admin
- pr_id = [ r for r in pkg.roles if r.user.name != self.admin ][0].id
- offset = url_for(controller='package', action='authz', id=self.pkgname,
- role_to_delete=pr_id)
- # need this here as o/w conflicts over session binding
- model.Session.remove()
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.admin})
- assert 'Deleted role' in res, res
- assert 'error' not in res, res
- pkg = model.Package.by_name(self.pkgname)
- assert len(pkg.roles) == 2
- assert model.Session.query(model.PackageRole).filter_by(id=pr_id).count() == 0
+ self.delete_role_as(self.admin)
def test_4_sysadmin_deletes_role(self):
- pkg = model.Package.by_name(self.pkgname2)
- assert len(pkg.roles) == 3
- # make sure not admin
- pr_id = [ r for r in pkg.roles if r.user.name != self.admin ][0].id
- offset = url_for(controller='package', action='authz', id=self.pkgname2,
- role_to_delete=pr_id)
- # need this here as o/w conflicts over session binding
- model.Session.remove()
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.sysadmin})
- assert 'Deleted role' in res, res
- assert 'error' not in res, res
- pkg = model.Package.by_name(self.pkgname2)
- assert len(pkg.roles) == 2
- assert model.Session.query(model.PackageRole).filter_by(id=pr_id).count() == 0
+ self.delete_role_as(self.sysadmin)
- def test_5_admin_adds_role(self):
+
+ def test_5_add_change_delete_authzgroup(self):
+ user=self.admin
+
+ # get the authz page, check that authzgroup isn't in there
offset = url_for(controller='package', action='authz', id=self.pkgname)
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.admin})
+ res = self.app.get(offset, extra_environ={'REMOTE_USER':user})
assert self.pkgname in res
- prs = self._prs(self.pkgname)
- startlen = len(prs)
- # could be 2 or 3 depending on whether we ran this test alone or not
- # assert len(prs) == 2, prs
- assert 'Create New User Roles' in res
- assert '<select id=' in res, res
- form = res.forms['package-authz']
- another = model.User.by_name(self.another)
- form.select('PackageRole--user_id', another.id)
- form.select('PackageRole--role', model.Role.ADMIN)
- res = form.submit('save', extra_environ={'REMOTE_USER': self.admin})
- model.Session.remove()
+ # check the state of the database
+ self.assert_package_roles_to_be([
+ ('madeup-administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')])
- prs = self._prs(self.pkgname)
- assert len(prs) == startlen+1, prs
- assert prs[self.another].role == model.Role.ADMIN
+ # and that corresponding user strings are in the authz page
+ assert 'visitor' in res
+ assert 'madeup-administrator' in res
+ assert 'logged_in' in res
+ assert 'madeup-authzgroup' not in res
- def test_5_sysadmin_adds_role(self):
- offset = url_for(controller='package', action='authz', id=self.pkgname2)
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.sysadmin})
- assert self.pkgname2 in res
- prs = self._prs(self.pkgname2)
- startlen = len(prs)
- # could be 2 or 3 depending on whether we ran this test alone or not
- # assert len(prs) == 2, prs
+ # add madeup-authzgroup as an admin
+ form = res.forms['authzgroup_addform']
+ form.fields['new_user_name'][0].value='madeup-authzgroup'
+ checkbox = [x for x in form.fields['admin'] \
+ if x.__class__.__name__ == 'Checkbox'][0]
+ # check the checkbox is currently unticked
+ assert checkbox.checked == False
+ # tick it and submit
+ checkbox.checked=True
+ res = form.submit('authz_add', extra_environ={'REMOTE_USER':user})
+ assert "Authorization Group Added" in res, "don't see flash message"
- assert 'Create New User Roles' in res
- assert '<select id=' in res, res
- form = res.forms['package-authz']
- another = model.User.by_name(self.another)
- form.select('PackageRole--user_id', another.id)
- form.select('PackageRole--role', model.Role.ADMIN)
- res = form.submit('save', extra_environ={'REMOTE_USER': self.sysadmin})
- model.Session.remove()
+ # examine the new page for user names/authzgroup names
+ assert 'visitor' in res
+ assert 'madeup-administrator' in res
+ assert 'logged_in' in res
+ assert 'madeup-authzgroup' in res
- prs = self._prs(self.pkgname2)
- assert len(prs) == startlen+1, prs
- assert prs[self.another].role == model.Role.ADMIN
+ # and ensure that the database has changed as expected
+ self.assert_package_roles_to_be([
+ ('madeup-authzgroup', 'admin'),
+ ('madeup-administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')])
+ # check that the checkbox states are what we think they should be
+ # and change madeup-authzgroup from admin to editor
+ form = res.forms['authzgroup_form']
+ check_and_set_checkbox(form, u'madeup-authzgroup', u'editor', False, True)
+ check_and_set_checkbox(form, u'madeup-authzgroup', u'admin', True, False)
+ res = form.submit('authz_save', extra_environ={'REMOTE_USER': user})
+
+ #check database has changed.
+ self.assert_package_roles_to_be([
+ ('madeup-authzgroup', 'editor'),
+ ('madeup-administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')])
+
+ # now remove madeup-authzgroup entirely
+ form = res.forms['authzgroup_form']
+ check_and_set_checkbox(form, u'madeup-authzgroup', u'editor', True, False)
+ check_and_set_checkbox(form, u'madeup-authzgroup', u'admin', False, False)
+ res = form.submit('authz_save', extra_environ={'REMOTE_USER': user})
+
+ #check database is back to normal
+ self.assert_package_roles_to_be([
+ ('madeup-administrator', 'admin'),
+ ('visitor', 'editor'),
+ ('logged_in', 'editor')])
+
+ # and that page contains only the expected strings
+ assert 'visitor' in res
+ assert 'madeup-administrator' in res
+ assert 'logged_in' in res
+ assert 'madeup-authzgroup' not in res
http://bitbucket.org/okfn/ckan/changeset/82040b86f194/
changeset: r3114:82040b86f194
user: John Lawrence Aspden
date: 2011-05-25 01:51:42
summary: [authz][s]: removed old authz tests, superseded by general authz tests
affected #: 1 file (0 bytes)
--- a/ckan/tests/functional/test_group_edit_authz.py Wed May 25 00:50:41 2011 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-import ckan.model as model
-from ckan.tests import *
-from ckan.lib.base import *
-import ckan.authz as authz
-
-class TestGroupEditAuthz(TestController):
- @classmethod
- def setup_class(self):
- model.repo.init_db()
- model.repo.new_revision()
- self.admin = 'madeup-administrator'
- user = model.User(name=unicode(self.admin))
- model.Session.add(user)
- self.another = u'madeup-another'
- model.Session.add(model.User(name=unicode(self.another)))
- self.groupname = u'test6'
- group = model.Group(name=self.groupname)
- model.setup_default_user_roles(group, admins=[user])
- model.repo.commit_and_remove()
-
- @classmethod
- def teardown_class(self):
- model.repo.rebuild_db()
-
- def test_0_nonadmin_cannot_edit_authz(self):
- offset = url_for(controller='group', action='authz', id=self.groupname)
- res = self.app.get(offset, status=[302, 401])
- res = res.follow()
- assert res.request.url.startswith('/user/login')
- # Alternative if we allowed read-only access
- # res = self.app.get(offset)
- # assert not '<form' in res, res
-
- def test_1_admin_has_access(self):
- offset_authz = url_for(controller='group', action='authz', id=self.groupname)
- res = self.app.get(offset_authz, extra_environ={'REMOTE_USER':
- self.admin}, status=200)
-
- # check link is there too
- offset_read = url_for(controller='group', action='read', id=self.groupname)
- res = self.app.get(offset_read, extra_environ={'REMOTE_USER':
- self.admin})
- assert offset_authz in res
-
-
- def test_2_read_ok(self):
- offset = url_for(controller='group', action='authz', id=self.groupname)
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.admin})
- assert self.groupname in res
- assert '<tr' in res
- assert self.admin in res
- assert 'Role' in res
- for uname in [ model.PSEUDO_USER__VISITOR, self.admin ]:
- assert '%s' % uname in res
- # crude but roughly correct
- group = model.Group.by_name(self.groupname)
- for r in group.roles:
- assert '<select id="GroupRole-%s-role' % r.id in res
-
- # now test delete links
- pr = group.roles[0]
- href = '%s' % pr.id
- assert href in res, res
-
- def _prs(self, groupname):
- group = model.Group.by_name(groupname)
- return dict([ (getattr(r.user, 'name', 'USER NAME IS NONE'), r) for r in group.roles ])
-
- def test_3_admin_changes_role(self):
- # create a role to be deleted
- group = model.Group.by_name(self.groupname)
- model.add_user_to_role(model.User.by_name(u'visitor'), model.Role.READER, group)
- model.repo.commit_and_remove()
-
- offset = url_for(controller='group', action='authz', id=self.groupname)
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.admin})
- assert self.groupname in res
-
- group = model.Group.by_name(self.groupname)
- assert len(group.roles) == 3, [(grouprole.user.name, grouprole.role) for grouprole in group.roles]
-
- def _r(r):
- return 'GroupRole-%s-role' % r.id
- def _u(r):
- return 'GroupRole-%s-user_id' % r.id
-
- prs = self._prs(self.groupname)
- assert prs.has_key('visitor')
- assert prs.has_key('logged_in')
- assert prs.has_key(self.admin), prs
- form = res.forms['group-authz']
-
- # change role assignments
- form.select(_r(prs['visitor']), model.Role.EDITOR)
- res = form.submit('save', extra_environ={'REMOTE_USER': self.admin})
-
- model.Session.remove()
- prs = self._prs(self.groupname)
- assert len(prs) == 3, prs
- assert prs['visitor'].role == model.Role.EDITOR
-
- def test_4_admin_deletes_role(self):
- group = model.Group.by_name(self.groupname)
-
- # create a role to be deleted
- model.add_user_to_role(model.User.by_name(u'logged_in'), model.Role.READER, group)
- model.repo.commit_and_remove()
-
- group = model.Group.by_name(self.groupname)
- num_roles_start = len(group.roles)
-
- # make sure not admin
- pr_id = [ r for r in group.roles if r.user.name != self.admin ][0].id
- offset = url_for(controller='group', action='authz', id=self.groupname,
- role_to_delete=pr_id)
- # need this here as o/w conflicts over session binding
- model.Session.remove()
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.admin})
- assert 'Deleted role' in res, res
- assert 'error' not in res, res
- group = model.Group.by_name(self.groupname)
- assert len(group.roles) == num_roles_start - 1
- assert model.Session.query(model.GroupRole).filter_by(id=pr_id).count() == 0
-
- def test_5_admin_adds_role(self):
- model.repo.commit_and_remove()
- offset = url_for(controller='group', action='authz', id=self.groupname)
- res = self.app.get(offset, extra_environ={'REMOTE_USER':
- self.admin})
- assert self.groupname in res
- prs = self._prs(self.groupname)
- startlen = len(prs)
- # could be 2 or 3 depending on whether we ran this test alone or not
- # assert len(prs) == 2, prs
-
- assert 'Create New User Roles' in res
- assert '<select id="GroupRole--user_id"' in res, res
- assert '<td>madeup-administrator</td>' not in res, res
- form = res.forms['group-authz']
- another = model.User.by_name(self.another)
- form.select('GroupRole--user_id', another.id)
- form.select('GroupRole--role', model.Role.ADMIN)
- res = form.submit('save', extra_environ={'REMOTE_USER': self.admin})
- model.Session.remove()
-
- prs = self._prs(self.groupname)
- assert len(prs) == startlen+1, prs
- assert prs[self.another].role == model.Role.ADMIN
-
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