FEATURE: new bootstrap mode settings for brand new Discourse community (#4193)
* FEATURE: new bootstrap mode settings for brand new Discourse community * new SiteSetting.set_and_log method
This commit is contained in:
parent
6c5548c2e4
commit
74b3807f60
|
@ -17,6 +17,14 @@ export default Ember.Component.extend(StringBuffer, {
|
|||
notices.push([I18n.t("emails_are_disabled"), 'alert-emails-disabled']);
|
||||
}
|
||||
|
||||
if (this.currentUser && this.currentUser.get('staff') && this.siteSettings.bootstrap_mode_enabled) {
|
||||
if (this.siteSettings.bootstrap_mode_min_users > 0) {
|
||||
notices.push([I18n.t("bootstrap_mode_enabled", {min_users: this.siteSettings.bootstrap_mode_min_users}), 'alert-bootstrap-mode']);
|
||||
} else {
|
||||
notices.push([I18n.t("bootstrap_mode_disabled"), 'alert-bootstrap-mode']);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_.isEmpty(this.siteSettings.global_notice)) {
|
||||
notices.push([this.siteSettings.global_notice, 'alert-global-notice']);
|
||||
}
|
||||
|
|
|
@ -10,9 +10,7 @@ class Admin::SiteSettingsController < Admin::AdminController
|
|||
value = params[id]
|
||||
value.strip! if value.is_a?(String)
|
||||
begin
|
||||
prev_value = SiteSetting.send(id)
|
||||
SiteSetting.set(id, value)
|
||||
StaffActionLogger.new(current_user).log_site_setting_change(id, prev_value, value) if SiteSetting.has_setting?(id)
|
||||
SiteSetting.set_and_log(id, value, current_user)
|
||||
render nothing: true
|
||||
rescue Discourse::InvalidParameters => e
|
||||
render json: {errors: [e.message]}, status: 422
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
module Jobs
|
||||
class EnableBootstrapMode < Jobs::Base
|
||||
sidekiq_options queue: 'critical'
|
||||
|
||||
def execute(args)
|
||||
raise Discourse::InvalidParameters.new(:user_id) unless args[:user_id].present?
|
||||
return if SiteSetting.bootstrap_mode_enabled
|
||||
|
||||
user = User.find_by(id: args[:user_id])
|
||||
return unless user.is_singular_admin?
|
||||
|
||||
# let's enable bootstrap mode settings
|
||||
SiteSetting.set_and_log('default_trust_level', TrustLevel[1])
|
||||
SiteSetting.set_and_log('default_email_digest_frequency', 1440)
|
||||
SiteSetting.set_and_log('bootstrap_mode_enabled', true)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
module Jobs
|
||||
class DisableBootstrapMode < Jobs::Scheduled
|
||||
every 1.day
|
||||
|
||||
def execute(args)
|
||||
return unless SiteSetting.bootstrap_mode_enabled
|
||||
total_users = User.where.not(id: Discourse::SYSTEM_USER_ID).count
|
||||
|
||||
if SiteSetting.bootstrap_mode_min_users == 0 || total_users > SiteSetting.bootstrap_mode_min_users
|
||||
SiteSetting.set_and_log('default_trust_level', TrustLevel[0])
|
||||
SiteSetting.set_and_log('default_email_digest_frequency', 10080)
|
||||
SiteSetting.set_and_log('bootstrap_mode_enabled', false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -845,6 +845,10 @@ class User < ActiveRecord::Base
|
|||
custom_fields["master_id"].to_i > 0
|
||||
end
|
||||
|
||||
def is_singular_admin?
|
||||
User.where(admin: true).where.not(id: id).where.not(id: Discourse::SYSTEM_USER_ID).blank?
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def badge_grant
|
||||
|
|
|
@ -147,6 +147,9 @@ en:
|
|||
|
||||
emails_are_disabled: "All outgoing email has been globally disabled by an administrator. No email notifications of any kind will be sent."
|
||||
|
||||
bootstrap_mode_enabled: "To make launching your new site easier, you are in bootstrap mode. All new users will be granted trust level 1 and have daily email digest updates enabled. This will be automatically turned off when total user count exceeds %{min_users} users."
|
||||
bootstrap_mode_disabled: "Bootstrap mode will be disabled in next 24 hours."
|
||||
|
||||
s3:
|
||||
regions:
|
||||
us_east_1: "US East (N. Virginia)"
|
||||
|
|
|
@ -1272,6 +1272,8 @@ en:
|
|||
|
||||
delete_drafts_older_than_n_days: Delete drafts older than (n) days.
|
||||
|
||||
bootstrap_mode_min_users: "Minimum number of users required to disable bootstrap mode (set to 0 to disable)"
|
||||
|
||||
vacuum_db_days: "Run VACUUM ANALYZE to reclaim DB space after migrations (set to 0 to disable)"
|
||||
|
||||
prevent_anons_from_downloading_files: "Prevent anonymous users from downloading attachments. WARNING: this will prevent any non-image site assets posted as attachments from working."
|
||||
|
|
|
@ -1090,6 +1090,17 @@ uncategorized:
|
|||
default: -1
|
||||
hidden: true
|
||||
|
||||
bootstrap_mode_min_users:
|
||||
default: 50
|
||||
client: true
|
||||
min: 0
|
||||
max: 5000
|
||||
|
||||
bootstrap_mode_enabled:
|
||||
default: false
|
||||
client: true
|
||||
hidden: true
|
||||
|
||||
automatically_unpin_topics:
|
||||
default: true
|
||||
client: true
|
||||
|
|
|
@ -68,6 +68,7 @@ class Auth::DefaultCurrentUserProvider
|
|||
end
|
||||
cookies.permanent[TOKEN_COOKIE] = { value: user.auth_token, httponly: true }
|
||||
make_developer_admin(user)
|
||||
enable_bootstrap_mode(user)
|
||||
@env[CURRENT_USER_KEY] = user
|
||||
end
|
||||
|
||||
|
@ -81,6 +82,10 @@ class Auth::DefaultCurrentUserProvider
|
|||
end
|
||||
end
|
||||
|
||||
def enable_bootstrap_mode(user)
|
||||
Jobs.enqueue(:enable_bootstrap_mode, user_id: user.id) if user.admin && user.last_seen_at.nil? && !SiteSetting.bootstrap_mode_enabled && user.is_singular_admin?
|
||||
end
|
||||
|
||||
def log_off_user(session, cookies)
|
||||
if SiteSetting.log_out_strict && (user = current_user)
|
||||
user.auth_token = nil
|
||||
|
|
|
@ -371,6 +371,12 @@ module SiteSettingExtension
|
|||
end
|
||||
end
|
||||
|
||||
def set_and_log(name, value, user=Discourse.system_user)
|
||||
prev_value = send(name)
|
||||
set(name, value)
|
||||
StaffActionLogger.new(user).log_site_setting_change(name, prev_value, value) if has_setting?(name)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def clear_cache!
|
||||
|
|
|
@ -64,7 +64,7 @@ describe CategoriesController do
|
|||
expect(category.slug).to eq("hello-cat")
|
||||
expect(category.color).to eq("ff0")
|
||||
expect(category.auto_close_hours).to eq(72)
|
||||
expect(UserHistory.count).to eq(1)
|
||||
expect(UserHistory.count).to eq(4) # 1 + 3 (bootstrap mode)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -228,7 +228,7 @@ describe CategoriesController do
|
|||
"everyone" => CategoryGroup.permission_types[:create_post]
|
||||
}
|
||||
|
||||
expect(UserHistory.count).to eq(2)
|
||||
expect(UserHistory.count).to eq(5) # 2 + 3 (bootstrap mode)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -77,9 +77,8 @@ describe UploadsController do
|
|||
end
|
||||
|
||||
it 'correctly sets retain_hours for admins' do
|
||||
Jobs.expects(:enqueue).with(:create_thumbnails, anything)
|
||||
|
||||
log_in :admin
|
||||
Jobs.expects(:enqueue).with(:create_thumbnails, anything)
|
||||
|
||||
message = MessageBus.track_publish do
|
||||
xhr :post, :create, file: logo, retain_hours: 100, type: "profile_background"
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Jobs::DisableBootstrapMode do
|
||||
|
||||
context '.execute' do
|
||||
let(:admin) { Fabricate(:admin) }
|
||||
|
||||
before do
|
||||
SiteSetting.bootstrap_mode_enabled = true
|
||||
end
|
||||
|
||||
it 'does not execute if bootstrap mode is already disabled' do
|
||||
SiteSetting.bootstrap_mode_enabled = false
|
||||
StaffActionLogger.any_instance.expects(:log_site_setting_change).never
|
||||
Jobs::DisableBootstrapMode.new.execute(user_id: admin.id)
|
||||
end
|
||||
|
||||
it 'turns off bootstrap mode if bootstrap_mode_min_users is set to 0' do
|
||||
SiteSetting.bootstrap_mode_min_users = 0
|
||||
StaffActionLogger.any_instance.expects(:log_site_setting_change).times(3)
|
||||
Jobs::DisableBootstrapMode.new.execute(user_id: admin.id)
|
||||
end
|
||||
|
||||
it 'successfully turns off bootstrap mode' do
|
||||
SiteSetting.bootstrap_mode_min_users = 5
|
||||
6.times do
|
||||
Fabricate(:user)
|
||||
end
|
||||
StaffActionLogger.any_instance.expects(:log_site_setting_change).times(3)
|
||||
Jobs::DisableBootstrapMode.new.execute(user_id: admin.id)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Jobs::EnableBootstrapMode do
|
||||
|
||||
context '.execute' do
|
||||
let(:admin) { Fabricate(:admin) }
|
||||
|
||||
before do
|
||||
SiteSetting.bootstrap_mode_enabled = false
|
||||
end
|
||||
|
||||
it 'raises an error when user_id is missing' do
|
||||
expect { Jobs::EnableBootstrapMode.new.execute({}) }.to raise_error(Discourse::InvalidParameters)
|
||||
end
|
||||
|
||||
it 'does not execute if bootstrap mode is already enabled' do
|
||||
SiteSetting.bootstrap_mode_enabled = true
|
||||
StaffActionLogger.any_instance.expects(:log_site_setting_change).never
|
||||
Jobs::EnableBootstrapMode.new.execute(user_id: admin.id)
|
||||
end
|
||||
|
||||
it 'does not turn on bootstrap mode if first admin already exists' do
|
||||
first_admin = Fabricate(:admin)
|
||||
StaffActionLogger.any_instance.expects(:log_site_setting_change).never
|
||||
Jobs::EnableBootstrapMode.new.execute(user_id: admin.id)
|
||||
end
|
||||
|
||||
it 'successfully turns on bootstrap mode' do
|
||||
StaffActionLogger.any_instance.expects(:log_site_setting_change).times(3)
|
||||
Jobs::EnableBootstrapMode.new.execute(user_id: admin.id)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -330,6 +330,20 @@ describe User do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.is_singular_admin?' do
|
||||
it 'returns true if user is singular admin' do
|
||||
admin = Fabricate(:admin)
|
||||
expect(admin.is_singular_admin?).to eq(true)
|
||||
end
|
||||
|
||||
it 'returns false if user is not the only admin' do
|
||||
admin = Fabricate(:admin)
|
||||
second_admin = Fabricate(:admin)
|
||||
|
||||
expect(admin.is_singular_admin?).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'name heuristics' do
|
||||
it 'is able to guess a decent name from an email' do
|
||||
expect(User.suggest_name('sam.saffron@gmail.com')).to eq('Sam Saffron')
|
||||
|
|
Loading…
Reference in New Issue