in samtranslator/swagger/swagger.py [0:0]
def set_path_default_apikey_required(self, path: str, required_options_api_key: bool = True) -> None:
"""
Add the ApiKey security as required for each method on this path unless ApiKeyRequired
was defined at the Function/Path/Method level. This is intended to be used to set the
apikey security restriction for all api methods based upon the default configured in the
Serverless API.
:param string path: Path name
:param bool required_options_api_key: Bool of whether to add the ApiKeyRequired
to OPTIONS preflight requests.
"""
for method_name, method_definition in self.iter_on_all_methods_for_path(path): # type: ignore[no-untyped-call]
apikey_security_names = {"api_key", "api_key_false"}
existing_non_apikey_security = []
existing_apikey_security = []
apikey_security = []
# Split existing security into ApiKey and everything else
# (e.g. sigv4 (AWS_IAM), authorizers, NONE (marker for ignoring default authorizer))
# We want to ensure only a single ApiKey security entry exists while keeping everything else
existing_security = method_definition.get("security", [])
if not isinstance(existing_security, list):
raise InvalidDocumentException(
[InvalidTemplateException(f"Type of security for path {path} method {method_name} must be a list")]
)
for security in existing_security:
SwaggerEditor.validate_is_dict(
security,
f"{security} in Security for path {path} method {method_name} is not a valid dictionary.",
)
if apikey_security_names.isdisjoint(security.keys()):
existing_non_apikey_security.append(security)
else:
existing_apikey_security.append(security)
# Check for an existing method level ApiKey setting before applying the default. It would be simpler
# if instead we applied the default first and then simply
# overwrote it if necessary, however, the order in which things get
# applied (Function Api Events first; then Api Resource) complicates it.
# Check if Function/Path/Method specified 'False' for ApiKeyRequired
apikeyfalse_idx = -1
for idx, security in enumerate(existing_apikey_security):
is_none = any(key == "api_key_false" for key in security)
if is_none:
apikeyfalse_idx = idx
break
# api_key_false was found; remove it and don't add default api_key security setting
if apikeyfalse_idx > -1:
del existing_apikey_security[apikeyfalse_idx]
# No existing ApiKey setting found or it's already set to the default
else:
security_dict = Py27Dict()
security_dict["api_key"] = []
apikey_security = [security_dict]
security = existing_non_apikey_security + apikey_security
if method_name == "options" and not required_options_api_key:
security = existing_non_apikey_security
if security != existing_security:
method_definition["security"] = security