Integrate GST operator agent authenticated browser download flow

This commit is contained in:
A R R R Associates
2026-09-11 22:14:52 +05:30
parent b361a66e44
commit 756daf67da
4 changed files with 338 additions and 101 deletions
@@ -147,7 +147,7 @@ router = APIRouter(prefix="/tools/accounting/gst-reconciliation", tags=["account
_TOKEN_PURPOSE = "gst_lightweight_operator_v3"
_TOKEN_MINUTES = 15
_UPLOAD_ROOT = Path(tempfile.gettempdir()) / "audit_firm_gst_operator_uploads"
_OPERATOR_AGENT_VERSION = "1.1.0"
_OPERATOR_AGENT_VERSION = "1.2.0"
_OPERATOR_RUNTIME_ROOT = Path(__file__).resolve().parent / "gst_operator_agent_runtime"
_OPERATOR_PACKAGE_FILES = ("gst_operator_agent.py", "requirements.txt", "README.txt", "install_gst_operator_agent.ps1", "uninstall_gst_operator_agent.ps1")
@@ -444,6 +444,14 @@ def download_operator_agent(request: Request):
db.close()
def _operator_public_base_url(request: Request) -> str:
proto = str(request.headers.get("x-forwarded-proto") or request.url.scheme or "https").split(",")[0].strip()
host = str(request.headers.get("x-forwarded-host") or request.headers.get("host") or request.url.netloc).split(",")[0].strip()
if not host:
return "https://office.arrrassociates.com"
return f"{proto}://{host}".rstrip("/")
@router.post("/download/start")
def start_download(
request: Request,
@@ -483,6 +491,7 @@ def start_download(
"node_code":str(node.node_code),"client_id":int(client.id),"client_name":str(client.client_name or ""),
"registration_id":int(reg.id),"credential_id":int(cred.id),"gstin":gstin,"financial_year":financial_year,
"periods":periods,"return_types":return_types,"gst_relative_dir":gst_dir,"accounting_relative_dir":accounting_dir,
"erp_base_url":_operator_public_base_url(request),
})
log_access(db,request,user,cred,"use_for_gst_download",reason=f"GST returns {financial_year}: {','.join(return_types)}",fields="username,secret",success=True)
db.commit()
@@ -510,7 +519,7 @@ async def operator_redeem(request: Request):
raise ValueError("GST username/password is missing in Credential Vault.")
finally:
db.close()
return JSONResponse({"ok":True,"payload":{**{k:v for k,v in data.items() if k not in {"iat","exp","purpose"}},"username":username,"password":password,"upload_url":str(get_settings().ERP_PUBLIC_BASE_URL).rstrip("/")+"/tools/accounting/gst-reconciliation/operator/upload","login_timeout_seconds":900,"operator_agent_min_version":_OPERATOR_AGENT_VERSION}})
return JSONResponse({"ok":True,"payload":{**{k:v for k,v in data.items() if k not in {"iat","exp","purpose"}},"username":username,"password":password,"upload_url":str(data.get("erp_base_url") or "https://office.arrrassociates.com").rstrip("/")+"/tools/accounting/gst-reconciliation/operator/upload","login_timeout_seconds":900,"operator_agent_min_version":_OPERATOR_AGENT_VERSION}})
except Exception as exc:
return JSONResponse({"ok":False,"error":str(exc)},status_code=400)