diff --git a/app/policies/setting_policy.rb b/app/policies/setting_policy.rb index 66c1a1c6f..843e09b50 100644 --- a/app/policies/setting_policy.rb +++ b/app/policies/setting_policy.rb @@ -13,6 +13,7 @@ class SettingPolicy < ApplicationPolicy private def permitted? + return false if record.preferences[:protected] return true if !record.preferences[:permission] user.permissions?(record.preferences[:permission]) diff --git a/db/migrate/20210830174638_maintenance_improve_setting_preferences.rb b/db/migrate/20210830174638_maintenance_improve_setting_preferences.rb new file mode 100644 index 000000000..f39a1a8ce --- /dev/null +++ b/db/migrate/20210830174638_maintenance_improve_setting_preferences.rb @@ -0,0 +1,15 @@ +# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/ + +class MaintenanceImproveSettingPreferences < ActiveRecord::Migration[6.0] + def change + return if !Setting.exists?(name: 'system_init_done') + + protected_settings = %w[application_secret] + + protected_settings.each do |name| + setting = Setting.find_by(name: name) + setting.preferences[:protected] = true + setting.save! + end + end +end diff --git a/db/seeds/settings.rb b/db/seeds/settings.rb index ae2ff84fe..6704464d5 100644 --- a/db/seeds/settings.rb +++ b/db/seeds/settings.rb @@ -9,6 +9,7 @@ Setting.create_if_not_exists( state: SecureRandom.hex(128), preferences: { permission: ['admin'], + protected: true, }, frontend: false ) diff --git a/spec/db/migrate/maintenance_improve_setting_preferences_spec.rb b/spec/db/migrate/maintenance_improve_setting_preferences_spec.rb new file mode 100644 index 000000000..1630aa0f6 --- /dev/null +++ b/spec/db/migrate/maintenance_improve_setting_preferences_spec.rb @@ -0,0 +1,18 @@ +# Copyright (C) 2012-2021 Zammad Foundation, http://zammad-foundation.org/ + +require 'rails_helper' + +RSpec.describe MaintenanceImproveSettingPreferences, type: :db_migration do + context 'when having old setting preferences without protected flag' do + before do + setting.preferences.delete(:protected) + setting.save! + end + + let(:setting) { Setting.find_by(name: 'application_secret') } + + it 'add protected flag' do + expect { migrate }.to change { setting.reload.preferences[:protected] }.to(true) + end + end +end diff --git a/spec/requests/settings_spec.rb b/spec/requests/settings_spec.rb index dd94b1f66..87cbd92d7 100644 --- a/spec/requests/settings_spec.rb +++ b/spec/requests/settings_spec.rb @@ -225,5 +225,31 @@ RSpec.describe 'Settings', type: :request do expect(response).to have_http_status(:forbidden) expect(json_response['error']).to eq('Not authorized (user)!') end + + it 'protected setting not existing in list' do + authenticated_as(admin) + get '/api/v1/settings', params: {}, as: :json + expect(json_response.detect { |setting| setting['name'] == 'application_secret' }).to eq(nil) + end + + it 'can not show protected setting' do + setting = Setting.find_by(name: 'application_secret') + authenticated_as(admin) + get "/api/v1/settings/#{setting.id}", params: {}, as: :json + expect(response).to have_http_status(:forbidden) + end + + it 'can not update protected setting' do + setting = Setting.find_by(name: 'application_secret') + params = { + id: setting.id, + state: 'Examaple' + } + put "/api/v1/settings/#{setting.id}", params: params, as: :json + + authenticated_as(admin) + put "/api/v1/settings/#{setting.id}", params: {}, as: :json + expect(response).to have_http_status(:forbidden) + end end end