add simple pattern validation

This commit is contained in:
axolotle 2023-01-13 12:27:42 +01:00
parent 4680c69b9f
commit 7c2e029f6d
3 changed files with 32 additions and 4 deletions

View file

@ -134,6 +134,11 @@ class Interface(BaseInterface):
else ... # required else ... # required
) )
pattern = param_kwargs.pop("pattern", None)
if pattern:
# FIXME for now throw generic error (need to catch and update text)
param_kwargs["regex"] = pattern
if param_kwargs.pop("file", False): if param_kwargs.pop("file", False):
new_param = param.replace( new_param = param.replace(
annotation=fastapi.UploadFile, annotation=fastapi.UploadFile,

View file

@ -42,6 +42,12 @@ def get_params_doc(docstring: Optional[str]) -> dict[str, str]:
} }
def validate_pattern(pattern: str, value: str, name: str):
if not re.match(pattern, value, re.UNICODE):
raise ValueError(f"'{value}' does'nt match pattern '{pattern}'")
return value
def override_function( def override_function(
func: Callable, func: Callable,
func_signature: inspect.Signature, func_signature: inspect.Signature,
@ -89,10 +95,10 @@ class BaseInterface:
def filter_params(self, params: list[inspect.Parameter]) -> list[inspect.Parameter]: def filter_params(self, params: list[inspect.Parameter]) -> list[inspect.Parameter]:
private = self.local_data.get("private", []) private = self.local_data.get("private", [])
if private: return [
return [param for param in params if param.name not in private] param for param in params
if param.name not in private and param.name != "operation_logger"
return params ]
def api(self, *args, **kwargs): def api(self, *args, **kwargs):
return pass_func return pass_func

View file

@ -17,6 +17,7 @@ from yunohost.interface.base import (
merge_dicts, merge_dicts,
get_params_doc, get_params_doc,
override_function, override_function,
validate_pattern
) )
from yunohost.utils.error import YunohostValidationError from yunohost.utils.error import YunohostValidationError
@ -31,6 +32,18 @@ def print_as_yaml(data: Any):
rprint(Syntax(data, "yaml", background_color="default")) rprint(Syntax(data, "yaml", background_color="default"))
def pattern_validator(pattern: str, name: str):
def inner_validator(ctx: typer.Context, param_: typer.CallbackParam, value: str):
if ctx.resilient_parsing:
return
try:
return validate_pattern(pattern, value, name)
except ValueError as e:
raise typer.BadParameter(str(e))
return inner_validator
class Interface(BaseInterface): class Interface(BaseInterface):
kind = InterfaceKind.CLI kind = InterfaceKind.CLI
instance: typer.Typer instance: typer.Typer
@ -89,6 +102,10 @@ class Interface(BaseInterface):
param_kwargs["confirmation_prompt"] = True param_kwargs["confirmation_prompt"] = True
param_kwargs["hide_input"] = True param_kwargs["hide_input"] = True
pattern = param_kwargs.pop("pattern", None)
if pattern:
param_kwargs["callback"] = pattern_validator(pattern, param.name)
# Populate default param value with typer.Argument|Option # Populate default param value with typer.Argument|Option
if param_kwargs.pop("file", False): if param_kwargs.pop("file", False):
new_param = param.replace( new_param = param.replace(