Esempio n. 1
0
File: update.py Progetto: zydio/ckan
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)
Esempio n. 2
0
File: update.py Progetto: zydio/ckan
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)