| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- import logging
- import uuid
- from constants import BIND_HINT
- from tools.bind_auth_code import BindAuthCodeTool
- from tools.query_order import QueryOrderTool
- from tools.query_track import QueryTrackTool
- from utils.security import hash_gateway_session_id
- logger = logging.getLogger(__name__)
- class PublicGatewayApp:
- def __init__(self, session_store, api_client, auth_client):
- self.session_store = session_store
- self.api_client = api_client
- self.auth_client = auth_client
- self._tools = {
- 'bind_auth_code': BindAuthCodeTool(auth_client=None),
- 'query_order': QueryOrderTool(api_client=None),
- 'query_track': QueryTrackTool(api_client=None),
- }
- def list_tools(self):
- return [tool.metadata() for tool in self._tools.values()]
- def build_request_id(self, request_id=''):
- request_id = str(request_id or '').strip()
- return request_id or 'rq_{0}'.format(uuid.uuid4().hex[:16])
- def bind_auth_code(self, gateway_session_id, auth_code):
- if self.auth_client is None:
- raise RuntimeError('auth client is required')
- session_hash = hash_gateway_session_id(gateway_session_id)[:12]
- logger.info(f"[AUDIT] bind_auth_code: session_hash={session_hash}, auth_code_provided={bool(auth_code)}")
- result = self.auth_client.exchange(gateway_session_id, auth_code)
- if result.get('code') == 'MCP_0000':
- session = self.session_store.get(gateway_session_id)
- admin_id = session.get('admin_id') if session else None
- company_id = session.get('company_id') if session else None
- logger.info(f"[AUDIT] bind_success: session_hash={session_hash}, admin_id={admin_id}, company_id={company_id}")
- else:
- logger.warning(f"[AUDIT] bind_failed: session_hash={session_hash}, code={result.get('code')}, msg={result.get('msg')}")
- return result
- def call_tool(self, gateway_session_id, name, arguments=None, request_id=''):
- if name == 'bind_auth_code':
- auth_code = (arguments or {}).get('auth_code', '')
- return self.bind_auth_code(gateway_session_id, auth_code)
- if name not in self._tools:
- raise KeyError('tool not registered: {0}'.format(name))
- session = self.session_store.get(gateway_session_id)
- if not session or not session.get('mcp_token'):
- raise RuntimeError(BIND_HINT)
- tool = self._tools[name]
- request_id = self.build_request_id(request_id)
- session_hash = hash_gateway_session_id(gateway_session_id)[:12]
- admin_id = session.get('admin_id')
- company_id = session.get('company_id')
- logger.info(f"[AUDIT] tool_call: session_hash={session_hash}, admin_id={admin_id}, company_id={company_id}, tool={name}, request_id={request_id}")
- try:
- result = self.api_client.call_tool(
- token=session['mcp_token'],
- tool_code=tool.name,
- route_path=tool.route_path,
- payload=arguments or {},
- request_id=request_id,
- )
- logger.info(f"[AUDIT] tool_success: session_hash={session_hash}, tool={name}, request_id={request_id}, code={result.get('code')}")
- return result
- except Exception as e:
- logger.error(f"[AUDIT] tool_error: session_hash={session_hash}, tool={name}, request_id={request_id}, error={str(e)}")
- raise
|