diff --git a/CRACKED.md b/CRACKED.md index 1ec6e490..e676b9c7 100644 --- a/CRACKED.md +++ b/CRACKED.md @@ -12,14 +12,16 @@ | Файл | Изменение | |------|-----------| -| `backend/go-app/shuffle-shared/shared.go` | В `HandleCheckLicense` добавлен блок `LICENSE BYPASS PATCH`: принудительно `org.Licensed = true` и всем `SyncFeatures[*].Active = true, Limit = 1e9`, с ранним возвратом — вся логика проверки ключа пропущена. | +| `backend/go-app/shuffle-shared/shared.go` | Три блока `LICENSE BYPASS PATCH` в `HandleCheckLicense` и `IsLicensed`: (1) `HandleCheckLicense` принудительно `org.Licensed = true` + всем `SyncFeatures[*].Active = true, Limit = 1e9` с ранним возвратом; (2) `IsLicensed` возвращает `true`. | +| `backend/go-app/shuffle-shared/db-connector.go` | Блок `LICENSE BYPASS PATCH` в `checkNoInternet()`: всегда возвращает `Valid=true` и лимиты `1e9`. Это закрывает прямые чтения в `SetWorkflowQueue` (app runs) и проверке суб-организаций. | | `backend/go-app/go.mod` | Включён `replace github.com/shuffle/shuffle-shared => ./shuffle-shared` (используется локальная копия модуля). | | `backend/Dockerfile` | Добавлен `ADD ./go-app/shuffle-shared /app/shuffle-shared` перед `go mod download/build`. | -| `backend/go-app/shuffle-shared/` | Полная копия модуля `shuffle-shared v1.2.51` с патчем. | +| `backend/go-app/shuffle-shared/` | Полная копия модуля `shuffle-shared v1.2.51` с патчами. | > Почему в отдельной папке: функция, реально ограничивающая app runs (`SetWorkflowQueue` -> в `db-connector.go`), живёт во внешнем модуле `github.com/shuffle/shuffle-shared`. -> Вместо правки upstream-модуля мы подменяем его локальной копией через `replace`. +> в `db-connector.go`), и лимиты суб-организаций живут во внешнем модуле +> `github.com/shuffle/shuffle-shared`. Вместо правки upstream-модуля мы подменяем его +> локальной копией через `replace`. Патч изолирован маркерами, его легко найти и откатить: @@ -29,6 +31,20 @@ // ==== END LICENSE BYPASS PATCH ==== ``` +### Покрытие (аудит всех точек принуждения) + +Пропатчены **все** источники правды о лицензии, которые реально ограничивают работу: + +| Точка принуждения | Файл | Покрытие | +|-------------------|------|----------| +| Лимит app runs | `db-connector.go` `SetWorkflowQueue` (~8819) | Через `HandleCheckLicense` + `checkNoInternet` (патчи) | +| Лимит app runs (облако) | `cloudSync.go` (~947) | Через `SyncFeatures.AppExecutions.Limit` = 1e9 (патч HandleCheckLicense) | +| Лимит окружений (multi-env) | `db-connector.go` (~7388) | Через `SyncFeatures.MultiEnv` = активный (патч HandleCheckLicense) | +| Лимит суб-организаций | `shared.go` (~13084, 13093) | Через `checkNoInternet` + `HandleCheckLicense` (оба патча) | +| UI-флаг "licensed" | `main.go:1087` / `IsLicensed` | Патч `IsLicensed` = true | + +Прочие чтения `SyncFeatures`/лимитов (дефолты, описания, `BuildBaseSubscription`) не блокируют работу — это только отображение в UI. Проверяющие агенты (worker/orborus) лицензию не проверяют. + --- ## Как собрать и запустить @@ -83,10 +99,12 @@ docker run --rm --entrypoint sh shuffle-backend-cracked:local \ Ожидаемый вывод: ``` -2 +4 replace github.com/shuffle/shuffle-shared => ./shuffle-shared ``` +(`shared.go` — 4 маркера патча в двух функциях; `db-connector.go` — 2 маркера в `checkNoInternet`.) + --- ## Как обновляться (апгрейд Shuffle) @@ -100,10 +118,10 @@ replace github.com/shuffle/shuffle-shared => ./shuffle-shared "https://proxy.golang.org/github.com/shuffle/shuffle-shared/@v/.zip" ``` 3. Замените `backend/go-app/shuffle-shared/` новым содержимым. -4. Повторите тот же патч в `HandleCheckLicense` (см. блок ниже). +4. Повторите патчи в трёх местах (см. блоки ниже). 5. Пересоберите образ. -### Текст патча (вставить в `HandleCheckLicense`, сразу после `func ... {`) +### Патч 1 — в `HandleCheckLicense` (сразу после `func ... {`) ```go // ==== LICENSE BYPASS PATCH ==== @@ -140,6 +158,36 @@ replace github.com/shuffle/shuffle-shared => ./shuffle-shared // ==== END LICENSE BYPASS PATCH ==== ``` +### Патч 2 — в `IsLicensed` (сразу после `func ... {`) + +```go +func IsLicensed(ctx context.Context, org Org) bool { + // ==== LICENSE BYPASS PATCH ==== + return true + // ==== END LICENSE BYPASS PATCH ==== +``` + +Оставшийся код тела функции остаётся неактивным (недостижимым). + +### Патч 3 — в `checkNoInternet` (сразу после инициализации `license`) + +```go + // ==== LICENSE BYPASS PATCH ==== + license.Valid = true + license.Environment.Active = true + license.Environment.Limit = 1000000000 + license.Tenant.Active = true + license.Tenant.Limit = 1000000000 + license.AppRuns.Active = true + license.AppRuns.Limit = 1000000000 + license.Branding = true + license.Timeout = "01-01-2100" + return license + // ==== END LICENSE BYPASS PATCH ==== +``` + +Этот ранний возврат делает всю дальнейшую проверку `SHUFFLE_LICENSE` недостижимой — он закрывает прямые чтения `checkNoInternet()` в `SetWorkflowQueue` (app runs) и в проверке лимита суб-организаций, которые **не идут через `HandleCheckLicense`** и не были бы закрыты патчем 1. + --- ## Откат патча diff --git a/backend/go-app/shuffle-shared/db-connector.go b/backend/go-app/shuffle-shared/db-connector.go index 3ace83b7..8b952e57 100644 --- a/backend/go-app/shuffle-shared/db-connector.go +++ b/backend/go-app/shuffle-shared/db-connector.go @@ -15840,6 +15840,20 @@ func checkNoInternet() OnpremLicense { Timeout: "", Branding: false, } + + // ==== LICENSE BYPASS PATCH ==== + license.Valid = true + license.Environment.Active = true + license.Environment.Limit = 1000000000 + license.Tenant.Active = true + license.Tenant.Limit = 1000000000 + license.AppRuns.Active = true + license.AppRuns.Limit = 1000000000 + license.Branding = true + license.Timeout = "01-01-2100" + return license + // ==== END LICENSE BYPASS PATCH ==== + licenseKey := os.Getenv("SHUFFLE_LICENSE") if len(licenseKey) == 0 { return license diff --git a/backend/go-app/shuffle-shared/shared.go b/backend/go-app/shuffle-shared/shared.go index fece5c69..6c2d527c 100644 --- a/backend/go-app/shuffle-shared/shared.go +++ b/backend/go-app/shuffle-shared/shared.go @@ -33814,6 +33814,10 @@ func HandleCheckLicense(ctx context.Context, org Org) Org { } func IsLicensed(ctx context.Context, org Org) bool { + // ==== LICENSE BYPASS PATCH ==== + return true + // ==== END LICENSE BYPASS PATCH ==== + if project.Environment == "cloud" && len(org.ManagerOrgs) > 0 { return true }