From 7d441e378285fa37431ab49a001fc57eb75bb469 Mon Sep 17 00:00:00 2001 From: Jeff Wong Date: Sun, 6 Oct 2024 22:46:58 +0900 Subject: [PATCH] FIX: skips caching a generated secret key base token if `skip_redis` is true. (#29029) Allows for `SKIP_DB_AND_REDIS` env var to be used without a secret key setup in global setting env. --- app/models/global_setting.rb | 17 +++++++++++------ spec/models/global_setting_spec.rb | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/app/models/global_setting.rb b/app/models/global_setting.rb index 6e06e18039e..e58134e7d75 100644 --- a/app/models/global_setting.rb +++ b/app/models/global_setting.rb @@ -18,6 +18,7 @@ class GlobalSetting # This method will # - use existing token if already set in ENV or discourse.conf # - generate a token on the fly if needed and cache in redis + # - skips caching generated token to redis if redis is skipped # - enforce rules about token format falling back to redis if needed def self.safe_secret_key_base if @safe_secret_key_base && @token_in_redis && @@ -31,13 +32,17 @@ class GlobalSetting begin token = secret_key_base if token.blank? || token !~ VALID_SECRET_KEY - @token_in_redis = true - @token_last_validated = Time.now - - token = Discourse.redis.without_namespace.get(REDIS_SECRET_KEY) - unless token && token =~ VALID_SECRET_KEY + if GlobalSetting.skip_redis? token = SecureRandom.hex(64) - Discourse.redis.without_namespace.set(REDIS_SECRET_KEY, token) + else + @token_in_redis = true + @token_last_validated = Time.now + + token = Discourse.redis.without_namespace.get(REDIS_SECRET_KEY) + unless token && token =~ VALID_SECRET_KEY + token = SecureRandom.hex(64) + Discourse.redis.without_namespace.set(REDIS_SECRET_KEY, token) + end end end if !secret_key_base.blank? && token != secret_key_base diff --git a/spec/models/global_setting_spec.rb b/spec/models/global_setting_spec.rb index 7347fb3c5ac..9b69423fcc4 100644 --- a/spec/models/global_setting_spec.rb +++ b/spec/models/global_setting_spec.rb @@ -46,6 +46,22 @@ RSpec.describe GlobalSetting do new_token = Discourse.redis.without_namespace.get(GlobalSetting::REDIS_SECRET_KEY) expect(new_token).to eq(token) end + + context "when a secret key is not provided and redis is not used" do + before do + GlobalSetting.skip_redis = true + GlobalSetting.stubs(:secret_key_base).returns("") + # Fail tests if redis calls are made + Discourse.stubs(:redis).returns(nil) + end + + it "generates a new random key in memory without redis" do + GlobalSetting.reset_secret_key_base! + token = GlobalSetting.safe_secret_key_base + new_token = GlobalSetting.safe_secret_key_base + expect(new_token).to eq(token) + end + end end describe ".add_default" do