Database refactor to separate modules.
This commit is contained in:
+34
-21
@@ -18,14 +18,27 @@ from uuid import UUID
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
from paskia.authsession import expires
|
||||
import pytest_asyncio
|
||||
import uuid7
|
||||
|
||||
from paskia import globals as paskia_globals
|
||||
from paskia.db import Credential, Org, Permission, Role, User
|
||||
from paskia.db.json import DB
|
||||
from paskia.authsession import expires
|
||||
from paskia.db import (
|
||||
Credential,
|
||||
Org,
|
||||
Permission,
|
||||
Role,
|
||||
User,
|
||||
add_permission_to_organization,
|
||||
create_credential,
|
||||
create_organization,
|
||||
create_permission,
|
||||
create_reset_token,
|
||||
create_role,
|
||||
create_session,
|
||||
create_user,
|
||||
)
|
||||
from paskia.db.operations import DB
|
||||
from paskia.fastapi.session import AUTH_COOKIE_NAME
|
||||
from paskia.sansio import Passkey
|
||||
from paskia.util.tokens import create_token, session_key
|
||||
@@ -45,15 +58,15 @@ async def test_db() -> AsyncGenerator[DB, None]:
|
||||
|
||||
Uses a temp file that gets cleaned up after each test.
|
||||
"""
|
||||
import paskia.db.json as json_db
|
||||
import paskia.db.operations as ops_db
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix=".jsonl", delete=True) as f:
|
||||
db = DB(f.name)
|
||||
db.load() # Synchronous now
|
||||
json_db._db = db
|
||||
await db.load()
|
||||
ops_db._db = db
|
||||
yield db
|
||||
# Clean up
|
||||
json_db._db = None
|
||||
ops_db._db = None
|
||||
|
||||
|
||||
@pytest_asyncio.fixture(scope="function")
|
||||
@@ -77,7 +90,7 @@ async def test_org(test_db: DB, admin_permission: Permission) -> Org:
|
||||
display_name="Test Organization",
|
||||
permissions=["auth:admin"], # Org can grant this permission
|
||||
)
|
||||
test_db.create_organization(org)
|
||||
create_organization(org)
|
||||
return org
|
||||
|
||||
|
||||
@@ -89,7 +102,7 @@ async def admin_permission(test_db: DB) -> Permission:
|
||||
perm = Permission(
|
||||
uuid=uuid7.create(), scope="auth:admin", display_name="Master Admin"
|
||||
)
|
||||
test_db.create_permission(perm)
|
||||
create_permission(perm)
|
||||
return perm
|
||||
|
||||
|
||||
@@ -101,9 +114,9 @@ async def org_admin_permission(test_db: DB, test_org: Org) -> Permission:
|
||||
perm = Permission(
|
||||
uuid=uuid7.create(), scope="auth:org:admin", display_name="Organization Admin"
|
||||
)
|
||||
test_db.create_permission(perm)
|
||||
create_permission(perm)
|
||||
# Make it grantable by the org
|
||||
test_db.add_permission_to_organization(str(test_org.uuid), "auth:org:admin")
|
||||
add_permission_to_organization(str(test_org.uuid), "auth:org:admin")
|
||||
return perm
|
||||
|
||||
|
||||
@@ -121,7 +134,7 @@ async def test_role(
|
||||
display_name="Test Admin Role",
|
||||
permissions=["auth:admin", "auth:org:admin"],
|
||||
)
|
||||
test_db.create_role(role)
|
||||
create_role(role)
|
||||
return role
|
||||
|
||||
|
||||
@@ -134,7 +147,7 @@ async def user_role(test_db: DB, test_org: Org) -> Role:
|
||||
display_name="User Role",
|
||||
permissions=[],
|
||||
)
|
||||
test_db.create_role(role)
|
||||
create_role(role)
|
||||
return role
|
||||
|
||||
|
||||
@@ -148,7 +161,7 @@ async def test_user(test_db: DB, test_role: Role) -> User:
|
||||
created_at=datetime.now(timezone.utc),
|
||||
visits=0,
|
||||
)
|
||||
test_db.create_user(user)
|
||||
create_user(user)
|
||||
return user
|
||||
|
||||
|
||||
@@ -162,7 +175,7 @@ async def regular_user(test_db: DB, user_role: Role) -> User:
|
||||
created_at=datetime.now(timezone.utc),
|
||||
visits=0,
|
||||
)
|
||||
test_db.create_user(user)
|
||||
create_user(user)
|
||||
return user
|
||||
|
||||
|
||||
@@ -180,7 +193,7 @@ async def test_credential(test_db: DB, test_user: User) -> Credential:
|
||||
last_used=None,
|
||||
last_verified=None,
|
||||
)
|
||||
test_db.create_credential(credential)
|
||||
create_credential(credential)
|
||||
return credential
|
||||
|
||||
|
||||
@@ -198,7 +211,7 @@ async def regular_credential(test_db: DB, regular_user: User) -> Credential:
|
||||
last_used=None,
|
||||
last_verified=None,
|
||||
)
|
||||
test_db.create_credential(credential)
|
||||
create_credential(credential)
|
||||
return credential
|
||||
|
||||
|
||||
@@ -208,7 +221,7 @@ async def session_token(
|
||||
) -> str:
|
||||
"""Create a session for the admin user and return the token."""
|
||||
token = create_token()
|
||||
test_db.create_session(
|
||||
create_session(
|
||||
user_uuid=test_user.uuid,
|
||||
credential_uuid=test_credential.uuid,
|
||||
key=session_key(token),
|
||||
@@ -226,7 +239,7 @@ async def regular_session_token(
|
||||
) -> str:
|
||||
"""Create a session for a regular user and return the token."""
|
||||
token = create_token()
|
||||
test_db.create_session(
|
||||
create_session(
|
||||
user_uuid=regular_user.uuid,
|
||||
credential_uuid=regular_credential.uuid,
|
||||
key=session_key(token),
|
||||
@@ -246,7 +259,7 @@ async def reset_token(test_db: DB, test_user: User, test_credential: Credential)
|
||||
from paskia.util.tokens import reset_key
|
||||
|
||||
token = generate()
|
||||
test_db.create_reset_token(
|
||||
create_reset_token(
|
||||
user_uuid=test_user.uuid,
|
||||
key=reset_key(token),
|
||||
expiry=reset_expires(),
|
||||
|
||||
+39
-26
@@ -20,8 +20,21 @@ import pytest_asyncio
|
||||
import uuid7
|
||||
|
||||
from paskia.authsession import expires
|
||||
from paskia.db import Credential, Org, Permission, Role, User
|
||||
from paskia.db.json import DB
|
||||
from paskia.db import (
|
||||
Credential,
|
||||
Org,
|
||||
Permission,
|
||||
Role,
|
||||
User,
|
||||
add_permission_to_organization,
|
||||
create_credential,
|
||||
create_organization,
|
||||
create_permission,
|
||||
create_role,
|
||||
create_session,
|
||||
create_user,
|
||||
)
|
||||
from paskia.db.operations import DB
|
||||
from paskia.util.tokens import create_token, encode_session_key, session_key
|
||||
from tests.conftest import auth_headers
|
||||
|
||||
@@ -36,7 +49,7 @@ async def second_org(test_db: DB) -> Org:
|
||||
display_name="Second Organization",
|
||||
permissions=[],
|
||||
)
|
||||
test_db.create_organization(org)
|
||||
create_organization(org)
|
||||
return org
|
||||
|
||||
|
||||
@@ -51,7 +64,7 @@ async def second_org_role(
|
||||
display_name="Second Org Admin Role",
|
||||
permissions=["auth:admin"],
|
||||
)
|
||||
test_db.create_role(role)
|
||||
create_role(role)
|
||||
return role
|
||||
|
||||
|
||||
@@ -65,7 +78,7 @@ async def second_org_user(test_db: DB, second_org_role: Role) -> User:
|
||||
created_at=datetime.now(timezone.utc),
|
||||
visits=0,
|
||||
)
|
||||
test_db.create_user(user)
|
||||
create_user(user)
|
||||
return user
|
||||
|
||||
|
||||
@@ -85,7 +98,7 @@ async def second_org_credential(test_db: DB, second_org_user: User) -> Credentia
|
||||
last_used=datetime.now(timezone.utc),
|
||||
last_verified=datetime.now(timezone.utc),
|
||||
)
|
||||
test_db.create_credential(credential)
|
||||
create_credential(credential)
|
||||
return credential
|
||||
|
||||
|
||||
@@ -95,7 +108,7 @@ async def second_org_session_token(
|
||||
) -> str:
|
||||
"""Create a session for the second org admin user."""
|
||||
token = create_token()
|
||||
test_db.create_session(
|
||||
create_session(
|
||||
user_uuid=second_org_user.uuid,
|
||||
credential_uuid=second_org_credential.uuid,
|
||||
key=session_key(token),
|
||||
@@ -116,7 +129,7 @@ async def org_admin_role(test_db: DB, test_org: Org, org_admin_permission) -> Ro
|
||||
display_name="Org Admin Role",
|
||||
permissions=["auth:org:admin"],
|
||||
)
|
||||
test_db.create_role(role)
|
||||
create_role(role)
|
||||
return role
|
||||
|
||||
|
||||
@@ -131,7 +144,7 @@ async def org_admin_user(test_db: DB, org_admin_role: Role) -> User:
|
||||
visits=5,
|
||||
last_seen=datetime.now(timezone.utc),
|
||||
)
|
||||
test_db.create_user(user)
|
||||
create_user(user)
|
||||
return user
|
||||
|
||||
|
||||
@@ -151,7 +164,7 @@ async def org_admin_credential(test_db: DB, org_admin_user: User) -> Credential:
|
||||
last_used=datetime.now(timezone.utc),
|
||||
last_verified=None,
|
||||
)
|
||||
test_db.create_credential(credential)
|
||||
create_credential(credential)
|
||||
return credential
|
||||
|
||||
|
||||
@@ -161,7 +174,7 @@ async def org_admin_session_token(
|
||||
) -> str:
|
||||
"""Create a session for the org admin user."""
|
||||
token = create_token()
|
||||
test_db.create_session(
|
||||
create_session(
|
||||
user_uuid=org_admin_user.uuid,
|
||||
credential_uuid=org_admin_credential.uuid,
|
||||
key=session_key(token),
|
||||
@@ -181,9 +194,9 @@ async def grantable_permission(test_db: DB, test_org: Org) -> Permission:
|
||||
perm = Permission(
|
||||
uuid=uuid7.create(), scope="test:grantable:perm", display_name="Grantable Perm"
|
||||
)
|
||||
test_db.create_permission(perm)
|
||||
create_permission(perm)
|
||||
# Add to org's grantable permissions
|
||||
test_db.add_permission_to_organization(str(test_org.uuid), perm.scope)
|
||||
add_permission_to_organization(str(test_org.uuid), perm.scope)
|
||||
return perm
|
||||
|
||||
|
||||
@@ -414,7 +427,7 @@ class TestAdminOrganizations:
|
||||
display_name="Org To Delete",
|
||||
permissions=[],
|
||||
)
|
||||
test_db.create_organization(org_to_delete)
|
||||
create_organization(org_to_delete)
|
||||
|
||||
# Create some org-specific permissions to test cleanup
|
||||
org_perm = Permission(
|
||||
@@ -422,7 +435,7 @@ class TestAdminOrganizations:
|
||||
scope=f"test:org:{org_to_delete.uuid}:feature",
|
||||
display_name="Org Feature",
|
||||
)
|
||||
test_db.create_permission(org_perm)
|
||||
create_permission(org_perm)
|
||||
|
||||
response = await client.delete(
|
||||
f"/auth/api/admin/orgs/{org_to_delete.uuid}",
|
||||
@@ -601,7 +614,7 @@ class TestAdminRoles:
|
||||
scope="test:not:grantable",
|
||||
display_name="Not Grantable",
|
||||
)
|
||||
test_db.create_permission(perm)
|
||||
create_permission(perm)
|
||||
|
||||
response = await client.post(
|
||||
f"/auth/api/admin/orgs/{test_org.uuid}/roles",
|
||||
@@ -676,7 +689,7 @@ class TestAdminRoles:
|
||||
scope="test:not:grantable:update",
|
||||
display_name="Not Grantable",
|
||||
)
|
||||
test_db.create_permission(perm)
|
||||
create_permission(perm)
|
||||
|
||||
response = await client.post(
|
||||
f"/auth/api/admin/orgs/{test_org.uuid}/roles/{user_role.uuid}/permissions/test:not:grantable:update",
|
||||
@@ -1097,7 +1110,7 @@ class TestAdminUsersInOrg:
|
||||
created_at=datetime.now(timezone.utc),
|
||||
visits=0,
|
||||
)
|
||||
test_db.create_user(user_no_cred)
|
||||
create_user(user_no_cred)
|
||||
|
||||
response = await client.post(
|
||||
f"/auth/api/admin/orgs/{test_org.uuid}/users/{user_no_cred.uuid}/create-link",
|
||||
@@ -1184,7 +1197,7 @@ class TestAdminSessions:
|
||||
# Create an additional session to delete
|
||||
extra_token = create_token()
|
||||
extra_key = session_key(extra_token)
|
||||
test_db.create_session(
|
||||
create_session(
|
||||
user_uuid=test_user.uuid,
|
||||
credential_uuid=test_credential.uuid,
|
||||
key=extra_key,
|
||||
@@ -1380,7 +1393,7 @@ class TestAdminPermissions:
|
||||
perm = Permission(
|
||||
uuid=uuid7.create(), scope="test:updateable", display_name="Updateable"
|
||||
)
|
||||
test_db.create_permission(perm)
|
||||
create_permission(perm)
|
||||
|
||||
response = await client.patch(
|
||||
"/auth/api/admin/permission?permission_id=test:updateable&display_name=Updated%20Name",
|
||||
@@ -1401,7 +1414,7 @@ class TestAdminPermissions:
|
||||
perm = Permission(
|
||||
uuid=uuid7.create(), scope="test:perm", display_name="Test Perm"
|
||||
)
|
||||
test_db.create_permission(perm)
|
||||
create_permission(perm)
|
||||
|
||||
response = await client.patch(
|
||||
"/auth/api/admin/permission?permission_id=test:perm&display_name=",
|
||||
@@ -1422,7 +1435,7 @@ class TestAdminPermissions:
|
||||
perm = Permission(
|
||||
uuid=uuid7.create(), scope="test:renameable2", display_name="Renameable"
|
||||
)
|
||||
test_db.create_permission(perm)
|
||||
create_permission(perm)
|
||||
|
||||
response = await client.post(
|
||||
"/auth/api/admin/permission/rename",
|
||||
@@ -1469,7 +1482,7 @@ class TestAdminPermissions:
|
||||
perm = Permission(
|
||||
uuid=uuid7.create(), scope="test:rename:withname", display_name="Old Name"
|
||||
)
|
||||
test_db.create_permission(perm)
|
||||
create_permission(perm)
|
||||
|
||||
response = await client.post(
|
||||
"/auth/api/admin/permission/rename",
|
||||
@@ -1493,7 +1506,7 @@ class TestAdminPermissions:
|
||||
perm = Permission(
|
||||
uuid=uuid7.create(), scope="test:deleteable", display_name="Deleteable"
|
||||
)
|
||||
test_db.create_permission(perm)
|
||||
create_permission(perm)
|
||||
|
||||
response = await client.delete(
|
||||
"/auth/api/admin/permission?permission_id=test:deleteable",
|
||||
@@ -1529,7 +1542,7 @@ class TestAdminPermissions:
|
||||
perm2 = Permission(
|
||||
uuid=uuid7.create(), scope="auth:admin", display_name="Secondary Admin"
|
||||
)
|
||||
test_db.create_permission(perm2)
|
||||
create_permission(perm2)
|
||||
|
||||
# Now we can delete the original one
|
||||
response = await client.delete(
|
||||
@@ -1556,7 +1569,7 @@ class TestAdminPermissions:
|
||||
display_name="Other Domain Admin",
|
||||
domain="other.example.com",
|
||||
)
|
||||
test_db.create_permission(perm2)
|
||||
create_permission(perm2)
|
||||
|
||||
# Cannot delete the original one because the remaining one is not accessible
|
||||
response = await client.delete(
|
||||
|
||||
+3
-2
@@ -15,6 +15,7 @@ from datetime import datetime, timezone
|
||||
import httpx
|
||||
import pytest
|
||||
|
||||
from paskia.db import create_session, delete_session
|
||||
from tests.conftest import auth_headers
|
||||
|
||||
|
||||
@@ -526,7 +527,7 @@ class TestValidateSessionRefresh:
|
||||
# Create a session with an old expiry time to trigger refresh
|
||||
token = create_token()
|
||||
old_expiry = datetime.now(timezone.utc) + EXPIRES - timedelta(minutes=10)
|
||||
test_db.create_session(
|
||||
create_session(
|
||||
user_uuid=test_user.uuid,
|
||||
credential_uuid=test_credential.uuid,
|
||||
key=session_key(token),
|
||||
@@ -537,7 +538,7 @@ class TestValidateSessionRefresh:
|
||||
)
|
||||
|
||||
# Delete the session right before validate tries to refresh
|
||||
test_db.delete_session(session_key(token))
|
||||
delete_session(session_key(token))
|
||||
|
||||
response = await client.post(
|
||||
"/auth/api/validate",
|
||||
|
||||
Reference in New Issue
Block a user