Ir para o conteúdo

Plano — Lorentz.Licenca.Api (.NET 9) + UI Portal / MonitorOPS

Instalação passo a passo (VPS): 30-instalar-licenca.md · Índice: 28-indice-instalacao-apps.md

Status: Fase 1 implementada (server/Lorentz.Licenca.Core + Lorentz.Licenca.Api).
Fase 2 concluída: Docker profile licenca, proxy nginx, UI Portal, MonitorOPS.
Pendente (Fase 3): persistência SQL, testes golden vs WinForms.


1. Objetivo

Substituir a dependência do Lorentz.Licenca.exe (WinForms, Windows) por:

Componente Função
Lorentz.Licenca.Core Crypto + montagem payload .lic (compatível CTI/URA/Supervisor)
Lorentz.Licenca.Api HTTP :8092 no Linux Docker
Portal /licenca/ UI comercial (formulário + download .lic)
MonitorOPS Atalho / card Ferramentas (opcional)

O WinForms permanece como fallback até validação cruzada em produção.


2. Arquitetura alvo

Browser (equipe comercial / TI)
    ├─► Portal /licenca/          (estático nginx)
    │         │
    │         └─► /api/licenca/*   (proxy nginx)
    │                   │
    │                   ▼
    │         lorentz-licenca :8092  (.NET 9)
    │                   │
    │                   ├─ Lorentz.Licenca.Core
    │                   └─ sqlserver:1433  (fase 2 — SAC_EMPRESA / SAC_LICENCA)
    └─► MonitorOPS :9090  (link rápido → Portal /licenca/)
flowchart LR
    Portal["Portal /licenca/"]
    Nginx["nginx proxy"]
    API["Lorentz.Licenca.Api :8092"]
    Core["Lorentz.Licenca.Core"]
    SQL[(SQL Server LorentzCTI)]
    CTI["LorentzCTI / URA / Supervisor"]

    Portal --> Nginx --> API --> Core
    API -.->|fase 2| SQL
    Core -->|".lic compatível"| CTI

3. Repositório — o que já existe

Caminho Descrição
server/Lorentz.Licenca/ WinForms legado (renomeado)
server/Lorentz.Licenca.Core/ Biblioteca compartilhada
server/Lorentz.Licenca.Api/ Host HTTP (LicencaApiHost.vb)
server/Lorentz.Licenca.Api.sln Build .NET 9
server/Lorentz.Licenca.Api/docs/api-licenca.md Referência REST

Build local

dotnet build server/Lorentz.Licenca.Api.sln -c Release
LORENTZ_LICENCA_API_KEY=dev dotnet run --project server/Lorentz.Licenca.Api
curl http://127.0.0.1:8092/health

4. API REST (Fase 1)

Método Path Auth Descrição
GET /health Health check
GET /api/licenca/catalog X-Licenca-Api-Key Sistemas e módulos
POST /api/licenca/generate idem Gera chave cifrada
GET /api/licenca/download/{cnpj}?key=... idem Download {cnpj}.lic

Header: X-Licenca-Api-Key: <LORENTZ_LICENCA_API_KEY>

Exemplo POST /api/licenca/generate:

{
  "cnpj": "03774573000160",
  "razaoSocial": "Cliente Exemplo Ltda",
  "nomeUsual": "Cliente Exemplo",
  "quantidadeAgentes": 10,
  "chaveValidadeInicio": "2026-07-12T00:00:00",
  "chaveValidadeFim": "2027-07-12T23:59:59",
  "licencaValidade": "2027-07-12T23:59:59",
  "naoExpirarLicenca": false,
  "modulos": [
    {
      "sistema": "CTI",
      "modulo": "Servidor",
      "licencas": 1,
      "usuarios": 50,
      "dataInicio": "2026-07-12T00:00:00",
      "dataFim": "2027-07-12T23:59:59"
    }
  ]
}

Resposta:

{
  "encryptedKey": "<base64>",
  "cnpj": "03774573000160",
  "arquivoLic": "03774573000160.lic",
  "downloadUrl": "/api/licenca/download/03774573000160"
}

5. Compatibilidade criptográfica

  • Algoritmo: Rijndael AES-256-CBC, PaddingMode.Zeros
  • Chaves legadas (mesmas do CTI):
  • Key: lkirwf897+22#bbtrm8814z5qq=498j5
  • IV: H8g7F6e5D4c3B2a1
  • Payload: formato FU_GerarChave de frmLicenca.vb

Fase 1.1 (obrigatória antes de produção): testes golden — gerar no WinForms e na API com mesmo input; comparar encryptedKey byte a byte.


6. Stack VPS — integração Docker (Fase 2)

6.1 Variáveis .env

LORENTZ_LICENCA_API_PORT=8092
LORENTZ_LICENCA_API_KEY=ChangeMe_LicencaApi2026!
LORENTZ_LICENCA_BIND_IP=127.0.0.1

6.2 Serviço Compose (profile licenca)

Espelhar lorentz-basehistorica:

lorentz-licenca:
  profiles: [licenca]
  build:
    dockerfile: docker/lorentz-licenca/Dockerfile.runtime
  ports:
    - "${LORENTZ_LICENCA_BIND_IP:-127.0.0.1}:8092:8092"
  environment:
    LORENTZ_LICENCA_API_PORT: "8092"
    LORENTZ_LICENCA_API_KEY: ${LORENTZ_LICENCA_API_KEY}

Scripts:

  • scripts/build-lorentz-licenca-zip.sh
  • scripts/extract-lorentz-licenca-publish.sh
  • scripts/deploy-licenca.sh

6.3 Proxy nginx (Portal)

location /api/licenca/ {
    proxy_pass http://lorentz-licenca:8092/api/licenca/;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Licenca-Api-Key $http_x_licenca_api_key;
}

config.jsonlicencaApi.apiBase, licencaApi.apiKey


7. UI Portal /licenca/ (Fase 2)

Tela Campos
Empresa CNPJ, razão, endereço, MAC
Validade Datas chave + licença, checkbox “não expirar”
Módulos Grid CTI/SAC/TMK × módulos (como WinForms)
Ações Gerar · Copiar chave · Download .lic

Acesso: restrito — VPN, IP allowlist ou subdomínio licenca.orbitall.app (ver 22-plano-dominio-orbitall-app.md).

Arquivos (placeholder Fase 1):

  • portal/licenca/index.html
  • portal/assets/licenca.js

Entrada no hub: app Licença em portal.apps.json.template.


8. MonitorOPS (Fase 2)

  • Card Ferramentas → Gerar licença Lorentz → abre Portal /licenca/ ou iframe
  • Checagem de porta 8092 em monitor_services.py quando profile licenca ativo
  • Runbook: API indisponível → docker compose --profile licenca up -d lorentz-licenca

9. Persistência SQL (Fase 3)

Portar lógica de btnGravar_Click (frmLicenca.vb):

  • SAC_EMPRESA — dados cliente + ObsCli (chave)
  • SAC_LICENCA — módulos por sistema
  • Modo PHP8 (att_phoenix.php?cmd=phoenixlic) — avaliar se ainda necessário ou unificar só Core

Endpoint proposto: POST /api/licenca/persist (grava SQL + retorna chave).


10. Segurança

Item Regra
Exposição Nunca 0.0.0.0:8092 público sem auth
Auth X-Licenca-Api-Key forte; rotacionar no .env
Audit Log estruturado: CNPJ, usuário (fase 3), IP
Chaves AES Migrar para secret manager (fase 4); manter legado até CTI migrar
Separação Não confundir com license-system Laravel (MySQL, outro formato)

11. Fases e checklist

Fase 1 — Core + API ✅ (código)

  • [x] Lorentz.Licenca.Core — crypto + builder + catálogo
  • [x] Lorentz.Licenca.Api — endpoints generate/catalog/download
  • [x] Build Release OK
  • [ ] Testes golden vs WinForms
  • [ ] docs/api-licenca.md no repo server

Fase 2 — Stack + UI ✅

  • [x] Dockerfile.runtime + profile licenca no compose
  • [x] Proxy nginx + licencaApi no config.json
  • [x] UI Portal /licenca/ (formulário + download .lic)
  • [x] Entrada no hub Orbitall (status: active)
  • [x] MonitorOPS — link rápido + card Ferramentas + runbook troubleshooting
  • [x] Scripts build/extract/deploy + docker-compose.source.yml

Fase 3 — SQL + operação

  • [ ] Persistência SAC_EMPRESA / SAC_LICENCA
  • [ ] Leitura licença existente (equivalente “Ler chave”)
  • [ ] Runbook em docs/18-monitor-troubleshooting.md

Fase 4 — Domínio + hardening

  • [ ] licenca.orbitall.app via Caddy (doc 22)
  • [ ] Desativar WinForms em estações comerciais (opcional)

12. Domínio (futuro)

Subdomínio Uso
licenca.orbitall.app Portal UI + proxy API (restrito TI/comercial)

13. Documentação relacionada

Doc Conteúdo
22-plano-dominio-orbitall-app.md TLS e subdomínios
server/Lorentz.Licenca/README.md WinForms legado
server/Lorentz.Licenca.Api/docs/api-licenca.md API REST

14. Histórico

Data Notas
2026-07-12 Fase 2 concluída: Docker profile licenca, nginx, Portal UI, MonitorOPS.
2026-07-12 Plano + scaffold Core/Api; build Release OK.