package auth import ( "context" "fmt" "strings" "sync" "time" "chat-agent-system/internal/config" ) // AuthStore 用户与认证配置存储接口 type AuthStore interface { GetUserByUsername(ctx context.Context, username string) (*UserAccount, error) GetUserByID(ctx context.Context, id int64) (*UserAccount, error) CreateUser(ctx context.Context, user *UserAccount) (*UserAccount, error) UpdateUser(ctx context.Context, user *UserAccount) (*UserAccount, error) UpdateUserRole(ctx context.Context, id int64, roleID, position string) (*UserAccount, error) UpdateUserStatus(ctx context.Context, id int64, status AccountStatus) (*UserAccount, error) UpdateUserPassword(ctx context.Context, id int64, passwordHash string, mustChangePassword bool) (*UserAccount, error) ListUsers(ctx context.Context) ([]*UserAccount, error) GetConfig(ctx context.Context) (SystemAuthConfig, error) UpdateConfig(ctx context.Context, cfg SystemAuthConfig) error } // MemoryStore 内存与并发安全存储实现 type MemoryStore struct { mu sync.RWMutex users map[int64]*UserAccount nextID int64 cfg SystemAuthConfig } // NewMemoryStore 初始化并载入初始系统管理员与基线用户 func NewMemoryStore(cfg *config.Config) *MemoryStore { store := &MemoryStore{ users: make(map[int64]*UserAccount), nextID: 1, cfg: SystemAuthConfig{ AllowRegistration: true, RequireApproval: false, }, } if cfg != nil { store.cfg.AllowRegistration = cfg.AuthRegistrationEnabled store.cfg.RequireApproval = cfg.AuthRequireApproval } now := time.Now().Format("2006-01-02 15:04:05") // 1. 初始化 .env 系统超级管理员 adminUser := "admin" adminPass := "admin-secret-password-123" if cfg != nil && cfg.AdminUsername != "" { adminUser = cfg.AdminUsername } if cfg != nil && cfg.AdminPassword != "" { adminPass = cfg.AdminPassword } adminHash, _ := HashPassword(adminPass) store.users[1] = &UserAccount{ ID: 1, Username: adminUser, Name: "系统管理员", PasswordHash: adminHash, Status: StatusActive, MustChangePassword: false, RoleID: "role-admin", Position: "系统管理员", Department: "系统运维部", EmployeeID: "SYS-000", CreatedAt: now, UpdatedAt: now, } store.nextID = 2 // 2. 标准测试用户仅 dev/test 环境种子化;生产不得携带固定密码演示账号 env := "" if cfg != nil { env = cfg.Env } if env == "dev" || env == "test" || env == "" { defaultPassHash, _ := HashPassword("123456") seedUsers := []struct { id int64 username string name string roleID string position string dept string employeeID string }{ {2, "zhanggong", "张工", "role-tech-lead", "技术主管", "骨科耗材研发组", "RD-001"}, {3, "lizhuguan", "李主管", "role-tech-lead", "技术主管", "骨科耗材研发组", "RD-002"}, {4, "wangzong", "王总监", "role-director", "研发总监", "研发中心", "RD-003"}, {5, "guest", "访客", "role-guest", "待指派", "外协中心", "EXT-999"}, } for _, su := range seedUsers { store.users[su.id] = &UserAccount{ ID: su.id, Username: su.username, Name: su.name, PasswordHash: defaultPassHash, Status: StatusActive, MustChangePassword: false, RoleID: su.roleID, Position: su.position, Department: su.dept, EmployeeID: su.employeeID, CreatedAt: now, UpdatedAt: now, } if su.id >= store.nextID { store.nextID = su.id + 1 } } } return store } // GetUserByUsername 根据用户名查询 func (s *MemoryStore) GetUserByUsername(ctx context.Context, username string) (*UserAccount, error) { s.mu.RLock() defer s.mu.RUnlock() for _, u := range s.users { if strings.EqualFold(u.Username, username) { copy := *u return ©, nil } } return nil, fmt.Errorf("user not found: %s", username) } // GetUserByID 根据用户ID查询 func (s *MemoryStore) GetUserByID(ctx context.Context, id int64) (*UserAccount, error) { s.mu.RLock() defer s.mu.RUnlock() u, exists := s.users[id] if !exists { return nil, fmt.Errorf("user not found: %d", id) } copy := *u return ©, nil } // CreateUser 创建新用户账号 func (s *MemoryStore) CreateUser(ctx context.Context, user *UserAccount) (*UserAccount, error) { s.mu.Lock() defer s.mu.Unlock() for _, existing := range s.users { if strings.EqualFold(existing.Username, user.Username) { return nil, fmt.Errorf("username already exists: %s", user.Username) } } user.ID = s.nextID s.nextID++ now := time.Now().Format("2006-01-02 15:04:05") if user.CreatedAt == "" { user.CreatedAt = now } user.UpdatedAt = now copied := *user s.users[user.ID] = &copied result := *user return &result, nil } // UpdateUser 更新用户基础资料 func (s *MemoryStore) UpdateUser(ctx context.Context, user *UserAccount) (*UserAccount, error) { s.mu.Lock() defer s.mu.Unlock() existing, ok := s.users[user.ID] if !ok { return nil, fmt.Errorf("user not found: %d", user.ID) } existing.Name = user.Name existing.Department = user.Department existing.EmployeeID = user.EmployeeID existing.Email = user.Email existing.Avatar = user.Avatar existing.UpdatedAt = time.Now().Format("2006-01-02 15:04:05") copy := *existing return ©, nil } // UpdateUserRole 更新用户职位与全局角色 func (s *MemoryStore) UpdateUserRole(ctx context.Context, id int64, roleID, position string) (*UserAccount, error) { s.mu.Lock() defer s.mu.Unlock() existing, ok := s.users[id] if !ok { return nil, fmt.Errorf("user not found: %d", id) } existing.RoleID = roleID existing.Position = position existing.UpdatedAt = time.Now().Format("2006-01-02 15:04:05") copy := *existing return ©, nil } // UpdateUserStatus 更新用户账号状态 func (s *MemoryStore) UpdateUserStatus(ctx context.Context, id int64, status AccountStatus) (*UserAccount, error) { s.mu.Lock() defer s.mu.Unlock() existing, ok := s.users[id] if !ok { return nil, fmt.Errorf("user not found: %d", id) } existing.Status = status existing.UpdatedAt = time.Now().Format("2006-01-02 15:04:05") copy := *existing return ©, nil } // UpdateUserPassword 更新用户密码并置位/复位首次强制改密 func (s *MemoryStore) UpdateUserPassword(ctx context.Context, id int64, passwordHash string, mustChangePassword bool) (*UserAccount, error) { s.mu.Lock() defer s.mu.Unlock() existing, ok := s.users[id] if !ok { return nil, fmt.Errorf("user not found: %d", id) } existing.PasswordHash = passwordHash existing.MustChangePassword = mustChangePassword existing.UpdatedAt = time.Now().Format("2006-01-02 15:04:05") copy := *existing return ©, nil } // ListUsers 列出所有用户 func (s *MemoryStore) ListUsers(ctx context.Context) ([]*UserAccount, error) { s.mu.RLock() defer s.mu.RUnlock() list := make([]*UserAccount, 0, len(s.users)) for _, u := range s.users { copy := *u // 脱敏密码哈希 copy.PasswordHash = "" list = append(list, ©) } return list, nil } // GetConfig 获取准入配置 func (s *MemoryStore) GetConfig(ctx context.Context) (SystemAuthConfig, error) { s.mu.RLock() defer s.mu.RUnlock() return s.cfg, nil } // UpdateConfig 更新准入配置 func (s *MemoryStore) UpdateConfig(ctx context.Context, cfg SystemAuthConfig) error { s.mu.Lock() defer s.mu.Unlock() s.cfg = cfg return nil }