total rebase
[anni] / lib / pleroma / html.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.HTML do
6   # Scrubbers are compiled on boot so they can be configured in OTP releases
7   #  @on_load :compile_scrubbers
8
9   def compile_scrubbers do
10     dir = Path.join(:code.priv_dir(:pleroma), "scrubbers")
11
12     dir
13     |> Pleroma.Utils.compile_dir()
14     |> case do
15       {:error, _errors, _warnings} ->
16         raise "Compiling scrubbers failed"
17
18       {:ok, _modules, _warnings} ->
19         :ok
20     end
21   end
22
23   defp get_scrubbers(scrubber) when is_atom(scrubber), do: [scrubber]
24   defp get_scrubbers(scrubbers) when is_list(scrubbers), do: scrubbers
25   defp get_scrubbers(_), do: [Pleroma.HTML.Scrubber.Default]
26
27   def get_scrubbers do
28     Pleroma.Config.get([:markup, :scrub_policy])
29     |> get_scrubbers
30   end
31
32   def filter_tags(html, nil) do
33     filter_tags(html, get_scrubbers())
34   end
35
36   def filter_tags(html, scrubbers) when is_list(scrubbers) do
37     Enum.reduce(scrubbers, html, fn scrubber, html ->
38       filter_tags(html, scrubber)
39     end)
40   end
41
42   def filter_tags(html, scrubber) do
43     {:ok, content} = FastSanitize.Sanitizer.scrub(html, scrubber)
44     content
45   end
46
47   def filter_tags(html), do: filter_tags(html, nil)
48   def strip_tags(html), do: filter_tags(html, FastSanitize.Sanitizer.StripTags)
49
50   def ensure_scrubbed_html(
51         content,
52         scrubbers,
53         fake,
54         callback
55       ) do
56     content =
57       content
58       |> filter_tags(scrubbers)
59       |> callback.()
60
61     if fake do
62       {:ignore, content}
63     else
64       {:commit, content}
65     end
66   end
67
68   @spec extract_first_external_url_from_object(Pleroma.Object.t()) :: String.t() | nil
69   def extract_first_external_url_from_object(%{data: %{"content" => content}})
70       when is_binary(content) do
71     content
72     |> Floki.parse_fragment!()
73     |> Floki.find("a:not(.mention,.hashtag,.attachment,[rel~=\"tag\"])")
74     |> Enum.take(1)
75     |> Floki.attribute("href")
76     |> Enum.at(0)
77   end
78
79   def extract_first_external_url_from_object(_), do: nil
80 end