Skip to content

Commit

Permalink
Merge pull request #753 from fractal-analytics-platform/752-align-wit…
Browse files Browse the repository at this point in the history
…h-new-set-groups-endpoint

Align with new `set-group` endpoint
  • Loading branch information
ychiucco authored Nov 27, 2024
2 parents 21a58fb + 33ec651 commit 2099f4a
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 9 deletions.
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

0 comments on commit 2099f4a

Please sign in to comment.