refactor: 清理旧版兼容性,升级为 bcrypt 密码算法

- 密码哈希从 MD5+SHA1 升级为 bcrypt
- 删除 super_admins/users 表中的 salt 字段
- 删除旧版升级文件(upgrade.php, check_upgrade, execute_upgrade, sql/upgrades/)
- 删除 PASSWORD_SALT 配置项
- 清理所有'兼容 Python 版'注释
- 新项目独立,无历史包袱
This commit is contained in:
2026-06-22 10:45:13 +08:00
parent 124d7f645e
commit 4193a1a153
17 changed files with 76 additions and 1319 deletions

View File

@@ -16,7 +16,6 @@ import (
"fmt"
"regexp"
"hz-gitea.sea-studio.top/canglan/SharedClassManager/internal/config"
"hz-gitea.sea-studio.top/canglan/SharedClassManager/internal/model"
"hz-gitea.sea-studio.top/canglan/SharedClassManager/internal/repository"
"hz-gitea.sea-studio.top/canglan/SharedClassManager/pkg/crypto"
@@ -100,10 +99,17 @@ func (s *AdminService) getInitialPassword(classID int) (string, error) {
return pwd, nil
}
// hashPassword 对密码进行 bcrypt 哈希,失败时 panic不应发生
func hashPasswordOrPanic(password string) string {
hash, err := crypto.HashPassword(password)
if err != nil {
logger.Sugared.Fatalf("密码哈希失败: %v", err)
}
return hash
}
// AddStudent 新增学生
func (s *AdminService) AddStudent(studentNo, name string, parentAccount *string, classID int, dormitoryNumber *string) (map[string]interface{}, error) {
cfg := config.AppConfig
// 校验宿舍号格式
if !validateDormitoryNumber(dormitoryNumber) {
return map[string]interface{}{"success": false, "message": "宿舍号格式不正确,应为如 东1-101 的格式"}, nil
@@ -134,7 +140,7 @@ func (s *AdminService) AddStudent(studentNo, name string, parentAccount *string,
if err != nil {
return nil, err
}
passwordHash := crypto.HashPassword(defaultPassword, cfg.PasswordSalt)
passwordHash := hashPasswordOrPanic(defaultPassword)
_, err = s.userRepo.CreateStudent(studentNo, passwordHash, name, studentID)
if err != nil {
logger.Sugared.Errorf("创建学生登录账号失败: student_no=%s, student_id=%d, err=%v", studentNo, studentID, err)
@@ -147,7 +153,7 @@ func (s *AdminService) AddStudent(studentNo, name string, parentAccount *string,
if parentAccount != nil && *parentAccount != "" {
exists, _ := s.userRepo.CheckUsernameExists(*parentAccount)
if !exists {
parentHash := crypto.HashPassword(defaultPassword, cfg.PasswordSalt)
parentHash := hashPasswordOrPanic(defaultPassword)
parentRealName := fmt.Sprintf("%s家长", name)
if _, err := s.userRepo.CreateParent(*parentAccount, parentHash, parentRealName, studentID); err != nil {
logger.Sugared.Warnf("创建家长账号失败(学生记录已保留): parent_account=%s, student_id=%d, err=%v", *parentAccount, studentID, err)
@@ -167,7 +173,6 @@ func (s *AdminService) AddStudent(studentNo, name string, parentAccount *string,
// 未使用数据库事务的原因Repository 层未暴露事务接口,全量事务包裹需要较大重构;
// 且批量导入场景下允许部分成功是合理的业务权衡(用户可修正失败记录后重新导入)。
func (s *AdminService) ImportStudents(students []map[string]interface{}, classID int) (map[string]interface{}, error) {
cfg := config.AppConfig
successCount := 0
failedCount := 0
var details []map[string]interface{}
@@ -262,7 +267,7 @@ func (s *AdminService) ImportStudents(students []map[string]interface{}, classID
existingSet[studentNo] = true
// 创建学生登录账号
passwordHash := crypto.HashPassword(password, cfg.PasswordSalt)
passwordHash := hashPasswordOrPanic(password)
if _, err := s.userRepo.CreateStudent(studentNo, passwordHash, name, studentID); err != nil {
logger.Sugared.Errorf("批量导入-创建学生登录账号失败: student_no=%s, student_id=%d, err=%v", studentNo, studentID, err)
// 回滚学生记录
@@ -277,7 +282,7 @@ func (s *AdminService) ImportStudents(students []map[string]interface{}, classID
// 创建家长账号
if parentAccount != nil && *parentAccount != "" && !usernameSet[*parentAccount] {
parentHash := crypto.HashPassword(password, cfg.PasswordSalt)
parentHash := hashPasswordOrPanic(password)
parentRealName := fmt.Sprintf("%s家长", name)
if _, err := s.userRepo.CreateParent(*parentAccount, parentHash, parentRealName, studentID); err != nil {
logger.Sugared.Errorf("批量导入-创建家长账号失败: parent_account=%s, student_id=%d, err=%v", *parentAccount, studentID, err)
@@ -346,7 +351,6 @@ func (s *AdminService) ResetStudentPassword(studentID int, newPassword string) e
if valid, msg := crypto.ValidatePasswordStrength(newPassword); !valid {
return fmt.Errorf("%s", msg)
}
cfg := config.AppConfig
student, err := s.studentRepo.GetByID(studentID)
if err != nil {
return fmt.Errorf("学生不存在")
@@ -356,14 +360,15 @@ func (s *AdminService) ResetStudentPassword(studentID int, newPassword string) e
if err != nil {
return fmt.Errorf("学生登录账号不存在")
}
passwordHash := crypto.HashPassword(newPassword, cfg.PasswordSalt)
passwordHash, err := crypto.HashPassword(newPassword)
if err != nil {
return fmt.Errorf("密码加密失败")
}
return s.userRepo.UpdatePassword(user.UserID, passwordHash)
}
// AddAdmin 添加管理员
func (s *AdminService) AddAdmin(username, realName, password, roleType string, classID int, subjectID *int) (map[string]interface{}, error) {
cfg := config.AppConfig
exists, _ := s.userRepo.CheckUsernameExists(username)
if exists {
return map[string]interface{}{"success": false, "message": "用户名已存在"}, nil
@@ -377,7 +382,10 @@ func (s *AdminService) AddAdmin(username, realName, password, roleType string, c
password = pwd
}
passwordHash := crypto.HashPassword(password, cfg.PasswordSalt)
passwordHash, err := crypto.HashPassword(password)
if err != nil {
return nil, fmt.Errorf("密码加密失败: %w", err)
}
userID, err := s.userRepo.CreateAdmin(username, passwordHash, realName)
if err != nil {
return nil, err
@@ -436,8 +444,10 @@ func (s *AdminService) ResetAdminPassword(userID int, newPassword string) error
if valid, msg := crypto.ValidatePasswordStrength(newPassword); !valid {
return fmt.Errorf("%s", msg)
}
cfg := config.AppConfig
passwordHash := crypto.HashPassword(newPassword, cfg.PasswordSalt)
passwordHash, err := crypto.HashPassword(newPassword)
if err != nil {
return fmt.Errorf("密码加密失败")
}
return s.userRepo.UpdatePassword(userID, passwordHash)
}