Caminho no Gestor bibliotecas/modulo-distribuido.php
Permite que um módulo tenha duas metades:
-
central (
"scope": "central-module"no<modulo>.json): roda na instalação central (a do fornecedor), onde ficam o código, os usuários e as permissões; -
distribuído (
"scope": "distributed-module"): roda no site do cliente e guarda os dados no banco do cliente.
O código do módulo central continua usando banco_select(), banco_insert()… normalmente; dentro do canal distribuído, banco_query() empacota a SQL e a executa na instalação do cliente. O cliente vê o módulo como uma tela embutida (iframe) do central, liberada só depois de o central confirmar login e permissão.
Configuração
No .env (variáveis globais): MODULO_DISTRIBUIDO_SECRET (segredo HMAC compartilhado), MODULO_DISTRIBUIDO_CENTRAL_URL (no distribuído: a URL do central) e MODULO_DISTRIBUIDO_ENDPOINT (no central: a URL da API do distribuído). Por módulo, $_CONFIG['modulo-distribuido']['secrets'][<slug>] e ['endpoints'][<slug>] sobrepõem os valores gerais (modulo_distribuido_config_get('modulo-distribuido.secrets.<slug>')).
modulo_distribuido_scope($manifesto), modulo_distribuido_scope_central(), modulo_distribuido_scope_distribuido() e modulo_distribuido_resolver_manifesto() leem o escopo do manifesto (constantes C2F_SCOPE_CENTRAL e C2F_SCOPE_DISTRIBUIDO).
O canal de dados
// No módulo central, envolvendo só as operações de dados do cliente:
// o manifesto do módulo central declara "distributed": {"target-slug": "meu-modulo"}
$config = modulo_distribuido_canal_central($_GESTOR['modulo#'.$_GESTOR['modulo-id']]);
$pedidos = modulo_distribuido_com_canal(function () {
return banco_select(['tabela' => 'pedidos', 'campos' => ['id', 'total']]);
}, $config);
// ou, à mão: banco_distribuido_iniciar($config); … banco_distribuido_finalizar();-
banco_distribuido_ativo()fazbanco_query()desviar parabanco_distribuido_query(). -
modulo_distribuido_montar_payload()empacota a SQL (operacao,modulo,linguagem,timestamp,nonce), emodulo_distribuido_enviar()a manda pormodulo_distribuido_http_post()para<endpoint>/modulo-distribuido/<slug>/db, comX-C2F-Signature= HMAC-SHA256 do corpo (modulo_distribuido_assinar()). -
No distribuído, a API confere a assinatura (
modulo_distribuido_verificar_assinatura(), tempo constante) emodulo_distribuido_executar_local()roda a SQL via PDO:SELECTdevolve colunas e linhas; escrita devolveaffected_rowseinsert_id. -
modulo_distribuido_resposta_para_resultado()converte a resposta numBancoResultadoRemoto, que imita omysqli_resultpara as funções da banco.php.
Autenticação, variáveis e o resto da requisição continuam no banco local do central: só o que estiver dentro do canal vai para o cliente. modulo_distribuido_canal_central($manifesto, $overrides) monta a configuração do lado central a partir de distributed.target-slug (e, opcionalmente, endpoint-config/secret-config, caminhos de chaves em $_CONFIG) do manifesto; modulo_distribuido_canal_distribuido() faz o mesmo no distribuído, para falar com o central; modulo_distribuido_detectar_operacao() e modulo_distribuido_operacao_leitura() classificam a SQL; modulo_distribuido_parse_rota() lê {slug}/{acao} da URL.
Login, permissão e tela
O distribuído não decide acesso: pergunta ao central.
-
O login é o do
perfil-usuariodo central: sem token, o host distribuído manda o navegador para/signin/do central com um contexto assinado; depois do login completo (inclusive segundo fator) o ganchologin.distribuidodevolve um código de uso único, trocado entre servidores pelos tokens (açãoexchange).modulo_distribuido_token_sessao()emodulo_distribuido_persistir_token()guardam e renovam os tokens na sessão. Não existe login por usuário e senha neste canal. -
modulo_distribuido_guardiao()(no distribuído) consulta o central, ondemodulo_distribuido_middleware_central()valida o token e a permissão do usuário no módulo e respondenao-autenticado,sem-permissaoou autorizado. Qualquer falha resolve para o estado mais restritivo. -
modulo_distribuido_estado_renderizacao()traduz isso emlogin,sem-permissaoouiframe;modulo_distribuido_montar_url_iframe()monta a URL da tela do central. -
modulo_distribuido_app()faz tudo numa chamada: token, guardião e a tela do estado, trocando#modulo-distribuido-app#na página pelo componentemodulo-distribuido-app(modulo_distribuido_render_estado(),modulo_distribuido_render_componente(),modulo_distribuido_textos()).
As variantes modulo_distribuido_estado_por_token_ativo(), modulo_distribuido_estado_por_permissao_central() e modulo_distribuido_middleware_permissao() são as peças puras (testáveis) desse fluxo.
Funções
Gerado a partir de gestor/bibliotecas/modulo-distribuido.php · 36 funções
modulo_distribuido_scope
ver no código · linha 140 ↗modulo_distribuido_scope(array|string $modulo, string|null $slug = null): string|nullLê o valor da chave "scope" do manifesto <slug>.json de um módulo.
Parâmetros
$moduloarray|string- Manifesto decodificado, caminho do .json ou do diretório do módulo.
$slugstring|null- Slug do módulo (necessário quando $modulo é um diretório).
Retorno
modulo_distribuido_scope_central
ver no código · linha 151 ↗modulo_distribuido_scope_central($scope): boolIndica se o scope informado é o de um módulo central.
Parâmetros
$scope
Retorno
modulo_distribuido_scope_distribuido
ver no código · linha 158 ↗modulo_distribuido_scope_distribuido($scope): boolIndica se o scope informado é o de um módulo distribuído.
Parâmetros
$scope
Retorno
modulo_distribuido_resolver_manifesto
ver no código · linha 170 ↗modulo_distribuido_resolver_manifesto(array|string $modulo, string|null $slug = null): array|nullResolve o manifesto (array) de um módulo a partir de array, caminho de .json ou diretório.
Parâmetros
$moduloarray|string- Manifesto decodificado, caminho do .json ou do diretório do módulo.
$slugstring|null- Slug do módulo (usado para achar <slug>.json quando $modulo é diretório).
Retorno
modulo_distribuido_assinar
ver no código · linha 209 ↗modulo_distribuido_assinar(string $corpo, string $secret, string $algo = 'sha256'): stringGera a assinatura HMAC de um corpo de requisição.
Parâmetros
$corpostring- Corpo cru (string JSON) a ser assinado.
$secretstring- Segredo compartilhado entre central e distribuído.
$algostring- Algoritmo de hash (padrão sha256).
Retorno
modulo_distribuido_verificar_assinatura
ver no código · linha 223 ↗modulo_distribuido_verificar_assinatura(string $corpo, string $assinatura, string $secret, string $algo = 'sha256'): boolVerifica, de forma resistente a ataques de timing, a assinatura HMAC de um corpo.
Parâmetros
$corpostring- Corpo cru recebido.
$assinaturastring- Assinatura recebida (header X-C2F-Signature).
$secretstring- Segredo compartilhado.
$algostring- Algoritmo de hash (padrão sha256).
Retorno
modulo_distribuido_detectar_operacao
ver no código · linha 240 ↗modulo_distribuido_detectar_operacao(string $sql): stringDetecta o tipo de operação SQL a partir da instrução.
Parâmetros
$sqlstring- Instrução SQL.
Retorno
modulo_distribuido_operacao_leitura
ver no código · linha 255 ↗modulo_distribuido_operacao_leitura($operacao): boolIndica se a operação detectada é de leitura (SELECT).
Parâmetros
$operacao
Retorno
modulo_distribuido_montar_payload
ver no código · linha 267 ↗modulo_distribuido_montar_payload(string $sql, array $opcoes = []): arrayMonta o payload (array) que empacota a instrução SQL para trânsito via API.
Parâmetros
$sqlstring- Instrução SQL já montada.
$opcoesarray- Opções: 'modulo' (slug), 'linguagem'.
Retorno
modulo_distribuido_enviar
ver no código · linha 298 ↗modulo_distribuido_enviar(array $payload, array $config): arrayEnvia um payload de banco distribuído para a instalação remota e decodifica a resposta.
Parâmetros
$payloadarray- Payload montado por modulo_distribuido_montar_payload().
$configarray- Configuração do canal distribuído.
Retorno
modulo_distribuido_http_post
ver no código · linha 374 ↗modulo_distribuido_http_post($url, $corpo, array $headers, $timeout = 15): string|falsePOST HTTP simples via cURL. Isolado para permitir mock nos testes.
Parâmetros
$url$corpo$headersarray$timeout
Retorno
modulo_distribuido_resposta_para_resultado
ver no código · linha 419 ↗modulo_distribuido_resposta_para_resultado(array $resposta): BancoResultadoRemoto|boolConverte a resposta remota em um resultado consumível por banco.php.
Parâmetros
$respostaarray- Resposta decodificada da instalação distribuída.
Retorno
modulo_distribuido_executar_local
ver no código · linha 457 ↗modulo_distribuido_executar_local(array $payload, PDO $pdo): arrayExecuta localmente, no banco do cliente, a instrução SQL recebida da central.
Parâmetros
$payloadarray- Payload recebido (deve conter 'sql').
$pdoPDO- Conexão PDO com o banco local do cliente.
Retorno
modulo_distribuido_sql_segura
ver no código · linha 521 ↗modulo_distribuido_sql_segura(string $sql): boolGuard básico contra múltiplas instruções empilhadas.
Parâmetros
$sqlstring- Instrução SQL.
Retorno
modulo_distribuido_parse_rota
ver no código · linha 570 ↗modulo_distribuido_parse_rota(array $caminho): array|nullFaz o parse da rota da API distribuída: api/v1/modulo-distribuido/{slug}/{acao}.
Parâmetros
$caminhoarray- Segmentos do caminho da URL.
Retorno
modulo_distribuido_estado_por_token_ativo
ver no código · linha 621 ↗modulo_distribuido_estado_por_token_ativo(bool $token_ativo): stringDecide o estado de renderização do módulo distribuído a partir da validade do token.
Parâmetros
$token_ativobool- Resultado de autenticacao_distribuido_token_ativo().
Retorno
modulo_distribuido_estado_renderizacao
ver no código · linha 640 ↗modulo_distribuido_estado_renderizacao(bool $token_ativo, bool $tem_permissao): stringDecide o estado de renderização considerando autenticação E permissão por módulo.
Parâmetros
$token_ativobool- Usuário autenticado (token válido).
$tem_permissaobool- Usuário autorizado ao módulo alvo.
Retorno
modulo_distribuido_estado_por_permissao_central
ver no código · linha 658 ↗modulo_distribuido_estado_por_permissao_central(string $estado_central): stringTraduz o 'estado' devolvido pelo middleware central (endpoint 'permissao') no estado de renderização do ambiente distribuído.
Parâmetros
$estado_centralstring- 'nao-autenticado' | 'sem-permissao' | 'permitido'.
Retorno
modulo_distribuido_middleware_permissao
ver no código · linha 682 ↗modulo_distribuido_middleware_permissao(array $config, string $token, string|null $slug = null): arrayMiddleware de permissão (lado distribuído): consulta o central e devolve o estado.
Parâmetros
$configarray- Config do canal (endpoint, slug, secret, transporte).
$tokenstring- Access token do usuário (obtido no signin).
$slugstring|null- Slug do módulo alvo (default: $config['slug']).
Retorno
modulo_distribuido_guardiao
ver no código · linha 732 ↗modulo_distribuido_guardiao(array $config, array $opcoes = []): arrayGuardião de módulo distribuído — fachada obrigatória de controle de acesso.
Parâmetros
$configarray- Config do canal (endpoint, slug, secret, transporte, central-url).
$opcoesarray- 'token', 'central-url', 'opcao', 'params-iframe', 'slug'.
Retorno
modulo_distribuido_middleware_central
ver no código · linha 778 ↗modulo_distribuido_middleware_central(string $token, string $slug, array $opcoes = []): arrayMiddleware central — avalia autenticação e permissão como AUTORIDADE do sistema.
Parâmetros
$tokenstring- Access token do usuário.
$slugstring- Slug do módulo alvo.
$opcoesarray- 'resolver_usuario' (callable(token):?int), 'verificar_permissao' (callable(id,slug):bool).
Retorno
modulo_distribuido_montar_url_iframe
ver no código · linha 818 ↗modulo_distribuido_montar_url_iframe(string $endpoint_central, string $slug, array $opcoes = []): stringMonta a URL administrativa do módulo no central para renderização em Iframe.
Parâmetros
$endpoint_centralstring- URL base do central (ex.: https://conn2flow.com/).
$slugstring- Slug do módulo (central) a ser embutido.
$opcoesarray- 'modulo' (override do slug na URL), 'opcao', 'token', 'params' (extra).
Retorno
banco_distribuido_iniciar
ver no código · linha 849 ↗banco_distribuido_iniciar(array $config): voidAtiva o modo distribuído do banco para as próximas operações.
Parâmetros
$configarray- Configuração do canal (endpoint, slug, secret, token, ...).
Retorno
banco_distribuido_finalizar
ver no código · linha 859 ↗banco_distribuido_finalizar(): voidDesativa o modo distribuído do banco, retornando às operações locais.
Retorno
banco_distribuido_ativo
ver no código · linha 869 ↗banco_distribuido_ativo(): boolIndica se o modo distribuído do banco está ativo no contexto atual.
Retorno
banco_distribuido_query
ver no código · linha 885 ↗banco_distribuido_query(string $sql): BancoResultadoRemoto|boolExecuta uma query no modo distribuído: empacota, envia e converte a resposta.
Parâmetros
$sqlstring- Instrução SQL montada pelas funções de banco.php.
Retorno
modulo_distribuido_config_get
ver no código · linha 922 ↗modulo_distribuido_config_get(string $path, mixed $default = null): mixedLê um valor de $_CONFIG por caminho em dot-notation (ex.: 'modulo-distribuido.secret').
Parâmetros
$pathstring- Caminho em dot-notation.
$defaultmixed- Valor padrão quando o caminho não existe.
Retorno
modulo_distribuido_canal_central
ver no código · linha 951 ↗modulo_distribuido_canal_central(array $modulo_config, array $overrides = []): arrayResolve a config do canal para um MÓDULO CENTRAL (que delega banco ao distribuído).
Parâmetros
$modulo_configarray- Manifesto do módulo central.
$overridesarray- endpoint, secret, slug, token, timeout, transporte.
Retorno
modulo_distribuido_canal_distribuido
ver no código · linha 991 ↗modulo_distribuido_canal_distribuido(array $modulo_config, array $overrides = []): arrayResolve a config do canal para um MÓDULO DISTRIBUÍDO (que consulta o central).
Parâmetros
$modulo_configarray- Manifesto do módulo distribuído.
$overridesarray- central-url, secret, slug, transporte.
Retorno
modulo_distribuido_com_canal
ver no código · linha 1026 ↗modulo_distribuido_com_canal(callable $operacao, array $config): mixedExecuta uma operação de dados dentro do canal distribuído, garantindo o fechamento.
Parâmetros
$operacaocallable- Função com as chamadas de banco (delegadas ao distribuído).
$configarray- Config do canal (de modulo_distribuido_canal_central()).
Retorno
modulo_distribuido_token_sessao
ver no código · linha 1042 ↗modulo_distribuido_token_sessao(string $chave, $slug = null): stringLê, da sessão, o token de acesso ao central guardado por um módulo distribuído.
Parâmetros
$chavestring- Chave da variável de sessão.
$slug
Retorno
modulo_distribuido_persistir_token
ver no código · linha 1079 ↗modulo_distribuido_persistir_token(string $chave, array $tokens, callable|null $persistir = null): voidPersiste os tokens obtidos no login/ativação distribuído.
Parâmetros
$chavestring- Chave base da variável de sessão do token.
$tokensarray- Tokens retornados pelo central (access_token, refresh_token, ...).
$persistircallable|null- Persistência customizada: function($chave, array $tokens): void.
Retorno
modulo_distribuido_textos
ver no código · linha 1107 ↗modulo_distribuido_textos(string|null $lang = null, array $overrides = [], $resolver = null): arrayDicionário de textos (i18n) do componente global de estados distribuídos.
Parâmetros
$langstring|null- Idioma (default: $_GESTOR['linguagem-codigo']).
$overridesarray- Sobrescritas de texto por chave (#c2f-md-*# sem as cercas).
$resolver
Retorno
modulo_distribuido_render_componente
ver no código · linha 1128 ↗modulo_distribuido_render_componente(string $html, string $estado, string|null $iframe_url = null, array $textos = []): stringProcessa o HTML do componente de estados segundo o estado de acesso (função pura).
Parâmetros
$htmlstring- HTML do componente (de gestor_componente()).
$estadostring- 'login' | 'sem-permissao' | 'iframe'.
$iframe_urlstring|null- URL do Iframe (quando 'iframe').
$textosarray- Mapa de textos (de modulo_distribuido_textos()).
Retorno
modulo_distribuido_render_estado
ver no código · linha 1172 ↗modulo_distribuido_render_estado(string $estado, string|null $iframe_url = null): stringAplica a renderização por estado diretamente sobre a página do módulo ($_GESTOR['pagina']).
Parâmetros
$estadostring- 'login' | 'sem-permissao' | 'iframe'.
$iframe_urlstring|null- URL do Iframe (quando 'iframe').
Retorno
modulo_distribuido_app
ver no código · linha 1207 ↗modulo_distribuido_app(array $config, array $opcoes = []): arrayOrquestração completa do "app" de um módulo distribuído (fachada de alto nível).
Parâmetros
$configarray- Config do canal (de modulo_distribuido_canal_distribuido()).
$opcoesarray- 'token', 'token-chave', 'opcao', 'params-iframe', 'central-url',
Retorno
Cadastro de instalações no central
O central reconhece cada instalação distribuída pelo app_id. A leitura é de modulo_distribuido_instalacao($app, $slug), que devolve url, secret, modules e tables, ou false.
-
Sem mais nada, o cadastro é a variável
MODULO_DISTRIBUIDO_INSTALLATIONSdo.env(JSON porapp_id). -
Um projeto pode manter o cadastro fora do
.enve declarar o leitor em$_CONFIG['modulo-distribuido']['installations-provider']:callable(string $app): array|false|null.arrayé a instalação;falsediz que ela existe e está desativada (o.envnão é consultado);nulldiz que o provedor não a conhece, e o.envresponde. Falha do provedor recusa a instalação.
Custo por consulta
Cada consulta do módulo original que alcança uma tabela da instalação vira uma chamada HTTP assinada. A conexão é reaproveitada dentro da requisição (modulo_distribuido_http_post() mantém o handle do cURL), e a faxina dos nonces vencidos no banco do cliente é amostrada, de modo que cada consulta custa uma gravação lá, não duas.