def test_assume_role_expiry(self): os.environ["CIS_DYNALITE_PORT"] = self.dynalite_port os.environ["CIS_KINESALITE_PORT"] = self.kinesalite_port from cis_aws import connect c = connect.AWS() os.environ["CIS_ASSUME_ROLE_ARN"] = "arn:aws:iam::123456789000:role/demo-assume-role" from cis_aws import connect c = connect.AWS() # Stub around the session because we are not testing sessions. c._boto_session = Stubber(boto3.session.Session(region_name="us-west-2")).client result = c.assume_role() assert result is not None os.environ["CIS_ENVIRONMENT"] = "TESTING" assert c._assume_role_is_expired() is False an_hour_ago = datetime.utcnow() - timedelta(minutes=61) c.assume_role_session["Credentials"]["Expiration"] = an_hour_ago assert c._assume_role_is_expired() is True # Test local always returns False os.environ["CIS_ENVIRONMENT"] = "local" assert c._assume_role_is_expired() is False # Test local always returns False os.environ["CIS_ENVIRONMENT"] = "LoCaL" assert c._assume_role_is_expired() is False # Test local always returns False os.environ["CIS_ENVIRONMENT"] = "LOCAL" assert c._assume_role_is_expired() is False
def test_discover_kinesis_mock_cloud(self): os.environ["CIS_ENVIRONMENT"] = "testing" name = "testing-stream" conn = boto3.client("kinesis", region_name="us-east-1", aws_access_key_id="ak", aws_secret_access_key="sk") response = conn.create_stream(StreamName=name, ShardCount=1) waiter = conn.get_waiter("stream_exists") waiter.wait(StreamName=name, Limit=100, WaiterConfig={"Delay": 1, "MaxAttempts": 5}) tags_1 = {"cis_environment": "testing"} tags_2 = {"application": "change-stream"} conn.add_tags_to_stream(StreamName=name, Tags=tags_1) conn.add_tags_to_stream(StreamName=name, Tags=tags_2) assert response is not None from cis_aws import connect c = connect.AWS() result = c._discover_kinesis_stream(conn) assert result is not None assert result.endswith(name)
def test_kinesis_client_with_mock_cloud(self): os.environ["CIS_ENVIRONMENT"] = "testing" name = "testing-stream" os.environ["CIS_ASSUME_ROLE_ARN"] = "arn:aws:iam::123456789000:role/demo-assume-role" conn = boto3.client("kinesis", region_name="us-east-1", aws_access_key_id="ak", aws_secret_access_key="sk") response = conn.create_stream(StreamName=name, ShardCount=1) waiter = conn.get_waiter("stream_exists") waiter.wait(StreamName=name, Limit=100, WaiterConfig={"Delay": 1, "MaxAttempts": 5}) tags_1 = {"cis_environment": "testing"} tags_2 = {"application": "change-stream"} conn.add_tags_to_stream(StreamName=name, Tags=tags_1) conn.add_tags_to_stream(StreamName=name, Tags=tags_2) assert response is not None from cis_aws import connect c = connect.AWS() c.session(region_name="us-east-1") c.assume_role() result = c.input_stream_client() assert result is not None assert result.get("arn").endswith(name)
def test_dynamodb_local_with_dynalite(self): name = "local-identity-vault" os.environ["CIS_ENVIRONMENT"] = "local" os.environ["CIS_DYNALITE_HOST"] = self.dynalite_host os.environ["CIS_DYNALITE_PORT"] = self.dynalite_port os.environ["CIS_ASSUME_ROLE_ARN"] = "arn:aws:iam::123456789000:role/demo-assume-role" dynalite_session = Stubber(boto3.session.Session(region_name="us-west-2")).client.client( "dynamodb", endpoint_url="http://{}:{}".format(self.dynalite_host, self.dynalite_port) ) dynalite_session.create_table( TableName=name, KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}], AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}], ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5}, ) from cis_aws import connect c = connect.AWS() c.session() c.assume_role() res = c.identity_vault_client() assert res is not None assert res.get("client") is not None
def test_connect_object_init(self): os.environ["CIS_DYNALITE_PORT"] = self.dynalite_port os.environ["CIS_KINESALITE_PORT"] = self.kinesalite_port from cis_aws import connect c = connect.AWS() assert c is not None
def test_kinesis_client_with_local(self): os.environ["CIS_ENVIRONMENT"] = "local" name = "local-stream" os.environ["CIS_DYNALITE_PORT"] = self.dynalite_port os.environ["CIS_KINESALITE_PORT"] = self.kinesalite_port os.environ["CIS_KINESALITE_HOST"] = self.kinesalite_host os.environ["CIS_ASSUME_ROLE_ARN"] = "arn:aws:iam::123456789000:role/demo-assume-role" conn = Stubber(boto3.session.Session(region_name="us-west-2")).client.client( "kinesis", endpoint_url="http://{}:{}".format(self.kinesalite_host, self.kinesalite_port) ) response = conn.create_stream(StreamName=name, ShardCount=1) waiter = conn.get_waiter("stream_exists") waiter.wait(StreamName=name, Limit=100, WaiterConfig={"Delay": 1, "MaxAttempts": 5}) assert response is not None from cis_aws import connect c = connect.AWS() c.session(region_name="us-west-2") c.assume_role() result = c.input_stream_client() assert result is not None assert result.get("arn").endswith(name)
def change(): connection = connect.AWS() connection.session() identity_vault_client = connection.identity_vault_client() user_profile = request.get_json(silent=True) if isinstance(user_profile, str): user_profile = json.loads(user_profile) logger.info("A json payload was received for user: {}".format( user_profile["user_id"]["value"])) if config("stream_bypass", namespace="cis", default="false") == "true": # Plan on stream integration not working an attempt a write directly to discoverable dynamo. # Great for development, seeding the vault, and contingency. logger.debug( "Stream bypass activated. Integrating user profile directly to dynamodb for: {}" .format(user_profile.get("user_id").get("value"))) vault = profile.Vault() vault.identity_vault_client = identity_vault_client result = vault.put_profile(user_profile) else: publish = operation.Publish() result = publish.to_stream(user_profile) logger.info("The result of publishing for user: {} is: {}".format( user_profile["user_id"]["value"], result)) return jsonify(result)
def test_discover_dynamodb_table_mock_cloud(self): os.environ["CIS_ENVIRONMENT"] = "testing" name = "testing-identity-vault" conn = boto3.client("dynamodb", region_name="us-east-1", aws_access_key_id="ak", aws_secret_access_key="sk") conn.create_table( TableName=name, KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}], AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "S"}], ProvisionedThroughput={"ReadCapacityUnits": 5, "WriteCapacityUnits": 5}, ) table_description = conn.describe_table(TableName=name) arn = table_description["Table"]["TableArn"] assert arn is not None waiter = conn.get_waiter("table_exists") waiter.wait(TableName="testing-identity-vault", WaiterConfig={"Delay": 5, "MaxAttempts": 5}) tags = [{"Key": "cis_environment", "Value": "testing"}, {"Key": "application", "Value": "identity-vault"}] conn.tag_resource(ResourceArn=arn, Tags=tags) from cis_aws import connect c = connect.AWS() res = c._discover_dynamo_table(conn) assert res is not None assert res.endswith("testing-identity-vault")
def test_dynamodb_full_client_with_mock_cloud(self): os.environ["CIS_ENVIRONMENT"] = "testing" name = "testing-identity-vault" conn = boto3.client("dynamodb", region_name="us-east-1", aws_access_key_id="ak", aws_secret_access_key="sk") conn.create_table( TableName=name, KeySchema=[{ "AttributeName": "id", "KeyType": "HASH" }], AttributeDefinitions=[{ "AttributeName": "id", "AttributeType": "S" }], ProvisionedThroughput={ "ReadCapacityUnits": 5, "WriteCapacityUnits": 5 }, ) table_description = conn.describe_table(TableName=name) arn = table_description["Table"]["TableArn"] assert arn is not None waiter = conn.get_waiter("table_exists") waiter.wait(TableName="testing-identity-vault", WaiterConfig={ "Delay": 5, "MaxAttempts": 5 }) tags = [{ "Key": "cis_environment", "Value": "testing" }, { "Key": "application", "Value": "identity-vault" }] conn.tag_resource(ResourceArn=arn, Tags=tags) os.environ[ "CIS_ASSUME_ROLE_ARN"] = "arn:aws:iam::123456789000:role/demo-assume-role" from cis_aws import connect c = connect.AWS() c._boto_session = boto3.session.Session(region_name="us-east-1") c.assume_role() res = c.identity_vault_client() assert res is not None assert res.get("client") is not None assert res.get("arn").endswith("testing-identity-vault")
def test_botocore_client_initialization(self): os.environ["CIS_DYNALITE_PORT"] = self.dynalite_port os.environ["CIS_KINESALITE_PORT"] = self.kinesalite_port from cis_aws import connect c = connect.AWS() tested_session = c.session(region_name="us-east-1") assert tested_session is not None
def __init__(self, sequence_number=None): self.connection_object = connect.AWS() self.identity_vault_client = None self.config = common.get_config() if sequence_number is not None: self.sequence_number = str(sequence_number) else: self.sequence_number = str(uuid.uuid4().int)
def setup(self): self.helper_configuration = helpers.Configuration() cis_environment = os.getenv("CIS_ENVIRONMENT", "development") os.environ["CIS_ENVIRONMENT"] = cis_environment os.environ["CIS_ASSUME_ROLE_ARN"] = "None" self.connection_object = connect.AWS() self.connection_object._boto_session = boto3.session.Session( region_name="us-west-2") self.idv = self.connection_object.identity_vault_client() # u = fake_profile.FakeUser() # u = helpers.ensure_appropriate_publishers_and_sign(fake_profile=u, condition="create") # u.verify_all_publishers(profile.User(user_structure_json=None)) fh = open("fixtures/durable.json") self.durable_profile = fh.read() fh.close() self.durable_profiles = [] logger.info("Loading 10 fake users.") for x in range(0, 10): fh = open("fixtures/{}.json".format(x)) self.durable_profiles.append(fh.read()) fh.close() logger.info( "Bypassing change service and writing directly to the id_vault.") vault = user.Profile(dynamodb_table_resource=self.idv["table"], dynamodb_client=self.idv["client"], transactions=True) this_user = json.loads(self.durable_profile) user_profile = { "id": this_user["user_id"]["value"], "profile": self.durable_profile, "primary_username": this_user["primary_username"]["value"], "primary_email": this_user["primary_email"]["value"], "user_uuid": this_user["uuid"]["value"], "sequence_number": "1", } res = vault.find_or_create(user_profile) logger.info("Single user created in vault result: {}".format(res)) for this_profile in self.durable_profiles: this_user = json.loads(this_profile) user_profile = { "id": this_user["user_id"]["value"], "profile": this_profile, "primary_username": this_user["primary_username"]["value"], "primary_email": this_user["primary_email"]["value"], "user_uuid": this_user["uuid"]["value"], "sequence_number": "1", } res = vault.find_or_create(user_profile=user_profile) logger.info("Single user created in vault result: {}".format(res))
def test_discover_cis_environment(self): os.environ["CIS_DYNALITE_PORT"] = self.dynalite_port os.environ["CIS_KINESALITE_PORT"] = self.kinesalite_port from cis_aws import connect c = connect.AWS() os.environ["CIS_ENVIRONMENT"] = "local" # Test default fall through to local environ assert c._discover_cis_environment() == "local"
def test_botocore_client_returns_session_if_inited(self): os.environ["CIS_DYNALITE_PORT"] = self.dynalite_port os.environ["CIS_KINESALITE_PORT"] = self.kinesalite_port from cis_aws import connect c = connect.AWS() tested_session = c.session(region_name="eu-west-1") c._boto_session = Stubber(boto3.session.Session(region_name="eu-west-1")).client tested_session = c.session() assert tested_session == c._boto_session
def changes(): connection = connect.AWS() connection.session() identity_vault_client = connection.identity_vault_client() profiles = request.get_json(silent=True) logger.info("A list numbering: {} profiles has been received.".format( len(profiles))) vault = profile.Vault(sequence_number=None) vault.identity_vault_client = identity_vault_client results = vault.put_profiles(profiles) logger.info( "The result of the attempt to publish the profiles was: {}".format( results), extra={"results": results}) return jsonify(results)
def test_assume_role(self): os.environ["CIS_DYNALITE_PORT"] = self.dynalite_port os.environ["CIS_KINESALITE_PORT"] = self.kinesalite_port os.environ["CIS_ASSUME_ROLE_ARN"] = "arn:aws:iam::123456789000:role/demo-assume-role" from cis_aws import connect c = connect.AWS() # Stub around the session because we are not testing sessions. c._boto_session = Stubber(boto3.session.Session(region_name="us-west-2")).client result = c.assume_role() assert result["Credentials"]["AccessKeyId"] is not None assert result["Credentials"]["SecretAccessKey"] is not None assert result["Credentials"]["SessionToken"] is not None assert result["Credentials"]["Expiration"] is not None assert result["AssumedRoleUser"]["Arn"] is not None
def test_discover_dynamodb_table_local(self): os.environ["CIS_ENVIRONMENT"] = "local" name = "local-identity-vault" conn = boto3.client("dynamodb", region_name="us-west-2", aws_access_key_id="ak", aws_secret_access_key="sk") conn.create_table( TableName=name, KeySchema=[{ "AttributeName": "id", "KeyType": "HASH" }], AttributeDefinitions=[{ "AttributeName": "id", "AttributeType": "S" }], ProvisionedThroughput={ "ReadCapacityUnits": 5, "WriteCapacityUnits": 5 }, ) table_description = conn.describe_table(TableName=name) arn = table_description["Table"]["TableArn"] tags = [{ "Key": "cis_environment", "Value": "unittest" }, { "Key": "application", "Value": "identity-vault" }] conn.tag_resource(ResourceArn=arn, Tags=tags) from cis_aws import connect c = connect.AWS() res = c._discover_dynamo_table(conn) assert res is not None
def __init__(self, sequence_number=None, profile_json=None, **kwargs): self.connection_object = connect.AWS() self.identity_vault_client = None self.config = common.get_config() self.condition = "unknown" self.user_id = kwargs.get("user_id") self.user_uuid = kwargs.get("user_uuid") self.primary_email = kwargs.get("primary_email") self.primary_username = kwargs.get("primary_username") if self.user_id is None: logger.info("No user_id arg was passed for the payload. This is a new user or batch.") tmp_user = User(user_structure_json=profile_json) self.user_id = tmp_user.user_id.value self.condition = "create" if sequence_number is not None: self.sequence_number = str(sequence_number) else: self.sequence_number = str(uuid.uuid4().int)
def changes(): connection = connect.AWS() connection.session() identity_vault_client = connection.identity_vault_client() profiles = request.get_json(silent=True) if config("stream_bypass", namespace="cis", default="false") == "true": logger.info("A list of profiles has been received: {}".format( len(profiles))) vault = profile.Vault(sequence_number=None) vault.identity_vault_client = identity_vault_client results = vault.put_profiles(profiles) else: logger.info("A json list of payloads was received totaling: {}".format( len(profiles))) publish = operation.Publish() results = publish.to_stream_batch(profiles) logger.info( "The result of the attempt to publish the profiles was: {}".format( results)) return jsonify(results)
def change(): connection = connect.AWS() connection.session() identity_vault_client = connection.identity_vault_client() user_profile = request.get_json(silent=True) if isinstance(user_profile, str): user_profile = json.loads(user_profile) user_id = request.args.get("user_id", user_profile["user_id"]["value"]) logger.info("A json payload was received for user: {}".format(user_id), extra={"user_id": user_id}) vault = profile.Vault(sequence_number=None, profile_json=user_profile, **request.args) if request.method in ["POST", "PUT", "GET"]: vault.identity_vault_client = identity_vault_client result = vault.put_profile(user_profile) logger.info( "The result of publishing for user: {} is: {}".format( user_id, result), extra={ "user_id": user_id, "result": result }, ) if config("allow_delete", namespace="cis", default="false") == "true": if request.method in ["DELETE"]: vault.identity_vault_client = identity_vault_client result = vault.delete_profile(user_profile) logger.info( "A delete operation was performed for user: {}".format( user_id), extra={ "user_id": user_id, "result": result }, ) return jsonify(result)
def profiles(self, user_ids=None): aws = connect.AWS() aws.session(region_name=getenv("DEFAULT_AWS_REGION", "us-west-2")) identity_vault_discovery = aws.identity_vault_client() dynamodb_client = identity_vault_discovery["client"] dynamodb_table = identity_vault_discovery["table"] vault = user.Profile(dynamodb_table, dynamodb_client) profiles = [] if user_ids is None: these_profiles = vault.all for this_profile in these_profiles: profiles.append(json.loads(this_profile["profile"])) else: for user_id in user_ids: # for each user id go and get the profile in full from the identity vault this_profile = vault.find_by_id(user_id)["Items"][0] # validate it self.user_structure_json = json.loads(this_profile["profile"]) if self.valid: # push it onto the stack profiles.append(self.profile.as_dict()) return profiles
def __init__(self, sequence_number): self.connection_object = connect.AWS() self.identity_vault_client = None self.sequence_number = sequence_number
def __init__(self): self.config = get_config() self.connection_object = connect.AWS() self.kinesis_client = None self.wk = cis_profile.common.WellKnown() self.schema = self.wk.get_schema()