pleroma/lib/pleroma/release_tasks.ex
Phantasm 7f97e21910
pleroma_ctl: Properly handle user arguments with whitespace
When user supplied arguments to pleroma_ctl include whitespace
that has been properly quoted, all arguments were sent to
ReleaseTasks in one string, which then String.split/1 the input on any
whitespace. This broke Mix tasks that accept certain user input like
instance gen and user management.

To fix this, pleroma_ctl now sends the arguments in list
form. Additionally pleroma_ctl arguments now need to be pre-processed.

Fixes pleroma/pleroma#7874
2026-04-24 18:04:31 +02:00

84 lines
2.1 KiB
Elixir

# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.ReleaseTasks do
@repo Pleroma.Repo
# TODO: Kept for some backwards compatibility with buggy pleroma_ctl,
# if a mismatch between pleroma_ctl and Pleroma accidentaly happens.
# Remove in the future.
def run(args) when is_binary(args) do
[task | args] = String.split(args)
case task do
"migrate" -> migrate(args)
"create" -> create()
"rollback" -> rollback(args)
task -> mix_task(task, args)
end
end
# HACK: Script arguments need to be received as a list, otherwise (quoted) arguments with
# whitespace will be broken. Previously the broken string form above was used,
# escaping in the shell does not help.
def run(args) when is_list(args) do
[task | args] = args
case task do
"migrate" -> migrate(args)
"create" -> create()
"rollback" -> rollback(args)
task -> mix_task(task, args)
end
end
def find_module(task) do
module_name =
task
|> String.split(".")
|> Enum.map(&String.capitalize/1)
|> then(fn x -> [Mix, Tasks, Pleroma] ++ x end)
|> Module.concat()
case Code.ensure_loaded(module_name) do
{:module, _} -> module_name
_ -> nil
end
end
defp mix_task(task, args) do
Application.load(:pleroma)
module = find_module(task)
if module do
module.run(args)
else
IO.puts("The task #{task} does not exist")
end
end
def migrate(args) do
Mix.Tasks.Pleroma.Ecto.Migrate.run(args)
end
def rollback(args) do
Mix.Tasks.Pleroma.Ecto.Rollback.run(args)
end
def create do
Application.load(:pleroma)
case @repo.__adapter__.storage_up(@repo.config) do
:ok ->
IO.puts("The database for #{inspect(@repo)} has been created")
{:error, :already_up} ->
IO.puts("The database for #{inspect(@repo)} has already been created")
{:error, term} when is_binary(term) ->
IO.puts(:stderr, "The database for #{inspect(@repo)} couldn't be created: #{term}")
end
end
end