Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ jobs:
python -m pip install --upgrade pip
pip install -e ".[test]"

- name: Run CLI tests with pytest
- name: Run test suite with pytest
env:
PYTHONIOENCODING: utf-8
run: |
python -m pytest tests/test_cli.py -v
python -m pytest -v
2 changes: 2 additions & 0 deletions docs/magic-dash-pro/二次开发指南.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@ roles = {

切换数据库类型时,先修改`DatabaseConfig.database_type`和对应连接配置,再确认目标数据库已创建。

内置模型会在`Peewee`、`SQLAlchemy`和`SQLModel`实现之间保持一致的上层类型契约。以登录日志为例,`LoginLogs.add_log()`的`login_datetime`参数应传入原生`datetime`对象,`LoginLogs.get_logs()`返回记录中的`login_datetime`也始终为`datetime`对象。日期时间的字符串格式化应留在页面展示、文件导出或接口序列化层处理,不应放在模型层,以免不同ORM返回不同类型。

## 登录与安全能力

常见安全增强点:
Expand Down
14 changes: 7 additions & 7 deletions magic_dash/templates/magic-dash-pro-fastapi/callbacks/login_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ def handle_login(
browser=browser_info,
os=os_info,
status="用户不存在",
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)

return [
Expand Down Expand Up @@ -199,7 +199,7 @@ def handle_login(
browser=browser_info,
os=os_info,
status="密码错误",
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)

return [
Expand All @@ -221,7 +221,7 @@ def handle_login(
browser=browser_info,
os=os_info,
status="登录成功",
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)

return [None] * 4
Expand Down Expand Up @@ -744,7 +744,7 @@ def handle_login_user_email_submit(nClicks, email, verification_code):
),
os="{} {}".format(user_agent.os.family, user_agent.os.version_string),
status=log_status,
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)
# 提前终止当前无输出回调
return
Expand All @@ -767,7 +767,7 @@ def handle_login_user_email_submit(nClicks, email, verification_code):
),
os="{} {}".format(user_agent.os.family, user_agent.os.version_string),
status="邮箱登录成功",
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)


Expand Down Expand Up @@ -841,7 +841,7 @@ def reject_login(
browser=browser_info,
os=os_info,
status=log_status,
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)

try:
Expand Down Expand Up @@ -927,5 +927,5 @@ def reject_login(
browser=browser_info,
os=os_info,
status="OTP登录成功",
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
from typing import List, Literal
from peewee import AutoField, CharField, DateTimeField

Expand Down Expand Up @@ -82,7 +83,7 @@ def add_log(
browser: str,
os: str,
status: str,
login_datetime: str,
login_datetime: datetime,
):
"""添加日志记录"""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,9 @@ def add_log(
browser: str,
os: str,
status: str,
login_datetime: str,
login_datetime: datetime,
):
with session_scope() as session:
# 应用回调中传入的是格式化后的字符串,这里统一转换为datetime入库
if isinstance(login_datetime, str):
login_datetime = datetime.strptime(
login_datetime,
"%Y-%m-%d %H:%M:%S",
)

session.add(
cls(
user_name=user_name,
Expand Down Expand Up @@ -108,12 +101,7 @@ def columns(cls):

@classmethod
def to_dict(cls, record):
result = object_to_dict(record, cls.columns())
if isinstance(result["login_datetime"], datetime):
result["login_datetime"] = result["login_datetime"].strftime(
"%Y-%m-%d %H:%M:%S"
)
return result
return object_to_dict(record, cls.columns())


# 保持Peewee旧实现的导入时建表行为,避免日志页首次访问时报表不存在
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,9 @@ def add_log(
browser: str,
os: str,
status: str,
login_datetime: str,
login_datetime: datetime,
):
with session_scope() as session:
# 应用回调中传入的是格式化后的字符串,这里统一转换为datetime入库
if isinstance(login_datetime, str):
login_datetime = datetime.strptime(
login_datetime,
"%Y-%m-%d %H:%M:%S",
)

session.add(
cls(
user_name=user_name,
Expand Down Expand Up @@ -120,12 +113,7 @@ def columns(cls):

@classmethod
def to_dict(cls, record):
result = object_to_dict(record, cls.columns())
if isinstance(result["login_datetime"], datetime):
result["login_datetime"] = result["login_datetime"].strftime(
"%Y-%m-%d %H:%M:%S"
)
return result
return object_to_dict(record, cls.columns())


# 保持Peewee旧实现的导入时建表行为,避免日志页首次访问时报表不存在
Expand Down
14 changes: 7 additions & 7 deletions magic_dash/templates/magic-dash-pro/callbacks/login_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ def handle_login(
browser=browser_info,
os=os_info,
status="用户不存在",
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)

return [
Expand Down Expand Up @@ -204,7 +204,7 @@ def handle_login(
browser=browser_info,
os=os_info,
status="密码错误",
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)

return [
Expand All @@ -226,7 +226,7 @@ def handle_login(
browser=browser_info,
os=os_info,
status="登录成功",
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)

return [None] * 4
Expand Down Expand Up @@ -749,7 +749,7 @@ def handle_login_user_email_submit(nClicks, email, verification_code):
),
os="{} {}".format(user_agent.os.family, user_agent.os.version_string),
status=log_status,
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)
# 提前终止当前无输出回调
return
Expand All @@ -772,7 +772,7 @@ def handle_login_user_email_submit(nClicks, email, verification_code):
),
os="{} {}".format(user_agent.os.family, user_agent.os.version_string),
status="邮箱登录成功",
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)


Expand Down Expand Up @@ -846,7 +846,7 @@ def reject_login(
browser=browser_info,
os=os_info,
status=log_status,
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)

try:
Expand Down Expand Up @@ -932,5 +932,5 @@ def reject_login(
browser=browser_info,
os=os_info,
status="OTP登录成功",
login_datetime=datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
login_datetime=datetime.now(),
)
3 changes: 2 additions & 1 deletion magic_dash/templates/magic-dash-pro/models/_peewee/logs.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
from typing import List, Literal
from peewee import AutoField, CharField, DateTimeField

Expand Down Expand Up @@ -82,7 +83,7 @@ def add_log(
browser: str,
os: str,
status: str,
login_datetime: str,
login_datetime: datetime,
):
"""添加日志记录"""

Expand Down
16 changes: 2 additions & 14 deletions magic_dash/templates/magic-dash-pro/models/_sqlalchemy/logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,9 @@ def add_log(
browser: str,
os: str,
status: str,
login_datetime: str,
login_datetime: datetime,
):
with session_scope() as session:
# 应用回调中传入的是格式化后的字符串,这里统一转换为datetime入库
if isinstance(login_datetime, str):
login_datetime = datetime.strptime(
login_datetime,
"%Y-%m-%d %H:%M:%S",
)

session.add(
cls(
user_name=user_name,
Expand Down Expand Up @@ -108,12 +101,7 @@ def columns(cls):

@classmethod
def to_dict(cls, record):
result = object_to_dict(record, cls.columns())
if isinstance(result["login_datetime"], datetime):
result["login_datetime"] = result["login_datetime"].strftime(
"%Y-%m-%d %H:%M:%S"
)
return result
return object_to_dict(record, cls.columns())


# 保持Peewee旧实现的导入时建表行为,避免日志页首次访问时报表不存在
Expand Down
16 changes: 2 additions & 14 deletions magic_dash/templates/magic-dash-pro/models/_sqlmodel/logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,9 @@ def add_log(
browser: str,
os: str,
status: str,
login_datetime: str,
login_datetime: datetime,
):
with session_scope() as session:
# 应用回调中传入的是格式化后的字符串,这里统一转换为datetime入库
if isinstance(login_datetime, str):
login_datetime = datetime.strptime(
login_datetime,
"%Y-%m-%d %H:%M:%S",
)

session.add(
cls(
user_name=user_name,
Expand Down Expand Up @@ -120,12 +113,7 @@ def columns(cls):

@classmethod
def to_dict(cls, record):
result = object_to_dict(record, cls.columns())
if isinstance(result["login_datetime"], datetime):
result["login_datetime"] = result["login_datetime"].strftime(
"%Y-%m-%d %H:%M:%S"
)
return result
return object_to_dict(record, cls.columns())


# 保持Peewee旧实现的导入时建表行为,避免日志页首次访问时报表不存在
Expand Down
5 changes: 5 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ def get_version():
"peewee>=4.0.0",
"SQLAlchemy>=2.0.0",
"sqlmodel>=0.0.27",
"cryptography",
"dash[fastapi]>=4.2.0,<5.0.0",
"fastapi-login",
"httpx",
"user_agents",
],
},
entry_points={
Expand Down
Loading
Loading