From 20e832d5593474d44cbf73206c54efc5a43a4b67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com>
Date: Fri, 6 Jan 2023 12:04:27 +0100
Subject: [PATCH] service + task

---
 app/services/active_storage_key_converter.rb | 19 +++++++++++++
 app/services/blocks_migration.rb             | 30 ++++++++++++++++++++
 lib/tasks/app.rake                           |  1 +
 3 files changed, 50 insertions(+)
 create mode 100644 app/services/active_storage_key_converter.rb
 create mode 100644 app/services/blocks_migration.rb

diff --git a/app/services/active_storage_key_converter.rb b/app/services/active_storage_key_converter.rb
new file mode 100644
index 000000000..1e5c643e3
--- /dev/null
+++ b/app/services/active_storage_key_converter.rb
@@ -0,0 +1,19 @@
+class ActiveStorageKeyConverter
+  def self.convert(legacy_signed_id)
+    # Try to find blob with the un-modified legacy_signed_id
+    blob = ActiveStorage::Blob.find_signed!(legacy_signed_id)
+    legacy_signed_id
+  rescue ActiveSupport::MessageVerifier::InvalidSignature
+    #
+    key_generator = ActiveSupport::KeyGenerator.new(
+      Rails.application.secrets.secret_key_base,
+      iterations: 1000,
+      hash_digest_class: OpenSSL::Digest::SHA1
+    )
+    key_generator = ActiveSupport::CachingKeyGenerator.new(key_generator)
+    secret = key_generator.generate_key("ActiveStorage")
+    verifier = ActiveSupport::MessageVerifier.new(secret)
+
+    ActiveStorage::Blob.find_by_id(verifier.verify(legacy_signed_id, purpose: :blob_id)).try(:signed_id)
+  end
+end
diff --git a/app/services/blocks_migration.rb b/app/services/blocks_migration.rb
new file mode 100644
index 000000000..95dfcf032
--- /dev/null
+++ b/app/services/blocks_migration.rb
@@ -0,0 +1,30 @@
+class BlocksMigration
+
+  def self.cleanup
+    Communication::Block.all.find_each { |block|
+      self.crawl(block.data)
+      block.save
+    }
+  end
+
+  protected
+
+  def self.crawl(enumerable)
+    case enumerable
+    when Array
+      enumerable.each do |item|
+        crawl(item) if [Array, Hash].include?(item.class)
+      end
+    when Hash
+      enumerable.keys.each do |key|
+        if key == "signed_id"
+          # Convert value
+          enumerable[key] = ActiveStorageKeyConverter.convert(enumerable[key]) if key == "signed_id"
+        elsif [Array, Hash].include?(enumerable[key].class)
+          crawl(enumerable[key])
+        end
+      end
+    end
+  end
+
+end
\ No newline at end of file
diff --git a/lib/tasks/app.rake b/lib/tasks/app.rake
index edf86d1e7..b3c536e31 100644
--- a/lib/tasks/app.rake
+++ b/lib/tasks/app.rake
@@ -8,6 +8,7 @@ namespace :app do
 
   desc 'Fix things'
   task fix: :environment do
+    BlocksMigration.cleanup
   end
 
   namespace :websites do
-- 
GitLab