This commit is contained in:
dtluna 2017-05-16 01:24:26 +03:00
parent 6a3efd27fa
commit 3dd6bd4bfd
18 changed files with 65 additions and 60 deletions

View File

@ -15,7 +15,7 @@ defmodule Pleroma.Application do
# Start your own worker by calling: Pleroma.Worker.start_link(arg1, arg2, arg3) # Start your own worker by calling: Pleroma.Worker.start_link(arg1, arg2, arg3)
# worker(Pleroma.Worker, [arg1, arg2, arg3]), # worker(Pleroma.Worker, [arg1, arg2, arg3]),
worker(Cachex, [:user_cache, [ worker(Cachex, [:user_cache, [
default_ttl: 25000, default_ttl: 25_000,
ttl_interval: 1000, ttl_interval: 1000,
limit: 2500 limit: 2500
]]), ]]),

View File

@ -123,10 +123,10 @@ defmodule Pleroma.User do
following = follower.following following = follower.following
|> List.delete(ap_followers) |> List.delete(ap_followers)
{ :ok, follower } = follower {:ok, follower} = follower
|> follow_changeset(%{following: following}) |> follow_changeset(%{following: following})
|> Repo.update |> Repo.update
{ :ok, follower, ActivityPub.fetch_latest_follow(follower, followed)} {:ok, follower, ActivityPub.fetch_latest_follow(follower, followed)}
else else
{:error, "Not subscribed!"} {:error, "Not subscribed!"}
end end

View File

@ -101,7 +101,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end) end)
end end
def unlike(%User{ap_id: ap_id}, %Object{data: %{ "id" => id}} = object) do def unlike(%User{ap_id: ap_id}, %Object{data: %{"id" => id}} = object) do
query = from activity in Activity, query = from activity in Activity,
where: fragment("? @> ?", activity.data, ^%{actor: ap_id, object: id, type: "Like"}) where: fragment("? @> ?", activity.data, ^%{actor: ap_id, object: id, type: "Like"})
@ -157,7 +157,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
order_by: [desc: :inserted_at] order_by: [desc: :inserted_at]
query = Enum.reduce(recipients, query, fn (recipient, q) -> query = Enum.reduce(recipients, query, fn (recipient, q) ->
map = %{ to: [recipient] } map = %{to: [recipient]}
from activity in q, from activity in q,
or_where: fragment(~s(? @> ?), activity.data, ^map) or_where: fragment(~s(? @> ?), activity.data, ^map)
end) end)
@ -258,7 +258,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def fetch_activities_for_context(context) do def fetch_activities_for_context(context) do
query = from activity in Activity, query = from activity in Activity,
where: fragment("? @> ?", activity.data, ^%{ context: context }) where: fragment("? @> ?", activity.data, ^%{context: context})
Repo.all(query) Repo.all(query)
end end

View File

@ -99,7 +99,8 @@ defmodule Pleroma.Web.OStatus do
end end
def get_attachments(entry) do def get_attachments(entry) do
:xmerl_xpath.string('/entry/link[@rel="enclosure"]', entry) xpath = :xmerl_xpath.string('/entry/link[@rel="enclosure"]', entry)
xpath
|> Enum.map(fn (enclosure) -> |> Enum.map(fn (enclosure) ->
with href when not is_nil(href) <- string_from_xpath("/link/@href", enclosure), with href when not is_nil(href) <- string_from_xpath("/link/@href", enclosure),
type when not is_nil(type) <- string_from_xpath("/link/@type", enclosure) do type when not is_nil(type) <- string_from_xpath("/link/@type", enclosure) do
@ -121,12 +122,12 @@ defmodule Pleroma.Web.OStatus do
[author] = :xmerl_xpath.string('//author[1]', doc) [author] = :xmerl_xpath.string('//author[1]', doc)
{:ok, actor} = find_make_or_update_user(author) {:ok, actor} = find_make_or_update_user(author)
inReplyTo = string_from_xpath("//thr:in-reply-to[1]/@ref", entry) in_reply_to = string_from_xpath("//thr:in-reply-to[1]/@ref", entry)
if !Object.get_cached_by_ap_id(inReplyTo) do if !Object.get_cached_by_ap_id(in_reply_to) do
inReplyToHref = string_from_xpath("//thr:in-reply-to[1]/@href", entry) in_reply_to_href = string_from_xpath("//thr:in-reply-to[1]/@href", entry)
if inReplyToHref do if in_reply_to_href do
fetch_activity_from_html_url(inReplyToHref) fetch_activity_from_html_url(in_reply_to_href)
end end
end end
@ -134,7 +135,7 @@ defmodule Pleroma.Web.OStatus do
attachments = get_attachments(entry) attachments = get_attachments(entry)
context = with %{data: %{"context" => context}} <- Object.get_cached_by_ap_id(inReplyTo) do context = with %{data: %{"context" => context}} <- Object.get_cached_by_ap_id(in_reply_to) do
context context
else _e -> else _e ->
if String.length(context) > 0 do if String.length(context) > 0 do
@ -148,8 +149,8 @@ defmodule Pleroma.Web.OStatus do
"https://www.w3.org/ns/activitystreams#Public", "https://www.w3.org/ns/activitystreams#Public",
User.ap_followers(actor) User.ap_followers(actor)
] ]
xpath = :xmerl_xpath.string('//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]', entry)
mentions = :xmerl_xpath.string('//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]', entry) mentions = xpath
|> Enum.map(fn(person) -> string_from_xpath("@href", person) end) |> Enum.map(fn(person) -> string_from_xpath("@href", person) end)
to = to ++ mentions to = to ++ mentions
@ -168,8 +169,8 @@ defmodule Pleroma.Web.OStatus do
"attachment" => attachments "attachment" => attachments
} }
object = if inReplyTo do object = if in_reply_to do
Map.put(object, "inReplyTo", inReplyTo) Map.put(object, "inReplyTo", in_reply_to)
else else
object object
end end
@ -245,7 +246,7 @@ defmodule Pleroma.Web.OStatus do
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)} {:ok, webfinger_data |> Map.merge(feed_data) |> Map.put("fqn", username)}
else e -> else e ->
Logger.debug(fn -> "Couldn't gather info for #{username}" end) Logger.debug(fn -> "Couldn't gather info for #{username}" end)
{:error, e} {:error, e}

View File

@ -67,8 +67,8 @@ defmodule Pleroma.Web.Salmon do
end end
def encode_key({:RSAPublicKey, modulus, exponent}) do def encode_key({:RSAPublicKey, modulus, exponent}) do
modulus_enc = :binary.encode_unsigned(modulus) |> Base.url_encode64 modulus_enc = modulus |> :binary.encode_unsigned |> Base.url_encode64
exponent_enc = :binary.encode_unsigned(exponent) |> Base.url_encode64 exponent_enc = exponent |> :binary.encode_unsigned |> Base.url_encode64
"RSA.#{modulus_enc}.#{exponent_enc}" "RSA.#{modulus_enc}.#{exponent_enc}"
end end
@ -139,7 +139,8 @@ defmodule Pleroma.Web.Salmon do
def publish(user, activity, poster \\ &@httpoison.post/3) def publish(user, activity, poster \\ &@httpoison.post/3)
def publish(%{info: %{"keys" => keys}} = user, activity, poster) do def publish(%{info: %{"keys" => keys}} = user, activity, poster) do
feed = ActivityRepresenter.to_simple_form(activity, user, true) feed = activity
|> ActivityRepresenter.to_simple_form(user, true)
|> ActivityRepresenter.wrap_with_entry |> ActivityRepresenter.wrap_with_entry
|> :xmerl.export_simple(:xmerl_xml) |> :xmerl.export_simple(:xmerl_xml)
|> to_string |> to_string
@ -148,7 +149,8 @@ defmodule Pleroma.Web.Salmon do
{:ok, private, _} = keys_from_pem(keys) {:ok, private, _} = keys_from_pem(keys)
{:ok, feed} = encode(private, feed) {:ok, feed} = encode(private, feed)
remote_users(activity) activity
|> remote_users
|> Enum.each(fn(remote_user) -> |> Enum.each(fn(remote_user) ->
Task.start(fn -> Task.start(fn ->
Logger.debug(fn -> "sending salmon to #{remote_user.ap_id}" end) Logger.debug(fn -> "sending salmon to #{remote_user.ap_id}" end)

View File

@ -84,6 +84,8 @@ defmodule Pleroma.Web.TwitterAPI.StatusController do
end end
end end
#TODO: DRY the code
def favorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do def favorite(%{assigns: %{user: user}} = conn, %{"id" => id}) do
case find_activity(conn, id) do case find_activity(conn, id) do
{:not_found, response} -> response {:not_found, response} -> response

View File

@ -9,6 +9,8 @@ defmodule Pleroma.Web.TwitterAPI.UserController do
render conn, "show.json", %{user: user, for: user} render conn, "show.json", %{user: user, for: user}
end end
#TODO: DRY the code
def follow(%{assigns: %{user: follower}} = conn, params) do def follow(%{assigns: %{user: follower}} = conn, params) do
case find_user(conn, params) do case find_user(conn, params) do
{:ok, followed = %User{}} -> {:ok, followed = %User{}} ->

View File

@ -12,7 +12,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
end end
def format_input(text, mentions) do def format_input(text, mentions) do
HtmlSanitizeEx.strip_tags(text) text
|> HtmlSanitizeEx.strip_tags
|> String.replace("\n", "<br>") |> String.replace("\n", "<br>")
|> add_user_links(mentions) |> add_user_links(mentions)
end end
@ -49,13 +50,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
to = to_for_user_and_mentions(user, mentions) to = to_for_user_and_mentions(user, mentions)
date = Misc.make_date() date = Misc.make_date()
inReplyTo = get_replied_to_activity(data["in_reply_to_status_id"]) in_reply_to = get_replied_to_activity(data["in_reply_to_status_id"])
# Wire up reply info. # Wire up reply info.
[to, context, object, additional] = [to, context, object, additional] =
if inReplyTo do if in_reply_to do
context = inReplyTo.data["context"] context = in_reply_to.data["context"]
to = to ++ [inReplyTo.data["actor"]] to = to ++ [in_reply_to.data["actor"]]
object = %{ object = %{
"type" => "Note", "type" => "Note",
@ -65,8 +66,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
"context" => context, "context" => context,
"attachment" => attachments, "attachment" => attachments,
"actor" => user.ap_id, "actor" => user.ap_id,
"inReplyTo" => inReplyTo.data["object"]["id"], "inReplyTo" => in_reply_to.data["object"]["id"],
"inReplyToStatusId" => inReplyTo.id, "inReplyToStatusId" => in_reply_to.id,
} }
additional = %{} additional = %{}
@ -91,7 +92,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
# Modified from https://www.w3.org/TR/html5/forms.html#valid-e-mail-address # Modified from https://www.w3.org/TR/html5/forms.html#valid-e-mail-address
regex = ~r/@[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@?[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*/ regex = ~r/@[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@?[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*/
Regex.scan(regex, text) regex
|> Regex.scan(text)
|> List.flatten |> List.flatten
|> Enum.uniq |> Enum.uniq
|> Enum.map(fn ("@" <> match = full_match) -> {full_match, User.get_cached_by_nickname(match)} end) |> Enum.map(fn ("@" <> match = full_match) -> {full_match, User.get_cached_by_nickname(match)} end)

View File

@ -6,11 +6,11 @@ defmodule Pleroma.Web.TwitterAPI.StatusView do
def render( def render(
"show.json", "show.json",
assigns = %{ %{
activity: %Activity{ activity: %Activity{
data: %{"type" => "Announce", "id" => id, "object" => ap_id} data: %{"type" => "Announce", "id" => id, "object" => ap_id}
}, },
}) do } = assigns) do
{activity, user} = render_activity(assigns) {activity, user} = render_activity(assigns)
[announced_activity = %Activity{}] = Activity.all_by_object_ap_id(ap_id) [announced_activity = %Activity{}] = Activity.all_by_object_ap_id(ap_id)
@ -29,10 +29,10 @@ defmodule Pleroma.Web.TwitterAPI.StatusView do
def render( def render(
"show.json", "show.json",
assigns = %{activity: %Activity{ %{activity: %Activity{
data: %{"type" => "Like", "id" => id, "object" => liked_id} data: %{"type" => "Like", "id" => id, "object" => liked_id}
}, },
}) do } = assigns) do
{activity, %User{nickname: nickname}} = render_activity(assigns) {activity, %User{nickname: nickname}} = render_activity(assigns)
text = "#{nickname} favorited a status." text = "#{nickname} favorited a status."
[%Activity{id: liked_activity_id}] = Activity.all_by_object_ap_id(liked_id) [%Activity{id: liked_activity_id}] = Activity.all_by_object_ap_id(liked_id)
@ -47,11 +47,11 @@ defmodule Pleroma.Web.TwitterAPI.StatusView do
def render( def render(
"show.json", "show.json",
assigns = %{ %{
activity: %Activity{ activity: %Activity{
data: %{"type" => "Follow", "object" => followed_id} data: %{"type" => "Follow", "object" => followed_id}
} }
} } = assigns
) do ) do
{activity, %User{nickname: follower_name}} = render_activity(assigns) {activity, %User{nickname: follower_name}} = render_activity(assigns)
%User{nickname: followed_name} = User.get_cached_by_ap_id(followed_id) %User{nickname: followed_name} = User.get_cached_by_ap_id(followed_id)
@ -65,16 +65,16 @@ defmodule Pleroma.Web.TwitterAPI.StatusView do
def render( def render(
"show.json", "show.json",
assigns = %{ %{
activity: %Activity{ activity: %Activity{
data: %{ data: %{
"type" => "Create", "to" => to, "type" => "Create", "to" => to,
"object" => object = %{ "object" => %{
"content" => content "content" => content
} } = object
} }
} }
} } = assigns
) do ) do
announcement_count = object["announcement_count"] || 0 announcement_count = object["announcement_count"] || 0
repeated = Misc.to_boolean(assigns[:for] && assigns[:for].ap_id in (object["announcements"] || [])) repeated = Misc.to_boolean(assigns[:for] && assigns[:for].ap_id in (object["announcements"] || []))
@ -107,7 +107,7 @@ defmodule Pleroma.Web.TwitterAPI.StatusView do
}) })
end end
def render("timeline.json", assigns = %{activities: activities}) do def render("timeline.json", %{activities: activities} = assigns) do
render_many(activities, Pleroma.Web.TwitterAPI.StatusView, "show.json", render_many(activities, Pleroma.Web.TwitterAPI.StatusView, "show.json",
Map.merge(assigns, %{as: :activity})) Map.merge(assigns, %{as: :activity}))
end end

View File

@ -2,7 +2,7 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
use Pleroma.Web, :view use Pleroma.Web, :view
alias Pleroma.User alias Pleroma.User
def render("show.json", assigns = %{user: user = %User{}}) do def render("show.json", %{user: user = %User{}} = assigns) do
image = User.avatar_url(user) image = User.avatar_url(user)
following = if assigns[:for] do following = if assigns[:for] do
User.following?(assigns[:for], user) User.following?(assigns[:for], user)

View File

@ -61,7 +61,8 @@ defmodule Pleroma.Web.Websub do
end end
def sign(secret, doc) do def sign(secret, doc) do
:crypto.hmac(:sha, secret, to_string(doc)) |> Base.encode16 |> String.downcase encrypted_secret = :crypto.hmac(:sha, secret, to_string(doc))
encrypted_secret |> Base.encode16 |> String.downcase
end end
def incoming_subscription_request(user, %{"hub.mode" => "subscribe"} = params) do def incoming_subscription_request(user, %{"hub.mode" => "subscribe"} = params) do
@ -135,7 +136,7 @@ defmodule Pleroma.Web.Websub do
hub: subscribed.info["hub"], hub: subscribed.info["hub"],
subscribers: [subscriber.ap_id], subscribers: [subscriber.ap_id],
state: "requested", state: "requested",
secret: :crypto.strong_rand_bytes(8) |> Base.url_encode64, secret: Base.url_encode64(:crypto.strong_rand_bytes(8)),
user: subscribed user: subscribed
} }
Repo.insert(subscription) Repo.insert(subscription)
@ -152,15 +153,15 @@ defmodule Pleroma.Web.Websub do
hub when not is_nil(hub) <- XML.string_from_xpath(~S{/feed/link[@rel="hub"]/@href}, doc) do hub when not is_nil(hub) <- XML.string_from_xpath(~S{/feed/link[@rel="hub"]/@href}, doc) do
name = XML.string_from_xpath("/feed/author[1]/name", doc) name = XML.string_from_xpath("/feed/author[1]/name", doc)
preferredUsername = XML.string_from_xpath("/feed/author[1]/poco:preferredUsername", doc) preferred_username = XML.string_from_xpath("/feed/author[1]/poco:preferredUsername", doc)
displayName = XML.string_from_xpath("/feed/author[1]/poco:displayName", doc) display_name = XML.string_from_xpath("/feed/author[1]/poco:displayName", doc)
avatar = OStatus.make_avatar_object(doc) avatar = OStatus.make_avatar_object(doc)
{:ok, %{ {:ok, %{
"uri" => uri, "uri" => uri,
"hub" => hub, "hub" => hub,
"nickname" => preferredUsername || name, "nickname" => preferred_username || name,
"name" => displayName || name, "name" => display_name || name,
"host" => URI.parse(uri).host, "host" => URI.parse(uri).host,
"avatar" => avatar "avatar" => avatar
}} }}

View File

@ -16,7 +16,7 @@ defmodule Pleroma.ObjectTest do
cs = Object.change(%Object{}, %{data: %{id: object.data["id"]}}) cs = Object.change(%Object{}, %{data: %{id: object.data["id"]}})
assert cs.valid? assert cs.valid?
{:error, result} = Repo.insert(cs) {:error, _result} = Repo.insert(cs)
end end
end end
end end

View File

@ -9,11 +9,6 @@ defmodule Pleroma.UserTest do
import Ecto.Query import Ecto.Query
test "ap_id returns the activity pub id for the user" do test "ap_id returns the activity pub id for the user" do
host =
Application.get_env(:pleroma, Pleroma.Web.Endpoint)
|> Keyword.fetch!(:url)
|> Keyword.fetch!(:host)
user = UserBuilder.build user = UserBuilder.build
expected_ap_id = "#{Pleroma.Web.base_url}/users/#{user.nickname}" expected_ap_id = "#{Pleroma.Web.base_url}/users/#{user.nickname}"

View File

@ -80,7 +80,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenterTest do
user = insert(:user) user = insert(:user)
object = Object.get_cached_by_ap_id(note.data["object"]["id"]) object = Object.get_cached_by_ap_id(note.data["object"]["id"])
{:ok, announce, object} = ActivityPub.announce(user, object) {:ok, announce, _object} = ActivityPub.announce(user, object)
announce = Repo.get(Activity, announce.id) announce = Repo.get(Activity, announce.id)

View File

@ -84,7 +84,7 @@ defmodule Pleroma.Web.Salmon.SalmonTest do
user = Repo.get_by(User, ap_id: activity.data["actor"]) user = Repo.get_by(User, ap_id: activity.data["actor"])
{:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user) {:ok, user} = Pleroma.Web.WebFinger.ensure_keys_present(user)
poster = fn (url, data, headers) -> poster = fn (url, _data, _headers) ->
assert url == "http://example.org/salmon" assert url == "http://example.org/salmon"
end end
Salmon.publish(user, activity, poster) Salmon.publish(user, activity, poster)

View File

@ -7,6 +7,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
import Pleroma.Factory import Pleroma.Factory
# TODO: separate into individual controller tests
describe "POST /api/account/verify_credentials" do describe "POST /api/account/verify_credentials" do
setup [:valid_user] setup [:valid_user]
test "without valid credentials", %{conn: conn} do test "without valid credentials", %{conn: conn} do

View File

@ -3,7 +3,6 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
alias Pleroma.{User, Activity, Object} alias Pleroma.{User, Activity, Object}
alias Pleroma.Web.TwitterAPI.{AttachmentView, UserView, StatusView} alias Pleroma.Web.TwitterAPI.{AttachmentView, UserView, StatusView}
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Builders.UserBuilder
import Pleroma.Factory import Pleroma.Factory
test "an announce activity" do test "an announce activity" do
@ -45,7 +44,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
end end
test "an activity" do test "an activity" do
{:ok, user} = UserBuilder.insert user = insert(:user, %{nickname: "dtluna"})
# {:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"}) # {:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"})
mentioned_user = insert(:user, %{nickname: "shp"}) mentioned_user = insert(:user, %{nickname: "shp"})
@ -105,7 +104,6 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
"id" => activity.id, "id" => activity.id,
"user" => UserView.render("show.json", %{user: user, for: follower}), "user" => UserView.render("show.json", %{user: user, for: follower}),
"is_local" => true, "is_local" => true,
"attentions" => [],
"statusnet_html" => content_html, "statusnet_html" => content_html,
"text" => content, "text" => content,
"is_post_verb" => true, "is_post_verb" => true,

View File

@ -172,6 +172,6 @@ defmodule Pleroma.Web.WebsubTest do
signed = Websub.sign("secret", "text") signed = Websub.sign("secret", "text")
assert signed == "B8392C23690CCF871F37EC270BE1582DEC57A503" |> String.downcase assert signed == "B8392C23690CCF871F37EC270BE1582DEC57A503" |> String.downcase
signed = Websub.sign("secret", [[""], ['']]) Websub.sign("secret", [[""], ['']])
end end
end end