Permitir remoção de nome usando SSO

Ao usar o endpoint /admin/users/sync_sso para sincronizar dados SSO, não é possível remover o nome de alguém da conta, mesmo que não seja necessário. Em outras palavras, não é possível alterar o nome de uma conta de algo para nada. Isso está acontecendo com full_name_required = false (e sso_overrides_name = true).

Acredito que o problema esteja aqui:

mas tenho receio de que meu conhecimento em Ruby/Discourse não seja tão bom para enviar um PR.

4 curtidas

Isso parece ser uma solicitação de recurso para mim. No momento, você pode usar a API de administração para limpar nomes nesses casos. Veja:

1 curtida

Desculpe, mas discordo. Não vejo como isso pode ser um pedido de recurso e não um bug.

Entendo que existam outros endpoints de API que podem ser usados. Mas o ponto principal de /admin/users/sync_sso é exatamente manter esse tipo de dados, bem, sincronizado. Ele já permite definir o campo do nome da conta — isso funciona. No entanto, ele assume que o nome é sempre um campo obrigatório e não permite que seja definido como vazio. Portanto, não pode ser usado para manter os dados sincronizados.

O código abaixo parece funcionar conforme o esperado no meu sandbox, mas, novamente, não me sinto confiante o suficiente para enviar um PR neste momento. Sinta-se à vontade para usá-lo/adaptá-lo, etc.

-    if SiteSetting.sso_overrides_name && user.name != name && name.present?
-      user.name = name || User.suggest_name(username.blank? ? email : username)
+    if SiteSetting.sso_overrides_name && user.name != name
+      if SiteSetting.full_name_required && name.present?
+        user.name = name || User.suggest_name(username.blank? ? email : username)
+      else
+        user.name = name
+      end

É um pedido de recurso, a semântica é ambígua. A falta de nome pode significar:

  1. Limpar o nome
  2. Manter o nome como estava

Você está pedindo uma mudança no protocolo. Geralmente prefiro explicitidade para não termos uma API confusa.

2 curtidas

Agora entendi seu ponto.

Mais uma vez, não conheço o suficiente os detalhes internos (ou Ruby)… mas não há como saber se o campo name foi fornecido naquela solicitação? Se estiver totalmente ausente, não altere o campo name da conta. Se o campo name foi fornecido, defina-o (se estiver em branco, limpe-o). Isso não respeitaria esse protocolo/comportamento onde apenas os campos fornecidos são sincronizados?

Desculpe se isso não faz sentido — estou apenas tentando compreender com base no que entendi.

O problema é que, atualmente, a semântica do protocolo para o parâmetro “name” faz com que, quando ele está presente e definido como vazio, seja equivalente à ausência do parâmetro “name”. Ou seja, ele simplesmente não o altera.

Uma mudança aqui seria uma alteração na semântica do protocolo. Poderíamos, supostamente, modificar isso para que name= signifique “deixar o nome em branco”, e a ausência de name signifique “não alterar o nome”. No entanto, como as pessoas já dependem do comportamento antigo, isso tecnicamente constituiria uma mudança incompatível.

Você poderia explicar por que está removendo os nomes?

1 curtida

Não estamos removendo os nomes de todos — os usuários atualizam seus próprios dados sempre que atualizam sua conta em nosso site (provedor de SSO). Contamos com /admin/users/sync_sso para manter os dados sincronizados (nome de usuário, nome, avatar, etc.) na conta do Discourse. O campo nome é opcional e pode ser definido como em branco/vazio.

Acabei de perceber que o problema ocorre não apenas com o nome, mas também com a atualização da biografia, avatar, etc.: não é possível manter esses registros de SSO sincronizados por meio de /admin/users/sync_sso se precisarem ser atualizados para vazio/em branco, independentemente de serem campos obrigatórios ou não.

Entendo o ponto de que as pessoas podem estar dependendo do comportamento existente (embora ninguém tenha relatado esse problema antes?), mas, se esse é o protocolo, parece que ele tem limitações significativas para seu propósito de sincronizar registros de SSO.

Também estou enfrentando esse problema: usuários individuais não conseguem remover suas próprias informações pessoais (nome, avatares, biografia, campos personalizados, etc.) do Discourse, o que tem consequências, como você pode imaginar.

Concordo em não alterar a semântica de como funciona atualmente, mas você não poderia permitir que definíssemos esses atributos como false no payload do SSO ou algo similar para ser explícito sobre a remoção deles?

1 curtida

Anteriormente, estávamos contornando essa limitação do SSO compondo a chamada para o endpoint /admin/users/sync_sso com outra chamada para o endpoint /u/{username} apenas para limpar o nome (se o novo valor para o nome estivesse vazio).

No entanto, isso também parece ter deixado de funcionar em alguma versão recente, possivelmente porque verifica se sso_overrides_name = true antes de atualizar o nome.

Portanto, como está, ao usar SSO e sso_overrides_name = true, agora parece impossível para o provedor de SSO limpar o campo de nome no Discourse via API.

Você consegue ver alguma solução alternativa para isso, @sam?

Acho que um parâmetro extra para nossa rota sync_sso seria apropriado? Algo como &clear_name não tenho certeza. Isso parece um caso extremo. Qual é o caso de uso para nomes em branco? Talvez apenas definir como nome de usuário se você não tiver nenhum e a interface do usuário puder suprimir duplicação.

É confuso para mim que você considere isso um caso extremo, então imagino que você esteja acostumado com instâncias onde o nome é o campo obrigatório.

Nós temos o contrário: o nome de usuário é o que todos devem ter, e o nome é um campo opcional (usamos prioritize_username_in_ux = true e full name required = false). Pense nas contas do Twitter, onde todos devem ter um nome de usuário/handle, e podem opcionalmente ter um nome também. Não acho que seja um cenário de caso extremo querer limpar o campo de nome (ou outros dados pessoais).

No momento, uma vez que alguém preencheu um nome, é impossível removê-lo. Isso era uma limitação do sync_sso que contornamos com uma chamada extra de API para atualizar o usuário, mas agora isso também não funciona mais.

Consideramos isso, mas induz algumas pessoas a assumir que o nome de usuário de alguém é também seu nome real: administramos um fórum internacional e muitas vezes não fica claro o que é o nome de uma pessoa e o que é um nome de usuário (além de sua posição na interface).

Devo mencionar que, se a memória não me falha, o mesmo problema exato acontece ao remover o avatar de alguém através do sync_sso, pois acho que isso também não funciona — contornamos isso fornecendo nossa própria URL para um avatar padrão.

Se houver vários campos que um usuário não possa limpar de alguma forma, talvez um array (ou lista csv) de quais campos limpar/resetar?

O que seria necessário para chegar a um acordo sobre uma forma de realizar isso? Ficarei feliz em implementar qualquer coisa do lado: um novo parâmetro, um valor especial, uma segunda chamada de API. Mas a situação atual, da minha perspectiva, não é um caso extremo. Como @mentalstring acima, estou sincronizando com uma fonte externa de verdade onde definir uma foto de perfil e um nome de exibição são opcionais. O usuário pode não tê-los. O Discourse permite que eles não sejam definidos. Se você não usa SSO, pode defini-los e removê-los livremente. O DiscourseConnect quebra isso: uma vez definidos, eles nunca podem ser removidos, o que, na minha opinião, é um (muito pequeno) bug.

Entendo a preocupação em alterar o protocolo onde vazio atualmente significa nenhuma alteração. Pessoalmente, discordo, acho que é uma maneira direta e razoável de interpretar o protocolo e o risco é minúsculo: seria muito estranho que sistemas fossem implementados de forma que sempre enviassem os valores de nome e avatar_url, mas às vezes os definissem como em branco, e esperassem que isso significasse manter o valor antigo. E se houver algum que faça isso, a consequência é apenas que o nome e o avatar sejam desdefinidos, e deve ser uma correção fácil.

Mas, de qualquer forma, não quero discutir esse ponto, mas quero defender que este é um recurso necessário. Estou disposto a fazer o PR, só quero saber qual solução seria aceita.

Muito obrigado desde já.

1 curtida

Dado que isso acontece com pelo menos name e avatar_url e possivelmente outros (acho que website também?), talvez um parâmetro reset_fields com uma lista de campos para limpar em vez de vários clear_x individuais?

Para nós, já seria útil se pudéssemos corrigir com chamadas adicionais ao endpoint /u/{username}, mas isso também parou de funcionar em algum momento.

1 curtida