FIX: Use full URL for secure attachments when secure media enabled (#9037)

When secure media is enabled and an attachment is marked as secure we want to use the full url instead of the short-url so we get the same access control post protections as secure media uploads.
This commit is contained in:
Martin Brennan
2020-03-04 10:11:08 +11:00
committed by GitHub
parent f971ecd231
commit 3e54e0191e
10 changed files with 223 additions and 55 deletions

View File

@@ -1,21 +1,18 @@
import { acceptance } from "helpers/qunit-helpers";
acceptance("Composer Attachment", {
loggedIn: true,
pretend(server, helper) {
server.post("/uploads/lookup-urls", () => {
return helper.response([
{
short_url: "upload://asdsad.png",
url: "/uploads/default/3X/1/asjdiasjdiasida.png",
short_path: "/uploads/short-url/asdsad.png"
}
]);
});
}
});
function setupPretender(server, helper) {
server.post("/uploads/lookup-urls", () => {
return helper.response([
{
short_url: "upload://asdsad.png",
url: "/secure-media-uploads/default/3X/1/asjdiasjdiasida.png",
short_path: "/uploads/short-url/asdsad.png"
}
]);
});
}
QUnit.test("attachments are cooked properly", async assert => {
async function writeInComposer(assert) {
await visit("/t/internationalization-localization/280");
await click("#topic-footer-buttons .btn.create");
@@ -29,7 +26,17 @@ QUnit.test("attachments are cooked properly", async assert => {
);
await fillIn(".d-editor-input", "[test|attachment](upload://asdsad.png)");
}
acceptance("Composer Attachment", {
loggedIn: true,
pretend(server, helper) {
setupPretender(server, helper);
}
});
QUnit.test("attachments are cooked properly", async assert => {
await writeInComposer(assert);
assert.equal(
find(".d-editor-preview:visible")
.html()
@@ -37,3 +44,26 @@ QUnit.test("attachments are cooked properly", async assert => {
'<p><a class="attachment" href="/uploads/short-url/asdsad.png">test</a></p>'
);
});
acceptance("Composer Attachment - Secure Media Enabled", {
loggedIn: true,
settings: {
secure_media: true
},
pretend(server, helper) {
setupPretender(server, helper);
}
});
QUnit.test(
"attachments are cooked properly when secure media is enabled",
async assert => {
await writeInComposer(assert);
assert.equal(
find(".d-editor-preview:visible")
.html()
.trim(),
'<p><a class="attachment" href="/secure-media-uploads/default/3X/1/asjdiasjdiasida.png">test</a></p>'
);
}
);

View File

@@ -99,7 +99,8 @@ Discourse.SiteSettingsOriginal = {
desktop_category_page_style: "categories_and_latest_topics",
enable_mentions: true,
enable_personal_messages: true,
unicode_usernames: false
unicode_usernames: false,
secure_media: false
};
Discourse.SiteSettings = jQuery.extend(
true,

View File

@@ -973,6 +973,58 @@ QUnit.test("images", assert => {
);
});
QUnit.test("attachment", assert => {
assert.cooked(
"[test.pdf|attachment](upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf)",
`<p><a class="attachment" href="/404" data-orig-href="upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf">test.pdf</a></p>`,
"It returns the correct attachment link HTML"
);
});
QUnit.test("attachment - mapped url - secure media disabled", assert => {
function lookupUploadUrls() {
let cache = {};
cache["upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf"] = {
short_url: "upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf",
url:
"/secure-media-uploads/original/3X/c/b/o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf",
short_path: "/uploads/short-url/blah"
};
return cache;
}
assert.cookedOptions(
"[test.pdf|attachment](upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf)",
{
siteSettings: { secure_media: false },
lookupUploadUrls: 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"
);
});
QUnit.test("attachment - mapped url - secure media enabled", assert => {
function lookupUploadUrls() {
let cache = {};
cache["upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf"] = {
short_url: "upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf",
url:
"/secure-media-uploads/original/3X/c/b/o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf",
short_path: "/uploads/short-url/blah"
};
return cache;
}
assert.cookedOptions(
"[test.pdf|attachment](upload://o8iobpLcW3WSFvVH7YQmyGlKmGM.pdf)",
{
siteSettings: { secure_media: true },
lookupUploadUrls: 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"
);
});
QUnit.test("video - secure media enabled", assert => {
assert.cookedOptions(
"![baby shark|video](upload://eyPnj7UzkU0AkGkx2dx8G4YM1Jx.mp4)",

View File

@@ -7,13 +7,12 @@ import { ajax } from "discourse/lib/ajax";
import { fixture } from "helpers/qunit-helpers";
import pretender from "helpers/create-pretender";
QUnit.module("lib:pretty-text/upload-short-url", {
beforeEach() {
const response = object => {
return [200, { "Content-Type": "application/json" }, object];
};
const imageSrcs = [
function stubUrls(imageSrcs, attachmentSrcs, otherMediaSrcs) {
const response = object => {
return [200, { "Content-Type": "application/json" }, object];
};
if (!imageSrcs) {
imageSrcs = [
{
short_url: "upload://a.jpeg",
url: "/uploads/default/original/3X/c/b/1.jpeg",
@@ -30,16 +29,20 @@ QUnit.module("lib:pretty-text/upload-short-url", {
short_path: "/uploads/short-url/z.jpeg"
}
];
}
const attachmentSrcs = [
if (!attachmentSrcs) {
attachmentSrcs = [
{
short_url: "upload://c.pdf",
url: "/uploads/default/original/3X/c/b/3.pdf",
short_path: "/uploads/short-url/c.pdf"
}
];
}
const otherMediaSrcs = [
if (!otherMediaSrcs) {
otherMediaSrcs = [
{
short_url: "upload://d.mp4",
url: "/uploads/default/original/3X/c/b/4.mp4",
@@ -51,30 +54,37 @@ QUnit.module("lib:pretty-text/upload-short-url", {
short_path: "/uploads/short-url/e.mp3"
}
];
}
// prettier-ignore
pretender.post("/uploads/lookup-urls", () => { //eslint-disable-line
return response(imageSrcs.concat(attachmentSrcs.concat(otherMediaSrcs)));
});
pretender.post("/uploads/lookup-urls", () => {
return response(imageSrcs.concat(attachmentSrcs.concat(otherMediaSrcs)));
});
fixture().html(
imageSrcs.map(src => `<img data-orig-src="${src.url}">`).join("") +
attachmentSrcs.map(src => `<a data-orig-href="${src.url}">`).join("") +
`<div class="scoped-area"><img data-orig-src="${imageSrcs[2].url}"></div>`
);
},
fixture().html(
imageSrcs.map(src => `<img data-orig-src="${src.short_url}"/>`).join("") +
attachmentSrcs
.map(
src =>
`<a data-orig-href="${src.short_url}">big enterprise contract.pdf</a>`
)
.join("") +
`<div class="scoped-area"><img data-orig-src="${imageSrcs[2].url}"></div>`
);
}
QUnit.module("lib:pretty-text/upload-short-url", {
afterEach() {
resetCache();
}
});
QUnit.test("resolveAllShortUrls", async assert => {
stubUrls();
let lookup;
lookup = lookupCachedUploadUrl("upload://a.jpeg");
assert.deepEqual(lookup, {});
await resolveAllShortUrls(ajax);
await resolveAllShortUrls(ajax, { secure_media: false });
lookup = lookupCachedUploadUrl("upload://a.jpeg");
@@ -112,7 +122,52 @@ QUnit.test("resolveAllShortUrls", async assert => {
});
});
QUnit.test(
"resolveAllShortUrls - href + src replaced correctly",
async assert => {
stubUrls();
await resolveAllShortUrls(ajax, { secure_media: false });
let image1 = fixture()
.find("img")
.eq(0);
let image2 = fixture()
.find("img")
.eq(1);
let link = fixture().find("a");
assert.equal(image1.attr("src"), "/uploads/default/original/3X/c/b/1.jpeg");
assert.equal(image2.attr("src"), "/uploads/default/original/3X/c/b/2.jpeg");
assert.equal(link.attr("href"), "/uploads/short-url/c.pdf");
}
);
QUnit.test(
"resolveAllShortUrls - when secure media is enabled use the attachment full URL",
async assert => {
stubUrls(
null,
[
{
short_url: "upload://c.pdf",
url: "/secure-media-uploads/default/original/3X/c/b/3.pdf",
short_path: "/uploads/short-url/c.pdf"
}
],
null
);
await resolveAllShortUrls(ajax, { secure_media: true });
let link = fixture().find("a");
assert.equal(
link.attr("href"),
"/secure-media-uploads/default/original/3X/c/b/3.pdf"
);
}
);
QUnit.test("resolveAllShortUrls - scoped", async assert => {
stubUrls();
let lookup;
await resolveAllShortUrls(ajax, ".scoped-area");