add image proxy test, fix test

markdown-link-rule-dess
Felix Ableitner 2023-12-21 12:04:43 +01:00
parent 3d698dde7c
commit becf54c4c4
8 changed files with 100 additions and 18 deletions

View File

@ -7,16 +7,23 @@ import {
PurgePost, PurgePost,
} from "lemmy-js-client"; } from "lemmy-js-client";
import { import {
alpha,
alphaImage, alphaImage,
alphaUrl, alphaUrl,
beta, beta,
betaUrl, betaUrl,
createCommunity,
createPost, createPost,
delta,
epsilon,
gamma,
getSite, getSite,
registerUser, registerUser,
resolveBetaCommunity, resolveBetaCommunity,
resolvePost,
setupLogins, setupLogins,
unfollowRemotes, unfollowRemotes,
waitForPost,
} from "./shared"; } from "./shared";
const downloadFileSync = require("download-file-sync"); const downloadFileSync = require("download-file-sync");
@ -29,9 +36,8 @@ afterAll(() => {
test("Upload image and delete it", async () => { test("Upload image and delete it", async () => {
// Upload test image. We use a simple string buffer as pictrs doesnt require an actual image // Upload test image. We use a simple string buffer as pictrs doesnt require an actual image
// in testing mode. // in testing mode.
const upload_image = Buffer.from("test");
const upload_form: UploadImage = { const upload_form: UploadImage = {
image: upload_image, image: Buffer.from("test"),
}; };
const upload = await alphaImage.uploadImage(upload_form); const upload = await alphaImage.uploadImage(upload_form);
expect(upload.files![0].file).toBeDefined(); expect(upload.files![0].file).toBeDefined();
@ -60,9 +66,8 @@ test("Purge user, uploaded image removed", async () => {
let user = await registerUser(alphaImage, alphaUrl); let user = await registerUser(alphaImage, alphaUrl);
// upload test image // upload test image
const upload_image = Buffer.from("test");
const upload_form: UploadImage = { const upload_form: UploadImage = {
image: upload_image, image: Buffer.from("test"),
}; };
const upload = await user.uploadImage(upload_form); const upload = await user.uploadImage(upload_form);
expect(upload.files![0].file).toBeDefined(); expect(upload.files![0].file).toBeDefined();
@ -91,9 +96,8 @@ test("Purge post, linked image removed", async () => {
let user = await registerUser(beta, betaUrl); let user = await registerUser(beta, betaUrl);
// upload test image // upload test image
const upload_image = Buffer.from("test");
const upload_form: UploadImage = { const upload_form: UploadImage = {
image: upload_image, image: Buffer.from("test"),
}; };
const upload = await user.uploadImage(upload_form); const upload = await user.uploadImage(upload_form);
expect(upload.files![0].file).toBeDefined(); expect(upload.files![0].file).toBeDefined();
@ -124,3 +128,48 @@ test("Purge post, linked image removed", async () => {
const content2 = downloadFileSync(upload.url); const content2 = downloadFileSync(upload.url);
expect(content2).toBe(""); expect(content2).toBe("");
}); });
test("Images in remote post are proxied", async () => {
let user = await registerUser(beta, betaUrl);
let community = await createCommunity(gamma);
const upload_form: UploadImage = {
image: Buffer.from("test"),
};
const upload = await user.uploadImage(upload_form);
console.log(upload);
let post = await createPost(
gamma,
community.community_view.community.id,
upload.url,
"![](http://example.com/image2.png)",
);
expect(post.post_view.post).toBeDefined();
// remote image gets proxied after upload
console.log(post.post_view.post);
expect(
post.post_view.post.url?.startsWith(
"http://lemmy-gamma:8561/api/v3/image_proxy?url",
),
).toBeTruthy();
expect(
post.post_view.post.body?.startsWith(
"![](http://lemmy-gamma:8561/api/v3/image_proxy?url",
),
).toBeTruthy();
let epsilonPost = await resolvePost(epsilon, post.post_view.post);
expect(epsilonPost.post).toBeDefined();
console.log(epsilonPost.post);
// remote image gets proxied after federation
expect(
epsilonPost.post!.post.url?.startsWith(
"http://lemmy-epsilon:8581/api/v3/image_proxy?url",
),
).toBeTruthy();
expect(
epsilonPost.post!.post.body?.startsWith(
"![](http://lemmy-epsilon:8581/api/v3/image_proxy?url",
),
).toBeTruthy();
});

View File

@ -204,9 +204,9 @@ export async function createPost(
community_id: number, community_id: number,
// use example.com for consistent title and embed description // use example.com for consistent title and embed description
url: string = "https://example.com/", url: string = "https://example.com/",
body = randomString(10),
): Promise<PostResponse> { ): Promise<PostResponse> {
let name = randomString(5); let name = randomString(5);
let body = randomString(10);
let form: CreatePost = { let form: CreatePost = {
name, name,
url, url,

View File

@ -864,7 +864,9 @@ pub async fn process_markdown_opt(
pub async fn proxy_image_link(link: Url, context: &LemmyContext) -> LemmyResult<DbUrl> { pub async fn proxy_image_link(link: Url, context: &LemmyContext) -> LemmyResult<DbUrl> {
// Dont rewrite links pointing to local domain. // Dont rewrite links pointing to local domain.
if link.domain() == Some(&context.settings().hostname) { if link.domain() == Some(&context.settings().hostname)
|| !context.settings().pictrs_config()?.image_proxy
{
return Ok(link.into()); return Ok(link.into());
} }

View File

@ -13,6 +13,7 @@ use lemmy_api_common::{
local_site_to_slur_regex, local_site_to_slur_regex,
mark_post_as_read, mark_post_as_read,
process_markdown_opt, process_markdown_opt,
proxy_image_link_opt_apub,
EndpointType, EndpointType,
}, },
}; };
@ -84,6 +85,7 @@ pub async fn create_post(
// Fetch post links and pictrs cached image // Fetch post links and pictrs cached image
let metadata = fetch_link_metadata_opt(url.as_ref(), true, &context).await?; let metadata = fetch_link_metadata_opt(url.as_ref(), true, &context).await?;
let url = proxy_image_link_opt_apub(url, &context).await?;
// Only need to check if language is allowed in case user set it explicitly. When using default // Only need to check if language is allowed in case user set it explicitly. When using default
// language, it already only returns allowed languages. // language, it already only returns allowed languages.
@ -109,7 +111,7 @@ pub async fn create_post(
let post_form = PostInsertForm::builder() let post_form = PostInsertForm::builder()
.name(data.name.trim().to_string()) .name(data.name.trim().to_string())
.url(url.map(Into::into)) .url(url)
.body(body) .body(body)
.community_id(data.community_id) .community_id(data.community_id)
.creator_id(local_user_view.person.id) .creator_id(local_user_view.person.id)

View File

@ -4,9 +4,14 @@ use lemmy_api_common::{
build_response::build_post_response, build_response::build_post_response,
context::LemmyContext, context::LemmyContext,
post::{EditPost, PostResponse}, post::{EditPost, PostResponse},
request::fetch_link_metadata_opt, request::fetch_link_metadata,
send_activity::{ActivityChannel, SendActivityData}, send_activity::{ActivityChannel, SendActivityData},
utils::{check_community_user_action, local_site_to_slur_regex, process_markdown_opt}, utils::{
check_community_user_action,
local_site_to_slur_regex,
process_markdown_opt,
proxy_image_link_opt_apub,
},
}; };
use lemmy_db_schema::{ use lemmy_db_schema::{
source::{ source::{
@ -65,8 +70,23 @@ pub async fn update_post(
Err(LemmyErrorType::NoPostEditAllowed)? Err(LemmyErrorType::NoPostEditAllowed)?
} }
// Fetch post links and Pictrs cached image // Fetch post links and Pictrs cached image if url was updated
let metadata = fetch_link_metadata_opt(url.as_ref(), true, &context).await?; let (embed_title, embed_description, embed_video_url, thumbnail_url) = match &url {
Some(url) => {
let metadata = fetch_link_metadata(url, true, &context).await?;
(
Some(metadata.title),
Some(metadata.description),
Some(metadata.embed_video_url),
Some(metadata.thumbnail),
)
}
_ => Default::default(),
};
let url = match url {
Some(url) => Some(proxy_image_link_opt_apub(Some(url), &context).await?),
_ => Default::default(),
};
let language_id = data.language_id; let language_id = data.language_id;
CommunityLanguage::is_allowed_community_language( CommunityLanguage::is_allowed_community_language(
@ -78,14 +98,14 @@ pub async fn update_post(
let post_form = PostUpdateForm { let post_form = PostUpdateForm {
name: data.name.clone(), name: data.name.clone(),
url: Some(url.map(Into::into)), url,
body: diesel_option_overwrite(body), body: diesel_option_overwrite(body),
nsfw: data.nsfw, nsfw: data.nsfw,
embed_title: Some(metadata.title), embed_title,
embed_description: Some(metadata.description), embed_description,
embed_video_url: Some(metadata.embed_video_url), embed_video_url,
language_id: data.language_id, language_id: data.language_id,
thumbnail_url: Some(metadata.thumbnail), thumbnail_url,
updated: Some(Some(naive_now())), updated: Some(Some(naive_now())),
..Default::default() ..Default::default()
}; };

View File

@ -228,6 +228,7 @@ impl Object for ApubPost {
if let Some(thumbnail_url_) = metadata.thumbnail { if let Some(thumbnail_url_) = metadata.thumbnail {
thumbnail_url = Some(thumbnail_url_.into()); thumbnail_url = Some(thumbnail_url_.into());
} }
let url = proxy_image_link_opt_apub(url, context).await?;
let thumbnail_url = proxy_image_link_opt_apub(thumbnail_url, context).await?; let thumbnail_url = proxy_image_link_opt_apub(thumbnail_url, context).await?;
let slur_regex = &local_site_opt_to_slur_regex(&local_site); let slur_regex = &local_site_opt_to_slur_regex(&local_site);

View File

@ -10,4 +10,8 @@
database: { database: {
host: postgres_epsilon host: postgres_epsilon
} }
pictrs: {
api_key: "my-pictrs-key"
image_proxy: true
}
} }

View File

@ -10,4 +10,8 @@
database: { database: {
host: postgres_gamma host: postgres_gamma
} }
pictrs: {
api_key: "my-pictrs-key"
image_proxy: true
}
} }