Пример #1
0
async def test_file_expiration_with_multiple_root_reference(tmpdir, system):
    """Tests that a file that expires but still has a root references are not
    deleted until all root references are deleted."""

    path = str(tmpdir / "test.txt")
    with open(path, "w") as fp:
        fp.write("Hello, world!")

    # add a root with a file that expires right away
    root_1 = system.new_root()
    file_observable = await root_1.add_file(path, expiration_date=utc_now())
    await root_1.save()
    await root_1.discard()

    # do it again but reference the same file
    root_2 = system.new_root()
    file_observable = await root_2.add_file(path, expiration_date=utc_now())
    await root_2.save()
    await root_2.discard()

    # the content meta should reference two different roots
    meta = await system.get_content_meta(file_observable.value)
    assert root_1.uuid in meta.roots
    assert root_2.uuid in meta.roots

    # this should return 0 since it still has a valid root reference
    assert len([_ async for _ in await system.iter_expired_content()]) == 0

    # make sure we don't delete anything
    assert await system.delete_expired_content() == 0
    assert await system.get_content_meta(file_observable.value) is not None

    # delete the first root
    await system.delete_root_analysis(root_1)

    # this should return 0 since we still have a valid root reference
    assert len([_ async for _ in await system.iter_expired_content()]) == 0

    # make sure we don't delete anything
    assert await system.delete_expired_content() == 0
    assert await system.get_content_meta(file_observable.value) is not None

    # delete the second root
    await system.delete_root_analysis(root_2)

    # now this should return 1 since the root is gone
    assert len([_ async for _ in await system.iter_expired_content()]) == 1

    # and now it should clear out
    assert await system.delete_expired_content() == 1

    # this should return 0 since it still has a valid root reference
    assert len([_ async for _ in await system.iter_expired_content()]) == 0

    # and the content is gone
    assert await system.get_content_meta(file_observable.value) is None
Пример #2
0
async def test_root_analysis_association(tmp_path, system):
    target_path = tmp_path / "test.txt"
    target_path.write_text("test")
    target_path = str(target_path)

    # we store the file with no initial root analysis set to expire now
    sha256 = await system.save_file(target_path, expiration_date=utc_now())
    assert await system.get_content_meta(sha256)

    # submit a root analysis with the given file *after* we upload it
    root = system.new_root()
    observable = root.add_observable("file", sha256)
    await root.submit()

    # now attempt to delete all expired content
    await system.delete_expired_content()

    # we should still have the content
    assert await system.get_content_meta(sha256)

    # delete the root
    await system.delete_root_analysis(root)

    # now attempt to delete all expired content
    await system.delete_expired_content()

    # should be gone
    assert await system.get_content_meta(sha256) is None
Пример #3
0
def test_observable_serialization():
    root = RootAnalysis()
    o_time = utc_now()
    target = root.add_observable("test", "other")
    o1 = root.add_observable(
        "test",
        "test",
        time=o_time,
        context="text context",
        directives=["directive1", "directive2"],
        limited_analysis=["limit1", "limit2"],
        excluded_analysis=["excluded1", "excluded2"],
        requested_analysis=["requested1", "requested2"],
    )

    o1.add_relationship("test", target)

    root = RootAnalysis.from_dict(root.to_model().dict())
    o2 = root.get_observable(o1)

    # should be two separate instances
    assert id(o1) != id(o2)

    assert o1.type == o2.type
    assert o1.value == o2.value
    assert o1.time == o2.time
    assert o1.context == o2.context
    assert o1.directives == o2.directives
    assert o1.limited_analysis == o2.limited_analysis
    assert o1.excluded_analysis == o2.excluded_analysis
    assert o1.requested_analysis == o2.requested_analysis
    assert o1.relationships == o2.relationships
Пример #4
0
async def test_file_expiration_with_root_reference(tmpdir, system):
    """Tests that a file that expires but still has a root reference does not
    get deleted until the root is also deleted."""

    path = str(tmpdir / "test.txt")
    with open(path, "w") as fp:
        fp.write("Hello, world!")

    root = system.new_root()
    # have the file expire right away
    file_observable = await root.add_file(path, expiration_date=utc_now())
    await root.save()
    await root.discard()

    # this should return 0 since it still has a valid root reference
    assert len([_ async for _ in await system.iter_expired_content()]) == 0

    # make sure we don't delete anything
    assert await system.delete_expired_content() == 0
    assert await system.get_content_meta(file_observable.value) is not None

    # delete the root
    await system.delete_root_analysis(root)

    # now this should return 1 since the root is gone
    assert len([_ async for _ in await system.iter_expired_content()]) == 1

    # and now it should clear out
    assert await system.delete_expired_content() == 1

    # this should return 0 since it still has a valid root reference
    assert len([_ async for _ in await system.iter_expired_content()]) == 0

    # and the content is gone
    assert await system.get_content_meta(file_observable.value) is None
Пример #5
0
    async def i_get_cached_analysis_result(
            self, cache_key: str) -> Union[AnalysisRequest, None]:
        async with self.get_db() as db:
            result = (await db.execute(
                select(AnalysisResultCache).where(
                    AnalysisResultCache.cache_key == cache_key)
            )).one_or_none()
            if result is None:
                return None

            result = result[0]
            if result.expiration_date is not None and utc_now(
            ) > result.expiration_date:
                return None

            return AnalysisRequest.from_json(result.json_data, system=self)
Пример #6
0
async def test_file_expiration(tmpdir, system):
    path = str(tmpdir / "test.txt")
    with open(path, "w") as fp:
        fp.write("Hello, world!")

    # store the file and have it expire right away
    sha256 = await system.save_file(path, expiration_date=utc_now())
    assert sha256

    # we should have a single expired file now
    assert len([_ async for _ in await system.iter_expired_content()]) == 1

    # clear them out
    await system.delete_expired_content()

    # now we should have no expired content
    assert len([_ async for _ in await system.iter_expired_content()]) == 0

    # and the file should be gone
    assert await system.get_content_meta(sha256) is None
Пример #7
0
    async def i_cache_analysis_result(self, cache_key: str,
                                      request: AnalysisRequest,
                                      expiration: Optional[int]) -> str:
        expiration_date = None
        # XXX using system side time
        if expiration is not None:
            expiration_date = utc_now() + datetime.timedelta(
                seconds=expiration)

        cache_result = AnalysisResultCache(
            cache_key=cache_key,
            expiration_date=expiration_date,
            analysis_module_type=request.type.name,
            json_data=request.to_json(),
        )

        async with self.get_db() as db:
            await db.merge(cache_result)
            await db.commit()

        return cache_key
Пример #8
0
def test_observable_eq():
    # same type, value no time
    assert RootAnalysis().add_observable(
        "test", "test") == RootAnalysis().add_observable("test", "test")
    # same type, value same time
    _now = utc_now()
    assert RootAnalysis().add_observable(
        "test", "test", time=_now) == RootAnalysis().add_observable("test",
                                                                    "test",
                                                                    time=_now)
    # same type, value different time
    assert RootAnalysis().add_observable(
        "test", "test", time=_now) != RootAnalysis().add_observable(
            "test", "test", time=_now - datetime.timedelta(seconds=1))
    # same type different value
    assert RootAnalysis().add_observable(
        "test", "test") != RootAnalysis().add_observable("test", "different")
    # different type
    assert RootAnalysis().add_observable(
        "test", "test") != RootAnalysis().add_observable("other", "test")
    # wrong object
    assert RootAnalysis().add_observable("test", "test") != object()
Пример #9
0
 async def i_register_alert_system(self, name: str) -> bool:
     async with self.get_redis_connection() as rc:
         return await rc.hsetnx(KEY_ALERT_SYSTEMS, name,
                                str(utc_now())) == 1
Пример #10
0
def test_utc_now():
    assert utc_now().tzinfo == pytz.utc
Пример #11
0
 async def i_add_work_queue(self, name: str) -> bool:
     async with self.get_redis_connection() as rc:
         # this has to exist for the queue to exist
         return await rc.hsetnx(KEY_WORK_QUEUES, name, str(utc_now())) == 1
Пример #12
0
def test_observable_str():
    assert str(RootAnalysis().add_observable("test", "test"))
    assert str(RootAnalysis().add_observable("test", "test", time=utc_now()))
Пример #13
0
 async def i_delete_expired_cached_analysis_results(self):
     async with self.get_db() as db:
         await db.execute(
             delete(AnalysisResultCache).where(
                 AnalysisResultCache.expiration_date < utc_now()))
         await db.commit()