Resolve merge conflicts and remove IO.inspects
[akkoma] / lib / pleroma / web / activity_pub / mrf / tag_policy.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do
6 alias Pleroma.User
7 @behaviour Pleroma.Web.ActivityPub.MRF
8 @moduledoc """
9 Apply policies based on user tags
10
11 This policy applies policies on a user activities depending on their tags
12 on your instance.
13
14 - `mrf_tag:media-force-nsfw`: Mark as sensitive on presence of attachments
15 - `mrf_tag:media-strip`: Remove attachments
16 - `mrf_tag:force-unlisted`: Mark as unlisted (removes from the federated timeline)
17 - `mrf_tag:sandbox`: Remove from public (local and federated) timelines
18 - `mrf_tag:disable-remote-subscription`: Reject non-local follow requests
19 - `mrf_tag:disable-any-subscription`: Reject any follow requests
20 """
21
22 defp get_tags(%User{tags: tags}) when is_list(tags), do: tags
23 defp get_tags(_), do: []
24
25 defp process_tag(
26 "mrf_tag:media-force-nsfw",
27 %{"type" => "Create", "object" => %{"attachment" => child_attachment} = object} = message
28 )
29 when length(child_attachment) > 0 do
30 tags = (object["tag"] || []) ++ ["nsfw"]
31
32 object =
33 object
34 |> Map.put("tag", tags)
35 |> Map.put("sensitive", true)
36
37 message = Map.put(message, "object", object)
38
39 {:ok, message}
40 end
41
42 defp process_tag(
43 "mrf_tag:media-strip",
44 %{"type" => "Create", "object" => %{"attachment" => child_attachment} = object} = message
45 )
46 when length(child_attachment) > 0 do
47 object = Map.delete(object, "attachment")
48 message = Map.put(message, "object", object)
49
50 {:ok, message}
51 end
52
53 defp process_tag(
54 "mrf_tag:force-unlisted",
55 %{"type" => "Create", "to" => to, "cc" => cc, "actor" => actor} = message
56 ) do
57 user = User.get_cached_by_ap_id(actor)
58
59 if Enum.member?(to, "https://www.w3.org/ns/activitystreams#Public") do
60 to =
61 List.delete(to, "https://www.w3.org/ns/activitystreams#Public") ++ [user.follower_address]
62
63 cc =
64 List.delete(cc, user.follower_address) ++ ["https://www.w3.org/ns/activitystreams#Public"]
65
66 object =
67 message["object"]
68 |> Map.put("to", to)
69 |> Map.put("cc", cc)
70
71 message =
72 message
73 |> Map.put("to", to)
74 |> Map.put("cc", cc)
75 |> Map.put("object", object)
76
77 {:ok, message}
78 else
79 {:ok, message}
80 end
81 end
82
83 defp process_tag(
84 "mrf_tag:sandbox",
85 %{"type" => "Create", "to" => to, "cc" => cc, "actor" => actor} = message
86 ) do
87 user = User.get_cached_by_ap_id(actor)
88
89 if Enum.member?(to, "https://www.w3.org/ns/activitystreams#Public") or
90 Enum.member?(cc, "https://www.w3.org/ns/activitystreams#Public") do
91 to =
92 List.delete(to, "https://www.w3.org/ns/activitystreams#Public") ++ [user.follower_address]
93
94 cc = List.delete(cc, "https://www.w3.org/ns/activitystreams#Public")
95
96 object =
97 message["object"]
98 |> Map.put("to", to)
99 |> Map.put("cc", cc)
100
101 message =
102 message
103 |> Map.put("to", to)
104 |> Map.put("cc", cc)
105 |> Map.put("object", object)
106
107 {:ok, message}
108 else
109 {:ok, message}
110 end
111 end
112
113 defp process_tag(
114 "mrf_tag:disable-remote-subscription",
115 %{"type" => "Follow", "actor" => actor} = message
116 ) do
117 user = User.get_cached_by_ap_id(actor)
118
119 if user.local == true do
120 {:ok, message}
121 else
122 {:reject, nil}
123 end
124 end
125
126 defp process_tag("mrf_tag:disable-any-subscription", %{"type" => "Follow"}), do: {:reject, nil}
127
128 defp process_tag(_, message), do: {:ok, message}
129
130 def filter_message(actor, message) do
131 User.get_cached_by_ap_id(actor)
132 |> get_tags()
133 |> Enum.reduce({:ok, message}, fn
134 tag, {:ok, message} ->
135 process_tag(tag, message)
136
137 _, error ->
138 error
139 end)
140 end
141
142 @impl true
143 def filter(%{"object" => target_actor, "type" => "Follow"} = message),
144 do: filter_message(target_actor, message)
145
146 @impl true
147 def filter(%{"actor" => actor, "type" => "Create"} = message),
148 do: filter_message(actor, message)
149
150 @impl true
151 def filter(message), do: {:ok, message}
152 end