html: add the ability to override the default scrub policy
[akkoma] / lib / pleroma / html.ex
1 defmodule Pleroma.HTML do
2 alias HtmlSanitizeEx.Scrubber
3
4 @markup Application.get_env(:pleroma, :markup)
5
6 def filter_tags(html, scrubber) do
7 html |> Scrubber.scrub(scrubber)
8 end
9
10 def filter_tags(html) do
11 scrubber = Keyword.get(@markup, :scrub_policy)
12 filter_tags(html, scrubber)
13 end
14
15 def strip_tags(html) do
16 html |> Scrubber.scrub(Scrubber.StripTags)
17 end
18 end
19
20 defmodule Pleroma.HTML.Scrubber.TwitterText do
21 @moduledoc """
22 An HTML scrubbing policy which limits to twitter-style text. Only
23 paragraphs, breaks and links are allowed through the filter.
24 """
25
26 require HtmlSanitizeEx.Scrubber.Meta
27 alias HtmlSanitizeEx.Scrubber.Meta
28
29 @valid_schemes ["http", "https"]
30
31 Meta.remove_cdata_sections_before_scrub()
32 Meta.strip_comments()
33
34 # links
35 Meta.allow_tag_with_uri_attributes("a", ["href"], @valid_schemes)
36 Meta.allow_tag_with_these_attributes("a", ["name", "title"])
37
38 # paragraphs and linebreaks
39 Meta.allow_tag_with_these_attributes("br", [])
40 Meta.allow_tag_with_these_attributes("p", [])
41
42 # microformats
43 Meta.allow_tag_with_these_attributes("span", [])
44
45 # allow inline images for custom emoji
46 @markup Application.get_env(:pleroma, :markup)
47 @allow_inline_images Keyword.get(@markup, :allow_inline_images)
48
49 if @allow_inline_images do
50 Meta.allow_tag_with_uri_attributes("img", ["src"], @valid_schemes)
51
52 Meta.allow_tag_with_these_attributes("img", [
53 "width",
54 "height",
55 "title",
56 "alt"
57 ])
58 end
59 end
60
61 defmodule Pleroma.HTML.Scrubber.Default do
62 @doc "The default HTML scrubbing policy: no "
63
64 require HtmlSanitizeEx.Scrubber.Meta
65 alias HtmlSanitizeEx.Scrubber.Meta
66
67 @valid_schemes ["http", "https"]
68
69 Meta.remove_cdata_sections_before_scrub()
70 Meta.strip_comments()
71
72 Meta.allow_tag_with_uri_attributes("a", ["href"], @valid_schemes)
73 Meta.allow_tag_with_these_attributes("a", ["name", "title"])
74
75 Meta.allow_tag_with_these_attributes("b", [])
76 Meta.allow_tag_with_these_attributes("blockquote", [])
77 Meta.allow_tag_with_these_attributes("br", [])
78 Meta.allow_tag_with_these_attributes("code", [])
79 Meta.allow_tag_with_these_attributes("del", [])
80 Meta.allow_tag_with_these_attributes("em", [])
81 Meta.allow_tag_with_these_attributes("i", [])
82 Meta.allow_tag_with_these_attributes("li", [])
83 Meta.allow_tag_with_these_attributes("ol", [])
84 Meta.allow_tag_with_these_attributes("p", [])
85 Meta.allow_tag_with_these_attributes("pre", [])
86 Meta.allow_tag_with_these_attributes("span", [])
87 Meta.allow_tag_with_these_attributes("strong", [])
88 Meta.allow_tag_with_these_attributes("u", [])
89 Meta.allow_tag_with_these_attributes("ul", [])
90
91 @markup Application.get_env(:pleroma, :markup)
92 @allow_inline_images Keyword.get(@markup, :allow_inline_images)
93
94 if @allow_inline_images do
95 Meta.allow_tag_with_uri_attributes("img", ["src"], @valid_schemes)
96
97 Meta.allow_tag_with_these_attributes("img", [
98 "width",
99 "height",
100 "title",
101 "alt"
102 ])
103 end
104
105 @allow_tables Keyword.get(@markup, :allow_tables)
106
107 if @allow_tables do
108 Meta.allow_tag_with_these_attributes("table", [])
109 Meta.allow_tag_with_these_attributes("tbody", [])
110 Meta.allow_tag_with_these_attributes("td", [])
111 Meta.allow_tag_with_these_attributes("th", [])
112 Meta.allow_tag_with_these_attributes("thead", [])
113 Meta.allow_tag_with_these_attributes("tr", [])
114 end
115
116 @allow_headings Keyword.get(@markup, :allow_headings)
117
118 if @allow_headings do
119 Meta.allow_tag_with_these_attributes("h1", [])
120 Meta.allow_tag_with_these_attributes("h2", [])
121 Meta.allow_tag_with_these_attributes("h3", [])
122 Meta.allow_tag_with_these_attributes("h4", [])
123 Meta.allow_tag_with_these_attributes("h5", [])
124 end
125
126 @allow_fonts Keyword.get(@markup, :allow_fonts)
127
128 if @allow_fonts do
129 Meta.allow_tag_with_these_attributes("font", ["face"])
130 end
131
132 Meta.strip_everything_not_covered()
133 end