forked from YokaiRick/akkoma
ActivityPub: Send out Accept after Follow.
This commit is contained in:
parent
e7b73359e3
commit
7b26443a76
6 changed files with 82 additions and 7 deletions
|
@ -150,11 +150,12 @@ def register_changeset(struct, params \\ %{}) do
|
||||||
|
|
||||||
def follow(%User{} = follower, %User{info: info} = followed) do
|
def follow(%User{} = follower, %User{info: info} = followed) do
|
||||||
ap_followers = followed.follower_address
|
ap_followers = followed.follower_address
|
||||||
|
|
||||||
if following?(follower, followed) or info["deactivated"] do
|
if following?(follower, followed) or info["deactivated"] do
|
||||||
{:error,
|
{:error,
|
||||||
"Could not follow user: #{followed.nickname} is already on your list."}
|
"Could not follow user: #{followed.nickname} is already on your list."}
|
||||||
else
|
else
|
||||||
if !followed.local && follower.local do
|
if !followed.local && follower.local && !ap_enabled?(followed) do
|
||||||
Websub.subscribe(follower, followed)
|
Websub.subscribe(follower, followed)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -420,4 +421,6 @@ def insert_or_update_user(data) do
|
||||||
cs = User.remote_user_creation(data)
|
cs = User.remote_user_creation(data)
|
||||||
Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname)
|
Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ap_enabled?(%User{info: %{"ap_enabled" => ap}}), do: ap
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,6 +49,16 @@ def create(%{to: to, actor: actor, context: context, object: object} = params) d
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def accept(%{to: to, actor: actor, object: object} = params) do
|
||||||
|
local = !(params[:local] == false) # only accept false as false value
|
||||||
|
|
||||||
|
with data <- %{"to" => to, "type" => "Accept", "actor" => actor, "object" => object},
|
||||||
|
{:ok, activity} <- insert(data, local),
|
||||||
|
:ok <- maybe_federate(activity) do
|
||||||
|
{:ok, activity}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# TODO: This is weird, maybe we shouldn't check here if we can make the activity.
|
# TODO: This is weird, maybe we shouldn't check here if we can make the activity.
|
||||||
def like(%User{ap_id: ap_id} = user, %Object{data: %{"id" => _}} = object, activity_id \\ nil, local \\ true) do
|
def like(%User{ap_id: ap_id} = user, %Object{data: %{"id" => _}} = object, activity_id \\ nil, local \\ true) do
|
||||||
with nil <- get_existing_like(ap_id, object),
|
with nil <- get_existing_like(ap_id, object),
|
||||||
|
@ -244,7 +254,11 @@ def make_user_from_ap_id(ap_id) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def publish(actor, activity) do
|
def publish(actor, activity) do
|
||||||
remote_users = Pleroma.Web.Salmon.remote_users(activity)
|
{:ok, followers} = User.get_followers(actor)
|
||||||
|
|
||||||
|
remote_users = Pleroma.Web.Salmon.remote_users(activity) ++ followers
|
||||||
|
|> Enum.uniq
|
||||||
|
|
||||||
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
|
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
|
||||||
Enum.each remote_users, fn(user) ->
|
Enum.each remote_users, fn(user) ->
|
||||||
if user.info["ap_enabled"] do
|
if user.info["ap_enabled"] do
|
||||||
|
|
|
@ -38,11 +38,11 @@ def handle_incoming(%{"type" => "Create", "object" => %{"type" => "Note"} = obje
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_incoming(%{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id}) do
|
def handle_incoming(%{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data) do
|
||||||
with %User{} = followed <- User.get_cached_by_ap_id(followed),
|
with %User{local: true} = followed <- User.get_cached_by_ap_id(followed),
|
||||||
%User{} = follower <- User.get_or_fetch_by_ap_id(follower),
|
%User{} = follower <- User.get_or_fetch_by_ap_id(follower),
|
||||||
{:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do
|
{:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do
|
||||||
# TODO: Send an "Accept" activity.
|
ActivityPub.accept(%{to: [follower.ap_id], actor: followed.ap_id, object: data, local: true})
|
||||||
User.follow(follower, followed)
|
User.follow(follower, followed)
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
else
|
else
|
||||||
|
@ -68,6 +68,13 @@ def prepare_outgoing(%{"type" => "Create", "object" => %{"type" => "Note"} = obj
|
||||||
{:ok, data}
|
{:ok, data}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def prepare_outgoing(%{"type" => type} = data) when type in ["Follow", "Accept"] do
|
||||||
|
data = data
|
||||||
|
|> Map.put("@context", "https://www.w3.org/ns/activitystreams")
|
||||||
|
|
||||||
|
{:ok, data}
|
||||||
|
end
|
||||||
|
|
||||||
def add_mention_tags(object) do
|
def add_mention_tags(object) do
|
||||||
mentions = object["to"]
|
mentions = object["to"]
|
||||||
|> Enum.map(fn (ap_id) -> User.get_cached_by_ap_id(ap_id) end)
|
|> Enum.map(fn (ap_id) -> User.get_cached_by_ap_id(ap_id) end)
|
||||||
|
|
|
@ -154,8 +154,16 @@ defp send_to_user(%{info: %{"salmon" => salmon}}, feed, poster) do
|
||||||
|
|
||||||
defp send_to_user(_,_,_), do: nil
|
defp send_to_user(_,_,_), do: nil
|
||||||
|
|
||||||
|
@supported_activities [
|
||||||
|
"Create",
|
||||||
|
"Follow",
|
||||||
|
"Like",
|
||||||
|
"Announce",
|
||||||
|
"Undo",
|
||||||
|
"Delete"
|
||||||
|
]
|
||||||
def publish(user, activity, poster \\ &@httpoison.post/4)
|
def publish(user, activity, poster \\ &@httpoison.post/4)
|
||||||
def publish(%{info: %{"keys" => keys}} = user, activity, poster) do
|
def publish(%{info: %{"keys" => keys}} = user, %{data: %{"type" => type}} = activity, poster) when type in @supported_activities do
|
||||||
feed = ActivityRepresenter.to_simple_form(activity, user, true)
|
feed = ActivityRepresenter.to_simple_form(activity, user, true)
|
||||||
|> ActivityRepresenter.wrap_with_entry
|
|> ActivityRepresenter.wrap_with_entry
|
||||||
|> :xmerl.export_simple(:xmerl_xml)
|
|> :xmerl.export_simple(:xmerl_xml)
|
||||||
|
|
|
@ -38,7 +38,15 @@ def verify(subscription, getter \\ &@httpoison.get/3) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def publish(topic, user, activity) do
|
@supported_activities [
|
||||||
|
"Create",
|
||||||
|
"Follow",
|
||||||
|
"Like",
|
||||||
|
"Announce",
|
||||||
|
"Undo",
|
||||||
|
"Delete"
|
||||||
|
]
|
||||||
|
def publish(topic, user, %{data: %{"type" => type}} = activity) when type in @supported_activities do
|
||||||
# TODO: Only send to still valid subscriptions.
|
# TODO: Only send to still valid subscriptions.
|
||||||
query = from sub in WebsubServerSubscription,
|
query = from sub in WebsubServerSubscription,
|
||||||
where: sub.topic == ^topic and sub.state == "active"
|
where: sub.topic == ^topic and sub.state == "active"
|
||||||
|
@ -58,6 +66,7 @@ def publish(topic, user, activity) do
|
||||||
Pleroma.Web.Federator.enqueue(:publish_single_websub, data)
|
Pleroma.Web.Federator.enqueue(:publish_single_websub, data)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
def publish(_,_,_), do: ""
|
||||||
|
|
||||||
def sign(secret, doc) do
|
def sign(secret, doc) do
|
||||||
:crypto.hmac(:sha, secret, to_string(doc)) |> Base.encode16 |> String.downcase
|
:crypto.hmac(:sha, secret, to_string(doc)) |> Base.encode16 |> String.downcase
|
||||||
|
|
34
test/fixtures/mastodon-accept-activity.json
vendored
Normal file
34
test/fixtures/mastodon-accept-activity.json
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"type": "Accept",
|
||||||
|
"signature": {
|
||||||
|
"type": "RsaSignature2017",
|
||||||
|
"signatureValue": "rBzK4Kqhd4g7HDS8WE5oRbWQb2R+HF/6awbUuMWhgru/xCODT0SJWSri0qWqEO4fPcpoUyz2d25cw6o+iy9wiozQb3hQNnu69AR+H5Mytc06+g10KCHexbGhbAEAw/7IzmeXELHUbaqeduaDIbdt1zw4RkwLXdqgQcGXTJ6ND1wM3WMHXQCK1m0flasIXFoBxpliPAGiElV8s0+Ltuh562GvflG3kB3WO+j+NaR0ZfG5G9N88xMj9UQlCKit5gpAE5p6syUsCU2WGBHywTumv73i3OVTIFfq+P9AdMsRuzw1r7zoKEsthW4aOzLQDi01ZjvdBz8zH6JnjDU7SMN/Ig==",
|
||||||
|
"creator": "http://mastodon.example.org/users/admin#main-key",
|
||||||
|
"created": "2018-02-17T14:36:41Z"
|
||||||
|
},
|
||||||
|
"object": {
|
||||||
|
"type": "Follow",
|
||||||
|
"object": "http://mastodon.example.org/users/admin",
|
||||||
|
"id": "http://localtesting.pleroma.lol/users/lain#follows/4",
|
||||||
|
"actor": "http://localtesting.pleroma.lol/users/lain"
|
||||||
|
},
|
||||||
|
"nickname": "lain",
|
||||||
|
"id": "http://mastodon.example.org/users/admin#accepts/follows/4",
|
||||||
|
"actor": "http://mastodon.example.org/users/admin",
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://w3id.org/security/v1",
|
||||||
|
{
|
||||||
|
"toot": "http://joinmastodon.org/ns#",
|
||||||
|
"sensitive": "as:sensitive",
|
||||||
|
"ostatus": "http://ostatus.org#",
|
||||||
|
"movedTo": "as:movedTo",
|
||||||
|
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||||
|
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
|
||||||
|
"conversation": "ostatus:conversation",
|
||||||
|
"atomUri": "ostatus:atomUri",
|
||||||
|
"Hashtag": "as:Hashtag",
|
||||||
|
"Emoji": "toot:Emoji"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in a new issue