DEV: Rename secure_media to secure_uploads (#18376)

This commit renames all secure_media related settings to secure_uploads_* along with the associated functionality.

This is being done because "media" does not really cover it, we aren't just doing this for images and videos etc. but for all uploads in the site.

Additionally, in future we want to secure more types of uploads, and enable a kind of "mixed mode" where some uploads are secure and some are not, so keeping media in the name is just confusing.

This also keeps compatibility with the `secure-media-uploads` path, and changes new
secure URLs to be `secure-uploads`.

Deprecated settings:

* secure_media -> secure_uploads
* secure_media_allow_embed_images_in_emails -> secure_uploads_allow_embed_images_in_emails
* secure_media_max_email_embed_image_size_kb -> secure_uploads_max_email_embed_image_size_kb
This commit is contained in:
Martin Brennan 2022-09-29 09:24:33 +10:00 committed by GitHub
parent 70b96ac4e7
commit 8ebd5edd1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 442 additions and 361 deletions

View File

@ -21,8 +21,8 @@ export function nativeLazyLoading(api) {
// Support for smallUpload should be maintained until Post::BAKED_VERSION is bumped higher than 2
const { smallUpload, dominantColor } = img.dataset;
if (siteSettings.secure_media && smallUpload) {
// Secure media requests go through the app. In topics with many images,
if (siteSettings.secure_uploads && smallUpload) {
// Secure uploads requests go through the app. In topics with many images,
// this makes it very easy to hit rate limiters. Skipping the low-res
// placeholders reduces the chance of this problem occuring.
return;

View File

@ -19,6 +19,7 @@ const SERVER_SIDE_ONLY = [
/^\/assets\//,
/^\/uploads\//,
/^\/secure-media-uploads\//,
/^\/secure-uploads\//,
/^\/stylesheets\//,
/^\/site_customizations\//,
/^\/raw\//,

View File

@ -97,7 +97,7 @@ const ORIGINAL_SETTINGS = {
enable_personal_messages: true,
personal_message_enabled_groups: "11", // TL1 group
unicode_usernames: false,
secure_media: false,
secure_uploads: false,
external_emoji_url: "",
remove_muted_tags_from_latest: "always",
enable_group_directory: true,

View File

@ -997,12 +997,12 @@ eviltrout</p>
);
});
test("attachment - mapped url - secure media disabled", function (assert) {
test("attachment - mapped url - secure uploads disabled", function (assert) {
function lookupUploadUrls() {
let cache = {};
cache["upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf"] = {
short_url: "upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf",
url: "/secure-media-uploads/original/3X/c/b/o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf",
url: "/secure-uploads/original/3X/c/b/o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf",
short_path: "/uploads/short-url/blah",
};
return cache;
@ -1010,20 +1010,20 @@ eviltrout</p>
assert.cookedOptions(
"[test.pdf|attachment](upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf)",
{
siteSettings: { secure_media: false },
siteSettings: { secure_uploads: false },
lookupUploadUrls,
},
`<p><a class="attachment" href="/uploads/short-url/blah">test.pdf</a></p>`,
"It returns the correct attachment link HTML when the URL is mapped without secure media"
"It returns the correct attachment link HTML when the URL is mapped without secure uploads"
);
});
test("attachment - mapped url - secure media enabled", function (assert) {
test("attachment - mapped url - secure uploads enabled", function (assert) {
function lookupUploadUrls() {
let cache = {};
cache["upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf"] = {
short_url: "upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf",
url: "/secure-media-uploads/original/3X/c/b/o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf",
url: "/secure-uploads/original/3X/c/b/o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf",
short_path: "/uploads/short-url/blah",
};
return cache;
@ -1031,11 +1031,11 @@ eviltrout</p>
assert.cookedOptions(
"[test.pdf|attachment](upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf)",
{
siteSettings: { secure_media: true },
siteSettings: { secure_uploads: true },
lookupUploadUrls,
},
`<p><a class="attachment" href="/secure-media-uploads/original/3X/c/b/o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf">test.pdf</a></p>`,
"It returns the correct attachment link HTML when the URL is mapped with secure media"
`<p><a class="attachment" href="/secure-uploads/original/3X/c/b/o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf">test.pdf</a></p>`,
"It returns the correct attachment link HTML when the URL is mapped with secure uploads"
);
});
@ -1052,12 +1052,12 @@ eviltrout</p>
);
});
test("video - mapped url - secure media enabled", function (assert) {
test("video - mapped url - secure uploads enabled", function (assert) {
function lookupUploadUrls() {
let cache = {};
cache["upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp4"] = {
short_url: "upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp4",
url: "/secure-media-uploads/original/3X/c/b/test.mp4",
url: "/secure-uploads/original/3X/c/b/test.mp4",
short_path: "/uploads/short-url/blah",
};
return cache;
@ -1065,16 +1065,16 @@ eviltrout</p>
assert.cookedOptions(
"![baby shark|video](upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp4)",
{
siteSettings: { secure_media: true },
siteSettings: { secure_uploads: true },
lookupUploadUrls,
},
`<p><div class="video-container">
<video width="100%" height="100%" preload="metadata" controls>
<source src="/secure-media-uploads/original/3X/c/b/test.mp4">
<a href="/secure-media-uploads/original/3X/c/b/test.mp4">/secure-media-uploads/original/3X/c/b/test.mp4</a>
<source src="/secure-uploads/original/3X/c/b/test.mp4">
<a href="/secure-uploads/original/3X/c/b/test.mp4">/secure-uploads/original/3X/c/b/test.mp4</a>
</video>
</div></p>`,
"It returns the correct video HTML when the URL is mapped with secure media, removing data-orig-src"
"It returns the correct video HTML when the URL is mapped with secure uploads, removing data-orig-src"
);
});
@ -1089,12 +1089,12 @@ eviltrout</p>
);
});
test("audio - mapped url - secure media enabled", function (assert) {
test("audio - mapped url - secure uploads enabled", function (assert) {
function lookupUploadUrls() {
let cache = {};
cache["upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp3"] = {
short_url: "upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp3",
url: "/secure-media-uploads/original/3X/c/b/test.mp3",
url: "/secure-uploads/original/3X/c/b/test.mp3",
short_path: "/uploads/short-url/blah",
};
return cache;
@ -1102,14 +1102,14 @@ eviltrout</p>
assert.cookedOptions(
"![baby shark|audio](upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp3)",
{
siteSettings: { secure_media: true },
siteSettings: { secure_uploads: true },
lookupUploadUrls,
},
`<p><audio preload="metadata" controls>
<source src="/secure-media-uploads/original/3X/c/b/test.mp3">
<a href="/secure-media-uploads/original/3X/c/b/test.mp3">/secure-media-uploads/original/3X/c/b/test.mp3</a>
<source src="/secure-uploads/original/3X/c/b/test.mp3">
<a href="/secure-uploads/original/3X/c/b/test.mp3">/secure-uploads/original/3X/c/b/test.mp3</a>
</audio></p>`,
"It returns the correct audio HTML when the URL is mapped with secure media, removing data-orig-src"
"It returns the correct audio HTML when the URL is mapped with secure uploads, removing data-orig-src"
);
});

View File

@ -96,7 +96,7 @@ module("Unit | Utility | pretty-text/upload-short-url", function (hooks) {
lookup = lookupCachedUploadUrl("upload://a.jpeg");
assert.deepEqual(lookup, {});
await resolveAllShortUrls(ajax, { secure_media: false }, fixture());
await resolveAllShortUrls(ajax, { secure_uploads: false }, fixture());
await settled();
lookup = lookupCachedUploadUrl("upload://a.jpeg");
@ -143,7 +143,7 @@ module("Unit | Utility | pretty-text/upload-short-url", function (hooks) {
test("resolveAllShortUrls - href + src replaced correctly", async function (assert) {
stubUrls();
await resolveAllShortUrls(ajax, { secure_media: false }, fixture());
await resolveAllShortUrls(ajax, { secure_uploads: false }, fixture());
await settled();
let image1 = fixture().querySelector("img");
@ -167,7 +167,7 @@ module("Unit | Utility | pretty-text/upload-short-url", function (hooks) {
test("resolveAllShortUrls - url with full origin replaced correctly", async function (assert) {
stubUrls();
await resolveAllShortUrls(ajax, { secure_media: false }, fixture());
await resolveAllShortUrls(ajax, { secure_uploads: false }, fixture());
await settled();
let video = fixture().querySelectorAll("video")[1];
@ -177,25 +177,25 @@ module("Unit | Utility | pretty-text/upload-short-url", function (hooks) {
);
});
test("resolveAllShortUrls - when secure media is enabled use the attachment full URL", async function (assert) {
test("resolveAllShortUrls - when secure uploads is enabled use the attachment full URL", async function (assert) {
stubUrls(
null,
[
{
short_url: "upload://c.pdf",
url: "/secure-media-uploads/default/original/3X/c/b/3.pdf",
url: "/secure-uploads/default/original/3X/c/b/3.pdf",
short_path: "/uploads/short-url/c.pdf",
},
],
null
);
await resolveAllShortUrls(ajax, { secure_media: true }, fixture());
await resolveAllShortUrls(ajax, { secure_uploads: true }, fixture());
await settled();
let link = fixture().querySelector("a");
assert.strictEqual(
link.getAttribute("href"),
"/secure-media-uploads/default/original/3X/c/b/3.pdf"
"/secure-uploads/default/original/3X/c/b/3.pdf"
);
});

View File

@ -143,14 +143,12 @@ module("Unit | Utility | url", function () {
);
});
test("routeTo redirects secure media URLS because they are server side only", async function (assert) {
test("routeTo redirects secure uploads URLS because they are server side only", async function (assert) {
sinon.stub(DiscourseURL, "redirectTo");
sinon.stub(DiscourseURL, "handleURL");
DiscourseURL.routeTo("/secure-media-uploads/original/1X/test.pdf");
DiscourseURL.routeTo("/secure-uploads/original/1X/test.pdf");
assert.ok(
DiscourseURL.redirectTo.calledWith(
"/secure-media-uploads/original/1X/test.pdf"
)
DiscourseURL.redirectTo.calledWith("/secure-uploads/original/1X/test.pdf")
);
});

View File

@ -525,7 +525,7 @@ export function setup(opts, siteSettings, state) {
getOptions.f = () => opts.discourse;
opts.discourse.limitedSiteSettings = {
secureMedia: siteSettings.secure_media,
secureUploads: siteSettings.secure_uploads,
enableDiffhtmlPreview: siteSettings.enable_diffhtml_preview,
traditionalMarkdownLinebreaks: siteSettings.traditional_markdown_linebreaks,
enableMarkdownLinkify: siteSettings.enable_markdown_linkify,

View File

@ -112,11 +112,12 @@ function getAttributeBasedUrl(dataAttribute, cachedUpload, siteSettings) {
return cachedUpload.url;
}
// attachments should use the full /secure-media-uploads/ URL
// in this case for permission checks
// attachments should use the full /secure-media-uploads/ or
// /secure-uploads/ URL in this case for permission checks
if (
siteSettings.secure_media &&
cachedUpload.url.includes("secure-media-uploads")
siteSettings.secure_uploads &&
(cachedUpload.url.includes("secure-media-uploads") ||
cachedUpload.url.includes("secure-uploads"))
) {
return cachedUpload.url;
}

View File

@ -136,11 +136,12 @@ function rule(state) {
}
} else if (token.tag === "a") {
if (mapped) {
// when secure media is enabled we want the full /secure-media-uploads/
// when secure uploads is enabled we want the full /secure-media-uploads or /secure-uploads
// url to take advantage of access control security
if (
state.md.options.discourse.limitedSiteSettings.secureMedia &&
mapped.url.includes("secure-media-uploads")
state.md.options.discourse.limitedSiteSettings.secureUploads &&
(mapped.url.includes("secure-media-uploads") ||
mapped.url.includes("secure-uploads"))
) {
token.attrs[srcIndex][1] = mapped.url;
} else {

View File

@ -28,7 +28,7 @@ workbox.routing.registerRoute(
plugins: [
new workbox.cacheableResponse.Plugin({
statuses: [200] // opaque responses will return status code '0'
}), // for s3 secure media signed urls
}), // for s3 secure uploads signed urls
new workbox.expiration.Plugin({
maxAgeSeconds: 7* 24 * 60 * 60, // 7 days
maxEntries: 250,

View File

@ -94,7 +94,7 @@ private
end
def ensure_publish_enabled
if !SiteSetting.enable_page_publishing? || SiteSetting.secure_media
if !SiteSetting.enable_page_publishing? || SiteSetting.secure_uploads
raise Discourse::NotFound
end
end

View File

@ -5,13 +5,13 @@ require "mini_mime"
class UploadsController < ApplicationController
include ExternalUploadHelpers
requires_login except: [:show, :show_short, :show_secure]
requires_login except: [:show, :show_short, :_show_secure_deprecated, :show_secure]
skip_before_action :preload_json, :check_xhr, :redirect_to_login_if_required, only: [:show, :show_short, :show_secure]
skip_before_action :preload_json, :check_xhr, :redirect_to_login_if_required, only: [:show, :show_short, :_show_secure_deprecated, :show_secure]
protect_from_forgery except: :show
before_action :is_asset_path, :apply_cdn_headers, only: [:show, :show_short, :show_secure]
before_action :external_store_check, only: [:show_secure]
before_action :is_asset_path, :apply_cdn_headers, only: [:show, :show_short, :_show_secure_deprecated, :show_secure]
before_action :external_store_check, only: [:_show_secure_deprecated, :show_secure]
SECURE_REDIRECT_GRACE_SECONDS = 5
@ -111,7 +111,7 @@ class UploadsController < ApplicationController
sha1 = Upload.sha1_from_base62_encoded(params[:base62])
if upload = Upload.find_by(sha1: sha1)
if upload.secure? && SiteSetting.secure_media?
if upload.secure? && SiteSetting.secure_uploads?
return handle_secure_upload_request(upload)
end
@ -125,6 +125,13 @@ class UploadsController < ApplicationController
end
end
# Kept to avoid rebaking old posts with /show-secure-uploads/ in their
# contents, this will ensure the uploads in these posts continue to
# work in future.
def _show_secure_deprecated
show_secure
end
def show_secure
# do not serve uploads requested via XHR to prevent XSS
return xhr_not_allowed if request.xhr?
@ -139,9 +146,9 @@ class UploadsController < ApplicationController
return render_404 if upload.blank?
return render_404 if SiteSetting.prevent_anons_from_downloading_files && current_user.nil?
return handle_secure_upload_request(upload, path_with_ext) if SiteSetting.secure_media?
return handle_secure_upload_request(upload, path_with_ext) if SiteSetting.secure_uploads?
# we don't want to 404 here if secure media gets disabled
# we don't want to 404 here if secure uploads gets disabled
# because all posts with secure uploads will show broken media
# until rebaked, which could take some time
#

View File

@ -67,6 +67,10 @@ module EmailHelper
border-color: #454545 !important;
}
[data-stripped-secure-upload] {
border-color: #454545 !important;
}
[dm='text-color'] {
color: #dddddd;
}

View File

@ -108,9 +108,9 @@ module Jobs
class UploadCreateError < StandardError; end
def attempt_download(src, user_id)
# secure-media-uploads endpoint prevents anonymous downloads, so we
# secure-uploads endpoint prevents anonymous downloads, so we
# need the presigned S3 URL here
src = Upload.signed_url_from_secure_media_url(src) if Upload.secure_media_url?(src)
src = Upload.signed_url_from_secure_uploads_url(src) if Upload.secure_uploads_url?(src)
hotlinked = download(src)
raise ImageBrokenError if !hotlinked
@ -147,7 +147,7 @@ module Jobs
].compact.map { |s| normalize_src(s) }
if Discourse.store.has_been_uploaded?(src) || normalize_src(src).start_with?(*local_bases) || src =~ /\A\/[^\/]/i
return false if !(src =~ /\/uploads\// || Upload.secure_media_url?(src))
return false if !(src =~ /\/uploads\// || Upload.secure_uploads_url?(src))
# Someone could hotlink a file from a different site on the same CDN,
# so check whether we have it in this database

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
module Jobs
# Sometimes we need to update a _lot_ of ACLs on S3 (such as when secure media
# Sometimes we need to update a _lot_ of ACLs on S3 (such as when secure uploads
# is enabled), and since it takes ~1s per upload to update the ACL, this is
# best spread out over many jobs instead of having to do the whole thing serially.
class SyncAclsForUploads < ::Jobs::Base

View File

@ -309,7 +309,7 @@ class Post < ActiveRecord::Base
options[:user_id] = post_user.id if post_user
options[:omit_nofollow] = true if omit_nofollow?
if self.with_secure_media?
if self.with_secure_uploads?
each_upload_url do |url|
uri = URI.parse(url)
if FileHelper.is_supported_media?(File.basename(uri.path))
@ -517,8 +517,8 @@ class Post < ActiveRecord::Base
ReviewableFlaggedPost.pending.find_by(target: self)
end
def with_secure_media?
return false if !SiteSetting.secure_media?
def with_secure_uploads?
return false if !SiteSetting.secure_uploads?
SiteSetting.login_required? || \
(topic.present? && (topic.private_message? || topic.category&.read_restricted))
end
@ -971,7 +971,7 @@ class Post < ActiveRecord::Base
UploadReference.where(target: self).delete_all
UploadReference.insert_all(upload_references) if upload_references.size > 0
if SiteSetting.secure_media?
if SiteSetting.secure_uploads?
Upload.where(
id: upload_ids, access_control_post_id: nil
).where(
@ -1033,7 +1033,7 @@ class Post < ActiveRecord::Base
next if Rails.configuration.multisite && src.exclude?(current_db)
src = "#{SiteSetting.force_https ? "https" : "http"}:#{src}" if src.start_with?("//")
next unless Discourse.store.has_been_uploaded?(src) || Upload.secure_media_url?(src) || (include_local_upload && src =~ /\A\/[^\/]/i)
next unless Discourse.store.has_been_uploaded?(src) || Upload.secure_uploads_url?(src) || (include_local_upload && src =~ /\A\/[^\/]/i)
path = begin
URI(UrlHelper.unencode(GlobalSetting.cdn_url ? src.sub(GlobalSetting.cdn_url, "") : src))&.path

View File

@ -186,7 +186,7 @@ class Upload < ActiveRecord::Base
"upload://#{short_url_basename}"
end
def uploaded_before_secure_media_enabled?
def uploaded_before_secure_uploads_enabled?
original_sha1.blank?
end
@ -204,14 +204,14 @@ class Upload < ActiveRecord::Base
end
def self.consider_for_reuse(upload, post)
return upload if !SiteSetting.secure_media? || upload.blank? || post.blank?
return nil if !upload.matching_access_control_post?(post) || upload.uploaded_before_secure_media_enabled?
return upload if !SiteSetting.secure_uploads? || upload.blank? || post.blank?
return nil if !upload.matching_access_control_post?(post) || upload.uploaded_before_secure_uploads_enabled?
upload
end
def self.secure_media_url?(url)
def self.secure_uploads_url?(url)
# we do not want to exclude topic links that for whatever reason
# have secure-media-uploads in the URL e.g. /t/secure-media-uploads-are-cool/223452
# have secure-uploads in the URL e.g. /t/secure-uploads-are-cool/223452
route = UrlHelper.rails_route_from_url(url)
return false if route.blank?
route[:action] == "show_secure" && route[:controller] == "uploads" && FileHelper.is_supported_media?(url)
@ -219,14 +219,14 @@ class Upload < ActiveRecord::Base
false
end
def self.signed_url_from_secure_media_url(url)
def self.signed_url_from_secure_uploads_url(url)
route = UrlHelper.rails_route_from_url(url)
url = Rails.application.routes.url_for(route.merge(only_path: true))
secure_upload_s3_path = url[url.index(route[:path])..-1]
Discourse.store.signed_url_for_path(secure_upload_s3_path)
end
def self.secure_media_url_from_upload_url(url)
def self.secure_uploads_url_from_upload_url(url)
return url if !url.include?(SiteSetting.Upload.absolute_base_url)
uri = URI.parse(url)
Rails.application.routes.url_for(

View File

@ -290,7 +290,7 @@ class TopicViewSerializer < ApplicationSerializer
SiteSetting.enable_page_publishing? &&
scope.is_staff? &&
object.published_page.present? &&
!SiteSetting.secure_media
!SiteSetting.secure_uploads
end
def thumbnails

View File

@ -17,6 +17,6 @@ class UploadSerializer < ApplicationSerializer
:dominant_color
def url
object.for_site_setting ? object.url : UrlHelper.cook_url(object.url, secure: SiteSetting.secure_media? && object.secure)
object.for_site_setting ? object.url : UrlHelper.cook_url(object.url, secure: SiteSetting.secure_uploads? && object.secure)
end
end

View File

@ -45,6 +45,7 @@ if defined?(Rack::MiniProfiler) && defined?(Rack::MiniProfiler::Config)
/^\/site_customizations/,
/^\/uploads/,
/^\/secure-media-uploads/,
/^\/secure-uploads/,
/^\/javascripts\//,
/^\/images\//,
/^\/stylesheets\//,

View File

@ -139,7 +139,7 @@ en:
unsubscribe_not_allowed: "Happens when unsubscribing via email is not allowed for this user."
email_not_allowed: "Happens when the email address is not on the allowlist or is on the blocklist."
unrecognized_error: "Unrecognized Error"
secure_media_placeholder: "Redacted: This site has secure media enabled, visit the topic or click View Media to see the attached media."
secure_uploads_placeholder: "Redacted: This site has secure uploads enabled, visit the topic or click View Media to see the attached uploads."
view_redacted_media: "View Media"
errors: &errors
@ -210,7 +210,7 @@ en:
page_publishing_requirements: "Page publishing cannot be enabled if secure media is enabled."
s3_backup_requires_s3_settings: "You cannot use S3 as backup location unless you've provided the '%{setting_name}'."
s3_bucket_reused: "You cannot use the same bucket for 's3_upload_bucket' and 's3_backup_bucket'. Choose a different bucket or use a different path for each bucket."
secure_media_requirements: "S3 uploads must be enabled before enabling secure media."
secure_uploads_requirements: "S3 uploads must be enabled before enabling secure uploads."
share_quote_facebook_requirements: "You must set a Facebook app id to enable quote sharing for Facebook."
second_factor_cannot_enforce_with_socials: "You cannot enforce 2FA with social logins enabled. You must first disable login via: %{auth_provider_names}"
second_factor_cannot_be_enforced_with_disabled_local_login: "You cannot enforce 2FA if local logins are disabled."
@ -2219,9 +2219,12 @@ en:
bootstrap_mode_min_users: "Minimum number of users required to disable bootstrap mode (set to 0 to disable)"
prevent_anons_from_downloading_files: "Prevent anonymous users from downloading attachments."
secure_media: 'Limits access to ALL uploads (images, video, audio, text, pdfs, zips, and others). If “login required” is enabled, only logged-in users can access uploads. Otherwise, access will be limited only for media uploads in private messages and private categories. WARNING: This setting is complex and requires deep administrative understanding. See <a target="_blank" href="https://meta.discourse.org/t/secure-media-uploads/140017">the secure media topic on Meta</a> for details.'
secure_media_allow_embed_images_in_emails: "Allows embedding secure images that would normally be redacted in emails, if their size is smaller than the 'secure media max email embed image size kb' setting."
secure_media_max_email_embed_image_size_kb: "The size cutoff for secure images that will be embedded in emails if the 'secure media allow embed in emails' setting is enabled. Without that setting enabled, this setting has no effect."
secure_media: 'DEPRECATED: Use the secure_uploads setting instead, will be removed in Discourse 3.0.'
secure_uploads: 'Limits access to ALL uploads (images, video, audio, text, pdfs, zips, and others). If "login required” is enabled, only logged-in users can access uploads. Otherwise, access will be limited only for media uploads in private messages and private categories. WARNING: This setting is complex and requires deep administrative understanding. See <a target="_blank" href="https://meta.discourse.org/t/-/140017">the secure uploads topic on Meta</a> for details.'
secure_media_allow_embed_images_in_emails: "DEPRECATED: Use secure_uploads_allow_embed_images_in_emails, will remove in Discourse 3.0."
secure_uploads_allow_embed_images_in_emails: "Allows embedding secure images that would normally be redacted in emails, if their size is smaller than the 'secure uploads max email embed image size kb' setting."
secure_media_max_email_embed_image_size_kb: "DEPRECATED: Use secure_uploads_max_email_embed_image_size_kb, will be removed in Discourse 3.0."
secure_uploads_max_email_embed_image_size_kb: "The size cutoff for secure images that will be embedded in emails if the 'secure uploads allow embed in emails' setting is enabled. Without that setting enabled, this setting has no effect."
slug_generation_method: "Choose a slug generation method. 'encoded' will generate percent encoding string. 'none' will disable slug at all."
enable_emoji: "Enable emoji"

View File

@ -110,7 +110,7 @@ server {
break;
}
location ~ ^/secure-media-uploads/ {
location ~ ^/(secure-media-uploads/|secure-uploads)/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";

View File

@ -583,7 +583,12 @@ Discourse::Application.routes.draw do
end
# used to download attachments (old route)
get "uploads/:site/:id/:sha" => "uploads#show", constraints: { site: /\w+/, id: /\d+/, sha: /\h{16}/, format: /.*/ }
get "secure-media-uploads/*path(.:extension)" => "uploads#show_secure", constraints: { extension: /[a-z0-9\._]+/i }
# NOTE: secure-media-uploads is the old form, all new URLs generated for
# secure uploads will be secure-uploads, this is left in for backwards
# compat without needing to rebake all posts for each site.
get "secure-media-uploads/*path(.:extension)" => "uploads#_show_secure_deprecated", constraints: { extension: /[a-z0-9\._]+/i }
get "secure-uploads/*path(.:extension)" => "uploads#show_secure", constraints: { extension: /[a-z0-9\._]+/i }
get "posts" => "posts#latest", id: "latest_posts", constraints: { format: /(json|rss)/ }
get "private-posts" => "posts#latest", id: "private_posts", constraints: { format: /(json|rss)/ }

View File

@ -1365,12 +1365,24 @@ files:
secure_media:
default: false
client: true
hidden: true
secure_media_allow_embed_images_in_emails:
default: true
hidden: true
secure_media_max_email_embed_image_size_kb:
default: 1024
min: 1
max: 10240
hidden: true
secure_uploads:
default: false
client: true
secure_uploads_allow_embed_images_in_emails:
default: true
secure_uploads_max_email_embed_image_size_kb:
default: 1024
min: 1
max: 10240
enable_s3_uploads:
default: false
client: true

View File

@ -0,0 +1,36 @@
# frozen_string_literal: true
class SetSecureUploadsSettingsBasedOnSecureMediaEquivalent < ActiveRecord::Migration[7.0]
def up
secure_media_enabled = DB.query_single("SELECT value FROM site_settings WHERE name = 'secure_media'")
if secure_media_enabled.present? && secure_media_enabled[0] == "t"
execute <<~SQL
INSERT INTO site_settings(name, data_type, value, created_at, updated_at)
VALUES ('secure_uploads', 5, 't', now(), now())
SQL
end
secure_media_allow_embed_images_in_emails = DB.query_single("SELECT value FROM site_settings WHERE name = 'secure_media_allow_embed_images_in_emails'")
if secure_media_allow_embed_images_in_emails.present? && secure_media_allow_embed_images_in_emails[0] == "t"
execute <<~SQL
INSERT INTO site_settings(name, data_type, value, created_at, updated_at)
VALUES ('secure_uploads_allow_embed_images_in_emails', 5, 't', now(), now())
SQL
end
secure_media_max_email_embed_image_size_kb = DB.query_single("SELECT value FROM site_settings WHERE name = 'secure_media_max_email_embed_image_size_kb'")
if secure_media_max_email_embed_image_size_kb.present?
execute <<~SQL
INSERT INTO site_settings(name, data_type, value, created_at, updated_at)
VALUES ('secure_uploads_max_email_embed_image_size_kb', 3, '#{secure_uploads_max_email_embed_image_size_kb[0]}', now(), now())
SQL
end
end
def down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -22,7 +22,7 @@ class CookedPostProcessor
@cooking_options = post.cooking_options || opts[:cooking_options] || {}
@cooking_options[:topic_id] = post.topic_id
@cooking_options = @cooking_options.symbolize_keys
@with_secure_media = @post.with_secure_media?
@with_secure_uploads = @post.with_secure_uploads?
@category_id = @post&.topic&.category_id
cooked = post.cook(post.raw, @cooking_options)
@ -225,14 +225,14 @@ class CookedPostProcessor
resized_h = (h * ratio).to_i
if !cropped && upload.width && resized_w > upload.width
cooked_url = UrlHelper.cook_url(upload.url, secure: @post.with_secure_media?)
cooked_url = UrlHelper.cook_url(upload.url, secure: @post.with_secure_uploads?)
srcset << ", #{cooked_url} #{ratio.to_s.sub(/\.0$/, "")}x"
elsif t = upload.thumbnail(resized_w, resized_h)
cooked_url = UrlHelper.cook_url(t.url, secure: @post.with_secure_media?)
cooked_url = UrlHelper.cook_url(t.url, secure: @post.with_secure_uploads?)
srcset << ", #{cooked_url} #{ratio.to_s.sub(/\.0$/, "")}x"
end
img["srcset"] = "#{UrlHelper.cook_url(img["src"], secure: @post.with_secure_media?)}#{srcset}" if srcset.present?
img["srcset"] = "#{UrlHelper.cook_url(img["src"], secure: @post.with_secure_uploads?)}#{srcset}" if srcset.present?
end
else
img["src"] = upload.url
@ -250,7 +250,7 @@ class CookedPostProcessor
lightbox.add_child(img)
# then, the link to our larger image
src = UrlHelper.cook_url(img["src"], secure: @post.with_secure_media?)
src = UrlHelper.cook_url(img["src"], secure: @post.with_secure_uploads?)
a = create_link_node("lightbox", src)
img.add_next_sibling(a)
@ -323,7 +323,7 @@ class CookedPostProcessor
@doc.css("img[#{selector}]").each do |img|
custom_emoji = img["class"]&.include?("emoji-custom") && Emoji.custom?(img["title"])
img[selector] = UrlHelper.cook_url(
img[selector].to_s, secure: @post.with_secure_media? && !custom_emoji
img[selector].to_s, secure: @post.with_secure_uploads? && !custom_emoji
)
end
end
@ -384,7 +384,7 @@ class CookedPostProcessor
still_an_image = false
elsif info&.downloaded? && upload = info&.upload
img["src"] = UrlHelper.cook_url(upload.url, secure: @with_secure_media)
img["src"] = UrlHelper.cook_url(upload.url, secure: @with_secure_uploads)
img.delete(PrettyText::BLOCKED_HOTLINKED_SRC_ATTR)
end

View File

@ -175,10 +175,10 @@ module CookedProcessorMixin
# FastImage fails when there's no scheme
absolute_url = SiteSetting.scheme + ":" + absolute_url if absolute_url.start_with?("//")
# we can't direct FastImage to our secure-media-uploads url because it bounces
# we can't direct FastImage to our secure-uploads url because it bounces
# anonymous requests with a 404 error
if url && Upload.secure_media_url?(url)
absolute_url = Upload.signed_url_from_secure_media_url(absolute_url)
if url && Upload.secure_uploads_url?(url)
absolute_url = Upload.signed_url_from_secure_uploads_url(absolute_url)
end
return unless is_valid_image_url?(absolute_url)

View File

@ -242,7 +242,7 @@ module Email
# Embeds any of the secure images that have been attached inline,
# removing the redaction notice.
if SiteSetting.secure_media_allow_embed_images_in_emails
if SiteSetting.secure_uploads_allow_embed_images_in_emails
style.inline_secure_images(@message.attachments, @message_attachments_index)
end
@ -357,8 +357,8 @@ module Email
end
def should_attach_image?(upload, optimized_1X = nil)
return if !SiteSetting.secure_media_allow_embed_images_in_emails || !upload.secure?
return if (optimized_1X&.filesize || upload.filesize) > SiteSetting.secure_media_max_email_embed_image_size_kb.kilobytes
return if !SiteSetting.secure_uploads_allow_embed_images_in_emails || !upload.secure?
return if (optimized_1X&.filesize || upload.filesize) > SiteSetting.secure_uploads_max_email_embed_image_size_kb.kilobytes
true
end

View File

@ -257,10 +257,10 @@ module Email
end
def inline_secure_images(attachments, attachments_index)
stripped_media = @fragment.css('[data-stripped-secure-media]')
stripped_media = @fragment.css('[data-stripped-secure-media], [data-stripped-secure-upload]')
upload_shas = {}
stripped_media.each do |div|
url = div['data-stripped-secure-media']
url = div['data-stripped-secure-media'] || div['data-stripped-secure-upload']
filename = File.basename(url)
filename_bare = filename.gsub(File.extname(filename), "")
sha1 = filename_bare.partition('_').first
@ -269,7 +269,9 @@ module Email
uploads = Upload.select(:original_filename, :sha1).where(sha1: upload_shas.values)
stripped_media.each do |div|
upload = uploads.find { |upl| upl.sha1 == upload_shas[div['data-stripped-secure-media']] }
upload = uploads.find do |upl|
upl.sha1 == (upload_shas[div['data-stripped-secure-media']] || upload_shas[div['data-stripped-secure-upload']])
end
next if !upload
if attachments[attachments_index[upload.sha1]]
@ -294,7 +296,7 @@ module Email
def to_html
# needs to be before class + id strip because we need to style redacted
# media and also not double-redact already redacted from lower levels
replace_secure_media_urls if SiteSetting.secure_media?
replace_secure_uploads_urls if SiteSetting.secure_uploads?
strip_classes_and_ids
replace_relative_urls
@ -369,13 +371,13 @@ module Email
end
end
def replace_secure_media_urls
def replace_secure_uploads_urls
# strip again, this can be done at a lower level like in the user
# notification template but that may not catch everything
PrettyText.strip_secure_media(@fragment)
PrettyText.strip_secure_uploads(@fragment)
style('div.secure-media-notice', 'border: 5px solid #e9e9e9; padding: 5px; display: inline-block;')
style('div.secure-media-notice a', "color: #{SiteSetting.email_link_color}")
style('div.secure-upload-notice', 'border: 5px solid #e9e9e9; padding: 5px; display: inline-block;')
style('div.secure-upload-notice a', "color: #{SiteSetting.email_link_color}")
end
def correct_first_body_margin

View File

@ -543,7 +543,7 @@ class Guardian
def can_publish_page?(topic)
return false if !SiteSetting.enable_page_publishing?
return false if SiteSetting.secure_media?
return false if SiteSetting.secure_uploads?
return false if topic.blank?
return false if topic.private_message?
return false unless can_see_topic?(topic)

View File

@ -398,7 +398,7 @@ class PostCreator
end
def update_uploads_secure_status
@post.update_uploads_secure_status(source: "post creator") if SiteSetting.secure_media?
@post.update_uploads_secure_status(source: "post creator") if SiteSetting.secure_uploads?
end
def delete_owned_bookmarks

View File

@ -488,14 +488,14 @@ module PrettyText
end
end
def self.strip_secure_media(doc)
def self.strip_secure_uploads(doc)
# images inside a lightbox or other link
doc.css('a[href]').each do |a|
next if !Upload.secure_media_url?(a['href'])
next if !Upload.secure_uploads_url?(a['href'])
non_image_media = %w(video audio).include?(a&.parent&.name)
target = non_image_media ? a.parent : a
next if target.to_s.include?('stripped-secure-view-media')
next if target.to_s.include?('stripped-secure-view-media') || target.to_s.include?('stripped-secure-view-upload')
next if a.css('img[src]').empty? && !non_image_media
@ -509,12 +509,12 @@ module PrettyText
else
url = img['src']
end
a.add_next_sibling secure_media_placeholder(doc, url, width: img['width'], height: img['height'])
a.add_next_sibling secure_uploads_placeholder(doc, url, width: img['width'], height: img['height'])
a.remove
else
width = non_image_media ? nil : a.at_css('img').attr('width')
height = non_image_media ? nil : a.at_css('img').attr('height')
target.add_next_sibling secure_media_placeholder(doc, a['href'], width: width, height: height)
target.add_next_sibling secure_uploads_placeholder(doc, a['href'], width: width, height: height)
target.remove
end
end
@ -551,20 +551,20 @@ module PrettyText
height = 16
end
if Upload.secure_media_url?(url)
img.add_next_sibling secure_media_placeholder(doc, url, onebox_type: onebox_type, width: width, height: height)
if Upload.secure_uploads_url?(url)
img.add_next_sibling secure_uploads_placeholder(doc, url, onebox_type: onebox_type, width: width, height: height)
img.remove
end
end
end
def self.secure_media_placeholder(doc, url, onebox_type: false, width: nil, height: nil)
def self.secure_uploads_placeholder(doc, url, onebox_type: false, width: nil, height: nil)
data_width = width ? "data-width=#{width}" : ''
data_height = height ? "data-height=#{height}" : ''
data_onebox_type = onebox_type ? "data-onebox-type='#{onebox_type}'" : ''
<<~HTML
<div class="secure-media-notice" data-stripped-secure-media="#{url}" #{data_onebox_type} #{data_width} #{data_height}>
#{I18n.t('emails.secure_media_placeholder')} <a class='stripped-secure-view-media' href="#{url}">#{I18n.t("emails.view_redacted_media")}</a>.
<div class="secure-upload-notice" data-stripped-secure-upload="#{url}" #{data_onebox_type} #{data_width} #{data_height}>
#{I18n.t('emails.secure_uploads_placeholder')} <a class='stripped-secure-view-upload' href="#{url}">#{I18n.t("emails.view_redacted_media")}</a>.
</div>
HTML
end
@ -572,7 +572,7 @@ module PrettyText
def self.format_for_email(html, post = nil)
doc = Nokogiri::HTML5.fragment(html)
DiscourseEvent.trigger(:reduce_cooked, doc, post)
strip_secure_media(doc) if post&.with_secure_media?
strip_secure_uploads(doc) if post&.with_secure_uploads?
strip_image_wrapping(doc)
convert_vimeo_iframes(doc)
make_all_links_absolute(doc)

View File

@ -70,11 +70,11 @@ module PrettyText
sha1, url, extension, original_filename, secure = row
if short_urls = reverse_map[sha1]
secure_media = SiteSetting.secure_media? && secure
secure_uploads = SiteSetting.secure_uploads? && secure
short_urls.each do |short_url|
result[short_url] = {
url: secure_media ? Upload.secure_media_url_from_upload_url(url) : Discourse.store.cdn_url(url),
url: secure_uploads ? Upload.secure_uploads_url_from_upload_url(url) : Discourse.store.cdn_url(url),
short_path: Upload.short_path(sha1: sha1, extension: extension),
base62_sha1: Upload.base62_sha1(sha1)
}

View File

@ -9,6 +9,9 @@ module SiteSettings::DeprecatedSettings
['default_categories_regular', 'default_categories_normal', true, '3.0'],
['min_trust_to_send_messages', 'personal_message_enabled_groups', false, '3.0'],
['enable_personal_messages', 'personal_message_enabled_groups', false, '3.0'],
['secure_media', 'secure_uploads', true, '3.0'],
['secure_media_allow_embed_images_in_emails', 'secure_uploads_allow_embed_images_in_emails', true, '3.0'],
['secure_media_max_email_embed_image_size_kb', 'secure_uploads_max_email_embed_image_size_kb', true, '3.0'],
]
def setup_deprecated_methods

View File

@ -162,12 +162,12 @@ module SiteSettings::Validations
validate_error :s3_upload_bucket_is_required if SiteSetting.s3_upload_bucket.blank?
end
def validate_secure_media(new_val)
validate_error :secure_media_requirements if new_val == "t" && !SiteSetting.Upload.enable_s3_uploads
def validate_secure_uploads(new_val)
validate_error :secure_uploads_requirements if new_val == "t" && !SiteSetting.Upload.enable_s3_uploads
end
def validate_enable_page_publishing(new_val)
validate_error :page_publishing_requirements if new_val == "t" && SiteSetting.secure_media?
validate_error :page_publishing_requirements if new_val == "t" && SiteSetting.secure_uploads?
end
def validate_share_quote_buttons(new_val)

View File

@ -518,16 +518,16 @@ task "uploads:sync_s3_acls" => :environment do
end
end
task "uploads:disable_secure_media" => :environment do
task "uploads:disable_secure_uploads" => :environment do
RailsMultisite::ConnectionManagement.each_connection do |db|
unless Discourse.store.external?
puts "This task only works for external storage."
exit 1
end
puts "Disabling secure media and resetting uploads to not secure in #{db}...", ""
puts "Disabling secure upload and resetting uploads to not secure in #{db}...", ""
SiteSetting.secure_media = false
SiteSetting.secure_uploads = false
secure_uploads = Upload.joins(:upload_references).where(upload_references: { target_type: 'Post' }).where(secure: true)
secure_upload_count = secure_uploads.count
@ -537,7 +537,7 @@ task "uploads:disable_secure_media" => :environment do
secure_uploads.update_all(
secure: false,
security_last_changed_at: Time.zone.now,
security_last_changed_reason: "marked as not secure by disable_secure_media task"
security_last_changed_reason: "marked as not secure by disable_secure_uploads task"
)
post_ids_to_rebake = DB.query_single(
@ -550,11 +550,11 @@ task "uploads:disable_secure_media" => :environment do
puts "", "Rebaking and uploading complete!", ""
end
puts "", "Secure media is now disabled!", ""
puts "", "Secure uploads are now disabled!", ""
end
##
# Run this task whenever the secure_media or login_required
# Run this task whenever the secure_uploads or login_required
# settings are changed for a Discourse instance to update
# the upload secure flag and S3 upload ACLs. Any uploads that
# have their secure status changed will have all associated posts
@ -569,12 +569,12 @@ task "uploads:secure_upload_analyse_and_update" => :environment do
puts "Analyzing security for uploads in #{db}...", ""
all_upload_ids_changed, post_ids_to_rebake = nil
Upload.transaction do
# If secure media is enabled we need to first set the access control post of
# If secure upload is enabled we need to first set the access control post of
# all post uploads (even uploads that are linked to multiple posts). If the
# upload is not set to secure media then this has no other effect on the upload,
# but we _must_ know what the access control post is because the with_secure_media?
# upload is not set to secure upload then this has no other effect on the upload,
# but we _must_ know what the access control post is because the with_secure_uploads?
# method is on the post, and this knows about the category security & PM status
if SiteSetting.secure_media?
if SiteSetting.secure_uploads?
update_uploads_access_control_post
end

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
##
# There are certain conditions with secure media when the security of
# There are certain conditions with secure uploads when the security of
# uploads will need to change depending on the context they reside in.
#
# For example on these conditions:
@ -38,16 +38,16 @@ class TopicUploadSecurityManager
end
end
return if !SiteSetting.secure_media
return if !SiteSetting.secure_uploads
# we only want to do this if secure media is enabled. if
# we only want to do this if secure uploads is enabled. if
# the setting is turned on after a site has been running
# already, we want to make sure that any post moves after
# this are handled and upload secure statuses and ACLs
# are updated appropriately, as well as setting the access control
# post for secure uploads missing it.
#
# examples (all after secure media is enabled):
# examples (all after secure uploads is enabled):
#
# -> a public topic is moved to a private category after
# -> a PM is converted to a public topic

View File

@ -94,15 +94,15 @@ class UploadCreator
if !external_upload_too_big
sha1 = Upload.generate_digest(@file)
end
if SiteSetting.secure_media || external_upload_too_big
if SiteSetting.secure_uploads || external_upload_too_big
unique_hash = generate_fake_sha1_hash
end
# we do not check for duplicate uploads if secure media is
# we do not check for duplicate uploads if secure uploads is
# enabled because we use a unique access hash to differentiate
# between uploads instead of the sha1, and to get around various
# access/permission issues for uploads
if !SiteSetting.secure_media && !external_upload_too_big
if !SiteSetting.secure_uploads && !external_upload_too_big
# do we already have that upload?
@upload = Upload.find_by(sha1: sha1)
@ -140,8 +140,8 @@ class UploadCreator
@upload.user_id = user_id
@upload.original_filename = fixed_original_filename || @filename
@upload.filesize = filesize
@upload.sha1 = (SiteSetting.secure_media? || external_upload_too_big) ? unique_hash : sha1
@upload.original_sha1 = SiteSetting.secure_media? ? sha1 : nil
@upload.sha1 = (SiteSetting.secure_uploads? || external_upload_too_big) ? unique_hash : sha1
@upload.original_sha1 = SiteSetting.secure_uploads? ? sha1 : nil
@upload.url = ""
@upload.origin = @opts[:origin][0...1000] if @opts[:origin]
@upload.extension = image_type || File.extname(@filename)[1..10]
@ -173,7 +173,7 @@ class UploadCreator
add_metadata!
if SiteSetting.secure_media
if SiteSetting.secure_uploads
secure, reason = UploadSecurity.new(@upload, @opts.merge(creating: true)).should_be_secure_with_reason
attrs = @upload.secure_params(secure, reason, "upload creator")
@upload.assign_attributes(attrs)

View File

@ -66,8 +66,8 @@ class UploadSecurity
[false, "no checks satisfied"]
end
def secure_media_disabled_check
!SiteSetting.secure_media?
def secure_uploads_disabled_check
!SiteSetting.secure_uploads?
end
def insecure_creation_for_modifiers_check
@ -96,14 +96,14 @@ class UploadSecurity
# whether the upload should remain secure or not after posting depends on its context,
# which is based on the post it is linked to via access_control_post_id.
# if that post is with_secure_media? then the upload should also be secure.
# if that post is with_secure_uploads? then the upload should also be secure.
# this may change to false if the upload was set to secure on upload e.g. in
# a post composer then it turned out that the post itself was not in a secure context
#
# a post is with secure media if it is a private message or in a read restricted
# a post is with secure uploads if it is a private message or in a read restricted
# category
def access_control_post_has_secure_media_check
access_control_post&.with_secure_media?
def access_control_post_has_secure_uploads_check
access_control_post&.with_secure_uploads?
end
def uploading_in_composer_check
@ -127,7 +127,7 @@ class UploadSecurity
def insecure_context_checks
{
secure_media_disabled: "secure media is disabled",
secure_uploads_disabled: "secure uploads is disabled",
insecure_creation_for_modifiers: "one or more creation for_modifiers was satisfied",
public_type: "upload is public type",
custom_emoji: "upload is used for custom emoji",
@ -138,7 +138,7 @@ class UploadSecurity
def secure_context_checks
{
login_required: "login is required",
access_control_post_has_secure_media: "access control post dictates security",
access_control_post_has_secure_uploads: "access control post dictates security",
secure_creation_for_modifiers: "one or more creation for_modifiers was satisfied",
uploading_in_composer: "uploading via the composer",
already_secure: "upload is already secure"
@ -149,7 +149,7 @@ class UploadSecurity
# of whether an upload should be secure or not, and thus should be returned
# immediately if there is an access control post
def priority_check?(check)
check == :access_control_post_has_secure_media && access_control_post
check == :access_control_post_has_secure_uploads && access_control_post
end
def perform_check(check)

View File

@ -57,7 +57,7 @@ class UrlHelper
end
def self.secure_proxy_without_cdn(url)
self.absolute(Upload.secure_media_url_from_upload_url(url), nil)
self.absolute(Upload.secure_uploads_url_from_upload_url(url), nil)
end
def self.escape_uri(uri)
@ -105,14 +105,14 @@ class UrlHelper
end
def self.cook_url(url, secure: false, local: nil)
is_secure = SiteSetting.secure_media && secure
is_secure = SiteSetting.secure_uploads && secure
local = is_local(url) if local.nil?
return url if !local
url = is_secure ? secure_proxy_without_cdn(url) : absolute_without_cdn(url)
# we always want secure media to come from
# Discourse.base_url_no_prefix/secure-media-uploads
# we always want secure uploads to come from
# Discourse.base_url_no_prefix/secure-uploads
# to avoid asset_host mixups
return schemaless(url) if is_secure

View File

@ -222,14 +222,14 @@ RSpec.describe Jobs::PullHotlinkedImages do
expect(post.raw).to eq(raw)
end
context "when secure media enabled for an upload that has already been downloaded and exists" do
context "when secure uploads enabled for an upload that has already been downloaded and exists" do
it "doesnt redownload the secure upload" do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
upload = Fabricate(:secure_upload_s3, secure: true)
stub_s3(upload)
url = Upload.secure_media_url_from_upload_url(upload.url)
url = Upload.secure_uploads_url_from_upload_url(upload.url)
url = Discourse.base_url + url
post = Fabricate(:post, raw: "<img src='#{url}'>")
upload.update(access_control_post: post)
@ -240,12 +240,12 @@ RSpec.describe Jobs::PullHotlinkedImages do
context "when the upload original_sha1 is missing" do
it "redownloads the upload" do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
upload = Fabricate(:upload_s3, secure: true)
stub_s3(upload)
Upload.stubs(:signed_url_from_secure_media_url).returns(upload.url)
url = Upload.secure_media_url_from_upload_url(upload.url)
Upload.stubs(:signed_url_from_secure_uploads_url).returns(upload.url)
url = Upload.secure_uploads_url_from_upload_url(upload.url)
url = Discourse.base_url + url
post = Fabricate(:post, raw: "<img src='#{url}'>")
upload.update(access_control_post: post)
@ -261,12 +261,12 @@ RSpec.describe Jobs::PullHotlinkedImages do
context "when the upload access_control_post is different to the current post" do
it "redownloads the upload" do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
upload = Fabricate(:secure_upload_s3, secure: true)
stub_s3(upload)
Upload.stubs(:signed_url_from_secure_media_url).returns(upload.url)
url = Upload.secure_media_url_from_upload_url(upload.url)
Upload.stubs(:signed_url_from_secure_uploads_url).returns(upload.url)
url = Upload.secure_uploads_url_from_upload_url(upload.url)
url = Discourse.base_url + url
post = Fabricate(:post, raw: "<img src='#{url}'>")
upload.update(access_control_post: Fabricate(:post))
@ -466,14 +466,14 @@ RSpec.describe Jobs::PullHotlinkedImages do
expect(subject.should_download_image?(Fabricate(:upload).url)).to eq(false)
end
context "when secure media enabled" do
it 'should return false for secure-media-upload url' do
context "when secure uploads enabled" do
it 'should return false for secure-upload url' do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
upload = Fabricate(:upload_s3, secure: true)
stub_s3(upload)
url = Upload.secure_media_url_from_upload_url(upload.url)
url = Upload.secure_uploads_url_from_upload_url(upload.url)
expect(subject.should_download_image?(url)).to eq(false)
end
end

View File

@ -14,7 +14,7 @@ RSpec.describe Jobs::UpdatePostUploadsSecureStatus do
before do
setup_s3
stub_s3_store
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
context "when login_required" do

View File

@ -485,7 +485,7 @@ RSpec.describe CookedPostProcessor do
stub_upload(upload)
SiteSetting.login_required = true
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
let(:optimized_size) { "600x500" }
@ -496,7 +496,7 @@ RSpec.describe CookedPostProcessor do
let(:cooked_html) do
<<~HTML
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost/secure-media-uploads/original/1X/#{upload.sha1}.png" data-download-href="//test.localhost/uploads/short-url/#{upload.base62_sha1}.unknown?dl=1" title="large.png"><img src="" alt="large.png" data-base62-sha1="#{upload.base62_sha1}" width="600" height="500"><div class="meta">
<p><div class="lightbox-wrapper"><a class="lightbox" href="//test.localhost/secure-uploads/original/1X/#{upload.sha1}.png" data-download-href="//test.localhost/uploads/short-url/#{upload.base62_sha1}.unknown?dl=1" title="large.png"><img src="" alt="large.png" data-base62-sha1="#{upload.base62_sha1}" width="600" height="500"><div class="meta">
<svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">large.png</span><span class="informations">1750×2000 1.21 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg>
</div></a></div></p>
HTML
@ -1074,13 +1074,13 @@ RSpec.describe CookedPostProcessor do
Oneboxer.unstub(:onebox)
end
context "when the post is with_secure_media and the upload is secure and secure media is enabled" do
context "when the post is with_secure_uploads and the upload is secure and secure uploads is enabled" do
before do
setup_s3
upload.update(secure: true)
SiteSetting.login_required = true
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it "does not use the direct URL, uses the cooked URL instead (because of the private ACL preventing w/h fetch)" do
@ -1091,7 +1091,7 @@ RSpec.describe CookedPostProcessor do
PostHotlinkedMedia.create!(url: "//image.com/avatar.png", post: post, status: 'downloaded', upload: upload)
cooked_url = "https://localhost/secure-media-uploads/test.png"
cooked_url = "https://localhost/secure-uploads/test.png"
UrlHelper.expects(:cook_url).with(upload.url, secure: true).returns(cooked_url)
cpp = CookedPostProcessor.new(post, invalidate_oneboxes: true)
@ -1417,8 +1417,8 @@ RSpec.describe CookedPostProcessor do
HTML
end
it "doesn't use CDN for secure media" do
SiteSetting.secure_media = true
it "doesn't use CDN for secure uploads" do
SiteSetting.secure_uploads = true
stored_path = Discourse.store.get_path_for_upload(upload)
upload.update_column(:url, "#{SiteSetting.Upload.absolute_base_url}/#{stored_path}")
@ -1431,11 +1431,11 @@ RSpec.describe CookedPostProcessor do
expect(cpp.html).to match_html <<~HTML
<p>This post has a local emoji <img src="https://local.cdn.com/images/emoji/twitter/+1.png?v=#{Emoji::EMOJI_VERSION}" title=":+1:" class="emoji" alt=":+1:" loading="lazy" width="20" height="20"> and an external upload</p>
<p><img src="/secure-media-uploads/#{stored_path}" alt="smallest.png" data-base62-sha1="#{upload.base62_sha1}" width="10" height="20"></p>
<p><img src="/secure-uploads/#{stored_path}" alt="smallest.png" data-base62-sha1="#{upload.base62_sha1}" width="10" height="20"></p>
HTML
end
it "doesn't use the secure media URL for custom emoji" do
it "doesn't use the secure uploads URL for custom emoji" do
CustomEmoji.create!(name: 'trout', upload: upload)
Emoji.clear_cache
Emoji.load_custom
@ -1484,9 +1484,9 @@ RSpec.describe CookedPostProcessor do
HTML
end
it "oneboxes video using secure url when secure_media is enabled" do
it "oneboxes video using secure url when secure_uploads is enabled" do
SiteSetting.login_required = true
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
video_upload.update_column(:secure, true)
the_post = Fabricate(:post, raw: "This post has an S3 video onebox:\n#{video_upload.url}")
@ -1494,7 +1494,7 @@ RSpec.describe CookedPostProcessor do
cpp = CookedPostProcessor.new(the_post)
cpp.post_process_oneboxes
secure_url = video_upload.url.sub(SiteSetting.s3_cdn_url, "#{Discourse.base_url}/secure-media-uploads")
secure_url = video_upload.url.sub(SiteSetting.s3_cdn_url, "#{Discourse.base_url}/secure-uploads")
expect(cpp.html).to match_html <<~HTML
<p>This post has an S3 video onebox:</p><div class="onebox video-onebox">
@ -1506,9 +1506,9 @@ RSpec.describe CookedPostProcessor do
HTML
end
it "oneboxes only audio/video and not images when secure_media is enabled" do
it "oneboxes only audio/video and not images when secure_uploads is enabled" do
SiteSetting.login_required = true
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
video_upload.update_column(:secure, true)
@ -1541,8 +1541,8 @@ RSpec.describe CookedPostProcessor do
cpp = CookedPostProcessor.new(the_post)
cpp.post_process_oneboxes
secure_video_url = video_upload.url.sub(SiteSetting.s3_cdn_url, "#{Discourse.base_url}/secure-media-uploads")
secure_audio_url = audio_upload.url.sub(SiteSetting.s3_cdn_url, "#{Discourse.base_url}/secure-media-uploads")
secure_video_url = video_upload.url.sub(SiteSetting.s3_cdn_url, "#{Discourse.base_url}/secure-uploads")
secure_audio_url = audio_upload.url.sub(SiteSetting.s3_cdn_url, "#{Discourse.base_url}/secure-uploads")
expect(cpp.html).to match_html <<~HTML
<p>This post has a video upload.</p>

View File

@ -4,7 +4,7 @@ require 'email/sender'
RSpec.describe Email::Sender do
before do
SiteSetting.secure_media_allow_embed_images_in_emails = false
SiteSetting.secure_uploads_allow_embed_images_in_emails = false
end
fab!(:post) { Fabricate(:post) }
let(:mock_smtp_transaction_response) { "250 Ok: queued as 2l3Md07BObzB8kRyHZeoN0baSUAhzc7A-NviRioOr80=@mailhog.example" }
@ -535,15 +535,15 @@ RSpec.describe Email::Sender do
.to contain_exactly(*[small_pdf, large_pdf, csv_file].map(&:original_filename))
end
context "when secure media enabled" do
context "when secure uploads enabled" do
before do
setup_s3
store = stub_s3_store
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
SiteSetting.login_required = true
SiteSetting.email_total_attachment_size_limit_kb = 14_000
SiteSetting.secure_media_max_email_embed_image_size_kb = 5_000
SiteSetting.secure_uploads_max_email_embed_image_size_kb = 5_000
Jobs.run_immediately!
Jobs::PullHotlinkedImages.any_instance.expects(:execute)
@ -566,7 +566,7 @@ RSpec.describe Email::Sender do
context "when embedding secure images in email is allowed" do
before do
SiteSetting.secure_media_allow_embed_images_in_emails = true
SiteSetting.secure_uploads_allow_embed_images_in_emails = true
end
it "can inline images with duplicate names" do
@ -590,7 +590,7 @@ RSpec.describe Email::Sender do
end
it "does not embed images that are too big" do
SiteSetting.secure_media_max_email_embed_image_size_kb = 1
SiteSetting.secure_uploads_max_email_embed_image_size_kb = 1
Email::Sender.new(message, :valid_type).send
expect(message.attachments.length).to eq(3)
end

View File

@ -208,32 +208,32 @@ RSpec.describe Email::Styles do
end
end
describe "replace_secure_media_urls" do
describe "replace_secure_uploads_urls" do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
let(:attachments) { { 'testimage.png' => stub(url: 'email/test.png') } }
it "replaces secure media within a link with a placeholder" do
frag = html_fragment("<a href=\"#{Discourse.base_url}\/secure-media-uploads/original/1X/testimage.png\"><img src=\"/secure-media-uploads/original/1X/testimage.png\"></a>")
it "replaces secure uploads within a link with a placeholder" do
frag = html_fragment("<a href=\"#{Discourse.base_url}\/secure-uploads/original/1X/testimage.png\"><img src=\"/secure-uploads/original/1X/testimage.png\"></a>")
expect(frag.at('img')).not_to be_present
expect(frag.to_s).to include("Redacted")
end
it "replaces secure images with a placeholder" do
frag = html_fragment("<img src=\"/secure-media-uploads/original/1X/testimage.png\">")
frag = html_fragment("<img src=\"/secure-uploads/original/1X/testimage.png\">")
expect(frag.at('img')).not_to be_present
expect(frag.to_s).to include("Redacted")
end
it "does not replace topic links with secure-media-uploads in the name" do
frag = html_fragment("<a href=\"#{Discourse.base_url}\/t/secure-media-uploads/235723\">Visit Topic</a>")
it "does not replace topic links with secure-uploads in the name" do
frag = html_fragment("<a href=\"#{Discourse.base_url}\/t/secure-uploads/235723\">Visit Topic</a>")
expect(frag.to_s).not_to include("Redacted")
end
it "works in lightboxes with missing srcset attribute" do
frag = html_fragment("<a href=\"#{Discourse.base_url}\/secure-media-uploads/original/1X/testimage.png\" class=\"lightbox\"><img src=\"/secure-media-uploads/original/1X/testimage.png\"></a>")
frag = html_fragment("<a href=\"#{Discourse.base_url}\/secure-uploads/original/1X/testimage.png\" class=\"lightbox\"><img src=\"/secure-uploads/original/1X/testimage.png\"></a>")
expect(frag.at('img')).not_to be_present
expect(frag.to_s).to include("Redacted")
end
@ -241,8 +241,8 @@ RSpec.describe Email::Styles do
it "works in lightboxes with srcset attribute set" do
frag = html_fragment(
<<~HTML
<a href="#{Discourse.base_url}/secure-media-uploads/original/1X/testimage.png" class="lightbox">
<img src="/secure-media-uploads/original/1X/testimage.png" srcset="/secure-media-uploads/optimized/1X/testimage.png, /secure-media-uploads/original/1X/testimage.png 1.5x" />
<a href="#{Discourse.base_url}/secure-uploads/original/1X/testimage.png" class="lightbox">
<img src="/secure-uploads/original/1X/testimage.png" srcset="/secure-uploads/optimized/1X/testimage.png, /secure-uploads/original/1X/testimage.png 1.5x" />
</a>
HTML
)
@ -252,7 +252,7 @@ RSpec.describe Email::Styles do
end
it "skips links with no images as children" do
frag = html_fragment("<a href=\"#{Discourse.base_url}\/secure-media-uploads/original/1X/testimage.png\"><span>Clearly not an image</span></a>")
frag = html_fragment("<a href=\"#{Discourse.base_url}\/secure-uploads/original/1X/testimage.png\"><span>Clearly not an image</span></a>")
expect(frag.to_s).to include("not an image")
end
@ -261,16 +261,16 @@ RSpec.describe Email::Styles do
describe "inline_secure_images" do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
fab!(:upload) { Fabricate(:upload, original_filename: 'testimage.png', secure: true, sha1: '123456') }
let(:attachments) { [stub(url: 'cid:email/test.png')] }
let(:attachments_index) { { upload.sha1 => 0 } }
let(:html) { "<a href=\"#{Discourse.base_url}\/secure-media-uploads/original/1X/123456.png\"><img src=\"/secure-media-uploads/original/1X/123456.png\" width=\"20\" height=\"30\"></a>" }
let(:html) { "<a href=\"#{Discourse.base_url}\/secure-uploads/original/1X/123456.png\"><img src=\"/secure-uploads/original/1X/123456.png\" width=\"20\" height=\"30\"></a>" }
def strip_and_inline
# strip out the secure media
# strip out the secure uploads
styler = Email::Styles.new(html)
styler.format_basic
styler.format_html
@ -285,7 +285,7 @@ RSpec.describe Email::Styles do
it "inlines attachments where stripped-secure-media data attr is present" do
strip_and_inline
expect(@frag.to_s).to include("cid:email/test.png")
expect(@frag.css('[data-stripped-secure-media]')).not_to be_present
expect(@frag.css('[data-stripped-secure-upload]')).not_to be_present
expect(@frag.children.attr('style').value).to eq("width: 20px; height: 30px;")
end
@ -294,17 +294,17 @@ RSpec.describe Email::Styles do
strip_and_inline
expect(@frag.to_s).not_to include("cid:email/test.png")
expect(@frag.css('[data-stripped-secure-media]')).to be_present
expect(@frag.css('[data-stripped-secure-upload]')).to be_present
end
context "when an optimized image is used instead of the original" do
let(:html) { "<a href=\"#{Discourse.base_url}\/secure-media-uploads/optimized/2X/1/123456_2_20x30.png\"><img src=\"/secure-media-uploads/optimized/2X/1/123456_2_20x30.png\" width=\"20\" height=\"30\"></a>" }
let(:html) { "<a href=\"#{Discourse.base_url}\/secure-uploads/optimized/2X/1/123456_2_20x30.png\"><img src=\"/secure-uploads/optimized/2X/1/123456_2_20x30.png\" width=\"20\" height=\"30\"></a>" }
it "inlines attachments where the stripped-secure-media data attr is present" do
optimized = Fabricate(:optimized_image, upload: upload, width: 20, height: 30)
strip_and_inline
expect(@frag.to_s).to include("cid:email/test.png")
expect(@frag.css('[data-stripped-secure-media]')).not_to be_present
expect(@frag.css('[data-stripped-secure-upload]')).not_to be_present
expect(@frag.children.attr('style').value).to eq("width: 20px; height: 30px;")
end
end
@ -321,11 +321,11 @@ RSpec.describe Email::Styles do
<<~HTML
<aside class="onebox allowlistedgeneric">
<header class="source">
<img src="#{Discourse.base_url}/secure-media-uploads/original/1X/#{siteicon.sha1}.ico" class="site-icon" width="64" height="64">
<img src="#{Discourse.base_url}/secure-uploads/original/1X/#{siteicon.sha1}.ico" class="site-icon" width="64" height="64">
<a href="https://test.com/article" target="_blank" rel="noopener" title="02:33PM - 24 October 2020">Test</a>
</header>
<article class="onebox-body">
<div class="aspect-image" style="--aspect-ratio:20/30;"><img src="#{Discourse.base_url}/secure-media-uploads/optimized/2X/1/123456_2_20x30.png" class="thumbnail d-lazyload" width="20" height="30" srcset="#{Discourse.base_url}/secure-media-uploads/optimized/2X/1/123456_2_20x30.png"></div>
<div class="aspect-image" style="--aspect-ratio:20/30;"><img src="#{Discourse.base_url}/secure-uploads/optimized/2X/1/123456_2_20x30.png" class="thumbnail d-lazyload" width="20" height="30" srcset="#{Discourse.base_url}/secure-uploads/optimized/2X/1/123456_2_20x30.png"></div>
<h3><a href="https://test.com/article" target="_blank" rel="noopener">Test</a></h3>
@ -344,7 +344,7 @@ RSpec.describe Email::Styles do
strip_and_inline
expect(@frag.to_s).to include("cid:email/test.png")
expect(@frag.to_s).to include("cid:email/test2.ico")
expect(@frag.css('[data-stripped-secure-media]')).not_to be_present
expect(@frag.css('[data-stripped-secure-upload]')).not_to be_present
expect(@frag.css('[data-embedded-secure-image]')[0].attr('style')).to eq('width: 16px; height: 16px;')
expect(@frag.css('[data-embedded-secure-image]')[1].attr('style')).to eq('width: 60px; max-height: 80%; max-width: 20%; height: auto; float: left; margin-right: 10px;')
end
@ -354,11 +354,11 @@ RSpec.describe Email::Styles do
<<~HTML
<aside class="onebox allowlistedgeneric">
<header class="source">
<img src="#{Discourse.base_url}/secure-media-uploads/original/1X/#{siteicon.sha1}.ico" class="site-icon" width="64" height="64">
<img src="#{Discourse.base_url}/secure-uploads/original/1X/#{siteicon.sha1}.ico" class="site-icon" width="64" height="64">
<a href="https://test.com/article" target="_blank" rel="noopener" title="02:33PM - 24 October 2020">Test</a>
</header>
<article class="onebox-body">
<img src="#{Discourse.base_url}/secure-media-uploads/original/1X/123456.png" class="thumbnail onebox-avatar" width="20" height="30">
<img src="#{Discourse.base_url}/secure-uploads/original/1X/123456.png" class="thumbnail onebox-avatar" width="20" height="30">
<h3><a href="https://test.com/article" target="_blank" rel="noopener">Test</a></h3>
@ -376,7 +376,7 @@ RSpec.describe Email::Styles do
strip_and_inline
expect(@frag.to_s).to include("cid:email/test.png")
expect(@frag.to_s).to include("cid:email/test2.ico")
expect(@frag.css('[data-stripped-secure-media]')).not_to be_present
expect(@frag.css('[data-stripped-secure-upload]')).not_to be_present
expect(@frag.css('[data-embedded-secure-image]')[1].attr('style')).to eq('width: 60px; max-height: 80%; max-width: 20%; height: auto; float: left; margin-right: 10px;')
end
end
@ -405,7 +405,7 @@ RSpec.describe Email::Styles do
</div>
<div class="user">
<a href="https://github.com/udan11" target="_blank" rel="noopener">
<img alt="udan11" src="#{Discourse.base_url}/secure-media-uploads/original/1X/123456.png" class="onebox-avatar-inline" width="20" height="20">
<img alt="udan11" src="#{Discourse.base_url}/secure-uploads/original/1X/123456.png" class="onebox-avatar-inline" width="20" height="20">
udan11
</a>
</div>
@ -428,7 +428,7 @@ RSpec.describe Email::Styles do
it "keeps the special onebox styles" do
strip_and_inline
expect(@frag.to_s).to include("cid:email/test.png")
expect(@frag.css('[data-stripped-secure-media]')).not_to be_present
expect(@frag.css('[data-stripped-secure-upload]')).not_to be_present
expect(@frag.css('[data-embedded-secure-image]')[0].attr('style')).to eq('width: 20px; height: 20px; float: none; vertical-align: middle; max-height: 80%; max-width: 20%; height: auto; float: left; margin-right: 10px;')
end
end

View File

@ -173,9 +173,9 @@ RSpec.describe FileStore::BaseStore do
expect(file.class).to eq(File)
end
it "should return the file when secure media are enabled" do
it "should return the file when secure uploads are enabled" do
SiteSetting.login_required = true
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
stub_request(:head, "https://s3-upload-bucket.s3.#{SiteSetting.s3_region}.amazonaws.com/")
signed_url = Discourse.store.signed_url_for_path(upload_s3.url)

View File

@ -3864,10 +3864,10 @@ RSpec.describe Guardian do
expect(Guardian.new(admin).can_publish_page?(post.topic)).to eq(false)
end
context "when secure_media is also enabled" do
context "when secure_uploads is also enabled" do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it "is false for everyone" do

View File

@ -1839,7 +1839,7 @@ RSpec.describe PostCreator do
end
end
describe "secure media uploads" do
describe "secure uploads uploads" do
fab!(:image_upload) { Fabricate(:upload, secure: true) }
fab!(:user2) { Fabricate(:user) }
fab!(:public_topic) { Fabricate(:topic) }
@ -1847,7 +1847,7 @@ RSpec.describe PostCreator do
before do
setup_s3
SiteSetting.authorized_extensions = "png|jpg|gif|mp4"
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
stub_upload(image_upload)
end

View File

@ -1242,13 +1242,13 @@ RSpec.describe PostRevisor do
expect(post.reload.upload_references.pluck(:upload_id)).to contain_exactly(image2.id, image3.id, image4.id)
end
context "with secure media uploads" do
context "with secure uploads uploads" do
let!(:image5) { Fabricate(:secure_upload) }
before do
Jobs.run_immediately!
setup_s3
SiteSetting.authorized_extensions = "png|jpg|gif|mp4"
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
stub_upload(image5)
end

View File

@ -1125,19 +1125,19 @@ RSpec.describe PrettyText do
end
end
describe "#strip_secure_media" do
describe "#strip_secure_uploads" do
before do
setup_s3
SiteSetting.s3_cdn_url = "https://s3.cdn.com"
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
SiteSetting.login_required = true
end
it "replaces secure video content" do
html = <<~HTML
<video width="100%" height="100%" controls="">
<source src="#{base_url}/secure-media-uploads/original/1X/some-video.mp4">
<a href="#{base_url}/secure-media-uploads/original/1X/some-video.mp4">Video label</a>
<source src="#{base_url}/secure-uploads/original/1X/some-video.mp4">
<a href="#{base_url}/secure-uploads/original/1X/some-video.mp4">Video label</a>
</source>
</video>
HTML
@ -1145,58 +1145,58 @@ RSpec.describe PrettyText do
md = PrettyText.format_for_email(html, post)
expect(md).not_to include('<video')
expect(md.to_s).to match(I18n.t("emails.secure_media_placeholder"))
expect(md.to_s).to match(I18n.t("emails.secure_uploads_placeholder"))
expect(md.to_s).not_to match(SiteSetting.Upload.s3_cdn_url)
end
it "replaces secure audio content" do
html = <<~HTML
<audio controls>
<source src="#{base_url}/secure-media-uploads/original/1X/some-audio.mp3">
<a href="#{base_url}/secure-media-uploads/original/1X/some-audio.mp3">Audio label</a>
<source src="#{base_url}/secure-uploads/original/1X/some-audio.mp3">
<a href="#{base_url}/secure-uploads/original/1X/some-audio.mp3">Audio label</a>
</source>
</audio>
HTML
md = PrettyText.format_for_email(html, post)
expect(md).not_to include('<video')
expect(md.to_s).to match(I18n.t("emails.secure_media_placeholder"))
expect(md).not_to include('<audio')
expect(md.to_s).to match(I18n.t("emails.secure_uploads_placeholder"))
expect(md.to_s).not_to match(SiteSetting.Upload.s3_cdn_url)
end
it "replaces secure media within a link with a placeholder, keeping the url in an attribute" do
url = "#{Discourse.base_url}\/secure-media-uploads/original/1X/testimage.png"
it "replaces secure uploads within a link with a placeholder, keeping the url in an attribute" do
url = "#{Discourse.base_url}\/secure-uploads/original/1X/testimage.png"
html = <<~HTML
<a href=\"#{url}\"><img src=\"/secure-media-uploads/original/1X/testimage.png\"></a>
<a href=\"#{url}\"><img src=\"/secure-uploads/original/1X/testimage.png\"></a>
HTML
md = PrettyText.format_for_email(html, post)
expect(md).not_to include('<img')
expect(md).to include("Redacted")
expect(md).to include("data-stripped-secure-media=\"#{url}\"")
expect(md).to include("data-stripped-secure-upload=\"#{url}\"")
end
it "does not create nested redactions from double processing because of the view media link" do
url = "#{Discourse.base_url}\/secure-media-uploads/original/1X/testimage.png"
url = "#{Discourse.base_url}\/secure-uploads/original/1X/testimage.png"
html = <<~HTML
<a href=\"#{url}\"><img src=\"/secure-media-uploads/original/1X/testimage.png\"></a>
<a href=\"#{url}\"><img src=\"/secure-uploads/original/1X/testimage.png\"></a>
HTML
md = PrettyText.format_for_email(html, post)
md = PrettyText.format_for_email(md, post)
expect(md.scan(/stripped-secure-view-media/).length).to eq(1)
expect(md.scan(/stripped-secure-view-upload/).length).to eq(1)
expect(md.scan(/Redacted/).length).to eq(1)
end
it "replaces secure images with a placeholder, keeping the url in an attribute" do
url = "/secure-media-uploads/original/1X/testimage.png"
url = "/secure-uploads/original/1X/testimage.png"
html = <<~HTML
<img src=\"#{url}\" width=\"20\" height=\"20\">
HTML
md = PrettyText.format_for_email(html, post)
expect(md).not_to include('<img')
expect(md).to include("Redacted")
expect(md).to include("data-stripped-secure-media=\"#{url}\"")
expect(md).to include("data-stripped-secure-upload=\"#{url}\"")
expect(md).to include("data-width=\"20\"")
expect(md).to include("data-height=\"20\"")
end

View File

@ -210,10 +210,10 @@ RSpec.describe SiteSettings::Validations do
expect { subject.validate_enable_page_publishing("t") }.not_to raise_error
end
context "if secure media is enabled" do
context "if secure uploads is enabled" do
let(:error_message) { I18n.t("errors.site_settings.page_publishing_requirements") }
before do
enable_secure_media
enable_secure_uploads
end
it "is not ok" do
@ -223,8 +223,8 @@ RSpec.describe SiteSettings::Validations do
end
end
describe "#validate_secure_media" do
let(:error_message) { I18n.t("errors.site_settings.secure_media_requirements") }
describe "#validate_secure_uploads" do
let(:error_message) { I18n.t("errors.site_settings.secure_uploads_requirements") }
context "when the new value is true" do
context 'if site setting for enable_s3_uploads is enabled' do
@ -233,7 +233,7 @@ RSpec.describe SiteSettings::Validations do
end
it "should be ok" do
expect { subject.validate_secure_media("t") }.not_to raise_error
expect { subject.validate_secure_uploads("t") }.not_to raise_error
end
end
@ -243,7 +243,7 @@ RSpec.describe SiteSettings::Validations do
end
it "is not ok" do
expect { subject.validate_secure_media("t") }.to raise_error(Discourse::InvalidParameters, error_message)
expect { subject.validate_secure_uploads("t") }.to raise_error(Discourse::InvalidParameters, error_message)
end
context "if global s3 setting is enabled" do
@ -252,7 +252,7 @@ RSpec.describe SiteSettings::Validations do
end
it "should be ok" do
expect { subject.validate_secure_media("t") }.not_to raise_error
expect { subject.validate_secure_uploads("t") }.not_to raise_error
end
end
end

View File

@ -27,10 +27,10 @@ RSpec.describe TopicUploadSecurityManager do
context "when the topic category is read restricted" do
let(:category) { Fabricate(:private_category, group: group) }
context "when secure media is enabled" do
context "when secure uploads is enabled" do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
[upload, upload2, upload3].each { |upl| stub_upload(upl) }
end
@ -49,7 +49,7 @@ RSpec.describe TopicUploadSecurityManager do
end
end
context "when secure media is disabled" do
context "when secure uploads is disabled" do
it "changes the upload secure statuses to false and updates ACLs and rebakes" do
expect_upload_status_to_change_and_rebake
end
@ -59,10 +59,10 @@ RSpec.describe TopicUploadSecurityManager do
context "when the topic is a private message" do
let(:topic) { Fabricate(:private_message_topic, category: category, user: user) }
context "when secure media is enabled" do
context "when secure uploads is enabled" do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
[upload, upload2, upload3].each { |upl| stub_upload(upl) }
end
@ -81,7 +81,7 @@ RSpec.describe TopicUploadSecurityManager do
end
end
context "when secure media is disabled" do
context "when secure uploads is disabled" do
it "changes the upload secure statuses to false and updates ACLs and rebakes" do
expect_upload_status_to_change_and_rebake
end
@ -89,10 +89,10 @@ RSpec.describe TopicUploadSecurityManager do
end
context "when the topic is public" do
context "when secure media is enabled" do
context "when secure uploads is enabled" do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
[upload, upload2, upload3].each { |upl| stub_upload(upl) }
end
@ -125,7 +125,7 @@ RSpec.describe TopicUploadSecurityManager do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
[upload, upload2, upload3].each { |upl| stub_upload(upl) }
end
@ -142,9 +142,9 @@ RSpec.describe TopicUploadSecurityManager do
expect(upload3.reload.access_control_post).to eq(post4)
end
context "when secure media is not enabled" do
context "when secure uploads is not enabled" do
before do
SiteSetting.secure_media = false
SiteSetting.secure_uploads = false
end
it "does not change the upload secure status and does not set the access control post" do

View File

@ -305,7 +305,7 @@ RSpec.describe UploadCreator do
setup_s3
stub_s3_store
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
SiteSetting.authorized_extensions = 'pdf|svg|jpg'
end
@ -357,7 +357,7 @@ RSpec.describe UploadCreator do
it 'should return signed URL for secure attachments in S3' do
SiteSetting.authorized_extensions = 'pdf'
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
upload = UploadCreator.new(pdf_file, pdf_filename, opts).create_for(user.id)
stored_upload = Upload.last
@ -399,12 +399,12 @@ RSpec.describe UploadCreator do
end
end
context "when SiteSetting.secure_media is enabled" do
context "when SiteSetting.secure_uploads is enabled" do
before do
setup_s3
stub_s3_store
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it "does not return the existing upload, as duplicate uploads are allowed" do
@ -413,18 +413,18 @@ RSpec.describe UploadCreator do
end
end
context "with secure media functionality" do
context "with secure uploads functionality" do
let(:filename) { "logo.jpg" }
let(:file) { file_from_fixtures(filename) }
let(:opts) { {} }
let(:result) { UploadCreator.new(file, filename, opts).create_for(user.id) }
context "when SiteSetting.secure_media enabled" do
context "when SiteSetting.secure_uploads enabled" do
before do
setup_s3
stub_s3_store
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it "sets an original_sha1 on the upload created because the sha1 column is securerandom in this case" do

View File

@ -161,7 +161,7 @@ RSpec.describe UploadRecovery do
end
it 'does not create a duplicate upload when secure uploads are enabled' do
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
upload.verification_status = Upload.verification_statuses[:invalid_etag]
upload.save!

View File

@ -8,10 +8,10 @@ RSpec.describe UploadSecurity do
let(:opts) { { type: type, creating: true } }
subject { described_class.new(upload, opts) }
context "when secure media is enabled" do
context "when secure uploads is enabled" do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
context "when login_required (everything should be secure except public context items)" do
@ -126,7 +126,7 @@ RSpec.describe UploadSecurity do
end
end
context "when the access control post has_secure_media?" do
context "when the access control post has_secure_uploads?" do
before do
upload.update(access_control_post_id: post_in_secure_context.id)
end
@ -138,7 +138,7 @@ RSpec.describe UploadSecurity do
before do
post_in_secure_context.trash!
end
it "still determines whether the post has secure media; returns true" do
it "still determines whether the post has secure uploads; returns true" do
expect(subject.should_be_secure?).to eq(true)
end
end
@ -180,7 +180,7 @@ RSpec.describe UploadSecurity do
upload.update(original_filename: 'test.pdf')
end
context "when the access control post has_secure_media?" do
context "when the access control post has_secure_uploads?" do
before do
upload.update(access_control_post: post_in_secure_context)
end
@ -191,9 +191,9 @@ RSpec.describe UploadSecurity do
end
end
context "when secure media is disabled" do
context "when secure uploads is disabled" do
before do
SiteSetting.secure_media = false
SiteSetting.secure_uploads = false
end
it "returns false" do
expect(subject.should_be_secure?).to eq(false)

View File

@ -197,7 +197,7 @@ RSpec.describe UrlHelper do
FileStore::S3Store.any_instance.stubs(:has_been_uploaded?).returns(true)
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
def cooked
@ -209,12 +209,12 @@ RSpec.describe UrlHelper do
it "returns the secure_proxy_without_cdn url, with no asset host URL change" do
expect(cooked).to eq(
"//test.localhost/secure-media-uploads/dev/original/3X/2/e/2e6f2ef81b6910ea592cd6d21ee897cd51cf72e4.jpeg"
"//test.localhost/secure-uploads/dev/original/3X/2/e/2e6f2ef81b6910ea592cd6d21ee897cd51cf72e4.jpeg"
)
end
context "when secure_media setting is disabled" do
before { SiteSetting.secure_media = false }
context "when secure_uploads setting is disabled" do
before { SiteSetting.secure_uploads = false }
it "returns the local_cdn_url" do
expect(cooked).to eq(

View File

@ -344,7 +344,7 @@ RSpec.describe OptimizedImage do
end
context "when the thumbnail is properly generated" do
context "with secure media disabled" do
context "with secure uploads disabled" do
let(:s3_upload) { Fabricate(:upload_s3) }
let(:optimized_path) { %r{/optimized/\d+X.*/#{s3_upload.sha1}_2_100x200\.png} }

View File

@ -149,25 +149,25 @@ RSpec.describe Post do
end
end
describe "with_secure_media?" do
describe "with_secure_uploads?" do
let(:topic) { Fabricate(:topic) }
let!(:post) { Fabricate(:post, topic: topic) }
it "returns false if secure media is not enabled" do
expect(post.with_secure_media?).to eq(false)
it "returns false if secure uploads is not enabled" do
expect(post.with_secure_uploads?).to eq(false)
end
context "when secure media is enabled" do
context "when secure uploads is enabled" do
before do
setup_s3
SiteSetting.authorized_extensions = "pdf|png|jpg|csv"
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
context "if login_required" do
before { SiteSetting.login_required = true }
it "returns true" do
expect(post.with_secure_media?).to eq(true)
expect(post.with_secure_uploads?).to eq(true)
end
end
@ -178,7 +178,7 @@ RSpec.describe Post do
end
it "returns true" do
expect(post.with_secure_media?).to eq(true)
expect(post.with_secure_uploads?).to eq(true)
end
end
@ -186,7 +186,7 @@ RSpec.describe Post do
let(:topic) { Fabricate(:private_message_topic) }
it "returns true" do
expect(post.with_secure_media?).to eq(true)
expect(post.with_secure_uploads?).to eq(true)
end
end
end
@ -1476,11 +1476,11 @@ RSpec.describe Post do
expect(post.reload.upload_references.pluck(:id)).to_not contain_exactly(post_uploads_ids)
end
context "when secure media is enabled" do
context "when secure uploads is enabled" do
before do
setup_s3
SiteSetting.authorized_extensions = "pdf|png|jpg|csv"
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it "sets the access_control_post_id on uploads in the post that don't already have the value set" do
@ -1523,7 +1523,7 @@ RSpec.describe Post do
setup_s3
SiteSetting.authorized_extensions = "pdf|png|jpg|csv"
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
attachment_upload.update!(original_filename: "hello.csv")
@ -1531,8 +1531,8 @@ RSpec.describe Post do
stub_upload(image_upload)
end
it "marks image and attachment uploads as secure in PMs when secure_media is ON" do
SiteSetting.secure_media = true
it "marks image and attachment uploads as secure in PMs when secure_uploads is ON" do
SiteSetting.secure_uploads = true
post = Fabricate(:post, raw: raw, user: user, topic: Fabricate(:private_message_topic, user: user))
post.link_post_uploads
post.update_uploads_secure_status(source: "test")
@ -1543,8 +1543,8 @@ RSpec.describe Post do
)
end
it "marks image uploads as not secure in PMs when when secure_media is ON" do
SiteSetting.secure_media = false
it "marks image uploads as not secure in PMs when when secure_uploads is ON" do
SiteSetting.secure_uploads = false
post = Fabricate(:post, raw: raw, user: user, topic: Fabricate(:private_message_topic, user: user))
post.link_post_uploads
post.update_uploads_secure_status(source: "test")
@ -1556,7 +1556,7 @@ RSpec.describe Post do
end
it "marks attachments as secure when relevant setting is enabled" do
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
private_category = Fabricate(:private_category, group: Fabricate(:group))
post = Fabricate(:post, raw: raw, user: user, topic: Fabricate(:topic, user: user, category: private_category))
post.link_post_uploads
@ -1697,7 +1697,7 @@ RSpec.describe Post do
it "correctly identifies secure uploads" do
setup_s3
SiteSetting.authorized_extensions = "pdf|png|jpg|csv"
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
upload1 = Fabricate(:upload_s3, secure: true)
upload2 = Fabricate(:upload_s3, secure: true)

View File

@ -399,9 +399,9 @@ RSpec.describe Upload do
let(:upload) { Fabricate(:upload, original_filename: "small.pdf", extension: "pdf", secure: true) }
it 'marks a local attachment as secure if secure media enabled' do
it 'marks a local attachment as secure if secure uploads enabled' do
upload.update!(secure: false, access_control_post: Fabricate(:private_message_post))
enable_secure_media
enable_secure_uploads
expect { upload.update_secure_status }
.to change { upload.secure }
@ -409,7 +409,7 @@ RSpec.describe Upload do
expect(upload.secure).to eq(true)
end
it 'marks a local attachment as not secure if secure media enabled' do
it 'marks a local attachment as not secure if secure uploads enabled' do
expect { upload.update_secure_status }
.to change { upload.secure }
@ -428,9 +428,9 @@ RSpec.describe Upload do
expect(upload.secure).to eq(false)
end
context "with secure media enabled" do
context "with secure uploads enabled" do
before do
enable_secure_media
enable_secure_uploads
end
it "does not mark an image upload as not secure when there is no access control post id, to avoid unintentional exposure" do
@ -543,9 +543,9 @@ RSpec.describe Upload do
end
end
def enable_secure_media
def enable_secure_uploads
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
stub_upload(upload)
end
@ -568,54 +568,54 @@ RSpec.describe Upload do
end
end
describe ".secure_media_url_from_upload_url" do
describe ".secure_uploads_url_from_upload_url" do
before do
# must be done so signed_url_for_path exists
enable_secure_media
enable_secure_uploads
end
it "gets the secure media url from an S3 upload url" do
it "gets the secure uploads url from an S3 upload url" do
upload = Fabricate(:upload_s3, secure: true)
url = upload.url
secure_url = Upload.secure_media_url_from_upload_url(url)
secure_url = Upload.secure_uploads_url_from_upload_url(url)
expect(secure_url).not_to include(SiteSetting.Upload.absolute_base_url)
end
end
describe ".secure_media_url?" do
it "works for a secure media url with or without schema + host" do
url = "//localhost:3000/secure-media-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.png"
expect(Upload.secure_media_url?(url)).to eq(true)
url = "/secure-media-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.png"
expect(Upload.secure_media_url?(url)).to eq(true)
url = "http://localhost:3000/secure-media-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.png"
expect(Upload.secure_media_url?(url)).to eq(true)
describe ".secure_uploads_url?" do
it "works for a secure uploads url with or without schema + host" do
url = "//localhost:3000/secure-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.png"
expect(Upload.secure_uploads_url?(url)).to eq(true)
url = "/secure-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.png"
expect(Upload.secure_uploads_url?(url)).to eq(true)
url = "http://localhost:3000/secure-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.png"
expect(Upload.secure_uploads_url?(url)).to eq(true)
end
it "does not get false positives on a topic url" do
url = "/t/secure-media-uploads-are-cool/42839"
expect(Upload.secure_media_url?(url)).to eq(false)
url = "/t/secure-uploads-are-cool/42839"
expect(Upload.secure_uploads_url?(url)).to eq(false)
end
it "returns true only for secure media URL for actual media (images/video/audio)" do
url = "/secure-media-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.mp4"
expect(Upload.secure_media_url?(url)).to eq(true)
url = "/secure-media-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.png"
expect(Upload.secure_media_url?(url)).to eq(true)
url = "/secure-media-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.mp3"
expect(Upload.secure_media_url?(url)).to eq(true)
url = "/secure-media-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.pdf"
expect(Upload.secure_media_url?(url)).to eq(false)
it "returns true only for secure uploads URL for actual media (images/video/audio)" do
url = "/secure-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.mp4"
expect(Upload.secure_uploads_url?(url)).to eq(true)
url = "/secure-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.png"
expect(Upload.secure_uploads_url?(url)).to eq(true)
url = "/secure-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.mp3"
expect(Upload.secure_uploads_url?(url)).to eq(true)
url = "/secure-uploads/original/2X/f/f62055931bb702c7fd8f552fb901f977e0289a18.pdf"
expect(Upload.secure_uploads_url?(url)).to eq(false)
end
it "does not work for regular upload urls" do
url = "/uploads/default/test_0/original/1X/e1864389d8252958586c76d747b069e9f68827e3.png"
expect(Upload.secure_media_url?(url)).to eq(false)
expect(Upload.secure_uploads_url?(url)).to eq(false)
end
it "does not raise for invalid URLs" do
url = "http://URL:%20https://google.com"
expect(Upload.secure_media_url?(url)).to eq(false)
expect(Upload.secure_uploads_url?(url)).to eq(false)
end
end

View File

@ -172,7 +172,7 @@ RSpec.describe 'Multisite s3 uploads', type: :multisite do
end
end
describe 'secure uploads' do
describe 'secure uploadss' do
let(:store) { FileStore::S3Store.new }
let(:client) { Aws::S3::Client.new(stub_responses: true) }
let(:resource) { Aws::S3::Resource.new(client: client) }
@ -209,10 +209,10 @@ RSpec.describe 'Multisite s3 uploads', type: :multisite do
end
end
describe "when secure media are enabled" do
describe "when secure uploads are enabled" do
before do
SiteSetting.login_required = true
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
s3_helper.stubs(:s3_client).returns(client)
Discourse.stubs(:store).returns(store)
end

View File

@ -100,10 +100,10 @@ RSpec.describe PublishedPagesController do
published_page.topic.tags = [Fabricate(:tag, name: "recipes")]
end
context "when secure media is enabled" do
context "when secure uploads is enabled" do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it "returns 404" do

View File

@ -6,7 +6,7 @@ RSpec.describe UploadsController, type: [:multisite, :request] do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
upload.update(secure: true)
end

View File

@ -399,9 +399,9 @@ RSpec.describe UploadsController do
expect(response).to redirect_to(upload.url)
end
context "when upload is secure and secure media enabled" do
context "when upload is secure and secure uploads enabled" do
before do
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
upload.update(secure: true)
end
@ -448,8 +448,8 @@ RSpec.describe UploadsController do
describe "local store" do
fab!(:image_upload) { upload_file("smallest.png") }
it "does not return secure media when using local store" do
secure_url = image_upload.url.sub("/uploads", "/secure-media-uploads")
it "does not return secure uploads when using local store" do
secure_url = image_upload.url.sub("/uploads", "/secure-uploads")
get secure_url
expect(response.status).to eq(404)
@ -458,12 +458,12 @@ RSpec.describe UploadsController do
describe "s3 store" do
let(:upload) { Fabricate(:upload_s3) }
let(:secure_url) { upload.url.sub(SiteSetting.Upload.absolute_base_url, "/secure-media-uploads") }
let(:secure_url) { upload.url.sub(SiteSetting.Upload.absolute_base_url, "/secure-uploads") }
before do
setup_s3
SiteSetting.authorized_extensions = "*"
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it "should return 404 for anonymous requests requests" do
@ -479,7 +479,7 @@ RSpec.describe UploadsController do
expect(response.redirect_url).to match("Amz-Expires")
end
it "should return secure media URL when looking up urls" do
it "should return secure uploads URL when looking up urls" do
upload.update_column(:secure, true)
sign_in(user)
@ -487,7 +487,7 @@ RSpec.describe UploadsController do
expect(response.status).to eq(200)
result = response.parsed_body
expect(result[0]["url"]).to match("secure-media-uploads")
expect(result[0]["url"]).to match("secure-uploads")
end
context "when the upload cannot be found from the URL" do
@ -571,9 +571,9 @@ RSpec.describe UploadsController do
end
end
context "when secure media is disabled" do
context "when secure uploads is disabled" do
before do
SiteSetting.secure_media = false
SiteSetting.secure_uploads = false
end
context "if the upload is secure false, meaning the ACL is probably public" do
@ -582,7 +582,7 @@ RSpec.describe UploadsController do
end
it "should redirect to the regular show route" do
secure_url = upload.url.sub(SiteSetting.Upload.absolute_base_url, "/secure-media-uploads")
secure_url = upload.url.sub(SiteSetting.Upload.absolute_base_url, "/secure-uploads")
sign_in(user)
get secure_url
@ -597,7 +597,7 @@ RSpec.describe UploadsController do
end
it "should redirect to the presigned URL still otherwise we will get a 403" do
secure_url = upload.url.sub(SiteSetting.Upload.absolute_base_url, "/secure-media-uploads")
secure_url = upload.url.sub(SiteSetting.Upload.absolute_base_url, "/secure-uploads")
sign_in(user)
get secure_url
@ -622,23 +622,23 @@ RSpec.describe UploadsController do
expect(result[0]["short_path"]).to eq(upload.short_path)
end
describe 'secure media' do
describe 'secure uploads' do
let(:upload) { Fabricate(:upload_s3, secure: true) }
before do
setup_s3
SiteSetting.authorized_extensions = "pdf|png"
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it 'returns secure url for a secure media upload' do
it 'returns secure url for a secure uploads upload' do
sign_in(user)
post "/uploads/lookup-urls.json", params: { short_urls: [upload.short_url] }
expect(response.status).to eq(200)
result = response.parsed_body
expect(result[0]["url"]).to match("/secure-media-uploads")
expect(result[0]["url"]).to match("/secure-uploads")
expect(result[0]["short_path"]).to eq(upload.short_path)
end
@ -650,7 +650,7 @@ RSpec.describe UploadsController do
expect(response.status).to eq(200)
result = response.parsed_body
expect(result[0]["url"]).to match("/secure-media-uploads")
expect(result[0]["url"]).to match("/secure-uploads")
expect(result[0]["short_path"]).to eq(upload.short_path)
end
end

View File

@ -487,10 +487,10 @@ RSpec.describe TopicViewSerializer do
expect(json[:published_page][:slug]).to eq(published_page.slug)
end
context "when secure media is enabled" do
context "when secure uploads is enabled" do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it "doesn't return the published page" do

View File

@ -18,17 +18,17 @@ RSpec.describe UploadSerializer do
context "when the upload is secure" do
fab!(:upload) { Fabricate(:secure_upload) }
context "when secure media is disabled" do
context "when secure uploads is disabled" do
it "just returns the normal URL, otherwise S3 errors are encountered" do
UrlHelper.expects(:cook_url).with(upload.url, secure: false)
subject.to_json
end
end
context "when secure media is enabled" do
context "when secure uploads is enabled" do
before do
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it "returns the cooked URL based on the upload URL" do

View File

@ -13,9 +13,16 @@ module UploadsHelpers
stub_request(:head, "https://#{SiteSetting.s3_upload_bucket}.s3.#{SiteSetting.s3_region}.amazonaws.com/")
end
# TODO (martin) Remove this alias once discourse-chat plugin has been
# updated to use secure_uploads instead.
def enable_secure_media
enable_secure_uploads
DiscourseEvent.trigger(:site_setting_changed, :secure_media, false, true)
end
def enable_secure_uploads
setup_s3
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
def stub_upload(upload)

View File

@ -52,9 +52,9 @@ RSpec.describe "tasks/uploads" do
uploads.each { |upload| stub_upload(upload) }
end
context "when secure media is enabled" do
context "when secure upload is enabled" do
before do
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
end
it "sets an access_control_post for each post upload, using the first linked post in the case of multiple links" do
@ -155,10 +155,10 @@ RSpec.describe "tasks/uploads" do
end
end
describe "uploads:disable_secure_media" do
describe "uploads:disable_secure_uploads" do
def invoke_task
capture_stdout do
Rake::Task['uploads:disable_secure_media'].invoke
Rake::Task['uploads:disable_secure_uploads'].invoke
end
end
@ -166,7 +166,7 @@ RSpec.describe "tasks/uploads" do
setup_s3
uploads.each { |upload| stub_upload(upload) }
SiteSetting.secure_media = true
SiteSetting.secure_uploads = true
UploadReference.create(target: post1, upload: upload1)
UploadReference.create(target: post1, upload: upload2)
UploadReference.create(target: post2, upload: upload3)
@ -186,9 +186,9 @@ RSpec.describe "tasks/uploads" do
let(:upload4) { Fabricate(:upload_s3, secure: true, access_control_post: post2) }
let(:upload5) { Fabricate(:upload_s3, secure: false) }
it "disables the secure media setting" do
it "disables the secure upload setting" do
invoke_task
expect(SiteSetting.secure_media).to eq(false)
expect(SiteSetting.secure_uploads).to eq(false)
end
it "updates all secure uploads to secure: false" do