mirror of
https://github.com/discourse/discourse.git
synced 2024-11-26 17:53:44 +08:00
FEATUE: automatically validate token is stored in redis
This ensures we have some handling for redis flushall We attempt to recover our in-memory session token once every 30 seconds Code is careful to only set the token if it is nil, to allow for manual cycling to remain safe if needed
This commit is contained in:
parent
82ca0e368e
commit
ef24fd54ba
|
@ -11,6 +11,8 @@ class GlobalSetting
|
|||
# for legacy reasons
|
||||
REDIS_SECRET_KEY = 'SECRET_TOKEN'
|
||||
|
||||
REDIS_VALIDATE_SECONDS = 30
|
||||
|
||||
# In Rails secret_key_base is used to encrypt the cookie store
|
||||
# the cookie store contains session data
|
||||
# Discourse also uses this secret key to digest user auth tokens
|
||||
|
@ -19,9 +21,21 @@ class GlobalSetting
|
|||
# - generate a token on the fly if needed and cache in redis
|
||||
# - 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 && (@token_last_validated + REDIS_VALIDATE_SECONDS) < Time.now
|
||||
token = $redis.without_namespace.get(REDIS_SECRET_KEY)
|
||||
if token.nil?
|
||||
$redis.without_namespace.set(REDIS_SECRET_KEY, @safe_secret_key_base)
|
||||
end
|
||||
end
|
||||
|
||||
@safe_secret_key_base ||= begin
|
||||
token = secret_key_base
|
||||
if token.blank? || token !~ VALID_SECRET_KEY
|
||||
|
||||
@token_in_redis = true
|
||||
@token_last_validated = Time.now
|
||||
|
||||
token = $redis.without_namespace.get(REDIS_SECRET_KEY)
|
||||
unless token && token =~ VALID_SECRET_KEY
|
||||
token = SecureRandom.hex(64)
|
||||
|
|
|
@ -2,6 +2,27 @@ require 'rails_helper'
|
|||
require 'tempfile'
|
||||
|
||||
describe GlobalSetting do
|
||||
|
||||
describe '.safe_secret_key_base' do
|
||||
it 'sets redis token if it is somehow flushed after 30 seconds' do
|
||||
token = GlobalSetting.safe_secret_key_base
|
||||
$redis.without_namespace.del(GlobalSetting::REDIS_SECRET_KEY)
|
||||
freeze_time 20.seconds.from_now
|
||||
|
||||
GlobalSetting.safe_secret_key_base
|
||||
new_token = $redis.without_namespace.get(GlobalSetting::REDIS_SECRET_KEY)
|
||||
expect(new_token).to eq(nil)
|
||||
|
||||
freeze_time 31.seconds.from_now
|
||||
|
||||
GlobalSetting.safe_secret_key_base
|
||||
|
||||
new_token = $redis.without_namespace.get(GlobalSetting::REDIS_SECRET_KEY)
|
||||
expect(new_token).to eq(token)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe '.redis_config' do
|
||||
describe 'when slave config is not present' do
|
||||
it "should not set any connector" do
|
||||
|
|
Loading…
Reference in New Issue
Block a user