aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authoreugenijm <eugenijm@protonmail.com>2019-04-02 01:31:01 +0300
committereugenijm <eugenijm@protonmail.com>2019-04-06 23:55:58 +0300
commitfc92a0fd8d5be0352f4791b79bda04960f36f707 (patch)
tree344c6f7dff59caf0cb93eaf3ffb8c0610e3e0c0e /lib
parentb3870df51fb2f35c3e51bea435134fe3fb692ef8 (diff)
downloadpleroma-fc92a0fd8d5be0352f4791b79bda04960f36f707.tar.gz
Added limits and media attachments for scheduled activities.
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/object.ex8
-rw-r--r--lib/pleroma/scheduled_activity.ex83
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_api_controller.ex18
-rw-r--r--lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex32
4 files changed, 121 insertions, 20 deletions
diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex
index 013d62157..786d6296c 100644
--- a/lib/pleroma/object.ex
+++ b/lib/pleroma/object.ex
@@ -184,4 +184,12 @@ defmodule Pleroma.Object do
_ -> {:error, "Not found"}
end
end
+
+ def enforce_user_objects(user, object_ids) do
+ Object
+ |> where([o], fragment("?->>'actor' = ?", o.data, ^user.ap_id))
+ |> where([o], o.id in ^object_ids)
+ |> select([o], o.id)
+ |> Repo.all()
+ end
end
diff --git a/lib/pleroma/scheduled_activity.ex b/lib/pleroma/scheduled_activity.ex
index 9fdc13990..723eb6dc3 100644
--- a/lib/pleroma/scheduled_activity.ex
+++ b/lib/pleroma/scheduled_activity.ex
@@ -5,9 +5,12 @@
defmodule Pleroma.ScheduledActivity do
use Ecto.Schema
+ alias Pleroma.Config
+ alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.ScheduledActivity
alias Pleroma.User
+ alias Pleroma.Web.CommonAPI.Utils
import Ecto.Query
import Ecto.Changeset
@@ -25,11 +28,69 @@ defmodule Pleroma.ScheduledActivity do
def changeset(%ScheduledActivity{} = scheduled_activity, attrs) do
scheduled_activity
|> cast(attrs, [:scheduled_at, :params])
+ |> validate_required([:scheduled_at, :params])
+ |> validate_scheduled_at()
+ |> with_media_attachments()
end
+ defp with_media_attachments(
+ %{changes: %{params: %{"media_ids" => media_ids} = params}} = changeset
+ )
+ when is_list(media_ids) do
+ user = User.get_cached_by_id(changeset.data.user_id)
+ media_ids = Object.enforce_user_objects(user, media_ids) |> Enum.map(&to_string(&1))
+ media_attachments = Utils.attachments_from_ids(%{"media_ids" => media_ids})
+
+ params =
+ params
+ |> Map.put("media_attachments", media_attachments)
+ |> Map.put("media_ids", media_ids)
+
+ put_change(changeset, :params, params)
+ end
+
+ defp with_media_attachments(changeset), do: changeset
+
def update_changeset(%ScheduledActivity{} = scheduled_activity, attrs) do
scheduled_activity
|> cast(attrs, [:scheduled_at])
+ |> validate_required([:scheduled_at])
+ |> validate_scheduled_at()
+ end
+
+ def validate_scheduled_at(changeset) do
+ validate_change(changeset, :scheduled_at, fn _, scheduled_at ->
+ cond do
+ not far_enough?(scheduled_at) ->
+ [scheduled_at: "must be at least 5 minutes from now"]
+
+ exceeds_daily_user_limit?(changeset.data.user_id, scheduled_at) ->
+ [scheduled_at: "daily limit exceeded"]
+
+ exceeds_total_user_limit?(changeset.data.user_id) ->
+ [scheduled_at: "total limit exceeded"]
+
+ true ->
+ []
+ end
+ end)
+ end
+
+ def exceeds_daily_user_limit?(user_id, scheduled_at) do
+ ScheduledActivity
+ |> where(user_id: ^user_id)
+ |> where([s], type(s.scheduled_at, :date) == type(^scheduled_at, :date))
+ |> select([u], count(u.id))
+ |> Repo.one()
+ |> Kernel.>=(Config.get([ScheduledActivity, :daily_user_limit]))
+ end
+
+ def exceeds_total_user_limit?(user_id) do
+ ScheduledActivity
+ |> where(user_id: ^user_id)
+ |> select([u], count(u.id))
+ |> Repo.one()
+ |> Kernel.>=(Config.get([ScheduledActivity, :total_user_limit]))
end
def far_enough?(scheduled_at) when is_binary(scheduled_at) do
@@ -64,23 +125,15 @@ defmodule Pleroma.ScheduledActivity do
|> Repo.one()
end
- def update(%User{} = user, scheduled_activity_id, attrs) do
- with %ScheduledActivity{} = scheduled_activity <- get(user, scheduled_activity_id) do
- scheduled_activity
- |> update_changeset(attrs)
- |> Repo.update()
- else
- nil -> {:error, :not_found}
- end
+ def update(scheduled_activity, attrs) do
+ scheduled_activity
+ |> update_changeset(attrs)
+ |> Repo.update()
end
- def delete(%User{} = user, scheduled_activity_id) do
- with %ScheduledActivity{} = scheduled_activity <- get(user, scheduled_activity_id) do
- scheduled_activity
- |> Repo.delete()
- else
- nil -> {:error, :not_found}
- end
+ def delete(scheduled_activity) do
+ scheduled_activity
+ |> Repo.delete()
end
def for_user_query(%User{} = user) do
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index 863fc3954..6cb5df378 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -390,18 +390,28 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
%{assigns: %{user: user}} = conn,
%{"id" => scheduled_activity_id} = params
) do
- with {:ok, scheduled_activity} <-
- ScheduledActivity.update(user, scheduled_activity_id, params) do
+ with %ScheduledActivity{} = scheduled_activity <-
+ ScheduledActivity.get(user, scheduled_activity_id),
+ {:ok, scheduled_activity} <- ScheduledActivity.update(scheduled_activity, params) do
conn
|> put_view(ScheduledActivityView)
|> render("show.json", %{scheduled_activity: scheduled_activity})
+ else
+ nil -> {:error, :not_found}
+ error -> error
end
end
def delete_scheduled_status(%{assigns: %{user: user}} = conn, %{"id" => scheduled_activity_id}) do
- with {:ok, %ScheduledActivity{}} <- ScheduledActivity.delete(user, scheduled_activity_id) do
+ with %ScheduledActivity{} = scheduled_activity <-
+ ScheduledActivity.get(user, scheduled_activity_id),
+ {:ok, scheduled_activity} <- ScheduledActivity.delete(scheduled_activity) do
conn
- |> json(%{})
+ |> put_view(ScheduledActivityView)
+ |> render("show.json", %{scheduled_activity: scheduled_activity})
+ else
+ nil -> {:error, :not_found}
+ error -> error
end
end
diff --git a/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex b/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex
index 87aa3729e..1ebff7aba 100644
--- a/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex
@@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityView do
alias Pleroma.ScheduledActivity
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.ScheduledActivityView
+ alias Pleroma.Web.MastodonAPI.StatusView
def render("index.json", %{scheduled_activities: scheduled_activities}) do
render_many(scheduled_activities, ScheduledActivityView, "show.json")
@@ -17,7 +18,36 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityView do
%{
id: scheduled_activity.id |> to_string,
scheduled_at: scheduled_activity.scheduled_at |> CommonAPI.Utils.to_masto_date(),
- params: scheduled_activity.params
+ params: status_params(scheduled_activity.params)
}
+ |> with_media_attachments(scheduled_activity)
+ end
+
+ defp with_media_attachments(data, %{params: %{"media_attachments" => media_attachments}}) do
+ attachments = render_many(media_attachments, StatusView, "attachment.json", as: :attachment)
+ Map.put(data, :media_attachments, attachments)
+ end
+
+ defp with_media_attachments(data, _), do: data
+
+ defp status_params(params) do
+ data = %{
+ text: params["status"],
+ sensitive: params["sensitive"],
+ spoiler_text: params["spoiler_text"],
+ visibility: params["visibility"],
+ scheduled_at: params["scheduled_at"],
+ poll: params["poll"],
+ in_reply_to_id: params["in_reply_to_id"]
+ }
+
+ data =
+ if media_ids = params["media_ids"] do
+ Map.put(data, :media_ids, media_ids)
+ else
+ data
+ end
+
+ data
end
end