323 lines
12 KiB
Python
323 lines
12 KiB
Python
import logging
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Add parent directory to path so we can import 'app'
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
from sqlalchemy import text, create_engine
|
|
from sqlalchemy.orm import Session, configure_mappers
|
|
|
|
from app.db.database import SessionLocal
|
|
from app.core.settings import DATABASE_URL
|
|
|
|
engine_direct = create_engine(DATABASE_URL, echo=False)
|
|
SessionLocal.configure(bind=engine_direct)
|
|
from app.modules.tenant.models.tenant_model import Tenant
|
|
from app.modules.auth.models.user_model import User
|
|
from app.modules.auth.models.access_model import Access
|
|
from app.modules.auth.models.role_model import Role
|
|
from app.modules.auth.models.role_access_model import RoleAccess
|
|
from app.modules.documents.models.document_model import Project, ProjectVersion
|
|
from app.modules.storage.models.storage_model import UserFile, UserStorageUsage
|
|
from app.modules.drive.models.drive_model import (
|
|
DriveFolder,
|
|
DriveFile,
|
|
DriveACL,
|
|
DriveActivity,
|
|
DriveComment,
|
|
DriveFileVersion,
|
|
DriveStar,
|
|
DriveShare,
|
|
)
|
|
from app.modules.chat.models.chat_model import ChatbotDocument
|
|
from app.modules.chat.models.chat_session_model import ChatSession
|
|
from app.modules.chat.models.chat_message_model import ChatMessage
|
|
from app.modules.chat.models.chat_usage_model import ChatTokenQuota, ChatTokenUsage
|
|
from app.infrastructure.vector.vector_client import VectorStoreManager
|
|
from app.modules.notifications.models.notification_model import Notification
|
|
from app.modules.collab.models.collab_model import CollaborationMessage
|
|
from app.modules.signing.models.signing_request import SigningRequest
|
|
from app.modules.configuration.models.system_configuration_model import (
|
|
SystemConfiguration,
|
|
)
|
|
|
|
configure_mappers()
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
PREDEFINED_ACCESSES = [
|
|
# Superadmin
|
|
("superadmin.main.view", "Superadmin", "Access to superadmin panel", None),
|
|
("superadmin.tenant.read", "Superadmin", "View all tenants", None),
|
|
("superadmin.tenant.create", "Superadmin", "Create tenants", None),
|
|
("superadmin.tenant.update", "Superadmin", "Update tenants", None),
|
|
("superadmin.tenant.delete", "Superadmin", "Delete tenants", None),
|
|
("superadmin.user.read", "Superadmin", "View all users", None),
|
|
("superadmin.user.create", "Superadmin", "Create users", None),
|
|
("superadmin.user.update", "Superadmin", "Update users", None),
|
|
("superadmin.user.delete", "Superadmin", "Delete users", None),
|
|
("superadmin.role.read", "Superadmin", "View all roles", None),
|
|
("superadmin.role.create", "Superadmin", "Create global roles", None),
|
|
("superadmin.role.update", "Superadmin", "Update global roles", None),
|
|
("superadmin.role.delete", "Superadmin", "Delete global roles", None),
|
|
("superadmin.access.read", "Superadmin", "View all accesses", None),
|
|
("superadmin.config.read", "Superadmin", "Read system configurations", None),
|
|
("superadmin.config.create", "Superadmin", "Create system configurations", None),
|
|
("superadmin.config.update", "Superadmin", "Update system configurations", None),
|
|
("superadmin.config.delete", "Superadmin", "Delete system configurations", None),
|
|
|
|
# Administration
|
|
("admin.user.read", "Administration", "Read users in tenant", None),
|
|
("admin.user.create", "Administration", "Create users in tenant", None),
|
|
("admin.user.update", "Administration", "Update users in tenant", None),
|
|
("admin.user.delete", "Administration", "Delete users from tenant", None),
|
|
("admin.user.invite", "Administration", "Invite users", None),
|
|
("admin.role.read", "Administration", "Read tenant roles", None),
|
|
("admin.role.create", "Administration", "Create tenant roles", None),
|
|
("admin.role.update", "Administration", "Update tenant roles", None),
|
|
("admin.role.assign", "Administration", "Assign roles to users", None),
|
|
("admin.access.read", "Administration", "View tenant accesses", None),
|
|
("admin.smtp.read", "Administration", "Read tenant SMTP settings", None),
|
|
("admin.smtp.update", "Administration", "Update tenant SMTP settings", None),
|
|
("admin.storage.read", "Administration", "Read tenant storage settings", None),
|
|
("admin.storage.update", "Administration", "Update tenant storage settings", None),
|
|
("admin.org.read", "Administration", "Read organization structure", None),
|
|
("admin.org.create", "Administration", "Create organization structure", None),
|
|
("admin.org.update", "Administration", "Update organization structure", None),
|
|
("admin.org.delete", "Administration", "Delete organization structure", None),
|
|
("admin.org.assign", "Administration", "Assign organization roles", None),
|
|
("admin.group.read", "Administration", "Read access groups", None),
|
|
("admin.group.create", "Administration", "Create access groups", None),
|
|
("admin.group.update", "Administration", "Update access groups", None),
|
|
("admin.group.delete", "Administration", "Delete access groups", None),
|
|
|
|
|
|
# Document Conversion
|
|
(
|
|
"document.conversion.pdf.read",
|
|
"Document Conversion",
|
|
"Read PDF conversion resources",
|
|
"document.conversion",
|
|
),
|
|
(
|
|
"document.conversion.pdf.write",
|
|
"Document Conversion",
|
|
"Create and run PDF conversions",
|
|
"document.conversion",
|
|
),
|
|
(
|
|
"document.conversion.pdf.to.word",
|
|
"Document Conversion",
|
|
"Use PDF to Word conversion",
|
|
"document.conversion",
|
|
),
|
|
(
|
|
"document.conversion.pdf.to.html",
|
|
"Document Conversion",
|
|
"Use PDF to HTML conversion",
|
|
"document.conversion",
|
|
),
|
|
(
|
|
"document.conversion.pdf.to.xml",
|
|
"Document Conversion",
|
|
"Use PDF to XML conversion",
|
|
"document.conversion",
|
|
),
|
|
(
|
|
"document.conversion.word.to.pdf",
|
|
"Document Conversion",
|
|
"Use Word to PDF conversion",
|
|
"document.conversion",
|
|
),
|
|
(
|
|
"document.conversion.image.to.word",
|
|
"Document Conversion",
|
|
"Use image to Word conversion",
|
|
"document.conversion",
|
|
),
|
|
|
|
# AI Chatbot
|
|
("chatbot", "AI Chatbot", "Full access to AI chatbot module", None),
|
|
("chatbot.read", "AI Chatbot", "Read chatbot documents", "chatbot"),
|
|
(
|
|
"chatbot.write",
|
|
"AI Chatbot",
|
|
"Upload/manage chatbot documents and chat",
|
|
"chatbot",
|
|
),
|
|
("document.extract", "AI Chatbot", "Extract data from documents using AI", "chatbot"),
|
|
|
|
# Document
|
|
("document.read", "Documents", "Read documents", None),
|
|
("document.edit", "Documents", "Edit documents", None),
|
|
("document.comment", "Documents", "Comment on documents", None),
|
|
("document.publish", "Documents", "Publish document versions", None),
|
|
("document.restore", "Documents", "Restore document versions", None),
|
|
("document.presentation.create", "Documents", "Create presentation documents", None),
|
|
("document.text.create", "Documents", "Create text documents", None),
|
|
("document.word.create", "Documents", "Create word documents", None),
|
|
("document.sheet.create", "Documents", "Create spreadsheet documents", None),
|
|
|
|
# Drive Folder
|
|
("drive.folder.create", "Drive", "Create folders", None),
|
|
("drive.folder.read", "Drive", "Read folders", None),
|
|
("drive.folder.update", "Drive", "Update folders", None),
|
|
("drive.folder.delete", "Drive", "Delete folders", None),
|
|
|
|
# Drive File
|
|
("drive.file.upload", "Drive", "Upload files", None),
|
|
("drive.file.download", "Drive", "Download files", None),
|
|
("drive.file.delete", "Drive", "Delete files", None),
|
|
("drive.file.share", "Drive", "Share files", None),
|
|
("drive.file.comment", "Drive", "Comment on files", None),
|
|
("drive.file.version.read", "Drive", "View file versions", None),
|
|
("drive.file.link.create", "Drive", "Create file links", None),
|
|
|
|
# Signing
|
|
("document.sign", "Signing", "Sign documents", None),
|
|
("document.sign.request", "Signing", "Request signatures from others", None),
|
|
("admin.logs.read", "Administration", "Read tenant activity logs", None),
|
|
]
|
|
|
|
|
|
def seed_accesses(db: Session) -> int:
|
|
logger.info("Seeding accesses...")
|
|
|
|
for sql in [
|
|
"ALTER TABLE accesses DROP CONSTRAINT IF EXISTS uq_accesses_name",
|
|
"ALTER TABLE accesses DROP CONSTRAINT IF EXISTS accesses_name_key",
|
|
"DROP INDEX IF EXISTS accesses_name_key",
|
|
]:
|
|
try:
|
|
db.execute(text(sql))
|
|
except Exception:
|
|
pass
|
|
db.commit()
|
|
|
|
created_count = 0
|
|
updated_count = 0
|
|
seen_names = set()
|
|
access_by_code = {}
|
|
|
|
for access_code, category, name, parent_code in PREDEFINED_ACCESSES:
|
|
unique_name = name
|
|
if unique_name in seen_names:
|
|
unique_name = f"{category}: {name}"
|
|
seen_names.add(unique_name)
|
|
|
|
access = db.query(Access).filter(Access.access_code == access_code).first()
|
|
if access:
|
|
access.category = category
|
|
access.name = unique_name
|
|
updated_count += 1
|
|
else:
|
|
access = Access(
|
|
access_code=access_code,
|
|
category=category,
|
|
name=unique_name,
|
|
parent_id=None,
|
|
)
|
|
db.add(access)
|
|
created_count += 1
|
|
access_by_code[access_code] = access
|
|
|
|
db.flush()
|
|
|
|
for access_code, _, _, parent_code in PREDEFINED_ACCESSES:
|
|
access = access_by_code.get(access_code)
|
|
if not access:
|
|
continue
|
|
if parent_code:
|
|
parent = access_by_code.get(parent_code)
|
|
access.parent_id = parent.id if parent else None
|
|
else:
|
|
access.parent_id = None
|
|
|
|
db.commit()
|
|
logger.info("Accesses upserted: %s created, %s updated", created_count, updated_count)
|
|
return created_count + updated_count
|
|
|
|
|
|
def seed_roles_with_permissions(db: Session) -> None:
|
|
logger.info("Creating roles...")
|
|
|
|
superadmin_role = (
|
|
db.query(Role).filter(Role.name == "superadmin", Role.tenant_id == None).first()
|
|
)
|
|
if not superadmin_role:
|
|
superadmin_role = Role(name="superadmin", tenant_id=None)
|
|
db.add(superadmin_role)
|
|
db.flush()
|
|
|
|
db.query(RoleAccess).filter(RoleAccess.role_id == superadmin_role.id).delete()
|
|
db.flush()
|
|
superadmin_accesses = (
|
|
db.query(Access)
|
|
.filter(
|
|
Access.access_code.like("superadmin.%") | Access.access_code.like("admin.%")
|
|
)
|
|
.all()
|
|
)
|
|
for access in superadmin_accesses:
|
|
db.add(RoleAccess(role_id=superadmin_role.id, access_id=access.id))
|
|
db.commit()
|
|
logger.info("Superadmin role synced with %s accesses", len(superadmin_accesses))
|
|
|
|
|
|
def create_and_link_superadmin(db: Session) -> None:
|
|
logger.info("Setting up superadmin user...")
|
|
from app.core.security import get_password_hash
|
|
|
|
superadmin_role = (
|
|
db.query(Role).filter(Role.name == "superadmin", Role.tenant_id == None).first()
|
|
)
|
|
|
|
superadmin = db.query(User).filter(User.email == "admin@maskan.com").first()
|
|
if not superadmin:
|
|
superadmin = User(
|
|
name="System Superadmin",
|
|
email="admin@maskan.com",
|
|
tenant_id=None,
|
|
password_hash=get_password_hash("Admin@123"),
|
|
role_id=superadmin_role.id if superadmin_role else None,
|
|
)
|
|
db.add(superadmin)
|
|
db.commit()
|
|
logger.info("Superadmin user created and linked to role")
|
|
return
|
|
|
|
if superadmin_role and superadmin.role_id != superadmin_role.id:
|
|
superadmin.role_id = superadmin_role.id
|
|
db.commit()
|
|
logger.info("Existing superadmin user linked to superadmin role")
|
|
else:
|
|
logger.info("Superadmin user already exists and is linked correctly")
|
|
|
|
|
|
def seed_data():
|
|
db = SessionLocal()
|
|
try:
|
|
logger.info("=" * 60)
|
|
logger.info("Starting seed process...")
|
|
logger.info("=" * 60)
|
|
|
|
seed_accesses(db)
|
|
seed_roles_with_permissions(db)
|
|
create_and_link_superadmin(db)
|
|
|
|
logger.info("=" * 60)
|
|
logger.info("Seeding completed successfully")
|
|
logger.info("=" * 60)
|
|
except Exception as e:
|
|
logger.error("Seeding failed: %s", e)
|
|
db.rollback()
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
seed_data()
|