""" 安全模块。 """ import asyncio import json from tornado.httpclient import HTTPResponse, HTTPRequest import apps import dock from dock.oa import oa_api from models.token import TokenModel from paste.core import config from paste.core.logging import echo_log from paste.util import udict from paste.web import requests async def login(): """ 登录 DCM 系统并获取认证 Token 和响应数据。 Args: 无参数。 Returns: tuple: 包含两个元素的元组: - str: 请求头中的 Token 字符串(如 "JSESSIONID=abc; ...") - dict: DCM 接口返回的完整 JSON 响应数据 Raises: AssertionError: 登录失败(`token` 为 '-1') ValueError: 响应体非合法 JSON HTTPError: 网络请求失败(由 `async_request` 抛出) """ _username = config.get_config(f"dock.oa.env.{apps.get_active_env()}.username") _password = config.get_config(f"dock.oa.env.{apps.get_active_env()}.password") _login_name = config.get_config(f"dock.oa.env.{apps.get_active_env()}.login_name") login_url = f"{oa_api.ApiUrl}/token/{_username}/{_password}?loginName={_login_name}" # 构建扩展头 user_agent, browser_ver, os_name = dock.get_random_user_agent() extra_headers = { 'User-Agent': user_agent, } # 构造请求 request_body = {} # 构造请求对象 request = dock.new_http_request( url=login_url, body=request_body, method='GET', timeout=dock.DEFAULT_TIMEOUT, use_form=True, extra_headers=extra_headers, ) queue = asyncio.Queue() await queue.put(request) await requests.async_concurrency( queue, con_count=1, retry=dock.MAX_RETRY_COUNT, after_request=after_login ) async def after_login(response: HTTPResponse, retry_queue: asyncio.Queue[HTTPRequest]): response_body = response.body.decode() response_data = json.loads(response_body) token = udict.get_by_path(response_data, 'id', '') if token and token != '-1': await TokenModel.refresh(platform=f'{oa_api.TokenPlatform}', token=token) echo_log(f"成功刷新 OA 登录令牌.") else: echo_log(f"OA 登录失败,无法刷新令牌,响应:{response_body}") if retry_queue: echo_log(f"登录重试队列中有:{retry_queue.qsize()} 个请求在等待.") return response_data, token async def get_token(platform: str = 'OA'): """ 取得可用 Cookies。 :param platform: 要查询的平台,默认是:OA :return: Cookies 字符串 """ _token = await TokenModel.find_by_platform(platform) return _token.token if __name__ == "__main__": from paste.core import aio_pool _runner = aio_pool.get_aio_runner() _runner(login())