mirror of
https://github.com/Horizontal42/netsleuth.git
synced 2026-11-10 22:42:03 +03:00
refactor build_reputation to use ReputationContext dataclass
This commit is contained in:
parent
fc37ff369d
commit
4c290ec309
3 changed files with 52 additions and 39 deletions
|
|
@ -208,6 +208,7 @@ async def _bgp_section(client, settings: Settings, asn: str | None, raw: dict):
|
||||||
async def _reputation_section(client, settings: Settings, options: Options, geo: IpGeo, raw: dict):
|
async def _reputation_section(client, settings: Settings, options: Options, geo: IpGeo, raw: dict):
|
||||||
from netsleuth.reputation import (
|
from netsleuth.reputation import (
|
||||||
build_reputation,
|
build_reputation,
|
||||||
|
ReputationContext,
|
||||||
fetch_abuseipdb,
|
fetch_abuseipdb,
|
||||||
fetch_internetdb,
|
fetch_internetdb,
|
||||||
normalize_internetdb,
|
normalize_internetdb,
|
||||||
|
|
@ -235,6 +236,7 @@ async def _reputation_section(client, settings: Settings, options: Options, geo:
|
||||||
else:
|
else:
|
||||||
warnings.append("ABUSEIPDB_API_KEY not set — abuse score skipped")
|
warnings.append("ABUSEIPDB_API_KEY not set — abuse score skipped")
|
||||||
reputation = build_reputation(
|
reputation = build_reputation(
|
||||||
|
ReputationContext(
|
||||||
internetdb=normalize_internetdb(payload),
|
internetdb=normalize_internetdb(payload),
|
||||||
firehol_hits=index.hits(geo.ip),
|
firehol_hits=index.hits(geo.ip),
|
||||||
dnsbl_outcomes=outcomes,
|
dnsbl_outcomes=outcomes,
|
||||||
|
|
@ -242,6 +244,7 @@ async def _reputation_section(client, settings: Settings, options: Options, geo:
|
||||||
abuseipdb_score=score,
|
abuseipdb_score=score,
|
||||||
abuseipdb_reports=reports,
|
abuseipdb_reports=reports,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
return ModuleResult(
|
return ModuleResult(
|
||||||
name="reputation", status="partial" if warnings else "ok", data=reputation, warnings=warnings
|
name="reputation", status="partial" if warnings else "ok", data=reputation, warnings=warnings
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -208,26 +208,29 @@ def _captcha_risk_full(
|
||||||
return risk, "; ".join(reasons), "; ".join(reasons_ru)
|
return risk, "; ".join(reasons), "; ".join(reasons_ru)
|
||||||
|
|
||||||
|
|
||||||
def build_reputation(
|
@dataclass
|
||||||
internetdb: InternetDbResult | None,
|
class ReputationContext:
|
||||||
firehol_hits: list[str],
|
ip_type: str
|
||||||
dnsbl_outcomes: list[DnsblOutcome] | None,
|
internetdb: InternetDbResult | None
|
||||||
ip_type: str,
|
firehol_hits: list[str]
|
||||||
abuseipdb_score: int | None,
|
dnsbl_outcomes: list[DnsblOutcome] | None
|
||||||
abuseipdb_reports: int | None,
|
abuseipdb_score: int | None
|
||||||
) -> Reputation:
|
abuseipdb_reports: int | None
|
||||||
|
|
||||||
|
|
||||||
|
def build_reputation(ctx: ReputationContext) -> Reputation:
|
||||||
hits: list[DnsblHit] | None = None
|
hits: list[DnsblHit] | None = None
|
||||||
blocked = False
|
blocked = False
|
||||||
if dnsbl_outcomes is not None:
|
if ctx.dnsbl_outcomes is not None:
|
||||||
hits, blocked = summarize_dnsbl(dnsbl_outcomes)
|
hits, blocked = summarize_dnsbl(ctx.dnsbl_outcomes)
|
||||||
risk, rationale, rationale_ru = _captcha_risk_full(firehol_hits, hits or [], ip_type, abuseipdb_score)
|
risk, rationale, rationale_ru = _captcha_risk_full(ctx.firehol_hits, hits or [], ctx.ip_type, ctx.abuseipdb_score)
|
||||||
return Reputation(
|
return Reputation(
|
||||||
internetdb=internetdb,
|
internetdb=ctx.internetdb,
|
||||||
firehol_hits=firehol_hits,
|
firehol_hits=ctx.firehol_hits,
|
||||||
dnsbl_hits=hits,
|
dnsbl_hits=hits,
|
||||||
dnsbl_query_blocked=blocked,
|
dnsbl_query_blocked=blocked,
|
||||||
abuseipdb_score=abuseipdb_score,
|
abuseipdb_score=ctx.abuseipdb_score,
|
||||||
abuseipdb_reports=abuseipdb_reports,
|
abuseipdb_reports=ctx.abuseipdb_reports,
|
||||||
captcha_risk=risk,
|
captcha_risk=risk,
|
||||||
rationale=rationale,
|
rationale=rationale,
|
||||||
rationale_ru=rationale_ru,
|
rationale_ru=rationale_ru,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||||
from netsleuth.reputation import (
|
from netsleuth.reputation import (
|
||||||
NetsetIndex,
|
NetsetIndex,
|
||||||
build_reputation,
|
build_reputation,
|
||||||
|
ReputationContext,
|
||||||
captcha_risk,
|
captcha_risk,
|
||||||
decode_dnsbl,
|
decode_dnsbl,
|
||||||
normalize_internetdb,
|
normalize_internetdb,
|
||||||
|
|
@ -132,6 +133,7 @@ def test_captcha_risk_escalates_on_a_high_abuseipdb_score():
|
||||||
|
|
||||||
def test_build_reputation_marks_the_query_as_blocked_without_inventing_hits(api_fixture):
|
def test_build_reputation_marks_the_query_as_blocked_without_inventing_hits(api_fixture):
|
||||||
rep = build_reputation(
|
rep = build_reputation(
|
||||||
|
ReputationContext(
|
||||||
internetdb=normalize_internetdb(api_fixture("internetdb.json")),
|
internetdb=normalize_internetdb(api_fixture("internetdb.json")),
|
||||||
firehol_hits=[],
|
firehol_hits=[],
|
||||||
dnsbl_outcomes=[decode_dnsbl("zen.spamhaus.org", ["127.255.255.254"])],
|
dnsbl_outcomes=[decode_dnsbl("zen.spamhaus.org", ["127.255.255.254"])],
|
||||||
|
|
@ -139,6 +141,7 @@ def test_build_reputation_marks_the_query_as_blocked_without_inventing_hits(api_
|
||||||
abuseipdb_score=None,
|
abuseipdb_score=None,
|
||||||
abuseipdb_reports=None,
|
abuseipdb_reports=None,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
assert rep.dnsbl_hits == []
|
assert rep.dnsbl_hits == []
|
||||||
assert rep.dnsbl_query_blocked is True
|
assert rep.dnsbl_query_blocked is True
|
||||||
assert rep.captcha_risk == "low"
|
assert rep.captcha_risk == "low"
|
||||||
|
|
@ -146,6 +149,7 @@ def test_build_reputation_marks_the_query_as_blocked_without_inventing_hits(api_
|
||||||
|
|
||||||
def test_build_reputation_without_dnsbl_leaves_the_field_none(api_fixture):
|
def test_build_reputation_without_dnsbl_leaves_the_field_none(api_fixture):
|
||||||
rep = build_reputation(
|
rep = build_reputation(
|
||||||
|
ReputationContext(
|
||||||
internetdb=normalize_internetdb(api_fixture("internetdb.json")),
|
internetdb=normalize_internetdb(api_fixture("internetdb.json")),
|
||||||
firehol_hits=["firehol_level1"],
|
firehol_hits=["firehol_level1"],
|
||||||
dnsbl_outcomes=None,
|
dnsbl_outcomes=None,
|
||||||
|
|
@ -153,6 +157,7 @@ def test_build_reputation_without_dnsbl_leaves_the_field_none(api_fixture):
|
||||||
abuseipdb_score=None,
|
abuseipdb_score=None,
|
||||||
abuseipdb_reports=None,
|
abuseipdb_reports=None,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
assert rep.dnsbl_hits is None
|
assert rep.dnsbl_hits is None
|
||||||
assert rep.dnsbl_query_blocked is False
|
assert rep.dnsbl_query_blocked is False
|
||||||
assert rep.captcha_risk == "high"
|
assert rep.captcha_risk == "high"
|
||||||
|
|
@ -181,6 +186,7 @@ def test_build_reputation_rationale_ru_is_populated_and_cyrillic_for_every_reaso
|
||||||
]
|
]
|
||||||
for case in cases:
|
for case in cases:
|
||||||
rep = build_reputation(
|
rep = build_reputation(
|
||||||
|
ReputationContext(
|
||||||
internetdb=normalize_internetdb(api_fixture("internetdb.json")),
|
internetdb=normalize_internetdb(api_fixture("internetdb.json")),
|
||||||
firehol_hits=case["firehol_hits"],
|
firehol_hits=case["firehol_hits"],
|
||||||
dnsbl_outcomes=case["dnsbl_outcomes"],
|
dnsbl_outcomes=case["dnsbl_outcomes"],
|
||||||
|
|
@ -188,6 +194,7 @@ def test_build_reputation_rationale_ru_is_populated_and_cyrillic_for_every_reaso
|
||||||
abuseipdb_score=case["abuseipdb_score"],
|
abuseipdb_score=case["abuseipdb_score"],
|
||||||
abuseipdb_reports=None,
|
abuseipdb_reports=None,
|
||||||
)
|
)
|
||||||
|
)
|
||||||
assert rep.rationale
|
assert rep.rationale
|
||||||
assert rep.rationale_ru
|
assert rep.rationale_ru
|
||||||
assert has_cyrillic(rep.rationale_ru)
|
assert has_cyrillic(rep.rationale_ru)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue