fix feishu reauth for online docs
This commit is contained in:
+54
-11
@@ -1132,6 +1132,7 @@ class SessionUpdate(BaseModel):
|
||||
|
||||
class FeishuAccountRequest(BaseModel):
|
||||
account_id: str | None = None
|
||||
force: bool = False
|
||||
|
||||
|
||||
class FeishuOnlineDocRequest(BaseModel):
|
||||
@@ -1616,7 +1617,7 @@ def create_app(state: AgentState) -> FastAPI:
|
||||
|
||||
@app.post('/api/integrations/feishu/login')
|
||||
async def feishu_login(payload: FeishuAccountRequest) -> dict[str, Any]:
|
||||
return _start_feishu_login(state, payload.account_id)
|
||||
return _start_feishu_login(state, payload.account_id, force=payload.force)
|
||||
|
||||
@app.post('/api/integrations/feishu/logout')
|
||||
async def feishu_logout(payload: FeishuAccountRequest) -> dict[str, Any]:
|
||||
@@ -1684,6 +1685,20 @@ def create_app(state: AgentState) -> FastAPI:
|
||||
except OSError as exc:
|
||||
raise HTTPException(status_code=400, detail=f'读取文件失败: {exc}')
|
||||
except Exception as exc:
|
||||
if _is_feishu_auth_error(str(exc)):
|
||||
_stop_feishu_login(payload.account_id)
|
||||
logout_result = _run_feishu_cli(paths, ['logout'], timeout_seconds=30)
|
||||
status = _feishu_status_payload(state, payload.account_id)
|
||||
status['logout_output'] = logout_result.get('output')
|
||||
raise HTTPException(
|
||||
status_code=409,
|
||||
detail={
|
||||
'code': 'feishu_auth_expired',
|
||||
'message': '飞书登录已过期或未登录,请重新授权后再转换。',
|
||||
'force_login': True,
|
||||
'status': status,
|
||||
},
|
||||
)
|
||||
target_name = '飞书表格' if kind == 'sheet' else '飞书文档'
|
||||
raise HTTPException(status_code=502, detail=f'{target_name}创建失败: {exc}')
|
||||
url = _extract_first_url(rendered)
|
||||
@@ -4379,16 +4394,36 @@ def _run_feishu_cli(
|
||||
}
|
||||
|
||||
|
||||
def _is_feishu_auth_error(text: str) -> bool:
|
||||
lowered = text.lower()
|
||||
markers = (
|
||||
'not logged in',
|
||||
'no credentials',
|
||||
'unauthorized',
|
||||
'unauthenticated',
|
||||
'login expired',
|
||||
'token expired',
|
||||
'invalid token',
|
||||
'access token expired',
|
||||
'refresh token expired',
|
||||
'登录已过期',
|
||||
'授权已过期',
|
||||
'未登录',
|
||||
'未授权',
|
||||
'凭证已过期',
|
||||
'认证失败',
|
||||
'请重新登录',
|
||||
'重新授权',
|
||||
)
|
||||
return any(marker in lowered for marker in markers)
|
||||
|
||||
|
||||
def _feishu_status_payload(state: AgentState, account_id: str | None) -> dict[str, Any]:
|
||||
paths = _feishu_paths(state, account_id)
|
||||
_reap_feishu_login(account_id)
|
||||
result = _run_feishu_cli(paths, ['status'], timeout_seconds=30)
|
||||
output = str(result.get('output') or '')
|
||||
lowered = output.lower()
|
||||
logged_in = result.get('returncode') == 0 and not any(
|
||||
marker in lowered
|
||||
for marker in ('not logged in', '未登录', 'no credentials')
|
||||
)
|
||||
logged_in = result.get('returncode') == 0 and not _is_feishu_auth_error(output)
|
||||
pending = _feishu_login_snapshot(account_id)
|
||||
payload: dict[str, Any] = {
|
||||
'logged_in': logged_in,
|
||||
@@ -4405,15 +4440,21 @@ def _feishu_status_payload(state: AgentState, account_id: str | None) -> dict[st
|
||||
return payload
|
||||
|
||||
|
||||
def _start_feishu_login(state: AgentState, account_id: str | None) -> dict[str, Any]:
|
||||
status = _feishu_status_payload(state, account_id)
|
||||
if status.get('logged_in'):
|
||||
return status
|
||||
def _start_feishu_login(
|
||||
state: AgentState,
|
||||
account_id: str | None,
|
||||
*,
|
||||
force: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
if not force:
|
||||
status = _feishu_status_payload(state, account_id)
|
||||
if status.get('logged_in'):
|
||||
return status
|
||||
|
||||
key = _feishu_login_key(account_id)
|
||||
with _FEISHU_LOGIN_LOCK:
|
||||
existing = _FEISHU_LOGIN_PROCESSES.get(key)
|
||||
if existing is not None and existing.process.poll() is None:
|
||||
if not force and existing is not None and existing.process.poll() is None:
|
||||
return {
|
||||
'logged_in': False,
|
||||
'status': 'login_pending',
|
||||
@@ -4422,6 +4463,8 @@ def _start_feishu_login(state: AgentState, account_id: str | None) -> dict[str,
|
||||
_FEISHU_LOGIN_PROCESSES.pop(key, None)
|
||||
|
||||
paths = _feishu_paths(state, account_id)
|
||||
if force:
|
||||
_run_feishu_cli(paths, ['logout'], timeout_seconds=30)
|
||||
env = os.environ.copy()
|
||||
env.update(_feishu_env(paths))
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user