Skip to content
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
6 changes: 6 additions & 0 deletions pybotx/client/users_api/user_from_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class BotXAPISearchUserResult(VerifiedPayloadBaseModel):
user_huid: UUID
ad_login: str | None = None
ad_domain: str | None = None
ad_groups: list[str] = Field(default_factory=list)
openid_roles: list[str] = Field(default_factory=list)
avatar: str | None = None
avatar_preview: str | None = None
name: str
Expand Down Expand Up @@ -53,6 +55,8 @@ def to_domain(self) -> UserFromSearch:
huid=self.result.user_huid,
ad_login=self.result.ad_login,
ad_domain=self.result.ad_domain,
ad_groups=self.result.ad_groups,
openid_roles=self.result.openid_roles,
avatar=self.result.avatar,
avatar_preview=self.result.avatar_preview,
username=self.result.name,
Expand Down Expand Up @@ -87,6 +91,8 @@ def to_domain(self) -> list[UserFromSearch]:
huid=user.user_huid,
ad_login=user.ad_login,
ad_domain=user.ad_domain,
ad_groups=user.ad_groups,
openid_roles=user.openid_roles,
avatar=user.avatar,
avatar_preview=user.avatar_preview,
username=user.name,
Expand Down
10 changes: 9 additions & 1 deletion pybotx/models/users.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from dataclasses import dataclass
from dataclasses import dataclass, field
from datetime import datetime
from uuid import UUID

Expand Down Expand Up @@ -34,6 +34,12 @@ class UserFromSearch:
rts_id: User RTS id.
created_at: User creation timestamp.
updated_at: User update timestamp.
ad_groups: User AD group names. BotX returns them only when the bot has
allow_read_ad_groups enabled. An empty list does not distinguish
no group membership from unavailable data.
openid_roles: User OpenID role names. BotX returns them only when the bot
has allow_read_openid_roles enabled. An empty list does not
distinguish no roles from unavailable data.
"""

huid: UUID
Expand All @@ -60,6 +66,8 @@ class UserFromSearch:
rts_id: UUID | None = None
created_at: datetime | None = None
updated_at: datetime | None = None
ad_groups: list[str] = field(default_factory=list)
openid_roles: list[str] = field(default_factory=list)


@dataclass(slots=True)
Expand Down
6 changes: 6 additions & 0 deletions tests/fixtures/users_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ def user_from_search_with_data_json() -> dict[str, Any]:
"user_huid": "6fafda2c-6505-57a5-a088-25ea5d1d0364",
"ad_login": "ad_user_login",
"ad_domain": "cts.com",
"ad_groups": ["employees", "developers", "vpn-users"],
"openid_roles": ["openid_user", "openid_profile"],
"avatar": (
"https://test-cts.ru/uploads/profile_avatar/fa13e946-121b-52ce-aa92-677b51d19d83/"
"3ebb64d5e2f54e1ab9a3f2ff8096f55a.jpg"
Expand Down Expand Up @@ -50,6 +52,8 @@ def user_from_search_with_data() -> UserFromSearch:
huid=UUID("6fafda2c-6505-57a5-a088-25ea5d1d0364"),
ad_login="ad_user_login",
ad_domain="cts.com",
ad_groups=["employees", "developers", "vpn-users"],
openid_roles=["openid_user", "openid_profile"],
avatar=(
"https://test-cts.ru/uploads/profile_avatar/fa13e946-121b-52ce-aa92-677b51d19d83/"
"3ebb64d5e2f54e1ab9a3f2ff8096f55a.jpg"
Expand Down Expand Up @@ -115,6 +119,8 @@ def user_from_search_without_data() -> UserFromSearch:
huid=UUID("6fafda2c-6505-57a5-a088-25ea5d1d0364"),
ad_login="ad_user_login",
ad_domain="cts.com",
ad_groups=[],
openid_roles=[],
avatar=None,
avatar_preview=None,
username="Bob",
Expand Down
58 changes: 58 additions & 0 deletions tests/models/test_users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from uuid import UUID

from pybotx import UserFromSearch, UserKinds


def test__user_from_search__preserves_existing_positional_arguments() -> None:
user = UserFromSearch(
UUID("6fafda2c-6505-57a5-a088-25ea5d1d0364"),
"alice",
"example.com",
"Alice",
None,
None,
None,
["alice@example.com"],
None,
UserKinds.CTS_USER,
"https://example.com/avatar.png",
"https://example.com/avatar-preview.png",
)

assert user.avatar == "https://example.com/avatar.png"
assert user.avatar_preview == "https://example.com/avatar-preview.png"
assert user.ad_groups == []
assert user.openid_roles == []


def test__user_from_search__group_and_role_defaults_are_independent() -> None:
first = UserFromSearch(
huid=UUID("6fafda2c-6505-57a5-a088-25ea5d1d0364"),
ad_login=None,
ad_domain=None,
username="Alice",
company=None,
company_position=None,
department=None,
emails=[],
other_id=None,
user_kind=UserKinds.CTS_USER,
)
second = UserFromSearch(
huid=UUID("6fafda2c-6505-57a5-a088-25ea5d1d0364"),
ad_login=None,
ad_domain=None,
username="Alice",
company=None,
company_position=None,
department=None,
emails=[],
other_id=None,
user_kind=UserKinds.CTS_USER,
)

first.ad_groups.append("employees")
first.openid_roles.append("reader")

assert second.ad_groups == []
assert second.openid_roles == []