inital commit
This commit is contained in:
96
server/app/db/bootstrap.py
Normal file
96
server/app/db/bootstrap.py
Normal file
@@ -0,0 +1,96 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db.base import Base
|
||||
from app.db.models import Role, Tenant, User
|
||||
from app.db.session import engine
|
||||
from app.security.api_keys import CreatedApiKey, create_api_key
|
||||
|
||||
DEFAULT_SCOPES = [
|
||||
"campaign:read",
|
||||
"campaign:write",
|
||||
"campaign:validate",
|
||||
"campaign:build",
|
||||
"campaign:queue",
|
||||
"campaign:send_test",
|
||||
"campaign:send",
|
||||
"attachments:read",
|
||||
"attachments:write",
|
||||
"reports:read",
|
||||
"reports:send",
|
||||
"audit:read",
|
||||
"admin:users",
|
||||
"admin:settings",
|
||||
]
|
||||
|
||||
DEFAULT_ROLES = {
|
||||
"owner": ["*"],
|
||||
"admin": [
|
||||
"campaign:read", "campaign:write", "campaign:validate", "campaign:build",
|
||||
"campaign:queue", "campaign:send_test", "campaign:send",
|
||||
"attachments:read", "attachments:write", "reports:read", "reports:send", "audit:read",
|
||||
"admin:users", "admin:settings",
|
||||
],
|
||||
"campaign_manager": ["campaign:read", "campaign:write", "campaign:validate", "campaign:build", "reports:read"],
|
||||
"sender": ["campaign:read", "campaign:queue", "campaign:send_test", "campaign:send", "reports:read", "reports:send"],
|
||||
"reviewer": ["campaign:read", "campaign:validate", "reports:read"],
|
||||
"viewer": ["campaign:read", "reports:read"],
|
||||
"auditor": ["campaign:read", "reports:read", "audit:read"],
|
||||
}
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class BootstrapResult:
|
||||
tenant: Tenant
|
||||
user: User
|
||||
created_api_key: CreatedApiKey | None
|
||||
|
||||
|
||||
def create_all_tables() -> None:
|
||||
# Import models so SQLAlchemy sees all tables.
|
||||
from app.db import models # noqa: F401
|
||||
|
||||
Base.metadata.create_all(bind=engine)
|
||||
|
||||
|
||||
def bootstrap_dev_data(
|
||||
session: Session,
|
||||
*,
|
||||
api_key_secret: str | None = None,
|
||||
tenant_slug: str = "default",
|
||||
user_email: str = "admin@example.local",
|
||||
) -> BootstrapResult:
|
||||
tenant = session.query(Tenant).filter(Tenant.slug == tenant_slug).one_or_none()
|
||||
if tenant is None:
|
||||
tenant = Tenant(slug=tenant_slug, name="Default Tenant")
|
||||
session.add(tenant)
|
||||
session.flush()
|
||||
|
||||
for slug, permissions in DEFAULT_ROLES.items():
|
||||
role = session.query(Role).filter(Role.tenant_id == tenant.id, Role.slug == slug).one_or_none()
|
||||
if role is None:
|
||||
session.add(Role(tenant_id=tenant.id, slug=slug, name=slug.replace("_", " ").title(), permissions=permissions))
|
||||
|
||||
user = session.query(User).filter(User.tenant_id == tenant.id, User.email == user_email).one_or_none()
|
||||
if user is None:
|
||||
user = User(tenant_id=tenant.id, email=user_email, display_name="Development Admin", is_tenant_admin=True)
|
||||
session.add(user)
|
||||
session.flush()
|
||||
|
||||
created_api_key = None
|
||||
if api_key_secret:
|
||||
existing = [key for key in user.api_keys if key.name == "Development API key" and key.revoked_at is None]
|
||||
if not existing:
|
||||
created_api_key = create_api_key(
|
||||
session,
|
||||
user=user,
|
||||
name="Development API key",
|
||||
scopes=["*"],
|
||||
secret=api_key_secret,
|
||||
)
|
||||
|
||||
session.commit()
|
||||
return BootstrapResult(tenant=tenant, user=user, created_api_key=created_api_key)
|
||||
Reference in New Issue
Block a user