Integração em custom auth system onde e-mails não são únicos?

Era exatamente o que eu tinha em mente também.
Incluirei o link para o tópico Category Group Review/Moderation, pois inicialmente tive dificuldade em localizá-lo através da pesquisa.
Sempre tenho dificuldade em encontrar Documentation na categoria Announcements

2 curtidas

Honestamente, esta é provavelmente uma boa ideia de qualquer maneira. Administradores têm TODOS os direitos (baixar backups, ver/alterar segredos de configuração, ver PII de pessoas, acesso a Mensagens Pessoais, …) e é melhor manter esse círculo restrito.

Há muito espaço para “privilégios elevados” sem ser um administrador completo.

2 curtidas

Obrigado a ambos por isso, eu não sabia que isso era uma coisa separada!

Obrigado por esse esclarecimento, eu não sabia que era o caso. Você está certo, definitivamente limitaríamos isso de qualquer maneira agora que sei.

Analisei os limites/requisitos disso e passei para minha equipe. Infelizmente, parece que ainda teremos que auto-hospedar. A hospedagem FOSS que você está oferecendo é muito generosa, nós simplesmente não nos encaixamos nos requisitos.

O maior infrator sendo os limites de visualizações de página. 50k/m de visualizações de página é provavelmente mais do que suficiente para a maioria dos projetos FOSS, mas geramos muito mais tráfego do que isso. Nosso site principal recebeu 1,87m de solicitações totais de 56,47k visitantes únicos apenas nos últimos 7 dias. Temo que atingiremos facilmente o limite de visualizações de página a essa taxa.

Obrigado por me apontar isso, no entanto!

4 curtidas

Provavelmente valeria a pena encontrar uma maneira de lidar com isso. Se você souber quais usuários em seu servidor são funcionários do Discourse (administradores ou moderadores), talvez defina o campo de e-mail do SSO para esses usuários com o e-mail real deles. Quaisquer contas de e-mail duplicadas que eles tenham receberiam o endereço de e-mail falso.

Existem alguns casos em que os funcionários poderem receber e-mails do Discourse é útil. O primeiro que você provavelmente encontrará é que o Discourse fornece uma rota /u/admin-login para usuários funcionários. Essa rota exibe um formulário que aceita um endereço de e-mail de funcionário. O Discourse enviará um link de login de uso único para o membro da equipe. É útil para configurar o SSO - se você acidentalmente se bloquear do site ao configurá-lo, ele permitirá que você volte. Também é útil se houver algum problema com seu servidor de autenticação.

1 curtida

Concordo, e é algo em que tenho pensado (por razões fora do Discourse). O grande problema vem do fato de que membros regulares podem se tornar, e se tornaram, staff. Portanto, mesmo que exigíssemos e-mails exclusivos para usuários staff, não poderíamos garantir que os usuários os tivessem, o que causaria problemas quando um usuário cuja conta tenha um e-mail duplicado se tornasse um membro staff.

Dito isso, agora que está claro que o DiscourseConnect primeiro usa o ID exclusivo para pesquisas de usuários e a parte “O Discourse usa e-mails para mapear usuários externos para usuários do Discourse” da postagem do DiscourseConnect se refere apenas ao vínculo de novos usuários SSO com contas existentes do Discourse, e meu mal-entendido de como o prompt de login funciona foi esclarecido, há algo realmente nos impedindo de simplesmente enviar endereços de e-mail duplicados como estão? Ou essa exclusividade é estritamente aplicada?

Sim. Deixei de fora uma etapa na minha descrição do fluxo de login. O Discourse primeiro tentará encontrar o usuário com base em external_id, depois tentará encontrar o usuário com base em seu email. Se nenhum for encontrado, o Discourse tentará criar o usuário. É assim que seus usuários serão registrados inicialmente no Discourse. O Discourse não permite endereços de e-mail duplicados, portanto, se uma tentativa for feita para criar um usuário com um endereço de e-mail que já está em uso, o Discourse gerará um erro.

Você precisará garantir que os e-mails enviados na carga útil sejam exclusivos por usuário.

Entendido, obrigado pelo esclarecimento :+1: é possível atualizar manualmente o e-mail de um usuário posteriormente? Agora que o problema do prompt de login foi resolvido, posso considerar implementar a ideia que minha equipe teve antes, usando e-mails falsos e um servidor SMTP que executamos e que mapeia esses e-mails falsos para o e-mail real de um usuário. Por exemplo, atualizaríamos o e-mail do Discourse de todos para algo como userid@example.com, que se conecta ao nosso servidor SMTP primeiro e pega o userid para procurar o e-mail real do usuário. No entanto, isso não estaria pronto por algum tempo, então precisaríamos atualizar os e-mails do Discourse dos usuários posteriormente, se possível.

Sim. Você precisará habilitar a configuração do site auth overrides email para isso. Quando habilitado, o e-mail do usuário do Discourse é sincronizado com o e-mail que foi incluído na carga útil de autenticação (a carga útil do DiscourseConnect para o seu caso) toda vez que o usuário faz login. Se não estiver habilitado, o e-mail do usuário será definido para o e-mail da carga útil de autenticação quando a conta for criada inicialmente, mas não será atualizado em logins subsequentes.

Assumindo que auth overrides email esteja habilitado, você também pode atualizá-lo sem exigir que os usuários façam login, fazendo uma solicitação de API para a rota sync_sso: Sincronizar dados do usuário do DiscourseConnect com a rota sync_sso.

Você também poderia atualizar os endereços de e-mail dos usuários em massa a partir do console Rails do site, mas (acho) fazer isso dessa forma enviará um e-mail de confirmação do Discourse para o usuário. Isso não funcionará com endereços de e-mail falsos.

Talvez você possa simplesmente definir os e-mails para algo significativo para começar. Assim que você configurar um site do Discourse, deverá fazer alguns testes para ver quais domínios de e-mail o Discourse aceitará para e-mails falsos. Pelo que me lembro, acho que @invalid.com é aceito. Não tenho certeza sobre outros domínios. Do seu lado, você pode mapear algo como <userId>@invalid.com para o endereço de e-mail real do usuário.

Você tem sido incrivelmente prestativo, muito obrigado! A solução da API é o que eu tinha em mente, mas saber que ela pode sincronizar sozinha funciona perfeitamente também.

Poderíamos, sim. Eu ia tentar usar o endereçamento plus primeiro, dessa forma pelo menos alguns usuários ainda receberiam e-mails desde o início. Depois, migrar para o nosso próprio servidor de mapeamento SMTP mais tarde para dar suporte a todos, incluindo aqueles para os quais o endereçamento plus não funcionou.

1 curtida

@simon @supermathie Vocês dois foram incrivelmente úteis até agora, espero poder sair um pouco do escopo do tópico e pedir alguma ajuda de acompanhamento?

Instalei o Discourse em uma máquina local para testes, usando Install Discourse for development using Docker como meu guia. Não consegui encontrar nenhum outro guia sobre como configurá-lo para testes locais? A wiki parece cobrir apenas configurações de produção, que exigem que seu domínio/DNS/SMTP já estejam configurados. Não queríamos expor o fórum ao público até que tudo fosse implementado do nosso lado, então precisávamos de testes locais onde nada disso era necessário.

Consegui colocá-lo em funcionamento usando esse guia e implementei o SSO em uma instância local do nosso site, mas encontrei 2 problemas até agora:

  1. O redirecionamento para return_sso_url parece funcionar apenas pela metade? No meu caso, o URL é http://localhost:3000/session/sso_login. Ele redireciona com sucesso, no entanto, após o redirecionamento inicial, ele me envia para http://localhost:3000, que apenas exibe o erro RuntimeError: Discourse does not support compiling scss/sass files via Sprockets. O único tópico que encontrei sobre esse erro é Error when building: discourse does not support compiling scss/sass files via sprockets, mas isso não pareceu ir a lugar nenhum. O OP não aceitou nenhuma solução, e a única coisa que aconteceu foi perguntar sobre os tamanhos de RAM e swap (a máquina em que isso está rodando tem 32 GB de RAM e 2 GB de swap. Então, duvido que esse seja o problema?)
  2. avatar_force_update parece não ser respeitado? Ou pelo menos, não para usuários administradores? Habilitei discourse connect overrides avatar nas configurações do site e, na carga útil da resposta do SSO, estou definindo avatar_url e avatar_force_update. Mas ao fazer login na conta de administrador (que está vinculada à minha conta externa), ela não mostra minha foto de perfil externa? Posso ver que external_avatar_url está sendo definido corretamente ao verificar os dados do usuário administrador através da API, apenas não parece estar sendo usado na interface do usuário?

Há uma lista de métodos de instalação aqui: Set up a local Discourse Development Environment?. Tenho um site de desenvolvimento que não usa Docker (usando o guia do Ubuntu). Se for possível para você, acho que você obterá os melhores resultados com a abordagem sem Docker. Uma das razões pelas quais eu o uso é para não ter que lidar com problemas de rede para requisições de API entre o Discourse e outros aplicativos que estou desenvolvendo localmente. É mais rápido que o Docker também.

Deveria ser. Certifique-se de que o aplicativo no qual você está gerando a carga útil do SSO não esteja convertendo o valor booleano true para 1. Esse é um problema comum. Para contornar isso, você pode definir quaisquer valores booleanos na carga útil do SSO para as strings \"true\" ou \"false\". O Discourse os interpretará corretamente. Verifique isso primeiro para ver se é o problema. Pode ser outra coisa. O código que lida com avatar_force_update é um tanto complexo, mas legível: discourse/app/models/discourse_connect.rb at 187204705323b650d61ed25862eb1a0c733aa63c · discourse/discourse · GitHub.

Editar: Para o problema de valores booleanos na carga útil do SSO, acho que é mais preciso dizer que, no processo de geração da carga útil do SSO, o ambiente converterá os valores booleanos true/false em strings. O Discourse espera que as strings sejam \"true\" ou \"false\", outros ambientes de programação podem lidar com elas de forma diferente. Por exemplo:

PHP:

wp> strval(true)
=> string(1) "1"

em oposição a Ruby:

irb(main):001> true.to_s
=> "true"

Python (não tenho certeza de como o Discourse lida com isso):

>>> str(True)
'True'
2 curtidas

Vou tentar uma dessas. Obrigado por me indicar essa direção. Isso é bastante contraintuitivo, no entanto. Normalmente, as pessoas procuram a solução Docker como o método “rápido e fácil” para configurar as coisas. Esta é a primeira vez que me recomendaram evitar a versão Docker. Embora ainda levante a questão de por que isso acontece com a versão Docker? Usar outro método de instalação para contornar o problema funciona por enquanto, mas não resolve o problema subjacente.

Definitivamente não está sendo definido como 1. Estou trabalhando em JavaScript, e o valor booleano true sempre será convertido para a string \"true\":

String(true); // 'true'

(true).toString(); // 'true'

// É isso que meu código está realmente usando
querystring.stringify({
	avatar_force_update: true
}); // 'avatar_force_update=true'

Eu nunca trabalhei com Ruby antes, então não sei o quão longe chegarei realmente investigando isso. Mas, apenas superficialmente, não vejo nenhum problema? No entanto, verifiquei que tanto a configuração relevante no painel do Discourse quanto na carga útil do SSO estão definidas:

Screenshot from 2024-05-05 20-52-06

Eu não testei tentar mudar a imagem de uma conta de usuário padrão de algo diferente do que a conta foi criada, mas quando fiz login em uma conta de usuário padrão pela primeira vez, o Discourse baixou o avatar e o aplicou como esperado. A única conta que não está sendo atualizada é a conta de administrador?

Para ser justo, em PHP você quase sempre gostaria de usar var_export para obter a representação de string “real” de uma variável, pois ela retorna o PHP válido necessário para recriar dita variável:

var_export(true); // true
1 curtida

Dê uma olhada na seção DiscourseConnect, que fica na parte inferior da página de administração do usuário. Há um botão no qual você pode clicar para expandir e mostrar os valores da última carga útil do SSO que foi recebida pelo Discourse.

Você também pode encontrar as mesmas informações do console Rails. Por exemplo:

>SingleSignOnRecord.last

# ou
>SingleSignOnRecord.where(external_id: 2)

Você deve habilitar a configuração do site verbose discourse connect logging. Isso adiciona alguns detalhes extras aos logs gerados em Admin / Logs / Error Logs. Para o problema do avatar, é possível que as entradas de log relevantes apareçam como logs de erro normais, não como logs do DiscourseConnect.

Possivelmente o problema é específico do WordPress. Ele sempre retorna 1 para true e "1" para a representação de string de true.

1 curtida

É o payload esperado, e a URL da imagem de perfil é exibida corretamente:

A imagem de perfil DEVERIA ser esta:

No entanto, ainda mostra como:

Screenshot from 2024-05-06 09-58-21 Screenshot from 2024-05-06 10-02-21

Que é o meu Gravatar:

A menos que eu esteja entendendo mal esta configuração, ou a menos que haja algo mais que eu também precise configurar, eu ativei a configuração para substituir estas:

Screenshot from 2024-05-06 10-05-42

Eu também tentei isso em modo anônimo, navegadores diferentes e limpando o cache do meu navegador apenas para descartar um problema de cache.

Isso está no seu site de desenvolvimento local?

Estou imaginando se o upload do avatar falhou por algum motivo. Tente ativar a configuração do site verbose discourse connect logging (registro detalhado do Discourse Connect), depois saia e entre novamente. Deverá haver pelo menos uma mensagem nos logs relacionada ao avatar:

Possivelmente haverá outro erro relacionado à falha do upload.

Caso você ainda não tenha descoberto, isso significa: “você deve acessar através do proxy ember-cli em vez de um navegador diretamente”.

Use bin/ember-cli -u para iniciá-lo para desenvolvimento.

Eu dupliquei sua situação de avatar:

antes:

carga útil de login:

depois:

mas:

Eu acho que este é um bug onde o Discourse define corretamente o URL do avatar personalizado, mas não muda do Gravatar para a imagem personalizada.

Se eu criar um novo usuário:

funciona imediatamente:
image

então suspeito que isso é acionado por ter uma conta com um gravatar definido antes de usar o DiscourseConnect.

2 curtidas

Consegui fazer com que as etapas do Ubuntu funcionassem (depois de um bom tempo ajustando, pois o script de instalação estava em conflito com pacotes e softwares que já tenho instalados). Isso corrigiu o erro original que eu tinha, mas o SSO ainda funciona pela metade. Agora, em vez do erro scss/sass, o SSO exibe Account login timed out, please try logging in again. toda vez. Clicar no botão Login uma segunda vez enquanto estiver nesta página de erro completa o login, no entanto. Nenhuma alteração de código aconteceu do meu lado, apenas a forma como o Discourse está sendo executado.

Vou simplesmente considerar tudo isso como peculiaridades de rodar isso localmente. Espero que uma implantação em produção não tenha os mesmos problemas.

Isso não pareceu fazer nada com a versão Docker. O script sairia sem nenhuma saída, e nada parecia realmente acontecer do lado do Discourse. Isso também vai contra as etapas listadas no guia Docker, o que parece estranho. Há alguma razão pela qual isso não é mencionado lá?

Parece estranho para mim que o método Docker pareça ter esses problemas, e que o conselho oficial seja instalar o Discourse nativamente (apesar do script de instalação nem sempre funcionar de imediato, pois assume coisas como o uso de bashrc e tentará instalar versões potencialmente conflitantes de pacotes já instalados)? Deveria haver talvez um aviso sobre os problemas potenciais com todas as versões de hospedagem disponíveis? Apenas superficialmente, não fica claro qual é a melhor opção, e tipicamente as pessoas assumem que, se uma build Docker estiver disponível, essa deve ser a escolhida.

Fico feliz em saber que não sou só eu! :smiley: Bugs nunca são divertidos, mas fico feliz em ter ajudado a encontrar este.

Esse pode ser o caso, mas você deve conseguir fazer o DiscourseConnect funcionar localmente sem problemas. Você está acessando o Discourse em http://localhost:4200? Existe um problema estranho (na minha opinião) em que o Discourse pode ser acessado em localhost:4200 ou 127.0.0.1:4200 em um ambiente de desenvolvimento local. Eu ficaria com o domínio localhost. Ele é tratado como uma sessão diferente de 127.0.0.1.

De qualquer forma, isso é apenas um palpite sobre o que está acontecendo. Certifique-se de habilitar a configuração de log detalhado e verificar os logs para obter detalhes.

As instruções de instalação devem deixar claro que você não precisa executar o script. Você pode simplesmente seguir o script passo a passo para garantir que todas as dependências sejam instaladas.

Sim, estou.

As que foram linkadas anteriormente não deixam isso claro. Fui para Set up a local Discourse Development Environment? e selecionei Install Discourse on Ubuntu or Debian for Development, pois estou executando o Ubuntu 22.04.3. Esta página diz que você não precisa executar o script inteiro, mas apenas em texto pequeno depois da parte que instrui os usuários a executá-lo.

Para mim, isso não ficou claro, pois ao ler as instruções de cima para baixo, naturalmente se assumiria que é preciso terminar a etapa atual antes de continuar. Então, eu lutei com o script de instalação, instalando apenas o que eu precisava, apenas para depois continuar lendo após terminar e ver que isso era intencional o tempo todo e que eu não precisava realmente lutar com nada.

Colocar esse aviso depois das instruções definitivamente não as torna claras, na minha opinião.

1 curtida

Parece que ele acredita que o nonce está incorreto? Estou vendo isso nos logs agora ao fazer login:

Não é possível verificar a autenticidade do token CSRF. 15:44
Log detalhado do SSO: Iniciado processo SSO add_groups: admin: avatar_force_update: avatar_url: bio: card_background_url: confirmed_2fa: email: external_id: failed: groups: locale: locale_force_ 15:44
Log detalhado do SSO: Nonce incorreto, foi gerado em uma sessão de navegador diferente ou expirou add_groups: admin: avatar_force_update: true avatar_url: https://pretendo-cdn.b-cdn.net/mii/1424784 15:44
Log detalhado do SSO: Iniciado processo SSO add_groups: admin: avatar_force_update: avatar_url: bio: card_background_url: confirmed_2fa: email: external_id: failed: groups: locale: locale_force_ 15:44
Log detalhado do SSO: O usuário foi logado em PN_Jon add_groups: admin: avatar_force_update: true avatar_url: https://pretendo-cdn.b-cdn.net/mii/1424784406/normal_face.png bio: card_background_url: confirm 15:44
MaxMindDB (/home/jon/discourse/vendor/data/GeoLite2-City.mmdb) não pôde ser encontrado: No such file or directory @ rb_sysopen - /home/jon/discourse/vendor/data/GeoLite2-City.mmdb 15:44
MaxMindDB (/home/jon/discourse/vendor/data/GeoLite2-ASN.mmdb) não pôde ser encontrado: No such file or directory @ rb_sysopen - /home/jon/discourse/vendor/data/GeoLite2-ASN.mmdb 15:44

Após uma inspeção mais detalhada, parece que é porque o redirecionamento do SSO não está usando localhost. Ele está me enviando de volta para 127.0.0.1. Se eu mudar de usar localhost para usar 127.0.0.1 inicialmente, o problema é corrigido.