Skip to content

Commit

Permalink
REST-API: add include_links and include_extensions to list users
Browse files Browse the repository at this point in the history
Change-Id: I2102be6c5b8b9b1e538eabb6890f0c6bcc06ca7e
JIRA-Ref: CMK-18835
  • Loading branch information
ottermata committed Sep 4, 2024
1 parent 48b2afc commit 05628cf
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 17 deletions.
43 changes: 29 additions & 14 deletions cmk/gui/openapi/endpoints/user_config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
from cmk.gui.fields import Username
from cmk.gui.http import Response
from cmk.gui.logged_in import user
from cmk.gui.openapi.endpoints.common_fields import field_include_extensions, field_include_links
from cmk.gui.openapi.endpoints.user_config.request_schemas import CreateUser, UpdateUser
from cmk.gui.openapi.endpoints.user_config.response_schemas import UserCollection, UserObject
from cmk.gui.openapi.endpoints.utils import complement_customer, update_customer_info
from cmk.gui.openapi.restful_objects import constructors, Endpoint
from cmk.gui.openapi.restful_objects.registry import EndpointRegistry
from cmk.gui.openapi.restful_objects.type_defs import DomainObject
from cmk.gui.openapi.utils import ProblemException, serve_json
from cmk.gui.type_defs import UserSpec
from cmk.gui.userdb import (
Expand Down Expand Up @@ -94,15 +96,19 @@ def show_user(params: Mapping[str, Any]) -> Response:
method="get",
response_schema=UserCollection,
permissions_required=PERMISSIONS,
query_params=[field_include_links(), field_include_extensions()],
)
def list_users(params: Mapping[str, Any]) -> Response:
"""Show all users"""
user.need_permission("wato.users")
users = []
for user_id, attrs in load_users(False).items():
user_attributes = _internal_to_api_format(attrs)
users.append(serialize_user(user_id, complement_customer(user_attributes)))

include_links: bool = params["include_links"]
include_extensions: bool = params["include_extensions"]
users = [
serialize_user(
user_id, spec, include_links=include_links, include_extensions=include_extensions
)
for user_id, spec in load_users(False).items()
]
return serve_json(constructors.collection_object(domain_type="user_config", value=users))


Expand Down Expand Up @@ -182,6 +188,7 @@ def edit_user(params: Mapping[str, Any]) -> Response:
api_attrs = params["body"]

current_attrs = _load_user(username)
constructors.require_etag(constructors.hash_of_dict(current_attrs))
internal_attrs = _api_to_internal_format(current_attrs, api_attrs)

if connector_id := internal_attrs.get("connector"):
Expand Down Expand Up @@ -217,18 +224,26 @@ def _identify_modified_attrs(initial_attrs: UserSpec, new_attrs: dict) -> set[st


def serve_user(user_id):
user_attributes_internal = _load_user(user_id)
user_attributes = _internal_to_api_format(user_attributes_internal)
response = serve_json(serialize_user(user_id, complement_customer(user_attributes)))
return constructors.response_with_etag_created_from_dict(response, user_attributes)


def serialize_user(user_id, attributes):
user_spec = _load_user(user_id)
response = serve_json(serialize_user(user_id, user_spec))
return constructors.response_with_etag_created_from_dict(response, user_spec)


def serialize_user(
user_id: UserId,
user_spec: UserSpec,
*,
include_links: bool = True,
include_extensions: bool = True,
) -> DomainObject:
return constructors.domain_object(
domain_type="user_config",
identifier=user_id,
title=attributes["fullname"],
extensions=attributes,
title=user_spec["alias"],
extensions=(
complement_customer(_internal_to_api_format(user_spec)) if include_extensions else None
),
include_links=include_links,
)


Expand Down
15 changes: 13 additions & 2 deletions tests/testlib/rest_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -623,11 +623,22 @@ def get(
expect_ok=expect_ok,
)

def get_all(self, effective_attributes: bool = False, expect_ok: bool = True) -> Response:
def get_all(
self,
*,
include_links: bool | None = None,
include_extensions: bool | None = None,
expect_ok: bool = True,
) -> Response:
return self.request(
"get",
url=f"/domain-types/{self.domain}/collections/all",
query_params={"effective_attributes": "true" if effective_attributes else "false"},
query_params=_only_set_keys(
{
"include_links": include_links,
"include_extensions": include_extensions,
}
),
expect_ok=expect_ok,
)

Expand Down
26 changes: 25 additions & 1 deletion tests/unit/cmk/gui/openapi/test_openapi_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,14 +239,38 @@ def test_openapi_user_minimal_password_settings(


def test_openapi_all_users(clients: ClientRegistry) -> None:
resp = clients.User.get_all()
resp = clients.User.get_all(include_links=True)
users = resp.json["value"]
assert len(users) == 1

user = clients.User.get(url=users[0]["links"][0]["href"])
assert user.json == users[0]


def test_openapi_list_users_include_links(clients: ClientRegistry) -> None:
default_response = clients.User.get_all()
enabled_response = clients.User.get_all(include_links=True)
disabled_response = clients.User.get_all(include_links=False)

assert len(default_response.json["value"]) > 0

assert default_response.json == disabled_response.json
assert any(bool(value["links"]) for value in enabled_response.json["value"])
assert all(value["links"] == [] for value in disabled_response.json["value"])


def test_openapi_list_users_include_extensions(clients: ClientRegistry) -> None:
default_response = clients.User.get_all()
enabled_response = clients.User.get_all(include_extensions=True)
disabled_response = clients.User.get_all(include_extensions=False)

assert len(default_response.json["value"]) > 0

assert default_response.json == enabled_response.json
assert any(bool(value["extensions"]) for value in enabled_response.json["value"])
assert all("extensions" not in value for value in disabled_response.json["value"])


@managedtest
def test_openapi_user_config(
clients: ClientRegistry,
Expand Down

0 comments on commit 05628cf

Please sign in to comment.