diff options
| author | Max Nanis | 2026-03-06 16:49:46 -0500 |
|---|---|---|
| committer | Max Nanis | 2026-03-06 16:49:46 -0500 |
| commit | 91d040211a4ed6e4157896256a762d3854777b5e (patch) | |
| tree | cd95922ea4257dc8d3f4e4cbe8534474709a20dc /generalresearch/grliq/managers/forensic_results.py | |
| download | generalresearch-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.py | 104 |
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 |
