feat: add multi-provider auth via AuthIdentity and extend site config

- Extract AuthIdentity model for multi-provider authentication (email_password, OAuth, Passkey, Magic Link)
- Remove password field from User model, credentials now stored in AuthIdentity
- Refactor unified login/register to use AuthIdentity-based provider checking
- Add site config fields: footer_code, tos_url, privacy_url, auth_methods
- Add auth settings defaults in migration (email_password enabled by default)
- Update admin user creation to create AuthIdentity records
- Update all tests to use AuthIdentity model

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-12 22:49:12 +08:00
parent d831c9c0d6
commit 729773cae3
20 changed files with 1447 additions and 412 deletions

View File

@@ -24,6 +24,7 @@ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')
from main import app
from sqlmodels.database import get_session
from sqlmodels.auth_identity import AuthIdentity, AuthProviderType
from sqlmodels.group import Group, GroupClaims, GroupOptions
from sqlmodels.migration import migration
from sqlmodels.object import Object, ObjectType
@@ -192,7 +193,6 @@ async def test_user(db_session: AsyncSession) -> dict[str, str | UUID]:
user = User(
email="testuser@test.local",
nickname="测试用户",
password=Password.hash(password),
status=UserStatus.ACTIVE,
storage=0,
score=100,
@@ -200,6 +200,17 @@ async def test_user(db_session: AsyncSession) -> dict[str, str | UUID]:
)
user = await user.save(db_session)
# 创建邮箱密码认证身份
identity = AuthIdentity(
provider=AuthProviderType.EMAIL_PASSWORD,
identifier="testuser@test.local",
credential=Password.hash(password),
is_primary=True,
is_verified=True,
user_id=user.id,
)
await identity.save(db_session)
# 创建用户根目录
root_folder = Object(
name="/",
@@ -279,7 +290,6 @@ async def admin_user(db_session: AsyncSession) -> dict[str, str | UUID]:
admin = User(
email="admin@disknext.local",
nickname="管理员",
password=Password.hash(password),
status=UserStatus.ACTIVE,
storage=0,
score=9999,
@@ -287,6 +297,17 @@ async def admin_user(db_session: AsyncSession) -> dict[str, str | UUID]:
)
admin = await admin.save(db_session)
# 创建管理员邮箱密码认证身份
admin_identity = AuthIdentity(
provider=AuthProviderType.EMAIL_PASSWORD,
identifier="admin@disknext.local",
credential=Password.hash(password),
is_primary=True,
is_verified=True,
user_id=admin.id,
)
await admin_identity.save(db_session)
# 创建管理员根目录
root_folder = Object(
name="/",