示例#1
0
def clean_user_groups():
    for u in user_list()["users"]:
        user_delete(u)

    for g in user_group_list()["groups"]:
        if g not in ["all_users", "visitors"]:
            user_group_delete(g)
示例#2
0
def test_del_group(mocker):

    with message(mocker, "group_deleted", group="dev"):
        user_group_delete("dev")

    group_res = user_group_list()["groups"]
    assert "dev" not in group_res
示例#3
0
def permission_sync_to_user():
    """
    Sychronise the inheritPermission attribut in the permission object from the
    user<->group link and the group<->permission link
    """
    import os
    from yunohost.app import app_ssowatconf
    from yunohost.user import user_group_list
    from yunohost.utils.ldap import _get_ldap_interface

    ldap = _get_ldap_interface()

    groups = user_group_list(full=True)["groups"]
    permissions = user_permission_list(full=True)["permissions"]

    for permission_name, permission_infos in permissions.items():

        # These are the users currently allowed because there's an 'inheritPermission' object corresponding to it
        currently_allowed_users = set(permission_infos["corresponding_users"])

        # These are the users that should be allowed because they are member of a group that is allowed for this permission ...
        should_be_allowed_users = set([
            user for group in permission_infos["allowed"]
            for user in groups[group]["members"]
        ])

        # Note that a LDAP operation with the same value that is in LDAP crash SLAP.
        # So we need to check before each ldap operation that we really change something in LDAP
        if currently_allowed_users == should_be_allowed_users:
            # We're all good, this permission is already correctly synchronized !
            continue

        new_inherited_perms = {
            "inheritPermission": [
                "uid=%s,ou=users,dc=yunohost,dc=org" % u
                for u in should_be_allowed_users
            ],
            "memberUid":
            should_be_allowed_users,
        }

        # Commit the change with the new inherited stuff
        try:
            ldap.update("cn=%s,ou=permission" % permission_name,
                        new_inherited_perms)
        except Exception as e:
            raise YunohostError("permission_update_failed",
                                permission=permission_name,
                                error=e)

    logger.debug("The permission database has been resynchronized")

    app_ssowatconf()

    # Reload unscd, otherwise the group ain't propagated to the LDAP database
    os.system("nscd --invalidate=passwd")
    os.system("nscd --invalidate=group")
示例#4
0
def test_update_group_add_user_already_in(mocker):
    with message(mocker,
                 "group_user_already_in_group",
                 user="******",
                 group="apps"):
        user_group_update("apps", add=["bob"])

    group_res = user_group_list()["groups"]
    assert group_res["apps"]["members"] == ["bob"]
示例#5
0
def test_create_group(mocker):

    with message(mocker, "group_created", group="adminsys"):
        user_group_create("adminsys")

    group_res = user_group_list()["groups"]
    assert "adminsys" in group_res
    assert "members" in group_res["adminsys"].keys()
    assert group_res["adminsys"]["members"] == []
示例#6
0
def test_del_user(mocker):

    with message(mocker, "user_deleted"):
        user_delete("alice")

    group_res = user_group_list()["groups"]
    assert "alice" not in user_list()
    assert "alice" not in group_res
    assert "alice" not in group_res["all_users"]["members"]
示例#7
0
def test_create_user(mocker):

    with message(mocker, "user_created"):
        user_create("albert", "Albert", "Good", maindomain, "test123Ynh")

    group_res = user_group_list()["groups"]
    assert "albert" in user_list()["users"]
    assert "albert" in group_res
    assert "albert" in group_res["albert"]["members"]
    assert "albert" in group_res["all_users"]["members"]
示例#8
0
def test_list_groups():
    res = user_group_list()["groups"]

    assert "all_users" in res
    assert "alice" in res
    assert "bob" in res
    assert "jack" in res
    for u in ["alice", "bob", "jack"]:
        assert u in res
        assert u in res[u]["members"]
        assert u in res["all_users"]["members"]
示例#9
0
def clean_user_groups_permission():
    for u in user_list()['users']:
        user_delete(u)

    for g in user_group_list()['groups']:
        if g not in ["all_users", "visitors"]:
            user_group_delete(g)

    for p in user_permission_list()['permissions']:
        if any(
                p.startswith(name) for name in
            ["wiki", "blog", "site", "web", "permissions_app"]):
            permission_delete(p, force=True, sync_perm=False)
    socket.getaddrinfo = prv_getaddrinfo
示例#10
0
def permission_create(
    operation_logger,
    permission,
    allowed=None,
    url=None,
    additional_urls=None,
    auth_header=True,
    label=None,
    show_tile=False,
    protected=False,
    sync_perm=True,
):
    """
    Create a new permission for a specific application

    Keyword argument:
        permission      -- Name of the permission (e.g. mail or nextcloud or wordpress.editors)
        allowed         -- (optional) List of group/user to allow for the permission
        url             -- (optional) URL for which access will be allowed/forbidden
        additional_urls -- (optional) List of additional URL for which access will be allowed/forbidden
        auth_header     -- (optional) Define for the URL of this permission, if SSOwat pass the authentication header to the application
        label           -- (optional) Define a name for the permission. This label will be shown on the SSO and in the admin. Default is "permission name"
        show_tile       -- (optional) Define if a tile will be shown in the SSO
        protected       -- (optional) Define if the permission can be added/removed to the visitor group

    If provided, 'url' is assumed to be relative to the app domain/path if they
    start with '/'.  For example:
       /                             -> domain.tld/app
       /admin                        -> domain.tld/app/admin
       domain.tld/app/api            -> domain.tld/app/api

    'url' can be later treated as a regex if it starts with "re:".
    For example:
       re:/api/[A-Z]*$               -> domain.tld/app/api/[A-Z]*$
       re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$
    """

    from yunohost.utils.ldap import _get_ldap_interface
    from yunohost.user import user_group_list

    ldap = _get_ldap_interface()

    # By default, manipulate main permission
    if "." not in permission:
        permission = permission + ".main"

    # Validate uniqueness of permission in LDAP
    if ldap.get_conflict({"cn": permission},
                         base_dn="ou=permission,dc=yunohost,dc=org"):
        raise YunohostValidationError("permission_already_exist",
                                      permission=permission)

    # Get random GID
    all_gid = {x.gr_gid for x in grp.getgrall()}

    uid_guid_found = False
    while not uid_guid_found:
        gid = str(random.randint(200, 99999))
        uid_guid_found = gid not in all_gid

    app, subperm = permission.split(".")

    attr_dict = {
        "objectClass": ["top", "permissionYnh", "posixGroup"],
        "cn":
        str(permission),
        "gidNumber":
        gid,
        "authHeader": ["TRUE"],
        "label": [
            str(label) if label else
            (subperm if subperm != "main" else app.title())
        ],
        "showTile": [
            "FALSE"
        ],  # Dummy value, it will be fixed when we call '_update_ldap_group_permission'
        "isProtected": [
            "FALSE"
        ],  # Dummy value, it will be fixed when we call '_update_ldap_group_permission'
    }

    if allowed is not None:
        if not isinstance(allowed, list):
            allowed = [allowed]

    # Validate that the groups to add actually exist
    all_existing_groups = user_group_list()["groups"].keys()
    for group in allowed or []:
        if group not in all_existing_groups:
            raise YunohostValidationError("group_unknown", group=group)

    operation_logger.related_to.append(("app", permission.split(".")[0]))
    operation_logger.start()

    try:
        ldap.add("cn=%s,ou=permission" % permission, attr_dict)
    except Exception as e:
        raise YunohostError("permission_creation_failed",
                            permission=permission,
                            error=e)

    permission_url(
        permission,
        url=url,
        add_url=additional_urls,
        auth_header=auth_header,
        sync_perm=False,
    )

    new_permission = _update_ldap_group_permission(
        permission=permission,
        allowed=allowed,
        label=label,
        show_tile=show_tile,
        protected=protected,
        sync_perm=sync_perm,
    )

    logger.debug(m18n.n("permission_created", permission=permission))
    return new_permission
示例#11
0
def user_permission_update(
    operation_logger,
    permission,
    add=None,
    remove=None,
    label=None,
    show_tile=None,
    protected=None,
    force=False,
    sync_perm=True,
):
    """
    Allow or Disallow a user or group to a permission for a specific application

    Keyword argument:
        permission     -- Name of the permission (e.g. mail or or wordpress or wordpress.editors)
        add            -- (optional) List of groups or usernames to add to this permission
        remove         -- (optional) List of groups or usernames to remove from to this permission
        label          -- (optional) Define a name for the permission. This label will be shown on the SSO and in the admin
        show_tile      -- (optional) Define if a tile will be shown in the SSO
        protected      -- (optional) Define if the permission can be added/removed to the visitor group
        force          -- (optional) Give the possibility to add/remove access from the visitor group to a protected permission
    """
    from yunohost.user import user_group_list

    # By default, manipulate main permission
    if "." not in permission:
        permission = permission + ".main"

    existing_permission = user_permission_info(permission)

    # Refuse to add "visitors" to mail, xmpp ... they require an account to make sense.
    if add and "visitors" in add and permission.split(".")[0] in SYSTEM_PERMS:
        raise YunohostValidationError("permission_require_account",
                                      permission=permission)

    # Refuse to add "visitors" to protected permission
    if ((add and "visitors" in add and existing_permission["protected"]) or
        (remove and "visitors" in remove
         and existing_permission["protected"])) and not force:
        raise YunohostValidationError("permission_protected",
                                      permission=permission)

    # Fetch currently allowed groups for this permission

    current_allowed_groups = existing_permission["allowed"]
    operation_logger.related_to.append(("app", permission.split(".")[0]))

    # Compute new allowed group list (and make sure what we're doing make sense)

    new_allowed_groups = copy.copy(current_allowed_groups)
    all_existing_groups = user_group_list()["groups"].keys()

    if add:
        groups_to_add = [add] if not isinstance(add, list) else add
        for group in groups_to_add:
            if group not in all_existing_groups:
                raise YunohostValidationError("group_unknown", group=group)
            if group in current_allowed_groups:
                logger.warning(
                    m18n.n("permission_already_allowed",
                           permission=permission,
                           group=group))
            else:
                operation_logger.related_to.append(("group", group))
                new_allowed_groups += [group]

    if remove:
        groups_to_remove = [remove] if not isinstance(remove, list) else remove
        for group in groups_to_remove:
            if group not in current_allowed_groups:
                logger.warning(
                    m18n.n(
                        "permission_already_disallowed",
                        permission=permission,
                        group=group,
                    ))
            else:
                operation_logger.related_to.append(("group", group))

        new_allowed_groups = [
            g for g in new_allowed_groups if g not in groups_to_remove
        ]

    # If we end up with something like allowed groups is ["all_users", "volunteers"]
    # we shall warn the users that they should probably choose between one or
    # the other, because the current situation is probably not what they expect
    # / is temporary ?  Note that it's fine to have ["all_users", "visitors"]
    # though, but it's not fine to have ["all_users", "visitors", "volunteers"]
    if "all_users" in new_allowed_groups and len(new_allowed_groups) >= 2:
        if "visitors" not in new_allowed_groups or len(
                new_allowed_groups) >= 3:
            logger.warning(
                m18n.n("permission_currently_allowed_for_all_users"))

    # Note that we can get this argument as string if we it come from the CLI
    if isinstance(show_tile, str):
        if show_tile.lower() == "true":
            show_tile = True
        else:
            show_tile = False

    if (existing_permission["url"]
            and existing_permission["url"].startswith("re:") and show_tile):
        logger.warning(
            m18n.n(
                "regex_incompatible_with_tile",
                regex=existing_permission["url"],
                permission=permission,
            ))

    # Commit the new allowed group list
    operation_logger.start()

    new_permission = _update_ldap_group_permission(
        permission=permission,
        allowed=new_allowed_groups,
        label=label,
        show_tile=show_tile,
        protected=protected,
        sync_perm=sync_perm,
    )

    logger.debug(m18n.n("permission_updated", permission=permission))

    return new_permission
示例#12
0
def test_update_group_add_user_that_doesnt_exist(mocker):
    with raiseYunohostError(mocker, "user_unknown"):
        user_group_update("dev", add=["doesnt_exist"])

    assert "doesnt_exist" not in user_group_list()["groups"]["dev"]["members"]
示例#13
0
def test_update_group_primary_manually(mocker):
    with raiseYunohostError(mocker, "group_cannot_edit_primary_group"):
        user_group_update("alice", remove=["alice"])

    assert "alice" in user_group_list()["groups"]["alice"]["members"]
示例#14
0
def test_update_group_remove_user_not_already_in(mocker):
    with message(mocker, "group_user_not_in_group", user="******", group="apps"):
        user_group_update("apps", remove=["jack"])

    group_res = user_group_list()["groups"]
    assert group_res["apps"]["members"] == ["bob"]
示例#15
0
def test_update_group_remove_user(mocker):
    with message(mocker, "group_updated", group="apps"):
        user_group_update("apps", remove=["bob"])

    group_res = user_group_list()["groups"]
    assert group_res["apps"]["members"] == []
示例#16
0
def test_update_group_add_user(mocker):
    with message(mocker, "group_updated", group="dev"):
        user_group_update("dev", add=["bob"])

    group_res = user_group_list()["groups"]
    assert set(group_res["dev"]["members"]) == set(["alice", "bob"])