DEV: Move core plugin TL -> group settings (#25355)

* DEV: Change poll_minimum_trust_level_to_create to group based setting

New setting is poll_create_allowed_groups

c.f. https://meta.discourse.org/t/changes-coming-to-settings-for-giving-access-to-features-from-trust-levels-to-groups/283408

* DEV: Move styleguide_admin_only to group based setting

Not exactly a TL -> group change, but still part of the
overall effort here:

https://meta.discourse.org/t/changes-coming-to-settings-for-giving-access-to-features-from-trust-levels-to-groups/283408

New setting is styleguide_allowed_groups
This commit is contained in:
Martin Brennan 2024-01-23 11:35:14 +10:00 committed by GitHub
parent 678e3cfd25
commit a03f87bdbd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 124 additions and 30 deletions

View File

@ -78,7 +78,7 @@ module DiscourseNarrativeBot
prerequisite:
Proc.new do
SiteSetting.poll_enabled &&
@user.has_trust_level?(SiteSetting.poll_minimum_trust_level_to_create)
@user.in_any_groups?(SiteSetting.poll_create_allowed_groups_map)
end,
next_state: :tutorial_details,
next_instructions: Proc.new { I18n.t("#{I18N_KEY}.details.instructions", i18n_post_args) },

View File

@ -29,6 +29,7 @@ RSpec.describe DiscourseNarrativeBot::AdvancedUserNarrative do
stub_image_size
Jobs.run_immediately!
SiteSetting.discourse_narrative_bot_enabled = true
Group.refresh_automatic_groups!
end
describe "#notify_timeout" do
@ -620,7 +621,7 @@ RSpec.describe DiscourseNarrativeBot::AdvancedUserNarrative do
end
it "should create the right reply (insufficient trust level)" do
user.update(trust_level: 0)
user.change_trust_level!(TrustLevel[0])
TopicUser.change(
user.id,

View File

@ -17,10 +17,7 @@ function initializePollUIBuilder(api) {
return (
siteSettings.poll_enabled &&
(composer.model.topic?.pm_with_non_human_user ||
(currentUser &&
(currentUser.staff ||
currentUser.trust_level >=
siteSettings.poll_minimum_trust_level_to_create)))
(currentUser && (currentUser.staff || currentUser.can_create_poll)))
);
},
});

View File

@ -4,9 +4,12 @@ en:
poll_maximum_options: "Maximum number of options allowed in a poll."
poll_edit_window_mins: "Number of minutes after post creation during which polls can be edited."
poll_minimum_trust_level_to_create: "Define the minimum trust level needed to create polls."
poll_create_allowed_groups: "The groups that are allowed to create polls."
poll_groupable_user_fields: "A set of user field names that can be used to group and filter poll results."
poll_export_data_explorer_query_id: "ID of the Data Explorer Query to use for exporting poll results (0 to disable)."
poll_default_public: "When creating a new poll, enable the 'show who voted' option by default."
keywords:
poll_create_allowed_groups: "poll_minimum_trust_level_to_create"
poll:
poll: "poll"

View File

@ -14,6 +14,14 @@ plugins:
default: 1
client: true
enum: "TrustLevelSetting"
hidden: true
poll_create_allowed_groups:
default: "11" # auto group trust_level_1
type: group_list
client: false
allow_any: false
refresh: true
validator: "AtLeastOneGroupValidator"
poll_groupable_user_fields:
default: ""
type: list

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
class FillPollCreateAllowedGroupsBasedOnDeprecatedSetting < ActiveRecord::Migration[7.0]
def up
old_setting_trust_level =
DB.query_single(
"SELECT value FROM site_settings WHERE name = 'poll_minimum_trust_level_to_create' LIMIT 1",
).first
if old_setting_trust_level.present?
allowed_groups = "1#{old_setting_trust_level}"
DB.exec(
"INSERT INTO site_settings(name, value, data_type, created_at, updated_at)
VALUES('poll_create_allowed_groups', :setting, '20', NOW(), NOW())",
setting: allowed_groups,
)
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -7,13 +7,11 @@ module DiscoursePoll
end
def validate_post
min_trust_level = SiteSetting.poll_minimum_trust_level_to_create
if (
@post.acting_user &&
(
@post.acting_user.staff? ||
@post.acting_user.trust_level >= TrustLevel[min_trust_level]
@post.acting_user.in_any_groups?(SiteSetting.poll_create_allowed_groups_map)
)
) || @post.topic&.pm_with_non_human_user?
true

View File

@ -206,6 +206,10 @@ after_initialize do
end
end
add_to_serializer(:current_user, :can_create_poll) do
scope.user&.staff? || scope.user&.in_any_groups?(SiteSetting.poll_create_allowed_groups_map)
end
add_to_class(PostSerializer, :preloaded_polls) do
@preloaded_polls ||=
if @topic_view.present?

View File

@ -33,6 +33,8 @@ RSpec.describe ::DiscoursePoll::PollsController do
)
end
before { Group.refresh_automatic_groups! }
describe "#vote" do
it "works" do
channel = "/polls/#{poll.topic_id}"

View File

@ -376,7 +376,7 @@ RSpec.describe PostsController do
end
describe "regular user with insufficient trust level" do
before { SiteSetting.poll_minimum_trust_level_to_create = 2 }
before { SiteSetting.poll_create_allowed_groups = Group::AUTO_GROUPS[:trust_level_2] }
it "invalidates the post" do
log_in_user(Fabricate(:user, trust_level: 1, refresh_auto_groups: true))
@ -409,7 +409,7 @@ RSpec.describe PostsController do
end
describe "regular user with equal trust level" do
before { SiteSetting.poll_minimum_trust_level_to_create = 2 }
before { SiteSetting.poll_create_allowed_groups = Group::AUTO_GROUPS[:trust_level_2] }
it "validates the post" do
log_in_user(Fabricate(:user, trust_level: 2, refresh_auto_groups: true))
@ -424,7 +424,7 @@ RSpec.describe PostsController do
end
describe "regular user with superior trust level" do
before { SiteSetting.poll_minimum_trust_level_to_create = 2 }
before { SiteSetting.poll_create_allowed_groups = Group::AUTO_GROUPS[:trust_level_2] }
it "validates the post" do
log_in_user(Fabricate(:user, trust_level: 3, refresh_auto_groups: true))
@ -439,7 +439,7 @@ RSpec.describe PostsController do
end
describe "staff with insufficient trust level" do
before { SiteSetting.poll_minimum_trust_level_to_create = 2 }
before { SiteSetting.poll_create_allowed_groups = Group::AUTO_GROUPS[:trust_level_2] }
it "validates the post" do
log_in_user(Fabricate(:user, moderator: true, trust_level: 1))
@ -454,7 +454,7 @@ RSpec.describe PostsController do
end
describe "staff editing posts of users with insufficient trust level" do
before { SiteSetting.poll_minimum_trust_level_to_create = 2 }
before { SiteSetting.poll_create_allowed_groups = Group::AUTO_GROUPS[:trust_level_2] }
it "validates the post" do
log_in_user(Fabricate(:user, trust_level: 1, refresh_auto_groups: true))

View File

@ -7,7 +7,7 @@ RSpec.describe NewPostManager do
let(:admin) { Fabricate(:admin, refresh_auto_groups: true) }
describe "when new post containing a poll is queued for approval" do
before { SiteSetting.poll_minimum_trust_level_to_create = 0 }
before { SiteSetting.poll_create_allowed_groups = Group::AUTO_GROUPS[:trust_level_0] }
let(:params) do
{

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe DiscoursePoll::Poll do
fab!(:user)
fab!(:user) { Fabricate(:user, refresh_auto_groups: true) }
fab!(:user_2) { Fabricate(:user) }
fab!(:post_with_regular_poll) { Fabricate(:post, raw: <<~RAW) }

View File

@ -38,7 +38,7 @@ RSpec.describe ::DiscoursePoll::Poll do
end
it "author can see results when results setting is on_vote" do
author = Fabricate(:user)
author = Fabricate(:user, refresh_auto_groups: true)
post = Fabricate(:post, user: author, raw: "[poll results=on_vote]\n- A\n- B\n[/poll]")
poll = post.polls.first
option = poll.poll_options.first
@ -60,7 +60,7 @@ RSpec.describe ::DiscoursePoll::Poll do
it "only staff members can see results when results setting is staff_only" do
post = Fabricate(:post, raw: "[poll results=staff_only]\n- A\n- B\n[/poll]")
user = Fabricate(:user)
user = Fabricate(:user, refresh_auto_groups: true)
poll = post.polls.first
option = poll.poll_options.first
@ -74,7 +74,7 @@ RSpec.describe ::DiscoursePoll::Poll do
describe "when post is trashed" do
it "maintains the association" do
user = Fabricate(:user)
user = Fabricate(:user, refresh_auto_groups: true)
post = Fabricate(:post, raw: "[poll results=staff_only]\n- A\n- B\n[/poll]", user: user)
poll = post.polls.first

View File

@ -1,4 +1,5 @@
import { test } from "qunit";
import { AUTO_GROUPS } from "discourse/lib/constants";
import {
acceptance,
exists,
@ -10,11 +11,16 @@ acceptance("Poll Builder - polls are disabled", function (needs) {
needs.user();
needs.settings({
poll_enabled: false,
poll_minimum_trust_level_to_create: 2,
poll_create_allowed_groups: AUTO_GROUPS.trust_level_2,
});
test("regular user - sufficient trust level", async function (assert) {
updateCurrentUser({ moderator: false, admin: false, trust_level: 3 });
test("regular user - sufficient permissions", async function (assert) {
updateCurrentUser({
moderator: false,
admin: false,
trust_level: 3,
can_create_poll: true,
});
await displayPollBuilderButton();
@ -24,8 +30,13 @@ acceptance("Poll Builder - polls are disabled", function (needs) {
);
});
test("regular user - insufficient trust level", async function (assert) {
updateCurrentUser({ moderator: false, admin: false, trust_level: 1 });
test("regular user - insufficient permissions", async function (assert) {
updateCurrentUser({
moderator: false,
admin: false,
trust_level: 1,
can_create_poll: false,
});
await displayPollBuilderButton();

View File

@ -1,5 +1,6 @@
import { click } from "@ember/test-helpers";
import { test } from "qunit";
import { AUTO_GROUPS } from "discourse/lib/constants";
import {
acceptance,
exists,
@ -12,11 +13,16 @@ acceptance("Poll Builder - polls are enabled", function (needs) {
needs.user();
needs.settings({
poll_enabled: true,
poll_minimum_trust_level_to_create: 1,
poll_create_allowed_groups: AUTO_GROUPS.trust_level_1,
});
test("regular user - sufficient trust level", async function (assert) {
updateCurrentUser({ moderator: false, admin: false, trust_level: 1 });
updateCurrentUser({
moderator: false,
admin: false,
trust_level: 1,
can_create_poll: true,
});
await displayPollBuilderButton();
@ -49,7 +55,12 @@ acceptance("Poll Builder - polls are enabled", function (needs) {
});
test("regular user - insufficient trust level", async function (assert) {
updateCurrentUser({ moderator: false, admin: false, trust_level: 0 });
updateCurrentUser({
moderator: false,
admin: false,
trust_level: 0,
can_create_poll: false,
});
await displayPollBuilderButton();

View File

@ -6,7 +6,9 @@ module Styleguide
skip_before_action :check_xhr
def index
ensure_admin if SiteSetting.styleguide_admin_only
if !current_user || !current_user.in_any_groups?(SiteSetting.styleguide_allowed_groups_map)
raise Discourse::InvalidAccess.new
end
render "default/empty"
end

View File

@ -2,3 +2,4 @@ en:
site_settings:
styleguide_enabled: 'Enable a "/styleguide" path to aid in styling of Discourse'
styleguide_admin_only: "Limits visibility of the styleguide to admins"
styleguide_allowed_groups: "Limits visibility of the styleguide to members of the provided groups"

View File

@ -3,3 +3,11 @@ plugins:
default: false
styleguide_admin_only:
default: true
hidden: true
styleguide_allowed_groups:
default: "1" # auto group admins
type: group_list
client: false
allow_any: false
refresh: true
validator: "AtLeastOneGroupValidator"

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
class FillStyleguideAdminOnlyGroups < ActiveRecord::Migration[7.0]
def up
old_setting =
DB.query_single(
"SELECT value FROM site_settings WHERE name = 'styleguide_admin_only' LIMIT 1",
).first
if old_setting.present?
allowed_groups = old_setting == "t" ? "1" : "14" # use admins AUTO_GROUP if true, otherwise default to TL4
DB.exec(
"INSERT INTO site_settings(name, value, data_type, created_at, updated_at)
VALUES('styleguide_allowed_groups', :setting, '20', NOW(), NOW())",
setting: allowed_groups,
)
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -1,10 +1,10 @@
# frozen_string_literal: true
RSpec.describe "SiteSetting.styleguide_admin_only" do
RSpec.describe "SiteSetting.styleguide_allowed_groups" do
before { SiteSetting.styleguide_enabled = true }
context "when styleguide is admin only" do
before { SiteSetting.styleguide_admin_only = true }
before { SiteSetting.styleguide_allowed_groups = Group::AUTO_GROUPS[:admins] }
context "when user is admin" do
before { sign_in(Fabricate(:admin)) }