import argparse import os import re from collections.abc import Callable from pathlib import Path from ..errors import ClanError from .sops import get_public_key VALID_SECRET_NAME = re.compile(r"^[a-zA-Z0-9._-]+$") VALID_USER_NAME = re.compile(r"^[a-z_]([a-z0-9_-]{0,31})?$") def secret_name_type(arg_value: str) -> str: if not VALID_SECRET_NAME.match(arg_value): raise argparse.ArgumentTypeError( "Invalid character in secret name. Allowed characters are a-z, A-Z, 0-9, ., -, and _" ) return arg_value def public_or_private_age_key_type(arg_value: str) -> str: if os.path.isfile(arg_value): arg_value = Path(arg_value).read_text().strip() if arg_value.startswith("age1"): return arg_value.strip() if arg_value.startswith("AGE-SECRET-KEY-"): return get_public_key(arg_value) if not arg_value.startswith("age1"): raise ClanError( f"Please provide an age key starting with age1, got: '{arg_value}'" ) return arg_value def group_or_user_name_type(what: str) -> Callable[[str], str]: def name_type(arg_value: str) -> str: if len(arg_value) > 32: raise argparse.ArgumentTypeError( f"{what.capitalize()} name must be less than 32 characters long" ) if not VALID_USER_NAME.match(arg_value): raise argparse.ArgumentTypeError( f"Invalid character in {what} name. Allowed characters are a-z, 0-9, -, and _. Must start with a letter or _" ) return arg_value return name_type user_name_type = group_or_user_name_type("user") group_name_type = group_or_user_name_type("group")