From 6ddefe7cada5268469561c70a8557cf1545684b2 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Thu, 22 Nov 2018 16:17:08 +0000 Subject: Correctly handle data-loss scenarios when encrypting columns If the EncryptColumns background migration runs in a sidekiq with a stale view of the database schema, or when the purported destination columns don't actually exist, data loss can result. Attempt to work around these issues by reloading schema information before running the migration, and raising errors if the model reports that any of its source or destination columns are missing. --- .../attr_encrypted_no_db_connection.rb | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'config') diff --git a/config/initializers/attr_encrypted_no_db_connection.rb b/config/initializers/attr_encrypted_no_db_connection.rb index e007666b852..7ad458929db 100644 --- a/config/initializers/attr_encrypted_no_db_connection.rb +++ b/config/initializers/attr_encrypted_no_db_connection.rb @@ -1,7 +1,18 @@ module AttrEncrypted module Adapters module ActiveRecord - module DBConnectionQuerier + module GitlabMonkeyPatches + # Prevent attr_encrypted from defining virtual accessors for encryption + # data when the code and schema are out of sync. See this issue for more + # details: https://github.com/attr-encrypted/attr_encrypted/issues/332 + def attribute_instance_methods_as_symbols_available? + false + end + + # Prevent attr_encrypted from checking out a database connection + # indefinitely. The result of this method is only used when the former + # is true, but it is called unconditionally, so there is still value to + # ensuring the connection is released def attribute_instance_methods_as_symbols # Use with_connection so the connection doesn't stay pinned to the thread. connected = ::ActiveRecord::Base.connection_pool.with_connection(&:active?) rescue false @@ -15,7 +26,16 @@ module AttrEncrypted end end end - prepend DBConnectionQuerier end end end + +# As of v3.1.0, the attr_encrypted gem defines the AttrEncrypted and +# AttrEncrypted::Adapters::ActiveRecord modules, and uses "extend" to mix them +# into the ActiveRecord::Base class. This intervention overrides utility methods +# defined by attr_encrypted to fix two bugs, as detailed above. +# +# The methods are used here: https://github.com/attr-encrypted/attr_encrypted/blob/3.1.0/lib/attr_encrypted.rb#L145-158 +ActiveSupport.on_load(:active_record) do + extend AttrEncrypted::Adapters::ActiveRecord::GitlabMonkeyPatches +end -- cgit v1.2.3