Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Align with new set-group endpoint #753

Merged
merged 10 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Remove (internal) obsolete `do_not_separate_logs` argument (\#738).
* Add `group {add|remove}-user` commands, and deprecate `--new-user-ids` argument from `group update` (\#748).
* Update `user whoami --viewer-paths` to call the new dedicated [server endpoint](https://github.com/fractal-analytics-platform/fractal-server/pull/2096) (\#748).
* Add `user set-groups` commands (\#753).
* Testing:
* Align with fractal-server 2.9.0 removal of `DB_ENGINE` variable (\#743).

Expand Down
8 changes: 8 additions & 0 deletions fractal_client/cmd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from ._user import user_edit
from ._user import user_list
from ._user import user_register
from ._user import user_set_groups
from ._user import user_show
from ._user import user_whoami
from ._workflow import delete_workflow
Expand Down Expand Up @@ -361,6 +362,13 @@ def user(
]
function_kwargs = get_kwargs(parameters, kwargs)
iface = user_edit(client, **function_kwargs)
elif subcmd == "set-groups":
parameters = [
"user_id",
"group_ids",
]
function_kwargs = get_kwargs(parameters, kwargs)
iface = user_set_groups(client, **function_kwargs)
elif subcmd == "whoami":
parameters = ["viewer_paths"]
function_kwargs = get_kwargs(parameters, kwargs)
Expand Down
11 changes: 11 additions & 0 deletions fractal_client/cmd/_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,17 @@ def user_edit(
return Interface(retcode=0, data=new_user_with_settings)


def user_set_groups(
client: AuthClient, *, user_id: int, group_ids: list[int]
) -> Interface:
res = client.post(
f"{settings.FRACTAL_SERVER}/auth/users/{user_id}/set-groups/",
json=dict(group_ids=group_ids),
)
user = check_response(res, expected_status_code=200)
return Interface(retcode=0, data=user)


def user_whoami(
client: AuthClient, *, batch: bool, viewer_paths: bool = False
) -> Interface:
Expand Down
21 changes: 21 additions & 0 deletions fractal_client/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,27 @@
required=False,
)

# user set-groups
user_set_groups_parser = user_subparsers.add_parser(
"set-groups",
description=(
"Reset user-group membership for an existing user."
),
allow_abbrev=False,
)
user_set_groups_parser.add_argument(
"user_id", help="ID of the user.", type=int
)
user_set_groups_parser.add_argument(
"group_ids",
help=(
"List of the IDs of groups we want the user to be member. "
"WARNING: this list replaces the current group memberships."
),
type=int,
nargs="+",
)


# (USER)GROUP GROUP

Expand Down
4 changes: 2 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 11 additions & 7 deletions tests/test_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,18 @@ def test_group_commands(

res = invoke_as_superuser("group list --user-ids")
assert len(res.data) == initial_number_of_groups + 2
assert res.data[0]["id"] == default_group_id
assert len(res.data[0]["user_ids"]) == initial_number_of_users + 3
assert res.data[-2]["id"] == group1_id
assert set(res.data[1]["user_ids"]) == set([user1_id, user2_id])
assert res.data[-1]["id"] == group2_id
assert set(res.data[2]["user_ids"]) == set(
[user3_id, user2_id, superuser_id]
users_default_group = next(
g["user_ids"] for g in res.data if g["id"] == default_group_id
)
assert len(users_default_group) == initial_number_of_users + 3
users_group_1 = next(
g["user_ids"] for g in res.data if g["id"] == group1_id
)
assert set(users_group_1) == set([user1_id, user2_id])
users_group_2 = next(
g["user_ids"] for g in res.data if g["id"] == group2_id
)
assert set(users_group_2) == set([user3_id, user2_id, superuser_id])

# Remove users from group
res = invoke_as_superuser(f"group remove-user {group2_id} {user3_id}")
Expand Down
74 changes: 74 additions & 0 deletions tests/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest
from devtools import debug
from fractal_server.app.security import FRACTAL_DEFAULT_GROUP_NAME

PWD_USER = "1234"

Expand Down Expand Up @@ -383,3 +384,76 @@ def test_whoami_as_superuser(invoke_as_superuser, superuser):
debug(res.data)
assert res.data["email"] == superuser["email"]
assert res.data["is_superuser"]


def test_user_set_groups(invoke_as_superuser, user_factory, new_name):
# get default group
res = invoke_as_superuser("group list --user-ids")
default_group = next(
group
for group in res.data
if group["name"] == FRACTAL_DEFAULT_GROUP_NAME
)
default_group_id = default_group["id"]
# create 2 new users
user1 = user_factory(email=f"{new_name()}@example.org", password="psw1")
assert len(user1["group_ids_names"]) == 1
user1_id = user1["id"]
user2 = user_factory(email=f"{new_name()}@example.org", password="psw2")
assert len(user2["group_ids_names"]) == 1
user2_id = user2["id"]
# create 2 new groups
group1 = invoke_as_superuser(f"group new {new_name()}")
assert len(group1.data["user_ids"]) == 0
group1_id = group1.data["id"]
group2 = invoke_as_superuser(f"group new {new_name()}")
assert len(group2.data["user_ids"]) == 0
group2_id = group2.data["id"]

with pytest.raises(SystemExit):
# no arguments
invoke_as_superuser("user set-groups")
with pytest.raises(SystemExit):
# no group_ids list
invoke_as_superuser(f"user set-groups {user1_id}")
with pytest.raises(SystemExit):
# group_ids must be a list of integers
invoke_as_superuser(f"user set-groups {user1_id} {group1_id} foo")
with pytest.raises(SystemExit):
# there must always be the default group id in group_ids
invoke_as_superuser(f"user set-groups {user1_id} {group1_id}")
with pytest.raises(SystemExit):
# repeated elements in group_ids are forbidden
invoke_as_superuser(
"user set-groups "
f"{user1_id} {default_group_id} {group1_id} {group1_id}"
)

# Add user1 to group1
res = invoke_as_superuser(
f"user set-groups {user1_id} {group1_id} {default_group_id}"
)
assert len(res.data["group_ids_names"]) == 2
group1 = invoke_as_superuser(f"group get {group1_id}")
assert len(group1.data["user_ids"]) == 1

# Add user2 to group1 and group2
res = invoke_as_superuser(
"user set-groups "
f"{user2_id} {group2_id} {group1_id} {default_group_id}"
)
assert len(res.data["group_ids_names"]) == 3
group1 = invoke_as_superuser(f"group get {group1_id}")
assert len(group1.data["user_ids"]) == 2
group2 = invoke_as_superuser(f"group get {group2_id}")
assert len(group2.data["user_ids"]) == 1

# Add user1 to group2 and remove them from group1
res = invoke_as_superuser(
f"user set-groups {user1_id} {group2_id} {default_group_id}"
)
assert len(res.data["group_ids_names"]) == 2
group1 = invoke_as_superuser(f"group get {group1_id}")
assert len(group1.data["user_ids"]) == 1
group2 = invoke_as_superuser(f"group get {group2_id}")
assert len(group2.data["user_ids"]) == 2
Loading