def resolve(function: ValidResolvers, params: Dict, mappings: Dict[str, Dict], conditions: Dict[str, bool]): if function is None or isinstance(function, str): return function if isinstance(function, (int, float, date, bool, IPv4Network, IPv6Network)): return str(function) if isinstance(function, list): result = [] for entry in function: resolved_value = resolve(entry, params, mappings, conditions) if resolved_value != AWS_NOVALUE: result.append(resolved_value) return result if isinstance(function, dict): if is_resolvable_dict(function): function_name = next(iter(function)) function_resolver = FUNCTION_MAPPINGS[function_name] return function_resolver(function[function_name], params, mappings, conditions) result = {} for k, v in function.items(): resolved_value = resolve(v, params, mappings, conditions) if resolved_value != AWS_NOVALUE: result[k] = resolved_value return result raise ValueError(f"Not supported type: {type(function)}")
def build_evaluator(function: str, arg_a: Any, arg_b: Any) -> Callable: if is_resolvable_dict(arg_b) or isinstance(arg_b, FunctionDict): raise StatementConditionBuildEvaluatorError if function == "Bool": return lambda kwargs: kwargs[arg_a] is arg_b elif function == "IpAddress": if not_ip(arg_b): return lambda _: False return lambda kwargs: kwargs[arg_a].subnet_of(arg_b) elif function == "NotIpAddress": if not_ip(arg_b): return lambda _: False return lambda kwargs: not kwargs[arg_a].subnet_of(arg_b) elif function == "Null": return lambda kwargs: (kwargs.get(arg_a) is not None) is arg_b elif function in ("StringEquals", "ArnEquals", "BinaryEquals", "NumericEquals", "DateEquals"): return lambda kwargs: kwargs[arg_a] == arg_b elif function in ("StringNotEquals", "ArnNotEquals", "NumericNotEquals", "DateNotEquals"): return lambda kwargs: kwargs[arg_a] != arg_b elif function in ("NumericLessThan", "DateLessThan"): return lambda kwargs: kwargs[arg_a] < arg_b elif function in ("NumericLessThanEquals", "DateLessThanEquals"): return lambda kwargs: kwargs[arg_a] <= arg_b elif function in ("NumericGreaterThan", "DateGreaterThan"): return lambda kwargs: kwargs[arg_a] > arg_b elif function in ("NumericGreaterThanEquals", "DateGreaterThanEquals"): return lambda kwargs: kwargs[arg_a] >= arg_b elif function == "StringEqualsIgnoreCase": arg_b = normalize("NFKD", arg_b.casefold()) return lambda kwargs: normalize("NFKD", kwargs[arg_a].casefold() ) == arg_b elif function == "StringNotEqualsIgnoreCase": arg_b = normalize("NFKD", arg_b.casefold()) return lambda kwargs: normalize("NFKD", kwargs[arg_a].casefold() ) != arg_b elif function in ("StringLike", "ArnLike"): arg_b = regex_from_cf_string(arg_b) return lambda kwargs: bool(arg_b.match(kwargs[arg_a])) elif function in ("StringNotLike", "ArnNotLike"): arg_b = regex_from_cf_string(arg_b) return lambda kwargs: not bool(arg_b.match(kwargs[arg_a])) else: logger.error(f"{function} is not supported.") raise NotImplementedError
def get_principal_list(self) -> List[ResolvableStr]: """ Gets all actions specified in `Principal` and `NotPrincipal`. Returns: List of principals. """ principal_list = [] for principals in [self.Principal, self.NotPrincipal]: if isinstance(principals, list): principal_list.extend(principals) elif isinstance(principals, str): principal_list.append(principals) elif is_resolvable_dict(principals): principal_list.append(principals) elif isinstance(principals, dict): for value in principals.values(): if isinstance(value, (str, Dict)): principal_list.append(value) elif isinstance(value, List): principal_list.extend(value) elif principals is not None: raise ValueError(f"Not supported type: {type(principals)}") return principal_list
def check_if_valid_function(cls, values): if not is_resolvable_dict(values): raise ValueError("FunctionDict should only have 1 key and be a function") return values