Детальные групповые права доступа для анонимных и авторизованных пользователей

В нашей кодовой базе исторически существовал запутанный псевдогруппа @everyone, которая могла использоваться для:

  • Настроек сайта типа group_list
  • Разрешений категорий
  • Групп тегов

В некоторых случаях люди интерпретируют @everyone как «все анонимные и все авторизованные пользователи», в то время как другие понимают под этим только «все авторизованные пользователи». В реальности для настроек сайта в большинстве случаев это означает только «все авторизованные пользователи».

Дополнительную путаницу вносит тот факт, что группа @everyone может применяться к настройкам сайта, где предоставление доступа «всем анонимным и авторизованным пользователям» не имеет смысла, например, для pm_tags_allowed_for_groups.

Это также создаёт проблемы с точки зрения управления флагами функций и опыта разработчиков, поскольку для некоторых будущих изменений или других настроек нам может действительно потребоваться включить их для «всех анонимных и авторизованных пользователей».

Решение

Мы внедряем две отдельные автоматические псевдогруппы:

  • anonymous_users (ID 4) — представляет анонимных пользователей, посещающих ваш сайт без аккаунта
  • logged_in_users (ID 5) — представляет всех авторизованных пользователей вашего сайта, по эффекту аналогично автоматической группе trust_level_0, но более специфично

Эти группы уже добавлены, но начнут действовать только после включения будущего изменения granular_anonymous_and_logged_in_groups_permissions на вашем сайте.

При включении этого будущего изменения любая настройка, где в качестве выбранной группы указан everyone, будет автоматически переведена на ID группы logged_in_users, поэтому данные в таблице настроек сайта не изменятся при переключении будущего изменения. Когда это изменение станет постоянным, мы выполним миграцию данных для всех настроек групп, чтобы внести это изменение.

Кроме того, группа anonymous_users помечена как disallowed_group для нескольких настроек сайта, где её использование не имеет смысла, например, personal_message_enabled_groups.

Конфликты с существующими именами групп обрабатываются автоматически: существующие группы переименовываются, а упоминания групп в постах обновляются.

А что насчёт разрешений для тегов и категорий?

Эти разрешения останутся без изменений, поскольку их концепция «всех» отличается в нескольких аспектах и не зависит от лежащей в основе автоматической группы.

9 лайков

Подождите… что? :flushed_face: Это значит, что все категории, которые сейчас открыты для всех (everyone), станут закрытыми и потребуют входа в систему, когда эта функция будет включена?

Нет, потому что:

Это касается только настроек сайта типа «список групп», которые в настоящее время позволяют выбирать «всех» следующим образом:

1 лайк

Может, кто-нибудь поможет мне понять, как мне нужно адаптировать компоненты моей темы?

Я попробовал использовать компонент copy-post в качестве примера, так как помню, что он тоже использует настройку группы, предоставляющую доступ к функции. И что была проблема, потому что псевдогруппа «все» требовала отдельной проверки, точно так же, как в моём компоненте, поскольку сравнение идентификаторов групп, к которым принадлежит пользователь, не помогает — эти идентификаторы нужно проверять отдельно. Поэтому я ожидал недавних изменений там, так как, насколько я понимаю, новые группы тоже являются псевдогруппами, и идентификатор нужно проверять отдельно. Не упускаю ли я что-то, что объясняет, почему здесь это не требуется?

В моём компоненте любимые фильтры есть две настройки групп: одна позволяет группам сохранять собственные фильтры, а другая предлагает стандартные фильтры.
По умолчанию только члены группы trust_level_0 могут использовать пользовательские фильтры, поскольку только зарегистрированные пользователи могут хранить данные в пользовательском поле. Поэтому здесь было бы логично, если бы я не разрешал выбор anonymous_users. Как это сделать в компоненте темы? Есть ли уже пример такого решения?

Настройка по умолчанию для стандартных фильтров — «все», потому что я считаю полезным, чтобы даже незарегистрированные пользователи могли видеть и использовать стандартные фильтры. Проблема в том, что everyone меняется на «logged_in_users», хотя я специально выбрал его. Нужно ли мне создать собственную миграцию для этого, чтобы администраторы, использующие сейчас everyone, в будущем продолжали иметь фильтры для незарегистрированных пользователей? Когда должна произойти эта миграция? Или каждый администратор должен изменить это индивидуально после того, как вы запустите миграцию?

Не является ли всё, о чём я беспокоюсь, на самом деле ненужным? Если нужны какие-то изменения, то менее четырёх недель — довольно короткий срок, учитывая количество поддерживаемых сообществом компонентов, которые могут быть затронуты.
Помимо «copy-post» я также посмотрел на компонент фильтра неотвеченных тем, но не нашёл там никаких изменений. Ощущение, что я упускаю что-то важное. В конце концов, изменение уже включено по умолчанию почти неделю. Поэтому я предполагаю, что официальные компоненты уже были бы обновлены, если бы потребовались какие-либо корректировки.

1 лайк

3 сообщения были объединены в существующую тему: Модернизация темы Foundation

Судя по этим компонентам, currentUser?.groups в любом случае ненадёжен, поскольку он включает только видимые группы пользователя, а группы, влияющие на разрешения, могут не быть сериализованы здесь:

В ядре и плагинах мы обходим это, делая что-то подобное в сериализаторе текущего пользователя:

Но, очевидно, это недоступно для тематических компонентов/тем и их настроек.

Хм, не уверен, нужно будет подумать об этом. Если вы действительно имели в виду everyone, то это должно измениться на logged_in_users И anonymous_users. Это была основная проблема с everyone, как указано в исходном посте — некоторые люди понимали это как только зарегистрированных пользователей, другие — как зарегистрированных плюс анонимов, и это сильно зависело от ситуации.

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

Нет, просто я не подумал о тематических компонентах/темах и их настройках и о том, как это изменение на них повлияет. Я был сосредоточен в основном на настройках сайта. Такие вещи особенно трудно найти, поскольку они даже не используют константу AUTO_GROUPS:

image

В любом случае, я придумаю несколько решений этих проблем и не переведу это изменение в стабильную версию, пока не разберусь с ними.

3 лайка

Краткое обновление: у меня есть идея, как это решить, и мы сейчас обсуждаем это внутри команды. Надеюсь, это займёт не слишком много времени :crossed_fingers:

1 лайк

Это именно я :upside_down_face:; поэтому, чтобы создать категорию только для зарегистрированных пользователей, я установил её разрешение доступа только для TL0, полагаясь на автоматическую группу пользователей TL0, чтобы отличить вошедших в систему пользователей от гостей.

Мне интересно, существует ли таблица, разъясняющая значение этого термина в разных контекстах. Такие различия вызывают как замешательство, так и тревогу — ведь когда люди изначально выбирали этот параметр, они, вероятно, не знали его реального значения, поэтому захотят проверить связанные настройки. В настоящее время я могу только проверять каждое место, где настроены группы, по отдельности и выяснять, что означало это раньше, глядя, на кого оно было изменено после включения функции детальных групп — что ощущается как ощупывание в темноте.

2 лайка

Отличная идея… Возможно, я смогу с помощью ИИ проанализировать все места, где используются настройки на основе групп, и выяснить, возможно ли вообще для anonymous получить доступ к этим ресурсам.

Есть целый ряд настроек, которые уже запрещают выбор группы anonymous_users, так что это, вероятно, хорошее отправное место… скоро отпишусь здесь с результатами.

Сейчас я работаю над PR для этого:

Скоро после этого будут следующие PR и изменения в документации.

3 лайка

@Noble_Fish, это сгенерированный ИИ список настроек, основанных на группах, назначение каждой настройки и то, как на неё влияют анонимные и авторизованные пользователи. Имейте в виду, что я относительно уверен в его правильности, но, как и в случае с любым контентом, созданным ИИ, вам следует самостоятельно проверить факты.

Я думаю, что самый интересный столбец — это «everyone также включал anonymous_users до изменения?». Если там указано «Да», это означает, что everyone означал авторизованных И анонимных пользователей до применения этого предстоящего изменения.

Как вы можете видеть, таких настроек всего несколько, поэтому именно для них администратору нужно будет явно добавить anonymous_users в настройки сайта:

  • hidden_post_visible_groups — мне действительно нужно изменить эту настройку, чтобы разрешить использование anonymous_users, текущий код не совсем подходит для этого предстоящего изменения.
  • lazy_load_categories_groups — мне нужно исправить и эту настройку, она выполняет избыточную проверку everyone, которая уже делается внутри user.in_any_groups?.
  • styleguide_allowed_groups — эта настройка работает как есть, но я также немного её подправлю.

Когда это предстоящее изменение станет постоянным, группы logged_in_users и anonymous_users будут использоваться исключительно, а группа everyone будет удалена.


Настройка Описание Применяется к logged_in_users? Применяется к anonymous_users? everyone также включал anonymous_users до изменения? Результат анализа кода
whispers_allowed_groups Разрешить частное общение внутри тем для членов указанных групп. Нет Нет Нет everyone, logged_in_users и anonymous_users запрещены; в runtime также ожидается конкретная принадлежность к группе.
hidden_post_visible_groups Разрешить членам этих групп просматривать скрытые сообщения. Сотрудники всегда могут просматривать скрытые сообщения. Да Нет Да Проверяет everyone перед отклонением анонимных пользователей; в противном случае использует in_any_groups?.
about_page_hidden_groups Не показывать членов конкретных групп на странице /about. Нет Нет Нет Использует group_users; у псевдогрупп нет строк участников.
about_page_extra_groups Группы, которые будут показаны на странице «О нас» ниже модераторов. Нет Нет Нет Загружает конкретные группы и участников для отображения.
anonymous_posting_allowed_groups Группам, которым разрешено включать анонимное размещение сообщений. Да Нет Нет Проверка авторизованного пользователя через in_any_groups?; anonymous_users запрещен.
personal_message_enabled_groups Разрешить пользователям из этих групп создавать личные сообщения. Да Нет Нет Проверка авторизованного пользователя через in_any_groups?; anonymous_users запрещен.
shared_drafts_allowed_groups Разрешить пользователям из этих групп просматривать и редактировать Общие черновики. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
here_mention_allowed_groups Группам, которым разрешено упоминать @here. Да Нет Нет Требуется аутентифицированный пользователь; anonymous_users запрещен.
approve_unless_allowed_groups Сообщения пользователей, не входящих в эти группы, должны быть одобрены. Да Нет Нет Проверка пользователя через in_any_groups?; anonymous_users запрещен.
approve_new_topics_unless_allowed_groups Новые темы от пользователей, не входящих в эти группы, должны быть одобрены. Да Нет Нет Проверка пользователя через in_any_groups?; anonymous_users запрещен.
skip_review_media_groups Пользователи, не входящие в эти группы, отправляют сообщения с встроенными медиафайлами на проверку. Да Нет Нет Проверка пользователя через in_any_groups?; anonymous_users запрещен.
content_localization_allowed_groups Группам, которым разрешено обновлять локализованный контент. Да Нет Нет Проверка через Guardian/пользователя; anonymous_users запрещен.
email_in_allowed_groups Группам, которым разрешено создавать новые темы через электронную почту. Да Нет Нет Проверка пользователя, отправившего письмо; anonymous_users запрещен.
view_raw_email_allowed_groups Группам, которым разрешено просматривать исходный текст входящих писем. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
uploaded_avatars_allowed_groups Укажите группы, которым разрешено загружать пользовательские аватары. Да Нет Нет Проверка текущего/целевого пользователя; anonymous_users запрещен.
create_topic_allowed_groups Группам, которым разрешено создавать новые темы. Да Нет Нет Требуется пользователь и использует in_any_groups?; anonymous_users запрещен.
topic_timers_allowed_groups Группам, которым разрешено устанавливать таймеры тем. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
edit_wiki_post_allowed_groups Группам, которым разрешено редактировать сообщения, отмеченные как wiki. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
edit_post_allowed_groups Группам, которым разрешено редактировать сообщения. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
self_wiki_allowed_groups Разрешить пользователям из этих групп делать свои сообщения wiki. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
send_email_messages_allowed_groups Группам, которым разрешено отправлять личные сообщения через электронную почту. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
flag_post_allowed_groups Группам, которым разрешено отмечать сообщения как спам/офтоп. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
post_links_allowed_groups Группам, которым разрешено включать ссылки в сообщения. Да Нет Нет Требуется аутентифицированный пользователь; anonymous_users запрещен.
embedded_media_post_allowed_groups Пользователям из этих групп разрешено встраивать медиафайлы в сообщения. Да Нет Нет Проверка действующего пользователя; anonymous_users запрещен.
profile_background_allowed_groups Группам, которым разрешено загружать фон профиля. Да Нет Нет Проверка пользователя; anonymous_users запрещен.
user_card_background_allowed_groups Группам, которым разрешено загружать фон карточки пользователя. Да Нет Нет Проверка пользователя; anonymous_users запрещен.
invite_allowed_groups Группам, которым разрешено приглашать пользователей. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
ignore_allowed_groups Группам, которым разрешено игнорировать других пользователей. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
delete_all_posts_and_topics_allowed_groups Группам, которым разрешено удалять сообщения и темы, созданные другими пользователями, и просматривать удаленный контент. Да Нет Нет Проверка через Guardian/текущего пользователя; anonymous_users запрещен.
edit_all_topic_groups Разрешить пользователям из этой группы редактировать заголовки, теги и категории тем других пользователей. Да Нет Нет Разделение raw, затем in_any_groups?; anonymous_users запрещен.
edit_all_post_groups Разрешить пользователям из этой группы редактировать сообщения других пользователей. Да Нет Нет Проверка пользователя через in_any_groups?; anonymous_users запрещен.
change_post_ownership_allowed_groups Разрешить пользователям из этих групп изменять владельца сообщения. Да Нет Нет Проверка текущего пользователя; anonymous_users запрещен.
cross_origin_opener_unsafe_none_groups Скрытые группы переопределения COOP; соответствующим пользователям присваивается Cross-Origin-Opener-Policy: unsafe-none. Да Нет Нет Требует current_user.present?; выбор анонимных пользователей не имеет эффекта в runtime.
user_api_key_allowed_groups Принадлежность к группе требуется для генерации пользовательских API-ключей. Да Нет Нет Проверка текущего пользователя; anonymous_users запрещен.
create_tag_allowed_groups Группам, которым разрешено создавать теги. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
edit_tags_allowed_groups Группам, которым разрешено редактировать теги, описания тегов и синонимы тегов. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
tag_topic_allowed_groups Группам, которым разрешено добавлять теги к темам. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
pm_tags_allowed_for_groups Разрешить членам включенных групп добавлять теги к любым личным сообщениям. Да Нет Нет Проверка через Guardian; anonymous_users запрещен.
lazy_load_categories_groups Ленивая загрузка информации о категориях только для пользователей этих групп. Да Да Да Явная проверка everyone плюс проверка Guardian через in_any_groups?; anonymous_users имеет значение.
chat_allowed_groups Пользователи из этих групп могут общаться в чате, за исключением анонимных пользователей, которые могут только просматривать чат, если добавлены в эту настройку. Да Да Нет Авторизованный чат использует in_any_groups?; анонимный публичный чат явно проверяет anonymous_users.
direct_message_enabled_groups Разрешить пользователям из этих групп создавать личные чаты между пользователями. Да Нет Нет Проверка Guardian для авторизованного чата; нет значимого пути для анонимных личных сообщений.
chat_pinning_messages_allowed_groups Пользователям из этих групп разрешено закреплять сообщения в чате. Да Нет Нет Требуется доступ к чату/текущий пользователь; нет пути для анонимного закрепления.
chat_message_flag_allowed_groups Пользователям из этих групп разрешено отмечать сообщения в чате как спам/офтоп. Да Нет Нет Проверка пользователя; путь для анонимных заблокирован окружающими разрешениями чата.
no_ads_for_groups Не показывать рекламу пользователям из этих групп. Да Нет Нет Добавляется только в сериализатор current_user; нет полезной нагрузки для анонимного текущего пользователя.
adsense_exclude_groups Реклама не будет показываться членам этих групп. Да Нет Нет Флаг рекламы текущего пользователя через in_any_groups?; нет полезной нагрузки для анонимного текущего пользователя.
dfp_exclude_groups Реклама не будет показываться членам этих групп. Да Нет Нет Флаг рекламы текущего пользователя через in_any_groups?.
amazon_exclude_groups Реклама не будет показываться членам этих групп. Да Нет Нет Флаг рекламы текущего пользователя через in_any_groups?.
carbonads_exclude_groups Реклама не будет показываться членам этих групп. Да Нет Нет Флаг рекламы текущего пользователя через in_any_groups?.
adbutler_exclude_groups Реклама не будет показываться членам этих групп. Да Нет Нет Флаг рекламы текущего пользователя через in_any_groups?.
composer_ai_helper_allowed_groups Пользователи из этих групп будут видеть кнопку помощника ИИ в редакторе. Да Нет Нет Проверка авторизованного помощника ИИ через in_any_groups?.
post_ai_helper_allowed_groups Группам пользователей, которым разрешен доступ к функциям помощника ИИ в сообщениях. Да Нет Нет Проверка авторизованного помощника ИИ через in_any_groups?.
ai_pm_summarization_allowed_groups Группам, которым разрешено создавать и просматривать сводки в личных сообщениях. Нет Нет Нет Использует raw user.group_ids, поэтому псевдогруппы не совпадают.
ai_bot_debugging_allowed_groups Разрешить этим группам видеть кнопку отладки, показывающую сырой запрос и ответ ИИ. Да Нет Нет Явно возвращает false для анонимных, затем использует in_any_groups?.
ai_bot_allowed_groups Когда у бота GPT есть доступ к личным сообщениям, он будет отвечать членам этих групп. Да Нет Нет Основные проверки используют in_any_groups?; один путь для песочницы использует raw group_ids.
ai_bot_public_sharing_allowed_groups Разрешить этим группам делиться личными сообщениями ИИ с публикой через уникальную ссылку. Да Нет Нет Явно возвращает false для анонимных, затем использует in_any_groups?.
assign_allowed_on_groups Пользователям из этих групп разрешено назначать темы. Нет Нет Нет Использует raw user.group_ids/GroupUser; у псевдогрупп нет строк.
discourse_post_event_allowed_on_groups Группам, которым разрешено создавать события. Нет Нет Нет Raw groups.where(id: ...); everyone обрабатывается отдельно, но logged_in_users — нет.
discourse_kanban_manage_board_allowed_groups Группам, которым разрешено создавать и настраивать канбан-доски. Да Нет Нет Guardian использует in_any_groups?, но контроллеры записи требуют входа.
create_policy_allowed_groups Принадлежность к группе требуется для добавления политик к сообщениям. Да Нет Нет Проверка сообщения/пользователя через in_any_groups?.
flag_posts_voting_comments_allowed_groups Группам, которым разрешено отмечать комментарии к голосованию как спам/офтоп. Да Нет Нет Проверка пользователя через in_any_groups?.
allow_solved_in_groups Разрешить отмечать решения в сообщениях групп для этих групп. Нет проверки пользователя Нет проверки пользователя Нет проверки пользователя Соответствует topic.allowed_groups личного сообщения, а не членству текущего пользователя.
accept_all_solutions_allowed_groups Группам, которым разрешено принимать решения в любой теме. Да Нет Нет Проверка аутентифицированного/текущего пользователя через in_any_groups?.
discourse_templates_groups_allowed_private_templates Группам, которым разрешено использовать частные шаблоны. Нет Нет Нет Raw GroupUser.exists?; только everyone обрабатывается отдельно.
poll_create_allowed_groups Группам, которым разрешено создавать опросы. Да Нет Нет Проверка действующего/текущего пользователя через in_any_groups?.
styleguide_allowed_groups Ограничивает видимость руководства по стилю членами указанных групп. Да Да Да Контроллер явно обрабатывает anonymous_users; он также позволял анонимным доступ через everyone до изменения.
2 лайка

Выделите эти изменения в отдельный PR:

2 лайка

@moin этот PR DEV: Add resolve_group_membership functionality to theme settings - Pull Request #41360 - discourse/discourse - GitHub теперь объединён, и я добавляю документацию в DEV: Docs for theme setting resolve_group_membership - Pull Request #41537 - discourse/discourse - GitHub. Я исправил discourse-copy-post с помощью DEV: Use resolve_group_membership core theme functionality - Pull Request #37 - discourse/discourse-copy-post - GitHub, и теперь я прохожусь по нашим другим официальным плагинам, чтобы посмотреть, нужно ли применить то же самое к другим (например, вы уже указали на GitHub - discourse/discourse-unanswered-filter · GitHub)

Для вашего собственного Filter Favorites, вы можете посмотреть на пример copy-post, который я сделал, но в основном вам нужно добавить resolve_group_membership: true в default_favorite_filters_groups и custom_favorite_filters_allowed_groups, тогда они будут доступны как логические значения в зависимости от групп пользователя в settings как settings.user_in_default_favorite_filters_groups и settings.user_in_custom_favorite_filters_allowed_groups соответственно, и теперь вам больше не нужно вручную проверять ID групп пользователей на фронтенде.

Я бы изменил значение по умолчанию для default_favorite_filters_groups на 4|5 в вашем компоненте темы, что означает зарегистрированных и анонимных пользователей, а не 0 (все), который скоро исчезнет.

Я сделаю заметку о запуске миграции БД для настроек темы, когда избавлюсь от группы «все», мне также нужно сделать это для настроек сайта, это произойдёт, когда предстоящие изменения станут постоянными в ближайшие недели (в зависимости от того, появятся ли другие проблемы и как быстро я смогу исправить другие темы/компоненты, которым нужно добавить resolve_group_membership).

Нет, на данный момент нет способа сделать это, как для настроек сайта… Я не думаю, что сейчас это необходимо добавлять, вы можете просто упомянуть это в описании настройки и защитить с помощью currentUser на фронтенде. Возможно, в будущем я добавлю это, если возникнет больше необходимости.

2 лайка

Работает ли это также для типа groups в настройках объекта?

Нет, а нужно ли это? Я не знал об этом, не уверен, используется ли это для разрешений или нет.

Я думаю, что это используется, например, в Discourse Group Sidebar Menus, чтобы администраторы могли настроить, какие группы должны иметь возможность видеть каждый раздел боковой панели, и это используется в Notification Banners для настройки видимости каждого баннера.

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

Я стараюсь предпочитать настройки типа группы, потому что они помогают администратору легко вводить группы с помощью выпадающего списка, в то время как они опираются на идентификаторы групп, которые менее склонны к изменениям по сравнению с именами. И я думаю, что это запутывает, если список групп в объектной настройке и список типа не работают одинаково.

Для меня написание "everyone" также приведет к "trust_level_0", потому что это не работает для посетителей отличается от новой версии, где в выпадающем списке явно предлагается "anonymous_users" — даже если я говорю, что это не будет работать. Если указания в описании было достаточно, вы могли бы сделать то же самое для настроек сайта. Для администратора, использующего оба типа настроек, будет трудно понять, почему в одних местах группы, которые не работают, скрыты, а в других — нет, не потому что создатель компонента не позаботился об этом, а потому что в этом месте это еще не возможно.

2 лайка