Режим разработки: служебные разделы, робот НРД и имитации — только по признаку из ключа лицензии

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
zuevav
2026-09-17 18:15:18 +03:00
parent 698956092b
commit 627dbca6af
22 changed files with 157 additions and 38 deletions
+26 -2
View File
@@ -180,6 +180,9 @@ type User struct {
}
func (u *User) Can(perm string) bool {
if perm == "dev" { // режим разработки: включает сервер лицензий, внутри — права настройки
return u != nil && devMode(globalRC) && u.Can("settings")
}
if u == nil || !permLicensed(perm) {
return false
}
@@ -809,16 +812,30 @@ func authExempt(p string) bool {
return true
case strings.HasPrefix(p, "/api/"):
return true
case p == "/admin/api/callback-url": // служебный вызов эмулятора ЛК
return true
case strings.HasPrefix(p, "/admin/npr/static/"):
return true
}
return false
}
// devOnlyPath — служебные разделы разработчиков (тестирование, имитации, прогоны с роботом НРД):
// доступны только в режиме разработки.
func devOnlyPath(p string) bool {
for _, pre := range []string{"/admin/m2m-testing", "/admin/incoming/depo-sim", "/admin/setup/test-nsd", "/admin/setup/test-run",
"/admin/setup/lk-simulate", "/admin/setup/postgres/quick-start", "/admin/help/robot", "/admin/api/clients", "/admin/api/callback-url",
"/admin/setup/advanced-unlock", "/admin/setup/advanced-lock"} {
if p == pre || strings.HasPrefix(p, pre+"/") {
return true
}
}
return false
}
// requiredPerm — какое право нужно для пути и метода.
func requiredPerm(p, method string) string {
if devOnlyPath(p) {
return "dev"
}
switch {
case strings.HasPrefix(p, "/admin/setup") || p == "/admin/wizard":
return "settings"
@@ -853,6 +870,10 @@ func clientIP(r *http.Request) string {
func authMiddleware(rc *RuntimeConfig, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
p := r.URL.Path
if devOnlyPath(p) && !devMode(rc) { // вне режима разработки служебных разделов нет вовсе
http.NotFound(w, r)
return
}
if authExempt(p) {
next.ServeHTTP(w, r)
return
@@ -1272,6 +1293,9 @@ func renderFor(w http.ResponseWriter, t *template.Template, data any) error {
t2.Funcs(template.FuncMap{
"curUser": func() *User { return u },
"can": func(perm string) bool {
if perm == "dev" {
return devMode(globalRC) && (authOpen() || u.Can("settings"))
}
if authOpen() {
return true
}