Merge branch 'feature/upload-limits' into 'develop'
configurable media upload limits Closes #118 See merge request pleroma/pleroma!401
This commit is contained in:
commit
a880e0a527
|
@ -85,6 +85,9 @@
|
||||||
description: "A Pleroma instance, an alternative fediverse server",
|
description: "A Pleroma instance, an alternative fediverse server",
|
||||||
limit: 5000,
|
limit: 5000,
|
||||||
upload_limit: 16_000_000,
|
upload_limit: 16_000_000,
|
||||||
|
avatar_upload_limit: 2_000_000,
|
||||||
|
background_upload_limit: 4_000_000,
|
||||||
|
banner_upload_limit: 4_000_000,
|
||||||
registrations_open: true,
|
registrations_open: true,
|
||||||
federating: true,
|
federating: true,
|
||||||
allow_relay: true,
|
allow_relay: true,
|
||||||
|
|
|
@ -4,61 +4,76 @@ defmodule Pleroma.Upload do
|
||||||
@storage_backend Application.get_env(:pleroma, Pleroma.Upload)
|
@storage_backend Application.get_env(:pleroma, Pleroma.Upload)
|
||||||
|> Keyword.fetch!(:uploader)
|
|> Keyword.fetch!(:uploader)
|
||||||
|
|
||||||
def store(%Plug.Upload{} = file, should_dedupe) do
|
def check_file_size(path, nil), do: true
|
||||||
content_type = get_content_type(file.path)
|
|
||||||
|
|
||||||
uuid = get_uuid(file, should_dedupe)
|
def check_file_size(path, size_limit) do
|
||||||
name = get_name(file, uuid, content_type, should_dedupe)
|
{:ok, %{size: size}} = File.stat(path)
|
||||||
|
size <= size_limit
|
||||||
strip_exif_data(content_type, file.path)
|
|
||||||
|
|
||||||
{:ok, url_path} =
|
|
||||||
@storage_backend.put_file(name, uuid, file.path, content_type, should_dedupe)
|
|
||||||
|
|
||||||
%{
|
|
||||||
"type" => "Document",
|
|
||||||
"url" => [
|
|
||||||
%{
|
|
||||||
"type" => "Link",
|
|
||||||
"mediaType" => content_type,
|
|
||||||
"href" => url_path
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name" => name
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def store(%{"img" => "data:image/" <> image_data}, should_dedupe) do
|
def store(file, should_dedupe, size_limit \\ nil)
|
||||||
|
|
||||||
|
def store(%Plug.Upload{} = file, should_dedupe, size_limit) do
|
||||||
|
content_type = get_content_type(file.path)
|
||||||
|
|
||||||
|
with uuid <- get_uuid(file, should_dedupe),
|
||||||
|
name <- get_name(file, uuid, content_type, should_dedupe),
|
||||||
|
true <- check_file_size(file.path, size_limit) do
|
||||||
|
strip_exif_data(content_type, file.path)
|
||||||
|
|
||||||
|
{:ok, url_path} =
|
||||||
|
@storage_backend.put_file(name, uuid, file.path, content_type, should_dedupe)
|
||||||
|
|
||||||
|
%{
|
||||||
|
"type" => "Document",
|
||||||
|
"url" => [
|
||||||
|
%{
|
||||||
|
"type" => "Link",
|
||||||
|
"mediaType" => content_type,
|
||||||
|
"href" => url_path
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name" => name
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_e -> nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def store(%{"img" => "data:image/" <> image_data}, should_dedupe, size_limit) do
|
||||||
parsed = Regex.named_captures(~r/(?<filetype>jpeg|png|gif);base64,(?<data>.*)/, image_data)
|
parsed = Regex.named_captures(~r/(?<filetype>jpeg|png|gif);base64,(?<data>.*)/, image_data)
|
||||||
data = Base.decode64!(parsed["data"], ignore: :whitespace)
|
data = Base.decode64!(parsed["data"], ignore: :whitespace)
|
||||||
|
|
||||||
tmp_path = tempfile_for_image(data)
|
with tmp_path <- tempfile_for_image(data),
|
||||||
|
uuid <- UUID.generate(),
|
||||||
|
true <- check_file_size(tmp_path, size_limit) do
|
||||||
|
content_type = get_content_type(tmp_path)
|
||||||
|
strip_exif_data(content_type, tmp_path)
|
||||||
|
|
||||||
uuid = UUID.generate()
|
name =
|
||||||
|
create_name(
|
||||||
|
String.downcase(Base.encode16(:crypto.hash(:sha256, data))),
|
||||||
|
parsed["filetype"],
|
||||||
|
content_type
|
||||||
|
)
|
||||||
|
|
||||||
content_type = get_content_type(tmp_path)
|
{:ok, url_path} =
|
||||||
strip_exif_data(content_type, tmp_path)
|
@storage_backend.put_file(name, uuid, tmp_path, content_type, should_dedupe)
|
||||||
|
|
||||||
name =
|
%{
|
||||||
create_name(
|
"type" => "Image",
|
||||||
String.downcase(Base.encode16(:crypto.hash(:sha256, data))),
|
"url" => [
|
||||||
parsed["filetype"],
|
%{
|
||||||
content_type
|
"type" => "Link",
|
||||||
)
|
"mediaType" => content_type,
|
||||||
|
"href" => url_path
|
||||||
{:ok, url_path} = @storage_backend.put_file(name, uuid, tmp_path, content_type, should_dedupe)
|
}
|
||||||
|
],
|
||||||
%{
|
"name" => name
|
||||||
"type" => "Image",
|
}
|
||||||
"url" => [
|
else
|
||||||
%{
|
_e -> nil
|
||||||
"type" => "Link",
|
end
|
||||||
"mediaType" => content_type,
|
|
||||||
"href" => url_path
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"name" => name
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
@ -575,9 +575,12 @@ def fetch_activities_bounded(recipients_to, recipients_cc, opts \\ %{}) do
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
end
|
end
|
||||||
|
|
||||||
def upload(file) do
|
def upload(file, size_limit \\ nil) do
|
||||||
data = Upload.store(file, Application.get_env(:pleroma, :instance)[:dedupe_media])
|
with data <-
|
||||||
Repo.insert(%Object{data: data})
|
Upload.store(file, Application.get_env(:pleroma, :instance)[:dedupe_media], size_limit),
|
||||||
|
false <- is_nil(data) do
|
||||||
|
Repo.insert(%Object{data: data})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_data_from_user_object(data) do
|
def user_data_from_user_object(data) do
|
||||||
|
|
|
@ -35,6 +35,14 @@ def create_app(conn, params) do
|
||||||
def update_credentials(%{assigns: %{user: user}} = conn, params) do
|
def update_credentials(%{assigns: %{user: user}} = conn, params) do
|
||||||
original_user = user
|
original_user = user
|
||||||
|
|
||||||
|
avatar_upload_limit =
|
||||||
|
Application.get_env(:pleroma, :instance)
|
||||||
|
|> Keyword.fetch(:avatar_upload_limit)
|
||||||
|
|
||||||
|
banner_upload_limit =
|
||||||
|
Application.get_env(:pleroma, :instance)
|
||||||
|
|> Keyword.fetch(:banner_upload_limit)
|
||||||
|
|
||||||
params =
|
params =
|
||||||
if bio = params["note"] do
|
if bio = params["note"] do
|
||||||
Map.put(params, "bio", bio)
|
Map.put(params, "bio", bio)
|
||||||
|
@ -52,7 +60,7 @@ def update_credentials(%{assigns: %{user: user}} = conn, params) do
|
||||||
user =
|
user =
|
||||||
if avatar = params["avatar"] do
|
if avatar = params["avatar"] do
|
||||||
with %Plug.Upload{} <- avatar,
|
with %Plug.Upload{} <- avatar,
|
||||||
{:ok, object} <- ActivityPub.upload(avatar),
|
{:ok, object} <- ActivityPub.upload(avatar, avatar_upload_limit),
|
||||||
change = Ecto.Changeset.change(user, %{avatar: object.data}),
|
change = Ecto.Changeset.change(user, %{avatar: object.data}),
|
||||||
{:ok, user} = User.update_and_set_cache(change) do
|
{:ok, user} = User.update_and_set_cache(change) do
|
||||||
user
|
user
|
||||||
|
@ -66,7 +74,7 @@ def update_credentials(%{assigns: %{user: user}} = conn, params) do
|
||||||
user =
|
user =
|
||||||
if banner = params["header"] do
|
if banner = params["header"] do
|
||||||
with %Plug.Upload{} <- banner,
|
with %Plug.Upload{} <- banner,
|
||||||
{:ok, object} <- ActivityPub.upload(banner),
|
{:ok, object} <- ActivityPub.upload(banner, banner_upload_limit),
|
||||||
new_info <- Map.put(user.info, "banner", object.data),
|
new_info <- Map.put(user.info, "banner", object.data),
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
change <- User.info_changeset(user, %{info: new_info}),
|
||||||
{:ok, user} <- User.update_and_set_cache(change) do
|
{:ok, user} <- User.update_and_set_cache(change) do
|
||||||
|
|
|
@ -113,6 +113,12 @@ def nodeinfo(conn, %{"version" => "2.0"}) do
|
||||||
staffAccounts: staff_accounts,
|
staffAccounts: staff_accounts,
|
||||||
federation: federation_response,
|
federation: federation_response,
|
||||||
postFormats: Keyword.get(instance, :allowed_post_formats),
|
postFormats: Keyword.get(instance, :allowed_post_formats),
|
||||||
|
uploadLimits: %{
|
||||||
|
general: Keyword.get(instance, :upload_limit),
|
||||||
|
avatar: Keyword.get(instance, :avatar_upload_limit),
|
||||||
|
banner: Keyword.get(instance, :banner_upload_limit),
|
||||||
|
background: Keyword.get(instance, :background_upload_limit)
|
||||||
|
},
|
||||||
features: features
|
features: features
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,11 @@ def register(conn, params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_avatar(%{assigns: %{user: user}} = conn, params) do
|
def update_avatar(%{assigns: %{user: user}} = conn, params) do
|
||||||
{:ok, object} = ActivityPub.upload(params)
|
upload_limit =
|
||||||
|
Application.get_env(:pleroma, :instance)
|
||||||
|
|> Keyword.fetch(:avatar_upload_limit)
|
||||||
|
|
||||||
|
{:ok, object} = ActivityPub.upload(params, upload_limit)
|
||||||
change = Changeset.change(user, %{avatar: object.data})
|
change = Changeset.change(user, %{avatar: object.data})
|
||||||
{:ok, user} = User.update_and_set_cache(change)
|
{:ok, user} = User.update_and_set_cache(change)
|
||||||
CommonAPI.update(user)
|
CommonAPI.update(user)
|
||||||
|
@ -272,7 +276,11 @@ def update_avatar(%{assigns: %{user: user}} = conn, params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_banner(%{assigns: %{user: user}} = conn, params) do
|
def update_banner(%{assigns: %{user: user}} = conn, params) do
|
||||||
with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}),
|
upload_limit =
|
||||||
|
Application.get_env(:pleroma, :instance)
|
||||||
|
|> Keyword.fetch(:banner_upload_limit)
|
||||||
|
|
||||||
|
with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, upload_limit),
|
||||||
new_info <- Map.put(user.info, "banner", object.data),
|
new_info <- Map.put(user.info, "banner", object.data),
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
change <- User.info_changeset(user, %{info: new_info}),
|
||||||
{:ok, user} <- User.update_and_set_cache(change) do
|
{:ok, user} <- User.update_and_set_cache(change) do
|
||||||
|
@ -286,7 +294,11 @@ def update_banner(%{assigns: %{user: user}} = conn, params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_background(%{assigns: %{user: user}} = conn, params) do
|
def update_background(%{assigns: %{user: user}} = conn, params) do
|
||||||
with {:ok, object} <- ActivityPub.upload(params),
|
upload_limit =
|
||||||
|
Application.get_env(:pleroma, :instance)
|
||||||
|
|> Keyword.fetch(:background_upload_limit)
|
||||||
|
|
||||||
|
with {:ok, object} <- ActivityPub.upload(params, upload_limit),
|
||||||
new_info <- Map.put(user.info, "background", object.data),
|
new_info <- Map.put(user.info, "background", object.data),
|
||||||
change <- User.info_changeset(user, %{info: new_info}),
|
change <- User.info_changeset(user, %{info: new_info}),
|
||||||
{:ok, _user} <- User.update_and_set_cache(change) do
|
{:ok, _user} <- User.update_and_set_cache(change) do
|
||||||
|
|
Loading…
Reference in New Issue