Allow name removal using SSO

Using /admin/users/sync_sso endpoint to sync SSO data, it is not possible to remove someone’s name from the account, even if it is not required. In other other words, it’s not possible to change an account’s name from something to nothing. This is happening with full_name_required = false (and sso_overrides_name = true).

I believe the issue is here:

https://github.com/discourse/discourse/blob/88ecb650a98921e5e3cd345e29f84d9dd204b777/app/models/discourse_single_sign_on.rb#L268

but I’m afraid my knowledge of Ruby/Discourse isn’t that hot to submit a PR.

「いいね!」 4

This feels like a feature request to me. At the moment you can use the admin API to clear names in cases like this. See:

「いいね!」 1

Sorry, but I disagree. I don’t see how this can be a feature request and not a bug.

I understand there’s other API endpoints which can be used. But the main point of /admin/users/sync_sso is precisely to keep this sort of data, well, in sync. It already allows to set the account name field — that works. But, it assumes name is always a required field and doesn’t allow it to be set it to blank. So it can’t be used to keep data in sync.

The code below seems to make it work as expected on my sandbox, but again, I don’t feel confident enough to submit a PR at this point. Feel free to use it/adapt it, 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

Its a feature request, the semantics are ambiguous. Lack of name could mean

  1. Clear the name
  2. Leave the name what it was

You are asking for a protocol change here. I usually prefer explicitness so we don’t have a confusing api.

「いいね!」 2

I see your point now.

Once again, I don’t know the internals (or ruby) enough… but there’s no way to know if the field name was provided on that request? Not present at all, don’t touch the name field of the account. Field name provided, set it (if blank, clear it). Wouldn’t this respect that protocol/behavior where only the provided fields are synched?

Sorry if this makes no sense — just trying to grasp from what I understand.

The problem is that the protocol semantics now of “name” param is there and set to blank, is the same as no “name” param. It simply does not touch it.

A change here is a change to protocol semantics. We could I guess change is so name= becomes name is blanked, and absence of name means “don’t touch name”, but people already rely on the old behavior so this is technically a breaking change.

Can you explain why you are removing names?

「いいね!」 1

We are not removing everyone’s names — the users are updating their own data whenever they update their account on our website (SSO provider). We rely on /admin/users/sync_sso to keep data in sync (username, name, avatar, etc) in their Discourse account. Name is an optional field and can be set to blank/empty.

I just realized the issue happens not just with name but also with updating bio, avatar, etc: it’s not possible to keep those SSO records in sync through /admin/users/sync_sso if they need to be updated to blank/empty, regardless whether they are mandatory fields or not.

I understand the point that people may be relying on existing behavior (although nobody reported this issue before?), but if this is the protocol, it seems it has significant limitations for its purpose of synchronizing SSO records.

I’m also getting bitten by this, individual users are unable to remove their own personal information (name, avatars, bio, custom fields etc) from Discourse which has ramifications as you can imagine.

Agree with not changing the semantics of how it works now but could you not allow us to set these attributes as false in the SSO payload or something similar to be explicit about removing them?

「いいね!」 1

以前は、/admin/users/sync_sso への呼び出しと /u/{username} エンドポイントへの別の呼び出しを組み合わせて、名前をクリアしていました(名前の新しい値が空の場合)。

しかし、これも最近のバージョンで動作しなくなったようです。おそらく、名前を更新する前に sso_overrides_name = true をチェックするためでしょう。

そのため、現状では、SSO と sso_overrides_name = true を使用している場合、SSO プロバイダーが API を介して Discourse の名前フィールドをクリアすることは不可能になったようです。

この回避策について、@sam さん、何かお分かりになりますか?

sync_sso ルートに &clear_name のような追加のパラメータが必要だと思いますか?よくわかりません。これは非常にまれなケースのように感じます。名前が空白の場合のユースケースは何ですか?ユーザー名がない場合は、ユーザー名に設定し、UI で重複を抑制できるようにすればよいのではないでしょうか。

これがエッジケースだと考えるのが私には混乱します。おそらく、名前が必須フィールドである状況に慣れているのでしょう。

私たちは逆で、ユーザー名が誰もが持たなければならないもので、名前はオプションのフィールドです(prioritize_username_in_ux = truefull name required = false を使用しています)。Twitterアカウントのように、誰もがユーザー名/ハンドルを持たなければならず、オプションで名前も持つことができます。名前フィールド(または他の個人データ)をクリアしたいというのは、エッジケースのシナリオではないと思います。

現在、名前を入力すると、それを削除することは不可能です。これはsync_ssoの制限であり、ユーザーを更新するための追加のAPI呼び出しで回避していましたが、それも現在では機能しません。

検討しましたが、ユーザー名が本名であると誤解する人もいます。私たちは国際フォーラムを運営しており、何が個人の名前で何がユーザー名なのか(インターフェイス上の位置を除いて)はしばしば不明瞭です。

記憶が正しければ、アバターを削除する場合もsync_ssoで全く同じ問題が発生すると思います。これも機能しないと思われます。デフォルトアバター用のURLを独自に提供することで回避しています。

クリアまたはリセットできないフィールドが複数ある場合、クリア/リセットするフィールドの配列(またはCSVリスト)が必要になるかもしれません。

これを達成する方法について合意するには、何が必要でしょうか? パラメータの追加、特別な値、2番目のAPI呼び出しなど、こちら側で実装することは何でも喜んで行います。しかし、私の見解では、現在の状況はエッジケースではありません。上記の@mentalstringと同様に、私は外部の真実の情報源と同期しており、プロフィール写真や表示名の設定はオプションです。ユーザーはそれらを持たないことが許可されています。Discourseでは設定しないことが可能です。SSOを使用しない場合、それらを自由に設定および削除できます。DiscourseConnectはこれを壊します。一度設定されると、それらを削除することは決してできません。これは私の意見では(非常に小さな)バグです。

プロトコルを変更することについての懸念は理解しています。そこでは空が現在のところ変更なしを意味します。個人的には同意しません。プロトコルを解釈するための簡単で合理的な方法であり、リスクはごくわずかだと考えています。名前とアバターのURL値を常に送信するが、時にはそれらを空白に設定し、古い値を保持することを意味すると期待するシステムを実装することは非常に奇妙でしょう。そして、そのようなシステムがもしあれば、その結果は名前とアバターが解除されるだけで、簡単な修正になるはずです。

しかし、いずれにせよ、その点については議論したくありません。しかし、これが不可欠な機能であるという主張をしたいのです。PRを行う用意はありますが、どのような解決策が受け入れられるかを知りたいだけです。

前もって感謝します。

「いいね!」 1

少なくともnameavatar_url、そしておそらく他のもの(websiteも?)でこれが起こることを考えると、いくつかの個別のclear_xの代わりに、クリアするフィールドのリストを持つreset_fieldsパラメータはどうでしょうか?

私たちにとっては、/u/{username}エンドポイントへの追加の呼び出しで修正できればすでに役立ちますが、それもいつの間にか機能しなくなりました。

「いいね!」 1