fix(v1): сделать отзыв доступа, бэкап и диагностику соответствующими своим именам
Проход по операциям, которые делают не то, что обещает их имя. P0. Удаление bootstrap-admin-peer не было отзывом доступа. Признаком «создавать пир или нет» служило наличие строки в таблице, а HY2XS_ADMIN_CON_PASS продолжает жить в /etc/hy2xs/hy2xs.env — его читает systemd-юнит. Оператор удалял пира, доступ исчезал, и ближайший restart возвращал того же пира с тем же секретом. Молча. Признаком стала отметка BOOTSTRAP_PEER_SEEDED в таблице config: «создавался когда-либо», а не «существует сейчас». Отметка и пир пишутся одной транзакцией. P1. Резервная копия с includeSecrets=true проглатывала и ошибку расшифровки, и отсутствие шифртекста, отдавая пира с пустым secret и успешный ответ. Теперь недоступный секрет любого пира отклоняет весь запрос с указанием имени. P1. DecryptPeerSecret возвращала содержимое колонки как расшифрованный секрет, если оно не начиналось с v1: — остаток поколения с открытыми секретами. P1. doctor перезапускал hysteria-server и hy2xs-admin: диагностика подозрения на проблему обрывала все живые соединения. P1. Админка сама генерировала HYSTERIA2_TRAFFIC_STATS_SECRET, записать который в /etc/hysteria/config.yaml она не может. Сервис объявлял себя здоровым, а machine auth переставал совпадать. P1. Обходы проверки зависимостей (accepted-risk/skipped) не могли произвести артефакт: приёмка требует dependency_security_gate=true. Удалены из сборки и документации, отсутствие проверяется приёмкой. P2. UPDATE по отсутствующей строке config считался успехом, и cron перепланировался при несохранённом значении. Решение по RowsAffected. P2. Слой данных не отличал «записи нет» от «база не ответила»: sentinel-значения ErrPeerNotFound / ErrAdminUserNotFound / ErrConfigNotFound / ErrStorage. P2. Удалены алиасы /:id/client-url и /:id/qr. Контракт разработки: apps/go.mod объявляет toolchain go1.26.7 (директива go — языковой baseline, а не выбор компилятора), tools/dev/doctor.sh|.ps1 сверяют среду с versions.env.
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
"hy2xs-admin/model/constant"
|
||||
"hy2xs-admin/model/entity"
|
||||
"time"
|
||||
)
|
||||
@@ -12,11 +11,11 @@ import (
|
||||
func GetAdminUser(query interface{}, args ...interface{}) (entity.AdminUser, error) {
|
||||
var admin entity.AdminUser
|
||||
if tx := sqliteDB.Model(&entity.AdminUser{}).Where(query, args...).First(&admin); tx.Error != nil {
|
||||
if tx.Error == gorm.ErrRecordNotFound {
|
||||
return admin, errors.New(constant.WrongPassword)
|
||||
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
|
||||
return admin, ErrAdminUserNotFound
|
||||
}
|
||||
logrus.Errorf("%v", tx.Error)
|
||||
return admin, errors.New(constant.SysError)
|
||||
return admin, ErrStorage
|
||||
}
|
||||
return admin, nil
|
||||
}
|
||||
@@ -24,7 +23,7 @@ func GetAdminUser(query interface{}, args ...interface{}) (entity.AdminUser, err
|
||||
func SaveAdminUser(admin entity.AdminUser) (int64, error) {
|
||||
if tx := sqliteDB.Save(&admin); tx.Error != nil {
|
||||
logrus.Errorf("%v", tx.Error)
|
||||
return 0, errors.New(constant.SysError)
|
||||
return 0, ErrStorage
|
||||
}
|
||||
return *admin.Id, nil
|
||||
}
|
||||
@@ -36,7 +35,7 @@ func UpdateAdminUser(ids []int64, updates map[string]interface{}) error {
|
||||
updates["update_time"] = time.Now().Format("2006-01-02 15:04:05")
|
||||
if tx := sqliteDB.Model(&entity.AdminUser{}).Where("id in ?", ids).Updates(updates); tx.Error != nil {
|
||||
logrus.Errorf("%v", tx.Error)
|
||||
return errors.New(constant.SysError)
|
||||
return ErrStorage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user