From 3449b766ff9e2435553a80fc49f322b9e58d97f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com> Date: Thu, 22 Dec 2022 23:56:12 +0100 Subject: [PATCH] doc migrate blocks data --- app/models/communication/website.rb | 10 ++-- app/models/education/school.rb | 6 ++- config/application.rb | 2 - docs/_rd/digest_upgrade.md | 73 +++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 9 deletions(-) create mode 100644 docs/_rd/digest_upgrade.md diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb index 0d0c46680..aece9ae4f 100644 --- a/app/models/communication/website.rb +++ b/app/models/communication/website.rb @@ -80,11 +80,11 @@ class Communication::Website < ApplicationRecord def git_dependencies(website) dependencies = [self, config_default_languages, config_default_permalinks, config_development_config, config_production_config] + menus - dependencies += pages + pages.map(&:active_storage_blobs).flatten - dependencies += posts + posts.map(&:active_storage_blobs).flatten - dependencies += people_with_facets + people.map(&:active_storage_blobs).flatten - dependencies += organizations_in_blocks + organizations_in_blocks.map(&:active_storage_blobs).flatten - dependencies += categories + dependencies += pages + pages.map(&:active_storage_blobs).flatten + pages.map(&:git_block_dependencies).flatten + dependencies += posts + posts.map(&:active_storage_blobs).flatten + posts.map(&:git_block_dependencies).flatten + dependencies += people_with_facets + people.map(&:active_storage_blobs).flatten + people.map(&:git_block_dependencies).flatten + dependencies += organizations_in_blocks + organizations_in_blocks.map(&:active_storage_blobs).flatten + organizations_in_blocks.map(&:git_block_dependencies).flatten + dependencies += categories + categories.map(&:git_block_dependencies).flatten dependencies += about.git_dependencies(website) if about.present? dependencies end diff --git a/app/models/education/school.rb b/app/models/education/school.rb index 0497ecea9..bf0870ba3 100644 --- a/app/models/education/school.rb +++ b/app/models/education/school.rb @@ -67,8 +67,10 @@ class Education::School < ApplicationRecord def git_dependencies(website) dependencies = [self] dependencies += programs + - programs.map(&:active_storage_blobs).flatten - dependencies += diplomas + programs.map(&:active_storage_blobs).flatten + + programs.map(&:git_block_dependencies).flatten + dependencies += diplomas + + diplomas.map(&:git_block_dependencies).flatten dependencies += teachers + teachers.map(&:teacher) + teachers.map(&:active_storage_blobs).flatten diff --git a/config/application.rb b/config/application.rb index 88f89b56b..03280c119 100644 --- a/config/application.rb +++ b/config/application.rb @@ -53,8 +53,6 @@ module Osuny # Need for +repage, because of https://github.com/rails/rails/commit/b2ab8dd3a4a184f3115e72b55c237c7b66405bd9 config.active_storage.supported_image_processing_methods = ["+"] - config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA1 - config.action_view.sanitized_allowed_tags = [ "a", "abbr", "acronym", "address", "b", "big", "blockquote", "br", "cite", "code", "dd", "del", "dfn", "div", "dl", "dt", "em", diff --git a/docs/_rd/digest_upgrade.md b/docs/_rd/digest_upgrade.md new file mode 100644 index 000000000..decc4b072 --- /dev/null +++ b/docs/_rd/digest_upgrade.md @@ -0,0 +1,73 @@ +# Mise à jour de l'algorithme de génération de clés + +## Préambule + +Avant Rails 7, le générateur de clés `ActiveSupport::KeyGenerator` utilisait l'algorithme SHA1 pour chiffrer des messages. Ce générateur est utilisé dans de multiples cas : +- Les cookies chiffrés (*encrypted cookies*) +- Les attributs chiffrés (*encrypted attributes*) (*Non utilisé par Osuny*) +- Les IDs signés des objets, notamment les blobs d'ActiveStorage +- Les ETags et les clés de cache + +A partir de Rails 7, le générateur de clés utilise SHA256 comme algorithme par défaut, ce qui casse les messages listés précédemment. Pas de vrai problème pour les cookies, les Etags et les clés de cache. Cependant, chaque ID signé de blobs créé avec SHA1 est désormais invalide. Ce qui pose problème dans les blocs qui stockent cet ID signé dans le data JSON ou encore dans l'attribut `direct_url` des fichiers médias des sites web créés avec Osuny. + +Pour les fichiers médias, une mise à jour des sites web va actualiser sans problème. Cependant, il faut un script pour mettre à jour les IDs signés dans les data JSON des blocs. + +## Classe du *rotator* + +### Définition + +```ruby +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 +``` + +### Utilisation + +```ruby +ActiveStorageKeyConverter.convert legacy_signed_id +``` + +## Script pour les blocs + +```ruby + +def 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 + +Communication::Block.all.find_each { |block| + crawl(block.data) + block.save +} +``` \ No newline at end of file -- GitLab