mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
form:UserOption: merge choices and default into root validator with first admin user as default
This commit is contained in:
parent
4a270b88b6
commit
650c0136f2
2 changed files with 25 additions and 56 deletions
|
@ -1449,6 +1449,7 @@ class TestSelect(BaseTest):
|
|||
# │ TAGS │
|
||||
# ╰───────────────────────────────────────────────────────╯
|
||||
|
||||
|
||||
# [], ["one"], {}
|
||||
class TestTags(BaseTest):
|
||||
raw_option = {"type": "tags", "id": "tags_id"}
|
||||
|
@ -1678,47 +1679,29 @@ class TestApp(BaseTest):
|
|||
|
||||
admin_username = "admin_user"
|
||||
admin_user = {
|
||||
"ssh_allowed": False,
|
||||
"username": admin_username,
|
||||
"mailbox-quota": "0",
|
||||
"mail": "a@ynh.local",
|
||||
"mail-aliases": [f"root@{main_domain}"], # Faking "admin"
|
||||
"fullname": "john doe",
|
||||
"group": [],
|
||||
"groups": ["admins"],
|
||||
}
|
||||
regular_username = "normal_user"
|
||||
regular_user = {
|
||||
"ssh_allowed": False,
|
||||
"username": regular_username,
|
||||
"mailbox-quota": "0",
|
||||
"mail": "z@ynh.local",
|
||||
"fullname": "john doe",
|
||||
"group": [],
|
||||
"groups": [],
|
||||
}
|
||||
|
||||
|
||||
@contextmanager
|
||||
def patch_users(
|
||||
*,
|
||||
users,
|
||||
admin_username,
|
||||
main_domain,
|
||||
):
|
||||
def patch_users(*, users):
|
||||
"""
|
||||
Data mocking for UserOption:
|
||||
- yunohost.user.user_list
|
||||
- yunohost.user.user_info
|
||||
- yunohost.domain._get_maindomain
|
||||
"""
|
||||
admin_info = next(
|
||||
(user for user in users.values() if user["username"] == admin_username),
|
||||
{"mail-aliases": []},
|
||||
)
|
||||
with patch.object(user, "user_list", return_value={"users": users}), patch.object(
|
||||
user,
|
||||
"user_info",
|
||||
return_value=admin_info, # Faking admin user
|
||||
), patch.object(domain, "_get_maindomain", return_value=main_domain):
|
||||
with patch.object(user, "user_list", return_value={"users": users}):
|
||||
yield
|
||||
|
||||
|
||||
|
@ -1729,8 +1712,8 @@ class TestUser(BaseTest):
|
|||
# No tests for empty users since it should not happens
|
||||
{
|
||||
"data": [
|
||||
{"users": {admin_username: admin_user}, "admin_username": admin_username, "main_domain": main_domain},
|
||||
{"users": {admin_username: admin_user, regular_username: regular_user}, "admin_username": admin_username, "main_domain": main_domain},
|
||||
{"users": {admin_username: admin_user}},
|
||||
{"users": {admin_username: admin_user, regular_username: regular_user}},
|
||||
],
|
||||
"scenarios": [
|
||||
# FIXME User option is not really nullable, even if optional
|
||||
|
@ -1741,7 +1724,7 @@ class TestUser(BaseTest):
|
|||
},
|
||||
{
|
||||
"data": [
|
||||
{"users": {admin_username: admin_user, regular_username: regular_user}, "admin_username": admin_username, "main_domain": main_domain},
|
||||
{"users": {admin_username: admin_user, regular_username: regular_user}},
|
||||
],
|
||||
"scenarios": [
|
||||
*xpass(scenarios=[
|
||||
|
@ -1756,18 +1739,12 @@ class TestUser(BaseTest):
|
|||
|
||||
@pytest.mark.usefixtures("patch_no_tty")
|
||||
def test_basic_attrs(self):
|
||||
with patch_users(
|
||||
users={admin_username: admin_user},
|
||||
admin_username=admin_username,
|
||||
main_domain=main_domain,
|
||||
):
|
||||
with patch_users(users={admin_username: admin_user}):
|
||||
self._test_basic_attrs()
|
||||
|
||||
def test_options_prompted_with_ask_help(self, prefill_data=None):
|
||||
with patch_users(
|
||||
users={admin_username: admin_user, regular_username: regular_user},
|
||||
admin_username=admin_username,
|
||||
main_domain=main_domain,
|
||||
users={admin_username: admin_user, regular_username: regular_user}
|
||||
):
|
||||
super().test_options_prompted_with_ask_help(
|
||||
prefill_data={"raw_option": {}, "prefill": admin_username}
|
||||
|
|
|
@ -46,6 +46,7 @@ from pydantic import (
|
|||
ValidationError,
|
||||
create_model,
|
||||
validator,
|
||||
root_validator,
|
||||
)
|
||||
from pydantic.color import Color
|
||||
from pydantic.fields import Field
|
||||
|
@ -1705,43 +1706,34 @@ class UserOption(BaseChoicesOption):
|
|||
filter: Literal[None] = None
|
||||
choices: Union[dict[str, str], None]
|
||||
|
||||
@validator("choices", pre=True, always=True)
|
||||
def inject_users_choices(
|
||||
cls, value: Union[dict[str, str], None], values: Values
|
||||
) -> dict[str, str]:
|
||||
@root_validator(pre=True)
|
||||
def inject_users_choices_and_default(cls, values: Values) -> Values:
|
||||
# TODO remove calls to resources in validators (pydantic V2 should adress this)
|
||||
from yunohost.user import user_list
|
||||
|
||||
value = {
|
||||
users = user_list(fields=["username", "fullname", "mail", "groups"])["users"]
|
||||
|
||||
values["choices"] = {
|
||||
username: f"{infos['fullname']} ({infos['mail']})"
|
||||
for username, infos in user_list()["users"].items()
|
||||
for username, infos in users.items()
|
||||
}
|
||||
|
||||
# FIXME keep this to test if any user, do not raise error if no admin?
|
||||
if not value:
|
||||
if not values["choices"]:
|
||||
raise YunohostValidationError(
|
||||
"app_argument_invalid",
|
||||
name=values["id"],
|
||||
error="You should create a YunoHost user first.",
|
||||
)
|
||||
|
||||
return value
|
||||
if not values.get("default"):
|
||||
values["default"] = next(
|
||||
username
|
||||
for username, infos in users.items()
|
||||
if "admins" in infos["groups"]
|
||||
)
|
||||
|
||||
@validator("default", pre=True, always=True)
|
||||
def inject_default(
|
||||
cls, value: Union[str, None], values: Values
|
||||
) -> Union[str, None]:
|
||||
# TODO remove calls to resources in validators (pydantic V2 should adress this)
|
||||
# from yunohost.domain import _get_maindomain
|
||||
# from yunohost.user import user_list, user_info
|
||||
|
||||
if value is None:
|
||||
# FIXME : in the past we looked for the user holding the "root@" alias
|
||||
# but it's now obsolete...
|
||||
# Should be replaced by something like "any first user we find in the admin group"
|
||||
pass
|
||||
|
||||
return value
|
||||
return values
|
||||
|
||||
|
||||
class GroupOption(BaseChoicesOption):
|
||||
|
|
Loading…
Add table
Reference in a new issue