form: fix entities validators order for filter and apply the right default

This commit is contained in:
axolotle 2023-04-18 17:51:21 +02:00
parent dbaea019fe
commit f1038de56d
2 changed files with 19 additions and 20 deletions

View file

@ -1816,9 +1816,7 @@ class TestGroup(BaseTest):
"scenarios": [ "scenarios": [
("custom_group", "custom_group"), ("custom_group", "custom_group"),
*all_as("", None, output="visitors", raw_option={"default": "visitors"}), *all_as("", None, output="visitors", raw_option={"default": "visitors"}),
*xpass(scenarios=[ ("", FAIL, {"default": "custom_group"}), # Not allowed to set a default which is not a default group
("", "custom_group", {"default": "custom_group"}),
], reason="Should throw 'default must be in (None, 'all_users', 'visitors', 'admins')"),
# readonly # readonly
("admins", FAIL, {"readonly": True}), # readonly is forbidden ("admins", FAIL, {"readonly": True}), # readonly is forbidden
] ]
@ -1837,13 +1835,6 @@ class TestGroup(BaseTest):
"prefill": "admins", "prefill": "admins",
} }
) )
# FIXME This should fail, not allowed to set a default which is not a default group
super().test_options_prompted_with_ask_help(
prefill_data={
"raw_option": {"default": "custom_group"},
"prefill": "custom_group",
}
)
def test_scenarios(self, intake, expected_output, raw_option, data): def test_scenarios(self, intake, expected_output, raw_option, data):
with patch_groups(**data): with patch_groups(**data):

View file

@ -951,6 +951,7 @@ ChoosableOptions = Literal[
class BaseChoicesOption(BaseInputOption): class BaseChoicesOption(BaseInputOption):
# FIXME probably forbid choices to be None? # FIXME probably forbid choices to be None?
filter: Union[JSExpression, None] = None # filter before choices
choices: Union[dict[str, Any], list[Any], None] choices: Union[dict[str, Any], list[Any], None]
@validator("choices", pre=True) @validator("choices", pre=True)
@ -1093,6 +1094,7 @@ class TagsOption(BaseChoicesOption):
class DomainOption(BaseChoicesOption): class DomainOption(BaseChoicesOption):
type: Literal[OptionType.domain] = OptionType.domain type: Literal[OptionType.domain] = OptionType.domain
filter: Literal[None] = None
choices: Union[dict[str, str], None] choices: Union[dict[str, str], None]
@validator("choices", pre=True, always=True) @validator("choices", pre=True, always=True)
@ -1108,18 +1110,15 @@ class DomainOption(BaseChoicesOption):
for domain in data["domains"] for domain in data["domains"]
} }
@validator("default") @validator("default", pre=True, always=True)
def inject_default( def inject_default(
cls, value: Union[str, None], values: Values cls, value: Union[str, None], values: Values
) -> Union[str, None]: ) -> Union[str, None]:
# TODO remove calls to resources in validators (pydantic V2 should adress this) # TODO remove calls to resources in validators (pydantic V2 should adress this)
from yunohost.domain import _get_maindomain from yunohost.domain import _get_maindomain
if value is None:
return _get_maindomain() return _get_maindomain()
return value
@staticmethod @staticmethod
def normalize(value, option={}): def normalize(value, option={}):
if value.startswith("https://"): if value.startswith("https://"):
@ -1135,9 +1134,9 @@ class DomainOption(BaseChoicesOption):
class AppOption(BaseChoicesOption): class AppOption(BaseChoicesOption):
type: Literal[OptionType.app] = OptionType.app type: Literal[OptionType.app] = OptionType.app
choices: Union[dict[str, str], None] filter: Union[JSExpression, None] = None
add_yunohost_portal_to_choices: bool = False add_yunohost_portal_to_choices: bool = False
filter: Union[str, None] = None choices: Union[dict[str, str], None]
@validator("choices", pre=True, always=True) @validator("choices", pre=True, always=True)
def inject_apps_choices( def inject_apps_choices(
@ -1172,6 +1171,7 @@ class AppOption(BaseChoicesOption):
class UserOption(BaseChoicesOption): class UserOption(BaseChoicesOption):
type: Literal[OptionType.user] = OptionType.user type: Literal[OptionType.user] = OptionType.user
filter: Literal[None] = None
choices: Union[dict[str, str], None] choices: Union[dict[str, str], None]
@validator("choices", pre=True, always=True) @validator("choices", pre=True, always=True)
@ -1196,19 +1196,19 @@ class UserOption(BaseChoicesOption):
return value return value
@validator("default") @validator("default", pre=True, always=True)
def inject_default( def inject_default(
cls, value: Union[str, None], values: Values cls, value: Union[str, None], values: Values
) -> Union[str, None]: ) -> Union[str, None]:
# TODO remove calls to resources in validators (pydantic V2 should adress this) # TODO remove calls to resources in validators (pydantic V2 should adress this)
from yunohost.domain import _get_maindomain from yunohost.domain import _get_maindomain
from yunohost.user import user_info from yunohost.user import user_list, user_info
if value is None: if value is None:
# FIXME: this code is obsolete with the new admins group # FIXME: this code is obsolete with the new admins group
# Should be replaced by something like "any first user we find in the admin group" # Should be replaced by something like "any first user we find in the admin group"
root_mail = "root@%s" % _get_maindomain() root_mail = "root@%s" % _get_maindomain()
for user in values["choices"].keys(): for user in user_list()["users"].keys():
if root_mail in user_info(user).get("mail-aliases", []): if root_mail in user_info(user).get("mail-aliases", []):
return user return user
@ -1217,6 +1217,7 @@ class UserOption(BaseChoicesOption):
class GroupOption(BaseChoicesOption): class GroupOption(BaseChoicesOption):
type: Literal[OptionType.group] = OptionType.group type: Literal[OptionType.group] = OptionType.group
filter: Literal[None] = None
choices: Union[dict[str, str], None] choices: Union[dict[str, str], None]
default: Union[Literal["visitors", "all_users", "admins"], None] = "all_users" default: Union[Literal["visitors", "all_users", "admins"], None] = "all_users"
@ -1241,6 +1242,13 @@ class GroupOption(BaseChoicesOption):
return {groupname: _human_readable_group(groupname) for groupname in groups} return {groupname: _human_readable_group(groupname) for groupname in groups}
@validator("default", pre=True, always=True)
def inject_default(cls, value: Union[str, None], values: Values) -> str:
# FIXME do we really want to default to something all the time?
if value is None:
return "all_users"
return value
OPTIONS = { OPTIONS = {
OptionType.display_text: DisplayTextOption, OptionType.display_text: DisplayTextOption,