mirror of
https://github.com/discourse/discourse.git
synced 2025-10-03 17:21:20 +08:00
FEATURE: Add site setting to prevent mods from changing trust levels
This commit is contained in:
parent
2b7835d02a
commit
6128a0736d
9 changed files with 106 additions and 28 deletions
|
@ -2,7 +2,7 @@ import { fn, hash } from "@ember/helper";
|
||||||
import { LinkTo } from "@ember/routing";
|
import { LinkTo } from "@ember/routing";
|
||||||
import { htmlSafe } from "@ember/template";
|
import { htmlSafe } from "@ember/template";
|
||||||
import RouteTemplate from "ember-route-template";
|
import RouteTemplate from "ember-route-template";
|
||||||
import { and, gt } from "truth-helpers";
|
import { and, gt, not } from "truth-helpers";
|
||||||
import ConditionalLoadingSpinner from "discourse/components/conditional-loading-spinner";
|
import ConditionalLoadingSpinner from "discourse/components/conditional-loading-spinner";
|
||||||
import DButton from "discourse/components/d-button";
|
import DButton from "discourse/components/d-button";
|
||||||
import PluginOutlet from "discourse/components/plugin-outlet";
|
import PluginOutlet from "discourse/components/plugin-outlet";
|
||||||
|
@ -476,10 +476,14 @@ export default RouteTemplate(
|
||||||
<div class="field">{{i18n "trust_level"}}</div>
|
<div class="field">{{i18n "trust_level"}}</div>
|
||||||
<div class="value">
|
<div class="value">
|
||||||
<ComboBox
|
<ComboBox
|
||||||
|
class="change-trust-level-dropdown"
|
||||||
@content={{@controller.site.trustLevels}}
|
@content={{@controller.site.trustLevels}}
|
||||||
@nameProperty="detailedName"
|
@nameProperty="detailedName"
|
||||||
@value={{@controller.model.trustLevel.id}}
|
@value={{@controller.model.trustLevel.id}}
|
||||||
@onChange={{fn (mut @controller.model.trust_level)}}
|
@onChange={{fn (mut @controller.model.trust_level)}}
|
||||||
|
@options={{hash
|
||||||
|
disabled=(not @controller.model.can_change_trust_level)
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{{#if @controller.model.dirty}}
|
{{#if @controller.model.dirty}}
|
||||||
|
@ -498,6 +502,7 @@ export default RouteTemplate(
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
|
{{#if @controller.model.can_change_trust_level}}
|
||||||
{{#if @controller.model.canLockTrustLevel}}
|
{{#if @controller.model.canLockTrustLevel}}
|
||||||
{{#if @controller.hasLockedTrustLevel}}
|
{{#if @controller.hasLockedTrustLevel}}
|
||||||
{{icon "lock" title="admin.user.trust_level_locked_tip"}}
|
{{icon "lock" title="admin.user.trust_level_locked_tip"}}
|
||||||
|
@ -524,6 +529,7 @@ export default RouteTemplate(
|
||||||
{{i18n "admin.user.trust_level_3_requirements"}}
|
{{i18n "admin.user.trust_level_3_requirements"}}
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ class AdminUserSerializer < AdminUserListSerializer
|
||||||
:can_activate,
|
:can_activate,
|
||||||
:can_deactivate,
|
:can_deactivate,
|
||||||
:can_approve,
|
:can_approve,
|
||||||
|
:can_change_trust_level,
|
||||||
:ip_address,
|
:ip_address,
|
||||||
:registration_ip_address,
|
:registration_ip_address,
|
||||||
:include_ip
|
:include_ip
|
||||||
|
@ -33,6 +34,10 @@ class AdminUserSerializer < AdminUserListSerializer
|
||||||
scope.can_deactivate?(object)
|
scope.can_deactivate?(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_change_trust_level
|
||||||
|
scope.can_change_trust_level?(object)
|
||||||
|
end
|
||||||
|
|
||||||
def ip_address
|
def ip_address
|
||||||
object.ip_address.try(:to_s)
|
object.ip_address.try(:to_s)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1931,6 +1931,7 @@ en:
|
||||||
top_page_default_timeframe: "Default top page time period for anonymous users (automatically adjusts for logged in users based on their last visit)."
|
top_page_default_timeframe: "Default top page time period for anonymous users (automatically adjusts for logged in users based on their last visit)."
|
||||||
moderators_view_emails: "Allow moderators to view user email addresses."
|
moderators_view_emails: "Allow moderators to view user email addresses."
|
||||||
moderators_view_ips: "Allow moderators to view user ip addresses."
|
moderators_view_ips: "Allow moderators to view user ip addresses."
|
||||||
|
moderators_change_trust_levels: "Allow moderators to change user trust levels."
|
||||||
prioritize_username_in_ux: "Show username first on user page, user card and posts (when disabled name is shown first)"
|
prioritize_username_in_ux: "Show username first on user page, user card and posts (when disabled name is shown first)"
|
||||||
enable_rich_text_paste: "Enable automatic HTML to Markdown conversion when pasting text into the composer."
|
enable_rich_text_paste: "Enable automatic HTML to Markdown conversion when pasting text into the composer."
|
||||||
send_old_credential_reminder_days: "Remind about old credentials after days"
|
send_old_credential_reminder_days: "Remind about old credentials after days"
|
||||||
|
|
|
@ -2588,6 +2588,8 @@ security:
|
||||||
moderators_view_ips:
|
moderators_view_ips:
|
||||||
default: true
|
default: true
|
||||||
client: true
|
client: true
|
||||||
|
moderators_change_trust_levels:
|
||||||
|
default: true
|
||||||
non_crawler_user_agents:
|
non_crawler_user_agents:
|
||||||
hidden: true
|
hidden: true
|
||||||
default: "trident|webkit|gecko|chrome|safari|msie|opera|goanna|discourse"
|
default: "trident|webkit|gecko|chrome|safari|msie|opera|goanna|discourse"
|
||||||
|
|
|
@ -397,7 +397,7 @@ class Guardian
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_change_trust_level?(user)
|
def can_change_trust_level?(user)
|
||||||
user && is_staff?
|
user && (is_admin? || (is_moderator? && SiteSetting.moderators_change_trust_levels))
|
||||||
end
|
end
|
||||||
|
|
||||||
# Support sites that have to approve users
|
# Support sites that have to approve users
|
||||||
|
|
|
@ -1038,17 +1038,43 @@ RSpec.describe Admin::UsersController do
|
||||||
|
|
||||||
before { sign_in(admin) }
|
before { sign_in(admin) }
|
||||||
|
|
||||||
|
context "when moderators_change_trust_levels setting is enabled" do
|
||||||
|
before { SiteSetting.moderators_change_trust_levels = true }
|
||||||
|
|
||||||
include_examples "trust level updates possible"
|
include_examples "trust level updates possible"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when moderators_change_trust_levels setting is disabled" do
|
||||||
|
before { SiteSetting.moderators_change_trust_levels = false }
|
||||||
|
|
||||||
|
include_examples "trust level updates possible"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when logged in as a moderator" do
|
context "when logged in as a moderator" do
|
||||||
let(:acting_user) { moderator }
|
let(:acting_user) { moderator }
|
||||||
|
|
||||||
before { sign_in(moderator) }
|
before { sign_in(moderator) }
|
||||||
|
|
||||||
|
context "when moderators_change_trust_levels setting is enabled" do
|
||||||
|
before { SiteSetting.moderators_change_trust_levels = true }
|
||||||
|
|
||||||
include_examples "trust level updates possible"
|
include_examples "trust level updates possible"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when moderators_change_trust_levels setting is disabled" do
|
||||||
|
before { SiteSetting.moderators_change_trust_levels = false }
|
||||||
|
|
||||||
|
it "prevents updates to trust level with a 422 response" do
|
||||||
|
another_user.update(trust_level: TrustLevel[1])
|
||||||
|
put "/admin/users/#{another_user.id}/trust_level.json", params: { level: TrustLevel[0] }
|
||||||
|
|
||||||
|
expect(response.status).to eq(422)
|
||||||
|
expect(another_user.reload.trust_level).to eq(TrustLevel[1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when logged in as a non-staff user" do
|
context "when logged in as a non-staff user" do
|
||||||
before { sign_in(user) }
|
before { sign_in(user) }
|
||||||
|
|
||||||
|
|
|
@ -80,6 +80,9 @@
|
||||||
"can_deactivate": {
|
"can_deactivate": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"can_change_trust_level": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"ip_address": {
|
"ip_address": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
|
|
@ -125,4 +125,30 @@ describe "Admin User Page", type: :system do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when logged in as a moderator" do
|
||||||
|
fab!(:current_user, :moderator)
|
||||||
|
|
||||||
|
context "when visiting a regular user's page" do
|
||||||
|
fab!(:user)
|
||||||
|
|
||||||
|
before { admin_user_page.visit(user) }
|
||||||
|
|
||||||
|
context "when moderators_change_trust_levels setting is enabled" do
|
||||||
|
before { SiteSetting.moderators_change_trust_levels = true }
|
||||||
|
|
||||||
|
it "the dropdown to change trust level is enabled" do
|
||||||
|
expect(admin_user_page).to have_change_trust_level_dropdown_enabled
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when moderators_change_trust_levels setting is disabled" do
|
||||||
|
before { SiteSetting.moderators_change_trust_levels = false }
|
||||||
|
|
||||||
|
it "the dropdown to change trust level is disabled" do
|
||||||
|
expect(admin_user_page).to have_change_trust_level_dropdown_disabled
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,6 +23,15 @@ module PageObjects
|
||||||
has_no_css?(".btn-danger.silence-user")
|
has_no_css?(".btn-danger.silence-user")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_change_trust_level_dropdown_enabled?
|
||||||
|
has_css?(".change-trust-level-dropdown") &&
|
||||||
|
has_no_css?(".change-trust-level-dropdown.is-disabled")
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_change_trust_level_dropdown_disabled?
|
||||||
|
has_css?(".change-trust-level-dropdown.is-disabled")
|
||||||
|
end
|
||||||
|
|
||||||
def click_suspend_button
|
def click_suspend_button
|
||||||
find(".btn-danger.suspend-user").click
|
find(".btn-danger.suspend-user").click
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue