FEATURE: Site setting/UI to allow users to set their primary group (#8244)

* FEATURE: Site setting/ui to allow users to set their primary group

* prettier and remove logic from account template

* added 1 to 43 to make web_hook_user_serializer_spec pass
This commit is contained in:
Mark VanLandingham 2019-10-28 12:46:27 -05:00 committed by GitHub
parent 0e1c5c6bba
commit 4eb54f08b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 115 additions and 6 deletions

View File

@ -17,7 +17,7 @@ export default Controller.extend(CanCheckEmails, PreferencesTabController, {
init() {
this._super(...arguments);
this.saveAttrNames = ["name", "title"];
this.saveAttrNames = ["name", "title", "primary_group_id"];
this.set("revoking", {});
},
@ -26,6 +26,7 @@ export default Controller.extend(CanCheckEmails, PreferencesTabController, {
newNameInput: null,
newTitleInput: null,
newPrimaryGroupInput: null,
passwordProgress: null,
@ -55,6 +56,14 @@ export default Controller.extend(CanCheckEmails, PreferencesTabController, {
canSelectTitle: Ember.computed.gt("model.availableTitles.length", 0),
@computed("model.filteredGroups")
canSelectPrimaryGroup(primaryGroupOptions) {
return (
primaryGroupOptions.length > 0 &&
this.siteSettings.user_selected_primary_groups
);
},
@computed("model.is_anonymous")
canChangePassword(isAnonymous) {
if (isAnonymous) {
@ -131,7 +140,8 @@ export default Controller.extend(CanCheckEmails, PreferencesTabController, {
this.model.setProperties({
name: this.newNameInput,
title: this.newTitleInput
title: this.newTitleInput,
primary_group_id: this.newPrimaryGroupInput
});
return this.model

View File

@ -266,7 +266,8 @@ const User = RestModel.extend({
"tracked_tags",
"watched_tags",
"watching_first_post_tags",
"date_of_birth"
"date_of_birth",
"primary_group_id"
];
const data = this.getProperties(

View File

@ -21,7 +21,8 @@ export default RestrictedUserRoute.extend({
controller.setProperties({
model: user,
newNameInput: user.get("name"),
newTitleInput: user.get("title")
newTitleInput: user.get("title"),
newPrimaryGroupInput: user.get("primary_group_id")
});
},

View File

@ -149,6 +149,19 @@
</div>
{{/if}}
{{#if canSelectPrimaryGroup}}
<div class="control-group pref-primary-group">
<label class="control-label">{{i18n 'user.primary_group.title'}}</label>
<div class="controls">
{{combo-box
value=newPrimaryGroupInput
content=model.filteredGroups
none="user.primary_group.none"}}
</div>
</div>
{{/if}}
{{#if canCheckEmails}}
<div class="control-group pref-auth-tokens">
<label class="control-label">{{i18n 'user.auth_tokens.title'}}</label>

View File

@ -1429,7 +1429,8 @@ class UsersController < ApplicationController
:website,
:dismissed_banner_key,
:profile_background_upload_url,
:card_background_upload_url
:card_background_upload_url,
:primary_group_id
]
editable_custom_fields = User.editable_user_custom_fields(by_staff: current_user.try(:staff?))

View File

@ -72,6 +72,7 @@ class UserSerializer < BasicUserSerializer
:profile_view_count,
:time_read,
:recent_time_read,
:primary_group_id,
:primary_group_name,
:primary_group_flair_url,
:primary_group_flair_bg_color,

View File

@ -82,6 +82,14 @@ class UserUpdater
user.title = attributes[:title]
end
if SiteSetting.user_selected_primary_groups &&
attributes[:primary_group_id] &&
attributes[:primary_group_id] != user.primary_group_id &&
guardian.can_use_primary_group?(user, attributes[:primary_group_id])
user.primary_group_id = attributes[:primary_group_id]
end
CATEGORY_IDS.each do |attribute, level|
if ids = attributes[attribute]
CategoryUser.batch_set(user, level, ids)

View File

@ -1300,6 +1300,9 @@ en:
title:
title: "Title"
none: "(none)"
primary_group:
title: "Primary Group"
none: "(none)"
filters:
all: "All"

View File

@ -1928,6 +1928,8 @@ en:
clean_up_inactive_users_after_days: "Number of days before an inactive user (trust level 0 without any posts) is removed. To disable clean up set to 0."
user_selected_primary_groups: "Allow users to set their own primary group"
user_website_domains_whitelist: "User website will be verified against these domains. Pipe-delimited list."
allow_profile_backgrounds: "Allow users to upload profile backgrounds."

View File

@ -575,6 +575,9 @@ users:
default: 730
min: 0
max: 3650
user_selected_primary_groups:
default: false
client: true
groups:
enable_group_directory:

View File

@ -316,6 +316,14 @@ class Guardian
user.groups.where(title: title).exists?
end
def can_use_primary_group?(user, group_id = nil)
return false if !user || !group_id
group = Group.find_by(id: group_id.to_i)
user.group_ids.include?(group_id.to_i) &&
(group ? !group.automatic : false)
end
def can_change_primary_group?(user)
user && is_staff?
end

View File

@ -2378,6 +2378,39 @@ describe Guardian do
end
end
describe 'can_use_primary_group?' do
fab!(:group) { Fabricate(:group, title: 'Groupie') }
it 'is false without a logged in user' do
expect(Guardian.new(nil).can_use_primary_group?(user)).to be_falsey
end
it 'is false with no group_id' do
user.update(groups: [group])
expect(Guardian.new(user).can_use_primary_group?(user, nil)).to be_falsey
end
it 'is false if the group does not exist' do
user.update(groups: [group])
expect(Guardian.new(user).can_use_primary_group?(user, Group.last.id + 1)).to be_falsey
end
it 'is false if the user is not a part of the group' do
user.update(groups: [])
expect(Guardian.new(user).can_use_primary_group?(user, group.id)).to be_falsey
end
it 'is false if the group is automatic' do
user.update(groups: [Group.new(name: 'autooo', automatic: true)])
expect(Guardian.new(user).can_use_primary_group?(user, group.id)).to be_falsey
end
it 'is true if the user is a part of the group, and the group is custom' do
user.update(groups: [group])
expect(Guardian.new(user).can_use_primary_group?(user, group.id)).to be_truthy
end
end
describe 'can_change_trust_level?' do
it 'is false without a logged in user' do

View File

@ -23,7 +23,7 @@ RSpec.describe WebHookUserSerializer do
it 'should only include the required keys' do
count = serializer.as_json.keys.count
difference = count - 43
difference = count - 44
expect(difference).to eq(0), lambda {
message = ""

View File

@ -249,6 +249,31 @@ describe UserUpdater do
end
end
context 'when updating primary group' do
let(:new_group) { Group.create(name: 'new_group') }
let(:user) { Fabricate(:user) }
it 'updates when setting is enabled' do
SiteSetting.user_selected_primary_groups = true
user.groups << new_group
user.update(primary_group_id: nil)
UserUpdater.new(acting_user, user).update(primary_group_id: new_group.id)
user.reload
expect(user.primary_group_id).to eq new_group.id
end
it 'does not update when setting is disabled' do
SiteSetting.user_selected_primary_groups = false
user.groups << new_group
user.update(primary_group_id: nil)
UserUpdater.new(acting_user, user).update(primary_group_id: new_group.id)
user.reload
expect(user.primary_group_id).to eq nil
end
end
context 'when update fails' do
it 'returns false' do
user = Fabricate(:user)