Pular para o conteúdo
Development

A mudança de config que já estava feita (API pública do Postiz)

Por Victor Da Luz
postizself-hostingrubydev-logblog-manager

Peguei uma issue pequena de pré-requisito essa semana. A coisa toda era uma linha só: “ativar a API pública no nosso Postiz self-hosted para conseguirmos gerar uma chave de API.” Postiz é o agendador social no qual estou conectando o blog-manager, e o build de cross-posting mais à frente precisa dessa chave. Ticket fácil. Ativar uma flag, gerar uma chave, seguir em frente.

Só que não tinha nenhuma flag para ativar. Já estava ligada. Descobrir isso levou mais tempo do que a mudança em si levaria, e virou a parte de fato útil do dia.

O que a issue presumia

O ticket que eu tinha escrito para mim mesmo alguns dias antes dizia para ativar a flag de tier public_api, e então pegar uma chave na aba Developers das configurações. Esse enquadramento presumia que o Postiz funciona como a versão SaaS hospedada: escolhe um plano, o plano libera a API. Então fui procurar onde esse plano vive no nosso deployment.

Nosso Postiz roda a partir de uma role do Ansible, fixado em ghcr.io/gitroomhq/postiz-app:v2.21.8. Antes de mexer em qualquer coisa, eu queria saber exatamente o que controla o acesso àquela aba Developers. Então li o código-fonte. O frontend mostra a aba quando:

user?.tier?.public_api && isGeneral

Duas condições. isGeneral vem direto da variável de ambiente IS_GENERAL, que nosso template de compose já define como "true". O tier é a parte interessante. No backend:

tier: organization?.subscription?.subscriptionTier
  || (!process.env.STRIPE_PUBLISHABLE_KEY ? 'ULTIMATE' : 'FREE')

Sem chave do Stripe, sem billing, então não existe objeto de subscription. O fallback entra em ação, e sem STRIPE_PUBLISHABLE_KEY definida, ele resolve para ULTIMATE. E na tabela de preços, ULTIMATE.public_api é true (só o tier FREE é false). Self-hosting com billing desligado não te joga para um tier gratuito. Te entrega o mais alto.

Então a cadeia já estava completa: IS_GENERAL=true + nenhuma chave do Stripe, logo ULTIMATE, logo public_api true, logo a aba renderiza. A tarefa de “ativar a API” era um no-op. A jogada certa era logar e confirmar que a aba estava ali, o que estava, gerar a chave, e fechar o ticket. Nenhuma mudança de config, nenhuma.

A parte que eu quase errei

Meu primeiro instinto foi ler a lógica de controle de acesso na branch main no GitHub, porque é isso que os resultados de busca mostram primeiro. Nós não rodamos a main. Rodamos a v2.21.8. A lógica de tier provavelmente não mudou, mas “provavelmente” é como você acaba raciocinando sobre código que não está em produção. A API do GitHub aceita um ?ref=v2.21.8 nas leituras de arquivo, então não tem desculpa. Reli cada arquivo na tag de fato usada. Mesma conclusão, mas agora era sobre a coisa que realmente estava rodando.

Esse é um hábito que continuo tendo que reaprender. A tag em produção é a fonte da verdade, não a branch padrão.

Duas correções que surgiram de checar

Por estar lendo em vez de presumir, duas outras coisas no ticket acabaram se mostrando erradas.

Primeiro, o ticket dizia para guardar a chave gerada em config/credentials.yml.enc. Mas não é ali que o blog-manager guarda chaves de terceiros. Todo token de publicação de blog nesse app vive numa coluna criptografada do banco, exposta na interface. A única chave de escopo global que já existe, a do Pexels, fica num singleton AppSetting com um campo na página de configurações. A chave do Postiz tem o mesmo formato, então ela pertence ali também, ao lado da do Pexels, não no arquivo de credentials. O arquivo de credentials guarda segredos de infraestrutura do app, não chaves de integração. Seguir o ticket ao pé da letra teria colocado ela no lugar errado e quebrado o padrão.

Segundo, o ticket empacotou “conectar nossas contas sociais” no mesmo pré-requisito. Mas conectar uma conta no Postiz precisa de apps OAuth por plataforma, um client ID e secret para o X, para o Bluesky, para o LinkedIn, cada um registrado e aprovado no portal de desenvolvedores daquela plataforma, cada um adicionado como variável de ambiente no container do Postiz. Nada disso está configurado, e nada disso é trabalho do blog-manager. É trabalho de infraestrutura do lado do homelab. Então separei isso na própria issue lá e deixei este ticket como ele de fato era: gerar uma chave.

O que eu levo dessa

O ticket descrevia três tarefas. Ler o código-fonte transformou as três em algo menor ou diferente: uma já estava feita, uma apontava para o arquivo errado, e uma não pertencia a esse repositório. Os trinta minutos de leitura pouparam uma mudança de config que não teria feito nada, uma credencial guardada no lugar errado, e uma pilha de configuração de OAuth registrada no projeto errado.

Eu escrevo tickets com antecedência para que o meu eu do futuro tenha um plano. O problema é que o meu eu do passado estava chutando como uma ferramenta que eu ainda não tinha colocado em produção ia se comportar. Software self-hosted continua me surpreendendo por ser mais generoso do que a tabela de tiers hospedados sugere, desliga o billing e muitas vezes você ganha tudo, porque o bloqueio existe para vender planos, não para restringir o código. Vale a pena checar antes de você presumir que está no tier barato.

Leitura relacionada

Development

Add a feature, or move a responsibility?

Adding Postiz social cross-posting looked done until a blunt question exposed a double-post bug, and a full audit of every posting path in the app found two more like it.

Ler

Você também pode achar útil

AdGuard

AdGuard para iOS

Bloqueio de anúncios e rastreadores em todo o sistema no iOS, sem necessidade de um servidor DNS separado.

Como afiliado da AdGuard, ganho com compras qualificadas.

Saiba mais
Proton

Proton Mail

E-mail criptografado de ponta a ponta, com arquitetura de acesso zero.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais
Proton

Proton Drive

Armazenamento em nuvem criptografado, da equipe por trás do Proton Mail.

Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).

Saiba mais