From e94a3e39dfb68c4e8a96cd6e88e4fbc502799439 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?c=C4=83t=C4=83lin?= Date: Fri, 23 Jul 2021 11:49:52 +0200 Subject: [PATCH 1/2] Add validity dates to IoT fakecerts --- moto/iot/models.py | 163 ++++++++++++++++++++++-------------------- moto/iot/responses.py | 2 +- 2 files changed, 85 insertions(+), 80 deletions(-) diff --git a/moto/iot/models.py b/moto/iot/models.py index 17ea65dc..ba311094 100644 --- a/moto/iot/models.py +++ b/moto/iot/models.py @@ -12,6 +12,7 @@ from datetime import datetime from boto3 import Session from moto.core import BaseBackend, BaseModel +from moto.utilities.utils import random_string from .exceptions import ( CertificateStateException, DeleteConflictException, @@ -21,7 +22,6 @@ from .exceptions import ( VersionConflictException, ResourceAlreadyExistsException, ) -from moto.utilities.utils import random_string class FakeThing(BaseModel): @@ -73,12 +73,12 @@ class FakeThingType(BaseModel): class FakeThingGroup(BaseModel): def __init__( - self, - thing_group_name, - parent_group_name, - thing_group_properties, - region_name, - thing_groups, + self, + thing_group_name, + parent_group_name, + thing_group_properties, + region_name, + thing_groups, ): self.region_name = region_name self.thing_group_name = thing_group_name @@ -144,7 +144,8 @@ class FakeCertificate(BaseModel): self.transfer_data = {} self.creation_date = time.time() self.last_modified_date = self.creation_date - + self.validity_not_before = (time.time() - 86400) + self.validity_not_after = (time.time() + 86400) self.ca_certificate_id = None self.ca_certificate_pem = ca_certificate_pem if ca_certificate_pem: @@ -174,6 +175,10 @@ class FakeCertificate(BaseModel): "ownedBy": self.owner, "creationDate": self.creation_date, "lastModifiedDate": self.last_modified_date, + "validity": { + "notBefore": self.validity_not_before, + "notAfter": self.validity_not_after + }, "transferData": self.transfer_data, } @@ -250,17 +255,17 @@ class FakeJob(BaseModel): JOB_ID_REGEX = re.compile(JOB_ID_REGEX_PATTERN) def __init__( - self, - job_id, - targets, - document_source, - document, - description, - presigned_url_config, - target_selection, - job_executions_rollout_config, - document_parameters, - region_name, + self, + job_id, + targets, + document_source, + document, + description, + presigned_url_config, + target_selection, + job_executions_rollout_config, + document_parameters, + region_name, ): if not self._job_id_matcher(self.JOB_ID_REGEX, job_id): raise InvalidRequestException() @@ -326,12 +331,12 @@ class FakeJob(BaseModel): class FakeJobExecution(BaseModel): def __init__( - self, - job_id, - thing_arn, - status="QUEUED", - force_canceled=False, - status_details_map={}, + self, + job_id, + thing_arn, + status="QUEUED", + force_canceled=False, + status_details_map={}, ): self.job_id = job_id self.status = status # IN_PROGRESS | CANCELED | COMPLETED @@ -429,17 +434,17 @@ class FakeEndpoint(BaseModel): class FakeRule(BaseModel): def __init__( - self, - rule_name, - description, - created_at, - rule_disabled, - topic_pattern, - actions, - error_action, - sql, - aws_iot_sql_version, - region_name, + self, + rule_name, + description, + created_at, + rule_disabled, + topic_pattern, + actions, + error_action, + sql, + aws_iot_sql_version, + region_name, ): self.region_name = region_name self.rule_name = rule_name @@ -539,16 +544,16 @@ class IoTBackend(BaseBackend): return self.thing_types.values() def list_things( - self, attribute_name, attribute_value, thing_type_name, max_results, token + self, attribute_name, attribute_value, thing_type_name, max_results, token ): all_things = [_.to_dict() for _ in self.things.values()] if attribute_name is not None and thing_type_name is not None: filtered_things = list( filter( lambda elem: attribute_name in elem["attributes"] - and elem["attributes"][attribute_name] == attribute_value - and "thingTypeName" in elem - and elem["thingTypeName"] == thing_type_name, + and elem["attributes"][attribute_name] == attribute_value + and "thingTypeName" in elem + and elem["thingTypeName"] == thing_type_name, all_things, ) ) @@ -556,7 +561,7 @@ class IoTBackend(BaseBackend): filtered_things = list( filter( lambda elem: attribute_name in elem["attributes"] - and elem["attributes"][attribute_name] == attribute_value, + and elem["attributes"][attribute_name] == attribute_value, all_things, ) ) @@ -564,7 +569,7 @@ class IoTBackend(BaseBackend): filtered_things = list( filter( lambda elem: "thingTypeName" in elem - and elem["thingTypeName"] == thing_type_name, + and elem["thingTypeName"] == thing_type_name, all_things, ) ) @@ -578,7 +583,7 @@ class IoTBackend(BaseBackend): ) else: token = int(token) - things = filtered_things[token : token + max_results] + things = filtered_things[token: token + max_results] next_token = ( str(token + max_results) if len(filtered_things) > token + max_results @@ -624,12 +629,12 @@ class IoTBackend(BaseBackend): del self.thing_types[thing_type.arn] def update_thing( - self, - thing_name, - thing_type_name, - attribute_payload, - expected_version, - remove_thing_type, + self, + thing_name, + thing_type_name, + attribute_payload, + expected_version, + remove_thing_type, ): # if attributes payload = {}, nothing thing = self.describe_thing(thing_name) @@ -730,7 +735,7 @@ class IoTBackend(BaseBackend): ) def register_certificate( - self, certificate_pem, ca_certificate_pem, set_as_active, status + self, certificate_pem, ca_certificate_pem, set_as_active, status ): certificate = FakeCertificate( certificate_pem, @@ -954,7 +959,7 @@ class IoTBackend(BaseBackend): return thing_groups[0] def create_thing_group( - self, thing_group_name, parent_group_name, thing_group_properties + self, thing_group_name, parent_group_name, thing_group_properties ): thing_group = FakeThingGroup( thing_group_name, @@ -1012,7 +1017,7 @@ class IoTBackend(BaseBackend): ] def update_thing_group( - self, thing_group_name, thing_group_properties, expected_version + self, thing_group_name, thing_group_properties, expected_version ): thing_group = self.describe_thing_group(thing_group_name) if expected_version and expected_version != thing_group.version: @@ -1071,7 +1076,7 @@ class IoTBackend(BaseBackend): return thing def add_thing_to_thing_group( - self, thing_group_name, thing_group_arn, thing_name, thing_arn + self, thing_group_name, thing_group_arn, thing_name, thing_arn ): thing_group = self._identify_thing_group(thing_group_name, thing_group_arn) thing = self._identify_thing(thing_name, thing_arn) @@ -1081,7 +1086,7 @@ class IoTBackend(BaseBackend): thing_group.things[thing.arn] = thing def remove_thing_from_thing_group( - self, thing_group_name, thing_group_arn, thing_name, thing_arn + self, thing_group_name, thing_group_arn, thing_name, thing_arn ): thing_group = self._identify_thing_group(thing_group_name, thing_group_arn) thing = self._identify_thing(thing_name, thing_arn) @@ -1109,7 +1114,7 @@ class IoTBackend(BaseBackend): return ret def update_thing_groups_for_thing( - self, thing_name, thing_groups_to_add, thing_groups_to_remove + self, thing_name, thing_groups_to_add, thing_groups_to_remove ): thing = self.describe_thing(thing_name) for thing_group_name in thing_groups_to_add: @@ -1124,16 +1129,16 @@ class IoTBackend(BaseBackend): ) def create_job( - self, - job_id, - targets, - document_source, - document, - description, - presigned_url_config, - target_selection, - job_executions_rollout_config, - document_parameters, + self, + job_id, + targets, + document_source, + document, + description, + presigned_url_config, + target_selection, + job_executions_rollout_config, + document_parameters, ): job = FakeJob( job_id, @@ -1192,13 +1197,13 @@ class IoTBackend(BaseBackend): return self.jobs[job_id] def list_jobs( - self, - status, - target_selection, - max_results, - token, - thing_group_name, - thing_group_id, + self, + status, + target_selection, + max_results, + token, + thing_group_name, + thing_group_id, ): # TODO: implement filters all_jobs = [_.to_dict() for _ in self.jobs.values()] @@ -1209,7 +1214,7 @@ class IoTBackend(BaseBackend): next_token = str(max_results) if len(filtered_jobs) > max_results else None else: token = int(token) - jobs = filtered_jobs[token : token + max_results] + jobs = filtered_jobs[token: token + max_results] next_token = ( str(token + max_results) if len(filtered_jobs) > token + max_results @@ -1225,15 +1230,15 @@ class IoTBackend(BaseBackend): raise ResourceNotFoundException() if job_execution is None or ( - execution_number is not None - and job_execution.execution_number != execution_number + execution_number is not None + and job_execution.execution_number != execution_number ): raise ResourceNotFoundException() return job_execution def cancel_job_execution( - self, job_id, thing_name, force, expected_version, status_details + self, job_id, thing_name, force, expected_version, status_details ): job_execution = self.job_executions[(job_id, thing_name)] @@ -1288,7 +1293,7 @@ class IoTBackend(BaseBackend): next_token = str(max_results) if len(job_executions) > max_results else None else: token = int(token) - job_executions = job_executions[token : token + max_results] + job_executions = job_executions[token: token + max_results] next_token = ( str(token + max_results) if len(job_executions) > token + max_results @@ -1298,7 +1303,7 @@ class IoTBackend(BaseBackend): return job_executions, next_token def list_job_executions_for_thing( - self, thing_name, status, max_results, next_token + self, thing_name, status, max_results, next_token ): job_executions = [ self.job_executions[je].to_dict() @@ -1320,7 +1325,7 @@ class IoTBackend(BaseBackend): next_token = str(max_results) if len(job_executions) > max_results else None else: token = int(token) - job_executions = job_executions[token : token + max_results] + job_executions = job_executions[token: token + max_results] next_token = ( str(token + max_results) if len(job_executions) > token + max_results diff --git a/moto/iot/responses.py b/moto/iot/responses.py index c0de6007..3a2804d9 100644 --- a/moto/iot/responses.py +++ b/moto/iot/responses.py @@ -49,7 +49,7 @@ class IoTResponse(BaseResponse): next_token = str(max_results) if len(thing_types) > max_results else None else: token = int(previous_next_token) - result = thing_types[token : token + max_results] + result = thing_types[token: token + max_results] next_token = ( str(token + max_results) if len(thing_types) > token + max_results From 457b18b2db02324dcc7e6e64c51ce32f08648c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?c=C4=83t=C4=83lin?= Date: Fri, 23 Jul 2021 12:25:50 +0200 Subject: [PATCH 2/2] Test iot certs' validity dates --- moto/ec2/responses/amis.py | 0 moto/iam/models.py | 0 moto/iot/models.py | 6 +++--- moto/iot/responses.py | 2 +- scripts/ec2_get_instance_type_offerings.py | 7 ++++--- scripts/get_instance_info.py | 6 ++---- setup.py | 22 ++++++++++++---------- tests/test_iot/test_iot.py | 6 +++++- update_version_from_git.py | 16 +++++++++++----- 9 files changed, 38 insertions(+), 27 deletions(-) mode change 100755 => 100644 moto/ec2/responses/amis.py mode change 100755 => 100644 moto/iam/models.py diff --git a/moto/ec2/responses/amis.py b/moto/ec2/responses/amis.py old mode 100755 new mode 100644 diff --git a/moto/iam/models.py b/moto/iam/models.py old mode 100755 new mode 100644 diff --git a/moto/iot/models.py b/moto/iot/models.py index ba311094..3b3451b3 100644 --- a/moto/iot/models.py +++ b/moto/iot/models.py @@ -144,8 +144,8 @@ class FakeCertificate(BaseModel): self.transfer_data = {} self.creation_date = time.time() self.last_modified_date = self.creation_date - self.validity_not_before = (time.time() - 86400) - self.validity_not_after = (time.time() + 86400) + self.validity_not_before = time.time() - 86400 + self.validity_not_after = time.time() + 86400 self.ca_certificate_id = None self.ca_certificate_pem = ca_certificate_pem if ca_certificate_pem: @@ -177,7 +177,7 @@ class FakeCertificate(BaseModel): "lastModifiedDate": self.last_modified_date, "validity": { "notBefore": self.validity_not_before, - "notAfter": self.validity_not_after + "notAfter": self.validity_not_after, }, "transferData": self.transfer_data, } diff --git a/moto/iot/responses.py b/moto/iot/responses.py index 3a2804d9..c0de6007 100644 --- a/moto/iot/responses.py +++ b/moto/iot/responses.py @@ -49,7 +49,7 @@ class IoTResponse(BaseResponse): next_token = str(max_results) if len(thing_types) > max_results else None else: token = int(previous_next_token) - result = thing_types[token: token + max_results] + result = thing_types[token : token + max_results] next_token = ( str(token + max_results) if len(thing_types) > token + max_results diff --git a/scripts/ec2_get_instance_type_offerings.py b/scripts/ec2_get_instance_type_offerings.py index 66ce4449..c7961b71 100755 --- a/scripts/ec2_get_instance_type_offerings.py +++ b/scripts/ec2_get_instance_type_offerings.py @@ -37,7 +37,9 @@ def main(): for region in regions: for location_type in TYPES: ec2 = boto3.client("ec2", region_name=region) - dest = os.path.join(root_dir, "{0}/{1}/{2}.json".format(PATH, location_type, region)) + dest = os.path.join( + root_dir, "{0}/{1}/{2}.json".format(PATH, location_type, region) + ) try: instances = [] offerings = ec2.describe_instance_type_offerings( @@ -47,8 +49,7 @@ def main(): next_token = offerings.get("NextToken", "") while next_token: offerings = ec2.describe_instance_type_offerings( - LocationType=location_type, - NextToken=next_token + LocationType=location_type, NextToken=next_token ) instances.extend(offerings["InstanceTypeOfferings"]) next_token = offerings.get("NextToken", None) diff --git a/scripts/get_instance_info.py b/scripts/get_instance_info.py index d8f0b418..56d962a7 100755 --- a/scripts/get_instance_info.py +++ b/scripts/get_instance_info.py @@ -26,9 +26,7 @@ def main(): instances.extend(offerings["InstanceTypes"]) next_token = offerings.get("NextToken", "") while next_token: - offerings = ec2.describe_instance_types( - NextToken=next_token - ) + offerings = ec2.describe_instance_types(NextToken=next_token) instances.extend(offerings["InstanceTypes"]) next_token = offerings.get("NextToken", None) except Exception: @@ -39,7 +37,7 @@ def main(): print("Parsing data") result = {} for instance in instances: - result[instance.get('InstanceType')] = instance + result[instance.get("InstanceType")] = instance root_dir = ( subprocess.check_output(["git", "rev-parse", "--show-toplevel"]) diff --git a/setup.py b/setup.py index dfb6a585..325f847e 100755 --- a/setup.py +++ b/setup.py @@ -104,11 +104,19 @@ all_server_deps = all_extra_deps + ["flask", "flask-cors"] # i.e. even those without extra dependencies. # Would be good for future-compatibility, I guess. extras_per_service = { - "apigateway": [_dep_python_jose_py2, _dep_python_jose_py3, _dep_python_jose_ecdsa_pin], + "apigateway": [ + _dep_python_jose_py2, + _dep_python_jose_py3, + _dep_python_jose_ecdsa_pin, + ], "awslambda": [_dep_docker], "batch": [_dep_docker], "cloudformation": [_dep_docker, _dep_PyYAML, _dep_cfn_lint, _dep_decorator], - "cognitoidp": [_dep_python_jose_py2, _dep_python_jose_py3, _dep_python_jose_ecdsa_pin], + "cognitoidp": [ + _dep_python_jose_py2, + _dep_python_jose_py3, + _dep_python_jose_ecdsa_pin, + ], "dynamodb2": [_dep_docker], "dynamodbstreams": [_dep_docker], "ec2": [_dep_docker, _dep_sshpubkeys_py2, _dep_sshpubkeys_py3], @@ -145,11 +153,7 @@ setup( author="Steve Pulec", author_email="spulec@gmail.com", url="https://github.com/spulec/moto", - entry_points={ - "console_scripts": [ - "moto_server = moto.server:main", - ], - }, + entry_points={"console_scripts": ["moto_server = moto.server:main",],}, packages=find_packages(exclude=("tests", "tests.*")), install_requires=install_requires, extras_require=extras_require, @@ -167,7 +171,5 @@ setup( "License :: OSI Approved :: Apache Software License", "Topic :: Software Development :: Testing", ], - project_urls={ - "Documentation": "http://docs.getmoto.org/en/latest/", - }, + project_urls={"Documentation": "http://docs.getmoto.org/en/latest/",}, ) diff --git a/tests/test_iot/test_iot.py b/tests/test_iot/test_iot.py index 1f9c940e..a6de07be 100644 --- a/tests/test_iot/test_iot.py +++ b/tests/test_iot/test_iot.py @@ -538,6 +538,10 @@ def test_certs(): cert_desc.should.have.key("certificateArn").which.should_not.be.none cert_desc.should.have.key("certificateId").which.should_not.be.none cert_desc.should.have.key("certificatePem").which.should_not.be.none + cert_desc.should.have.key("validity").which.should_not.be.none + validity = cert_desc["validity"] + validity.should.have.key("notBefore").which.should_not.be.none + validity.should.have.key("notAfter").which.should_not.be.none cert_desc.should.have.key("status").which.should.equal("ACTIVE") cert_pem = cert_desc["certificatePem"] @@ -1019,7 +1023,7 @@ def test_delete_thing_group(): group_name_1a = "my-group-name-1a" group_name_2a = "my-group-name-2a" tree_dict = { - group_name_1a: {group_name_2a: {},}, + group_name_1a: {group_name_2a: {}, }, } group_catalog = generate_thing_group_tree(client, tree_dict) diff --git a/update_version_from_git.py b/update_version_from_git.py index 7a51a5c2..e08ad75f 100644 --- a/update_version_from_git.py +++ b/update_version_from_git.py @@ -54,7 +54,7 @@ def migrate_version(target_file, new_version): regex = r"['\"](.*)['\"]" migrate_source_attribute( "__version__", - "\"{new_version}\"".format(new_version=new_version), + '"{new_version}"'.format(new_version=new_version), target_file, regex, ) @@ -84,7 +84,9 @@ def prerelease_version(): assert ( initpy_ver > ver ), "the moto/__init__.py version should be newer than the last tagged release." - return "{}.{}.{}.dev{}".format(initpy_ver.major, initpy_ver.minor, initpy_ver.micro, commits_since) + return "{}.{}.{}.dev{}".format( + initpy_ver.major, initpy_ver.minor, initpy_ver.micro, commits_since + ) def read(*parts): @@ -116,7 +118,9 @@ def increase_patch_version(old_version): :param old_version: 2.0.1 :return: 2.0.2.dev """ - return "{}.{}.{}.dev".format(old_version.major, old_version.minor, old_version.micro + 1) + return "{}.{}.{}.dev".format( + old_version.major, old_version.minor, old_version.micro + 1 + ) def release_version_correct(): @@ -154,5 +158,7 @@ if __name__ == "__main__": initpy = os.path.abspath("moto/__init__.py") migrate_version(initpy, new_version) else: - print("Invalid usage. Supply 0 or 1 arguments. " - "Argument can be either a version '1.2.3' or 'patch' if you want to increase the patch-version (1.2.3 -> 1.2.4.dev)") + print( + "Invalid usage. Supply 0 or 1 arguments. " + "Argument can be either a version '1.2.3' or 'patch' if you want to increase the patch-version (1.2.3 -> 1.2.4.dev)" + )