Разрешить удаление имени через SSO

При использовании эндпоинта /admin/users/sync_sso для синхронизации данных SSO невозможно удалить имя пользователя из учётной записи, даже если это не требуется. Иными словами, нельзя изменить имя учётной записи с какого-либо значения на пустое. Это происходит при настройках full_name_required = falsesso_overrides_name = true).

Я полагаю, что проблема здесь:

но боюсь, что моих знаний Ruby/Discourse недостаточно для создания PR.

4 лайка

На мой взгляд, это похоже на запрос о новой функции. На данный момент вы можете использовать административный API для очистки имен в подобных случаях. См.:

1 лайк

Извините, но я не согласен. Не вижу, как это может быть запросом на новую функцию, а не ошибкой.

Понимаю, что существуют другие конечные точки API, которые можно использовать. Однако основная суть /admin/users/sync_sso заключается именно в том, чтобы поддерживать такие данные в синхронизации. Уже есть возможность устанавливать поле имени учётной записи — это работает. Но при этом предполагается, что имя всегда является обязательным полем, и не допускается установка его в пустое значение. Следовательно, его нельзя использовать для синхронизации данных.

Код ниже, похоже, работает как ожидалось в моём тестовом окружении, но, опять же, я пока не чувствую себя достаточно уверенно, чтобы отправить запрос на слияние (PR). Используйте его или адаптируйте по своему усмотрению.

-    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

Это запрос на новую функцию, семантика которого неоднозначна. Отсутствие имени может означать:

  1. Очистить имя
  2. Оставить имя без изменений

Вы предлагаете изменить протокол. Я обычно предпочитаю явность, чтобы избежать запутанного API.

2 лайка

Теперь я понимаю вашу точку зрения.

Ещё раз: я недостаточно хорошо знаю внутреннее устройство (или Ruby)… но разве нет способа узнать, был ли передан в этом запросе поле name? Если его нет вообще — не трогать поле name аккаунта. Если поле name передано — установить его (если оно пустое, очистить его). Разве это не соответствует тому протоколу/поведению, при котором синхронизируются только переданные поля?

Извините, если это звучит бессмысленно — просто пытаюсь разобраться, исходя из того, что я понимаю.

Проблема заключается в том, что сейчас семантика протокола такова: если параметр «name» присутствует и установлен в пустое значение, это эквивалентно отсутствию параметра «name» — он просто не затрагивается.

Любое изменение здесь меняет семантику протокола. Можно, конечно, сделать так, чтобы name= означало «очистить имя», а отсутствие параметра name — «не трогать имя», но поскольку люди уже полагаются на старое поведение, это технически является разрушающим изменением.

Не могли бы вы объяснить, почему вы удаляете имена?

1 лайк

Мы не удаляем имена всех пользователей — пользователи сами обновляют свои данные при обновлении аккаунта на нашем сайте (поставщик SSO). Мы полагаемся на /admin/users/sync_sso для синхронизации данных (имя пользователя, имя, аватар и т. д.) в их аккаунте Discourse. Поле «Имя» является необязательным и может быть оставлено пустым.

Я только что осознал, что проблема возникает не только с именем, но и с обновлением биографии, аватара и т. д.: невозможно синхронизировать эти записи SSO через /admin/users/sync_sso, если их необходимо обновить до пустого значения, независимо от того, являются ли они обязательными полями или нет.

Я понимаю, что люди могут полагаться на существующее поведение (хотя никто не сообщал об этой проблеме ранее?), но если это протокол, то, похоже, он имеет существенные ограничения для своей цели — синхронизации записей SSO.

У меня тоже возникает эта проблема: отдельные пользователи не могут удалить свои личные данные (имя, аватары, биографию, пользовательские поля и т. д.) из Discourse, что, как вы можете представить, имеет серьёзные последствия.

Согласен с тем, чтобы не менять семантику текущей работы, но нельзя ли разрешить нам явно указывать удаление этих атрибутов, устанавливая их значение в false в полезной нагрузке SSO или используя аналогичный механизм?

1 лайк

Ранее мы обходили это ограничение SSO, комбинируя вызов /admin/users/sync_sso с дополнительным вызовом к эндпоинту /u/{username}, чтобы очистить имя (если новое значение имени было пустым).

Однако это тоже перестало работать в какой-то момент в одной из последних версий, возможно, потому что проверка теперь учитывает sso_overrides_name = true перед обновлением имени.

Таким образом, в текущем виде при использовании SSO и sso_overrides_name = true провайдеру SSO, похоже, больше невозможно очищать поле имени на Discourse через API.

Можете ли вы предложить какое-либо решение, @sam?

Полагаю, для нашего маршрута sync_sso нужен дополнительный параметр? Например, &clear_name, хотя точно не уверен. Это кажется таким уж частным случаем. В чём смысл использования пустых имён? Может, просто установить имя равным имени пользователя, если оно отсутствует, а интерфейс уже подавит дубликаты?

Мне непонятно, почему вы считаете это пограничным случаем — видимо, вы привыкли к ситуациям, где поле «имя» является обязательным.

У нас всё наоборот: username обязателен для всех, а поле «имя» опционально (мы используем prioritize_username_in_ux = true и full name required = false). Подумайте о аккаунтах в Twitter: у каждого должен быть username/никнейм, а имя может быть указано дополнительно. Не считаю пограничным случаем желание очистить поле имени (или другие личные данные).

В данный момент, если пользователь однажды ввёл имя, удалить его невозможно. Это было ограничением sync_sso, с которым мы справлялись через дополнительный вызов API для обновления пользователя, но теперь и этот способ не работает.

Мы рассматривали такой вариант, но это может привести к тому, что некоторые пользователи будут считать, что их username — это и есть их реальное имя: мы ведём международный форум, и часто непонятно, что является именем человека, а что — его username (кроме их расположения в интерфейсе).

Стоит упомянуть, что, если память мне не изменяет, точно такая же проблема возникает при попытке удалить аватар через sync_sso, поскольку, как мне кажется, это тоже не работает — мы обходим это, предоставляя собственную ссылку на аватар по умолчанию.

Если есть несколько полей, которые нельзя каким-либо образом очистить, возможно, стоит добавить массив (или CSV-список) полей, которые нужно очистить/сбросить?

Что нужно, чтобы прийти к согласию по способу реализации этого? Я готов реализовать что угодно с моей стороны: новый параметр, специальное значение, второй вызов API. Но текущая ситуация, с моей точки зрения, не является пограничным случаем. Как и @mentalstring выше, я синхронизируюсь с внешним источником истины, где установка аватара и отображаемого имени является опциональной. Пользователь может не иметь их. Discourse позволяет не устанавливать эти поля. Если вы не используете SSO, вы можете свободно устанавливать и удалять их. DiscourseConnect нарушает это: после установки их больше нельзя удалить, что, на мой взгляд, является (очень мелкой) ошибкой.

Я понимаю опасения относительно изменения протокола, где пустое значение сейчас означает «без изменений». Лично я не согласен с этим; я считаю, что это прямой и разумный способ интерпретации протокола, а риск минимален: было бы очень странно, если бы системы были реализованы так, что они всегда отправляют значения name и avatar_url, но иногда устанавливают их в пустые, ожидая, что это будет означать сохранение старого значения. И даже если есть такие системы, последствием будет лишь сброс имени и аватара, и это должно быть легко исправить.

Но в любом случае я не хочу спорить об этом пункте, однако я хочу аргументировать, что это необходимая функция. Я готов сделать pull request, мне просто нужно знать, какое решение будет принято.

Заранее большое спасибо.

1 лайк

Учитывая, что это происходит как минимум с полями name и avatar_url, а возможно, и с другими (я думаю, что с website тоже), может быть, стоит добавить параметр reset_fields со списком полей для очистки вместо нескольких отдельных параметров clear_x?

Для нас уже было бы полезно, если бы мы могли исправить это с помощью дополнительных вызовов к конечной точке /u/{username}, но и это в какой-то момент перестало быть возможным.

1 лайк