Granular group-based permissions for anonymous and logged in users

There has been a historically confusing pseudogroup called @everyone within our codebase, which can be used for:

  • Site settings which are of the group_list type
  • Category permissions
  • Tag groups

In some cases people are taking @everyone to mean “all anonymous and all logged in users”, and others are taking it to mean only “all logged in users”, where the reality for site settings is that it only means “all logged in users” in most cases.

Further muddying the waters is the fact that this @everyone group can be used on site settings where it makes no sense for “all anon and logged in users” to have access to the feature, such as pm_tags_allowed_for_groups.

This is also confusing from a feature flagging and developer experience perspective, since for some upcoming changes or other settings we may truly want to enable them for “all anon and logged in users”.

Solution

We are introducing two separate automatic pseudogroups:

  • anonymous_users (ID 4) - Represents anonymous users visiting your site with no account
  • logged_in_users (ID 5) - Represents all logged in users to your site, similar in effect to the trust_level_0 automatic group, but more specific

These have already been introduced, but will only take effect when the granular_anonymous_and_logged_in_groups_permissions upcoming change is enabled on your site.

When the upcoming change is enabled, any setting with everyone as a selected group will have it automatically translated to the logged_in_users ID, so no data in the site settings table will be changed when toggling the upcoming change. When the upcoming change becomes Permanent, we will do a data migration for all group settings to make this change.

In addition, we have marked anonymous_users as a disallowed_group for several site settings where it makes no sense, for example personal_message_enabled_groups.

Conflicts with existing group names are handled automatically, by renaming the existing groups and updating post group mentions.

What about tag and category permissions?

These permissions will be unchanged, since their concept of “everyone” is different in a few ways and doesn’t rely on the underlying automatic group.

8 likes

Wait… what :flushed_face: Does that mean all categories that are now public (everyone) will change to closed ones requiring login, when that is enabled?

No, because:

This only affects group list type site settings that currently allow you to select “everyone” like so:

1 like

Can anyone help me understand how I need to adjust my theme components?

I tried to use the copy-post component as an example because I remember that it also uses a group setting that grants access to the feature. And that there was an issue because the “everyone” pseudo-group required a separate check, just like in my component, because comparing the IDs of the groups the user belongs to doesn’t help - those IDs need to be checked separately. That’s why I expected a recent change there, because as I understand it, the new groups are also pseudo-groups and the ID would need to be checked separately. Am I missing something that explains why this isn’t necessary here?

My favorite filters component has two group settings: one that allows groups to save their own filters, and one that offers standard filters.
By default, only members of the trust_level_0 group can use custom filters, because only registered users can have data stored in a custom user field. So here it would make sense if I didn’t allow anonymous_users as a selection. How do I do that in a theme component? Is there already an example for this?

The default setting for the default filters is “everyone,” because I find it helpful for even unregistered users to be able to see and use the default filters. The problem is that everyone changes to ‘logged_in_users’ even though I specifically selected it. Do I need to create a custom migration for this so that admins currently using everyone will continue to have filters for unregistered users in the future? When does this migration need to take place? Or does every admin need to change this individually after you have run the migration?

Is all this I’m worrying about actually unnecessary? If adjustments are needed, less than four weeks feels like a fairly short timeframe given the number of community-maintained components that could potentially be affected.
In addition to “copy-post,” I also looked at the unanswered filter component, but I couldn’t find any changes there either. It feels like I’m overlooking something important. After all, the change has been enabled by default for almost a week now. That’s why I assume that official components would already have been updated if adjustments were necessary.

1 like

3 posts were merged into an existing topic: Modernizing the Foundation theme

Looking at these components, currentUser?.groups is not reliable anyway, since it only includes visible groups for the user, and the groups that they are in that impact permissions may not be serialized here:

We get around this in core/plugins by doing stuff like this in the current user serializer:

But obviously, this is not available to theme components/themes and their settings.

Hmm not sure, will have to think about this. If you truly meant everyone, then it would need to change to both logged_in_users AND anonymous_users . This was the main problem with everyone as stated in the OP – some people took it to mean only logged in users, others took it to mean logged in + anon, and it was very situation-dependent.

I chose the “only logged in users” interpretation because that was safer from a security POV.

Nope, just didn’t think about theme components/themes and their settings and how they would be impacted by this change, I was mostly focused on site settings. Stuff like this especially will be very hard to find, since it’s not even using the AUTO_GROUPS const:

image

Anyway, I will think up some solutions to these issues, and I won’t move this change along to Stable until I figure them out.

2 likes

Quick update, I have an idea on how to handle this, and we are having some internal discussions around it. Hopefully won’t take too long :crossed_fingers:

1 like

This is exactly me :upside_down_face:; so in order to create a category for registered users only, I set its access permission to TL0 only, relying on the TL0 automatic user group to distinguish logged-in users from guests.

I wonder if there is a table for distinguishing the meaning of this term in different contexts. Such differences are both confusing and unsettling—because when people originally chose this setting, they probably didn’t know its actual meaning, so they would want to check the related settings. Currently, I can only check each place where groups are set individually, and confirm what it used to mean by seeing who it was changed to after the Granular group feature was enabled—which feels like fumbling in the dark.

2 likes

This is a good idea…I might be able to finagle something with AI to go look in all the places group-based settings are used and spit out whether it’s even possible for anonymous to access those things.

There are a bunch of settings that already disallow the anonymous_users group from being selected, so those are probably a good starting point…will report back here with findings.

I have PRs for this I am working on now:

Will have followup PRs & docs changes soon after.

2 likes

@Noble_Fish , this is the AI-generated list of group based settings, what the setting is for, and how anonymous/logged in users apply to that setting. Be aware that I am reasonably confident this is correct, but like anything AI generated, it’s good to double-check the facts yourself.

I think the most interesting column is “everyone also included anonymous_users before change?”, if this is Yes that means everyone meant logged in AND anonymous before this upcoming change was applied.

As you can see, there are only a few in there, so those are the only ones that an admin would need to explicitly add anonymous_users to in site settings:

  • hidden_post_visible_groups - I actually need to change this one to allow for anonymous_users, the code isn’t quite right for this upcoming change.
  • lazy_load_categories_groups - I need to fix this one too, it does a redundant everyone check that’s already done inside user.in_any_groups?
  • styleguide_allowed_groups - This works as is, but I will also tweak it a bit

When this upcoming change becomes permanent, the logged_in_users and anonymous_users groups will be used exclusively, and everyone will be deleted.


Setting Description logged_in_users applies? anonymous_users applies? everyone also included anonymous_users before change? Code finding
whispers_allowed_groups Allow private communication within topics for members of specified groups. No No No everyone, logged_in_users, and anonymous_users are disallowed; runtime also expects concrete/group membership.
hidden_post_visible_groups Allow members of these groups to view hidden posts. Staff users can always view hidden posts. Yes No Yes Checks everyone before rejecting anonymous users; otherwise uses in_any_groups?.
about_page_hidden_groups Do not show members of specific groups on the /about page. No No No Uses group_users; pseudogroups have no member rows.
about_page_extra_groups Groups to show on the about page below the moderators. No No No Loads concrete groups and members for display.
anonymous_posting_allowed_groups Groups that are allowed to enable anonymous posting. Yes No No Logged-in user gate via in_any_groups?; anonymous_users is disallowed.
personal_message_enabled_groups Allow users in these groups to create personal messages. Yes No No Logged-in user gate via in_any_groups?; anonymous_users is disallowed.
shared_drafts_allowed_groups Allow users in these groups to see and edit Shared Drafts. Yes No No Logged-in guardian gate; anonymous_users is disallowed.
here_mention_allowed_groups Groups that are allowed to mention @here. Yes No No Requires authenticated user; anonymous_users is disallowed.
approve_unless_allowed_groups Posts by users not in these groups must be approved. Yes No No User gate via in_any_groups?; anonymous_users is disallowed.
approve_new_topics_unless_allowed_groups New topics by users not in these groups must be approved. Yes No No User gate via in_any_groups?; anonymous_users is disallowed.
skip_review_media_groups Users outside these groups have posts with embedded media sent for review. Yes No No User gate via in_any_groups?; anonymous_users is disallowed.
content_localization_allowed_groups Groups allowed to update localized content. Yes No No Guardian/user gate; anonymous_users is disallowed.
email_in_allowed_groups Groups that are allowed to post new topics via email. Yes No No Email sender user gate; anonymous_users is disallowed.
view_raw_email_allowed_groups Groups which can view raw incoming email content. Yes No No Guardian user gate; anonymous_users is disallowed.
uploaded_avatars_allowed_groups Specify groups allowed to upload custom profile pictures. Yes No No Current/target user gate; anonymous_users is disallowed.
create_topic_allowed_groups Groups that are allowed to create new topics. Yes No No Requires user and uses in_any_groups?; anonymous_users is disallowed.
topic_timers_allowed_groups Groups that are allowed to set topic timers. Yes No No Guardian user gate; anonymous_users is disallowed.
edit_wiki_post_allowed_groups Groups that are allowed to edit posts marked as wiki. Yes No No Guardian user gate; anonymous_users is disallowed.
edit_post_allowed_groups Groups that are allowed to edit posts. Yes No No Guardian user gate; anonymous_users is disallowed.
self_wiki_allowed_groups Allow users in these groups to make their own posts wiki. Yes No No Guardian user gate; anonymous_users is disallowed.
send_email_messages_allowed_groups Groups that are allowed to send personal messages via email. Yes No No Guardian user gate; anonymous_users is disallowed.
flag_post_allowed_groups Groups that are allowed to flag posts. Yes No No Guardian user gate; anonymous_users is disallowed.
post_links_allowed_groups Groups that are allowed to include links in posts. Yes No No Requires authenticated user; anonymous_users is disallowed.
embedded_media_post_allowed_groups Users in these groups are allowed to embed media items in a post. Yes No No Acting user gate; anonymous_users is disallowed.
profile_background_allowed_groups Groups that are allowed to upload a profile background. Yes No No User gate; anonymous_users is disallowed.
user_card_background_allowed_groups Groups that are allowed to upload a user card background. Yes No No User gate; anonymous_users is disallowed.
invite_allowed_groups Groups that are allowed to invite users. Yes No No Guardian user gate; anonymous_users is disallowed.
ignore_allowed_groups Groups that are allowed to ignore other users. Yes No No Guardian user gate; anonymous_users is disallowed.
delete_all_posts_and_topics_allowed_groups Groups allowed to delete posts and topics created by other users and see deleted content. Yes No No Guardian/current user gate; anonymous_users is disallowed.
edit_all_topic_groups Allow users in this group to edit other users’ topic titles, tags, and categories. Yes No No Raw split then in_any_groups?; anonymous_users is disallowed.
edit_all_post_groups Allow users in this group to edit other users’ posts. Yes No No User gate via in_any_groups?; anonymous_users is disallowed.
change_post_ownership_allowed_groups Allow users in these groups to change post ownership. Yes No No Current user gate; anonymous_users is disallowed.
cross_origin_opener_unsafe_none_groups Hidden COOP override groups; matched users get Cross-Origin-Opener-Policy: unsafe-none. Yes No No Requires current_user.present?; anonymous selection has no runtime effect.
user_api_key_allowed_groups Group membership required for generation of user API keys. Yes No No Current user gate; anonymous_users is disallowed.
create_tag_allowed_groups Groups that are allowed to create tags. Yes No No Guardian user gate; anonymous_users is disallowed.
edit_tags_allowed_groups Groups that are allowed to edit tags, tag descriptions, and tag synonyms. Yes No No Guardian user gate; anonymous_users is disallowed.
tag_topic_allowed_groups Groups that are allowed to tag topics. Yes No No Guardian user gate; anonymous_users is disallowed.
pm_tags_allowed_for_groups Allow members of included groups to tag any personal message. Yes No No Guardian user gate; anonymous_users is disallowed.
lazy_load_categories_groups Lazy load category information only for users of these groups. Yes Yes Yes Explicit everyone check plus guardian in_any_groups?; anonymous_users is meaningful.
chat_allowed_groups Users in these groups can chat, except anonymous users who can only view chat when added to this setting. Yes Yes No Logged-in chat uses in_any_groups?; anonymous public chat explicitly checks anonymous_users.
direct_message_enabled_groups Allow users within these groups to create user-to-user Personal Chats. Yes No No Logged-in chat guardian gate; no meaningful anonymous DM path.
chat_pinning_messages_allowed_groups Users in these groups are allowed to pin chat messages. Yes No No Requires chat access/current user; no anonymous pin path.
chat_message_flag_allowed_groups Users in these groups are allowed to flag chat messages. Yes No No User gate; anonymous path is blocked by surrounding chat permissions.
no_ads_for_groups Don’t show ads to users in these groups. Yes No No Added to current_user serializer only; no anonymous current-user payload.
adsense_exclude_groups Ads will not be shown to members of these groups. Yes No No Current-user ad flag via in_any_groups?; no anonymous current-user payload.
dfp_exclude_groups Ads will not be shown to members of these groups. Yes No No Current-user ad flag via in_any_groups?.
amazon_exclude_groups Ads will not be shown to members of these groups. Yes No No Current-user ad flag via in_any_groups?.
carbonads_exclude_groups Ads will not be shown to members of these groups. Yes No No Current-user ad flag via in_any_groups?.
adbutler_exclude_groups Ads will not be shown to members of these groups. Yes No No Current-user ad flag via in_any_groups?.
composer_ai_helper_allowed_groups Users in these groups will see the AI helper button in the composer. Yes No No Logged-in AI helper gate via in_any_groups?.
post_ai_helper_allowed_groups User groups allowed to access AI Helper features in posts. Yes No No Logged-in AI helper gate via in_any_groups?.
ai_pm_summarization_allowed_groups Groups allowed to create and view summaries in PMs. No No No Uses raw user.group_ids, so pseudogroups do not match.
ai_bot_debugging_allowed_groups Allow these groups to see a debug button showing the raw AI request and response. Yes No No Explicitly returns false for anonymous, then uses in_any_groups?.
ai_bot_allowed_groups When the GPT Bot has access to the PM, it will reply to members of these groups. Yes No No Primary gates use in_any_groups?; one playground path uses raw group_ids.
ai_bot_public_sharing_allowed_groups Allow these groups to share AI personal messages with the public via a unique link. Yes No No Explicitly returns false for anonymous, then uses in_any_groups?.
assign_allowed_on_groups Users in these groups are allowed to assign topics. No No No Uses raw user.group_ids/GroupUser; pseudogroups have no rows.
discourse_post_event_allowed_on_groups Groups that are allowed to create events. No No No Raw groups.where(id: ...); everyone is special-cased, but logged_in_users is not.
discourse_kanban_manage_board_allowed_groups Groups allowed to create and configure kanban boards. Yes No No Guardian uses in_any_groups?, but write controllers require login.
create_policy_allowed_groups Group membership required for adding policies to posts. Yes No No Post/user gate via in_any_groups?.
flag_posts_voting_comments_allowed_groups Groups allowed to flag a post voting comment. Yes No No User gate via in_any_groups?.
allow_solved_in_groups Allow marking solutions in group messages for these groups. No user gate No user gate No user gate Matches PM topic.allowed_groups, not current user membership.
accept_all_solutions_allowed_groups Groups that are allowed to accept solutions on any topic. Yes No No Authenticated/current user gate via in_any_groups?.
discourse_templates_groups_allowed_private_templates Groups allowed to use private templates. No No No Raw GroupUser.exists?; only everyone is special-cased.
poll_create_allowed_groups The groups that are allowed to create polls. Yes No No Acting/current user gate via in_any_groups?.
styleguide_allowed_groups Limits visibility of the styleguide to members of the provided groups. Yes Yes Yes Controller explicitly handles anonymous_users; it also allowed anonymous through everyone before the change.
2 likes

Split out these tweaks into a new PR:

1 like

@moin this PR DEV: Add resolve_group_membership functionality to theme settings - Pull Request #41360 - discourse/discourse - GitHub is now merged and I’m adding docs in DEV: Docs for theme setting resolve_group_membership - Pull Request #41537 - discourse/discourse - GitHub . I’ve fixed discourse-copy-post with DEV: Use resolve_group_membership core theme functionality - Pull Request #37 - discourse/discourse-copy-post - GitHub and now I am going through our other official plugins to see if any others need the same treatment (e.g. you already pointed to GitHub - discourse/discourse-unanswered-filter · GitHub )

For your own Filter Favorites , you can see the copy-post example I did, but basically you need to add resolve_group_membership: true to both default_favorite_filters_groups and custom_favorite_filters_allowed_groups , then they will be available as booleans depending on the user’s group memberships on settings as settings.user_in_default_favorite_filters_groups and settings.user_in_custom_favorite_filters_allowed_groups respectively, and you now no longer need to manually check user group IDs on the frontend.

I would change the default of default_favorite_filters_groups to 4|5 in your theme component, which is logged in & anonymous users, rather than 0 (everyone) which is going away soon.

I will make a note to run a DB migration on theme settings when I get rid of the everyone group, I need to do one for site settings too, this will happen when the upcoming change moves to permanent in the next few weeks (depending on whether other issues come up and how fast I get through fixing other themes/components that need resolve_group_membership added).

No there is no way to do this at the moment like there is for site settings…I don’t think it’s necessary to add right now, you can just mention this in the setting description and guard with currentUser in the frontend anyway. Maybe in future I will add this if there is more need.

1 like

Does this work for the groups type in object settings too?