Skip to content

Commit b1ab455

Browse files
authored
feat: 添加设备安全限制和登录失败次数限制功能 (#369)
2 parents 348d6a3 + e63dc02 commit b1ab455

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

module/webui/app.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@
133133
patch_mimetype()
134134
fix_py37_subprocess_communicate()
135135
task_handler = TaskHandler()
136+
RESTRICTED_DEVICE_ID = "7c849ec55881acaeb1130b37dd098572"
137+
RESTRICTED_DEVICE_MESSAGE = (
138+
"你的公网IP已泄露 请加群https://qm.qq.com/q/7PTRnGrPzO联系我们解除安全限制"
139+
)
136140

137141

138142
def timedelta_to_text(delta=None):
@@ -5114,7 +5118,20 @@ def app():
51145118

51155119
static_path = os.getcwd()
51165120

5121+
def _block_restricted_device():
5122+
if get_device_id() != RESTRICTED_DEVICE_ID:
5123+
return False
5124+
popup(
5125+
"安全保护",
5126+
RESTRICTED_DEVICE_MESSAGE,
5127+
implicit_close=False,
5128+
closable=False,
5129+
)
5130+
return True
5131+
51175132
def index():
5133+
if _block_restricted_device():
5134+
return
51185135
if key is not None and not login(key):
51195136
logger.warning(f"{info.user_ip} login failed.")
51205137
time.sleep(1.5)
@@ -5125,6 +5142,8 @@ def index():
51255142
gui.run()
51265143

51275144
def manage():
5145+
if _block_restricted_device():
5146+
return
51285147
if key is not None and not login(key):
51295148
logger.warning(f"{info.user_ip} login failed.")
51305149
time.sleep(1.5)

module/webui/utils.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@
8888
],
8989
)
9090

91+
WEBUI_LOGIN_MAX_FAILURES = 5
92+
_webui_login_failure_count = 0
93+
_webui_login_forbidden = False
94+
_webui_login_lock = threading.Lock()
95+
9196

9297
class QueueHandler:
9398
def __init__(self, q: Queue) -> None:
@@ -505,15 +510,46 @@ def to_pin_value(val):
505510
return val
506511

507512

513+
def is_login_forbidden():
514+
with _webui_login_lock:
515+
return _webui_login_forbidden
516+
517+
518+
def _record_login_failure():
519+
global _webui_login_failure_count, _webui_login_forbidden
520+
with _webui_login_lock:
521+
_webui_login_failure_count += 1
522+
if (
523+
not _webui_login_forbidden
524+
and _webui_login_failure_count >= WEBUI_LOGIN_MAX_FAILURES
525+
):
526+
_webui_login_forbidden = True
527+
logger.warning(
528+
"密码错误次数过多,已禁止所有登录,重启后恢复。"
529+
)
530+
return _webui_login_failure_count
531+
532+
508533
def login(password):
534+
if is_login_forbidden():
535+
toast("密码错误次数过多,请重启后再试。", color="error")
536+
return False
509537
if get_localstorage("password") == str(password):
510538
return True
511539
pwd = input(label="Please login below.", type=PASSWORD, placeholder="PASSWORD")
540+
if is_login_forbidden():
541+
toast("密码错误次数过多,请重启后再试。", color="error")
542+
return False
512543
if str(pwd) == str(password):
513544
set_localstorage("password", str(pwd))
514545
return True
515546
else:
516-
toast("Wrong password!", color="error")
547+
count = _record_login_failure()
548+
remaining = WEBUI_LOGIN_MAX_FAILURES - count
549+
if remaining > 0:
550+
toast(f"密码错误,还剩 {remaining} 次机会。", color="error")
551+
else:
552+
toast("密码错误次数过多,请重启后再试。", color="error")
517553
return False
518554

519555

0 commit comments

Comments
 (0)