fix: P2 security and correctness issues
P2-10: Change ActivateEmail from GET to POST - token now passed in request body instead of URL query parameter for better security P2-11: Change ValidateResetToken from GET to POST - token now passed in request body instead of URL query parameter to prevent log leakage P2-12: Note - /uploads static exposure remains (requires architectural decision about file serving) P2-13: cursor.Encode() now checks and returns empty string on JSON marshaling error instead of silently ignoring P2-14: initDefaultData and ensurePermissions now properly check and propagate errors from RolePermission creation, and createDefaultPermissions aggregates errors instead of silently continuing P2-15: NewJWT now returns (nil, error) on initialization failure instead of a partially initialized object. All callers updated to handle the error return. Backend routes updated: - POST /auth/activate-email (was GET /activate) - POST /auth/password/validate (was GET /reset-password) Frontend updated to match new API endpoints.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
@@ -155,7 +156,9 @@ func (db *DB) initDefaultData(cfg *config.Config) error {
|
||||
// 3. 给 admin 角色绑定所有权限
|
||||
if adminRoleID > 0 {
|
||||
for _, permID := range permIDs {
|
||||
db.DB.Create(&domain.RolePermission{RoleID: adminRoleID, PermissionID: permID})
|
||||
if err := db.DB.Create(&domain.RolePermission{RoleID: adminRoleID, PermissionID: permID}).Error; err != nil {
|
||||
return fmt.Errorf("assign permission %d to admin role failed: %w", permID, err)
|
||||
}
|
||||
}
|
||||
log.Printf("assigned %d permissions to admin role", len(permIDs))
|
||||
}
|
||||
@@ -166,7 +169,9 @@ func (db *DB) initDefaultData(cfg *config.Config) error {
|
||||
for _, code := range userPermCodes {
|
||||
var perm domain.Permission
|
||||
if err := db.DB.Where("code = ?", code).First(&perm).Error; err == nil {
|
||||
db.DB.Create(&domain.RolePermission{RoleID: userRoleID, PermissionID: perm.ID})
|
||||
if err := db.DB.Create(&domain.RolePermission{RoleID: userRoleID, PermissionID: perm.ID}).Error; err != nil {
|
||||
return fmt.Errorf("assign permission %s to user role failed: %w", code, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -229,7 +234,9 @@ func (db *DB) ensurePermissions() error {
|
||||
var adminRole domain.Role
|
||||
if err := db.DB.Where("code = ?", "admin").First(&adminRole).Error; err == nil {
|
||||
for _, permID := range permIDs {
|
||||
db.DB.Create(&domain.RolePermission{RoleID: adminRole.ID, PermissionID: permID})
|
||||
if err := db.DB.Create(&domain.RolePermission{RoleID: adminRole.ID, PermissionID: permID}).Error; err != nil {
|
||||
return fmt.Errorf("assign permission %d to admin role failed: %w", permID, err)
|
||||
}
|
||||
}
|
||||
log.Printf("assigned %d permissions to admin role (upgrade)", len(permIDs))
|
||||
}
|
||||
@@ -241,7 +248,9 @@ func (db *DB) ensurePermissions() error {
|
||||
for _, code := range userPermCodes {
|
||||
var perm domain.Permission
|
||||
if err := db.DB.Where("code = ?", code).First(&perm).Error; err == nil {
|
||||
db.DB.Create(&domain.RolePermission{RoleID: userRole.ID, PermissionID: perm.ID})
|
||||
if err := db.DB.Create(&domain.RolePermission{RoleID: userRole.ID, PermissionID: perm.ID}).Error; err != nil {
|
||||
return fmt.Errorf("assign permission %s to user role failed: %w", code, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,15 +262,19 @@ func (db *DB) ensurePermissions() error {
|
||||
func (db *DB) createDefaultPermissions() ([]int64, error) {
|
||||
permissions := domain.DefaultPermissions()
|
||||
var ids []int64
|
||||
var errs []error
|
||||
for i := range permissions {
|
||||
p := permissions[i]
|
||||
// 使用 FirstOrCreate 防止重复插入(幂等)
|
||||
result := db.DB.Where("code = ?", p.Code).FirstOrCreate(&p)
|
||||
if result.Error != nil {
|
||||
log.Printf("warn: create permission %s failed: %v", p.Code, result.Error)
|
||||
errs = append(errs, fmt.Errorf("create permission %s failed: %w", p.Code, result.Error))
|
||||
continue
|
||||
}
|
||||
ids = append(ids, p.ID)
|
||||
}
|
||||
if len(errs) > 0 {
|
||||
return ids, errors.Join(errs...)
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user