mirror of
https://github.com/laramies/theHarvester.git
synced 2026-08-17 19:35:40 +02:00
186 lines
7.0 KiB
Python
186 lines
7.0 KiB
Python
import pytest
|
|
from aiohttp import ClientSession, web
|
|
|
|
from theHarvester.discovery import bravesearch, censysearch, githubcode
|
|
from theHarvester.lib.configuration import InMemoryCredentialAdapter
|
|
from theHarvester.lib.source_execution import SourceExecutionReport
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_brave_pagination_preserves_provider_cookies(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
unused_tcp_port: int,
|
|
) -> None:
|
|
requests: list[tuple[str | None, str | None]] = []
|
|
sessions: list[ClientSession] = []
|
|
original_build_session = bravesearch.AsyncFetcher._build_session
|
|
|
|
async def tracked_build_session(*args: object, **kwargs: object) -> ClientSession:
|
|
session = await original_build_session(*args, **kwargs) # type: ignore[arg-type]
|
|
sessions.append(session)
|
|
return session
|
|
|
|
monkeypatch.setattr(bravesearch.AsyncFetcher, '_build_session', tracked_build_session)
|
|
|
|
async def search(request: web.Request) -> web.Response:
|
|
offset = request.query.get('offset')
|
|
requests.append((offset, request.cookies.get('provider-session')))
|
|
if offset == '0':
|
|
response = web.json_response(
|
|
{
|
|
'query': {'more_results_available': True},
|
|
'web': {
|
|
'results': [
|
|
{
|
|
'title': 'First',
|
|
'description': 'one.example.com',
|
|
'url': 'https://one.example.com',
|
|
}
|
|
]
|
|
},
|
|
}
|
|
)
|
|
response.set_cookie('provider-session', 'ready')
|
|
return response
|
|
if request.cookies.get('provider-session') != 'ready':
|
|
return web.json_response({'error': 'missing provider session'}, status=403)
|
|
return web.json_response(
|
|
{
|
|
'query': {'more_results_available': False},
|
|
'web': {
|
|
'results': [
|
|
{
|
|
'title': 'Second',
|
|
'description': 'two.example.com',
|
|
'url': 'https://two.example.com',
|
|
}
|
|
]
|
|
},
|
|
}
|
|
)
|
|
|
|
app = web.Application()
|
|
app.router.add_get('/search', search)
|
|
runner = web.AppRunner(app)
|
|
await runner.setup()
|
|
site = web.TCPSite(runner, '127.0.0.1', unused_tcp_port)
|
|
await site.start()
|
|
monkeypatch.setattr(bravesearch, 'get_delay', lambda: 0)
|
|
|
|
try:
|
|
source = bravesearch.SearchBrave(
|
|
'example.com',
|
|
limit=2,
|
|
credential_adapter=InMemoryCredentialAdapter({'brave': {'key': 'test-token'}}),
|
|
)
|
|
source.server = f'http://localhost:{unused_tcp_port}/search'
|
|
report = await source.process()
|
|
finally:
|
|
await runner.cleanup()
|
|
|
|
assert requests == [('0', None), ('1', 'ready')]
|
|
assert await source.get_hostnames() == ['one.example.com', 'two.example.com']
|
|
assert report == SourceExecutionReport('completed', 'result-limit')
|
|
assert len(sessions) == 1
|
|
assert sessions[0].closed is True
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_censys_pagination_preserves_provider_cookies(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
unused_tcp_port: int,
|
|
) -> None:
|
|
requests: list[tuple[str | None, str | None]] = []
|
|
|
|
async def search(request: web.Request) -> web.Response:
|
|
body = await request.json()
|
|
page_token = body.get('page_token')
|
|
requests.append((page_token, request.cookies.get('provider-session')))
|
|
if page_token is None:
|
|
response = web.json_response(
|
|
{
|
|
'result': {
|
|
'hits': [{'certificate_v1': {'resource': {'names': ['one.example.com']}}}],
|
|
'next_page_token': 'page-two',
|
|
}
|
|
}
|
|
)
|
|
response.set_cookie('provider-session', 'ready')
|
|
return response
|
|
if request.cookies.get('provider-session') != 'ready':
|
|
return web.json_response({'error': 'missing provider session'}, status=403)
|
|
return web.json_response(
|
|
{
|
|
'result': {
|
|
'hits': [{'certificate_v1': {'resource': {'names': ['two.example.com']}}}],
|
|
'next_page_token': '',
|
|
}
|
|
}
|
|
)
|
|
|
|
app = web.Application()
|
|
app.router.add_post('/search', search)
|
|
runner = web.AppRunner(app)
|
|
await runner.setup()
|
|
site = web.TCPSite(runner, '127.0.0.1', unused_tcp_port)
|
|
await site.start()
|
|
monkeypatch.setattr(censysearch.Core, 'censys_key', lambda: ('platform-token', None))
|
|
monkeypatch.setattr(censysearch.SearchCensys, 'SERVER', f'http://localhost:{unused_tcp_port}/search')
|
|
|
|
try:
|
|
source = censysearch.SearchCensys('example.com', limit=2)
|
|
report = await source.process()
|
|
finally:
|
|
await runner.cleanup()
|
|
|
|
assert requests == [(None, None), ('page-two', 'ready')]
|
|
assert await source.get_hostnames() == {'one.example.com', 'two.example.com'}
|
|
assert report is None
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_github_code_pagination_preserves_provider_cookies(
|
|
monkeypatch: pytest.MonkeyPatch,
|
|
unused_tcp_port: int,
|
|
) -> None:
|
|
requests: list[tuple[str | None, str | None]] = []
|
|
|
|
async def search(request: web.Request) -> web.Response:
|
|
page = request.query.get('page')
|
|
requests.append((page, request.cookies.get('provider-session')))
|
|
if page == '1':
|
|
response = web.json_response(
|
|
{'items': [{'text_matches': [{'fragment': 'first@example.com'}]}]},
|
|
headers={'Link': f'<http://localhost:{unused_tcp_port}/search/code?q=example.com&page=2>; rel="next"'},
|
|
)
|
|
response.set_cookie('provider-session', 'ready')
|
|
return response
|
|
if request.cookies.get('provider-session') != 'ready':
|
|
return web.json_response({'error': 'missing provider session'}, status=403)
|
|
return web.json_response({'items': [{'text_matches': [{'fragment': 'second@example.com'}]}]})
|
|
|
|
app = web.Application()
|
|
app.router.add_get('/search/code', search)
|
|
runner = web.AppRunner(app)
|
|
await runner.setup()
|
|
site = web.TCPSite(runner, '127.0.0.1', unused_tcp_port)
|
|
await site.start()
|
|
monkeypatch.setattr(githubcode.Core, 'github_key', lambda: 'github-token')
|
|
monkeypatch.setattr(githubcode, 'get_delay', lambda: 0)
|
|
|
|
async def no_sleep(_seconds: float) -> None:
|
|
return None
|
|
|
|
monkeypatch.setattr(githubcode.asyncio, 'sleep', no_sleep)
|
|
|
|
try:
|
|
source = githubcode.SearchGithubCode('example.com', limit=2)
|
|
source.base_url = f'http://localhost:{unused_tcp_port}/search/code?q=example.com'
|
|
await source.process()
|
|
finally:
|
|
await runner.cleanup()
|
|
|
|
assert requests == [('1', None), ('2', 'ready')]
|
|
assert source.counter == 2
|
|
assert await source.get_emails() == {'first@example.com', 'second@example.com'}
|