black format
This commit is contained in:
parent
89c43820c9
commit
78e2714496
@ -2362,7 +2362,7 @@
|
|||||||
- [ ] send_ssh_public_key
|
- [ ] send_ssh_public_key
|
||||||
|
|
||||||
## ecr
|
## ecr
|
||||||
30% implemented
|
27% implemented
|
||||||
- [ ] batch_check_layer_availability
|
- [ ] batch_check_layer_availability
|
||||||
- [X] batch_delete_image
|
- [X] batch_delete_image
|
||||||
- [X] batch_get_image
|
- [X] batch_get_image
|
||||||
@ -2371,6 +2371,7 @@
|
|||||||
- [ ] delete_lifecycle_policy
|
- [ ] delete_lifecycle_policy
|
||||||
- [X] delete_repository
|
- [X] delete_repository
|
||||||
- [ ] delete_repository_policy
|
- [ ] delete_repository_policy
|
||||||
|
- [ ] describe_image_scan_findings
|
||||||
- [X] describe_images
|
- [X] describe_images
|
||||||
- [X] describe_repositories
|
- [X] describe_repositories
|
||||||
- [ ] get_authorization_token
|
- [ ] get_authorization_token
|
||||||
@ -2382,9 +2383,11 @@
|
|||||||
- [X] list_images
|
- [X] list_images
|
||||||
- [ ] list_tags_for_resource
|
- [ ] list_tags_for_resource
|
||||||
- [X] put_image
|
- [X] put_image
|
||||||
|
- [ ] put_image_scanning_configuration
|
||||||
- [ ] put_image_tag_mutability
|
- [ ] put_image_tag_mutability
|
||||||
- [ ] put_lifecycle_policy
|
- [ ] put_lifecycle_policy
|
||||||
- [ ] set_repository_policy
|
- [ ] set_repository_policy
|
||||||
|
- [ ] start_image_scan
|
||||||
- [ ] start_lifecycle_policy_preview
|
- [ ] start_lifecycle_policy_preview
|
||||||
- [ ] tag_resource
|
- [ ] tag_resource
|
||||||
- [ ] untag_resource
|
- [ ] untag_resource
|
||||||
@ -2475,6 +2478,7 @@
|
|||||||
- [ ] authorize_cache_security_group_ingress
|
- [ ] authorize_cache_security_group_ingress
|
||||||
- [ ] batch_apply_update_action
|
- [ ] batch_apply_update_action
|
||||||
- [ ] batch_stop_update_action
|
- [ ] batch_stop_update_action
|
||||||
|
- [ ] complete_migration
|
||||||
- [ ] copy_snapshot
|
- [ ] copy_snapshot
|
||||||
- [ ] create_cache_cluster
|
- [ ] create_cache_cluster
|
||||||
- [ ] create_cache_parameter_group
|
- [ ] create_cache_parameter_group
|
||||||
@ -2516,6 +2520,7 @@
|
|||||||
- [ ] remove_tags_from_resource
|
- [ ] remove_tags_from_resource
|
||||||
- [ ] reset_cache_parameter_group
|
- [ ] reset_cache_parameter_group
|
||||||
- [ ] revoke_cache_security_group_ingress
|
- [ ] revoke_cache_security_group_ingress
|
||||||
|
- [ ] start_migration
|
||||||
- [ ] test_failover
|
- [ ] test_failover
|
||||||
|
|
||||||
## elasticbeanstalk
|
## elasticbeanstalk
|
||||||
@ -3262,7 +3267,8 @@
|
|||||||
- [ ] describe_events
|
- [ ] describe_events
|
||||||
|
|
||||||
## iam
|
## iam
|
||||||
61% implemented- [ ] add_client_id_to_open_id_connect_provider
|
62% implemented
|
||||||
|
- [ ] add_client_id_to_open_id_connect_provider
|
||||||
- [X] add_role_to_instance_profile
|
- [X] add_role_to_instance_profile
|
||||||
- [X] add_user_to_group
|
- [X] add_user_to_group
|
||||||
- [X] attach_group_policy
|
- [X] attach_group_policy
|
||||||
|
@ -127,13 +127,11 @@ class InvalidInput(RESTError):
|
|||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
super(InvalidInput, self).__init__(
|
super(InvalidInput, self).__init__("InvalidInput", message)
|
||||||
'InvalidInput', message)
|
|
||||||
|
|
||||||
|
|
||||||
class NoSuchEntity(RESTError):
|
class NoSuchEntity(RESTError):
|
||||||
code = 404
|
code = 404
|
||||||
|
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
super(NoSuchEntity, self).__init__(
|
super(NoSuchEntity, self).__init__("NoSuchEntity", message)
|
||||||
'NoSuchEntity', message)
|
|
||||||
|
@ -654,12 +654,22 @@ class User(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class AccountPasswordPolicy(BaseModel):
|
class AccountPasswordPolicy(BaseModel):
|
||||||
|
def __init__(
|
||||||
def __init__(self, allow_change_password, hard_expiry, max_password_age, minimum_password_length,
|
self,
|
||||||
password_reuse_prevention, require_lowercase_characters, require_numbers,
|
allow_change_password,
|
||||||
require_symbols, require_uppercase_characters):
|
hard_expiry,
|
||||||
|
max_password_age,
|
||||||
|
minimum_password_length,
|
||||||
|
password_reuse_prevention,
|
||||||
|
require_lowercase_characters,
|
||||||
|
require_numbers,
|
||||||
|
require_symbols,
|
||||||
|
require_uppercase_characters,
|
||||||
|
):
|
||||||
self._errors = []
|
self._errors = []
|
||||||
self._validate(max_password_age, minimum_password_length, password_reuse_prevention)
|
self._validate(
|
||||||
|
max_password_age, minimum_password_length, password_reuse_prevention
|
||||||
|
)
|
||||||
|
|
||||||
self.allow_users_to_change_password = allow_change_password
|
self.allow_users_to_change_password = allow_change_password
|
||||||
self.hard_expiry = hard_expiry
|
self.hard_expiry = hard_expiry
|
||||||
@ -675,35 +685,41 @@ class AccountPasswordPolicy(BaseModel):
|
|||||||
def expire_passwords(self):
|
def expire_passwords(self):
|
||||||
return True if self.max_password_age and self.max_password_age > 0 else False
|
return True if self.max_password_age and self.max_password_age > 0 else False
|
||||||
|
|
||||||
def _validate(self, max_password_age, minimum_password_length, password_reuse_prevention):
|
def _validate(
|
||||||
|
self, max_password_age, minimum_password_length, password_reuse_prevention
|
||||||
|
):
|
||||||
if minimum_password_length > 128:
|
if minimum_password_length > 128:
|
||||||
self._errors.append(self._format_error(
|
self._errors.append(
|
||||||
key='minimumPasswordLength',
|
self._format_error(
|
||||||
value=minimum_password_length,
|
key="minimumPasswordLength",
|
||||||
constraint='Member must have value less than or equal to 128'
|
value=minimum_password_length,
|
||||||
))
|
constraint="Member must have value less than or equal to 128",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if password_reuse_prevention and password_reuse_prevention > 24:
|
if password_reuse_prevention and password_reuse_prevention > 24:
|
||||||
self._errors.append(self._format_error(
|
self._errors.append(
|
||||||
key='passwordReusePrevention',
|
self._format_error(
|
||||||
value=password_reuse_prevention,
|
key="passwordReusePrevention",
|
||||||
constraint='Member must have value less than or equal to 24'
|
value=password_reuse_prevention,
|
||||||
))
|
constraint="Member must have value less than or equal to 24",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
if max_password_age and max_password_age > 1095:
|
if max_password_age and max_password_age > 1095:
|
||||||
self._errors.append(self._format_error(
|
self._errors.append(
|
||||||
key='maxPasswordAge',
|
self._format_error(
|
||||||
value=max_password_age,
|
key="maxPasswordAge",
|
||||||
constraint='Member must have value less than or equal to 1095'
|
value=max_password_age,
|
||||||
))
|
constraint="Member must have value less than or equal to 1095",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self._raise_errors()
|
self._raise_errors()
|
||||||
|
|
||||||
def _format_error(self, key, value, constraint):
|
def _format_error(self, key, value, constraint):
|
||||||
return 'Value "{value}" at "{key}" failed to satisfy constraint: {constraint}'.format(
|
return 'Value "{value}" at "{key}" failed to satisfy constraint: {constraint}'.format(
|
||||||
constraint=constraint,
|
constraint=constraint, key=key, value=value,
|
||||||
key=key,
|
|
||||||
value=value,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def _raise_errors(self):
|
def _raise_errors(self):
|
||||||
@ -713,9 +729,11 @@ class AccountPasswordPolicy(BaseModel):
|
|||||||
errors = "; ".join(self._errors)
|
errors = "; ".join(self._errors)
|
||||||
self._errors = [] # reset collected errors
|
self._errors = [] # reset collected errors
|
||||||
|
|
||||||
raise ValidationError('{count} validation error{plural} detected: {errors}'.format(
|
raise ValidationError(
|
||||||
count=count, plural=plural, errors=errors,
|
"{count} validation error{plural} detected: {errors}".format(
|
||||||
))
|
count=count, plural=plural, errors=errors,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class IAMBackend(BaseBackend):
|
class IAMBackend(BaseBackend):
|
||||||
@ -1657,9 +1675,18 @@ class IAMBackend(BaseBackend):
|
|||||||
def list_open_id_connect_providers(self):
|
def list_open_id_connect_providers(self):
|
||||||
return list(self.open_id_providers.keys())
|
return list(self.open_id_providers.keys())
|
||||||
|
|
||||||
def update_account_password_policy(self, allow_change_password, hard_expiry, max_password_age, minimum_password_length,
|
def update_account_password_policy(
|
||||||
password_reuse_prevention, require_lowercase_characters, require_numbers,
|
self,
|
||||||
require_symbols, require_uppercase_characters):
|
allow_change_password,
|
||||||
|
hard_expiry,
|
||||||
|
max_password_age,
|
||||||
|
minimum_password_length,
|
||||||
|
password_reuse_prevention,
|
||||||
|
require_lowercase_characters,
|
||||||
|
require_numbers,
|
||||||
|
require_symbols,
|
||||||
|
require_uppercase_characters,
|
||||||
|
):
|
||||||
self.account_password_policy = AccountPasswordPolicy(
|
self.account_password_policy = AccountPasswordPolicy(
|
||||||
allow_change_password,
|
allow_change_password,
|
||||||
hard_expiry,
|
hard_expiry,
|
||||||
@ -1669,18 +1696,24 @@ class IAMBackend(BaseBackend):
|
|||||||
require_lowercase_characters,
|
require_lowercase_characters,
|
||||||
require_numbers,
|
require_numbers,
|
||||||
require_symbols,
|
require_symbols,
|
||||||
require_uppercase_characters
|
require_uppercase_characters,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_account_password_policy(self):
|
def get_account_password_policy(self):
|
||||||
if not self.account_password_policy:
|
if not self.account_password_policy:
|
||||||
raise NoSuchEntity('The Password Policy with domain name {} cannot be found.'.format(ACCOUNT_ID))
|
raise NoSuchEntity(
|
||||||
|
"The Password Policy with domain name {} cannot be found.".format(
|
||||||
|
ACCOUNT_ID
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return self.account_password_policy
|
return self.account_password_policy
|
||||||
|
|
||||||
def delete_account_password_policy(self):
|
def delete_account_password_policy(self):
|
||||||
if not self.account_password_policy:
|
if not self.account_password_policy:
|
||||||
raise NoSuchEntity('The account policy with name PasswordPolicy cannot be found.')
|
raise NoSuchEntity(
|
||||||
|
"The account policy with name PasswordPolicy cannot be found."
|
||||||
|
)
|
||||||
|
|
||||||
self.account_password_policy = None
|
self.account_password_policy = None
|
||||||
|
|
||||||
|
@ -839,20 +839,33 @@ class IamResponse(BaseResponse):
|
|||||||
return template.render(open_id_provider_arns=open_id_provider_arns)
|
return template.render(open_id_provider_arns=open_id_provider_arns)
|
||||||
|
|
||||||
def update_account_password_policy(self):
|
def update_account_password_policy(self):
|
||||||
allow_change_password = self._get_bool_param('AllowUsersToChangePassword', False)
|
allow_change_password = self._get_bool_param(
|
||||||
hard_expiry = self._get_bool_param('HardExpiry')
|
"AllowUsersToChangePassword", False
|
||||||
max_password_age = self._get_int_param('MaxPasswordAge')
|
)
|
||||||
minimum_password_length = self._get_int_param('MinimumPasswordLength', 6)
|
hard_expiry = self._get_bool_param("HardExpiry")
|
||||||
password_reuse_prevention = self._get_int_param('PasswordReusePrevention')
|
max_password_age = self._get_int_param("MaxPasswordAge")
|
||||||
require_lowercase_characters = self._get_bool_param('RequireLowercaseCharacters', False)
|
minimum_password_length = self._get_int_param("MinimumPasswordLength", 6)
|
||||||
require_numbers = self._get_bool_param('RequireNumbers', False)
|
password_reuse_prevention = self._get_int_param("PasswordReusePrevention")
|
||||||
require_symbols = self._get_bool_param('RequireSymbols', False)
|
require_lowercase_characters = self._get_bool_param(
|
||||||
require_uppercase_characters = self._get_bool_param('RequireUppercaseCharacters', False)
|
"RequireLowercaseCharacters", False
|
||||||
|
)
|
||||||
|
require_numbers = self._get_bool_param("RequireNumbers", False)
|
||||||
|
require_symbols = self._get_bool_param("RequireSymbols", False)
|
||||||
|
require_uppercase_characters = self._get_bool_param(
|
||||||
|
"RequireUppercaseCharacters", False
|
||||||
|
)
|
||||||
|
|
||||||
iam_backend.update_account_password_policy(
|
iam_backend.update_account_password_policy(
|
||||||
allow_change_password, hard_expiry, max_password_age, minimum_password_length,
|
allow_change_password,
|
||||||
password_reuse_prevention, require_lowercase_characters, require_numbers,
|
hard_expiry,
|
||||||
require_symbols, require_uppercase_characters)
|
max_password_age,
|
||||||
|
minimum_password_length,
|
||||||
|
password_reuse_prevention,
|
||||||
|
require_lowercase_characters,
|
||||||
|
require_numbers,
|
||||||
|
require_symbols,
|
||||||
|
require_uppercase_characters,
|
||||||
|
)
|
||||||
|
|
||||||
template = self.response_template(UPDATE_ACCOUNT_PASSWORD_POLICY_TEMPLATE)
|
template = self.response_template(UPDATE_ACCOUNT_PASSWORD_POLICY_TEMPLATE)
|
||||||
return template.render()
|
return template.render()
|
||||||
|
@ -2199,45 +2199,45 @@ def test_list_open_id_connect_providers():
|
|||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
def test_update_account_password_policy():
|
def test_update_account_password_policy():
|
||||||
client = boto3.client('iam', region_name='us-east-1')
|
client = boto3.client("iam", region_name="us-east-1")
|
||||||
|
|
||||||
client.update_account_password_policy()
|
client.update_account_password_policy()
|
||||||
|
|
||||||
response = client.get_account_password_policy()
|
response = client.get_account_password_policy()
|
||||||
response['PasswordPolicy'].should.equal({
|
response["PasswordPolicy"].should.equal(
|
||||||
'AllowUsersToChangePassword': False,
|
{
|
||||||
'ExpirePasswords': False,
|
"AllowUsersToChangePassword": False,
|
||||||
'MinimumPasswordLength': 6,
|
"ExpirePasswords": False,
|
||||||
'RequireLowercaseCharacters': False,
|
"MinimumPasswordLength": 6,
|
||||||
'RequireNumbers': False,
|
"RequireLowercaseCharacters": False,
|
||||||
'RequireSymbols': False,
|
"RequireNumbers": False,
|
||||||
'RequireUppercaseCharacters': False
|
"RequireSymbols": False,
|
||||||
})
|
"RequireUppercaseCharacters": False,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
def test_update_account_password_policy_errors():
|
def test_update_account_password_policy_errors():
|
||||||
client = boto3.client('iam', region_name='us-east-1')
|
client = boto3.client("iam", region_name="us-east-1")
|
||||||
|
|
||||||
client.update_account_password_policy.when.called_with(
|
client.update_account_password_policy.when.called_with(
|
||||||
MaxPasswordAge=1096,
|
MaxPasswordAge=1096, MinimumPasswordLength=129, PasswordReusePrevention=25
|
||||||
MinimumPasswordLength=129,
|
|
||||||
PasswordReusePrevention=25
|
|
||||||
).should.throw(
|
).should.throw(
|
||||||
ClientError,
|
ClientError,
|
||||||
'3 validation errors detected: '
|
"3 validation errors detected: "
|
||||||
'Value "129" at "minimumPasswordLength" failed to satisfy constraint: '
|
'Value "129" at "minimumPasswordLength" failed to satisfy constraint: '
|
||||||
'Member must have value less than or equal to 128; '
|
"Member must have value less than or equal to 128; "
|
||||||
'Value "25" at "passwordReusePrevention" failed to satisfy constraint: '
|
'Value "25" at "passwordReusePrevention" failed to satisfy constraint: '
|
||||||
'Member must have value less than or equal to 24; '
|
"Member must have value less than or equal to 24; "
|
||||||
'Value "1096" at "maxPasswordAge" failed to satisfy constraint: '
|
'Value "1096" at "maxPasswordAge" failed to satisfy constraint: '
|
||||||
'Member must have value less than or equal to 1095'
|
"Member must have value less than or equal to 1095",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
def test_get_account_password_policy():
|
def test_get_account_password_policy():
|
||||||
client = boto3.client('iam', region_name='us-east-1')
|
client = boto3.client("iam", region_name="us-east-1")
|
||||||
client.update_account_password_policy(
|
client.update_account_password_policy(
|
||||||
AllowUsersToChangePassword=True,
|
AllowUsersToChangePassword=True,
|
||||||
HardExpiry=True,
|
HardExpiry=True,
|
||||||
@ -2247,57 +2247,58 @@ def test_get_account_password_policy():
|
|||||||
RequireLowercaseCharacters=True,
|
RequireLowercaseCharacters=True,
|
||||||
RequireNumbers=True,
|
RequireNumbers=True,
|
||||||
RequireSymbols=True,
|
RequireSymbols=True,
|
||||||
RequireUppercaseCharacters=True
|
RequireUppercaseCharacters=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
response = client.get_account_password_policy()
|
response = client.get_account_password_policy()
|
||||||
|
|
||||||
response['PasswordPolicy'].should.equal({
|
response["PasswordPolicy"].should.equal(
|
||||||
'AllowUsersToChangePassword': True,
|
{
|
||||||
'ExpirePasswords': True,
|
"AllowUsersToChangePassword": True,
|
||||||
'HardExpiry': True,
|
"ExpirePasswords": True,
|
||||||
'MaxPasswordAge': 60,
|
"HardExpiry": True,
|
||||||
'MinimumPasswordLength': 10,
|
"MaxPasswordAge": 60,
|
||||||
'PasswordReusePrevention': 3,
|
"MinimumPasswordLength": 10,
|
||||||
'RequireLowercaseCharacters': True,
|
"PasswordReusePrevention": 3,
|
||||||
'RequireNumbers': True,
|
"RequireLowercaseCharacters": True,
|
||||||
'RequireSymbols': True,
|
"RequireNumbers": True,
|
||||||
'RequireUppercaseCharacters': True
|
"RequireSymbols": True,
|
||||||
})
|
"RequireUppercaseCharacters": True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
def test_get_account_password_policy_errors():
|
def test_get_account_password_policy_errors():
|
||||||
client = boto3.client('iam', region_name='us-east-1')
|
client = boto3.client("iam", region_name="us-east-1")
|
||||||
|
|
||||||
client.get_account_password_policy.when.called_with().should.throw(
|
client.get_account_password_policy.when.called_with().should.throw(
|
||||||
ClientError,
|
ClientError,
|
||||||
'The Password Policy with domain name 123456789012 cannot be found.'
|
"The Password Policy with domain name 123456789012 cannot be found.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
def test_delete_account_password_policy():
|
def test_delete_account_password_policy():
|
||||||
client = boto3.client('iam', region_name='us-east-1')
|
client = boto3.client("iam", region_name="us-east-1")
|
||||||
client.update_account_password_policy()
|
client.update_account_password_policy()
|
||||||
|
|
||||||
response = client.get_account_password_policy()
|
response = client.get_account_password_policy()
|
||||||
|
|
||||||
response.should.have.key('PasswordPolicy').which.should.be.a(dict)
|
response.should.have.key("PasswordPolicy").which.should.be.a(dict)
|
||||||
|
|
||||||
client.delete_account_password_policy()
|
client.delete_account_password_policy()
|
||||||
|
|
||||||
client.get_account_password_policy.when.called_with().should.throw(
|
client.get_account_password_policy.when.called_with().should.throw(
|
||||||
ClientError,
|
ClientError,
|
||||||
'The Password Policy with domain name 123456789012 cannot be found.'
|
"The Password Policy with domain name 123456789012 cannot be found.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@mock_iam
|
@mock_iam
|
||||||
def test_delete_account_password_policy_errors():
|
def test_delete_account_password_policy_errors():
|
||||||
client = boto3.client('iam', region_name='us-east-1')
|
client = boto3.client("iam", region_name="us-east-1")
|
||||||
|
|
||||||
client.delete_account_password_policy.when.called_with().should.throw(
|
client.delete_account_password_policy.when.called_with().should.throw(
|
||||||
ClientError,
|
ClientError, "The account policy with name PasswordPolicy cannot be found."
|
||||||
'The account policy with name PasswordPolicy cannot be found.'
|
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user