FIX: moderators can add/remove group owners (#10960)
If `SiteSetting.moderators_manage_categories_and_groups` is enabled, a moderator shoud be able to add/remove group owners.
This commit is contained in:
parent
5597aeb1b9
commit
a74805d3f8
|
@ -23,7 +23,7 @@ export default DropdownSelectBoxComponent.extend({
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
if (this.get("currentUser.admin")) {
|
if (this.canAdminGroup) {
|
||||||
if (this.member.owner) {
|
if (this.member.owner) {
|
||||||
items.push({
|
items.push({
|
||||||
id: "removeOwner",
|
id: "removeOwner",
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
{{#if canManageGroup}}
|
{{#if canManageGroup}}
|
||||||
{{group-member-dropdown
|
{{group-member-dropdown
|
||||||
member=m
|
member=m
|
||||||
|
canAdminGroup=model.can_admin_group
|
||||||
onChange=(action "actOnGroup" m)
|
onChange=(action "actOnGroup" m)
|
||||||
}}
|
}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
{{#if canManageGroup}}
|
{{#if canManageGroup}}
|
||||||
{{group-member-dropdown
|
{{group-member-dropdown
|
||||||
member=user
|
member=user
|
||||||
|
canAdminGroup=model.can_admin_group
|
||||||
onChange=(action "actOnGroup" user)
|
onChange=(action "actOnGroup" user)
|
||||||
}}
|
}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
id="group-add-members-user-selector"}}
|
id="group-add-members-user-selector"}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if currentUser.admin}}
|
{{#if model.can_admin_group}}
|
||||||
<div class="control-group group-add-members-make-owner">
|
<div class="control-group group-add-members-make-owner">
|
||||||
<label>
|
<label>
|
||||||
{{input type="checkbox"
|
{{input type="checkbox"
|
||||||
|
|
|
@ -256,3 +256,33 @@ test("Admin Viewing Group", async (assert) => {
|
||||||
"it should display the group name"
|
"it should display the group name"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Moderator Viewing Group", async (assert) => {
|
||||||
|
await visit("/g/alternative-group");
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
find(".nav-pills li a[title='Manage']").length === 1,
|
||||||
|
"it should show manage group tab if user can_admin_group"
|
||||||
|
);
|
||||||
|
|
||||||
|
await click(".group-members-add.btn");
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
find(".group-add-members-modal .group-add-members-make-owner"),
|
||||||
|
"it allows moderators to set group owners"
|
||||||
|
);
|
||||||
|
|
||||||
|
await click(".group-add-members-modal .modal-close");
|
||||||
|
|
||||||
|
const memberDropdown = selectKit(".group-member-dropdown:first");
|
||||||
|
await memberDropdown.expand();
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
memberDropdown.rowByIndex(0).name(),
|
||||||
|
I18n.t("groups.members.remove_member")
|
||||||
|
);
|
||||||
|
assert.equal(
|
||||||
|
memberDropdown.rowByIndex(1).name(),
|
||||||
|
I18n.t("groups.members.make_owner")
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
|
@ -1295,5 +1295,33 @@ export default {
|
||||||
extras: {
|
extras: {
|
||||||
visible_group_names: ["alternative-group"]
|
visible_group_names: ["alternative-group"]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/groups/alternative-group/members.json": {
|
||||||
|
owners: [],
|
||||||
|
members: [
|
||||||
|
{
|
||||||
|
id: 2770,
|
||||||
|
username: "awesomerobot",
|
||||||
|
uploaded_avatar_id: 33872,
|
||||||
|
avatar_template:
|
||||||
|
"/user_avatar/meta.discourse.org/awesomerobot/{size}/33872.png",
|
||||||
|
name: "",
|
||||||
|
last_seen_at: "2015-01-23T15:53:17.844Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 32,
|
||||||
|
username: "codinghorror",
|
||||||
|
uploaded_avatar_id: 5297,
|
||||||
|
avatar_template:
|
||||||
|
"/user_avatar/meta.discourse.org/codinghorror/{size}/5297.png",
|
||||||
|
name: "Jeff Atwood",
|
||||||
|
last_seen_at: "2015-01-23T06:05:25.457Z"
|
||||||
|
},
|
||||||
|
],
|
||||||
|
meta: {
|
||||||
|
total: 2,
|
||||||
|
limit: 50,
|
||||||
|
offset: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,6 +90,8 @@ class Admin::GroupsController < Admin::AdminController
|
||||||
raise Discourse::NotFound unless group
|
raise Discourse::NotFound unless group
|
||||||
|
|
||||||
return can_not_modify_automatic if group.automatic
|
return can_not_modify_automatic if group.automatic
|
||||||
|
guardian.ensure_can_edit_group!(group)
|
||||||
|
|
||||||
users = User.where(username: group_params[:usernames].split(","))
|
users = User.where(username: group_params[:usernames].split(","))
|
||||||
|
|
||||||
users.each do |user|
|
users.each do |user|
|
||||||
|
@ -117,6 +119,7 @@ class Admin::GroupsController < Admin::AdminController
|
||||||
raise Discourse::NotFound unless group
|
raise Discourse::NotFound unless group
|
||||||
|
|
||||||
return can_not_modify_automatic if group.automatic
|
return can_not_modify_automatic if group.automatic
|
||||||
|
guardian.ensure_can_edit_group!(group)
|
||||||
|
|
||||||
user = User.find(params[:user_id].to_i)
|
user = User.find(params[:user_id].to_i)
|
||||||
group.group_users.where(user_id: user.id).update_all(owner: false)
|
group.group_users.where(user_id: user.id).update_all(owner: false)
|
||||||
|
|
|
@ -91,7 +91,12 @@ Discourse::Application.routes.draw do
|
||||||
get "reports/bulk" => "reports#bulk"
|
get "reports/bulk" => "reports#bulk"
|
||||||
get "reports/:type" => "reports#show"
|
get "reports/:type" => "reports#show"
|
||||||
|
|
||||||
resources :groups, only: [:create]
|
resources :groups, only: [:create] do
|
||||||
|
member do
|
||||||
|
put "owners" => "groups#add_owners"
|
||||||
|
delete "owners" => "groups#remove_owner"
|
||||||
|
end
|
||||||
|
end
|
||||||
resources :groups, except: [:create], constraints: AdminConstraint.new do
|
resources :groups, except: [:create], constraints: AdminConstraint.new do
|
||||||
collection do
|
collection do
|
||||||
get 'bulk'
|
get 'bulk'
|
||||||
|
@ -99,10 +104,6 @@ Discourse::Application.routes.draw do
|
||||||
put 'bulk' => 'groups#bulk_perform'
|
put 'bulk' => 'groups#bulk_perform'
|
||||||
put "automatic_membership_count" => "groups#automatic_membership_count"
|
put "automatic_membership_count" => "groups#automatic_membership_count"
|
||||||
end
|
end
|
||||||
member do
|
|
||||||
put "owners" => "groups#add_owners"
|
|
||||||
delete "owners" => "groups#remove_owner"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
get "groups/:type" => "groups#show", constraints: AdminConstraint.new
|
get "groups/:type" => "groups#show", constraints: AdminConstraint.new
|
||||||
|
|
|
@ -282,4 +282,105 @@ RSpec.describe Admin::GroupsController do
|
||||||
expect(response.parsed_body["user_count"]).to eq(0)
|
expect(response.parsed_body["user_count"]).to eq(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when moderators_manage_categories_and_groups is enabled" do
|
||||||
|
let(:group_params) do
|
||||||
|
{
|
||||||
|
group: {
|
||||||
|
name: 'testing-as-moderator',
|
||||||
|
usernames: [admin.username, user.username].join(","),
|
||||||
|
owner_usernames: [user.username].join(","),
|
||||||
|
allow_membership_requests: true,
|
||||||
|
membership_request_template: 'Testing',
|
||||||
|
members_visibility_level: Group.visibility_levels[:staff]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
SiteSetting.moderators_manage_categories_and_groups = true
|
||||||
|
end
|
||||||
|
|
||||||
|
context "the user is a moderator" do
|
||||||
|
before do
|
||||||
|
user.update!(moderator: true)
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should allow groups to be created' do
|
||||||
|
post "/admin/groups.json", params: group_params
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
group = Group.last
|
||||||
|
|
||||||
|
expect(group.name).to eq('testing-as-moderator')
|
||||||
|
expect(group.users).to contain_exactly(admin, user)
|
||||||
|
expect(group.allow_membership_requests).to eq(true)
|
||||||
|
expect(group.membership_request_template).to eq('Testing')
|
||||||
|
expect(group.members_visibility_level).to eq(Group.visibility_levels[:staff])
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should allow group owners to be added' do
|
||||||
|
put "/admin/groups/#{group.id}/owners.json", params: {
|
||||||
|
group: {
|
||||||
|
usernames: [user.username, admin.username].join(",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
|
||||||
|
response_body = response.parsed_body
|
||||||
|
|
||||||
|
expect(response_body["usernames"]).to contain_exactly(user.username, admin.username)
|
||||||
|
|
||||||
|
expect(group.group_users.where(owner: true).map(&:user))
|
||||||
|
.to contain_exactly(user, admin)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should allow groups owners to be removed' do
|
||||||
|
group.add_owner(user)
|
||||||
|
|
||||||
|
delete "/admin/groups/#{group.id}/owners.json", params: {
|
||||||
|
user_id: user.id
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
expect(group.group_users.where(owner: true)).to eq([])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "the user is not a moderator or admin" do
|
||||||
|
before do
|
||||||
|
user.update!(moderator: false, admin: false)
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not allow groups to be created' do
|
||||||
|
post "/admin/groups.json", params: group_params
|
||||||
|
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not allow group owners to be added' do
|
||||||
|
put "/admin/groups/#{group.id}/owners.json", params: {
|
||||||
|
group: {
|
||||||
|
usernames: [user.username, admin.username].join(",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not allow groups owners to be removed' do
|
||||||
|
group.add_owner(user)
|
||||||
|
|
||||||
|
delete "/admin/groups/#{group.id}/owners.json", params: {
|
||||||
|
user_id: user.id
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(response.status).to eq(404)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue