Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Followup fix for cache & global site setttings handling #1525

Merged
merged 9 commits into from
Jan 26, 2025
1 change: 1 addition & 0 deletions app/assets/stylesheets/site_settings.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.site-setting--value {
min-height: 1em;
min-width: 2em;
overflow-wrap: anywhere;
}
63 changes: 56 additions & 7 deletions app/controllers/site_settings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ class SiteSettingsController < ApplicationController
before_action :verify_admin
before_action :verify_global_admin, only: [:global]

# Checks if a given user has access to site settings on a given community
# @param [User] user user to check access for
# @param [String, nil] community_id id of the community to check access on
# @return [Boolean]
def access?(user, community_id)
community_id.present? || user.is_global_admin
end

def index
# The weird argument to sort_by here sorts without throwing errors on nil values -
# see https://stackoverflow.com/a/35539062/3160466. 0:1,c sorts nil last, to switch
Expand All @@ -26,8 +34,41 @@ def show
render json: @setting&.as_json&.merge(typed: @setting.typed)
end

# Adds an audit log for a given site setting update event
# @param [User] user initiating user
# @param [SiteSetting] before current site setting
# @param [SiteSetting] after updated site setting
# @return [void]
def audit_update(user, before, after)
AuditLog.admin_audit(event_type: 'setting_update',
related: after,
user: user,
comment: "from <<SiteSetting #{before}>>\nto <<SiteSetting #{after.attributes_print}>>")
end

# Deletes cache for a given site setting for a given community
# @param [SiteSetting] setting site setting to clear cache for
# @param [String, nil] community_id community id to clear cache for
# @return [Boolean]
def clear_cache(setting, community_id)
Rails.cache.delete("SiteSettings/#{community_id}/#{setting.name}", include_community: false)
end

# Actually creates a given site setting
# @param [SiteSetting] setting site setting to create
# @param [String, nil] community_id community id to create a setting for
# @return [SiteSetting]
def do_create(setting, community_id)
SiteSetting.create(name: setting.name,
community_id: community_id,
value: '',
value_type: setting.value_type,
category: setting.category,
description: setting.description)
end

def update
if params[:community_id].blank? && !current_user.is_global_admin
unless access?(current_user, params[:community_id])
not_found
return
end
Expand All @@ -36,20 +77,28 @@ def update
matches = SiteSetting.unscoped.where(community_id: RequestContext.community_id, name: params[:name])
if matches.count.zero?
global = SiteSetting.unscoped.where(community_id: nil, name: params[:name]).first
SiteSetting.create(name: global.name, community_id: RequestContext.community_id, value: '',
value_type: global.value_type, category: global.category,
description: global.description)
do_create(global, RequestContext.community_id)
else
matches.first
end
else
SiteSetting.unscoped.where(community_id: nil, name: params[:name]).first
end

before = @setting.attributes_print

@setting.update(setting_params)
AuditLog.admin_audit(event_type: 'setting_update', related: @setting, user: current_user,
comment: "from <<SiteSetting #{before}>>\nto <<SiteSetting #{@setting.attributes_print}>>")
Rails.cache.delete "SiteSettings/#{RequestContext.community_id}/#{@setting.name}", include_community: false

audit_update(current_user, before, @setting)

if @setting.global?
Community.all.each do |c|
clear_cache(@setting, c.id)
end
else
clear_cache(@setting, RequestContext.community_id)
end

render json: { status: 'OK', setting: @setting&.as_json&.merge(typed: @setting.typed) }
end

Expand Down
6 changes: 6 additions & 0 deletions app/models/site_setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ def self.exist?(name)
SiteSetting.where(name: name).count.positive?
end

# Checks whether the setting is a global site setting
# @return [Boolean]
def global?
community_id.nil?
end

def typed
SettingConverter.new(value).send("as_#{value_type.downcase}")
end
Expand Down
16 changes: 7 additions & 9 deletions app/views/site_settings/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@
<% settings.each do |setting| %>
<tr>
<td>
<h4>
<%= setting.name %>
<% if setting.community_id.nil? %>
<span class="badge is-tag is-master-tag">global</span>
<% else %>
<span class="badge is-tag">site</span>
<% end %>
<span class="badge is-tag"><%= setting.value_type %></span>
</h4>
<% if setting.global? %>
<span class="badge is-tag is-master-tag">global</span>
<% else %>
<span class="badge is-tag">site</span>
<% end %>
<span class="badge is-tag"><%= setting.value_type %></span>
<h4><%= setting.name %></h4>
<div class="form-caption"><%= setting.description %></div>
</td>
<td class="site-setting--value js-setting-value" data-type="<%= setting.value_type %>" data-name="<%= setting.name %>"
Expand Down
Loading