def find_changes_batch(self, items, exception_map): # Given the list of items, find new items that don't yet exist: durable_items = [] from security_monkey.datastore_utils import hash_item, detect_change, persist_item for item in items: complete_hash, durable_hash = hash_item(item.config, self.ephemeral_paths) # Detect if a change occurred: is_change, change_type, db_item = detect_change(item, self.current_account[0], self.technology, complete_hash, durable_hash) # As Officer Barbrady says: "Move along... Nothing to see here..." if not is_change: continue # Now call out to persist item: is_durable = (change_type == "durable") persist_item(item, db_item, self.technology, self.current_account[0], complete_hash, durable_hash, is_durable) if is_durable: durable_items.append(item) return durable_items
def test_inactivate_old_revisions(self): from security_monkey.datastore_utils import inactivate_old_revisions, hash_item, persist_item, result_from_item from security_monkey.datastore import ItemRevision, Item self.setup_db() # Need to create 3 items first before we can test deletions: for x in range(0, 3): modConf = dict(ACTIVE_CONF) modConf["name"] = "SomeRole{}".format(x) modConf["Arn"] = "arn:aws:iam::012345678910:role/SomeRole{}".format(x) sti = SomeTestItem().from_slurp(modConf, account_name=self.account.name) # Get the hash: complete_hash, durable_hash = hash_item(sti.config, []) # persist: persist_item(sti, None, self.technology, self.account, complete_hash, durable_hash, True) db_item = result_from_item(sti, self.account, self.technology) # Add issues for these items: (just add two for testing purposes) db.session.add(ItemAudit(score=10, issue="IAM Role has full admin permissions.", notes=json.dumps(sti.config), item_id=db_item.id)) db.session.add(ItemAudit(score=9001, issue="Some test issue", notes="{}", item_id=db_item.id)) db.session.commit() # Now, actually test for deleted revisions: arns = [ "arn:aws:iam::012345678910:role/SomeRole", # <-- Does not exist in the list "arn:aws:iam::012345678910:role/SomeRole0", # <-- Does exist -- should not get deleted ] inactivate_old_revisions(SomeWatcher(), arns, self.account, self.technology) # Check that SomeRole1 and SomeRole2 are marked as inactive: for x in range(1, 3): item_revision = ItemRevision.query.join((Item, ItemRevision.id == Item.latest_revision_id)).filter( Item.arn == "arn:aws:iam::012345678910:role/SomeRole{}".format(x), ).one() assert not item_revision.active # Check that there are no issues associated with this item: assert len(ItemAudit.query.filter(ItemAudit.item_id == item_revision.item_id).all()) == 0 # Check that the SomeRole0 is still OK: item_revision = ItemRevision.query.join((Item, ItemRevision.id == Item.latest_revision_id)).filter( Item.arn == "arn:aws:iam::012345678910:role/SomeRole0".format(x), ).one() assert len(ItemAudit.query.filter(ItemAudit.item_id == item_revision.item_id).all()) == 2 assert item_revision.active
def find_changes_batch(self, items, exception_map): # Given the list of items, find new items that don't yet exist: durable_items = [] from security_monkey.datastore_utils import hash_item, detect_change, persist_item for item in items: complete_hash, durable_hash = hash_item(item.config, self.ephemeral_paths) # Detect if a change occurred: is_change, change_type, db_item, created_changed = detect_change( item, self.current_account[0], self.technology, complete_hash, durable_hash) if not is_change: continue is_durable = (change_type == "durable") if is_durable: durable_items.append(item) if created_changed == 'created': self.created_items.append( ChangeItem.from_items(old_item=None, new_item=item, source_watcher=self)) if created_changed == 'changed': db_item.audit_issues = db_item.issues db_item.config = db_item.revisions.first().config # At this point, a durable change was detected. If the complete hash is the same, # then the durable hash is out of date, and this is not a real item change. This could happen if the # ephemeral definitions change (this will be fixed in persist_item). # Only add the items to the changed item list that are real item changes: if db_item.latest_revision_complete_hash != complete_hash: self.changed_items.append( ChangeItem.from_items(old_item=db_item, new_item=item, source_watcher=self)) persist_item(item, db_item, self.technology, self.current_account[0], complete_hash, durable_hash, is_durable) return durable_items
def find_changes_batch(self, items, exception_map): # Given the list of items, find new items that don't yet exist: durable_items = [] from security_monkey.datastore_utils import hash_item, detect_change, persist_item for item in items: complete_hash, durable_hash = hash_item(item.config, self.ephemeral_paths) # Detect if a change occurred: is_change, change_type, db_item, created_changed = detect_change( item, self.current_account[0], self.technology, complete_hash, durable_hash) if not is_change: continue is_durable = (change_type == "durable") if is_durable: durable_items.append(item) if created_changed == 'created': self.created_items.append(ChangeItem.from_items(old_item=None, new_item=item, source_watcher=self)) if created_changed == 'changed': db_item.audit_issues = db_item.issues db_item.config = db_item.revisions.first().config # At this point, a durable change was detected. If the complete hash is the same, # then the durable hash is out of date, and this is not a real item change. This could happen if the # ephemeral definitions change (this will be fixed in persist_item). # Only add the items to the changed item list that are real item changes: if db_item.latest_revision_complete_hash != complete_hash: self.changed_items.append(ChangeItem.from_items(old_item=db_item, new_item=item, source_watcher=self)) persist_item(item, db_item, self.technology, self.current_account[0], complete_hash, durable_hash, is_durable) return durable_items
def find_changes_batch(self, items, exception_map): # Given the list of items, find new items that don't yet exist: durable_items = [] from security_monkey.datastore_utils import hash_item, detect_change, persist_item for item in items: complete_hash, durable_hash = hash_item(item.config, self.ephemeral_paths) # Detect if a change occurred: is_change, change_type, db_item, created_changed = detect_change( item, self.current_account[0], self.technology, complete_hash, durable_hash) if not is_change: continue is_durable = (change_type == "durable") if is_durable: durable_items.append(item) if created_changed == 'created': self.created_items.append( ChangeItem.from_items(old_item=None, new_item=item)) if created_changed == 'changed': db_item.audit_issues = db_item.issues db_item.config = db_item.revisions.first().config self.changed_items.append( ChangeItem.from_items(old_item=db_item, new_item=item)) persist_item(item, db_item, self.technology, self.current_account[0], complete_hash, durable_hash, is_durable) return durable_items
def test_persist_item(self): from security_monkey.datastore_utils import persist_item, hash_item, result_from_item self.setup_db() sti = SomeTestItem().from_slurp(ACTIVE_CONF, account_name=self.account.name) # Get the hash: complete_hash, durable_hash = hash_item(sti.config, []) # Persist a durable change: persist_item(sti, None, self.technology, self.account, complete_hash, durable_hash, True) db_item = result_from_item(sti, self.account, self.technology) assert db_item assert db_item.revisions.count() == 1 assert db_item.latest_revision_durable_hash == durable_hash == complete_hash assert db_item.latest_revision_complete_hash == complete_hash == durable_hash # No changes: persist_item(sti, db_item, self.technology, self.account, complete_hash, durable_hash, True) db_item = result_from_item(sti, self.account, self.technology) assert db_item assert db_item.revisions.count() == 1 assert db_item.latest_revision_durable_hash == complete_hash == durable_hash assert db_item.latest_revision_complete_hash == complete_hash == durable_hash # Ephemeral change: mod_conf = dict(ACTIVE_CONF) mod_conf["IGNORE_ME"] = "I am ephemeral!" new_complete_hash, new_durable_hash = hash_item( mod_conf, ["IGNORE_ME"]) sti = SomeTestItem().from_slurp(mod_conf, account_name=self.account.name) persist_item(sti, db_item, self.technology, self.account, new_complete_hash, new_durable_hash, False) db_item = result_from_item(sti, self.account, self.technology) assert db_item assert db_item.revisions.count() == 1 assert db_item.latest_revision_durable_hash == new_durable_hash == durable_hash assert db_item.latest_revision_complete_hash == new_complete_hash != complete_hash
def test_persist_item(self): from security_monkey.datastore_utils import persist_item, hash_item, result_from_item self.setup_db() sti = SomeTestItem().from_slurp(ACTIVE_CONF, account_name=self.account.name) # Get the hash: complete_hash, durable_hash = hash_item(sti.config, []) # Persist a durable change: persist_item(sti, None, self.technology, self.account, complete_hash, durable_hash, True) db_item = result_from_item(sti, self.account, self.technology) assert db_item assert db_item.revisions.count() == 1 assert db_item.latest_revision_durable_hash == durable_hash == complete_hash assert db_item.latest_revision_complete_hash == complete_hash == durable_hash # No changes: persist_item(sti, db_item, self.technology, self.account, complete_hash, durable_hash, True) db_item = result_from_item(sti, self.account, self.technology) assert db_item assert db_item.revisions.count() == 1 assert db_item.latest_revision_durable_hash == complete_hash == durable_hash assert db_item.latest_revision_complete_hash == complete_hash == durable_hash # Ephemeral change: mod_conf = dict(ACTIVE_CONF) mod_conf["IGNORE_ME"] = "I am ephemeral!" new_complete_hash, new_durable_hash = hash_item(mod_conf, ["IGNORE_ME"]) sti = SomeTestItem().from_slurp(mod_conf, account_name=self.account.name) persist_item(sti, db_item, self.technology, self.account, new_complete_hash, new_durable_hash, False) db_item = result_from_item(sti, self.account, self.technology) assert db_item assert db_item.revisions.count() == 1 assert db_item.latest_revision_durable_hash == new_durable_hash == durable_hash assert db_item.latest_revision_complete_hash == new_complete_hash != complete_hash