FEATURE: `group_removes_trust_level` setting

By default in Discourse, if a group grants a user a particular trust
level that is locked even if they are removed from the group.

With this new setting, when a user is removed from a group their
trust level is set to either the next highest trust level based on group
membership, or they are unlocked and promoted based on the default
mechanisms.
This commit is contained in:
Robin Ward 2017-11-23 12:58:46 -05:00
parent 613f4d737a
commit ad07e6e172
3 changed files with 88 additions and 1 deletions

View File

@ -8,7 +8,7 @@ class GroupUser < ActiveRecord::Base
after_destroy :remove_title after_destroy :remove_title
after_save :set_primary_group after_save :set_primary_group
after_destroy :remove_primary_group after_destroy :remove_primary_group, :recalculate_trust_level
before_create :set_notification_level before_create :set_notification_level
after_save :grant_trust_level after_save :grant_trust_level
@ -67,6 +67,30 @@ class GroupUser < ActiveRecord::Base
return if group.grant_trust_level.nil? return if group.grant_trust_level.nil?
TrustLevelGranter.grant(group.grant_trust_level, user) TrustLevelGranter.grant(group.grant_trust_level, user)
end end
def recalculate_trust_level
return if group.grant_trust_level.nil?
return unless SiteSetting.group_removes_trust_level?
# Find the highest level of the user's remaining groups
highest_level = GroupUser
.where(user_id: user.id)
.includes(:group)
.maximum("groups.grant_trust_level")
if highest_level.nil?
# If the user no longer has a group with a trust level,
# unlock them, start at 0 and consider promotions.
user.trust_level_locked = false
user.trust_level = 0
user.save
Promotion.new(user).review
else
user.change_trust_level!(highest_level)
end
end
end end
# == Schema Information # == Schema Information

View File

@ -908,6 +908,8 @@ trust:
tl3_links_no_follow: tl3_links_no_follow:
default: false default: false
client: true client: true
group_removes_trust_level:
default: false
security: security:
force_https: force_https:

View File

@ -468,6 +468,67 @@ describe Group do
expect(u3.reload.trust_level).to eq(3) expect(u3.reload.trust_level).to eq(3)
end end
describe "group_removes_trust_level" do
context "set to false" do
before do
SiteSetting.group_removes_trust_level = false
end
it "maintains the chosen trust level" do
g0 = Fabricate(:group, grant_trust_level: 2)
g1 = Fabricate(:group, grant_trust_level: 3)
user = Fabricate(:user, trust_level: 0)
g0.add(user)
expect(user.reload.trust_level).to eq(2)
g1.add(user)
expect(user.reload.trust_level).to eq(3)
g1.remove(user)
expect(user.reload.trust_level).to eq(3)
g0.remove(user)
expect(user.reload.trust_level).to eq(3)
end
end
context "set to true" do
before do
SiteSetting.group_removes_trust_level = true
end
it "adjusts the user trust level" do
g0 = Fabricate(:group, grant_trust_level: 2)
g1 = Fabricate(:group, grant_trust_level: 3)
g2 = Fabricate(:group)
# Add a group without one to consider `NULL` check
g2.add(user)
user = Fabricate(:user, trust_level: 0)
g0.add(user)
expect(user.reload.trust_level).to eq(2)
expect(user.trust_level_locked?).to eq(true)
g1.add(user)
expect(user.reload.trust_level).to eq(3)
expect(user.trust_level_locked?).to eq(true)
g1.remove(user)
expect(user.reload.trust_level).to eq(2)
expect(user.trust_level_locked?).to eq(true)
g0.remove(user)
expect(user.reload.trust_level).to eq(0)
expect(user.trust_level_locked?).to eq(false)
end
end
end
it 'should cook the bio' do it 'should cook the bio' do
group = Fabricate(:group) group = Fabricate(:group)
group.update_attributes!(bio_raw: 'This is a group for :unicorn: lovers') group.update_attributes!(bio_raw: 'This is a group for :unicorn: lovers')