From b848ba3867d64056945f9b4f137a6ac94597b264 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Misty=20De=20M=C3=A9o?= <mistydemeo@gmail.com>
Date: Wed, 19 Jul 2023 00:02:49 -0700
Subject: [PATCH] Paperclip: add support for Azure blob storage (#23607)

---
 Gemfile                                       |  1 +
 Gemfile.lock                                  | 17 ++++++++++++++++
 app/helpers/application_helper.rb             |  2 +-
 .../initializers/content_security_policy.rb   |  1 +
 config/initializers/paperclip.rb              | 20 +++++++++++++++++++
 5 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/Gemfile b/Gemfile
index 0746970664..fcd10c5f9b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -18,6 +18,7 @@ gem 'aws-sdk-s3', '~> 1.123', require: false
 gem 'fog-core', '<= 2.4.0'
 gem 'fog-openstack', '~> 0.3', require: false
 gem 'kt-paperclip', '~> 7.2'
+gem 'md-paperclip-azure', '~> 2.2', require: false
 gem 'blurhash', '~> 0.1'
 
 gem 'active_model_serializers', '~> 0.10'
diff --git a/Gemfile.lock b/Gemfile.lock
index a75746355a..63a9388ee2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -118,6 +118,14 @@ GEM
       aws-sigv4 (~> 1.6)
     aws-sigv4 (1.6.0)
       aws-eventstream (~> 1, >= 1.0.2)
+    azure-storage-blob (2.0.3)
+      azure-storage-common (~> 2.0)
+      nokogiri (~> 1, >= 1.10.8)
+    azure-storage-common (2.0.4)
+      faraday (~> 1.0)
+      faraday_middleware (~> 1.0, >= 1.0.0.rc1)
+      net-http-persistent (~> 4.0)
+      nokogiri (~> 1, >= 1.10.8)
     bcrypt (3.1.18)
     better_errors (2.10.1)
       erubi (>= 1.0.0)
@@ -261,6 +269,8 @@ GEM
     faraday-patron (1.0.0)
     faraday-rack (1.0.0)
     faraday-retry (1.0.3)
+    faraday_middleware (1.2.0)
+      faraday (~> 1.0)
     fast_blank (1.0.1)
     fastimage (2.2.7)
     ffi (1.15.5)
@@ -410,6 +420,10 @@ GEM
     mario-redis-lock (1.2.1)
       redis (>= 3.0.5)
     matrix (0.4.2)
+    md-paperclip-azure (2.2.0)
+      addressable (~> 2.5)
+      azure-storage-blob (~> 2.0.1)
+      hashie (~> 5.0)
     memory_profiler (1.0.1)
     method_source (1.0.0)
     mime-types (3.4.1)
@@ -423,6 +437,8 @@ GEM
     multipart-post (2.3.0)
     net-http (0.3.2)
       uri
+    net-http-persistent (4.0.2)
+      connection_pool (~> 2.2)
     net-imap (0.3.6)
       date
       net-protocol
@@ -822,6 +838,7 @@ DEPENDENCIES
   link_header (~> 0.0)
   lograge (~> 0.12)
   mario-redis-lock (~> 1.2)
+  md-paperclip-azure (~> 2.2)
   memory_profiler
   mime-types (~> 3.4.1)
   net-http (~> 0.3.2)
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 281219186f..5f9d7e7c48 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -235,6 +235,6 @@ module ApplicationHelper
   private
 
   def storage_host_var
-    ENV.fetch('S3_ALIAS_HOST', nil) || ENV.fetch('S3_CLOUDFRONT_HOST', nil)
+    ENV.fetch('S3_ALIAS_HOST', nil) || ENV.fetch('S3_CLOUDFRONT_HOST', nil) || ENV.fetch('AZURE_ALIAS_HOST', nil)
   end
 end
diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb
index adc9adcc31..4cc9c204db 100644
--- a/config/initializers/content_security_policy.rb
+++ b/config/initializers/content_security_policy.rb
@@ -15,6 +15,7 @@ assets_host ||= host_to_url(base_host)
 
 media_host   = host_to_url(ENV['S3_ALIAS_HOST'])
 media_host ||= host_to_url(ENV['S3_CLOUDFRONT_HOST'])
+media_host ||= host_to_url(ENV['AZURE_ALIAS_HOST'])
 media_host ||= host_to_url(ENV['S3_HOSTNAME']) if ENV['S3_ENABLED'] == 'true'
 media_host ||= assets_host
 
diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb
index f2da410dbe..12d8d69341 100644
--- a/config/initializers/paperclip.rb
+++ b/config/initializers/paperclip.rb
@@ -131,6 +131,26 @@ elsif ENV['SWIFT_ENABLED'] == 'true'
     fog_host: ENV['SWIFT_OBJECT_URL'],
     fog_public: true
   )
+elsif ENV['AZURE_ENABLED'] == 'true'
+  require 'paperclip-azure'
+
+  Paperclip::Attachment.default_options.merge!(
+    storage: :azure,
+    azure_options: {
+      protocol: 'https',
+    },
+    azure_credentials: {
+      storage_account_name: ENV['AZURE_STORAGE_ACCOUNT'],
+      storage_access_key: ENV['AZURE_STORAGE_ACCESS_KEY'],
+      container: ENV['AZURE_CONTAINER_NAME'],
+    }
+  )
+  if ENV.has_key?('AZURE_ALIAS_HOST')
+    Paperclip::Attachment.default_options.merge!(
+      url: ':azure_alias_url',
+      azure_host_alias: ENV['AZURE_ALIAS_HOST']
+    )
+  end
 else
   Paperclip::Attachment.default_options.merge!(
     storage: :filesystem,
-- 
GitLab