feat: add models for physical files, policies, and user management
- Implement PhysicalFile model to manage physical file references and reference counting. - Create Policy model with associated options and group links for storage policies. - Introduce Redeem and Report models for handling redeem codes and reports. - Add Settings model for site configuration and user settings management. - Develop Share model for sharing objects with unique codes and associated metadata. - Implement SourceLink model for managing download links associated with objects. - Create StoragePack model for managing user storage packages. - Add Tag model for user-defined tags with manual and automatic types. - Implement Task model for managing background tasks with status tracking. - Develop User model with comprehensive user management features including authentication. - Introduce UserAuthn model for managing WebAuthn credentials. - Create WebDAV model for managing WebDAV accounts associated with users.
This commit is contained in:
@@ -124,7 +124,7 @@ async def test_admin_get_user_list_contains_user_data(
|
||||
if len(users) > 0:
|
||||
user = users[0]
|
||||
assert "id" in user
|
||||
assert "username" in user
|
||||
assert "email" in user
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -132,7 +132,7 @@ async def test_admin_create_user_requires_auth(async_client: AsyncClient):
|
||||
"""测试创建用户需要认证"""
|
||||
response = await async_client.post(
|
||||
"/api/admin/user/create",
|
||||
json={"username": "newadminuser", "password": "pass123"}
|
||||
json={"email": "newadminuser@test.local", "password": "pass123"}
|
||||
)
|
||||
assert response.status_code == 401
|
||||
|
||||
@@ -146,7 +146,7 @@ async def test_admin_create_user_requires_admin(
|
||||
response = await async_client.post(
|
||||
"/api/admin/user/create",
|
||||
headers=auth_headers,
|
||||
json={"username": "newadminuser", "password": "pass123"}
|
||||
json={"email": "newadminuser@test.local", "password": "pass123"}
|
||||
)
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ from uuid import UUID
|
||||
@pytest.mark.asyncio
|
||||
async def test_directory_requires_auth(async_client: AsyncClient):
|
||||
"""测试获取目录需要认证"""
|
||||
response = await async_client.get("/api/directory/testuser")
|
||||
response = await async_client.get("/api/directory/")
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ async def test_directory_get_root(
|
||||
):
|
||||
"""测试获取用户根目录"""
|
||||
response = await async_client.get(
|
||||
"/api/directory/testuser",
|
||||
"/api/directory/",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert response.status_code == 200
|
||||
@@ -45,7 +45,7 @@ async def test_directory_get_nested(
|
||||
):
|
||||
"""测试获取嵌套目录"""
|
||||
response = await async_client.get(
|
||||
"/api/directory/testuser/docs",
|
||||
"/api/directory/docs",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert response.status_code == 200
|
||||
@@ -63,7 +63,7 @@ async def test_directory_get_contains_children(
|
||||
):
|
||||
"""测试目录包含子对象"""
|
||||
response = await async_client.get(
|
||||
"/api/directory/testuser/docs",
|
||||
"/api/directory/docs",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert response.status_code == 200
|
||||
@@ -75,19 +75,6 @@ async def test_directory_get_contains_children(
|
||||
assert len(objects) >= 1
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_directory_forbidden_other_user(
|
||||
async_client: AsyncClient,
|
||||
auth_headers: dict[str, str]
|
||||
):
|
||||
"""测试访问他人目录返回 403"""
|
||||
response = await async_client.get(
|
||||
"/api/directory/admin",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_directory_not_found(
|
||||
async_client: AsyncClient,
|
||||
@@ -95,23 +82,23 @@ async def test_directory_not_found(
|
||||
):
|
||||
"""测试目录不存在返回 404"""
|
||||
response = await async_client.get(
|
||||
"/api/directory/testuser/nonexistent",
|
||||
"/api/directory/nonexistent",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_directory_empty_path_returns_400(
|
||||
async def test_directory_root_returns_200(
|
||||
async_client: AsyncClient,
|
||||
auth_headers: dict[str, str]
|
||||
):
|
||||
"""测试空路径返回 400"""
|
||||
"""测试根目录端点返回 200"""
|
||||
response = await async_client.get(
|
||||
"/api/directory/",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert response.status_code == 400
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@@ -121,7 +108,7 @@ async def test_directory_response_includes_policy(
|
||||
):
|
||||
"""测试目录响应包含存储策略"""
|
||||
response = await async_client.get(
|
||||
"/api/directory/testuser",
|
||||
"/api/directory/",
|
||||
headers=auth_headers
|
||||
)
|
||||
assert response.status_code == 200
|
||||
@@ -284,7 +271,7 @@ async def test_directory_create_other_user_parent(
|
||||
"""测试在他人目录下创建目录返回 404"""
|
||||
# 先用管理员账号获取管理员的根目录ID
|
||||
admin_response = await async_client.get(
|
||||
"/api/directory/admin",
|
||||
"/api/directory/",
|
||||
headers=admin_headers
|
||||
)
|
||||
assert admin_response.status_code == 200
|
||||
|
||||
@@ -16,7 +16,7 @@ async def test_user_login_success(
|
||||
response = await async_client.post(
|
||||
"/api/user/session",
|
||||
data={
|
||||
"username": test_user_info["username"],
|
||||
"username": test_user_info["email"],
|
||||
"password": test_user_info["password"],
|
||||
}
|
||||
)
|
||||
@@ -38,7 +38,7 @@ async def test_user_login_wrong_password(
|
||||
response = await async_client.post(
|
||||
"/api/user/session",
|
||||
data={
|
||||
"username": test_user_info["username"],
|
||||
"username": test_user_info["email"],
|
||||
"password": "wrongpassword",
|
||||
}
|
||||
)
|
||||
@@ -51,7 +51,7 @@ async def test_user_login_nonexistent_user(async_client: AsyncClient):
|
||||
response = await async_client.post(
|
||||
"/api/user/session",
|
||||
data={
|
||||
"username": "nonexistent",
|
||||
"username": "nonexistent@test.local",
|
||||
"password": "anypassword",
|
||||
}
|
||||
)
|
||||
@@ -67,7 +67,7 @@ async def test_user_login_user_banned(
|
||||
response = await async_client.post(
|
||||
"/api/user/session",
|
||||
data={
|
||||
"username": banned_user_info["username"],
|
||||
"username": banned_user_info["email"],
|
||||
"password": banned_user_info["password"],
|
||||
}
|
||||
)
|
||||
@@ -82,7 +82,7 @@ async def test_user_register_success(async_client: AsyncClient):
|
||||
response = await async_client.post(
|
||||
"/api/user/",
|
||||
json={
|
||||
"username": "newuser",
|
||||
"email": "newuser@test.local",
|
||||
"password": "newpass123",
|
||||
}
|
||||
)
|
||||
@@ -91,20 +91,20 @@ async def test_user_register_success(async_client: AsyncClient):
|
||||
data = response.json()
|
||||
assert "data" in data
|
||||
assert "user_id" in data["data"]
|
||||
assert "username" in data["data"]
|
||||
assert data["data"]["username"] == "newuser"
|
||||
assert "email" in data["data"]
|
||||
assert data["data"]["email"] == "newuser@test.local"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_register_duplicate_username(
|
||||
async def test_user_register_duplicate_email(
|
||||
async_client: AsyncClient,
|
||||
test_user_info: dict[str, str]
|
||||
):
|
||||
"""测试重复用户名返回 400"""
|
||||
"""测试重复邮箱返回 400"""
|
||||
response = await async_client.post(
|
||||
"/api/user/",
|
||||
json={
|
||||
"username": test_user_info["username"],
|
||||
"email": test_user_info["email"],
|
||||
"password": "anypassword",
|
||||
}
|
||||
)
|
||||
@@ -143,8 +143,8 @@ async def test_user_me_returns_user_info(
|
||||
assert "data" in data
|
||||
user_data = data["data"]
|
||||
assert "id" in user_data
|
||||
assert "username" in user_data
|
||||
assert user_data["username"] == "testuser"
|
||||
assert "email" in user_data
|
||||
assert user_data["email"] == "testuser@test.local"
|
||||
assert "group" in user_data
|
||||
assert "tags" in user_data
|
||||
|
||||
|
||||
Reference in New Issue
Block a user