Enforce parameter naming (#3190)

* Enforce parameter naming

Parameters are not allowed to start with `ssm` or `aws`. This commit adds error messages which
correspond exactly to the error messages returned by boto3.

* Fix for Python 2 compatibility

f-strings not supported in Python 2.7
This commit is contained in:
Jordan Reiter 2020-07-28 10:26:59 -04:00 committed by GitHub
parent 97139d4253
commit 28d1d762af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 92 additions and 0 deletions

View File

@ -78,6 +78,13 @@ class InvalidDocumentOperation(JsonRESTError):
)
class AccessDeniedException(JsonRESTError):
code = 400
def __init__(self, message):
super(AccessDeniedException, self).__init__("AccessDeniedException", message)
class InvalidDocumentContent(JsonRESTError):
code = 400

View File

@ -27,6 +27,7 @@ from .exceptions import (
ParameterNotFound,
DocumentAlreadyExists,
InvalidDocumentOperation,
AccessDeniedException,
InvalidDocument,
InvalidDocumentContent,
InvalidDocumentVersion,
@ -1254,6 +1255,23 @@ class SimpleSystemManagerBackend(BaseBackend):
def put_parameter(
self, name, description, value, type, allowed_pattern, keyid, overwrite
):
if name.lower().lstrip("/").startswith("aws") or name.lower().lstrip(
"/"
).startswith("ssm"):
is_path = name.count("/") > 1
if name.lower().startswith("/aws") and is_path:
raise AccessDeniedException(
"No access to reserved parameter name: {name}.".format(name=name)
)
if not is_path:
invalid_prefix_error = 'Parameter name: can\'t be prefixed with "aws" or "ssm" (case-insensitive).'
else:
invalid_prefix_error = (
'Parameter name: can\'t be prefixed with "ssm" (case-insensitive). '
"If formed as a path, it can consist of sub-paths divided by slash symbol; each sub-path can be "
"formed as a mix of letters, numbers and the following 3 symbols .-_"
)
raise ValidationException(invalid_prefix_error)
previous_parameter_versions = self._parameters[name]
if len(previous_parameter_versions) == 0:
previous_parameter = None

View File

@ -299,6 +299,73 @@ def test_put_parameter():
)
@mock_ssm
def test_put_parameter_invalid_names():
client = boto3.client("ssm", region_name="us-east-1")
invalid_prefix_err = (
'Parameter name: can\'t be prefixed with "aws" or "ssm" (case-insensitive).'
)
client.put_parameter.when.called_with(
Name="ssm_test", Value="value", Type="String"
).should.throw(
ClientError, invalid_prefix_err,
)
client.put_parameter.when.called_with(
Name="SSM_TEST", Value="value", Type="String"
).should.throw(
ClientError, invalid_prefix_err,
)
client.put_parameter.when.called_with(
Name="aws_test", Value="value", Type="String"
).should.throw(
ClientError, invalid_prefix_err,
)
client.put_parameter.when.called_with(
Name="AWS_TEST", Value="value", Type="String"
).should.throw(
ClientError, invalid_prefix_err,
)
ssm_path = "/ssm_test/path/to/var"
client.put_parameter.when.called_with(
Name=ssm_path, Value="value", Type="String"
).should.throw(
ClientError,
'Parameter name: can\'t be prefixed with "ssm" (case-insensitive). If formed as a path, it can consist of '
"sub-paths divided by slash symbol; each sub-path can be formed as a mix of letters, numbers and the following "
"3 symbols .-_",
)
ssm_path = "/SSM/PATH/TO/VAR"
client.put_parameter.when.called_with(
Name=ssm_path, Value="value", Type="String"
).should.throw(
ClientError,
'Parameter name: can\'t be prefixed with "ssm" (case-insensitive). If formed as a path, it can consist of '
"sub-paths divided by slash symbol; each sub-path can be formed as a mix of letters, numbers and the following "
"3 symbols .-_",
)
aws_path = "/aws_test/path/to/var"
client.put_parameter.when.called_with(
Name=aws_path, Value="value", Type="String"
).should.throw(
ClientError, "No access to reserved parameter name: {}.".format(aws_path),
)
aws_path = "/AWS/PATH/TO/VAR"
client.put_parameter.when.called_with(
Name=aws_path, Value="value", Type="String"
).should.throw(
ClientError, "No access to reserved parameter name: {}.".format(aws_path),
)
@mock_ssm
def test_put_parameter_china():
client = boto3.client("ssm", region_name="cn-north-1")