From a5d8dfb07e5362f688344f576160066fd0bfaceb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9gis=20Hanol?= <regis@hanol.fr>
Date: Wed, 6 Apr 2016 22:51:28 +0200
Subject: [PATCH] FIX: don't hardcode maximum file size

---
 app/assets/javascripts/discourse/lib/utilities.js |  9 +++++++--
 app/controllers/uploads_controller.rb             | 12 +++++++-----
 config/locales/client.en.yml                      |  1 -
 config/site_settings.yml                          |  8 ++++++--
 4 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/app/assets/javascripts/discourse/lib/utilities.js b/app/assets/javascripts/discourse/lib/utilities.js
index fa1f063f0..8e85d1c79 100644
--- a/app/assets/javascripts/discourse/lib/utilities.js
+++ b/app/assets/javascripts/discourse/lib/utilities.js
@@ -208,7 +208,7 @@ Discourse.Utilities = {
       if (upload instanceof Blob && !(upload instanceof File) && upload.type === "image/png") { upload.name = "blob.png"; }
     }
 
-    var type = Discourse.Utilities.isAnImage(upload.name) ? 'image' : 'attachment';
+    var type = Discourse.Utilities.uploadTypeFromFileName(upload.name);
 
     return Discourse.Utilities.validateUploadedFile(upload, type, bypassNewUserRestriction);
   },
@@ -234,6 +234,10 @@ Discourse.Utilities = {
     return true;
   },
 
+  uploadTypeFromFileName: function(fileName) {
+    return Discourse.Utilities.isAnImage(fileName) ? 'image' : 'attachment';
+  },
+
   authorizesAllExtensions: function() {
     return Discourse.SiteSettings.authorized_extensions.indexOf("*") >= 0;
   },
@@ -295,7 +299,8 @@ Discourse.Utilities = {
 
         // entity too large, usually returned from the web server
         case 413:
-          var maxSizeKB = 10 * 1024; // 10 MB
+          var type = Discourse.Utilities.uploadTypeFromFileName(data.files[0].name);
+          var maxSizeKB = Discourse.SiteSettings['max_' + type + '_size_kb'];
           bootbox.alert(I18n.t('post.errors.file_too_large', { max_size_kb: maxSizeKB }));
           return;
 
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index f91f70763..07fe29de4 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -51,16 +51,17 @@ class UploadsController < ApplicationController
     render nothing: true, status: 404
   end
 
-  MAXIMUM_UPLOAD_SIZE ||= 10.megabytes
   DOWNSIZE_RATIO ||= 0.8
 
   def create_upload(type, file, url)
     begin
+      maximum_upload_size = [SiteSetting.max_image_size_kb, SiteSetting.max_attachment_size_kb].max.kilobytes
+
       # ensure we have a file
       if file.nil?
         # API can provide a URL
         if url.present? && is_api?
-          tempfile = FileHelper.download(url, MAXIMUM_UPLOAD_SIZE, "discourse-upload-#{type}") rescue nil
+          tempfile = FileHelper.download(url, maximum_upload_size, "discourse-upload-#{type}") rescue nil
           filename = File.basename(URI.parse(url).path)
         end
       else
@@ -72,14 +73,15 @@ class UploadsController < ApplicationController
       return { errors: I18n.t("upload.file_missing") } if tempfile.nil?
 
       # allow users to upload (not that) large images that will be automatically reduced to allowed size
-      if SiteSetting.max_image_size_kb > 0 && FileHelper.is_image?(filename)
+      max_image_size_kb = SiteSetting.max_image_size_kb.kilobytes
+      if max_image_size_kb > 0 && FileHelper.is_image?(filename)
         uploaded_size = File.size(tempfile.path)
-        if 0 < uploaded_size && uploaded_size < MAXIMUM_UPLOAD_SIZE && Upload.should_optimize?(tempfile.path)
+        if 0 < uploaded_size && uploaded_size < maximum_upload_size && Upload.should_optimize?(tempfile.path)
           attempt = 2
           allow_animation = type == "avatar" ? SiteSetting.allow_animated_avatars : SiteSetting.allow_animated_thumbnails
           while attempt > 0
             downsized_size = File.size(tempfile.path)
-            break if uploaded_size < downsized_size || downsized_size < SiteSetting.max_image_size_kb.kilobytes
+            break if downsized_size >= uploaded_size || downsized_size < max_image_size_kb
             image_info = FastImage.new(tempfile.path) rescue nil
             w, h = *(image_info.try(:size) || [0, 0])
             break if w == 0 || h == 0
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 599de42fc..194b49a71 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1513,7 +1513,6 @@ en:
         create: "Sorry, there was an error creating your post. Please try again."
         edit: "Sorry, there was an error editing your post. Please try again."
         upload: "Sorry, there was an error uploading that file. Please try again."
-        attachment_too_large: "Sorry, the file you are trying to upload is too big (maximum size is {{max_size_kb}}kb)."
         file_too_large: "Sorry, the file you are trying to upload is too big (maximum size is {{max_size_kb}}kb)"
         too_many_uploads: "Sorry, you can only upload one file at a time."
         too_many_dragged_and_dropped_files: "Sorry, you can only drag & drop up to 10 files at a time."
diff --git a/config/site_settings.yml b/config/site_settings.yml
index 16c07a246..f3fb12829 100644
--- a/config/site_settings.yml
+++ b/config/site_settings.yml
@@ -566,8 +566,12 @@ email:
   enable_staged_users: true
 
 files:
-  max_image_size_kb: 3072
-  max_attachment_size_kb: 3072
+  max_image_size_kb:
+    client: true
+    default: 3072
+  max_attachment_size_kb:
+    client: true
+    default: 3072
   authorized_extensions:
     client: true
     default: 'jpg|jpeg|png|gif'