use sea_orm::{ActiveModelTrait, Set}; use uuid::Uuid; use crate::entity::{permission, role, role_permission, user, user_credential, user_role}; use crate::error::AuthError; use super::password; /// Permission definitions to seed for every new tenant. /// Each tuple is: (code, name, resource, action, description) /// /// 编码使用点分隔 (`resource.action`),与 handler 中的 `require_permission` 调用保持一致。 const DEFAULT_PERMISSIONS: &[(&str, &str, &str, &str, &str)] = &[ // === Auth module === ("user.list", "查看用户列表", "user", "list", "查看用户列表"), ("user.create", "创建用户", "user", "create", "创建新用户"), ("user.read", "查看用户详情", "user", "read", "查看用户信息"), ("user.update", "编辑用户", "user", "update", "编辑用户信息"), ("user.delete", "删除用户", "user", "delete", "软删除用户"), ("role.list", "查看角色列表", "role", "list", "查看角色列表"), ("role.create", "创建角色", "role", "create", "创建新角色"), ("role.read", "查看角色详情", "role", "read", "查看角色信息"), ("role.update", "编辑角色", "role", "update", "编辑角色"), ("role.delete", "删除角色", "role", "delete", "删除角色"), ( "permission.list", "查看权限", "permission", "list", "查看权限列表", ), ( "organization.list", "查看组织列表", "organization", "list", "查看组织列表", ), ( "organization.create", "创建组织", "organization", "create", "创建组织", ), ( "organization.update", "编辑组织", "organization", "update", "编辑组织", ), ( "organization.delete", "删除组织", "organization", "delete", "删除组织", ), ( "department.list", "查看部门列表", "department", "list", "查看部门列表", ), ( "department.create", "创建部门", "department", "create", "创建部门", ), ( "department.update", "编辑部门", "department", "update", "编辑部门", ), ( "department.delete", "删除部门", "department", "delete", "删除部门", ), ( "position.list", "查看岗位列表", "position", "list", "查看岗位列表", ), ( "position.create", "创建岗位", "position", "create", "创建岗位", ), ( "position.update", "编辑岗位", "position", "update", "编辑岗位", ), ( "position.delete", "删除岗位", "position", "delete", "删除岗位", ), // === Config module === ( "dictionary.list", "查看字典", "dictionary", "list", "查看数据字典", ), ( "dictionary.create", "创建字典", "dictionary", "create", "创建数据字典", ), ( "dictionary.update", "编辑字典", "dictionary", "update", "编辑数据字典", ), ( "dictionary.delete", "删除字典", "dictionary", "delete", "删除数据字典", ), ("menu.list", "查看菜单", "menu", "list", "查看菜单配置"), ("menu.update", "编辑菜单", "menu", "update", "编辑菜单配置"), ( "setting.read", "查看配置", "setting", "read", "查看系统参数", ), ( "setting.update", "编辑配置", "setting", "update", "编辑系统参数", ), ( "setting.delete", "删除配置", "setting", "delete", "删除系统参数", ), ( "numbering.list", "查看编号规则", "numbering", "list", "查看编号规则", ), ( "numbering.create", "创建编号规则", "numbering", "create", "创建编号规则", ), ( "numbering.update", "编辑编号规则", "numbering", "update", "编辑编号规则", ), ( "numbering.delete", "删除编号规则", "numbering", "delete", "删除编号规则", ), ( "numbering.generate", "生成编号", "numbering", "generate", "生成文档编号", ), ("theme.read", "查看主题", "theme", "read", "查看主题设置"), ( "theme.update", "编辑主题", "theme", "update", "编辑主题设置", ), ( "language.list", "查看语言", "language", "list", "查看语言配置", ), ( "language.update", "编辑语言", "language", "update", "编辑语言设置", ), // === Workflow module === ( "workflow.create", "创建流程", "workflow", "create", "创建流程定义", ), ( "workflow.list", "查看流程", "workflow", "list", "查看流程列表", ), ( "workflow.read", "查看流程详情", "workflow", "read", "查看流程定义详情", ), ( "workflow.update", "编辑流程", "workflow", "update", "编辑流程定义", ), ( "workflow.publish", "发布流程", "workflow", "publish", "发布流程定义", ), ( "workflow.start", "发起流程", "workflow", "start", "发起流程实例", ), ( "workflow.approve", "审批任务", "workflow", "approve", "审批流程任务", ), ( "workflow.delegate", "委派任务", "workflow", "delegate", "委派流程任务", ), // === Message module === ( "message.list", "查看消息", "message", "list", "查看消息列表", ), ("message.send", "发送消息", "message", "send", "发送新消息"), ( "message.template.list", "查看消息模板", "message.template", "list", "查看消息模板列表", ), ( "message.template.create", "创建消息模板", "message.template", "create", "创建消息模板", ), ]; /// Indices of read-only (list/read) permissions within DEFAULT_PERMISSIONS. const READ_PERM_INDICES: &[usize] = &[ 0, // user.list 2, // user.read 5, // role.list 7, // role.read 10, // permission.list 11, // organization.list 15, // department.list 19, // position.list 23, // dictionary.list 28, // menu.list 30, // setting.read 32, // numbering.list 37, // theme.read 39, // language.list 43, // workflow.list 44, // workflow.read 49, // message.list 51, // message.template.list ]; /// Seed default auth data for a new tenant. /// /// Creates: /// - 53 permissions covering auth/config/workflow/message modules /// - An "admin" system role with all permissions /// - A "viewer" system role with read-only permissions /// - A super-admin user with the admin role and a password credential pub async fn seed_tenant_auth( db: &sea_orm::DatabaseConnection, tenant_id: Uuid, super_admin_password: &str, ) -> Result<(), AuthError> { let now = chrono::Utc::now(); let system_user_id = Uuid::nil(); // 1. Create permissions let mut perm_ids: Vec = Vec::with_capacity(DEFAULT_PERMISSIONS.len()); for (code, name, resource, action, desc) in DEFAULT_PERMISSIONS { let perm_id = Uuid::now_v7(); perm_ids.push(perm_id); let perm = permission::ActiveModel { id: Set(perm_id), tenant_id: Set(tenant_id), code: Set(code.to_string()), name: Set(name.to_string()), resource: Set(resource.to_string()), action: Set(action.to_string()), description: Set(Some(desc.to_string())), created_at: Set(now), updated_at: Set(now), created_by: Set(system_user_id), updated_by: Set(system_user_id), deleted_at: Set(None), version: Set(1), }; perm.insert(db) .await .map_err(|e| AuthError::Validation(e.to_string()))?; } // 2. Create "admin" role with all permissions let admin_role_id = Uuid::now_v7(); let admin_role = role::ActiveModel { id: Set(admin_role_id), tenant_id: Set(tenant_id), name: Set("管理员".to_string()), code: Set("admin".to_string()), description: Set(Some("系统管理员,拥有所有权限".to_string())), is_system: Set(true), created_at: Set(now), updated_at: Set(now), created_by: Set(system_user_id), updated_by: Set(system_user_id), deleted_at: Set(None), version: Set(1), }; admin_role .insert(db) .await .map_err(|e| AuthError::Validation(e.to_string()))?; // Assign all permissions to admin role for perm_id in &perm_ids { let rp = role_permission::ActiveModel { role_id: Set(admin_role_id), permission_id: Set(*perm_id), tenant_id: Set(tenant_id), created_at: Set(now), updated_at: Set(now), created_by: Set(system_user_id), updated_by: Set(system_user_id), deleted_at: Set(None), version: Set(1), }; rp.insert(db) .await .map_err(|e| AuthError::Validation(e.to_string()))?; } // 3. Create "viewer" role with read-only permissions let viewer_role_id = Uuid::now_v7(); let viewer_role = role::ActiveModel { id: Set(viewer_role_id), tenant_id: Set(tenant_id), name: Set("查看者".to_string()), code: Set("viewer".to_string()), description: Set(Some("只读用户,可查看所有数据".to_string())), is_system: Set(true), created_at: Set(now), updated_at: Set(now), created_by: Set(system_user_id), updated_by: Set(system_user_id), deleted_at: Set(None), version: Set(1), }; viewer_role .insert(db) .await .map_err(|e| AuthError::Validation(e.to_string()))?; // Assign read permissions to viewer role for idx in READ_PERM_INDICES { if *idx < perm_ids.len() { let rp = role_permission::ActiveModel { role_id: Set(viewer_role_id), permission_id: Set(perm_ids[*idx]), tenant_id: Set(tenant_id), created_at: Set(now), updated_at: Set(now), created_by: Set(system_user_id), updated_by: Set(system_user_id), deleted_at: Set(None), version: Set(1), }; rp.insert(db) .await .map_err(|e| AuthError::Validation(e.to_string()))?; } } // 4. Create super admin user let admin_user_id = Uuid::now_v7(); let password_hash = password::hash_password(super_admin_password)?; let admin_user = user::ActiveModel { id: Set(admin_user_id), tenant_id: Set(tenant_id), username: Set("admin".to_string()), email: Set(None), phone: Set(None), display_name: Set(Some("系统管理员".to_string())), avatar_url: Set(None), status: Set("active".to_string()), last_login_at: Set(None), created_at: Set(now), updated_at: Set(now), created_by: Set(system_user_id), updated_by: Set(system_user_id), deleted_at: Set(None), version: Set(1), }; admin_user .insert(db) .await .map_err(|e| AuthError::Validation(e.to_string()))?; // Create password credential for admin user let cred = user_credential::ActiveModel { id: Set(Uuid::now_v7()), tenant_id: Set(tenant_id), user_id: Set(admin_user_id), credential_type: Set("password".to_string()), credential_data: Set(Some(serde_json::json!({ "hash": password_hash }))), verified: Set(true), created_at: Set(now), updated_at: Set(now), created_by: Set(system_user_id), updated_by: Set(system_user_id), deleted_at: Set(None), version: Set(1), }; cred.insert(db) .await .map_err(|e| AuthError::Validation(e.to_string()))?; // 5. Assign admin role to admin user let user_role_assignment = user_role::ActiveModel { user_id: Set(admin_user_id), role_id: Set(admin_role_id), tenant_id: Set(tenant_id), created_at: Set(now), updated_at: Set(now), created_by: Set(system_user_id), updated_by: Set(system_user_id), deleted_at: Set(None), version: Set(1), }; user_role_assignment .insert(db) .await .map_err(|e| AuthError::Validation(e.to_string()))?; tracing::info!( tenant_id = %tenant_id, admin_user_id = %admin_user_id, "Seeded tenant auth: admin user, 2 roles, {} permissions", DEFAULT_PERMISSIONS.len() ); Ok(()) }