Skip to content

About

Envio em lote para webservice SOAP legado: WS-Security PasswordDigest, resolucao de titular em cadeia com cache SQLite, modo simulacao por padrao

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

soap-doc-sync

testes Python 3.10+ Licença MIT

Sincronizador de documentos para webservices SOAP legados, com autenticação WS-Security UsernameToken / PasswordDigest, cache local e resolução de titular em cadeia.

Nasceu de um problema real e chato: um sistema corporativo antigo que só aceita upload por SOAP, exige um par de códigos internos que o nome do documento não traz, e responde devagar. A parte interessante não é o upload — é como descobrir esses códigos sem transformar cada lote em trabalho manual.


O problema

Chega uma pasta com centenas de PDFs nomeados assim:

ATESTADO 140422 MARIA DAS GRACAS.pdf
EXAME 030525 JOAO PEREIRA DA SILVA.pdf

O webservice não aceita "MARIA DAS GRACAS". Ele quer codigoTitular e codigoUnidade — dois números que só existem no cadastro do sistema. Descobrir esses números é a maior parte do trabalho.

A solução

Ler o nome do arquivo, nunca o conteúdo. Um lote de mil documentos é classificado em milissegundos. Só o que não casa com o padrão paga o custo de abrir o PDF.

Resolver o titular em cadeia, do barato para o caro. Quatro estratégias com o mesmo protocolo; a primeira que responder vence:

# Estratégia Custo Cobertura
1 Cache SQLite local microssegundos, offline o que já foi visto antes
2 Consulta REST ~200 ms parcial
3 Consulta SOAP segundos completa
4 Pergunta ao operador humano tudo, mas não escala

O detalhe que faz a diferença: todo acerto vindo de fora é gravado no cache. A estratégia 4 alimenta a 1. Na primeira execução quase tudo cai na consulta remota ou no operador; no décimo lote a maioria resolve offline, e a intervenção humana vira exceção em vez de rotina.

Nunca escrever por acidente. MODO_SIMULACAO vem ligado por padrão. A ferramenta faz o percurso completo, loga o que faria, e não envia nada. Quem liga o envio é uma flag explícita (--enviar). Existe ainda UNIDADE_PERMITIDA, uma trava que recusa qualquer upload fora de uma unidade específica — útil para homologar em produção sem risco de espalhar documento errado.

Cada arquivo termina em exatamente uma pasta. O destino conta o que houve:

_resultado/
├── processados/            enviado com sucesso
├── sem_padrao/             nome fora da convenção
├── titular_nao_resolvido/  nome lido, sem correspondência
├── erros/                  falhou o envio após as tentativas
└── log_envio.csv           uma linha por arquivo

Reprocessar é apontar a ferramenta para erros/ depois de corrigir a causa.


WS-Security PasswordDigest

A parte que costuma travar integrações com SOAP corporativo. A senha não trafega em texto claro:

Digest = Base64( SHA1( nonce + created + senha ) )

Três armadilhas, todas cobertas por teste em tests/test_wsse.py:

  • o nonce entra na concatenação como bytes crus, não como a string Base64 que aparece no XML — trocar isso gera um digest bem formado que o servidor rejeita com 401, sem pista nenhuma no log;
  • o created precisa ser UTC em ISO 8601 com sufixo Z;
  • a ordem nonce + created + senha é fixa.

Como o nonce muda a cada requisição, o digest também muda — o que impede replay de uma chamada capturada.

O zeep tem suporte nativo a UsernameToken, mas servidores legados costumam ser rígidos quanto à ordem dos elementos e ao mustUnderstand. Por isso o cabeçalho é montado à mão em src/wsse.py.


Estrutura

src/
├── wsse.py          assinatura WS-Security (PasswordDigest)
├── config.py        configuração via ambiente, sem segredo em código
├── nomes_arquivo.py leitura de "TIPO DDMMAA NOME"
├── cache.py         cache SQLite de titulares
├── resolvedor.py    cadeia de estratégias
├── cliente_soap.py  zeep + retry + modo simulação
├── pipeline.py      orquestração do lote e log CSV
└── cli.py           linha de comando
tests/               36 testes, sem rede

Rodando

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r requirements.txt -r requirements-dev.txt

cp .env.example .env             # e preencha

pytest -q                        # 36 testes, nenhuma credencial necessária
python -m src.cli ./pdfs         # simulação: não envia nada
python -m src.cli ./pdfs --enviar

Os testes rodam sem .env e sem rede: toda I/O externa entra por injeção de dependência, então a lógica é testada com funções falsas em vez de mocks de biblioteca.

Configuração

Tudo por variável de ambiente. .env está no .gitignore; o .env.example documenta as chaves sem conter valor.

Variável Para quê
WSDL_UPLOAD endereço do WSDL de upload
WSSE_USUARIO / WSSE_SENHA credenciais WS-Security
CONSULTA_URL / CONSULTA_CODIGO / CONSULTA_CHAVE endpoint REST opcional
MODO_SIMULACAO true (padrão) não envia nada
UNIDADE_PERMITIDA trava: recusa upload fora desta unidade
TIMEOUT_S / TENTATIVAS comportamento de rede

Config.resumo_seguro() é o que vai para o log — senha e chave saem mascaradas.


Sobre este repositório

Reimplementação genérica e independente de uma automação que escrevi no trabalho. Não contém código, credencial, endpoint, nome de empresa nem dado de pessoa do sistema original: o domínio aqui é neutro ("titulares" e "unidades") e o código foi escrito do zero para publicação. Serve como amostra de como eu estruturo uma integração — separação de responsabilidades, configuração fora do código, falha explícita e teste sem rede.

MIT.


In English — Batch uploader for legacy SOAP webservices. Implements WS-Security UsernameToken with PasswordDigest, a four-step owner-resolution chain (SQLite cache → REST → SOAP → human fallback) where every external hit feeds the cache, dry-run by default, per-unit safety lock, and per-file outcome folders with a CSV audit log. 36 tests, no network required.

About

Envio em lote para webservice SOAP legado: WS-Security PasswordDigest, resolucao de titular em cadeia com cache SQLite, modo simulacao por padrao

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages