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

@@ -19,7 +19,7 @@ async def test_object_create_folder(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="testuser", password="password", group_id=group.id)
user = User(email="testuser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(
@@ -53,7 +53,7 @@ async def test_object_create_file(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="testuser", password="password", group_id=group.id)
user = User(email="testuser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(
@@ -98,7 +98,7 @@ async def test_object_is_file_property(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="testuser", password="password", group_id=group.id)
user = User(email="testuser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(name="本地策略", type=PolicyType.LOCAL, server="/tmp/test")
@@ -125,7 +125,7 @@ async def test_object_is_folder_property(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="testuser", password="password", group_id=group.id)
user = User(email="testuser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(name="本地策略", type=PolicyType.LOCAL, server="/tmp/test")
@@ -151,7 +151,7 @@ async def test_object_get_root(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="rootuser", password="password", group_id=group.id)
user = User(email="rootuser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(name="本地策略", type=PolicyType.LOCAL, server="/tmp/test")
@@ -183,7 +183,7 @@ async def test_object_get_by_path_root(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="pathuser", password="password", group_id=group.id)
user = User(email="pathuser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(name="本地策略", type=PolicyType.LOCAL, server="/tmp/test")
@@ -214,7 +214,7 @@ async def test_object_get_by_path_nested(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="nesteduser", password="password", group_id=group.id)
user = User(email="nesteduser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(name="本地策略", type=PolicyType.LOCAL, server="/tmp/test")
@@ -277,7 +277,7 @@ async def test_object_get_by_path_not_found(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="notfounduser", password="password", group_id=group.id)
user = User(email="notfounduser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(name="本地策略", type=PolicyType.LOCAL, server="/tmp/test")
@@ -311,7 +311,7 @@ async def test_object_get_children(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="childrenuser", password="password", group_id=group.id)
user = User(email="childrenuser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(name="本地策略", type=PolicyType.LOCAL, server="/tmp/test")
@@ -363,7 +363,7 @@ async def test_object_parent_child_relationship(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="reluser", password="password", group_id=group.id)
user = User(email="reluser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(name="本地策略", type=PolicyType.LOCAL, server="/tmp/test")
@@ -408,7 +408,7 @@ async def test_object_unique_constraint(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="uniqueuser", password="password", group_id=group.id)
user = User(email="uniqueuser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(name="本地策略", type=PolicyType.LOCAL, server="/tmp/test")
@@ -456,7 +456,7 @@ async def test_object_get_full_path(db_session: AsyncSession):
group = Group(name="测试组")
group = await group.save(db_session)
user = User(email="pathuser", password="password", group_id=group.id)
user = User(email="pathuser", group_id=group.id)
user = await user.save(db_session)
policy = Policy(name="本地策略", type=PolicyType.LOCAL, server="/tmp/test")