mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 13:40:45 +00:00
2.3.0:手表界面精简 + 播放器 + 鼠标重做
手表端 - 功能页从 10 个杂项精简到 7 个(屏幕/鼠标/媒体/文件/电脑/语音/电源) - 删掉:游戏封锁、待办、掷骰子、抽奖、壁纸、显示器开关、定时关机、 剪贴板历史、性能/磁盘/电量、文件夹浏览、教室限制等 - 改成显式列按钮,不再把电脑端所有功能组无脑铺到表盘 - 远程鼠标控制重做:滑动区 + 左键/滚轮/右键三按钮 滚轮点按=中键、上下滑=滚动 - 新增视频/音乐播放器(手表本地播放):进度拖动、左右滑快进退10秒、 点画面播放暂停、上一/下一、播完自动下一首 电脑端 - 新增 kill_all(结束所有进程),白名单保护系统关键进程和自身 - 新增 media_list / media_pull(播放器数据源) 安全边界:只允许媒体目录,用 relative_to 判断,防同前缀兄弟目录绕过 中转站 - known_devices 从 ID 集合改成「设备ID -> 配对码」映射 - 修复:管理员改码后关机超过 6 小时,改码会被超时清理冲掉 - 老格式 state 文件平滑升级
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
r'''Halo 登录(第三版):处理 CSRF,然后发文章。
|
||||
|
||||
== 前面两次为什么失败 ==
|
||||
|
||||
第一版:`Authorization: Basic` -> **302**(Halo 的 console API 不认 Basic,
|
||||
它要会话 cookie 或 Personal Access Token)
|
||||
第二版:直接 POST `/login` -> **403**(Spring Security 的 CSRF 保护)
|
||||
|
||||
== 这一版 ==
|
||||
|
||||
走完整的网页登录流程:
|
||||
|
||||
1. GET /login -> 拿 SESSION cookie + HTML 里的 _csrf token
|
||||
2. POST /login -> 带上 cookie + _csrf + 用户名密码
|
||||
3. 用返回的会话 cookie 调 console API
|
||||
|
||||
CSRF token 通常在登录页的 HTML 里(`<input name="_csrf">` 或 `<meta>`)。
|
||||
Halo 的登录页是 SPA 还是服务端渲染会影响它在不在 —— 所以脚本会
|
||||
**两种都找**,找不到就明确报出来,不瞎猜。
|
||||
|
||||
== 如果还是不行 ==
|
||||
|
||||
那就得让用户在 Halo 后台建一个**个人令牌**(设置 -> 个人令牌),
|
||||
拿到之后 `Authorization: Bearer <token>` 就能用。
|
||||
那是最可靠的方式 —— 30 秒的事,而且不用把密码给脚本。
|
||||
'''
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
sys.path.insert(0, str(ROOT / "_build"))
|
||||
from lssh import run # noqa: E402
|
||||
|
||||
PWFILE = ROOT / "_build" / ".halo_password"
|
||||
USER = "xmz7891"
|
||||
|
||||
|
||||
def main() -> int:
|
||||
print("=" * 62)
|
||||
print(" Halo 登录(带 CSRF)")
|
||||
print("=" * 62)
|
||||
print()
|
||||
|
||||
pw = PWFILE.read_text(encoding="utf-8").strip()
|
||||
|
||||
out = run(r'''
|
||||
rm -f /tmp/hc.txt /tmp/login.html
|
||||
|
||||
echo "── 1. GET /login(拿 cookie + csrf token)──"
|
||||
curl -s -c /tmp/hc.txt -o /tmp/login.html \
|
||||
-w " HTTP %{http_code} %{size_download} 字节 Content-Type: %{content_type}\n" \
|
||||
--max-time 15 http://127.0.0.1:3001/login
|
||||
|
||||
echo " cookie:"
|
||||
grep -v '^#' /tmp/hc.txt 2>/dev/null | while read -r a b c d e f g; do
|
||||
[ -n "$f" ] && echo " $f"
|
||||
done
|
||||
[ -s /tmp/hc.txt ] || echo " (没拿到 cookie)"
|
||||
|
||||
echo
|
||||
echo " HTML 里找 csrf token:"
|
||||
grep -oiE '(<input[^>]*name="_csrf"[^>]*>|name="_csrf"[^>]*value="[^"]*"|"csrf[a-zA-Z]*"\s*:\s*"[^"]*"|csrf-token[^>]*content="[^"]*")' /tmp/login.html 2>/dev/null | head -5 | sed 's/^/ /'
|
||||
echo " HTML 前 400 字:"
|
||||
head -c 400 /tmp/login.html | tr -d '\n' | sed 's/^/ /'
|
||||
echo
|
||||
echo
|
||||
echo " title:"
|
||||
grep -oiE '<title>[^<]*</title>' /tmp/login.html 2>/dev/null | head -2 | sed 's/^/ /'
|
||||
''', timeout=240, quiet=True)
|
||||
print(out[1] if isinstance(out, tuple) else out)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user