diff options
author | cascode <cascode@amplifie.red> | 2019-01-04 20:32:55 -0800 |
---|---|---|
committer | cascode <cascode@amplifie.red> | 2019-01-04 20:32:55 -0800 |
commit | a81307251c7dde298013003373e9cd28ebd9dede (patch) | |
tree | 973e4022c9d44a18ea13f1923195f56969608daa /lib | |
parent | 4c5ee4c62bb68982bf286b302dec77468a6d19b5 (diff) | |
parent | ba17518a0aff404e265f4aebec1257912ad2750c (diff) | |
download | pleroma-a81307251c7dde298013003373e9cd28ebd9dede.tar.gz |
Merge branch 'develop' of git.pleroma.social:cascode/pleroma into fix/user-search-null-name
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/application.ex | 11 | ||||
-rw-r--r-- | lib/pleroma/html.ex | 35 | ||||
-rw-r--r-- | lib/pleroma/web/activity_pub/activity_pub_controller.ex | 52 | ||||
-rw-r--r-- | lib/pleroma/web/mastodon_api/views/status_view.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/rich_media/controllers/rich_media_controller.ex | 17 | ||||
-rw-r--r-- | lib/pleroma/web/rich_media/parser.ex | 33 | ||||
-rw-r--r-- | lib/pleroma/web/rich_media/parsers/ogp.ex | 30 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 6 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/views/activity_view.ex | 8 |
9 files changed, 155 insertions, 43 deletions
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index cb3e6b69b..ad2797209 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -66,6 +66,17 @@ defmodule Pleroma.Application do worker( Cachex, [ + :rich_media_cache, + [ + default_ttl: :timer.minutes(120), + limit: 5000 + ] + ], + id: :cachex_rich_media + ), + worker( + Cachex, + [ :scrubber_cache, [ limit: 2500 diff --git a/lib/pleroma/html.ex b/lib/pleroma/html.ex index 71db516e6..0c5b0f03f 100644 --- a/lib/pleroma/html.ex +++ b/lib/pleroma/html.ex @@ -28,13 +28,18 @@ defmodule Pleroma.HTML do def filter_tags(html), do: filter_tags(html, nil) def strip_tags(html), do: Scrubber.scrub(html, Scrubber.StripTags) - def get_cached_scrubbed_html_for_object(content, scrubbers, object) do - key = "#{generate_scrubber_signature(scrubbers)}|#{object.id}" + def get_cached_scrubbed_html_for_object(content, scrubbers, object, module) do + key = "#{module}#{generate_scrubber_signature(scrubbers)}|#{object.id}" Cachex.fetch!(:scrubber_cache, key, fn _key -> ensure_scrubbed_html(content, scrubbers) end) end - def get_cached_stripped_html_for_object(content, object) do - get_cached_scrubbed_html_for_object(content, HtmlSanitizeEx.Scrubber.StripTags, object) + def get_cached_stripped_html_for_object(content, object, module) do + get_cached_scrubbed_html_for_object( + content, + HtmlSanitizeEx.Scrubber.StripTags, + object, + module + ) end def ensure_scrubbed_html( @@ -50,15 +55,7 @@ defmodule Pleroma.HTML do defp generate_scrubber_signature(scrubbers) do Enum.reduce(scrubbers, "", fn scrubber, signature -> - # If a scrubber does not have a version(e.g HtmlSanitizeEx.Scrubber.StripTags) it is assumed it is always 0) - version = - if Kernel.function_exported?(scrubber, :version, 0) do - scrubber.version - else - 0 - end - - "#{signature}#{to_string(scrubber)}#{version}" + "#{signature}#{to_string(scrubber)}" end) end end @@ -76,10 +73,6 @@ defmodule Pleroma.HTML.Scrubber.TwitterText do require HtmlSanitizeEx.Scrubber.Meta alias HtmlSanitizeEx.Scrubber.Meta - def version do - 0 - end - Meta.remove_cdata_sections_before_scrub() Meta.strip_comments() @@ -118,10 +111,6 @@ defmodule Pleroma.HTML.Scrubber.Default do require HtmlSanitizeEx.Scrubber.Meta alias HtmlSanitizeEx.Scrubber.Meta - def version do - 0 - end - @markup Application.get_env(:pleroma, :markup) @uri_schemes Application.get_env(:pleroma, :uri_schemes, []) @valid_schemes Keyword.get(@uri_schemes, :valid_schemes, []) @@ -199,10 +188,6 @@ defmodule Pleroma.HTML.Transform.MediaProxy do alias Pleroma.Web.MediaProxy - def version do - 0 - end - def before_scrub(html), do: html def scrub_attribute("img", {"src", "http" <> target}) do diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index fc7972eaf..a3f736fee 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -165,9 +165,39 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do end end + def handle_user_activity(user, %{"type" => "Create"} = params) do + object = + params["object"] + |> Map.merge(Map.take(params, ["to", "cc"])) + |> Map.put("attributedTo", user.ap_id()) + |> Transmogrifier.fix_object() + + ActivityPub.create(%{ + to: params["to"], + actor: user, + context: object["context"], + object: object, + additional: Map.take(params, ["cc"]) + }) + end + + def handle_user_activity(user, %{"type" => "Delete"} = params) do + with %Object{} = object <- Object.normalize(params["object"]), + true <- user.info.is_moderator || user.ap_id == object.data["actor"], + {:ok, delete} <- ActivityPub.delete(object) do + {:ok, delete} + else + _ -> {:error, "Can't delete object"} + end + end + + def handle_user_activity(_, _) do + {:error, "Unhandled activity type"} + end + def update_outbox( %{assigns: %{user: user}} = conn, - %{"nickname" => nickname, "type" => "Create"} = params + %{"nickname" => nickname} = params ) do if nickname == user.nickname do actor = user.ap_id() @@ -178,24 +208,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do |> Map.put("actor", actor) |> Transmogrifier.fix_addressing() - object = - params["object"] - |> Map.merge(Map.take(params, ["to", "cc"])) - |> Map.put("attributedTo", actor) - |> Transmogrifier.fix_object() - - with {:ok, %Activity{} = activity} <- - ActivityPub.create(%{ - to: params["to"], - actor: user, - context: object["context"], - object: object, - additional: Map.take(params, ["cc"]) - }) do + with {:ok, %Activity{} = activity} <- handle_user_activity(user, params) do conn |> put_status(:created) |> put_resp_header("location", activity.data["id"]) |> json(activity.data) + else + {:error, message} -> + conn + |> put_status(:bad_request) + |> json(message) end else conn diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 477ab3b5f..8e8fa8121 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -120,7 +120,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do content = object |> render_content() - |> HTML.get_cached_scrubbed_html_for_object(User.html_filter_policy(opts[:for]), activity) + |> HTML.get_cached_scrubbed_html_for_object( + User.html_filter_policy(opts[:for]), + activity, + __MODULE__ + ) %{ id: to_string(activity.id), diff --git a/lib/pleroma/web/rich_media/controllers/rich_media_controller.ex b/lib/pleroma/web/rich_media/controllers/rich_media_controller.ex new file mode 100644 index 000000000..91019961d --- /dev/null +++ b/lib/pleroma/web/rich_media/controllers/rich_media_controller.ex @@ -0,0 +1,17 @@ +defmodule Pleroma.Web.RichMedia.RichMediaController do + use Pleroma.Web, :controller + + import Pleroma.Web.ControllerHelper, only: [json_response: 3] + + def parse(conn, %{"url" => url}) do + case Pleroma.Web.RichMedia.Parser.parse(url) do + {:ok, data} -> + conn + |> json_response(200, data) + + {:error, msg} -> + conn + |> json_response(404, msg) + end + end +end diff --git a/lib/pleroma/web/rich_media/parser.ex b/lib/pleroma/web/rich_media/parser.ex new file mode 100644 index 000000000..3746feaf6 --- /dev/null +++ b/lib/pleroma/web/rich_media/parser.ex @@ -0,0 +1,33 @@ +defmodule Pleroma.Web.RichMedia.Parser do + @parsers [Pleroma.Web.RichMedia.Parsers.OGP] + + if Mix.env() == :test do + def parse(url), do: parse_url(url) + else + def parse(url), + do: {:commit, Cachex.fetch!(:rich_media_cache, url, fn _ -> parse_url(url) end)} + end + + defp parse_url(url) do + {:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url) + + html |> maybe_parse() |> get_parsed_data() + end + + defp maybe_parse(html) do + Enum.reduce_while(@parsers, %{}, fn parser, acc -> + case parser.parse(html, acc) do + {:ok, data} -> {:halt, data} + {:error, _msg} -> {:cont, acc} + end + end) + end + + defp get_parsed_data(data) when data == %{} do + {:error, "No metadata found"} + end + + defp get_parsed_data(data) do + {:ok, data} + end +end diff --git a/lib/pleroma/web/rich_media/parsers/ogp.ex b/lib/pleroma/web/rich_media/parsers/ogp.ex new file mode 100644 index 000000000..5773a5263 --- /dev/null +++ b/lib/pleroma/web/rich_media/parsers/ogp.ex @@ -0,0 +1,30 @@ +defmodule Pleroma.Web.RichMedia.Parsers.OGP do + def parse(html, data) do + with elements = [_ | _] <- get_elements(html), + ogp_data = + Enum.reduce(elements, data, fn el, acc -> + attributes = normalize_attributes(el) + + Map.merge(acc, attributes) + end) do + {:ok, ogp_data} + else + _e -> {:error, "No OGP metadata found"} + end + end + + defp get_elements(html) do + html |> Floki.find("meta[property^='og:']") + end + + defp normalize_attributes(html_node) do + {_tag, attributes, _children} = html_node + + data = + Enum.into(attributes, %{}, fn {name, value} -> + {name, String.trim_leading(value, "og:")} + end) + + %{String.to_atom(data["property"]) => data["content"]} + end +end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 1f929ee21..8df45bf4d 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -232,6 +232,12 @@ defmodule Pleroma.Web.Router do put("/settings", MastodonAPIController, :put_settings) end + scope "/api", Pleroma.Web.RichMedia do + pipe_through(:authenticated_api) + + get("/rich_media/parse", RichMediaController, :parse) + end + scope "/api/v1", Pleroma.Web.MastodonAPI do pipe_through(:api) get("/instance", MastodonAPIController, :masto_instance) diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex index 84f35ebf9..a0be5cfc5 100644 --- a/lib/pleroma/web/twitter_api/views/activity_view.ex +++ b/lib/pleroma/web/twitter_api/views/activity_view.ex @@ -245,14 +245,18 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do html = content - |> HTML.get_cached_scrubbed_html_for_object(User.html_filter_policy(opts[:for]), activity) + |> HTML.get_cached_scrubbed_html_for_object( + User.html_filter_policy(opts[:for]), + activity, + __MODULE__ + ) |> Formatter.emojify(object["emoji"]) text = if content do content |> String.replace(~r/<br\s?\/?>/, "\n") - |> HTML.get_cached_stripped_html_for_object(activity) + |> HTML.get_cached_stripped_html_for_object(activity, __MODULE__) end reply_parent = Activity.get_in_reply_to_activity(activity) |