package controller import ( "strings" "testing" "hy2xs-admin/service" ) // Набор символов логина и пароля закреплён ФАКТИЧЕСКИМ множеством. // // Прежняя запись класса `[a-zA-Z0-9!@#$%^&*()_+-=]` содержала неэкранированный // дефис, из-за чего `+-=` образовывал диапазон и впускал `, - . / 0-9 : ; < =`. // Новая запись перечисляет эти символы явно и НЕ сужает множество: имя // администратора приходит из HY2XS_ADMIN_USER в hy2xs.env, оркестратор его // набор символов не ограничивает, и сужение правила означало бы, что установка // с логином вроде `admin.ops` перестаёт пускать оператора в панель. // // Тест существует, чтобы это решение было явным: попытка «навести порядок» в // классе символов уронит его, а не вход администратора на живом сервере. func TestCredentialCharsetIsUnchanged(t *testing.T) { const historical = "abcXYZ019" + "!@#$%^&*()_" + "+,-./:;<=" for _, symbol := range strings.Split(historical, "") { candidate := "admin" + symbol if !credentialStrPattern.MatchString(candidate) { t.Errorf("символ %q больше не принимается логином: сужение набора ломает вход существующей установки", symbol) } } for _, rejected := range []string{ "admi", // короче шести символов strings.Repeat("a", 33), // длиннее тридцати двух "admin пробел", // пробел "админ1", // кириллица "admin\n1", // перевод строки "admin'1", // апостроф вне набора } { if credentialStrPattern.MatchString(rejected) { t.Errorf("значение %q принято логином, ожидался отказ", rejected) } } } // Имя пира проверяется ОДНИМ правилом на весь продукт: панель и импорт ведут в // одну таблицу и не имеют права требовать разного. func TestPeerNameRuleIsSharedWithImport(t *testing.T) { accepted := []string{ "client-01", "alpha1", "bootstrap-admin-peer", strings.Repeat("a", 6), strings.Repeat("a", 32), } for _, name := range accepted { if !service.IsValidPeerName(name) { t.Errorf("имя %q отклонено, ожидался приём", name) } } rejected := []string{ "", " ", "pc1", strings.Repeat("a", 33), "peer name", "peer\nname", "peer/name", "peer:name", "peer.name", "пир-01", } for _, name := range rejected { if service.IsValidPeerName(name) { t.Errorf("имя %q принято, ожидался отказ", name) } } }