aboutsummaryrefslogtreecommitdiff
path: root/generalresearch/grliq/managers/forensic_results.py
diff options
context:
space:
mode:
authorMax Nanis2026-03-06 16:49:46 -0500
committerMax Nanis2026-03-06 16:49:46 -0500
commit91d040211a4ed6e4157896256a762d3854777b5e (patch)
treecd95922ea4257dc8d3f4e4cbe8534474709a20dc /generalresearch/grliq/managers/forensic_results.py
downloadgeneralresearch-91d040211a4ed6e4157896256a762d3854777b5e.tar.gz
generalresearch-91d040211a4ed6e4157896256a762d3854777b5e.zip
Initial commitv3.3.4
Diffstat (limited to 'generalresearch/grliq/managers/forensic_results.py')
-rw-r--r--generalresearch/grliq/managers/forensic_results.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/generalresearch/grliq/managers/forensic_results.py b/generalresearch/grliq/managers/forensic_results.py
new file mode 100644
index 0000000..dd1b039
--- /dev/null
+++ b/generalresearch/grliq/managers/forensic_results.py
@@ -0,0 +1,104 @@
+from datetime import datetime
+from typing import Optional, List, Collection, Dict, Tuple
+
+from generalresearch.grliq.models.forensic_result import (
+ GrlIqForensicCategoryResult,
+ Phase,
+)
+from generalresearch.grliq.models.useragents import GrlUserAgent
+from generalresearch.models.thl.user import User
+from generalresearch.pg_helper import PostgresConfig
+
+
+class GrlIqCategoryResultsReader:
+ def __init__(self, postgres_config: PostgresConfig):
+ self.postgres_config = postgres_config
+
+ def filter_category_results(
+ self,
+ session_uuid: Optional[str] = None,
+ fingerprint: Optional[str] = None,
+ phase: Optional[Phase] = None,
+ uuids: Optional[Collection[str]] = None,
+ product_ids: Optional[Collection[str]] = None,
+ created_since: Optional[datetime] = None,
+ created_between: Optional[Tuple[datetime, datetime]] = None,
+ user: Optional[User] = None,
+ limit: Optional[int] = None,
+ ) -> List[Dict]:
+ """
+ For retrieving GrlIqForensicCategoryResult objects from db.
+ :return: List of Dict. Keys are below in the 'select_str'.
+ """
+ select_str = (
+ "id, uuid, session_uuid, product_id, product_user_id, created_at,"
+ " country_iso, client_ip, phase, data,"
+ " data->>'user_agent_str' AS user_agent_str,"
+ " category_result, is_attempt_allowed, fraud_score"
+ )
+ if not limit:
+ limit = 5000
+
+ filters = []
+ params = {}
+ if session_uuid:
+ params["session_uuid"] = session_uuid
+ filters.append("d.session_uuid = %(session_uuid)s")
+ if fingerprint:
+ params["fingerprint"] = fingerprint
+ filters.append("d.fingerprint = %(fingerprint)s")
+ if phase:
+ params["phase"] = phase.value
+ filters.append("d.phase = %(phase)s")
+ if product_ids:
+ params["product_ids"] = product_ids
+ filters.append("d.product_id = ANY(%(product_ids)s::UUID[])")
+ if uuids:
+ params["uuids"] = uuids
+ filters.append("d.uuid = ANY(%(uuids)s)")
+ if created_since:
+ params["created_since"] = created_since
+ filters.append(
+ "d.created_at >= %(created_since)s::timestamp with time zone"
+ )
+ if created_between:
+ assert (
+ created_since is None
+ ), "Cannot pass both created_until and created_between"
+ params["created_since"] = created_between[0]
+ params["created_until"] = created_between[1]
+ filters.append(
+ "d.created_at BETWEEN %(created_since)s::timestamptz AND %(created_until)s::timestamptz"
+ )
+ if user:
+ assert product_ids is None, "Cannot pass both product_ids and user"
+ params["product_id"] = user.product_id
+ params["product_user_id"] = user.product_user_id
+ filters.append(
+ "(d.product_id = %(product_id)s AND d.product_user_id = %(product_user_id)s)"
+ )
+ filter_str = " AND ".join(filters)
+ filter_str = "WHERE " + filter_str if filter_str else ""
+ query = f"""
+ SELECT {select_str}
+ FROM grliq_forensicdata d
+ {filter_str}
+ ORDER BY created_at DESC LIMIT {limit}
+ """
+ with self.postgres_config.make_connection() as conn:
+ with conn.cursor() as c:
+ c.execute(query, params)
+ res = c.fetchall()
+
+ for x in res:
+ x["client_ip"] = str(x["client_ip"])
+ x["category_result"] = (
+ GrlIqForensicCategoryResult.model_validate(x["category_result"])
+ if x["category_result"]
+ else None
+ )
+ if x.get("user_agent_str"):
+ x["user_agent"] = GrlUserAgent.from_ua_str(x["user_agent_str"])
+ x.pop("user_agent_str", None)
+
+ return res