mirror of
https://github.com/discourse/discourse.git
synced 2025-05-30 07:11:34 +08:00
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:

committed by
GitHub

parent
0e1c5c6bba
commit
4eb54f08b2
@ -17,7 +17,7 @@ export default Controller.extend(CanCheckEmails, PreferencesTabController, {
|
|||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
this.saveAttrNames = ["name", "title"];
|
this.saveAttrNames = ["name", "title", "primary_group_id"];
|
||||||
this.set("revoking", {});
|
this.set("revoking", {});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -26,6 +26,7 @@ export default Controller.extend(CanCheckEmails, PreferencesTabController, {
|
|||||||
|
|
||||||
newNameInput: null,
|
newNameInput: null,
|
||||||
newTitleInput: null,
|
newTitleInput: null,
|
||||||
|
newPrimaryGroupInput: null,
|
||||||
|
|
||||||
passwordProgress: null,
|
passwordProgress: null,
|
||||||
|
|
||||||
@ -55,6 +56,14 @@ export default Controller.extend(CanCheckEmails, PreferencesTabController, {
|
|||||||
|
|
||||||
canSelectTitle: Ember.computed.gt("model.availableTitles.length", 0),
|
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")
|
@computed("model.is_anonymous")
|
||||||
canChangePassword(isAnonymous) {
|
canChangePassword(isAnonymous) {
|
||||||
if (isAnonymous) {
|
if (isAnonymous) {
|
||||||
@ -131,7 +140,8 @@ export default Controller.extend(CanCheckEmails, PreferencesTabController, {
|
|||||||
|
|
||||||
this.model.setProperties({
|
this.model.setProperties({
|
||||||
name: this.newNameInput,
|
name: this.newNameInput,
|
||||||
title: this.newTitleInput
|
title: this.newTitleInput,
|
||||||
|
primary_group_id: this.newPrimaryGroupInput
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.model
|
return this.model
|
||||||
|
@ -266,7 +266,8 @@ const User = RestModel.extend({
|
|||||||
"tracked_tags",
|
"tracked_tags",
|
||||||
"watched_tags",
|
"watched_tags",
|
||||||
"watching_first_post_tags",
|
"watching_first_post_tags",
|
||||||
"date_of_birth"
|
"date_of_birth",
|
||||||
|
"primary_group_id"
|
||||||
];
|
];
|
||||||
|
|
||||||
const data = this.getProperties(
|
const data = this.getProperties(
|
||||||
|
@ -21,7 +21,8 @@ export default RestrictedUserRoute.extend({
|
|||||||
controller.setProperties({
|
controller.setProperties({
|
||||||
model: user,
|
model: user,
|
||||||
newNameInput: user.get("name"),
|
newNameInput: user.get("name"),
|
||||||
newTitleInput: user.get("title")
|
newTitleInput: user.get("title"),
|
||||||
|
newPrimaryGroupInput: user.get("primary_group_id")
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -149,6 +149,19 @@
|
|||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/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}}
|
{{#if canCheckEmails}}
|
||||||
<div class="control-group pref-auth-tokens">
|
<div class="control-group pref-auth-tokens">
|
||||||
<label class="control-label">{{i18n 'user.auth_tokens.title'}}</label>
|
<label class="control-label">{{i18n 'user.auth_tokens.title'}}</label>
|
||||||
|
@ -1429,7 +1429,8 @@ class UsersController < ApplicationController
|
|||||||
:website,
|
:website,
|
||||||
:dismissed_banner_key,
|
:dismissed_banner_key,
|
||||||
:profile_background_upload_url,
|
: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?))
|
editable_custom_fields = User.editable_user_custom_fields(by_staff: current_user.try(:staff?))
|
||||||
|
@ -72,6 +72,7 @@ class UserSerializer < BasicUserSerializer
|
|||||||
:profile_view_count,
|
:profile_view_count,
|
||||||
:time_read,
|
:time_read,
|
||||||
:recent_time_read,
|
:recent_time_read,
|
||||||
|
:primary_group_id,
|
||||||
:primary_group_name,
|
:primary_group_name,
|
||||||
:primary_group_flair_url,
|
:primary_group_flair_url,
|
||||||
:primary_group_flair_bg_color,
|
:primary_group_flair_bg_color,
|
||||||
|
@ -82,6 +82,14 @@ class UserUpdater
|
|||||||
user.title = attributes[:title]
|
user.title = attributes[:title]
|
||||||
end
|
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|
|
CATEGORY_IDS.each do |attribute, level|
|
||||||
if ids = attributes[attribute]
|
if ids = attributes[attribute]
|
||||||
CategoryUser.batch_set(user, level, ids)
|
CategoryUser.batch_set(user, level, ids)
|
||||||
|
@ -1300,6 +1300,9 @@ en:
|
|||||||
title:
|
title:
|
||||||
title: "Title"
|
title: "Title"
|
||||||
none: "(none)"
|
none: "(none)"
|
||||||
|
primary_group:
|
||||||
|
title: "Primary Group"
|
||||||
|
none: "(none)"
|
||||||
|
|
||||||
filters:
|
filters:
|
||||||
all: "All"
|
all: "All"
|
||||||
|
@ -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."
|
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."
|
user_website_domains_whitelist: "User website will be verified against these domains. Pipe-delimited list."
|
||||||
|
|
||||||
allow_profile_backgrounds: "Allow users to upload profile backgrounds."
|
allow_profile_backgrounds: "Allow users to upload profile backgrounds."
|
||||||
|
@ -575,6 +575,9 @@ users:
|
|||||||
default: 730
|
default: 730
|
||||||
min: 0
|
min: 0
|
||||||
max: 3650
|
max: 3650
|
||||||
|
user_selected_primary_groups:
|
||||||
|
default: false
|
||||||
|
client: true
|
||||||
|
|
||||||
groups:
|
groups:
|
||||||
enable_group_directory:
|
enable_group_directory:
|
||||||
|
@ -316,6 +316,14 @@ class Guardian
|
|||||||
user.groups.where(title: title).exists?
|
user.groups.where(title: title).exists?
|
||||||
end
|
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)
|
def can_change_primary_group?(user)
|
||||||
user && is_staff?
|
user && is_staff?
|
||||||
end
|
end
|
||||||
|
@ -2378,6 +2378,39 @@ describe Guardian do
|
|||||||
end
|
end
|
||||||
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
|
describe 'can_change_trust_level?' do
|
||||||
|
|
||||||
it 'is false without a logged in user' do
|
it 'is false without a logged in user' do
|
||||||
|
@ -23,7 +23,7 @@ RSpec.describe WebHookUserSerializer do
|
|||||||
|
|
||||||
it 'should only include the required keys' do
|
it 'should only include the required keys' do
|
||||||
count = serializer.as_json.keys.count
|
count = serializer.as_json.keys.count
|
||||||
difference = count - 43
|
difference = count - 44
|
||||||
|
|
||||||
expect(difference).to eq(0), lambda {
|
expect(difference).to eq(0), lambda {
|
||||||
message = ""
|
message = ""
|
||||||
|
@ -249,6 +249,31 @@ describe UserUpdater do
|
|||||||
end
|
end
|
||||||
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
|
context 'when update fails' do
|
||||||
it 'returns false' do
|
it 'returns false' do
|
||||||
user = Fabricate(:user)
|
user = Fabricate(:user)
|
||||||
|
Reference in New Issue
Block a user