FR-048 Phase 2a — 授權守門盤點:Misc Group(較小模組)

事實盤點,未做軸線判斷。URL prefix = /api/1.0。@jwt_required 以 route method 上的裝飾器為準。 「現況守門」= app-service 層是否有 role/admin/manager guard(ForbiddenError on role/is_admin/participant.role)。 盤點日期 2026-07-07,branch fix/v1.8.0-bugs

本檔涵蓋含 write method 或敏感 GET 的模組。 跳過(無 write / 無敏感 GET):api/translate(POST 實為翻譯查詢、無寫入無敏感檔)、api/issue(僅 GET get_members)、api/label(僅 GET menu)—— 詳見末段「跳過模組」。


§1

api/cloud_integration

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/integrations/google-drive DELETE api/cloud_integration/routes/google_drive_integration_route.py:41 google_drive_integration_service.disconnect(is_admin=...) 已有: if not is_admin and not _is_super_admin → ForbiddenError(GRC_NOT_ADMIN) @ app/cloud_integration/service/google_drive_integration_service.py:189 admin/super-admin 守門
/api/1.0/integrations/google-drive/auth-url POST api/cloud_integration/routes/google_drive_integration_route.py:58 google_drive_integration_service.build_auth_url(is_admin=...) 已有: if not is_admin → ForbiddenError(GRC_NOT_ADMIN) @ app/cloud_integration/service/google_drive_integration_service.py:66 admin 守門
/api/1.0/integrations/google-drive/callback GET api/cloud_integration/routes/google_drive_integration_route.py:73 google_drive_integration_service.handle_callback(code, state) 無 JWT 刻意公開(OAuth callback);auth 靠 state token(cloud-integrations#2/#4)
/api/1.0/integrations/google-drive/sync-jobs/<uid>/retry POST api/cloud_integration/routes/google_drive_sync_route.py:84 drive_sync_admin_service.manual_retry(is_admin=...) 已有: if not is_admin → ForbiddenError(GRC_NOT_ADMIN) @ app/cloud_integration/service/drive_sync_admin_service.py:110 admin 守門
/api/1.0/integrations/google-drive/projects/<project_uid>/init-folders POST api/cloud_integration/routes/google_drive_sync_route.py:105 drive_sync_admin_service.trigger_init_project_folders(...) 僅 JWT 刻意不加 is_admin gate(避免擋非 tenant-admin 的 project manager)— 註解 @ drive_sync_admin_service.py:127-129
/api/1.0/integrations/google-drive/projects/<project_uid>/verify-and-repair-folders POST api/cloud_integration/routes/google_drive_sync_route.py:136 drive_project_verify_service.verify_and_repair(...) 已有: if participant is None or participant.role != "manager" → ForbiddenError(GRC_NOT_MANAGER) @ app/cloud_integration/service/drive_project_verify_service.py:129 project manager 守門
/api/1.0/integrations/google-drive/tenant/rebuild-all POST api/cloud_integration/routes/google_drive_sync_route.py:164 drive_sync_admin_service.rebuild_all_for_tenant(is_admin=...) 已有: if not is_admin → ForbiddenError(GRC_NOT_ADMIN) @ app/cloud_integration/service/drive_sync_admin_service.py:157 admin 守門;破壞性操作
/api/1.0/integrations/google-drive/webhook/register POST api/cloud_integration/routes/google_drive_sync_route.py:195 webhook_channel_manager.register_for_tenant(...) + orchestration 僅 JWT doc 註明「admin only」但 service 端未見 is_admin guard — 僅 @jwt_required
/api/1.0/webhooks/google-drive/<int:tenant_id> POST api/cloud_integration/routes/google_drive_webhook_route.py:39 google_drive_webhook_service.handle_notification(...) 無 JWT 刻意公開(Drive push webhook);auth 靠 X-Goog-Channel-Token header(永遠回 200)

§2

api/feedback

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/feedbacks POST api/feedback/routes/feedback_route.py:26 feedback_service.get_feedbacks_and_pager(...) 僅 JWT POST 實為分頁查詢(讀)
/api/1.0/feedback POST api/feedback/routes/feedback_route.py:52 feedback_service.add_feedback(...) 僅 JWT 建立 feedback
/api/1.0/feedback/<uid> PUT api/feedback/routes/feedback_route.py:70 feedback_service.update_feedback(...) 僅 JWT 無 owner check
/api/1.0/feedback/<uid> DELETE api/feedback/routes/feedback_route.py:89 feedback_service.delete_feedback(uid, login_name) 僅 JWT 傳 login_name 但無 owner/role gate
/api/1.0/feedback/file/<uid>/<file_uid> DELETE api/feedback/routes/feedback_route.py:99 feedback_service.delete_feedback_file(uid, file_uid) 僅 JWT 無 owner check
/api/1.0/feedback/export/<export_type> POST api/feedback/routes/feedback_route.py:108 feedback_service.export_feedbacks(export_type) 僅 JWT 敏感 GET 性質(匯出全站 feedback),但為 POST

§3

api/system_config

SystemConfigService = jedi 套件 jedi_system_config.app.service.system_config_service;全數 method 皆無 role/admin guard(僅 JWT)。

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/system/configs/<group> GET api/system_config/routes/system_config_route.py:25 system_config_service.get_system_config_by_group(group) 僅 JWT 敏感 GET — value dict 含 secret 無遮罩,SMTP/LDAP/issue-integration token 明文回傳(jedi_system_config/.../system_config_service.py:43 無 mask)
/api/1.0/system/config/<uid> GET api/system_config/routes/system_config_route.py:44 system_config_service.get_system_config(uid) 僅 JWT 敏感 GET;同上,secret 明文
/api/1.0/system/config POST api/system_config/routes/system_config_route.py:58 system_config_service.create_system_config(payload) 僅 JWT 系統級設定寫入,無 admin gate
/api/1.0/system/config/<uid> PUT api/system_config/routes/system_config_route.py:72 system_config_service.update_system_config(uid, payload) 僅 JWT 系統級設定改寫,無 admin gate
/api/1.0/system/config/<uid> DELETE api/system_config/routes/system_config_route.py:86 system_config_service.delete_system_config(uid) 僅 JWT 無 admin gate
/api/1.0/system/config/<group>/<key> GET api/system_config/routes/system_config_route.py:97 system_config_service.get_system_config_by_key(group, key) 僅 JWT 敏感 GET;secret 明文回傳
/api/1.0/system/config/<group>/<key> PUT api/system_config/routes/system_config_route.py:111 system_config_service.update_config_by_group_key(group, key, payload) 僅 JWT 無 admin gate
/api/1.0/system/config/<group>/<key> DELETE api/system_config/routes/system_config_route.py:126 system_config_service.delete_config_by_group_key(group, key) 僅 JWT 無 admin gate

§4

api/system_menu

SystemMenuService = jedi 套件 jedi_system_menu;write method 皆無 role/admin guard(僅 JWT)。

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/system/menus POST api/system_menu/routes/system_menu_route.py:38 system_menu_service.get_system_manus_and_pager(...) 僅 JWT POST 實為分頁查詢(讀)
/api/1.0/system-menu POST api/system_menu/routes/system_menu_route.py:67 system_menu_service.add_system_menu(**payload) 僅 JWT 系統選單新增,無 admin gate
/api/1.0/system-menu/<int:id> PUT api/system_menu/routes/system_menu_route.py:78 system_menu_service.update_system_menu(id, **payload) 僅 JWT 無 admin gate
/api/1.0/system-menu/<int:id> DELETE api/system_menu/routes/system_menu_route.py:88 system_menu_service.delete_system_menu(id) 僅 JWT 無 admin gate

§5

api/information_system

InformationSystemService / InformationSystemAppService = 本地 app/information_system/...;write method 無 role/owner guard(僅 JWT)。

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/information-systems/list POST api/information_system/routes/information_system_route.py:59 information_system_app_service.get_information_systems_and_pager(...) 僅 JWT POST 實為分頁查詢(讀)
/api/1.0/information-systems POST api/information_system/routes/information_system_route.py:90 information_system_service.add_information_system(...) 僅 JWT 建立,無 role gate
/api/1.0/information-system/<uid> PUT api/information_system/routes/information_system_route.py:137 information_system_service.update_information_system(...) 僅 JWT 無 owner/role gate
/api/1.0/information-system/<uid> DELETE api/information_system/routes/information_system_route.py:161 information_system_service.delete_information_system(uid, user) 僅 JWT 傳 login_name 但無 owner/role gate

§6

api/evidence_classification

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/project/<project_uid>/ap/<ap_uid>/classify-evidence POST api/evidence_classification/routes/evidence_classification_route.py:42 service.trigger_classify(...) 已有: if participant is None or participant.role != "manager" → ForbiddenError(EC_NOT_MANAGER) @ app/evidence_classification/service/evidence_classification_service.py:167 project manager 守門
/api/1.0/classification-run/<run_folder_id>/state PUT api/evidence_classification/routes/evidence_classification_route.py:141 service.put_state(run_folder_id, body, user.id) 僅 JWT _resolve_tenant_for_run_folder(tenant 解析,非 role gate)@ evidence_classification_service.py:737
/api/1.0/classification-run/<run_folder_id>/archive POST api/evidence_classification/routes/evidence_classification_route.py:161 service.archive_run(run_folder_id, user.id) 僅 JWT 同上,僅 tenant 解析非 role gate
/api/1.0/classification-ground-truth POST api/evidence_classification/routes/evidence_classification_route.py:237 service.import_ground_truth(...) 僅 JWT GT 灌入,無 admin/role gate

敏感 GET(下載/報表/預覽)— 皆 @jwt_required,僅 tenant 解析非 role gate:

  • GET /classification-run/<id>/file/<file_drive_id>/preview(route:178,檔案 bytes 串流)
  • GET /classification-run/<id>/report/validation(route:203)
  • GET /classification-run/<id>/report/adjudication(route:220)

§7

api/device

DeviceAppService = 本地 app/device/...;write method 無 owner check(context 已知坑「device has no owner check」)。

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/devices POST api/device/routes/device_route.py:27 device_app_service.get_devices_and_pager(...) 僅 JWT POST 實為分頁查詢(讀)
/api/1.0/device POST api/device/routes/device_route.py:68 device_app_service.add_device(user, **payload) 僅 JWT 建立
/api/1.0/device/<uid> PUT api/device/routes/device_route.py:81 device_app_service.update_device(uid, user, <strong>payload) 僅 JWT 無 owner check**
/api/1.0/device/<uid> DELETE api/device/routes/device_route.py:93 device_app_service.delete_device(uid, user) 僅 JWT 無 owner check

§8

api/bulletin

BulletinService = 本地 app/bulletin/...;write method 無 role/owner guard(裸奔)。

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/bulletins POST api/bulletin/routes/bulletin_route.py:27 bulletin_service.get_bulletins_and_pager(...) 僅 JWT POST 實為分頁查詢(讀)
/api/1.0/bulletin POST api/bulletin/routes/bulletin_route.py:55 bulletin_service.add_bulletin(user, **payload) 僅 JWT 建立公告,無 admin gate
/api/1.0/bulletin/<uid> PUT api/bulletin/routes/bulletin_route.py:67 bulletin_service.update_bulletin(uid, user, **payload) 僅 JWT 無 owner/role gate
/api/1.0/bulletin/<uid> DELETE api/bulletin/routes/bulletin_route.py:78 bulletin_service.delete_bulletin(uid) 僅 JWT 無 owner/role gate

§9

api/uploadfile

FileUploadService / UploadFileService = jedi 套件 jedi_file_upload;upload/delete 無 owner check(僅 JWT)。

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/file/upload POST api/uploadfile/routes/uploadfile_route.py:34 file_upload_service.upload_files([file], login_name, save_dir) 僅 JWT 單檔上傳
/api/1.0/file/upload/<uid> DELETE api/uploadfile/routes/uploadfile_route.py:54 file_upload_service.delete_file(uid) 僅 JWT 無 owner checkjedi_file_upload/.../file_upload_service.py:93
/api/1.0/file/uploads POST api/uploadfile/routes/uploadfile_route.py:63 file_upload_service.upload_files(files, login_name, save_dir) 僅 JWT 多檔上傳
/api/1.0/file/download/<uid> GET api/uploadfile/routes/uploadfile_route.py:81 upload_file_service.get_upload_file(uid)send_file 無 JWT 敏感 GET — 檔案下載,無 JWT 且無 owner check(任意 uid 可下載)
/api/1.0/file/pdf-preview/<uid> GET api/uploadfile/routes/uploadfile_route.py:108 file_upload_service.convert_to_pdf/get_upload_file(uid)send_file 無 JWT 敏感 GET — PDF 預覽下載,無 JWT 且無 owner check

§10

api/notification

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/notification POST api/notification/routes/notification_route.py:22 notification_service.send_discord/telegram_notification("test...") 僅 JWT 測試發送端點(寫死 "test from Raymond"),無 admin gate
/api/1.0/mail/test POST api/notification/routes/mail_route.py:25 test_mail_service.send_test_mail(mail_to, smtp_config, change_pwd) 僅 JWT 測試寄信,收 SMTP config,無 admin gate

§11

api/notify_config

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/notify-config/<channel>/test POST api/notify_config/routes/notify_config_route.py:21 notify_config_test_service.test_channel(...) 已有: if not user or not user.is_admin → ForbiddenError(NOTIFY_CHANNEL_TEST_FORBIDDEN) @ app/notify_config/service/notify_config_test_service.py:56 admin 守門

§12

api/ai

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/ai-chatbot POST api/ai/routes/ai_bot_route.py:19 AiBotService().chat(user.id, session_id, message) 僅 JWT 對話端點,作用於自身 user.id
/api/1.0/ai-chatbot DELETE api/ai/routes/ai_bot_route.py:45 AiBotService().clear_history(user.id, session_id) 僅 JWT 清自身 session 記錄(scoped by user.id)

§13

api/ai_dashboard

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/ai-dashboard/health GET api/ai_dashboard/routes/ai_dashboard_route.py:56 (無 service,回靜態 config) 無 JWT 刻意公開(health);前端 onMounted 呼叫;回靜態 provider/speed 清單
/api/1.0/ai-dashboard/auto-generate POST api/ai_dashboard/routes/ai_dashboard_route.py:91 ai_dashboard_app_service.generate_dashboard_auto(...) 僅 JWT 呼叫 LLM 生成,作用於自身 user context

§14

api/report

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/schedule-report/file-list POST api/report/routes/scheduler_report_route.py:21 (route 內直接讀檔系統目錄,無 service) 僅 JWT POST 實為檔案清單查詢(讀);依 payload 拼 SCHEDULE_REPORT_DIR 路徑
/api/1.0/schedule-report/preview GET api/report/routes/scheduler_report_route.py:42 (route 內 send_file(report_path),無 service) 無 JWT 敏感 GET — 檔案下載/預覽,無 JWT;path 由 query param 拼接(report_name/type/file_name),無 owner/tenant 隔離

§15

api/log

Route path Method Route file:line @jwt_required? 呼叫的 service method 現況守門 備註
/api/1.0/log/api-logs POST api/log/routes/api_log_route.py:26 api_log_service.get_devices_and_pager(...) 僅 JWT POST 實為分頁查詢(讀);操作日誌列表
/api/1.0/log/api-logs/export GET api/log/routes/api_log_route.py:53 api_log_service.export_api_log_file() 僅 JWT 敏感 GET — 匯出操作日誌 zip@jwt_required() 已於 commit 182bb2f7 (SEC-001) 恢復,現況存在(route:52)

§16

跳過模組(無 write / 無敏感 GET)

Module 唯一端點 Method @jwt_required? 說明
api/translate /api/1.0/translate POST 是(translate_route.py:41 翻譯查詢(呼叫 OpenAI),非資料寫入、非敏感檔案匯出 — 依「write / sensitive GET」定義不列入,但 POST 實為查詢動作。若採嚴格 write 定義則歸此類跳過。
api/issue /api/1.0/issue/get_members GET issue_member_route.py:8,class/method 均無 @jwt_required 讀取成員清單。注意:無 JWT — 純讀但完全裸奔。
api/label /api/1.0/labels/menu/<scope> GET 是(label_route.py:16 讀取 label menu,非敏感。