2026-01-02 13:41:09 +00:00
|
|
|
# Copyright (C) 2012-2026 Zammad Foundation, https://zammad-foundation.org/
|
2013-06-12 15:59:58 +00:00
|
|
|
|
2012-04-10 14:06:46 +00:00
|
|
|
class SettingsController < ApplicationController
|
2023-03-19 20:43:36 +00:00
|
|
|
prepend_before_action :authenticate_and_authorize!
|
2012-04-10 14:06:46 +00:00
|
|
|
|
|
|
|
|
# GET /settings
|
|
|
|
|
def index
|
2026-02-03 13:38:55 +00:00
|
|
|
list = Setting.all.filter { |elem| authorized?(elem, :show?) }
|
|
|
|
|
masked_list = list.map { |object| mask_sensitive_values(object.as_json, object) }
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2026-02-03 13:38:55 +00:00
|
|
|
render json: masked_list, status: :ok
|
2012-04-10 14:06:46 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# GET /settings/1
|
|
|
|
|
def show
|
2012-09-20 12:08:02 +00:00
|
|
|
model_show_render(Setting, params)
|
2012-04-10 14:06:46 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# POST /settings
|
|
|
|
|
def create
|
2021-11-15 15:58:19 +00:00
|
|
|
raise Exceptions::Forbidden, __('Not authorized (feature not possible)')
|
2012-04-10 14:06:46 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# PUT /settings/1
|
|
|
|
|
def update
|
2024-12-13 10:38:15 +00:00
|
|
|
model_update_render(Setting, keep_certain_attributes)
|
2012-04-10 14:06:46 +00:00
|
|
|
end
|
|
|
|
|
|
2015-07-12 01:32:40 +00:00
|
|
|
# PUT /settings/image/:id
|
|
|
|
|
def update_image
|
2024-01-16 11:06:18 +00:00
|
|
|
logo_content = %i[logo logo_resize].each_with_object({}) do |key, memo|
|
|
|
|
|
data = params[key]
|
2015-07-12 01:32:40 +00:00
|
|
|
|
2024-01-16 11:06:18 +00:00
|
|
|
next if !data&.match? %r{^data:image}i
|
|
|
|
|
|
|
|
|
|
file = ImageHelper.data_url_attributes(data)
|
|
|
|
|
|
|
|
|
|
memo[key] = file[:content] if file
|
2015-07-12 01:32:40 +00:00
|
|
|
end
|
|
|
|
|
|
2024-01-16 11:06:18 +00:00
|
|
|
logo_timestamp = Service::SystemAssets::ProductLogo.store(logo_content[:logo], logo_content[:logo_resize])
|
2015-07-12 01:32:40 +00:00
|
|
|
|
2024-01-16 11:06:18 +00:00
|
|
|
if !logo_timestamp
|
2015-07-12 01:32:40 +00:00
|
|
|
render json: {
|
2018-12-19 17:31:51 +00:00
|
|
|
result: 'invalid',
|
2023-06-16 10:09:14 +00:00
|
|
|
message: __('The uploaded image could not be processed. Need data:image in logo or logo_resize param.'),
|
2015-07-12 01:32:40 +00:00
|
|
|
}
|
2024-01-16 11:06:18 +00:00
|
|
|
return
|
2015-07-12 01:32:40 +00:00
|
|
|
end
|
|
|
|
|
|
2024-01-16 11:06:18 +00:00
|
|
|
setting = Setting.lookup(name: 'product_logo')
|
|
|
|
|
setting.state = logo_timestamp
|
|
|
|
|
setting.save!
|
|
|
|
|
|
2015-07-12 01:32:40 +00:00
|
|
|
render json: {
|
2018-12-19 17:31:51 +00:00
|
|
|
result: 'ok',
|
2015-07-12 01:32:40 +00:00
|
|
|
settings: [setting],
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
2012-04-10 14:06:46 +00:00
|
|
|
# DELETE /settings/1
|
|
|
|
|
def destroy
|
2021-11-15 15:58:19 +00:00
|
|
|
raise Exceptions::Forbidden, __('Not authorized (feature not possible)')
|
2012-04-10 14:06:46 +00:00
|
|
|
end
|
2015-07-16 13:36:59 +00:00
|
|
|
|
2023-05-02 10:00:21 +00:00
|
|
|
# POST /settings/reset/1
|
|
|
|
|
def reset
|
|
|
|
|
setting = Setting.find(params[:id])
|
|
|
|
|
Setting.reset(setting.name)
|
|
|
|
|
|
|
|
|
|
setting.reload
|
|
|
|
|
|
|
|
|
|
if response_expand?
|
|
|
|
|
render json: setting.attributes_with_association_names, status: :ok
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if response_full?
|
|
|
|
|
render json: setting.class.full(setting.id), status: :ok
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
render json: setting.attributes_with_association_ids, status: :ok
|
|
|
|
|
end
|
|
|
|
|
|
2015-07-16 13:36:59 +00:00
|
|
|
private
|
|
|
|
|
|
2016-08-26 10:06:27 +00:00
|
|
|
def keep_certain_attributes
|
2015-07-16 13:36:59 +00:00
|
|
|
setting = Setting.find(params[:id])
|
2017-11-23 08:09:44 +00:00
|
|
|
%i[name area state_initial frontend options].each do |key|
|
2016-08-26 10:06:27 +00:00
|
|
|
params.delete(key)
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2017-11-23 08:09:44 +00:00
|
|
|
if params[:preferences].present?
|
|
|
|
|
%i[online_service_disable permission render].each do |key|
|
2016-08-26 15:08:49 +00:00
|
|
|
params[:preferences].delete(key)
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2016-08-26 15:08:49 +00:00
|
|
|
params[:preferences].merge!(setting.preferences)
|
|
|
|
|
end
|
2016-08-26 10:06:27 +00:00
|
|
|
params
|
|
|
|
|
end
|
2026-02-03 13:38:55 +00:00
|
|
|
|
|
|
|
|
# Setting hash value keys matching those partterns are sanitized.
|
|
|
|
|
# Checks inclusion of the substring in the key.
|
|
|
|
|
SENSITIVE_STATE_KEYS = %w[_key token secret bind_pw].freeze
|
|
|
|
|
|
|
|
|
|
# Settings with matching names are sanitized as a whole
|
|
|
|
|
# This is applied to non-boolean settings only!
|
|
|
|
|
# Used for single-value settings that can't be sanitized based on value hash keys.
|
|
|
|
|
# Checks inclusion of the substring in the name
|
|
|
|
|
SENSITIVE_NAMES = %w[_password _secret _key].freeze
|
|
|
|
|
|
|
|
|
|
def sensitive_attributes(object_payload, object)
|
|
|
|
|
return if object.options[:form].try(:one?) && object.options[:form].one? { |elem| elem[:tag] == 'boolean' }
|
|
|
|
|
|
|
|
|
|
if SENSITIVE_NAMES.any? { |elem| object.name.include?(elem) }
|
|
|
|
|
return ['state_current.value']
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
(object_payload.dig('state_current', 'value').try(:keys) || [])
|
|
|
|
|
.select { |elem| elem.end_with?(*SENSITIVE_STATE_KEYS) }
|
|
|
|
|
.map { |elem| "state_current.value.#{elem}" }
|
|
|
|
|
end
|
2012-04-10 14:06:46 +00:00
|
|
|
end
|