def user_role_bulk_update(context, data_dict): """ For a given domain_object, update authz roles that several users have on it. To delete all roles for a user on a domain object, set {roles: []}. """ for user_or_authgroup in ("user", "authorization_group"): # Collate all the roles for each user roles_by_user = {} # user:roles for user_role_dict in data_dict["user_roles"]: user = user_role_dict.get(user_or_authgroup) if user: roles = user_role_dict["roles"] if user not in roles_by_user: roles_by_user[user] = [] roles_by_user[user].extend(roles) # For each user, update its roles for user in roles_by_user: uro_data_dict = { user_or_authgroup: user, "roles": roles_by_user[user], "domain_object": data_dict["domain_object"], } user_role_update(context, uro_data_dict) return roles_show(context, data_dict)
def user_role_update(context, data_dict): """ For a named user (or authz group), set his/her authz roles on a domain_object. """ model = context["model"] user = context["user"] # the current user, who is making the authz change new_user_ref = data_dict.get("user") # the user who is being given the new role new_authgroup_ref = data_dict.get("authorization_group") # the authgroup who is being given the new role if bool(new_user_ref) == bool(new_authgroup_ref): raise ParameterError('You must provide either "user" or "authorization_group" parameter.') domain_object_ref = data_dict["domain_object"] if not isinstance(data_dict["roles"], (list, tuple)): raise ParameterError('Parameter "%s" must be of type: "%s"' % ("role", "list")) desired_roles = set(data_dict["roles"]) if new_user_ref: user_object = model.User.get(new_user_ref) if not user_object: raise NotFound("Cannot find user %r" % new_user_ref) data_dict["user"] = user_object.id add_user_to_role_func = model.add_user_to_role remove_user_from_role_func = model.remove_user_from_role else: user_object = model.AuthorizationGroup.get(new_authgroup_ref) if not user_object: raise NotFound("Cannot find authorization group %r" % new_authgroup_ref) data_dict["authorization_group"] = user_object.id add_user_to_role_func = model.add_authorization_group_to_role remove_user_from_role_func = model.remove_authorization_group_from_role domain_object = get_domain_object(model, domain_object_ref) data_dict["id"] = domain_object.id if isinstance(domain_object, model.Package): check_access("package_edit_permissions", context, data_dict) elif isinstance(domain_object, model.Group): check_access("group_edit_permissions", context, data_dict) elif isinstance(domain_object, model.AuthorizationGroup): check_access("authorization_group_edit_permissions", context, data_dict) # Todo: 'system' object else: raise ParameterError("Not possible to update roles for domain object type %s" % type(domain_object)) # current_uors: 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_role_dicts = roles_show(context, data_dict)["roles"] current_roles = set([role_dict["role"] for role_dict in current_role_dicts]) # Whenever our desired state is different from our current state, # change it. for role in desired_roles - current_roles: add_user_to_role_func(user_object, role, domain_object) for role in current_roles - desired_roles: remove_user_from_role_func(user_object, role, domain_object) # and finally commit all these changes to the database if not (current_roles == desired_roles): model.repo.commit_and_remove() return roles_show(context, data_dict)