From bf21e79494e093b4c84425b8492a4aebebb420da Mon Sep 17 00:00:00 2001 From: Sergei Tsoganov Date: Fri, 12 Jan 2024 11:43:09 +0200 Subject: [PATCH] Encrypted auth info cache --- app/controllers/application_controller.rb | 48 +++++++++++++++-------- lib/encryptor.rb | 24 ++++++++++++ 2 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 lib/encryptor.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 495f840a..6485d0a5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -29,9 +29,7 @@ def logged_in? def sign_out session[:uuid] = nil - Rails.cache.instance_variable_get(:@data)&.each_key do |key| - Rails.cache.delete(key) unless key.match?(/distribution_data|growth_rate_data/) - end + clear_cache end def sign_in(uuid) @@ -77,14 +75,10 @@ def respond(msg, dialog: false) def store_auth_info(token:, request_ip:, data:) uuid = SecureRandom.uuid - Rails.cache.write(uuid, { username: data[:username], - registrar_name: data[:registrar_name], - role: data[:roles].first, - legaldoc_mandatory: data[:legaldoc_mandatory], - address_processing: data[:address_processing], - token: token, - request_ip: request_ip, - abilities: data[:abilities] }, expires_in: 18.hours) + data = construct_auth_info(token, request_ip, data) + encrypted_data = Encryptor.encrypt(data.to_json) + Rails.cache.write(uuid, encrypted_data, expires_in: 18.hours) + uuid end @@ -129,16 +123,38 @@ def respond_turbo_stream(msg, dialog) flash.now[:alert] = msg turbo_stream_render = if dialog - turbo_stream.update_all('.dialog_flash', partial: 'common/dialog_flash') - else - turbo_stream.update('flash', partial: 'common/flash') - end + turbo_stream.update_all('.dialog_flash', partial: 'common/dialog_flash') + else + turbo_stream.update('flash', partial: 'common/flash') + end render turbo_stream: turbo_stream_render end + def construct_auth_info(token, request_ip, data) + { + username: data[:username], + registrar_name: data[:registrar_name], + role: data[:roles].first, + legaldoc_mandatory: data[:legaldoc_mandatory], + address_processing: data[:address_processing], + token: token, request_ip: request_ip, + abilities: data[:abilities] + } + end + def auth_info - Rails.cache.fetch(session[:uuid])&.symbolize_keys + cached_data = Rails.cache.fetch(session[:uuid]) || '' + decrypted_data = Encryptor.decrypt(cached_data) + return unless decrypted_data + + JSON.parse(decrypted_data).symbolize_keys + end + + def clear_cache + Rails.cache.instance_variable_get(:@data)&.each_key do |key| + Rails.cache.delete(key) unless key.match?(/distribution_data|growth_rate_data/) + end end def default_url_options diff --git a/lib/encryptor.rb b/lib/encryptor.rb new file mode 100644 index 00000000..6e92620b --- /dev/null +++ b/lib/encryptor.rb @@ -0,0 +1,24 @@ +# lib/encryptor.rb +class Encryptor + class << self + def encrypt(value) + encryptor.encrypt_and_sign(value) + end + + def decrypt(value) + encryptor.decrypt_and_verify(value) + rescue ActiveSupport::MessageVerifier::InvalidSignature, ActiveSupport::MessageEncryptor::InvalidMessage + nil + end + + private + + def encryptor + @encryptor ||= begin + secret_key_base = Rails.application.secret_key_base + key = ActiveSupport::KeyGenerator.new(secret_key_base).generate_key('', 32) + ActiveSupport::MessageEncryptor.new(key) + end + end + end +end