Fix: also patch checkNoInternet and IsLicensed to close all limit gates
dockerbuild / main (backend, true, backend) (push) Failing after 29m15s
dockerbuild / main (frontend, true, frontend) (push) Failing after 26m52s
dockerbuild / sync-orborus (push) Has been cancelled
dockerbuild / main (worker, true, functions/onprem/worker) (push) Has been cancelled

Audit of all license enforcement points found two hard limits that read
checkNoInternet() directly, bypassing HandleCheckLicense:
- SetWorkflowQueue (app runs limit) at db-connector.go:8822/8828
- sub-organization limit check at shared.go:13084

Patches now close all sources of truth:
- checkNoInternet: always return Valid=true with 1e9 limits (closes the
  two direct reads above and cloudSync.go app-runs limit)
- IsLicensed: return true (UI 'licensed' flag)
- HandleCheckLicense: unchanged (already forces Licensed + all limits)

Verified: backend image builds successfully via docker.
This commit is contained in:
Marat Kharitonov
2026-08-12 03:26:33 +03:00
parent 4934f92ddb
commit 747fd15176
3 changed files with 73 additions and 7 deletions
+55 -7
View File
@@ -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/<VERSION>.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.
---
## Откат патча