Acapadev SDK
Problemas Conhecidos
Esta página existe por uma razão concreta: durante meses, várias aplicações ligadas ao Acapadev ID resolveram os mesmos defeitos cada uma à sua maneira, sem que ninguém soubesse que o problema era do pacote. O conhecimento ficou espalhado por overrides locais, variáveis de ambiente inventadas e chamadas HTTP escritas à mão para não passar pelo SDK.
Se estás a integrar uma aplicação nova, lê isto antes de escrever qualquer contorno. Se estás a manter uma aplicação antiga, usa como lista do que podes apagar.
| Sintoma | Versão afetada | Estado |
|---|---|---|
| Cargos sempre vazios, sem erro nenhum | ≤ 1.1.0 | Corrigido em 1.2.0 |
| Login por SSO falha ao obter o perfil | ≤ 1.1.0 | Corrigido em 1.2.0 |
| Cargos vazios só para alguns utilizadores | ≤ 1.2.0 | Corrigido em 1.2.0 |
| Só aparece um cargo quando o utilizador tem vários | servidor | Corrigido no Acapadev ID |
| Mudança de formato passaria despercebida | ≤ 1.2.0 | Corrigido em 1.2.1 |
1. Cargos sempre vazios, sem um único erro
Como se manifestava. getAcapadevRoles() devolvia [] para toda a gente. Sem exceção, sem aviso, sem nada nos registos. Uma aplicação que usasse cargos para autorizar acesso negava-o a todos, silenciosamente.
Porquê. O SDK construía o URL da API como {ACAPADEV_URL}/api/v1, o que dava https://id.acapadev.com/api/v1/... — host errado e um prefixo /api que não existe. A API vive em https://api.acapadev.com/v1.
Contornos que apareceram nas aplicações:
// Chamada direta, escrita para não passar pelo SDK
$roles = Http::withToken($token)
->get('https://api.acapadev.com/v1/users/' . $id . '/roles')
->json('data');
# Variável inventada para guardar o host correto
ACAPADEV_API_HOST=https://api.acapadev.com
O que fazer hoje. Nada. O SDK deriva o host da API a partir do ACAPADEV_URL. Apaga o contorno; se tens ACAPADEV_API_HOST, muda o nome para ACAPADEV_API_URL (que o SDK lê) ou apaga-a.
2. O login por SSO não conseguia obter o perfil
Porquê. Dois defeitos ao mesmo tempo: o provider lia o perfil em {ACAPADEV_URL}/api/user, rota que não existe em host nenhum; e a resposta vem embrulhada num envelope que o mapeamento não esperava.
{ "status": "success", "data": { "id": 3, "name": "...", "email": "..." } }
Contorno que apareceu: uma subclasse anónima do provider, só para corrigir o URL e desembrulhar o data.
O que fazer hoje. O provider do SDK já usa {API}/v1/user e desembrulha o data. Podes remover o override — exceto se existir por outra razão legítima, como a configuração de SSL para certificados auto-assinados em ambiente local:
$config['guzzle'] = ['verify' => ! $app->environment('local')];
3. Cargos vazios apenas para alguns utilizadores
O mais traiçoeiro dos três, porque parecia funcionar. A Trait pedia os cargos com a chave primária local, não com o ID do utilizador no Acapadev ID. Quando os dois números coincidiam por acaso, funcionava.
O que fazer hoje. Guarda o acapadev_id no callback do SSO e o SDK usa-o sozinho. Se guardas esse ID noutra coluna, sobrepõe getAcapadevIdentifier() em vez de contornar. Ver Cargos e Permissões.
4. Só aparecia um cargo quando o utilizador tinha vários
Este era do lado do servidor. Um utilizador com gestor e auditor na mesma aplicação recebia apenas um dos dois — o endpoint prometia uma lista mas devolvia só o primeiro registo, descartando os restantes em silêncio.
O que fazer hoje. Foi corrigido no Acapadev ID. Mas há uma consequência para o teu código: não assumas data[0].
// Errado, mesmo que funcione hoje
$cargo = $user->getAcapadevRoles()[0] ?? null;
// Certo
if ($user->hasAnyAcapadevRole(['gestor', 'auditor'])) { /* ... */ }
5. Uma mudança de formato passaria despercebida
Enquanto os cargos vinham sempre vazios, ninguém chegou a ver o formato real da resposta. Se o servidor passasse a devolver objetos em vez de nomes:
in_array('gestor', [['name' => 'gestor']], true); // false
hasAcapadevRole() devolveria false para toda a gente e — mais uma vez — não haveria nada nos registos a explicar porquê. A partir da v1.2.1 o SDK normaliza a resposta e avisa quando não consegue interpretar alguma coisa.
A Lição, que é a Parte Reutilizável
Nenhum destes defeitos sobreviveu por ser difícil de corrigir. Sobreviveram porque falhavam em silêncio, e porque cada equipa que tropeçou neles resolveu o seu caso sem reportar.
Duas regras que valem para qualquer integração
- Um estado seguro não pode ser indistinguível de uma resposta legítima. Devolver «sem cargos» quando a API está em baixo é a decisão certa; não registar que a API estava em baixo é o que torna o problema invisível.
- Cuidado com o curto-circuito na verificação de permissões. Em
$this->role === 'admin' || $this->hasAcapadevRole('admin'), o||pára no primeirotrue— as contas de administração nunca chegam a consultar a API, e a falha só se manifesta para utilizadores normais. Testa sempre com uma conta que não seja administradora localmente.
Se Encontrares Alguma Coisa
Reporta em vez de contornar, mesmo que já tenhas a solução. Um contorno local resolve uma aplicação; um relatório resolve todas as outras — e evita que o próximo integrador perca os mesmos dias.