diff --git a/app/assets/javascripts/discourse/lib/click_track.js b/app/assets/javascripts/discourse/lib/click_track.js index a77894dfe..b66b6d65e 100644 --- a/app/assets/javascripts/discourse/lib/click_track.js +++ b/app/assets/javascripts/discourse/lib/click_track.js @@ -79,7 +79,7 @@ Discourse.ClickTrack = { e.preventDefault(); // We don't track clicks on quote back buttons - if ($link.hasClass('back') || $link.hasClass('quote-other-topic')) return true; + if ($link.hasClass('back') || $link.hasClass('quote-other-topic')) { return true; } // Remove the href, put it as a data attribute if (!$link.data('href')) { @@ -90,6 +90,12 @@ Discourse.ClickTrack = { $link.data('auto-route', true); } + // warn the user if they can't download the file + if (Discourse.SiteSettings.prevent_anons_from_downloading_files && $link.hasClass("attachment") && !Discourse.User.current()) { + bootbox.alert(I18n.t("post.errors.attachment_download_requires_login")); + return false; + } + // If we're on the same site, use the router and track via AJAX if (Discourse.URL.isInternal(href) && !$link.hasClass('attachment')) { Discourse.ajax("/clicks/track", { diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb index b380804d0..ac2ae1012 100644 --- a/app/controllers/uploads_controller.rb +++ b/app/controllers/uploads_controller.rb @@ -20,6 +20,7 @@ class UploadsController < ApplicationController RailsMultisite::ConnectionManagement.with_connection(params[:site]) do |db| return render_404 unless Discourse.store.internal? + return render_404 if SiteSetting.prevent_anons_from_downloading_files && current_user.nil? id = params[:id].to_i url = request.fullpath diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 56da24b31..18c0c2afe 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1068,6 +1068,7 @@ en: upload_not_authorized: "Sorry, the file you are trying to upload is not authorized (authorized extension: {{authorized_extensions}})." image_upload_not_allowed_for_new_user: "Sorry, new users can not upload images." attachment_upload_not_allowed_for_new_user: "Sorry, new users can not upload attachments." + attachment_download_requires_login: "Sorry, you need to be logged in to download attachments." abandon: confirm: "Are you sure you want to abandon your post?" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index da6cf6151..64a2fb642 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -1002,6 +1002,8 @@ en: vacuum_db_days: "Run VACUUM FULL ANALYZE to reclaim DB space after migrations (set to 0 to disable)" + prevent_anons_from_downloading_files: "Prevent anonymous users from downloading files." + errors: invalid_email: "Invalid email address." invalid_username: "There's no user with that username." diff --git a/config/site_settings.yml b/config/site_settings.yml index 0e6db843b..2698d1b77 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -438,6 +438,9 @@ files: clean_up_uploads: false clean_orphan_uploads_grace_period_hours: 1 purge_deleted_uploads_grace_period_days: 30 + prevent_anons_from_downloading_files: + default: false + client: true enable_s3_uploads: false s3_use_iam_profile: false s3_access_key_id: '' diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb index a1deb7b98..6dfc34a41 100644 --- a/spec/controllers/uploads_controller_spec.rb +++ b/spec/controllers/uploads_controller_spec.rb @@ -137,6 +137,18 @@ describe UploadsController do get :show, site: "default", id: 42, sha: "66b3ed1503efc936", extension: "zip" end + context "prevent anons from downloading files" do + + before { SiteSetting.stubs(:prevent_anons_from_downloading_files).returns(true) } + + it "returns 404 when an anonymous user tries to download a file" do + Upload.expects(:find_by).never + get :show, site: "default", id: 2, sha: "1234567890abcdef", extension: "pdf" + response.response_code.should == 404 + end + + end + end end