95 lines
2.5 KiB
Go
95 lines
2.5 KiB
Go
package database
|
|
|
|
import (
|
|
"RenewCMS/internal/domain/role"
|
|
entity "RenewCMS/internal/infrastructure/persistence/models"
|
|
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/clause"
|
|
)
|
|
|
|
const (
|
|
usersTable = "users"
|
|
legacyRoleColumn = "role"
|
|
legacyOwnerValue = "owner"
|
|
legacyAdminValue = "admin"
|
|
legacyUnsetValue = ""
|
|
unassignedRoleCond = "(role_id IS NULL OR role_id = 0)"
|
|
)
|
|
|
|
func legacyRoleColumnExists(db *gorm.DB) bool {
|
|
return db.Migrator().HasColumn(usersTable, legacyRoleColumn)
|
|
}
|
|
|
|
func requireBuiltInRoleID(tx *gorm.DB, name string) (uint32, error) {
|
|
id, found, err := builtInRoleID(tx, name)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if !found {
|
|
return 0, role.ErrRoleNotFound
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
func BackfillLegacyUserRoles(db *gorm.DB) error {
|
|
if !legacyRoleColumnExists(db) {
|
|
return nil
|
|
}
|
|
return db.Transaction(func(tx *gorm.DB) error {
|
|
done, err := markerApplied(tx, legacyUserRolesMarker)
|
|
if err != nil || done {
|
|
return err
|
|
}
|
|
ownerID, err := requireBuiltInRoleID(tx, role.OwnerName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
adminID, err := requireBuiltInRoleID(tx, role.AdminName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
writerID, err := requireBuiltInRoleID(tx, role.WriterName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
legacy := clause.Column{Name: legacyRoleColumn}
|
|
assign := func(roleID uint32, condition string, args ...any) error {
|
|
return tx.Table(usersTable).Where(unassignedRoleCond).Where(condition, args...).UpdateColumn("role_id", roleID).Error
|
|
}
|
|
var owners []uint32
|
|
if err := tx.Table(usersTable).Where(unassignedRoleCond).Where("? = ?", legacy, legacyOwnerValue).Order("id asc").Pluck("id", &owners).Error; err != nil {
|
|
return err
|
|
}
|
|
if len(owners) > 0 {
|
|
if err := assign(ownerID, "id = ?", owners[0]); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if err := assign(adminID, "? = ?", legacy, legacyOwnerValue); err != nil {
|
|
return err
|
|
}
|
|
if err := assign(adminID, "? = ?", legacy, legacyAdminValue); err != nil {
|
|
return err
|
|
}
|
|
if len(owners) == 0 {
|
|
var lowest []uint32
|
|
if err := tx.Model(&entity.User{}).Order("id asc").Limit(1).Pluck("id", &lowest).Error; err != nil {
|
|
return err
|
|
}
|
|
if len(lowest) > 0 {
|
|
if err := assign(ownerID, "? = ? AND id = ?", legacy, legacyUnsetValue, lowest[0]); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
if err := assign(adminID, "? = ?", legacy, legacyUnsetValue); err != nil {
|
|
return err
|
|
}
|
|
if err := assign(writerID, "1 = 1"); err != nil {
|
|
return err
|
|
}
|
|
return applyMarker(tx, legacyUserRolesMarker)
|
|
})
|
|
}
|