Path in the Gestor bibliotecas/modulo-distribuido.php
It lets a module have two halves:
-
central (
"scope": "central-module"in<module>.json): runs on the central installation (the vendor's), where the code, users and permissions live; -
distributed (
"scope": "distributed-module"): runs on the client's site and keeps the data in the client's database.
The central module code keeps using banco_select(), banco_insert()… as usual; inside the distributed channel, banco_query() packs the SQL and runs it on the client installation. The client sees the module as an embedded screen (iframe) of the central, unlocked only after the central confirms login and permission.
Configuration
In the .env (global variables): MODULO_DISTRIBUIDO_SECRET (shared HMAC secret), MODULO_DISTRIBUIDO_CENTRAL_URL (on the distributed side: the central URL) and MODULO_DISTRIBUIDO_ENDPOINT (on the central side: the distributed API URL). Per module, $_CONFIG['modulo-distribuido']['secrets'][<slug>] and ['endpoints'][<slug>] override the general values (modulo_distribuido_config_get('modulo-distribuido.secrets.<slug>')).
modulo_distribuido_scope($manifest), modulo_distribuido_scope_central(), modulo_distribuido_scope_distribuido() and modulo_distribuido_resolver_manifesto() read the scope from the manifest (constants C2F_SCOPE_CENTRAL and C2F_SCOPE_DISTRIBUIDO).
The data channel
// In the central module, wrapping only the client's data operations:
// the central module manifest declares "distributed": {"target-slug": "my-module"}
$config = modulo_distribuido_canal_central($_GESTOR['modulo#'.$_GESTOR['modulo-id']]);
$orders = modulo_distribuido_com_canal(function () {
return banco_select(['tabela' => 'pedidos', 'campos' => ['id', 'total']]);
}, $config);
// or by hand: banco_distribuido_iniciar($config); … banco_distribuido_finalizar();-
banco_distribuido_ativo()makesbanco_query()divert tobanco_distribuido_query(). -
modulo_distribuido_montar_payload()packs the SQL (operacao,modulo,linguagem,timestamp,nonce), andmodulo_distribuido_enviar()sends it throughmodulo_distribuido_http_post()to<endpoint>/modulo-distribuido/<slug>/db, withX-C2F-Signature= HMAC-SHA256 of the body (modulo_distribuido_assinar()). -
On the distributed side, the API checks the signature (
modulo_distribuido_verificar_assinatura(), constant time) andmodulo_distribuido_executar_local()runs the SQL through PDO: aSELECTreturns columns and rows; a write returnsaffected_rowsandinsert_id. -
modulo_distribuido_resposta_para_resultado()turns the response into aBancoResultadoRemoto, which mimicsmysqli_resultfor the banco.php functions.
Authentication, variables and the rest of the request stay in the central's local database: only what is inside the channel goes to the client. modulo_distribuido_canal_central($manifest, $overrides) builds the central-side configuration from the manifest's distributed.target-slug (and, optionally, endpoint-config/secret-config, key paths in $_CONFIG); modulo_distribuido_canal_distribuido() does the same on the distributed side, to talk to the central; modulo_distribuido_detectar_operacao() and modulo_distribuido_operacao_leitura() classify the SQL; modulo_distribuido_parse_rota() reads {slug}/{action} from the URL.
Login, permission and screen
The distributed side does not decide access: it asks the central.
-
Sign-in is the central's
perfil-usuario: without a token, the distributed host sends the browser to the central's/signin/with a signed context; after the complete sign-in (second factor included) thelogin.distribuidohook returns a single-use code, exchanged server to server for the tokens (exchangeaction).modulo_distribuido_token_sessao()andmodulo_distribuido_persistir_token()keep and renew the tokens in the session. There is no username and password sign-in on this channel. -
modulo_distribuido_guardiao()(distributed side) asks the central, wheremodulo_distribuido_middleware_central()validates the token and the user's permission on the module and answersnao-autenticado,sem-permissaoor authorized. Any failure resolves to the most restrictive state. -
modulo_distribuido_estado_renderizacao()translates that intologin,sem-permissaooriframe;modulo_distribuido_montar_url_iframe()builds the URL of the central screen. -
modulo_distribuido_app()does it all in one call: token, guardian and the state screen, replacing#modulo-distribuido-app#on the page with themodulo-distribuido-appcomponent (modulo_distribuido_render_estado(),modulo_distribuido_render_componente(),modulo_distribuido_textos()).
The variants modulo_distribuido_estado_por_token_ativo(), modulo_distribuido_estado_por_permissao_central() and modulo_distribuido_middleware_permissao() are the pure (testable) pieces of this flow.
Functions
Generated from gestor/bibliotecas/modulo-distribuido.php · 36 functions
modulo_distribuido_scope
view source · line 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.
Parameters
$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).
Returns
modulo_distribuido_scope_central
view source · line 151 ↗modulo_distribuido_scope_central($scope): boolIndica se o scope informado é o de um módulo central.
Parameters
$scope
Returns
modulo_distribuido_scope_distribuido
view source · line 158 ↗modulo_distribuido_scope_distribuido($scope): boolIndica se o scope informado é o de um módulo distribuído.
Parameters
$scope
Returns
modulo_distribuido_resolver_manifesto
view source · line 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.
Parameters
$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).
Returns
modulo_distribuido_assinar
view source · line 209 ↗modulo_distribuido_assinar(string $corpo, string $secret, string $algo = 'sha256'): stringGera a assinatura HMAC de um corpo de requisição.
Parameters
$corpostring- Corpo cru (string JSON) a ser assinado.
$secretstring- Segredo compartilhado entre central e distribuído.
$algostring- Algoritmo de hash (padrão sha256).
Returns
modulo_distribuido_verificar_assinatura
view source · line 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.
Parameters
$corpostring- Corpo cru recebido.
$assinaturastring- Assinatura recebida (header X-C2F-Signature).
$secretstring- Segredo compartilhado.
$algostring- Algoritmo de hash (padrão sha256).
Returns
modulo_distribuido_detectar_operacao
view source · line 240 ↗modulo_distribuido_detectar_operacao(string $sql): stringDetecta o tipo de operação SQL a partir da instrução.
Parameters
$sqlstring- Instrução SQL.
Returns
modulo_distribuido_operacao_leitura
view source · line 255 ↗modulo_distribuido_operacao_leitura($operacao): boolIndica se a operação detectada é de leitura (SELECT).
Parameters
$operacao
Returns
modulo_distribuido_montar_payload
view source · line 267 ↗modulo_distribuido_montar_payload(string $sql, array $opcoes = []): arrayMonta o payload (array) que empacota a instrução SQL para trânsito via API.
Parameters
$sqlstring- Instrução SQL já montada.
$opcoesarray- Opções: 'modulo' (slug), 'linguagem'.
Returns
modulo_distribuido_enviar
view source · line 298 ↗modulo_distribuido_enviar(array $payload, array $config): arrayEnvia um payload de banco distribuído para a instalação remota e decodifica a resposta.
Parameters
$payloadarray- Payload montado por modulo_distribuido_montar_payload().
$configarray- Configuração do canal distribuído.
Returns
modulo_distribuido_http_post
view source · line 374 ↗modulo_distribuido_http_post($url, $corpo, array $headers, $timeout = 15): string|falsePOST HTTP simples via cURL. Isolado para permitir mock nos testes.
Parameters
$url$corpo$headersarray$timeout
Returns
modulo_distribuido_resposta_para_resultado
view source · line 419 ↗modulo_distribuido_resposta_para_resultado(array $resposta): BancoResultadoRemoto|boolConverte a resposta remota em um resultado consumível por banco.php.
Parameters
$respostaarray- Resposta decodificada da instalação distribuída.
Returns
modulo_distribuido_executar_local
view source · line 457 ↗modulo_distribuido_executar_local(array $payload, PDO $pdo): arrayExecuta localmente, no banco do cliente, a instrução SQL recebida da central.
Parameters
$payloadarray- Payload recebido (deve conter 'sql').
$pdoPDO- Conexão PDO com o banco local do cliente.
Returns
modulo_distribuido_sql_segura
view source · line 521 ↗modulo_distribuido_sql_segura(string $sql): boolGuard básico contra múltiplas instruções empilhadas.
Parameters
$sqlstring- Instrução SQL.
Returns
modulo_distribuido_parse_rota
view source · line 570 ↗modulo_distribuido_parse_rota(array $caminho): array|nullFaz o parse da rota da API distribuída: api/v1/modulo-distribuido/{slug}/{acao}.
Parameters
$caminhoarray- Segmentos do caminho da URL.
Returns
modulo_distribuido_estado_por_token_ativo
view source · line 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.
Parameters
$token_ativobool- Resultado de autenticacao_distribuido_token_ativo().
Returns
modulo_distribuido_estado_renderizacao
view source · line 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.
Parameters
$token_ativobool- Usuário autenticado (token válido).
$tem_permissaobool- Usuário autorizado ao módulo alvo.
Returns
modulo_distribuido_estado_por_permissao_central
view source · line 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.
Parameters
$estado_centralstring- 'nao-autenticado' | 'sem-permissao' | 'permitido'.
Returns
modulo_distribuido_middleware_permissao
view source · line 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.
Parameters
$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']).
Returns
modulo_distribuido_guardiao
view source · line 732 ↗modulo_distribuido_guardiao(array $config, array $opcoes = []): arrayGuardião de módulo distribuído — fachada obrigatória de controle de acesso.
Parameters
$configarray- Config do canal (endpoint, slug, secret, transporte, central-url).
$opcoesarray- 'token', 'central-url', 'opcao', 'params-iframe', 'slug'.
Returns
modulo_distribuido_middleware_central
view source · line 778 ↗modulo_distribuido_middleware_central(string $token, string $slug, array $opcoes = []): arrayMiddleware central — avalia autenticação e permissão como AUTORIDADE do sistema.
Parameters
$tokenstring- Access token do usuário.
$slugstring- Slug do módulo alvo.
$opcoesarray- 'resolver_usuario' (callable(token):?int), 'verificar_permissao' (callable(id,slug):bool).
Returns
modulo_distribuido_montar_url_iframe
view source · line 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.
Parameters
$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).
Returns
banco_distribuido_iniciar
view source · line 849 ↗banco_distribuido_iniciar(array $config): voidAtiva o modo distribuído do banco para as próximas operações.
Parameters
$configarray- Configuração do canal (endpoint, slug, secret, token, ...).
Returns
banco_distribuido_finalizar
view source · line 859 ↗banco_distribuido_finalizar(): voidDesativa o modo distribuído do banco, retornando às operações locais.
Returns
banco_distribuido_ativo
view source · line 869 ↗banco_distribuido_ativo(): boolIndica se o modo distribuído do banco está ativo no contexto atual.
Returns
banco_distribuido_query
view source · line 885 ↗banco_distribuido_query(string $sql): BancoResultadoRemoto|boolExecuta uma query no modo distribuído: empacota, envia e converte a resposta.
Parameters
$sqlstring- Instrução SQL montada pelas funções de banco.php.
Returns
modulo_distribuido_config_get
view source · line 922 ↗modulo_distribuido_config_get(string $path, mixed $default = null): mixedLê um valor de $_CONFIG por caminho em dot-notation (ex.: 'modulo-distribuido.secret').
Parameters
$pathstring- Caminho em dot-notation.
$defaultmixed- Valor padrão quando o caminho não existe.
Returns
modulo_distribuido_canal_central
view source · line 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).
Parameters
$modulo_configarray- Manifesto do módulo central.
$overridesarray- endpoint, secret, slug, token, timeout, transporte.
Returns
modulo_distribuido_canal_distribuido
view source · line 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).
Parameters
$modulo_configarray- Manifesto do módulo distribuído.
$overridesarray- central-url, secret, slug, transporte.
Returns
modulo_distribuido_com_canal
view source · line 1026 ↗modulo_distribuido_com_canal(callable $operacao, array $config): mixedExecuta uma operação de dados dentro do canal distribuído, garantindo o fechamento.
Parameters
$operacaocallable- Função com as chamadas de banco (delegadas ao distribuído).
$configarray- Config do canal (de modulo_distribuido_canal_central()).
Returns
modulo_distribuido_token_sessao
view source · line 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.
Parameters
$chavestring- Chave da variável de sessão.
$slug
Returns
modulo_distribuido_persistir_token
view source · line 1079 ↗modulo_distribuido_persistir_token(string $chave, array $tokens, callable|null $persistir = null): voidPersiste os tokens obtidos no login/ativação distribuído.
Parameters
$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.
Returns
modulo_distribuido_textos
view source · line 1107 ↗modulo_distribuido_textos(string|null $lang = null, array $overrides = [], $resolver = null): arrayDicionário de textos (i18n) do componente global de estados distribuídos.
Parameters
$langstring|null- Idioma (default: $_GESTOR['linguagem-codigo']).
$overridesarray- Sobrescritas de texto por chave (#c2f-md-*# sem as cercas).
$resolver
Returns
modulo_distribuido_render_componente
view source · line 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).
Parameters
$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()).
Returns
modulo_distribuido_render_estado
view source · line 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']).
Parameters
$estadostring- 'login' | 'sem-permissao' | 'iframe'.
$iframe_urlstring|null- URL do Iframe (quando 'iframe').
Returns
modulo_distribuido_app
view source · line 1207 ↗modulo_distribuido_app(array $config, array $opcoes = []): arrayOrquestração completa do "app" de um módulo distribuído (fachada de alto nível).
Parameters
$configarray- Config do canal (de modulo_distribuido_canal_distribuido()).
$opcoesarray- 'token', 'token-chave', 'opcao', 'params-iframe', 'central-url',
Returns
Installation registry at the central
The central recognizes each distributed installation by its app_id. The reader is modulo_distribuido_instalacao($app, $slug), which returns url, secret, modules and tables, or false.
-
By default the registry is the
MODULO_DISTRIBUIDO_INSTALLATIONSvariable of the.env(JSON keyed byapp_id). -
A project may keep the registry outside the
.envand declare the reader in$_CONFIG['modulo-distribuido']['installations-provider']:callable(string $app): array|false|null.arrayis the installation;falsesays it exists and is disabled (the.envis not consulted);nullsays the provider does not know it, and the.envanswers. A provider failure refuses the installation.
Cost per query
Each query of the original module that reaches a table of the installation becomes a signed HTTP call. The connection is reused within the request (modulo_distribuido_http_post() keeps the cURL handle), and the sweep of expired nonces in the client's database is sampled, so each query costs one write there, not two.