From 4e093db632176e326253f3af0dac1650f69aebd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Fri, 14 Aug 2026 16:51:12 +0400 Subject: [PATCH] =?UTF-8?q?v0.1.35:=20=D0=BB=D0=B8=D0=BC=D0=B8=D1=82=20?= =?UTF-8?q?=D0=BE=D1=87=D0=B5=D1=80=D0=B5=D0=B4=D0=B5=D0=B9=20JWT-=D1=82?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=D0=BD=D1=82=D0=BE=D0=B2=2050,=20=D0=BE=D0=B1?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BB=D0=B8?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D0=B0=20=D0=BF=D1=80=D0=B8=20=D0=BB=D0=BE?= =?UTF-8?q?=D0=B3=D0=B8=D0=BD=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/admin.go | 2 +- app/tenant/tenant_store.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/admin/admin.go b/app/admin/admin.go index 372c157..b35e8ee 100644 --- a/app/admin/admin.go +++ b/app/admin/admin.go @@ -245,7 +245,7 @@ func (h *Handler) jwtAuth(w http.ResponseWriter, r *http.Request) { // Auto-provisioning: тенант и ключи детерминированы из email. // Токен — только аутентификация; ключи в ответ не возвращаем (GET /ui/api/credentials). - t, err := h.store.CreateFromJWT(claims.Sub, claims.Email, 10) + t, err := h.store.CreateFromJWT(claims.Sub, claims.Email, tenant.DefaultTenantMaxQueues) if err != nil { log.Errorf("jwt auth: failed to create tenant: %v", err) jsonErr(w, http.StatusInternalServerError, "failed to provision tenant") diff --git a/app/tenant/tenant_store.go b/app/tenant/tenant_store.go index 9fdd05d..bf14ec4 100644 --- a/app/tenant/tenant_store.go +++ b/app/tenant/tenant_store.go @@ -18,6 +18,11 @@ import ( // MaxTenantsGlobal — глобальный лимит тенантов (защита от OOM, Fix #12) const MaxTenantsGlobal = 1000 +// DefaultTenantMaxQueues — лимит очередей для JWT-тенантов (auto-provisioning). +// Используется в app/admin при логине; при каждом логине лимит существующего +// тенанта обновляется до этого значения (см. CreateFromJWT). +const DefaultTenantMaxQueues = 50 + // Tenant — модель тенанта shared-sqs. // AccessKey используется как идентификатор в AWS Authorization header. type Tenant struct { @@ -215,6 +220,16 @@ func (s *TenantStore) CreateFromJWT(sub, email string, maxQueues int) (*Tenant, if sub != "" { existing.NubesSub = sub } + // Обновляем лимит очередей на актуальное значение из кода при каждом + // логине и персистим в Redis — иначе после рестарта пода из Redis + // восстановится старый лимит (было: тенант навсегда оставался с лимитом, + // заданным при первом логине). + if existing.MaxQueues != maxQueues { + existing.MaxQueues = maxQueues + if data, err := json.Marshal(existing); err == nil { + persistence.SaveTenantRaw(existing.ID, data) + } + } return existing, nil } // Легаси: убираем старую запись из всех индексов и из Redis, ниже создаём новую