added test for Ostatus

This commit is contained in:
Maksim Pechnikov 2019-09-12 09:59:34 +03:00
parent 50269e9cac
commit 4f548cb2b7
4 changed files with 68 additions and 67 deletions

View file

@ -1049,8 +1049,8 @@ def upgrade_user_from_ap_id(ap_id) do
with %User{local: false} = user <- User.get_cached_by_ap_id(ap_id), with %User{local: false} = user <- User.get_cached_by_ap_id(ap_id),
{:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id), {:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id),
already_ap <- User.ap_enabled?(user), already_ap <- User.ap_enabled?(user),
{:ok, user} <- user |> User.upgrade_changeset(data) |> User.update_and_set_cache() do {:ok, user} <- upgrade_user(user, data) do
unless already_ap do if not already_ap do
PleromaJobQueue.enqueue(:transmogrifier, __MODULE__, [:user_upgrade, user]) PleromaJobQueue.enqueue(:transmogrifier, __MODULE__, [:user_upgrade, user])
end end
@ -1061,6 +1061,12 @@ def upgrade_user_from_ap_id(ap_id) do
end end
end end
defp upgrade_user(user, data) do
user
|> User.upgrade_changeset(data)
|> User.update_and_set_cache()
end
def maybe_retire_websub(ap_id) do def maybe_retire_websub(ap_id) do
# some sanity checks # some sanity checks
if is_binary(ap_id) && String.length(ap_id) > 8 do if is_binary(ap_id) && String.length(ap_id) > 8 do

View file

@ -3,14 +3,12 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.OStatus do defmodule Pleroma.Web.OStatus do
import Ecto.Query
import Pleroma.Web.XML import Pleroma.Web.XML
require Logger require Logger
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.HTTP alias Pleroma.HTTP
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web alias Pleroma.Web
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
@ -38,21 +36,13 @@ def is_representable?(%Activity{} = activity) do
end end
end end
def feed_path(user) do def feed_path(user), do: "#{user.ap_id}/feed.atom"
"#{user.ap_id}/feed.atom"
end
def pubsub_path(user) do def pubsub_path(user), do: "#{Web.base_url()}/push/hub/#{user.nickname}"
"#{Web.base_url()}/push/hub/#{user.nickname}"
end
def salmon_path(user) do def salmon_path(user), do: "#{user.ap_id}/salmon"
"#{user.ap_id}/salmon"
end
def remote_follow_path do def remote_follow_path, do: "#{Web.base_url()}/ostatus_subscribe?acct={uri}"
"#{Web.base_url()}/ostatus_subscribe?acct={uri}"
end
def handle_incoming(xml_string, options \\ []) do def handle_incoming(xml_string, options \\ []) do
with doc when doc != :error <- parse_document(xml_string) do with doc when doc != :error <- parse_document(xml_string) do
@ -217,10 +207,9 @@ def get_content(entry) do
Get the cw that mastodon uses. Get the cw that mastodon uses.
""" """
def get_cw(entry) do def get_cw(entry) do
with cw when not is_nil(cw) <- string_from_xpath("/*/summary", entry) do case string_from_xpath("/*/summary", entry) do
cw cw when not is_nil(cw) -> cw
else _ -> nil
_e -> nil
end end
end end
@ -232,19 +221,17 @@ def get_tags(entry) do
end end
def maybe_update(doc, user) do def maybe_update(doc, user) do
if "true" == string_from_xpath("//author[1]/ap_enabled", doc) do case string_from_xpath("//author[1]/ap_enabled", doc) do
Transmogrifier.upgrade_user_from_ap_id(user.ap_id) "true" ->
else Transmogrifier.upgrade_user_from_ap_id(user.ap_id)
maybe_update_ostatus(doc, user)
_ ->
maybe_update_ostatus(doc, user)
end end
end end
def maybe_update_ostatus(doc, user) do def maybe_update_ostatus(doc, user) do
old_data = %{ old_data = Map.take(user, [:bio, :avatar, :name])
avatar: user.avatar,
bio: user.bio,
name: user.name
}
with false <- user.local, with false <- user.local,
avatar <- make_avatar_object(doc), avatar <- make_avatar_object(doc),
@ -279,38 +266,37 @@ def find_make_or_update_actor(doc) do
end end
end end
@spec find_or_make_user(String.t()) :: {:ok, User.t()}
def find_or_make_user(uri) do def find_or_make_user(uri) do
query = from(user in User, where: user.ap_id == ^uri) case User.get_by_ap_id(uri) do
%User{} = user -> {:ok, user}
user = Repo.one(query) _ -> make_user(uri)
if is_nil(user) do
make_user(uri)
else
{:ok, user}
end end
end end
@spec make_user(String.t(), boolean()) :: {:ok, User.t()} | {:error, any()}
def make_user(uri, update \\ false) do def make_user(uri, update \\ false) do
with {:ok, info} <- gather_user_info(uri) do with {:ok, info} <- gather_user_info(uri) do
data = %{
name: info["name"],
nickname: info["nickname"] <> "@" <> info["host"],
ap_id: info["uri"],
info: info,
avatar: info["avatar"],
bio: info["bio"]
}
with false <- update, with false <- update,
%User{} = user <- User.get_cached_by_ap_id(data.ap_id) do %User{} = user <- User.get_cached_by_ap_id(info["uri"]) do
{:ok, user} {:ok, user}
else else
_e -> User.insert_or_update_user(data) _e -> User.insert_or_update_user(build_user_data(info))
end end
end end
end end
defp build_user_data(info) do
%{
name: info["name"],
nickname: info["nickname"] <> "@" <> info["host"],
ap_id: info["uri"],
info: info,
avatar: info["avatar"],
bio: info["bio"]
}
end
# TODO: Just takes the first one for now. # TODO: Just takes the first one for now.
def make_avatar_object(author_doc, rel \\ "avatar") do def make_avatar_object(author_doc, rel \\ "avatar") do
href = string_from_xpath("//author[1]/link[@rel=\"#{rel}\"]/@href", author_doc) href = string_from_xpath("//author[1]/link[@rel=\"#{rel}\"]/@href", author_doc)
@ -319,23 +305,23 @@ def make_avatar_object(author_doc, rel \\ "avatar") do
if href do if href do
%{ %{
"type" => "Image", "type" => "Image",
"url" => [ "url" => [%{"type" => "Link", "mediaType" => type, "href" => href}]
%{
"type" => "Link",
"mediaType" => type,
"href" => href
}
]
} }
else else
nil nil
end end
end end
@spec gather_user_info(String.t()) :: {:ok, map()} | {:error, any()}
def gather_user_info(username) do def gather_user_info(username) do
with {:ok, webfinger_data} <- WebFinger.finger(username), with {:ok, webfinger_data} <- WebFinger.finger(username),
{:ok, feed_data} <- Websub.gather_feed_data(webfinger_data["topic"]) do {:ok, feed_data} <- Websub.gather_feed_data(webfinger_data["topic"]) do
{:ok, Map.merge(webfinger_data, feed_data) |> Map.put("fqn", username)} data =
webfinger_data
|> Map.merge(feed_data)
|> Map.put("fqn", username)
{:ok, data}
else else
e -> e ->
Logger.debug(fn -> "Couldn't gather info for #{username}" end) Logger.debug(fn -> "Couldn't gather info for #{username}" end)
@ -371,10 +357,7 @@ def get_atom_url(body) do
def fetch_activity_from_atom_url(url, options \\ []) do def fetch_activity_from_atom_url(url, options \\ []) do
with true <- String.starts_with?(url, "http"), with true <- String.starts_with?(url, "http"),
{:ok, %{body: body, status: code}} when code in 200..299 <- {:ok, %{body: body, status: code}} when code in 200..299 <-
HTTP.get( HTTP.get(url, [{:Accept, "application/atom+xml"}]) do
url,
[{:Accept, "application/atom+xml"}]
) do
Logger.debug("Got document from #{url}, handling...") Logger.debug("Got document from #{url}, handling...")
handle_incoming(body, options) handle_incoming(body, options)
else else

View file

@ -55,12 +55,11 @@ def feed_redirect(conn, %{"nickname" => nickname}) do
def feed(conn, %{"nickname" => nickname} = params) do def feed(conn, %{"nickname" => nickname} = params) do
with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do
query_params =
Map.take(params, ["max_id"])
|> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id})
activities = activities =
ActivityPub.fetch_public_activities(query_params) params
|> Map.take(["max_id"])
|> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id})
|> ActivityPub.fetch_public_activities()
|> Enum.reverse() |> Enum.reverse()
response = response =
@ -98,8 +97,7 @@ def salmon_incoming(conn, _) do
Federator.incoming_doc(doc) Federator.incoming_doc(doc)
conn send_resp(conn, 200, "")
|> send_resp(200, "")
end end
def object(%{assigns: %{format: format}} = conn, %{"uuid" => _uuid}) def object(%{assigns: %{format: format}} = conn, %{"uuid" => _uuid})

View file

@ -628,4 +628,18 @@ test "Article objects are not representable" do
refute OStatus.is_representable?(note_activity) refute OStatus.is_representable?(note_activity)
end end
end end
describe "make_user/2" do
test "creates new user" do
{:ok, user} = OStatus.make_user("https://social.heldscal.la/user/23211")
created_user =
User
|> Repo.get_by(ap_id: "https://social.heldscal.la/user/23211")
|> Map.put(:last_digest_emailed_at, nil)
assert user.info
assert user == created_user
end
end
end end