Skip to content

Commit a42a2fe

Browse files
committed
use libgd instead of ImageMagick
In RHEL8+ ImageMagick is no longer provided due to being hard to maintain and prone to security issues. That's why we implement an image processor based on the `libgd` backed `local-fastimage_resize` gem for logo processing instead of the Paperclip's default ImageMagick based processor `Paperclip::Thumbnail`. We remove support for uploading GIF profile logos in the process. Logo is used when generating invoices. But prawn only supports JPEGs and PNGs. With ImageMagick we could specify target format for the `:invoice` style to be `png` regardless of source image format. `local-fastimage_resize` only resizes between same formats though. Provided very low adoption of GIF logos, it is not worth implementing such support for `local-fastimage_resize` although it shouldn't be too hard if need arise. Note: existing attachments don't need to be processed because the `:invoice` style will already be PNG. Make sure NOT to manually re-process all attachments though. Anyway no need to. fixes THREESCALE-8579
1 parent 5485408 commit a42a2fe

14 files changed

Lines changed: 194 additions & 22 deletions

File tree

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,11 @@ gem 'baby_squeel', '~> 1.4.3'
9494
gem 'ransack', '2.4.1' # we can remove line when stop using ruby 2.4
9595
gem 'browser', '~> 5.0.0' # we can update to lts when we stop using ruby 2.4
9696
gem 'diff-lcs', '~> 1.2'
97+
gem 'fastimage'
9798
gem 'hiredis', '~> 0.6.3'
9899
gem 'httpclient', github: 'mikz/httpclient', branch: 'ssl-env-cert'
99100
gem 'json-schema', git: 'https://github.com/3scale/json-schema.git'
101+
gem 'local-fastimage_resize', require: 'fastimage/resize'
100102
gem 'paperclip', '~> 6.0'
101103
gem 'prawn-core', git: 'https://github.com/3scale/prawn.git', branch: '0.5.1-3scale'
102104
gem 'prawn-format', '0.2.1'

Gemfile.lock

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ GEM
351351
multipart-post (>= 1.2, < 3)
352352
faraday_middleware (0.13.1)
353353
faraday (>= 0.7.4, < 1.0)
354+
fastimage (2.2.6)
354355
ffi (1.15.4)
355356
ffi-compiler (1.0.1)
356357
ffi (>= 1.0.0)
@@ -431,6 +432,9 @@ GEM
431432
listen (3.2.1)
432433
rb-fsevent (~> 0.10, >= 0.10.3)
433434
rb-inotify (~> 0.9, >= 0.9.10)
435+
local-fastimage (3.1.3)
436+
local-fastimage_resize (3.4.0)
437+
local-fastimage (~> 3.0)
434438
loofah (2.18.0)
435439
crass (~> 1.0.2)
436440
nokogiri (>= 1.5.9)
@@ -930,6 +934,7 @@ DEPENDENCIES
930934
fakefs (~> 0.18.0)
931935
faraday (~> 0.15.3)
932936
faraday_middleware (~> 0.13.1)
937+
fastimage
933938
font-awesome-rails (~> 4.7.0.5)
934939
formtastic (~> 2.3.1)
935940
github-markdown
@@ -953,6 +958,7 @@ DEPENDENCIES
953958
letter_opener
954959
license_finder (~> 6.12.0)
955960
listen
961+
local-fastimage_resize
956962
mail_view (~> 2.0.4)
957963
mechanize
958964
mimemagic (~> 0.3.10)

INSTALL.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,8 @@ xcode-select —install
112112

113113
```
114114
brew install
115-
brew install chromedriver imagemagick@6 [email protected] gs pkg-config openssl geckodriver postgresql@14 memcached
115+
brew install chromedriver gd [email protected] gs pkg-config openssl geckodriver postgresql@14 memcached
116116
brew link [email protected] --force
117-
brew link imagemagick@6 --force
118117
brew services start [email protected]
119118
```
120119

@@ -240,8 +239,9 @@ asdf install
240239
241240
#### Dependencies
242241
242+
<<<<<<< HEAD
243243
```
244-
sudo yum install patch autoconf automake bison libffi-devel libtool libyaml-devel readline-devel sqlite-devel zlib-devel openssl-devel ImageMagick ImageMagick-devel mysql-devel postgresql-devel chromedriver memcached
244+
sudo yum install patch autoconf automake bison libffi-devel libtool libyaml-devel readline-devel sqlite-devel zlib-devel openssl-devel gd-devel mysql-devel postgresql-devel chromedriver memcached
245245

246246
sudo systemctl restart memcached
247247
```

app/models/profile.rb

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,19 @@ class Profile < ApplicationRecord
4242
belongs_to :account
4343
delegate :s3_provider_prefix, to: :account
4444

45+
LOGO_STYLES = proc do |logo|
46+
dynamic_style = logo.content_type.end_with?("gif") ? ['200x50>'.freeze, :png] : '200x50>'
47+
{large: '300x300>'.freeze, medium: '150x150>'.freeze, thumb: '100x100>'.freeze, invoice: dynamic_style.freeze}.freeze
48+
end
49+
4550
# Profile has attached logo.
4651
has_attached_file :logo,
47-
styles: { large: '300x300>'.freeze, medium: '150x150>'.freeze, thumb: '100x100>'.freeze, invoice: ['200x50>'.freeze, :png].freeze }.freeze,
52+
processors: [:g_d_image_processor],
53+
styles: LOGO_STYLES,
4854
:url => ':url_root/:account_id/:class/:attachment/:style/:basename.:extension'.freeze,
4955
:s3_permissions => 'public-read'.freeze,
5056
:default_url => '/assets/3scale-logo.png'.freeze
51-
validates_attachment_content_type :logo, content_type: %r{^image\/(png|gif|jpeg)}
52-
57+
validates_attachment_content_type :logo, content_type: %r{^image\/(png|jpeg)}, if: :will_save_change_to_logo?
5358

5459
# Find only published profiles.
5560
scope :published, -> { where(:state => 'published') }
@@ -117,6 +122,10 @@ def fix_http str
117122

118123
delegate :provider_id_for_audits, :to => :account, :allow_nil => true
119124

125+
def will_save_change_to_logo?
126+
logo.dirty?
127+
end
128+
120129
private
121130

122131
#issue 7486981, this is needed since Account accepts_nested_attrs from profile
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# frozen_string_literal: true
2+
3+
module Paperclip
4+
class GDImageProcessor < Processor
5+
def make
6+
original_geometry = Geometry.new(*FastImage.size(file))
7+
computed_geometry = original_geometry.resize_to(target_geometry_str)
8+
file.rewind
9+
original_geometry.to_s[/\d+x\d+/] == computed_geometry.to_s[/\d+x\d+/] ? temp_copy(file) : FastImage.resize(file, computed_geometry.width, computed_geometry.height)
10+
end
11+
12+
private
13+
14+
def target_geometry_str
15+
options.fetch(:geometry)
16+
end
17+
18+
def temp_copy(uploaded_file)
19+
file = Tempfile.new(["copy", File.extname(uploaded_file.path)])
20+
File.copy_stream(uploaded_file, file)
21+
uploaded_file.rewind
22+
file.rewind
23+
file
24+
end
25+
end
26+
end

lib/tasks/fixes.rake

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,17 @@ namespace :fixes do
113113
end
114114
end
115115

116+
desc "Regenerate JPEG logos :invoice style"
117+
task :regenerate_jpeg_invoice_logo => :environment do
118+
Profile.where(logo_content_type: "image/jpeg").find_each do |profile|
119+
begin
120+
profile.logo.reprocess!(:invoice)
121+
rescue => exception
122+
Rails.logger.error("Failed to reprocess invoice logo for #{profile.account_id}: #{exception.message}")
123+
end
124+
end
125+
end
126+
116127
desc "Checks for cinstances with zero plan_id and associats them with the Default plan"
117128
task :zero_plan_id => :environment do
118129
Cinstance.find_each do |cinstance|

openshift/system/Dockerfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ RUN yum-config-manager --save --setopt=cbs.centos.org_repos_sclo7-rh-ruby26-rh-c
1616
&& yum -y update \
1717
&& yum remove -y postgresql \
1818
&& yum -y install centos-release-scl-rh \
19-
ImageMagick \
20-
ImageMagick-devel \
19+
gd-devel \
2120
unixODBC-devel \
2221
mysql \
2322
postgresql10 postgresql10-devel postgresql10-libs \

test/fixtures/small.gif

41 Bytes
Loading

test/fixtures/small.png

76 Bytes
Loading

test/fixtures/wide.png

3.48 KB
Loading

0 commit comments

Comments
 (0)