aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2018-03-30 15:01:53 +0200
committerlain <lain@soykaf.club>2018-03-30 15:01:53 +0200
commit4afbef39f49948ddd3b1cd1bbda58ff7e3ac2785 (patch)
tree6959e12d9058c981f3b69c77b8b0290049651cd6 /lib
parent480932c8e524e1a80c9c8ef1a1aa23379f633afe (diff)
downloadpleroma-4afbef39f49948ddd3b1cd1bbda58ff7e3ac2785.tar.gz
Format the code.
Diffstat (limited to 'lib')
-rw-r--r--lib/jason_types.ex6
-rw-r--r--lib/mix/tasks/fix_ap_users.ex12
-rw-r--r--lib/mix/tasks/generate_config.ex64
-rw-r--r--lib/mix/tasks/generate_password_reset.ex15
-rw-r--r--lib/mix/tasks/make_moderator.ex19
-rw-r--r--lib/pleroma/PasswordResetToken.ex8
-rw-r--r--lib/pleroma/activity.ex56
-rw-r--r--lib/pleroma/application.ex45
-rw-r--r--lib/pleroma/formatter.ex128
-rw-r--r--lib/pleroma/http/http.ex3
-rw-r--r--lib/pleroma/notification.ex57
-rw-r--r--lib/pleroma/object.ex30
-rw-r--r--lib/pleroma/plugs/authentication_plug.ex8
-rw-r--r--lib/pleroma/plugs/oauth_plug.ex11
-rw-r--r--lib/pleroma/stats.ex25
-rw-r--r--lib/pleroma/upload.ex93
-rw-r--r--lib/pleroma/user.ex260
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub.ex263
-rw-r--r--lib/pleroma/web/activity_pub/activity_pub_controller.ex11
-rw-r--r--lib/pleroma/web/activity_pub/transmogrifier.ex250
-rw-r--r--lib/pleroma/web/activity_pub/utils.ex93
-rw-r--r--lib/pleroma/web/activity_pub/views/user_view.ex25
-rw-r--r--lib/pleroma/web/channels/user_socket.ex4
-rw-r--r--lib/pleroma/web/chat_channel.ex8
-rw-r--r--lib/pleroma/web/common_api/common_api.ex53
-rw-r--r--lib/pleroma/web/common_api/utils.ex92
-rw-r--r--lib/pleroma/web/endpoint.ex38
-rw-r--r--lib/pleroma/web/federator/federator.ex63
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_api.ex1
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_api_controller.ex538
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_socket.ex26
-rw-r--r--lib/pleroma/web/mastodon_api/views/status_view.ex87
-rw-r--r--lib/pleroma/web/media_proxy/controller.ex57
-rw-r--r--lib/pleroma/web/media_proxy/media_proxy.ex7
-rw-r--r--lib/pleroma/web/oauth/app.ex23
-rw-r--r--lib/pleroma/web/oauth/authorization.ex17
-rw-r--r--lib/pleroma/web/oauth/fallback_controller.ex19
-rw-r--r--lib/pleroma/web/oauth/oauth_controller.ex60
-rw-r--r--lib/pleroma/web/oauth/token.ex16
-rw-r--r--lib/pleroma/web/ostatus/activity_representer.ex185
-rw-r--r--lib/pleroma/web/ostatus/feed_representer.ex81
-rw-r--r--lib/pleroma/web/ostatus/handlers/follow_handler.ex3
-rw-r--r--lib/pleroma/web/ostatus/handlers/note_handler.ex82
-rw-r--r--lib/pleroma/web/ostatus/ostatus.ex186
-rw-r--r--lib/pleroma/web/ostatus/ostatus_controller.ex42
-rw-r--r--lib/pleroma/web/ostatus/user_representer.ex24
-rw-r--r--lib/pleroma/web/router.ex337
-rw-r--r--lib/pleroma/web/salmon/salmon.ex90
-rw-r--r--lib/pleroma/web/streamer.ex67
-rw-r--r--lib/pleroma/web/twitter_api/controllers/util_controller.ex98
-rw-r--r--lib/pleroma/web/twitter_api/representers/activity_representer.ex86
-rw-r--r--lib/pleroma/web/twitter_api/representers/base_representer.ex16
-rw-r--r--lib/pleroma/web/twitter_api/representers/object_representer.ex1
-rw-r--r--lib/pleroma/web/twitter_api/twitter_api.ex173
-rw-r--r--lib/pleroma/web/twitter_api/twitter_api_controller.ex81
-rw-r--r--lib/pleroma/web/twitter_api/views/activity_view.ex44
-rw-r--r--lib/pleroma/web/twitter_api/views/user_view.ex35
-rw-r--r--lib/pleroma/web/views/error_view.ex2
-rw-r--r--lib/pleroma/web/web.ex7
-rw-r--r--lib/pleroma/web/web_finger/web_finger.ex206
-rw-r--r--lib/pleroma/web/web_finger/web_finger_controller.ex4
-rw-r--r--lib/pleroma/web/websub/websub.ex158
-rw-r--r--lib/pleroma/web/websub/websub_client_subscription.ex14
-rw-r--r--lib/pleroma/web/websub/websub_controller.ex58
-rw-r--r--lib/pleroma/web/websub/websub_server_subscription.ex10
-rw-r--r--lib/pleroma/web/xml/xml.ex15
-rw-r--r--lib/transports.ex28
-rw-r--r--lib/xml_builder.ex12
68 files changed, 2969 insertions, 1767 deletions
diff --git a/lib/jason_types.ex b/lib/jason_types.ex
index 4c89664ff..d1a7bc7ac 100644
--- a/lib/jason_types.ex
+++ b/lib/jason_types.ex
@@ -1 +1,5 @@
-Postgrex.Types.define(Pleroma.PostgresTypes, [] ++ Ecto.Adapters.Postgres.extensions(), json: Jason)
+Postgrex.Types.define(
+ Pleroma.PostgresTypes,
+ [] ++ Ecto.Adapters.Postgres.extensions(),
+ json: Jason
+)
diff --git a/lib/mix/tasks/fix_ap_users.ex b/lib/mix/tasks/fix_ap_users.ex
index ff09074c3..2523cdbcb 100644
--- a/lib/mix/tasks/fix_ap_users.ex
+++ b/lib/mix/tasks/fix_ap_users.ex
@@ -8,12 +8,16 @@ defmodule Mix.Tasks.FixApUsers do
def run([]) do
Mix.Task.run("app.start")
- q = from u in User,
- where: fragment("? @> ?", u.info, ^%{"ap_enabled" => true}),
- where: u.local == false
+ q =
+ from(
+ u in User,
+ where: fragment("? @> ?", u.info, ^%{"ap_enabled" => true}),
+ where: u.local == false
+ )
+
users = Repo.all(q)
- Enum.each(users, fn(user) ->
+ Enum.each(users, fn user ->
try do
IO.puts("Fetching #{user.nickname}")
Pleroma.Web.ActivityPub.Transmogrifier.upgrade_user_from_ap_id(user.ap_id, false)
diff --git a/lib/mix/tasks/generate_config.ex b/lib/mix/tasks/generate_config.ex
index 2d962124f..ae9ac3b75 100644
--- a/lib/mix/tasks/generate_config.ex
+++ b/lib/mix/tasks/generate_config.ex
@@ -5,27 +5,51 @@ defmodule Mix.Tasks.GenerateConfig do
def run(_) do
IO.puts("Answer a few questions to generate a new config\n")
IO.puts("--- THIS WILL OVERWRITE YOUR config/generated_config.exs! ---\n")
- domain = IO.gets("What is your domain name? (e.g. pleroma.soykaf.com): ") |> String.trim
- name = IO.gets("What is the name of your instance? (e.g. Pleroma/Soykaf): ") |> String.trim
- email = IO.gets("What's your admin email address: ") |> String.trim
- mediaproxy = IO.gets("Do you want to activate the mediaproxy? (y/N): ")
- |> String.trim()
- |> String.downcase()
- |> String.starts_with?("y")
- proxy_url = if mediaproxy do
- IO.gets("What is the mediaproxy's URL? (e.g. https://cache.example.com): ") |> String.trim
- else
- "https://cache.example.com"
- end
- secret = :crypto.strong_rand_bytes(64) |> Base.encode64 |> binary_part(0, 64)
- dbpass = :crypto.strong_rand_bytes(64) |> Base.encode64 |> binary_part(0, 64)
-
- resultSql = EEx.eval_file("lib/mix/tasks/sample_psql.eex", [dbpass: dbpass])
- result = EEx.eval_file("lib/mix/tasks/sample_config.eex", [domain: domain, email: email, name: name, secret: secret, mediaproxy: mediaproxy, proxy_url: proxy_url, dbpass: dbpass])
-
- IO.puts("\nWriting config to config/generated_config.exs.\n\nCheck it and configure your database, then copy it to either config/dev.secret.exs or config/prod.secret.exs")
+ domain = IO.gets("What is your domain name? (e.g. pleroma.soykaf.com): ") |> String.trim()
+ name = IO.gets("What is the name of your instance? (e.g. Pleroma/Soykaf): ") |> String.trim()
+ email = IO.gets("What's your admin email address: ") |> String.trim()
+
+ mediaproxy =
+ IO.gets("Do you want to activate the mediaproxy? (y/N): ")
+ |> String.trim()
+ |> String.downcase()
+ |> String.starts_with?("y")
+
+ proxy_url =
+ if mediaproxy do
+ IO.gets("What is the mediaproxy's URL? (e.g. https://cache.example.com): ")
+ |> String.trim()
+ else
+ "https://cache.example.com"
+ end
+
+ secret = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
+ dbpass = :crypto.strong_rand_bytes(64) |> Base.encode64() |> binary_part(0, 64)
+
+ resultSql = EEx.eval_file("lib/mix/tasks/sample_psql.eex", dbpass: dbpass)
+
+ result =
+ EEx.eval_file(
+ "lib/mix/tasks/sample_config.eex",
+ domain: domain,
+ email: email,
+ name: name,
+ secret: secret,
+ mediaproxy: mediaproxy,
+ proxy_url: proxy_url,
+ dbpass: dbpass
+ )
+
+ IO.puts(
+ "\nWriting config to config/generated_config.exs.\n\nCheck it and configure your database, then copy it to either config/dev.secret.exs or config/prod.secret.exs"
+ )
+
File.write("config/generated_config.exs", result)
- IO.puts("\nWriting setup_db.psql, please run it as postgre superuser, i.e.: sudo su postgres -c 'psql -f config/setup_db.psql'")
+
+ IO.puts(
+ "\nWriting setup_db.psql, please run it as postgre superuser, i.e.: sudo su postgres -c 'psql -f config/setup_db.psql'"
+ )
+
File.write("config/setup_db.psql", resultSql)
end
end
diff --git a/lib/mix/tasks/generate_password_reset.ex b/lib/mix/tasks/generate_password_reset.ex
index b968b1f98..e39134007 100644
--- a/lib/mix/tasks/generate_password_reset.ex
+++ b/lib/mix/tasks/generate_password_reset.ex
@@ -9,11 +9,20 @@ defmodule Mix.Tasks.GeneratePasswordReset do
with %User{local: true} = user <- User.get_by_nickname(nickname),
{:ok, token} <- Pleroma.PasswordResetToken.create_token(user) do
- IO.puts "Generated password reset token for #{user.nickname}"
- IO.puts "Url: #{Pleroma.Web.Router.Helpers.util_url(Pleroma.Web.Endpoint, :show_password_reset, token.token)}"
+ IO.puts("Generated password reset token for #{user.nickname}")
+
+ IO.puts(
+ "Url: #{
+ Pleroma.Web.Router.Helpers.util_url(
+ Pleroma.Web.Endpoint,
+ :show_password_reset,
+ token.token
+ )
+ }"
+ )
else
_ ->
- IO.puts "No local user #{nickname}"
+ IO.puts("No local user #{nickname}")
end
end
end
diff --git a/lib/mix/tasks/make_moderator.ex b/lib/mix/tasks/make_moderator.ex
index a76b54f40..20f04c54c 100644
--- a/lib/mix/tasks/make_moderator.ex
+++ b/lib/mix/tasks/make_moderator.ex
@@ -7,21 +7,24 @@ defmodule Mix.Tasks.SetModerator do
def run([nickname | rest]) do
ensure_started(Repo, [])
- moderator = case rest do
- [moderator] -> moderator == "true"
- _ -> true
- end
+ moderator =
+ case rest do
+ [moderator] -> moderator == "true"
+ _ -> true
+ end
with %User{local: true} = user <- User.get_by_nickname(nickname) do
- info = user.info
- |> Map.put("is_moderator", !!moderator)
+ info =
+ user.info
+ |> Map.put("is_moderator", !!moderator)
+
cng = User.info_changeset(user, %{info: info})
user = Repo.update!(cng)
- IO.puts "Moderator status of #{nickname}: #{user.info["is_moderator"]}"
+ IO.puts("Moderator status of #{nickname}: #{user.info["is_moderator"]}")
else
_ ->
- IO.puts "No local user #{nickname}"
+ IO.puts("No local user #{nickname}")
end
end
end
diff --git a/lib/pleroma/PasswordResetToken.ex b/lib/pleroma/PasswordResetToken.ex
index 52b1fcd50..15750565b 100644
--- a/lib/pleroma/PasswordResetToken.ex
+++ b/lib/pleroma/PasswordResetToken.ex
@@ -6,15 +6,15 @@ defmodule Pleroma.PasswordResetToken do
alias Pleroma.{User, PasswordResetToken, Repo}
schema "password_reset_tokens" do
- belongs_to :user, User
- field :token, :string
- field :used, :boolean, default: false
+ belongs_to(:user, User)
+ field(:token, :string)
+ field(:used, :boolean, default: false)
timestamps()
end
def create_token(%User{} = user) do
- token = :crypto.strong_rand_bytes(32) |> Base.url_encode64
+ token = :crypto.strong_rand_bytes(32) |> Base.url_encode64()
token = %PasswordResetToken{
user_id: user.id,
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index 96ddcc480..c7502981e 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -4,33 +4,53 @@ defmodule Pleroma.Activity do
import Ecto.Query
schema "activities" do
- field :data, :map
- field :local, :boolean, default: true
- field :actor, :string
- field :recipients, {:array, :string}
- has_many :notifications, Notification, on_delete: :delete_all
+ field(:data, :map)
+ field(:local, :boolean, default: true)
+ field(:actor, :string)
+ field(:recipients, {:array, :string})
+ has_many(:notifications, Notification, on_delete: :delete_all)
timestamps()
end
def get_by_ap_id(ap_id) do
- Repo.one(from activity in Activity,
- where: fragment("(?)->>'id' = ?", activity.data, ^to_string(ap_id)))
+ Repo.one(
+ from(
+ activity in Activity,
+ where: fragment("(?)->>'id' = ?", activity.data, ^to_string(ap_id))
+ )
+ )
end
# TODO:
# Go through these and fix them everywhere.
# Wrong name, only returns create activities
def all_by_object_ap_id_q(ap_id) do
- from activity in Activity,
- where: fragment("coalesce((?)->'object'->>'id', (?)->>'object') = ?", activity.data, activity.data, ^to_string(ap_id)),
+ from(
+ activity in Activity,
+ where:
+ fragment(
+ "coalesce((?)->'object'->>'id', (?)->>'object') = ?",
+ activity.data,
+ activity.data,
+ ^to_string(ap_id)
+ ),
where: fragment("(?)->>'type' = 'Create'", activity.data)
+ )
end
# Wrong name, returns all.
def all_non_create_by_object_ap_id_q(ap_id) do
- from activity in Activity,
- where: fragment("coalesce((?)->'object'->>'id', (?)->>'object') = ?", activity.data, activity.data, ^to_string(ap_id))
+ from(
+ activity in Activity,
+ where:
+ fragment(
+ "coalesce((?)->'object'->>'id', (?)->>'object') = ?",
+ activity.data,
+ activity.data,
+ ^to_string(ap_id)
+ )
+ )
end
# Wrong name plz fix thx
@@ -39,13 +59,21 @@ defmodule Pleroma.Activity do
end
def create_activity_by_object_id_query(ap_ids) do
- from activity in Activity,
- where: fragment("coalesce((?)->'object'->>'id', (?)->>'object') = ANY(?)", activity.data, activity.data, ^ap_ids),
+ from(
+ activity in Activity,
+ where:
+ fragment(
+ "coalesce((?)->'object'->>'id', (?)->>'object') = ANY(?)",
+ activity.data,
+ activity.data,
+ ^ap_ids
+ ),
where: fragment("(?)->>'type' = 'Create'", activity.data)
+ )
end
def get_create_activity_by_object_ap_id(ap_id) do
create_activity_by_object_id_query([ap_id])
- |> Repo.one
+ |> Repo.one()
end
end
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index 79b9dee9d..5e29a5d65 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -7,23 +7,34 @@ defmodule Pleroma.Application do
import Supervisor.Spec
# Define workers and child supervisors to be supervised
- children = [
- # Start the Ecto repository
- supervisor(Pleroma.Repo, []),
- # Start the endpoint when the application starts
- supervisor(Pleroma.Web.Endpoint, []),
- # Start your own worker by calling: Pleroma.Worker.start_link(arg1, arg2, arg3)
- # worker(Pleroma.Worker, [arg1, arg2, arg3]),
- worker(Cachex, [:user_cache, [
- default_ttl: 25000,
- ttl_interval: 1000,
- limit: 2500
- ]]),
- worker(Pleroma.Web.Federator, []),
- worker(Pleroma.Stats, []),
- ]
- ++ if Mix.env == :test, do: [], else: [worker(Pleroma.Web.Streamer, [])]
- ++ if !chat_enabled(), do: [], else: [worker(Pleroma.Web.ChatChannel.ChatChannelState, [])]
+ children =
+ [
+ # Start the Ecto repository
+ supervisor(Pleroma.Repo, []),
+ # Start the endpoint when the application starts
+ supervisor(Pleroma.Web.Endpoint, []),
+ # Start your own worker by calling: Pleroma.Worker.start_link(arg1, arg2, arg3)
+ # worker(Pleroma.Worker, [arg1, arg2, arg3]),
+ worker(Cachex, [
+ :user_cache,
+ [
+ default_ttl: 25000,
+ ttl_interval: 1000,
+ limit: 2500
+ ]
+ ]),
+ worker(Pleroma.Web.Federator, []),
+ worker(Pleroma.Stats, [])
+ ] ++
+ if Mix.env() == :test,
+ do: [],
+ else:
+ [worker(Pleroma.Web.Streamer, [])] ++
+ if(
+ !chat_enabled(),
+ do: [],
+ else: [worker(Pleroma.Web.ChatChannel.ChatChannelState, [])]
+ )
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex
index 66ca92f27..9396b1826 100644
--- a/lib/pleroma/formatter.ex
+++ b/lib/pleroma/formatter.ex
@@ -5,19 +5,26 @@ defmodule Pleroma.Formatter do
@tag_regex ~r/\#\w+/u
def parse_tags(text, data \\ %{}) do
Regex.scan(@tag_regex, text)
- |> Enum.map(fn (["#" <> tag = full_tag]) -> {full_tag, String.downcase(tag)} end)
- |> (fn map -> if data["sensitive"] in [true, "True", "true", "1"], do: [{"#nsfw", "nsfw"}] ++ map, else: map end).()
+ |> Enum.map(fn ["#" <> tag = full_tag] -> {full_tag, String.downcase(tag)} end)
+ |> (fn map ->
+ if data["sensitive"] in [true, "True", "true", "1"],
+ do: [{"#nsfw", "nsfw"}] ++ map,
+ else: map
+ end).()
end
def parse_mentions(text) do
# 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])?)*/u
+ 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])?)*/u
Regex.scan(regex, text)
- |> List.flatten
- |> Enum.uniq
- |> Enum.map(fn ("@" <> match = full_match) -> {full_match, User.get_cached_by_nickname(match)} end)
- |> Enum.filter(fn ({_match, user}) -> user end)
+ |> List.flatten()
+ |> Enum.uniq()
+ |> Enum.map(fn "@" <> match = full_match ->
+ {full_match, User.get_cached_by_nickname(match)}
+ end)
+ |> Enum.filter(fn {_match, user} -> user end)
end
@finmoji [
@@ -86,9 +93,9 @@ defmodule Pleroma.Formatter do
"woollysocks"
]
- @finmoji_with_filenames Enum.map(@finmoji, fn (finmoji) ->
- {finmoji, "/finmoji/128px/#{finmoji}-128.png"}
- end)
+ @finmoji_with_filenames Enum.map(@finmoji, fn finmoji ->
+ {finmoji, "/finmoji/128px/#{finmoji}-128.png"}
+ end)
@emoji_from_file (with {:ok, default} <- File.read("config/emoji.txt") do
custom =
@@ -97,31 +104,40 @@ defmodule Pleroma.Formatter do
else
_e -> ""
end
+
(default <> "\n" <> custom)
|> String.trim()
|> String.split(~r/\n+/)
- |> Enum.map(fn(line) ->
+ |> Enum.map(fn line ->
[name, file] = String.split(line, ~r/,\s*/)
{name, file}
- end)
+ end)
else
_ -> []
- end)
+ end)
@emoji @finmoji_with_filenames ++ @emoji_from_file
def emojify(text, emoji \\ @emoji)
def emojify(text, nil), do: text
+
def emojify(text, emoji) do
- Enum.reduce(emoji, text, fn ({emoji, file}, text) ->
+ Enum.reduce(emoji, text, fn {emoji, file}, text ->
emoji = HtmlSanitizeEx.strip_tags(emoji)
file = HtmlSanitizeEx.strip_tags(file)
- String.replace(text, ":#{emoji}:", "<img height='32px' width='32px' alt='#{emoji}' title='#{emoji}' src='#{MediaProxy.url(file)}' />")
+
+ String.replace(
+ text,
+ ":#{emoji}:",
+ "<img height='32px' width='32px' alt='#{emoji}' title='#{emoji}' src='#{
+ MediaProxy.url(file)
+ }' />"
+ )
end)
end
def get_emoji(text) do
- Enum.filter(@emoji, fn ({emoji, _}) -> String.contains?(text, ":#{emoji}:") end)
+ Enum.filter(@emoji, fn {emoji, _} -> String.contains?(text, ":#{emoji}:") end)
end
def get_custom_emoji() do
@@ -141,59 +157,71 @@ defmodule Pleroma.Formatter do
@doc "changes http:... links to html links"
def add_links({subs, text}) do
- links = Regex.scan(@link_regex, text)
- |> Enum.map(fn ([url]) -> {Ecto.UUID.generate, url} end)
+ links =
+ Regex.scan(@link_regex, text)
+ |> Enum.map(fn [url] -> {Ecto.UUID.generate(), url} end)
- uuid_text = links
- |> Enum.reduce(text, fn({uuid, url}, acc) -> String.replace(acc, url, uuid) end)
+ uuid_text =
+ links
+ |> Enum.reduce(text, fn {uuid, url}, acc -> String.replace(acc, url, uuid) end)
- subs = subs ++ Enum.map(links, fn({uuid, url}) ->
- {uuid, "<a href='#{url}'>#{url}</a>"}
- end)
+ subs =
+ subs ++
+ Enum.map(links, fn {uuid, url} ->
+ {uuid, "<a href='#{url}'>#{url}</a>"}
+ end)
{subs, uuid_text}
end
@doc "Adds the links to mentioned users"
def add_user_links({subs, text}, mentions) do
- mentions = mentions
- |> Enum.sort_by(fn ({name, _}) -> -String.length(name) end)
- |> Enum.map(fn({name, user}) -> {name, user, Ecto.UUID.generate} end)
-
- uuid_text = mentions
- |> Enum.reduce(text, fn ({match, _user, uuid}, text) ->
- String.replace(text, match, uuid)
- end)
-
- subs = subs ++ Enum.map(mentions, fn ({match, %User{ap_id: ap_id}, uuid}) ->
- short_match = String.split(match, "@") |> tl() |> hd()
- {uuid, "<span><a href='#{ap_id}'>@<span>#{short_match}</span></a></span>"}
- end)
+ mentions =
+ mentions
+ |> Enum.sort_by(fn {name, _} -> -String.length(name) end)
+ |> Enum.map(fn {name, user} -> {name, user, Ecto.UUID.generate()} end)
+
+ uuid_text =
+ mentions
+ |> Enum.reduce(text, fn {match, _user, uuid}, text ->
+ String.replace(text, match, uuid)
+ end)
+
+ subs =
+ subs ++
+ Enum.map(mentions, fn {match, %User{ap_id: ap_id}, uuid} ->
+ short_match = String.split(match, "@") |> tl() |> hd()
+ {uuid, "<span><a href='#{ap_id}'>@<span>#{short_match}</span></a></span>"}
+ end)
{subs, uuid_text}
end
@doc "Adds the hashtag links"
def add_hashtag_links({subs, text}, tags) do
- tags = tags
- |> Enum.sort_by(fn ({name, _}) -> -String.length(name) end)
- |> Enum.map(fn({name, short}) -> {name, short, Ecto.UUID.generate} end)
-
- uuid_text = tags
- |> Enum.reduce(text, fn ({match, _short, uuid}, text) ->
- String.replace(text, match, uuid)
- end)
-
- subs = subs ++ Enum.map(tags, fn ({_, tag, uuid}) ->
- url = "<a href='#{Pleroma.Web.base_url}/tag/#{tag}' rel='tag'>##{tag}</a>"
- {uuid, url}
- end)
+ tags =
+ tags
+ |> Enum.sort_by(fn {name, _} -> -String.length(name) end)
+ |> Enum.map(fn {name, short} -> {name, short, Ecto.UUID.generate()} end)
+
+ uuid_text =
+ tags
+ |> Enum.reduce(text, fn {match, _short, uuid}, text ->
+ String.replace(text, match, uuid)
+ end)
+
+ subs =
+ subs ++
+ Enum.map(tags, fn {_, tag, uuid} ->
+ url = "<a href='#{Pleroma.Web.base_url()}/tag/#{tag}' rel='tag'>##{tag}</a>"
+ {uuid, url}
+ end)
{subs, uuid_text}
end
def finalize({subs, text}) do
- Enum.reduce(subs, text, fn({uuid, replacement}, result_text) ->
+ Enum.reduce(subs, text, fn {uuid, replacement}, result_text ->
String.replace(result_text, uuid, replacement)
end)
end
diff --git a/lib/pleroma/http/http.ex b/lib/pleroma/http/http.ex
index 8b8a82353..84f34eb4a 100644
--- a/lib/pleroma/http/http.ex
+++ b/lib/pleroma/http/http.ex
@@ -1,14 +1,13 @@
-
defmodule Pleroma.HTTP do
use HTTPoison.Base
def process_request_options(options) do
config = Application.get_env(:pleroma, :http, [])
proxy = Keyword.get(config, :proxy_url, nil)
+
case proxy do
nil -> options
_ -> options ++ [proxy: proxy]
end
end
-
end
diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex
index 241d6a9e0..e26e49c8c 100644
--- a/lib/pleroma/notification.ex
+++ b/lib/pleroma/notification.ex
@@ -4,75 +4,89 @@ defmodule Pleroma.Notification do
import Ecto.Query
schema "notifications" do
- field :seen, :boolean, default: false
- belongs_to :user, Pleroma.User
- belongs_to :activity, Pleroma.Activity
+ field(:seen, :boolean, default: false)
+ belongs_to(:user, Pleroma.User)
+ belongs_to(:activity, Pleroma.Activity)
timestamps()
end
# TODO: Make generic and unify (see activity_pub.ex)
defp restrict_max(query, %{"max_id" => max_id}) do
- from activity in query, where: activity.id < ^max_id
+ from(activity in query, where: activity.id < ^max_id)
end
+
defp restrict_max(query, _), do: query
defp restrict_since(query, %{"since_id" => since_id}) do
- from activity in query, where: activity.id > ^since_id
+ from(activity in query, where: activity.id > ^since_id)
end
+
defp restrict_since(query, _), do: query
def for_user(user, opts \\ %{}) do
- query = from n in Notification,
- where: n.user_id == ^user.id,
- order_by: [desc: n.id],
- preload: [:activity],
- limit: 20
-
- query = query
- |> restrict_since(opts)
- |> restrict_max(opts)
+ query =
+ from(
+ n in Notification,
+ where: n.user_id == ^user.id,
+ order_by: [desc: n.id],
+ preload: [:activity],
+ limit: 20
+ )
+
+ query =
+ query
+ |> restrict_since(opts)
+ |> restrict_max(opts)
Repo.all(query)
end
def get(%{id: user_id} = _user, id) do
- query = from n in Notification,
- where: n.id == ^id,
- preload: [:activity]
+ query =
+ from(
+ n in Notification,
+ where: n.id == ^id,
+ preload: [:activity]
+ )
notification = Repo.one(query)
+
case notification do
%{user_id: ^user_id} ->
{:ok, notification}
+
_ ->
{:error, "Cannot get notification"}
end
end
def clear(user) do
- query = from n in Notification,
- where: n.user_id == ^user.id
+ query = from(n in Notification, where: n.user_id == ^user.id)
Repo.delete_all(query)
end
def dismiss(%{id: user_id} = _user, id) do
notification = Repo.get(Notification, id)
+
case notification do
%{user_id: ^user_id} ->
Repo.delete(notification)
+
_ ->
{:error, "Cannot dismiss notification"}
end
end
- def create_notifications(%Activity{id: _, data: %{"to" => _, "type" => type}} = activity) when type in ["Create", "Like", "Announce", "Follow"] do
+ def create_notifications(%Activity{id: _, data: %{"to" => _, "type" => type}} = activity)
+ when type in ["Create", "Like", "Announce", "Follow"] do
users = User.get_notified_from_activity(activity)
- notifications = Enum.map(users, fn (user) -> create_notification(activity, user) end)
+ notifications = Enum.map(users, fn user -> create_notification(activity, user) end)
{:ok, notifications}
end
+
def create_notifications(_), do: {:ok, []}
# TODO move to sql, too.
@@ -85,4 +99,3 @@ defmodule Pleroma.Notification do
end
end
end
-
diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex
index 30ba7b57a..558e151b0 100644
--- a/lib/pleroma/object.ex
+++ b/lib/pleroma/object.ex
@@ -4,14 +4,14 @@ defmodule Pleroma.Object do
import Ecto.{Query, Changeset}
schema "objects" do
- field :data, :map
+ field(:data, :map)
timestamps()
end
def create(data) do
Object.change(%Object{}, %{data: data})
- |> Repo.insert
+ |> Repo.insert()
end
def change(struct, params \\ %{}) do
@@ -22,24 +22,30 @@ defmodule Pleroma.Object do
end
def get_by_ap_id(nil), do: nil
+
def get_by_ap_id(ap_id) do
- Repo.one(from object in Object,
- where: fragment("(?)->>'id' = ?", object.data, ^ap_id))
+ Repo.one(from(object in Object, where: fragment("(?)->>'id' = ?", object.data, ^ap_id)))
end
def get_cached_by_ap_id(ap_id) do
- if Mix.env == :test do
+ if Mix.env() == :test do
get_by_ap_id(ap_id)
else
key = "object:#{ap_id}"
- Cachex.get!(:user_cache, key, fallback: fn(_) ->
- object = get_by_ap_id(ap_id)
- if object do
- {:commit, object}
- else
- {:ignore, object}
+
+ Cachex.get!(
+ :user_cache,
+ key,
+ fallback: fn _ ->
+ object = get_by_ap_id(ap_id)
+
+ if object do
+ {:commit, object}
+ else
+ {:ignore, object}
+ end
end
- end)
+ )
end
end
diff --git a/lib/pleroma/plugs/authentication_plug.ex b/lib/pleroma/plugs/authentication_plug.ex
index 4794e625a..86a514541 100644
--- a/lib/pleroma/plugs/authentication_plug.ex
+++ b/lib/pleroma/plugs/authentication_plug.ex
@@ -14,8 +14,7 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
{:ok, user} <- opts[:fetcher].(username),
false <- !!user.info["deactivated"],
saved_user_id <- get_session(conn, :user_id),
- {:ok, verified_user} <- verify(user, password, saved_user_id)
- do
+ {:ok, verified_user} <- verify(user, password, saved_user_id) do
conn
|> assign(:user, verified_user)
|> put_session(:user_id, verified_user.id)
@@ -30,7 +29,7 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
end
defp verify(nil, _password, _user_id) do
- Pbkdf2.dummy_checkpw
+ Pbkdf2.dummy_checkpw()
:error
end
@@ -45,8 +44,7 @@ defmodule Pleroma.Plugs.AuthenticationPlug do
defp decode_header(conn) do
with ["Basic " <> header] <- get_req_header(conn, "authorization"),
{:ok, userinfo} <- Base.decode64(header),
- [username, password] <- String.split(userinfo, ":", parts: 2)
- do
+ [username, password] <- String.split(userinfo, ":", parts: 2) do
{:ok, username, password}
end
end
diff --git a/lib/pleroma/plugs/oauth_plug.ex b/lib/pleroma/plugs/oauth_plug.ex
index be737dc9a..0380ce14d 100644
--- a/lib/pleroma/plugs/oauth_plug.ex
+++ b/lib/pleroma/plugs/oauth_plug.ex
@@ -9,11 +9,14 @@ defmodule Pleroma.Plugs.OAuthPlug do
end
def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
+
def call(conn, _) do
- token = case get_req_header(conn, "authorization") do
- ["Bearer " <> header] -> header
- _ -> get_session(conn, :oauth_token)
- end
+ token =
+ case get_req_header(conn, "authorization") do
+ ["Bearer " <> header] -> header
+ _ -> get_session(conn, :oauth_token)
+ end
+
with token when not is_nil(token) <- token,
%Token{user_id: user_id} <- Repo.get_by(Token, token: token),
%User{} = user <- Repo.get(User, user_id),
diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex
index 5f8130ff8..83b896a16 100644
--- a/lib/pleroma/stats.ex
+++ b/lib/pleroma/stats.ex
@@ -18,22 +18,31 @@ defmodule Pleroma.Stats do
def schedule_update do
spawn(fn ->
- Process.sleep(1000 * 60 * 60 * 1) # 1 hour
+ # 1 hour
+ Process.sleep(1000 * 60 * 60 * 1)
schedule_update()
end)
+
update_stats()
end
def update_stats do
- peers = from(u in Pleroma.User,
- select: fragment("distinct ?->'host'", u.info),
- where: u.local != ^true)
- |> Repo.all()
+ peers =
+ from(
+ u in Pleroma.User,
+ select: fragment("distinct ?->'host'", u.info),
+ where: u.local != ^true
+ )
+ |> Repo.all()
+
domain_count = Enum.count(peers)
- status_query = from(u in User.local_user_query,
- select: fragment("sum((?->>'note_count')::int)", u.info))
+
+ status_query =
+ from(u in User.local_user_query(), select: fragment("sum((?->>'note_count')::int)", u.info))
+
status_count = Repo.one(status_query)
- user_count = Repo.aggregate(User.local_user_query, :count, :id)
+ user_count = Repo.aggregate(User.local_user_query(), :count, :id)
+
Agent.update(__MODULE__, fn _ ->
{peers, %{domain_count: domain_count, status_count: status_count, user_count: user_count}}
end)
diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex
index c41617c68..8a9dc612a 100644
--- a/lib/pleroma/upload.ex
+++ b/lib/pleroma/upload.ex
@@ -1,27 +1,31 @@
defmodule Pleroma.Upload do
alias Ecto.UUID
alias Pleroma.Web
+
def store(%Plug.Upload{} = file) do
- uuid = UUID.generate
+ uuid = UUID.generate()
upload_folder = Path.join(upload_path(), uuid)
File.mkdir_p!(upload_folder)
result_file = Path.join(upload_folder, file.filename)
File.cp!(file.path, result_file)
# fix content type on some image uploads
- content_type = if file.content_type in [nil, "application/octet-stream"] do
- get_content_type(file.path)
- else
- file.content_type
- end
+ content_type =
+ if file.content_type in [nil, "application/octet-stream"] do
+ get_content_type(file.path)
+ else
+ file.content_type
+ end
%{
"type" => "Image",
- "url" => [%{
- "type" => "Link",
- "mediaType" => content_type,
- "href" => url_for(Path.join(uuid, :cow_uri.urlencode(file.filename)))
- }],
+ "url" => [
+ %{
+ "type" => "Link",
+ "mediaType" => content_type,
+ "href" => url_for(Path.join(uuid, :cow_uri.urlencode(file.filename)))
+ }
+ ],
"name" => file.filename,
"uuid" => uuid
}
@@ -30,7 +34,7 @@ defmodule Pleroma.Upload do
def store(%{"img" => "data:image/" <> image_data}) do
parsed = Regex.named_captures(~r/(?<filetype>jpeg|png|gif);base64,(?<data>.*)/, image_data)
data = Base.decode64!(parsed["data"])
- uuid = UUID.generate
+ uuid = UUID.generate()
upload_folder = Path.join(upload_path(), uuid)
File.mkdir_p!(upload_folder)
filename = Base.encode16(:crypto.hash(:sha256, data)) <> ".#{parsed["filetype"]}"
@@ -42,11 +46,13 @@ defmodule Pleroma.Upload do
%{
"type" => "Image",
- "url" => [%{
- "type" => "Link",
- "mediaType" => content_type,
- "href" => url_for(Path.join(uuid, :cow_uri.urlencode(filename)))
- }],
+ "url" => [
+ %{
+ "type" => "Link",
+ "mediaType" => content_type,
+ "href" => url_for(Path.join(uuid, :cow_uri.urlencode(filename)))
+ }
+ ],
"name" => filename,
"uuid" => uuid
}
@@ -62,28 +68,37 @@ defmodule Pleroma.Upload do
end
def get_content_type(file) do
- match = File.open(file, [:read], fn(f) ->
- case IO.binread(f, 8) do
- <<0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a>> ->
- "image/png"
- <<0x47, 0x49, 0x46, 0x38, _, 0x61, _, _>> ->
- "image/gif"
- <<0xff, 0xd8, 0xff, _, _, _, _, _>> ->
- "image/jpeg"
- <<0x1a, 0x45, 0xdf, 0xa3, _, _, _, _>> ->
- "video/webm"
- <<0x00, 0x00, 0x00, _, 0x66, 0x74, 0x79, 0x70>> ->
- "video/mp4"
- <<0x49, 0x44, 0x33, _, _, _, _, _>> ->
- "audio/mpeg"
- <<0x4f, 0x67, 0x67, 0x53, 0x00, 0x02, 0x00, 0x00>> ->
- "audio/ogg"
- <<0x52, 0x49, 0x46, 0x46, _, _, _, _>> ->
- "audio/wav"
- _ ->
- "application/octet-stream"
- end
- end)
+ match =
+ File.open(file, [:read], fn f ->
+ case IO.binread(f, 8) do
+ <<0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A>> ->
+ "image/png"
+
+ <<0x47, 0x49, 0x46, 0x38, _, 0x61, _, _>> ->
+ "image/gif"
+
+ <<0xFF, 0xD8, 0xFF, _, _, _, _, _>> ->
+ "image/jpeg"
+
+ <<0x1A, 0x45, 0xDF, 0xA3, _, _, _, _>> ->
+ "video/webm"
+
+ <<0x00, 0x00, 0x00, _, 0x66, 0x74, 0x79, 0x70>> ->
+ "video/mp4"
+
+ <<0x49, 0x44, 0x33, _, _, _, _, _>> ->
+ "audio/mpeg"
+
+ <<0x4F, 0x67, 0x67, 0x53, 0x00, 0x02, 0x00, 0x00>> ->
+ "audio/ogg"
+
+ <<0x52, 0x49, 0x46, 0x46, _, _, _, _>> ->
+ "audio/wav"
+
+ _ ->
+ "application/octet-stream"
+ end
+ end)
case match do
{:ok, type} -> type
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 0594afb38..55b290309 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -8,20 +8,20 @@ defmodule Pleroma.User do
alias Pleroma.Web.ActivityPub.{Utils, ActivityPub}
schema "users" do
- field :bio, :string
- field :email, :string
- field :name, :string
- field :nickname, :string
- field :password_hash, :string
- field :password, :string, virtual: true
- field :password_confirmation, :string, virtual: true
- field :following, {:array, :string}, default: []
- field :ap_id, :string
- field :avatar, :map
- field :local, :boolean, default: true
- field :info, :map, default: %{}
- field :follower_address, :string
- has_many :notifications, Notification
+ field(:bio, :string)
+ field(:email, :string)
+ field(:name, :string)
+ field(:nickname, :string)
+ field(:password_hash, :string)
+ field(:password, :string, virtual: true)
+ field(:password_confirmation, :string, virtual: true)
+ field(:following, {:array, :string}, default: [])
+ field(:ap_id, :string)
+ field(:avatar, :map)
+ field(:local, :boolean, default: true)
+ field(:info, :map, default: %{})
+ field(:follower_address, :string)
+ has_many(:notifications, Notification)
timestamps()
end
@@ -41,7 +41,7 @@ defmodule Pleroma.User do
end
def ap_id(%User{nickname: nickname}) do
- "#{Web.base_url}/users/#{nickname}"
+ "#{Web.base_url()}/users/#{nickname}"
end
def ap_followers(%User{} = user) do
@@ -62,6 +62,7 @@ defmodule Pleroma.User do
def user_info(%User{} = user) do
oneself = if user.local, do: 1, else: 0
+
%{
following_count: length(user.following) - oneself,
note_count: user.info["note_count"] || 0,
@@ -71,21 +72,25 @@ defmodule Pleroma.User do
@email_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])?)*$/
def remote_user_creation(params) do
- changes = %User{}
- |> cast(params, [:bio, :name, :ap_id, :nickname, :info, :avatar])
- |> validate_required([:name, :ap_id, :nickname])
- |> unique_constraint(:nickname)
- |> validate_format(:nickname, @email_regex)
- |> validate_length(:bio, max: 5000)
- |> validate_length(:name, max: 100)
- |> put_change(:local, false)
+ changes =
+ %User{}
+ |> cast(params, [:bio, :name, :ap_id, :nickname, :info, :avatar])
+ |> validate_required([:name, :ap_id, :nickname])
+ |> unique_constraint(:nickname)
+ |> validate_format(:nickname, @email_regex)
+ |> validate_length(:bio, max: 5000)
+ |> validate_length(:name, max: 100)
+ |> put_change(:local, false)
+
if changes.valid? do
case changes.changes[:info]["source_data"] do
%{"followers" => followers} ->
changes
|> put_change(:follower_address, followers)
+
_ ->
followers = User.ap_followers(%User{nickname: changes.changes[:nickname]})
+
changes
|> put_change(:follower_address, followers)
end
@@ -113,13 +118,15 @@ defmodule Pleroma.User do
end
def password_update_changeset(struct, params) do
- changeset = struct
- |> cast(params, [:password, :password_confirmation])
- |> validate_required([:password, :password_confirmation])
- |> validate_confirmation(:password)
+ changeset =
+ struct
+ |> cast(params, [:password, :password_confirmation])
+ |> validate_required([:password, :password_confirmation])
+ |> validate_confirmation(:password)
if changeset.valid? do
hashed = Pbkdf2.hashpwsalt(changeset.changes[:password])
+
changeset
|> put_change(:password_hash, hashed)
else
@@ -132,21 +139,23 @@ defmodule Pleroma.User do
end
def register_changeset(struct, params \\ %{}) do
- changeset = struct
- |> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation])
- |> validate_required([:email, :name, :nickname, :password, :password_confirmation])
- |> validate_confirmation(:password)
- |> unique_constraint(:email)
- |> unique_constraint(:nickname)
- |> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/)
- |> validate_format(:email, @email_regex)
- |> validate_length(:bio, max: 1000)
- |> validate_length(:name, min: 1, max: 100)
+ changeset =
+ struct
+ |> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation])
+ |> validate_required([:email, :name, :nickname, :password, :password_confirmation])
+ |> validate_confirmation(:password)
+ |> unique_constraint(:email)
+ |> unique_constraint(:nickname)
+ |> validate_format(:nickname, ~r/^[a-zA-Z\d]+$/)
+ |> validate_format(:email, @email_regex)
+ |> validate_length(:bio, max: 1000)
+ |> validate_length(:name, min: 1, max: 100)
if changeset.valid? do
hashed = Pbkdf2.hashpwsalt(changeset.changes[:password])
ap_id = User.ap_id(%User{nickname: changeset.changes[:nickname]})
followers = User.ap_followers(%User{nickname: changeset.changes[:nickname]})
+
changeset
|> put_change(:password_hash, hashed)
|> put_change(:ap_id, ap_id)
@@ -161,19 +170,20 @@ defmodule Pleroma.User do
ap_followers = followed.follower_address
if following?(follower, followed) or info["deactivated"] do
- {:error,
- "Could not follow user: #{followed.nickname} is already on your list."}
+ {:error, "Could not follow user: #{followed.nickname} is already on your list."}
else
if !followed.local && follower.local && !ap_enabled?(followed) do
Websub.subscribe(follower, followed)
end
- following = [ap_followers | follower.following]
- |> Enum.uniq
+ following =
+ [ap_followers | follower.following]
+ |> Enum.uniq()
- follower = follower
- |> follow_changeset(%{following: following})
- |> update_and_set_cache
+ follower =
+ follower
+ |> follow_changeset(%{following: following})
+ |> update_and_set_cache
{:ok, _} = update_follower_count(followed)
@@ -183,13 +193,16 @@ defmodule Pleroma.User do
def unfollow(%User{} = follower, %User{} = followed) do
ap_followers = followed.follower_address
+
if following?(follower, followed) and follower.ap_id != followed.ap_id do
- following = follower.following
- |> List.delete(ap_followers)
+ following =
+ follower.following
+ |> List.delete(ap_followers)
- { :ok, follower } = follower
- |> follow_changeset(%{following: following})
- |> update_and_set_cache
+ {:ok, follower} =
+ follower
+ |> follow_changeset(%{following: following})
+ |> update_and_set_cache
{:ok, followed} = update_follower_count(followed)
@@ -225,12 +238,12 @@ defmodule Pleroma.User do
def get_cached_by_ap_id(ap_id) do
key = "ap_id:#{ap_id}"
- Cachex.get!(:user_cache, key, fallback: fn(_) -> get_by_ap_id(ap_id) end)
+ Cachex.get!(:user_cache, key, fallback: fn _ -> get_by_ap_id(ap_id) end)
end
def get_cached_by_nickname(nickname) do
key = "nickname:#{nickname}"
- Cachex.get!(:user_cache, key, fallback: fn(_) -> get_or_fetch_by_nickname(nickname) end)
+ Cachex.get!(:user_cache, key, fallback: fn _ -> get_or_fetch_by_nickname(nickname) end)
end
def get_by_nickname(nickname) do
@@ -239,7 +252,7 @@ defmodule Pleroma.User do
def get_cached_user_info(user) do
key = "user_info:#{user.id}"
- Cachex.get!(:user_cache, key, fallback: fn(_) -> user_info(user) end)
+ Cachex.get!(:user_cache, key, fallback: fn _ -> user_info(user) end)
end
def fetch_by_nickname(nickname) do
@@ -252,29 +265,37 @@ defmodule Pleroma.User do
end
def get_or_fetch_by_nickname(nickname) do
- with %User{} = user <- get_by_nickname(nickname) do
+ with %User{} = user <- get_by_nickname(nickname) do
user
- else _e ->
- with [_nick, _domain] <- String.split(nickname, "@"),
- {:ok, user} <- fetch_by_nickname(nickname) do
- user
- else _e -> nil
- end
+ else
+ _e ->
+ with [_nick, _domain] <- String.split(nickname, "@"),
+ {:ok, user} <- fetch_by_nickname(nickname) do
+ user
+ else
+ _e -> nil
+ end
end
end
def get_followers(%User{id: id, follower_address: follower_address}) do
- q = from u in User,
- where: fragment("? <@ ?", ^[follower_address], u.following),
- where: u.id != ^id
+ q =
+ from(
+ u in User,
+ where: fragment("? <@ ?", ^[follower_address], u.following),
+ where: u.id != ^id
+ )
{:ok, Repo.all(q)}
end
def get_friends(%User{id: id, following: following}) do
- q = from u in User,
- where: u.follower_address in ^following,
- where: u.id != ^id
+ q =
+ from(
+ u in User,
+ where: u.follower_address in ^following,
+ where: u.id != ^id
+ )
{:ok, Repo.all(q)}
end
@@ -289,9 +310,12 @@ defmodule Pleroma.User do
end
def update_note_count(%User{} = user) do
- note_count_query = from a in Object,
- where: fragment("?->>'actor' = ? and ?->>'type' = 'Note'", a.data, ^user.ap_id, a.data),
- select: count(a.id)
+ note_count_query =
+ from(
+ a in Object,
+ where: fragment("?->>'actor' = ? and ?->>'type' = 'Note'", a.data, ^user.ap_id, a.data),
+ select: count(a.id)
+ )
note_count = Repo.one(note_count_query)
@@ -303,10 +327,13 @@ defmodule Pleroma.User do
end
def update_follower_count(%User{} = user) do
- follower_count_query = from u in User,
- where: ^user.follower_address in u.following,
- where: u.id != ^user.id,
- select: count(u.id)
+ follower_count_query =
+ from(
+ u in User,
+ where: ^user.follower_address in u.following,
+ where: u.id != ^user.id,
+ select: count(u.id)
+ )
follower_count = Repo.one(follower_count_query)
@@ -318,20 +345,25 @@ defmodule Pleroma.User do
end
def get_notified_from_activity(%Activity{recipients: to}) do
- query = from u in User,
- where: u.ap_id in ^to,
- where: u.local == true
+ query =
+ from(
+ u in User,
+ where: u.ap_id in ^to,
+ where: u.local == true
+ )
Repo.all(query)
end
def get_recipients_from_activity(%Activity{recipients: to}) do
- query = from u in User,
- where: u.ap_id in ^to,
- or_where: fragment("? && ?", u.following, ^to)
+ query =
+ from(
+ u in User,
+ where: u.ap_id in ^to,
+ or_where: fragment("? && ?", u.following, ^to)
+ )
- query = from u in query,
- where: u.local == true
+ query = from(u in query, where: u.local == true)
Repo.all(query)
end
@@ -340,9 +372,20 @@ defmodule Pleroma.User do
if resolve do
User.get_or_fetch_by_nickname(query)
end
- q = from u in User,
- where: fragment("(to_tsvector('english', ?) || to_tsvector('english', ?)) @@ plainto_tsquery('english', ?)", u.nickname, u.name, ^query),
- limit: 20
+
+ q =
+ from(
+ u in User,
+ where:
+ fragment(
+ "(to_tsvector('english', ?) || to_tsvector('english', ?)) @@ plainto_tsquery('english', ?)",
+ u.nickname,
+ u.name,
+ ^query
+ ),
+ limit: 20
+ )
+
Repo.all(q)
end
@@ -370,36 +413,40 @@ defmodule Pleroma.User do
end
def local_user_query() do
- from u in User,
- where: u.local == true
+ from(u in User, where: u.local == true)
end
- def deactivate (%User{} = user) do
+ def deactivate(%User{} = user) do
new_info = Map.put(user.info, "deactivated", true)
cs = User.info_changeset(user, %{info: new_info})
update_and_set_cache(cs)
end
- def delete (%User{} = user) do
+ def delete(%User{} = user) do
{:ok, user} = User.deactivate(user)
# Remove all relationships
- {:ok, followers } = User.get_followers(user)
+ {:ok, followers} = User.get_followers(user)
+
followers
- |> Enum.each(fn (follower) -> User.unfollow(follower, user) end)
+ |> Enum.each(fn follower -> User.unfollow(follower, user) end)
{:ok, friends} = User.get_friends(user)
+
friends
- |> Enum.each(fn (followed) -> User.unfollow(user, followed) end)
+ |> Enum.each(fn followed -> User.unfollow(user, followed) end)
- query = from a in Activity,
- where: a.actor == ^user.ap_id
+ query = from(a in Activity, where: a.actor == ^user.ap_id)
Repo.all(query)
- |> Enum.each(fn (activity) ->
+ |> Enum.each(fn activity ->
case activity.data["type"] do
- "Create" -> ActivityPub.delete(Object.get_by_ap_id(activity.data["object"]["id"]))
- _ -> "Doing nothing" # TODO: Do something with likes, follows, repeats.
+ "Create" ->
+ ActivityPub.delete(Object.get_by_ap_id(activity.data["object"]["id"]))
+
+ # TODO: Do something with likes, follows, repeats.
+ _ ->
+ "Doing nothing"
end
end)
@@ -413,7 +460,9 @@ defmodule Pleroma.User do
ap_try = ActivityPub.make_user_from_ap_id(ap_id)
case ap_try do
- {:ok, user} -> user
+ {:ok, user} ->
+ user
+
_ ->
case OStatus.make_user(ap_id) do
{:ok, user} -> user
@@ -424,12 +473,15 @@ defmodule Pleroma.User do
end
# AP style
- def public_key_from_info(%{"source_data" => %{"publicKey" => %{"publicKeyPem" => public_key_pem}}}) do
- key = :public_key.pem_decode(public_key_pem)
- |> hd()
- |> :public_key.pem_entry_decode()
+ def public_key_from_info(%{
+ "source_data" => %{"publicKey" => %{"publicKeyPem" => public_key_pem}}
+ }) do
+ key =
+ :public_key.pem_decode(public_key_pem)
+ |> hd()
+ |> :public_key.pem_entry_decode()
- {:ok, key}
+ {:ok, key}
end
# OStatus Magic Key
@@ -450,8 +502,10 @@ defmodule Pleroma.User do
defp blank?(n), do: n
def insert_or_update_user(data) do
- data = data
- |> Map.put(:name, blank?(data[:name]) || data[:nickname])
+ data =
+ data
+ |> Map.put(:name, blank?(data[:name]) || data[:nickname])
+
cs = User.remote_user_creation(data)
Repo.insert(cs, on_conflict: :replace_all, conflict_target: :nickname)
end
diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
index 3a914088f..04b50c1cc 100644
--- a/lib/pleroma/web/activity_pub/activity_pub.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub.ex
@@ -18,7 +18,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
with nil <- Activity.get_by_ap_id(map["id"]),
map <- lazy_put_activity_defaults(map),
:ok <- insert_full_object(map) do
- {:ok, activity} = Repo.insert(%Activity{data: map, local: local, actor: map["actor"], recipients: get_recipients(map)})
+ {:ok, activity} =
+ Repo.insert(%Activity{
+ data: map,
+ local: local,
+ actor: map["actor"],
+ recipients: get_recipients(map)
+ })
+
Notification.create_notifications(activity)
stream_out(activity)
{:ok, activity}
@@ -31,8 +38,10 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def stream_out(activity) do
if activity.data["type"] in ["Create", "Announce"] do
Pleroma.Web.Streamer.stream("user", activity)
+
if Enum.member?(activity.data["to"], "https://www.w3.org/ns/activitystreams#Public") do
Pleroma.Web.Streamer.stream("public", activity)
+
if activity.local do
Pleroma.Web.Streamer.stream("public:local", activity)
end
@@ -42,10 +51,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def create(%{to: to, actor: actor, context: context, object: object} = params) do
additional = params[:additional] || %{}
- local = !(params[:local] == false) # only accept false as false value
+ # only accept false as false value
+ local = !(params[:local] == false)
published = params[:published]
- with create_data <- make_create_data(%{to: to, actor: actor, published: published, context: context, object: object}, additional),
+ with create_data <-
+ make_create_data(
+ %{to: to, actor: actor, published: published, context: context, object: object},
+ additional
+ ),
{:ok, activity} <- insert(create_data, local),
:ok <- maybe_federate(activity) do
{:ok, activity}
@@ -53,7 +67,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
def accept(%{to: to, actor: actor, object: object} = params) do
- local = !(params[:local] == false) # only accept false as false value
+ # only accept false as false value
+ local = !(params[:local] == false)
with data <- %{"to" => to, "type" => "Accept", "actor" => actor, "object" => object},
{:ok, activity} <- insert(data, local),
@@ -63,9 +78,16 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
def update(%{to: to, cc: cc, actor: actor, object: object} = params) do
- local = !(params[:local] == false) # only accept false as false value
-
- with data <- %{"to" => to, "cc" => cc, "type" => "Update", "actor" => actor, "object" => object},
+ # only accept false as false value
+ local = !(params[:local] == false)
+
+ with data <- %{
+ "to" => to,
+ "cc" => cc,
+ "type" => "Update",
+ "actor" => actor,
+ "object" => object
+ },
{:ok, activity} <- insert(data, local),
:ok <- maybe_federate(activity) do
{:ok, activity}
@@ -73,7 +95,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
# 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),
like_data <- make_like_data(user, object, activity_id),
{:ok, activity} <- insert(like_data, local),
@@ -91,11 +118,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
{:ok, _activity} <- Repo.delete(activity),
{:ok, object} <- remove_like_from_object(activity, object) do
{:ok, object}
- else _e -> {:ok, object}
+ else
+ _e -> {:ok, object}
end
end
- def announce(%User{ap_id: _} = user, %Object{data: %{"id" => _}} = object, activity_id \\ nil, local \\ true) do
+ def announce(
+ %User{ap_id: _} = user,
+ %Object{data: %{"id" => _}} = object,
+ activity_id \\ nil,
+ local \\ true
+ ) do
with true <- is_public?(object),
announce_data <- make_announce_data(user, object, activity_id),
{:ok, activity} <- insert(announce_data, local),
@@ -119,19 +152,22 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
with %Activity{} = follow_activity <- fetch_latest_follow(follower, followed),
unfollow_data <- make_unfollow_data(follower, followed, follow_activity),
{:ok, activity} <- insert(unfollow_data, local),
- :ok, maybe_federate(activity) do
+ :ok,
+ maybe_federate(activity) do
{:ok, activity}
end
end
def delete(%Object{data: %{"id" => id, "actor" => actor}} = object, local \\ true) do
user = User.get_cached_by_ap_id(actor)
+
data = %{
"type" => "Delete",
"actor" => actor,
"object" => id,
"to" => [user.follower_address, "https://www.w3.org/ns/activitystreams#Public"]
}
+
with Repo.delete(object),
Repo.delete_all(Activity.all_non_create_by_object_ap_id_q(id)),
{:ok, activity} <- insert(data, local),
@@ -142,112 +178,147 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def fetch_activities_for_context(context, opts \\ %{}) do
public = ["https://www.w3.org/ns/activitystreams#Public"]
- recipients = if opts["user"], do: [opts["user"].ap_id | opts["user"].following] ++ public, else: public
- query = from activity in Activity
- query = query
+ recipients =
+ if opts["user"], do: [opts["user"].ap_id | opts["user"].following] ++ public, else: public
+
+ query = from(activity in Activity)
+
+ query =
+ query
|> restrict_blocked(opts)
|> restrict_recipients(recipients, opts["user"])
- query = from activity in query,
- where: fragment("?->>'type' = ? and ?->>'context' = ?", activity.data, "Create", activity.data, ^context),
- order_by: [desc: :id]
+ query =
+ from(
+ activity in query,
+ where:
+ fragment(
+ "?->>'type' = ? and ?->>'context' = ?",
+ activity.data,
+ "Create",
+ activity.data,
+ ^context
+ ),
+ order_by: [desc: :id]
+ )
+
Repo.all(query)
end
# TODO: Make this work properly with unlisted.
def fetch_public_activities(opts \\ %{}) do
q = fetch_activities_query(["https://www.w3.org/ns/activitystreams#Public"], opts)
+
q
- |> Repo.all
- |> Enum.reverse
+ |> Repo.all()
+ |> Enum.reverse()
end
defp restrict_since(query, %{"since_id" => since_id}) do
- from activity in query, where: activity.id > ^since_id
+ from(activity in query, where: activity.id > ^since_id)
end
+
defp restrict_since(query, _), do: query
defp restrict_tag(query, %{"tag" => tag}) do
- from activity in query,
+ from(
+ activity in query,
where: fragment("? <@ (? #> '{\"object\",\"tag\"}')", ^tag, activity.data)
+ )
end
+
defp restrict_tag(query, _), do: query
defp restrict_recipients(query, [], user), do: query
+
defp restrict_recipients(query, recipients, nil) do
- from activity in query,
- where: fragment("? && ?", ^recipients, activity.recipients)
+ from(activity in query, where: fragment("? && ?", ^recipients, activity.recipients))
end
+
defp restrict_recipients(query, recipients, user) do
- from activity in query,
+ from(
+ activity in query,
where: fragment("? && ?", ^recipients, activity.recipients),
or_where: activity.actor == ^user.ap_id
+ )
end
defp restrict_limit(query, %{"limit" => limit}) do
- from activity in query,
- limit: ^limit
+ from(activity in query, limit: ^limit)
end
+
defp restrict_limit(query, _), do: query
defp restrict_local(query, %{"local_only" => true}) do
- from activity in query, where: activity.local == true
+ from(activity in query, where: activity.local == true)
end
+
defp restrict_local(query, _), do: query
defp restrict_max(query, %{"max_id" => max_id}) do
- from activity in query, where: activity.id < ^max_id
+ from(activity in query, where: activity.id < ^max_id)
end
+
defp restrict_max(query, _), do: query
defp restrict_actor(query, %{"actor_id" => actor_id}) do
- from activity in query,
- where: activity.actor == ^actor_id
+ from(activity in query, where: activity.actor == ^actor_id)
end
+
defp restrict_actor(query, _), do: query
defp restrict_type(query, %{"type" => type}) when is_binary(type) do
restrict_type(query, %{"type" => [type]})
end
+
defp restrict_type(query, %{"type" => type}) do
- from activity in query,
- where: fragment("?->>'type' = ANY(?)", activity.data, ^type)
+ from(activity in query, where: fragment("?->>'type' = ANY(?)", activity.data, ^type))
end
+
defp restrict_type(query, _), do: query
defp restrict_favorited_by(query, %{"favorited_by" => ap_id}) do
- from activity in query,
+ from(
+ activity in query,
where: fragment("? <@ (? #> '{\"object\",\"likes\"}')", ^ap_id, activity.data)
+ )
end
+
defp restrict_favorited_by(query, _), do: query
defp restrict_media(query, %{"only_media" => val}) when val == "true" or val == "1" do
- from activity in query,
+ from(
+ activity in query,
where: fragment("not (? #> '{\"object\",\"attachment\"}' = ?)", activity.data, ^[])
+ )
end
+
defp restrict_media(query, _), do: query
# Only search through last 100_000 activities by default
defp restrict_recent(query, %{"whole_db" => true}), do: query
+
defp restrict_recent(query, _) do
since = (Repo.aggregate(Activity, :max, :id) || 0) - 100_000
- from activity in query,
- where: activity.id > ^since
+ from(activity in query, where: activity.id > ^since)
end
defp restrict_blocked(query, %{"blocking_user" => %User{info: info}}) do
blocks = info["blocks"] || []
- from activity in query,
- where: fragment("not (? = ANY(?))", activity.actor, ^blocks)
+ from(activity in query, where: fragment("not (? = ANY(?))", activity.actor, ^blocks))
end
+
defp restrict_blocked(query, _), do: query
def fetch_activities_query(recipients, opts \\ %{}) do
- base_query = from activity in Activity,
- limit: 20,
- order_by: [fragment("? desc nulls last", activity.id)]
+ base_query =
+ from(
+ activity in Activity,
+ limit: 20,
+ order_by: [fragment("? desc nulls last", activity.id)]
+ )
base_query
|> restrict_recipients(recipients, opts["user"])
@@ -266,8 +337,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def fetch_activities(recipients, opts \\ %{}) do
fetch_activities_query(recipients, opts)
- |> Repo.all
- |> Enum.reverse
+ |> Repo.all()
+ |> Enum.reverse()
end
def upload(file) do
@@ -276,15 +347,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
def user_data_from_user_object(data) do
- avatar = data["icon"]["url"] && %{
- "type" => "Image",
- "url" => [%{"href" => data["icon"]["url"]}]
- }
-
- banner = data["image"]["url"] && %{
- "type" => "Image",
- "url" => [%{"href" => data["image"]["url"]}]
- }
+ avatar =
+ data["icon"]["url"] &&
+ %{
+ "type" => "Image",
+ "url" => [%{"href" => data["icon"]["url"]}]
+ }
+
+ banner =
+ data["image"]["url"] &&
+ %{
+ "type" => "Image",
+ "url" => [%{"href" => data["image"]["url"]}]
+ }
user_data = %{
ap_id: data["id"],
@@ -304,8 +379,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
def fetch_and_prepare_user_from_ap_id(ap_id) do
- with {:ok, %{status_code: 200, body: body}} <- @httpoison.get(ap_id, ["Accept": "application/activity+json"]),
- {:ok, data} <- Jason.decode(body) do
+ with {:ok, %{status_code: 200, body: body}} <-
+ @httpoison.get(ap_id, Accept: "application/activity+json"),
+ {:ok, data} <- Jason.decode(body) do
user_data_from_user_object(data)
else
e -> Logger.error("Could not decode user at fetch #{ap_id}, #{inspect(e)}")
@@ -333,32 +409,48 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
def publish(actor, activity) do
- followers = if actor.follower_address in activity.recipients do
- {:ok, followers} = User.get_followers(actor)
- followers |> Enum.filter(&(!&1.local))
- else
- []
- end
+ followers =
+ if actor.follower_address in activity.recipients do
+ {:ok, followers} = User.get_followers(actor)
+ followers |> Enum.filter(&(!&1.local))
+ else
+ []
+ end
- remote_inboxes = (Pleroma.Web.Salmon.remote_users(activity) ++ followers)
- |> Enum.filter(fn (user) -> User.ap_enabled?(user) end)
- |> Enum.map(fn (%{info: %{"source_data" => data}}) ->
- (data["endpoints"] && data["endpoints"]["sharedInbox"]) || data["inbox"]
- end)
- |> Enum.uniq
+ remote_inboxes =
+ (Pleroma.Web.Salmon.remote_users(activity) ++ followers)
+ |> Enum.filter(fn user -> User.ap_enabled?(user) end)
+ |> Enum.map(fn %{info: %{"source_data" => data}} ->
+ (data["endpoints"] && data["endpoints"]["sharedInbox"]) || data["inbox"]
+ end)
+ |> Enum.uniq()
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
json = Jason.encode!(data)
- Enum.each remote_inboxes, fn(inbox) ->
- Federator.enqueue(:publish_single_ap, %{inbox: inbox, json: json, actor: actor, id: activity.data["id"]})
- end
+
+ Enum.each(remote_inboxes, fn inbox ->
+ Federator.enqueue(:publish_single_ap, %{
+ inbox: inbox,
+ json: json,
+ actor: actor,
+ id: activity.data["id"]
+ })
+ end)
end
def publish_one(%{inbox: inbox, json: json, actor: actor, id: id}) do
Logger.info("Federating #{id} to #{inbox}")
host = URI.parse(inbox).host
- signature = Pleroma.Web.HTTPSignatures.sign(actor, %{host: host, "content-length": byte_size(json)})
- @httpoison.post(inbox, json, [{"Content-Type", "application/activity+json"}, {"signature", signature}], hackney: [pool: :default])
+
+ signature =
+ Pleroma.Web.HTTPSignatures.sign(actor, %{host: host, "content-length": byte_size(json)})
+
+ @httpoison.post(
+ inbox,
+ json,
+ [{"Content-Type", "application/activity+json"}, {"signature", signature}],
+ hackney: [pool: :default]
+ )
end
# TODO:
@@ -368,17 +460,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
{:ok, object}
else
Logger.info("Fetching #{id} via AP")
+
with true <- String.starts_with?(id, "http"),
- {:ok, %{body: body, status_code: code}} when code in 200..299 <- @httpoison.get(id, [Accept: "application/activity+json"], follow_redirect: true, timeout: 10000, recv_timeout: 20000),
+ {:ok, %{body: body, status_code: code}} when code in 200..299 <-
+ @httpoison.get(
+ id,
+ [Accept: "application/activity+json"],
+ follow_redirect: true,
+ timeout: 10000,
+ recv_timeout: 20000
+ ),
{:ok, data} <- Jason.decode(body),
nil <- Object.get_by_ap_id(data["id"]),
- params <- %{"type" => "Create", "to" => data["to"], "cc" => data["cc"], "actor" => data["attributedTo"], "object" => data},
+ params <- %{
+ "type" => "Create",
+ "to" => data["to"],
+ "cc" => data["cc"],
+ "actor" => data["attributedTo"],
+ "object" => data
+ },
{:ok, activity} <- Transmogrifier.handle_incoming(params) do
{:ok, Object.get_by_ap_id(activity.data["object"]["id"])}
else
- object = %Object{} -> {:ok, object}
+ object = %Object{} ->
+ {:ok, object}
+
e ->
Logger.info("Couldn't get object via AP, trying out OStatus fetching...")
+
case OStatus.fetch_activity_from_url(id) do
{:ok, [activity | _]} -> {:ok, Object.get_by_ap_id(activity.data["object"]["id"])}
e -> e
@@ -388,15 +497,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
def is_public?(activity) do
- "https://www.w3.org/ns/activitystreams#Public" in (activity.data["to"] ++ (activity.data["cc"] || []))
+ "https://www.w3.org/ns/activitystreams#Public" in (activity.data["to"] ++
+ (activity.data["cc"] || []))
end
def visible_for_user?(activity, nil) do
is_public?(activity)
end
+
def visible_for_user?(activity, user) do
x = [user.ap_id | user.following]
- y = (activity.data["to"] ++ (activity.data["cc"] || []))
+ y = activity.data["to"] ++ (activity.data["cc"] || [])
visible_for_user?(activity, nil) || Enum.any?(x, &(&1 in y))
end
end
diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex
index 47a8bf5ab..12f61f5f0 100644
--- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex
@@ -7,7 +7,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
require Logger
- action_fallback :errors
+ action_fallback(:errors)
def user(conn, %{"nickname" => nickname}) do
with %User{} = user <- User.get_cached_by_nickname(nickname),
@@ -31,6 +31,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
with %User{} = user <- User.get_cached_by_nickname(nickname),
{:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
{page, _} = Integer.parse(page)
+
conn
|> put_resp_header("content-type", "application/activity+json")
|> json(UserView.render("following.json", %{user: user, page: page}))
@@ -50,6 +51,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
with %User{} = user <- User.get_cached_by_nickname(nickname),
{:ok, user} <- Pleroma.Web.WebFinger.ensure_keys_present(user) do
{page, _} = Integer.parse(page)
+
conn
|> put_resp_header("content-type", "application/activity+json")
|> json(UserView.render("followers.json", %{user: user, page: page}))
@@ -74,7 +76,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
end
end
- def outbox(conn, %{"nickname" => nickname}) do outbox(conn, %{"nickname" => nickname, "max_id" => nil}) end
+ def outbox(conn, %{"nickname" => nickname}) do
+ outbox(conn, %{"nickname" => nickname, "max_id" => nil})
+ end
# TODO: Ensure that this inbox is a recipient of the message
def inbox(%{assigns: %{valid_signature: true}} = conn, params) do
@@ -84,7 +88,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
def inbox(conn, params) do
headers = Enum.into(conn.req_headers, %{})
- if !(String.contains?(headers["signature"] || "", params["actor"])) do
+
+ if !String.contains?(headers["signature"] || "", params["actor"]) do
Logger.info("Signature not from author, relayed message, fetching from source")
ActivityPub.fetch_object_from_id(params["object"]["id"])
else
diff --git a/lib/pleroma/web/activity_pub/transmogrifier.ex b/lib/pleroma/web/activity_pub/transmogrifier.ex
index 6561b8d76..00b9f74ff 100644
--- a/lib/pleroma/web/activity_pub/transmogrifier.ex
+++ b/lib/pleroma/web/activity_pub/transmogrifier.ex
@@ -25,21 +25,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> fix_tag
end
- def fix_in_reply_to(%{"inReplyTo" => in_reply_to_id} = object) when not is_nil(in_reply_to_id) do
+ def fix_in_reply_to(%{"inReplyTo" => in_reply_to_id} = object)
+ when not is_nil(in_reply_to_id) do
case ActivityPub.fetch_object_from_id(in_reply_to_id) do
{:ok, replied_object} ->
activity = Activity.get_create_activity_by_object_ap_id(replied_object.data["id"])
+
object
|> Map.put("inReplyTo", replied_object.data["id"])
|> Map.put("inReplyToAtomUri", object["inReplyToAtomUri"] || in_reply_to_id)
|> Map.put("inReplyToStatusId", activity.id)
|> Map.put("conversation", replied_object.data["context"] || object["conversation"])
|> Map.put("context", replied_object.data["context"] || object["conversation"])
+
e ->
Logger.error("Couldn't fetch #{object["inReplyTo"]} #{inspect(e)}")
object
end
end
+
def fix_in_reply_to(object), do: object
def fix_context(object) do
@@ -48,27 +52,32 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
def fix_attachments(object) do
- attachments = (object["attachment"] || [])
- |> Enum.map(fn (data) ->
- url = [%{"type" => "Link", "mediaType" => data["mediaType"], "href" => data["url"]}]
- Map.put(data, "url", url)
- end)
+ attachments =
+ (object["attachment"] || [])
+ |> Enum.map(fn data ->
+ url = [%{"type" => "Link", "mediaType" => data["mediaType"], "href" => data["url"]}]
+ Map.put(data, "url", url)
+ end)
object
|> Map.put("attachment", attachments)
end
def fix_emoji(object) do
- tags = (object["tag"] || [])
- emoji = tags |> Enum.filter(fn (data) -> data["type"] == "Emoji" and data["icon"] end)
- emoji = emoji |> Enum.reduce(%{}, fn (data, mapping) ->
- name = data["name"]
- if String.starts_with?(name, ":") do
- name = name |> String.slice(1..-2)
- end
+ tags = object["tag"] || []
+ emoji = tags |> Enum.filter(fn data -> data["type"] == "Emoji" and data["icon"] end)
+
+ emoji =
+ emoji
+ |> Enum.reduce(%{}, fn data, mapping ->
+ name = data["name"]
+
+ if String.starts_with?(name, ":") do
+ name = name |> String.slice(1..-2)
+ end
- mapping |> Map.put(name, data["icon"]["url"])
- end)
+ mapping |> Map.put(name, data["icon"]["url"])
+ end)
# we merge mastodon and pleroma emoji into a single mapping, to allow for both wire formats
emoji = Map.merge(object["emoji"] || %{}, emoji)
@@ -78,9 +87,10 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
def fix_tag(object) do
- tags = (object["tag"] || [])
- |> Enum.filter(fn (data) -> data["type"] == "Hashtag" and data["name"] end)
- |> Enum.map(fn (data) -> String.slice(data["name"], 1..-1) end)
+ tags =
+ (object["tag"] || [])
+ |> Enum.filter(fn data -> data["type"] == "Hashtag" and data["name"] end)
+ |> Enum.map(fn data -> String.slice(data["name"], 1..-1) end)
combined = (object["tag"] || []) ++ tags
@@ -103,13 +113,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
context: object["conversation"],
local: false,
published: data["published"],
- additional: Map.take(data, [
- "cc",
- "id"
- ])
+ additional:
+ Map.take(data, [
+ "cc",
+ "id"
+ ])
}
-
ActivityPub.create(params)
else
%Activity{} = activity -> {:ok, activity}
@@ -117,11 +127,14 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
end
- def handle_incoming(%{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data) do
+ def handle_incoming(
+ %{"type" => "Follow", "object" => followed, "actor" => follower, "id" => id} = data
+ ) do
with %User{local: true} = followed <- User.get_cached_by_ap_id(followed),
%User{} = follower <- User.get_or_fetch_by_ap_id(follower),
{:ok, activity} <- ActivityPub.follow(follower, followed, id, false) do
ActivityPub.accept(%{to: [follower.ap_id], actor: followed.ap_id, object: data, local: true})
+
User.follow(follower, followed)
{:ok, activity}
else
@@ -129,7 +142,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
end
- def handle_incoming(%{"type" => "Like", "object" => object_id, "actor" => actor, "id" => id} = data) do
+ def handle_incoming(
+ %{"type" => "Like", "object" => object_id, "actor" => actor, "id" => id} = data
+ ) do
with %User{} = actor <- User.get_or_fetch_by_ap_id(actor),
{:ok, object} <- get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id),
{:ok, activity, object} <- ActivityPub.like(actor, object, id, false) do
@@ -139,7 +154,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
end
- def handle_incoming(%{"type" => "Announce", "object" => object_id, "actor" => actor, "id" => id} = data) do
+ def handle_incoming(
+ %{"type" => "Announce", "object" => object_id, "actor" => actor, "id" => id} = data
+ ) do
with %User{} = actor <- User.get_or_fetch_by_ap_id(actor),
{:ok, object} <- get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id),
{:ok, activity, object} <- ActivityPub.announce(actor, object, id, false) do
@@ -149,20 +166,31 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
end
- def handle_incoming(%{"type" => "Update", "object" => %{"type" => "Person"} = object, "actor" => actor_id} = data) do
+ def handle_incoming(
+ %{"type" => "Update", "object" => %{"type" => "Person"} = object, "actor" => actor_id} =
+ data
+ ) do
with %User{ap_id: ^actor_id} = actor <- User.get_by_ap_id(object["id"]) do
{:ok, new_user_data} = ActivityPub.user_data_from_user_object(object)
banner = new_user_data[:info]["banner"]
- update_data = new_user_data
- |> Map.take([:name, :bio, :avatar])
- |> Map.put(:info, Map.merge(actor.info, %{"banner" => banner}))
+
+ update_data =
+ new_user_data
+ |> Map.take([:name, :bio, :avatar])
+ |> Map.put(:info, Map.merge(actor.info, %{"banner" => banner}))
actor
|> User.upgrade_changeset(update_data)
|> User.update_and_set_cache()
- ActivityPub.update(%{local: false, to: data["to"] || [], cc: data["cc"] || [], object: object, actor: actor_id})
+ ActivityPub.update(%{
+ local: false,
+ to: data["to"] || [],
+ cc: data["cc"] || [],
+ object: object,
+ actor: actor_id
+ })
else
e ->
Logger.error(e)
@@ -171,11 +199,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
# TODO: Make secure.
- def handle_incoming(%{"type" => "Delete", "object" => object_id, "actor" => actor, "id" => id} = data) do
- object_id = case object_id do
- %{"id" => id} -> id
- id -> id
- end
+ def handle_incoming(
+ %{"type" => "Delete", "object" => object_id, "actor" => actor, "id" => id} = data
+ ) do
+ object_id =
+ case object_id do
+ %{"id" => id} -> id
+ id -> id
+ end
+
with %User{} = actor <- User.get_or_fetch_by_ap_id(actor),
{:ok, object} <- get_obj_helper(object_id) || ActivityPub.fetch_object_from_id(object_id),
{:ok, activity} <- ActivityPub.delete(object, false) do
@@ -203,6 +235,7 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
_e -> object
end
end
+
def set_reply_to_uri(obj), do: obj
# Prepares the object of an outgoing create activity.
@@ -222,20 +255,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
"""
internal -> Mastodon
"""
+
def prepare_outgoing(%{"type" => "Create", "object" => %{"type" => "Note"} = object} = data) do
- object = object
- |> prepare_object
- data = data
- |> Map.put("object", object)
- |> Map.put("@context", "https://www.w3.org/ns/activitystreams")
+ object =
+ object
+ |> prepare_object
+
+ data =
+ data
+ |> Map.put("object", object)
+ |> Map.put("@context", "https://www.w3.org/ns/activitystreams")
{:ok, data}
end
def prepare_outgoing(%{"type" => type} = data) do
- data = data
- |> maybe_fix_object_url
- |> Map.put("@context", "https://www.w3.org/ns/activitystreams")
+ data =
+ data
+ |> maybe_fix_object_url
+ |> Map.put("@context", "https://www.w3.org/ns/activitystreams")
{:ok, data}
end
@@ -245,11 +283,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
case ActivityPub.fetch_object_from_id(data["object"]) do
{:ok, relative_object} ->
if relative_object.data["external_url"] do
- data = data
- |> Map.put("object", relative_object.data["external_url"])
+ data =
+ data
+ |> Map.put("object", relative_object.data["external_url"])
else
data
end
+
e ->
Logger.error("Couldn't fetch #{data["object"]} #{inspect(e)}")
data
@@ -260,8 +300,15 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
def add_hashtags(object) do
- tags = (object["tag"] || [])
- |> Enum.map fn (tag) -> %{"href" => Pleroma.Web.Endpoint.url() <> "/tags/#{tag}", "name" => "##{tag}", "type" => "Hashtag"} end
+ tags =
+ (object["tag"] || [])
+ |> Enum.map(fn tag ->
+ %{
+ "href" => Pleroma.Web.Endpoint.url() <> "/tags/#{tag}",
+ "name" => "##{tag}",
+ "type" => "Hashtag"
+ }
+ end)
object
|> Map.put("tag", tags)
@@ -269,10 +316,14 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def add_mention_tags(object) do
recipients = object["to"] ++ (object["cc"] || [])
- mentions = recipients
- |> Enum.map(fn (ap_id) -> User.get_cached_by_ap_id(ap_id) end)
- |> Enum.filter(&(&1))
- |> Enum.map(fn(user) -> %{"type" => "Mention", "href" => user.ap_id, "name" => "@#{user.nickname}"} end)
+
+ mentions =
+ recipients
+ |> Enum.map(fn ap_id -> User.get_cached_by_ap_id(ap_id) end)
+ |> Enum.filter(& &1)
+ |> Enum.map(fn user ->
+ %{"type" => "Mention", "href" => user.ap_id, "name" => "@#{user.nickname}"}
+ end)
tags = object["tag"] || []
@@ -284,13 +335,18 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def add_emoji_tags(object) do
tags = object["tag"] || []
emoji = object["emoji"] || []
- out = emoji |> Enum.map(fn {name, url} ->
- %{"icon" => %{"url" => url, "type" => "Image"},
- "name" => ":" <> name <> ":",
- "type" => "Emoji",
- "updated" => "1970-01-01T00:00:00Z",
- "id" => url}
- end)
+
+ out =
+ emoji
+ |> Enum.map(fn {name, url} ->
+ %{
+ "icon" => %{"url" => url, "type" => "Image"},
+ "name" => ":" <> name <> ":",
+ "type" => "Emoji",
+ "updated" => "1970-01-01T00:00:00Z",
+ "id" => url
+ }
+ end)
object
|> Map.put("tag", tags ++ out)
@@ -313,11 +369,12 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
end
def prepare_attachments(object) do
- attachments = (object["attachment"] || [])
- |> Enum.map(fn (data) ->
- [%{"mediaType" => media_type, "href" => href} | _] = data["url"]
- %{"url" => href, "mediaType" => media_type, "name" => data["name"], "type" => "Document"}
- end)
+ attachments =
+ (object["attachment"] || [])
+ |> Enum.map(fn data ->
+ [%{"mediaType" => media_type, "href" => href} | _] = data["url"]
+ %{"url" => href, "mediaType" => media_type, "name" => data["name"], "type" => "Document"}
+ end)
object
|> Map.put("attachment", attachments)
@@ -325,9 +382,24 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
defp user_upgrade_task(user) do
old_follower_address = User.ap_followers(user)
- q = from u in User,
- where: ^old_follower_address in u.following,
- update: [set: [following: fragment("array_replace(?,?,?)", u.following, ^old_follower_address, ^user.follower_address)]]
+
+ q =
+ from(
+ u in User,
+ where: ^old_follower_address in u.following,
+ update: [
+ set: [
+ following:
+ fragment(
+ "array_replace(?,?,?)",
+ u.following,
+ ^old_follower_address,
+ ^user.follower_address
+ )
+ ]
+ ]
+ )
+
Repo.update_all(q, [])
maybe_retire_websub(user.ap_id)
@@ -335,22 +407,40 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
# Only do this for recent activties, don't go through the whole db.
# Only look at the last 1000 activities.
since = (Repo.aggregate(Activity, :max, :id) || 0) - 1_000
- q = from a in Activity,
- where: ^old_follower_address in a.recipients,
- where: a.id > ^since,
- update: [set: [recipients: fragment("array_replace(?,?,?)", a.recipients, ^old_follower_address, ^user.follower_address)]]
+
+ q =
+ from(
+ a in Activity,
+ where: ^old_follower_address in a.recipients,
+ where: a.id > ^since,
+ update: [
+ set: [
+ recipients:
+ fragment(
+ "array_replace(?,?,?)",
+ a.recipients,
+ ^old_follower_address,
+ ^user.follower_address
+ )
+ ]
+ ]
+ )
+
Repo.update_all(q, [])
end
def upgrade_user_from_ap_id(ap_id, async \\ true) do
with %User{local: false} = user <- User.get_by_ap_id(ap_id),
{:ok, data} <- ActivityPub.fetch_and_prepare_user_from_ap_id(ap_id) do
- data = data
- |> Map.put(:info, Map.merge(user.info, data[:info]))
+ data =
+ data
+ |> Map.put(:info, Map.merge(user.info, data[:info]))
already_ap = User.ap_enabled?(user)
- {:ok, user} = User.upgrade_changeset(user, data)
- |> Repo.update()
+
+ {:ok, user} =
+ User.upgrade_changeset(user, data)
+ |> Repo.update()
if !already_ap do
# This could potentially take a long time, do it in the background
@@ -371,9 +461,13 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
def maybe_retire_websub(ap_id) do
# some sanity checks
- if is_binary(ap_id) && (String.length(ap_id) > 8) do
- q = from ws in Pleroma.Web.Websub.WebsubClientSubscription,
- where: fragment("? like ?", ws.topic, ^"#{ap_id}%")
+ if is_binary(ap_id) && String.length(ap_id) > 8 do
+ q =
+ from(
+ ws in Pleroma.Web.Websub.WebsubClientSubscription,
+ where: fragment("? like ?", ws.topic, ^"#{ap_id}%")
+ )
+
Repo.delete_all(q)
end
end
diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
index a25b27aab..16a1d3e97 100644
--- a/lib/pleroma/web/activity_pub/utils.ex
+++ b/lib/pleroma/web/activity_pub/utils.ex
@@ -26,7 +26,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
end
def make_date do
- DateTime.utc_now() |> DateTime.to_iso8601
+ DateTime.utc_now() |> DateTime.to_iso8601()
end
def generate_activity_id do
@@ -38,25 +38,28 @@ defmodule Pleroma.Web.ActivityPub.Utils do
end
def generate_object_id do
- Helpers.o_status_url(Endpoint, :object, UUID.generate)
+ Helpers.o_status_url(Endpoint, :object, UUID.generate())
end
def generate_id(type) do
- "#{Web.base_url()}/#{type}/#{UUID.generate}"
+ "#{Web.base_url()}/#{type}/#{UUID.generate()}"
end
@doc """
Enqueues an activity for federation if it's local
"""
def maybe_federate(%Activity{local: true} = activity) do
- priority = case activity.data["type"] do
- "Delete" -> 10
- "Create" -> 1
- _ -> 5
- end
+ priority =
+ case activity.data["type"] do
+ "Delete" -> 10
+ "Create" -> 1
+ _ -> 5
+ end
+
Pleroma.Web.Federator.enqueue(:publish, activity, priority)
:ok
end
+
def maybe_federate(_), do: :ok
@doc """
@@ -64,9 +67,10 @@ defmodule Pleroma.Web.ActivityPub.Utils do
also adds it to an included object
"""
def lazy_put_activity_defaults(map) do
- map = map
- |> Map.put_new_lazy("id", &generate_activity_id/0)
- |> Map.put_new_lazy("published", &make_date/0)
+ map =
+ map
+ |> Map.put_new_lazy("id", &generate_activity_id/0)
+ |> Map.put_new_lazy("published", &make_date/0)
if is_map(map["object"]) do
object = lazy_put_object_defaults(map["object"])
@@ -88,11 +92,13 @@ defmodule Pleroma.Web.ActivityPub.Utils do
@doc """
Inserts a full object if it is contained in an activity.
"""
- def insert_full_object(%{"object" => %{"type" => type} = object_data}) when is_map(object_data) and type in ["Note"] do
+ def insert_full_object(%{"object" => %{"type" => type} = object_data})
+ when is_map(object_data) and type in ["Note"] do
with {:ok, _} <- Object.create(object_data) do
:ok
end
end
+
def insert_full_object(_), do: :ok
def update_object_in_activities(%{data: %{"id" => id}} = object) do
@@ -101,7 +107,8 @@ defmodule Pleroma.Web.ActivityPub.Utils do
# Alternatively, just don't do this and fetch the current object each time. Most
# could probably be taken from cache.
relevant_activities = Activity.all_by_object_ap_id(id)
- Enum.map(relevant_activities, fn (activity) ->
+
+ Enum.map(relevant_activities, fn activity ->
new_activity_data = activity.data |> Map.put("object", object.data)
changeset = Changeset.change(activity, data: new_activity_data)
Repo.update(changeset)
@@ -114,11 +121,20 @@ defmodule Pleroma.Web.ActivityPub.Utils do
Returns an existing like if a user already liked an object
"""
def get_existing_like(actor, %{data: %{"id" => id}}) do
- query = from activity in Activity,
- where: fragment("(?)->>'actor' = ?", activity.data, ^actor),
- # this is to use the index
- where: fragment("coalesce((?)->'object'->>'id', (?)->>'object') = ?", activity.data, activity.data, ^id),
- where: fragment("(?)->>'type' = 'Like'", activity.data)
+ query =
+ from(
+ activity in Activity,
+ where: fragment("(?)->>'actor' = ?", activity.data, ^actor),
+ # this is to use the index
+ where:
+ fragment(
+ "coalesce((?)->'object'->>'id', (?)->>'object') = ?",
+ activity.data,
+ activity.data,
+ ^id
+ ),
+ where: fragment("(?)->>'type' = 'Like'", activity.data)
+ )
Repo.one(query)
end
@@ -137,10 +153,12 @@ defmodule Pleroma.Web.ActivityPub.Utils do
end
def update_element_in_object(property, element, object) do
- with new_data <- object.data |> Map.put("#{property}_count", length(element)) |> Map.put("#{property}s", element),
+ with new_data <-
+ object.data |> Map.put("#{property}_count", length(element))
+ |> Map.put("#{property}s", element),
changeset <- Changeset.change(object, data: new_data),
{:ok, object} <- Repo.update(changeset),
- _ <- update_object_in_activities(object) do
+ _ <- update_object_in_activities(object) do
{:ok, object}
end
end
@@ -150,7 +168,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
end
def add_like_to_object(%Activity{data: %{"actor" => actor}}, object) do
- with likes <- [actor | (object.data["likes"] || [])] |> Enum.uniq do
+ with likes <- [actor | object.data["likes"] || []] |> Enum.uniq() do
update_likes_in_object(likes, object)
end
end
@@ -178,13 +196,20 @@ defmodule Pleroma.Web.ActivityPub.Utils do
if activity_id, do: Map.put(data, "id", activity_id), else: data
end
- def fetch_latest_follow(%User{ap_id: follower_id},
- %User{ap_id: followed_id}) do
- query = from activity in Activity,
- where: fragment("? @> ?", activity.data, ^%{type: "Follow", actor: follower_id,
- object: followed_id}),
- order_by: [desc: :id],
- limit: 1
+ def fetch_latest_follow(%User{ap_id: follower_id}, %User{ap_id: followed_id}) do
+ query =
+ from(
+ activity in Activity,
+ where:
+ fragment(
+ "? @> ?",
+ activity.data,
+ ^%{type: "Follow", actor: follower_id, object: followed_id}
+ ),
+ order_by: [desc: :id],
+ limit: 1
+ )
+
Repo.one(query)
end
@@ -193,7 +218,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do
@doc """
Make announce activity data for the given actor and object
"""
- def make_announce_data(%User{ap_id: ap_id} = user, %Object{data: %{"id" => id}} = object, activity_id) do
+ def make_announce_data(
+ %User{ap_id: ap_id} = user,
+ %Object{data: %{"id" => id}} = object,
+ activity_id
+ ) do
data = %{
"type" => "Announce",
"actor" => ap_id,
@@ -207,7 +236,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
end
def add_announce_to_object(%Activity{data: %{"actor" => actor}}, object) do
- with announcements <- [actor | (object.data["announcements"] || [])] |> Enum.uniq do
+ with announcements <- [actor | object.data["announcements"] || []] |> Enum.uniq() do
update_element_in_object("announcement", announcements, object)
end
end
@@ -223,14 +252,14 @@ defmodule Pleroma.Web.ActivityPub.Utils do
}
end
-
#### Create-related helpers
def make_create_data(params, additional) do
published = params.published || make_date()
+
%{
"type" => "Create",
- "to" => params.to |> Enum.uniq,
+ "to" => params.to |> Enum.uniq(),
"actor" => params.actor.ap_id,
"object" => params.object,
"published" => published,
diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
index 9ff1f0c77..997d8308f 100644
--- a/lib/pleroma/web/activity_pub/views/user_view.ex
+++ b/lib/pleroma/web/activity_pub/views/user_view.ex
@@ -12,6 +12,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
{:ok, _, public_key} = Salmon.keys_from_pem(user.info["keys"])
public_key = :public_key.pem_entry_encode(:RSAPublicKey, public_key)
public_key = :public_key.pem_encode([public_key])
+
%{
"id" => user.ap_id,
"type" => "Person",
@@ -30,7 +31,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"publicKeyPem" => public_key
},
"endpoints" => %{
- "sharedInbox" => "#{Pleroma.Web.Endpoint.url}/inbox"
+ "sharedInbox" => "#{Pleroma.Web.Endpoint.url()}/inbox"
},
"icon" => %{
"type" => "Image",
@@ -47,7 +48,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do
def collection(collection, iri, page) do
offset = (page - 1) * 10
items = Enum.slice(collection, offset, 10)
- items = Enum.map(items, fn (user) -> user.ap_id end)
+ items = Enum.map(items, fn user -> user.ap_id end)
+
map = %{
"id" => "#{iri}?page=#{page}",
"type" => "OrderedCollectionPage",
@@ -55,19 +57,22 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"totalItems" => length(collection),
"orderedItems" => items
}
+
if offset < length(collection) do
- Map.put(map, "next", "#{iri}?page=#{page+1}")
+ Map.put(map, "next", "#{iri}?page=#{page + 1}")
end
end
def render("following.json", %{user: user, page: page}) do
{:ok, following} = User.get_friends(user)
+
collection(following, "#{user.ap_id}/following", page)
|> Map.merge(Utils.make_json_ld_header())
end
def render("following.json", %{user: user}) do
{:ok, following} = User.get_friends(user)
+
%{
"id" => "#{user.ap_id}/following",
"type" => "OrderedCollection",
@@ -79,12 +84,14 @@ defmodule Pleroma.Web.ActivityPub.UserView do
def render("followers.json", %{user: user, page: page}) do
{:ok, followers} = User.get_followers(user)
+
collection(followers, "#{user.ap_id}/followers", page)
|> Map.merge(Utils.make_json_ld_header())
end
def render("followers.json", %{user: user}) do
{:ok, followers} = User.get_followers(user)
+
%{
"id" => "#{user.ap_id}/followers",
"type" => "OrderedCollection",
@@ -115,19 +122,21 @@ defmodule Pleroma.Web.ActivityPub.UserView do
activities = Enum.reverse(activities)
max_id = Enum.at(activities, 0).id
- collection = Enum.map(activities, fn (act) ->
- {:ok, data} = Transmogrifier.prepare_outgoing(act.data)
- data
- end)
+ collection =
+ Enum.map(activities, fn act ->
+ {:ok, data} = Transmogrifier.prepare_outgoing(act.data)
+ data
+ end)
iri = "#{user.ap_id}/outbox"
+
page = %{
"id" => "#{iri}?max_id=#{max_id}",
"type" => "OrderedCollectionPage",
"partOf" => iri,
"totalItems" => info.note_count,
"orderedItems" => collection,
- "next" => "#{iri}?max_id=#{min_id-1}",
+ "next" => "#{iri}?max_id=#{min_id - 1}"
}
if max_qid == nil do
diff --git a/lib/pleroma/web/channels/user_socket.ex b/lib/pleroma/web/channels/user_socket.ex
index f18b3cb80..fd8918a7d 100644
--- a/lib/pleroma/web/channels/user_socket.ex
+++ b/lib/pleroma/web/channels/user_socket.ex
@@ -6,11 +6,11 @@ defmodule Pleroma.Web.UserSocket do
## Channels
# channel "room:*", Pleroma.Web.RoomChannel
if Application.get_env(:pleroma, :chat) |> Keyword.get(:enabled) do
- channel "chat:*", Pleroma.Web.ChatChannel
+ channel("chat:*", Pleroma.Web.ChatChannel)
end
## Transports
- transport :websocket, Phoenix.Transports.WebSocket
+ transport(:websocket, Phoenix.Transports.WebSocket)
# transport :longpoll, Phoenix.Transports.LongPoll
# Socket params are passed from the client and can
diff --git a/lib/pleroma/web/chat_channel.ex b/lib/pleroma/web/chat_channel.ex
index ddc1d6f80..37eba8c3f 100644
--- a/lib/pleroma/web/chat_channel.ex
+++ b/lib/pleroma/web/chat_channel.ex
@@ -9,19 +9,21 @@ defmodule Pleroma.Web.ChatChannel do
end
def handle_info(:after_join, socket) do
- push socket, "messages", %{messages: ChatChannelState.messages()}
+ push(socket, "messages", %{messages: ChatChannelState.messages()})
{:noreply, socket}
end
def handle_in("new_msg", %{"text" => text}, %{assigns: %{user_name: user_name}} = socket) do
text = String.trim(text)
+
if String.length(text) > 0 do
author = User.get_cached_by_nickname(user_name)
author = Pleroma.Web.MastodonAPI.AccountView.render("account.json", user: author)
message = ChatChannelState.add_message(%{text: text, author: author})
- broadcast! socket, "new_msg", message
+ broadcast!(socket, "new_msg", message)
end
+
{:noreply, socket}
end
end
@@ -43,6 +45,6 @@ defmodule Pleroma.Web.ChatChannel.ChatChannelState do
end
def messages() do
- Agent.get(__MODULE__, fn state -> state[:messages] |> Enum.reverse end)
+ Agent.get(__MODULE__, fn state -> state[:messages] |> Enum.reverse() end)
end
end
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
index 5fc940261..21225c3b7 100644
--- a/lib/pleroma/web/common_api/common_api.ex
+++ b/lib/pleroma/web/common_api/common_api.ex
@@ -8,7 +8,7 @@ defmodule Pleroma.Web.CommonAPI do
def delete(activity_id, user) do
with %Activity{data: %{"object" => %{"id" => object_id}}} <- Repo.get(Activity, activity_id),
%Object{} = object <- Object.get_by_ap_id(object_id),
- true <- user.info["is_moderator"] || (user.ap_id == object.data["actor"]),
+ true <- user.info["is_moderator"] || user.ap_id == object.data["actor"],
{:ok, delete} <- ActivityPub.delete(object) do
{:ok, delete}
end
@@ -46,17 +46,22 @@ defmodule Pleroma.Web.CommonAPI do
end
end
- def get_visibility(%{"visibility" => visibility}) when visibility in ~w{public unlisted private direct}, do: visibility
+ def get_visibility(%{"visibility" => visibility})
+ when visibility in ~w{public unlisted private direct},
+ do: visibility
+
def get_visibility(%{"in_reply_to_status_id" => status_id}) when not is_nil(status_id) do
inReplyTo = get_replied_to_activity(status_id)
Pleroma.Web.MastodonAPI.StatusView.get_visibility(inReplyTo.data["object"])
end
+
def get_visibility(_), do: "public"
@instance Application.get_env(:pleroma, :instance)
@limit Keyword.get(@instance, :limit)
def post(user, %{"status" => status} = data) do
visibility = get_visibility(data)
+
with status <- String.trim(status),
length when length in 1..@limit <- String.length(status),
attachments <- attachments_from_ids(data["media_ids"]),
@@ -64,18 +69,52 @@ defmodule Pleroma.Web.CommonAPI do
inReplyTo <- get_replied_to_activity(data["in_reply_to_status_id"]),
{to, cc} <- to_for_user_and_mentions(user, mentions, inReplyTo, visibility),
tags <- Formatter.parse_tags(status, data),
- content_html <- make_content_html(status, mentions, attachments, tags, data["no_attachment_links"]),
+ content_html <-
+ make_content_html(status, mentions, attachments, tags, data["no_attachment_links"]),
context <- make_context(inReplyTo),
cw <- data["spoiler_text"],
- object <- make_note_data(user.ap_id, to, context, content_html, attachments, inReplyTo, tags, cw, cc),
- object <- Map.put(object, "emoji", Formatter.get_emoji(status) |> Enum.reduce(%{}, fn({name, file}, acc) -> Map.put(acc, name, "#{Pleroma.Web.Endpoint.static_url}#{file}") end)) do
- res = ActivityPub.create(%{to: to, actor: user, context: context, object: object, additional: %{"cc" => cc}})
+ object <-
+ make_note_data(
+ user.ap_id,
+ to,
+ context,
+ content_html,
+ attachments,
+ inReplyTo,
+ tags,
+ cw,
+ cc
+ ),
+ object <-
+ Map.put(
+ object,
+ "emoji",
+ Formatter.get_emoji(status)
+ |> Enum.reduce(%{}, fn {name, file}, acc ->
+ Map.put(acc, name, "#{Pleroma.Web.Endpoint.static_url()}#{file}")
+ end)
+ ) do
+ res =
+ ActivityPub.create(%{
+ to: to,
+ actor: user,
+ context: context,
+ object: object,
+ additional: %{"cc" => cc}
+ })
+
User.increase_note_count(user)
res
end
end
def update(user) do
- ActivityPub.update(%{local: true, to: [user.follower_address], cc: [], actor: user.ap_id, object: Pleroma.Web.ActivityPub.UserView.render("user.json", %{user: user})})
+ ActivityPub.update(%{
+ local: true,
+ to: [user.follower_address],
+ cc: [],
+ actor: user.ap_id,
+ object: Pleroma.Web.ActivityPub.UserView.render("user.json", %{user: user})
+ })
end
end
diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex
index 3c09f0cc7..49c4ee1eb 100644
--- a/lib/pleroma/web/common_api/utils.ex
+++ b/lib/pleroma/web/common_api/utils.ex
@@ -6,6 +6,7 @@ defmodule Pleroma.Web.CommonAPI.Utils do
# This is a hack for twidere.
def get_by_id_or_ap_id(id) do
activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id)
+
if activity.data["type"] == "Create" do
activity
else
@@ -16,10 +17,11 @@ defmodule Pleroma.Web.CommonAPI.Utils do
def get_replied_to_activity(id) when not is_nil(id) do
Repo.get(Activity, id)
end
+
def get_replied_to_activity(_), do: nil
def attachments_from_ids(ids) do
- Enum.map(ids || [], fn (media_id) ->
+ Enum.map(ids || [], fn media_id ->
Repo.get(Object, media_id).data
end)
end
@@ -27,8 +29,9 @@ defmodule Pleroma.Web.CommonAPI.Utils do
def to_for_user_and_mentions(user, mentions, inReplyTo, "public") do
to = ["https://www.w3.org/ns/activitystreams#Public"]
- mentioned_users = Enum.map(mentions, fn ({_, %{ap_id: ap_id}}) -> ap_id end)
+ mentioned_users = Enum.map(mentions, fn {_, %{ap_id: ap_id}} -> ap_id end)
cc = [user.follower_address | mentioned_users]
+
if inReplyTo do
{to, Enum.uniq([inReplyTo.data["actor"] | cc])}
else
@@ -47,7 +50,8 @@ defmodule Pleroma.Web.CommonAPI.Utils do
end
def to_for_user_and_mentions(user, mentions, inReplyTo, "direct") do
- mentioned_users = Enum.map(mentions, fn ({_, %{ap_id: ap_id}}) -> ap_id end)
+ mentioned_users = Enum.map(mentions, fn {_, %{ap_id: ap_id}} -> ap_id end)
+
if inReplyTo do
{Enum.uniq([inReplyTo.data["actor"] | mentioned_users]), []}
else
@@ -62,55 +66,72 @@ defmodule Pleroma.Web.CommonAPI.Utils do
end
def make_context(%Activity{data: %{"context" => context}}), do: context
- def make_context(_), do: Utils.generate_context_id
+ def make_context(_), do: Utils.generate_context_id()
def maybe_add_attachments(text, attachments, _no_links = true), do: text
+
def maybe_add_attachments(text, attachments, _no_links) do
add_attachments(text, attachments)
end
+
def add_attachments(text, attachments) do
- attachment_text = Enum.map(attachments, fn
- (%{"url" => [%{"href" => href} | _]}) ->
- name = URI.decode(Path.basename(href))
- "<a href=\"#{href}\" class='attachment'>#{shortname(name)}</a>"
- _ -> ""
- end)
+ attachment_text =
+ Enum.map(attachments, fn
+ %{"url" => [%{"href" => href} | _]} ->
+ name = URI.decode(Path.basename(href))
+ "<a href=\"#{href}\" class='attachment'>#{shortname(name)}</a>"
+
+ _ ->
+ ""
+ end)
+
Enum.join([text | attachment_text], "<br>")
end
def format_input(text, mentions, tags) do
text
- |> Formatter.html_escape
+ |> Formatter.html_escape()
|> String.replace("\n", "<br>")
- |> (&({[], &1})).()
- |> Formatter.add_links
+ |> (&{[], &1}).()
+ |> Formatter.add_links()
|> Formatter.add_user_links(mentions)
|> Formatter.add_hashtag_links(tags)
- |> Formatter.finalize
+ |> Formatter.finalize()
end
def add_tag_links(text, tags) do
- tags = tags
- |> Enum.sort_by(fn ({tag, _}) -> -String.length(tag) end)
+ tags =
+ tags
+ |> Enum.sort_by(fn {tag, _} -> -String.length(tag) end)
- Enum.reduce(tags, text, fn({full, tag}, text) ->
- url = "#<a href='#{Pleroma.Web.base_url}/tag/#{tag}' rel='tag'>#{tag}</a>"
+ Enum.reduce(tags, text, fn {full, tag}, text ->
+ url = "#<a href='#{Pleroma.Web.base_url()}/tag/#{tag}' rel='tag'>#{tag}</a>"
String.replace(text, full, url)
end)
end
- def make_note_data(actor, to, context, content_html, attachments, inReplyTo, tags, cw \\ nil, cc \\ []) do
- object = %{
- "type" => "Note",
- "to" => to,
- "cc" => cc,
- "content" => content_html,
- "summary" => cw,
- "context" => context,
- "attachment" => attachments,
- "actor" => actor,
- "tag" => tags |> Enum.map(fn ({_, tag}) -> tag end)
- }
+ def make_note_data(
+ actor,
+ to,
+ context,
+ content_html,
+ attachments,
+ inReplyTo,
+ tags,
+ cw \\ nil,
+ cc \\ []
+ ) do
+ object = %{
+ "type" => "Note",
+ "to" => to,
+ "cc" => cc,
+ "content" => content_html,
+ "summary" => cw,
+ "context" => context,
+ "attachment" => attachments,
+ "actor" => actor,
+ "tag" => tags |> Enum.map(fn {_, tag} -> tag end)
+ }
if inReplyTo do
object
@@ -130,24 +151,25 @@ defmodule Pleroma.Web.CommonAPI.Utils do
end
def date_to_asctime(date) do
- with {:ok, date, _offset} <- date |> DateTime.from_iso8601 do
+ with {:ok, date, _offset} <- date |> DateTime.from_iso8601() do
format_asctime(date)
- else _e ->
+ else
+ _e ->
""
end
end
def to_masto_date(%NaiveDateTime{} = date) do
date
- |> NaiveDateTime.to_iso8601
+ |> NaiveDateTime.to_iso8601()
|> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
end
def to_masto_date(date) do
try do
date
- |> NaiveDateTime.from_iso8601!
- |> NaiveDateTime.to_iso8601
+ |> NaiveDateTime.from_iso8601!()
+ |> NaiveDateTime.to_iso8601()
|> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
rescue
_e -> ""
diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex
index a2fb71451..0a2ac853e 100644
--- a/lib/pleroma/web/endpoint.ex
+++ b/lib/pleroma/web/endpoint.ex
@@ -2,47 +2,55 @@ defmodule Pleroma.Web.Endpoint do
use Phoenix.Endpoint, otp_app: :pleroma
if Application.get_env(:pleroma, :chat) |> Keyword.get(:enabled) do
- socket "/socket", Pleroma.Web.UserSocket
+ socket("/socket", Pleroma.Web.UserSocket)
end
- socket "/api/v1", Pleroma.Web.MastodonAPI.MastodonSocket
+
+ socket("/api/v1", Pleroma.Web.MastodonAPI.MastodonSocket)
# Serve at "/" the static files from "priv/static" directory.
#
# You should set gzip to true if you are running phoenix.digest
# when deploying your static files in production.
- plug Plug.Static,
- at: "/media", from: "uploads", gzip: false
- plug Plug.Static,
- at: "/", from: :pleroma,
+ plug(Plug.Static, at: "/media", from: "uploads", gzip: false)
+
+ plug(
+ Plug.Static,
+ at: "/",
+ from: :pleroma,
only: ~w(index.html static finmoji emoji packs sounds images instance sw.js)
+ )
# Code reloading can be explicitly enabled under the
# :code_reloader configuration of your endpoint.
if code_reloading? do
- plug Phoenix.CodeReloader
+ plug(Phoenix.CodeReloader)
end
- plug TrailingFormatPlug
- plug Plug.RequestId
- plug Plug.Logger
+ plug(TrailingFormatPlug)
+ plug(Plug.RequestId)
+ plug(Plug.Logger)
- plug Plug.Parsers,
+ plug(
+ Plug.Parsers,
parsers: [:urlencoded, :multipart, :json],
pass: ["*/*"],
json_decoder: Jason
+ )
- plug Plug.MethodOverride
- plug Plug.Head
+ plug(Plug.MethodOverride)
+ plug(Plug.Head)
# The session will be stored in the cookie and signed,
# this means its contents can be read but not tampered with.
# Set :encryption_salt if you would also like to encrypt it.
- plug Plug.Session,
+ plug(
+ Plug.Session,
store: :cookie,
key: "_pleroma_key",
signing_salt: "CqaoopA2"
+ )
- plug Pleroma.Web.Router
+ plug(Pleroma.Web.Router)
@doc """
Dynamically loads configuration from the system environment
diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex
index 51d293196..8335add9c 100644
--- a/lib/pleroma/web/federator/federator.ex
+++ b/lib/pleroma/web/federator/federator.ex
@@ -16,27 +16,36 @@ defmodule Pleroma.Web.Federator do
def start_link do
spawn(fn ->
- Process.sleep(1000 * 60 * 1) # 1 minute
+ # 1 minute
+ Process.sleep(1000 * 60 * 1)
enqueue(:refresh_subscriptions, nil)
end)
- GenServer.start_link(__MODULE__, %{
- in: {:sets.new(), []},
- out: {:sets.new(), []}
- }, name: __MODULE__)
+
+ GenServer.start_link(
+ __MODULE__,
+ %{
+ in: {:sets.new(), []},
+ out: {:sets.new(), []}
+ },
+ name: __MODULE__
+ )
end
def handle(:refresh_subscriptions, _) do
Logger.debug("Federator running refresh subscriptions")
Websub.refresh_subscriptions()
+
spawn(fn ->
- Process.sleep(1000 * 60 * 60 * 6) # 6 hours
+ # 6 hours
+ Process.sleep(1000 * 60 * 60 * 6)
enqueue(:refresh_subscriptions, nil)
end)
end
def handle(:request_subscription, websub) do
Logger.debug("Refreshing #{websub.topic}")
- with {:ok, websub } <- Websub.request_subscription(websub) do
+
+ with {:ok, websub} <- Websub.request_subscription(websub) do
Logger.debug("Successfully refreshed #{websub.topic}")
else
_e -> Logger.debug("Couldn't refresh #{websub.topic}")
@@ -45,8 +54,10 @@ defmodule Pleroma.Web.Federator do
def handle(:publish, activity) do
Logger.debug(fn -> "Running publish for #{activity.data["id"]}" end)
+
with actor when not is_nil(actor) <- User.get_cached_by_ap_id(activity.data["actor"]) do
{:ok, actor} = WebFinger.ensure_keys_present(actor)
+
if ActivityPub.is_public?(activity) do
Logger.info(fn -> "Sending #{activity.data["id"]} out via WebSub" end)
Websub.publish(Pleroma.Web.OStatus.feed_path(actor), actor, activity)
@@ -61,7 +72,10 @@ defmodule Pleroma.Web.Federator do
end
def handle(:verify_websub, websub) do
- Logger.debug(fn -> "Running WebSub verification for #{websub.id} (#{websub.topic}, #{websub.callback})" end)
+ Logger.debug(fn ->
+ "Running WebSub verification for #{websub.id} (#{websub.topic}, #{websub.callback})"
+ end)
+
@websub.verify(websub)
end
@@ -72,16 +86,18 @@ defmodule Pleroma.Web.Federator do
def handle(:incoming_ap_doc, params) do
Logger.info("Handling incoming AP activity")
+
with {:ok, _user} <- ap_enabled_actor(params["actor"]),
nil <- Activity.get_by_ap_id(params["id"]),
{:ok, activity} <- Transmogrifier.handle_incoming(params) do
else
%Activity{} ->
Logger.info("Already had #{params["id"]}")
+
e ->
# Just drop those for now
Logger.info("Unhandled activity")
- Logger.info(Poison.encode!(params, [pretty: 2]))
+ Logger.info(Poison.encode!(params, pretty: 2))
end
end
@@ -93,12 +109,21 @@ defmodule Pleroma.Web.Federator do
signature = @websub.sign(secret || "", xml)
Logger.debug(fn -> "Pushing #{topic} to #{callback}" end)
- with {:ok, %{status_code: code}} <- @httpoison.post(callback, xml, [
- {"Content-Type", "application/atom+xml"},
- {"X-Hub-Signature", "sha1=#{signature}"}
- ], timeout: 10000, recv_timeout: 20000, hackney: [pool: :default]) do
+ with {:ok, %{status_code: code}} <-
+ @httpoison.post(
+ callback,
+ xml,
+ [
+ {"Content-Type", "application/atom+xml"},
+ {"X-Hub-Signature", "sha1=#{signature}"}
+ ],
+ timeout: 10000,
+ recv_timeout: 20000,
+ hackney: [pool: :default]
+ ) do
Logger.debug(fn -> "Pushed to #{callback}, code #{code}" end)
- else e ->
+ else
+ e ->
Logger.debug(fn -> "Couldn't push to #{callback}, #{inspect(e)}" end)
end
end
@@ -110,7 +135,7 @@ defmodule Pleroma.Web.Federator do
def enqueue(type, payload, priority \\ 1) do
if @federating do
- if Mix.env == :test do
+ if Mix.env() == :test do
handle(type, payload)
else
GenServer.cast(__MODULE__, {:enqueue, type, payload, priority})
@@ -119,7 +144,7 @@ defmodule Pleroma.Web.Federator do
end
def maybe_start_job(running_jobs, queue) do
- if (:sets.size(running_jobs) < @max_jobs) && queue != [] do
+ if :sets.size(running_jobs) < @max_jobs && queue != [] do
{{type, payload}, queue} = queue_pop(queue)
{:ok, pid} = Task.start(fn -> handle(type, payload) end)
mref = Process.monitor(pid)
@@ -129,7 +154,8 @@ defmodule Pleroma.Web.Federator do
end
end
- def handle_cast({:enqueue, type, payload, priority}, state) when type in [:incoming_doc, :incoming_ap_doc] do
+ def handle_cast({:enqueue, type, payload, priority}, state)
+ when type in [:incoming_doc, :incoming_ap_doc] do
%{in: {i_running_jobs, i_queue}, out: {o_running_jobs, o_queue}} = state
i_queue = enqueue_sorted(i_queue, {type, payload}, 1)
{i_running_jobs, i_queue} = maybe_start_job(i_running_jobs, i_queue)
@@ -160,7 +186,7 @@ defmodule Pleroma.Web.Federator do
def enqueue_sorted(queue, element, priority) do
[%{item: element, priority: priority} | queue]
- |> Enum.sort_by(fn (%{priority: priority}) -> priority end)
+ |> Enum.sort_by(fn %{priority: priority} -> priority end)
end
def queue_pop([%{item: element} | queue]) do
@@ -169,6 +195,7 @@ defmodule Pleroma.Web.Federator do
def ap_enabled_actor(id) do
user = User.get_by_ap_id(id)
+
if User.ap_enabled?(user) do
{:ok, user}
else
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api.ex b/lib/pleroma/web/mastodon_api/mastodon_api.ex
index e69de29bb..8b1378917 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api.ex
@@ -0,0 +1 @@
+
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index 9428acd7e..58bb5e03a 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -11,8 +11,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
require Logger
def create_app(conn, params) do
- with cs <- App.register_changeset(%App{}, params) |> IO.inspect,
- {:ok, app} <- Repo.insert(cs) |> IO.inspect do
+ with cs <- App.register_changeset(%App{}, params) |> IO.inspect(),
+ {:ok, app} <- Repo.insert(cs) |> IO.inspect() do
res = %{
id: app.id,
client_id: app.client_id,
@@ -25,51 +25,57 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def update_credentials(%{assigns: %{user: user}} = conn, params) do
original_user = user
- params = if bio = params["note"] do
- Map.put(params, "bio", bio)
- else
- params
- end
- params = if name = params["display_name"] do
- Map.put(params, "name", name)
- else
- params
- end
+ params =
+ if bio = params["note"] do
+ Map.put(params, "bio", bio)
+ else
+ params
+ end
- user = if avatar = params["avatar"] do
- with %Plug.Upload{} <- avatar,
- {:ok, object} <- ActivityPub.upload(avatar),
- change = Ecto.Changeset.change(user, %{avatar: object.data}),
- {:ok, user} = User.update_and_set_cache(change) do
- user
+ params =
+ if name = params["display_name"] do
+ Map.put(params, "name", name)
else
- _e -> user
+ params
end
- else
- user
- end
- user = if banner = params["header"] do
- with %Plug.Upload{} <- banner,
- {:ok, object} <- ActivityPub.upload(banner),
- new_info <- Map.put(user.info, "banner", object.data),
- change <- User.info_changeset(user, %{info: new_info}),
- {:ok, user} <- User.update_and_set_cache(change) do
+ user =
+ if avatar = params["avatar"] do
+ with %Plug.Upload{} <- avatar,
+ {:ok, object} <- ActivityPub.upload(avatar),
+ change = Ecto.Changeset.change(user, %{avatar: object.data}),
+ {:ok, user} = User.update_and_set_cache(change) do
+ user
+ else
+ _e -> user
+ end
+ else
user
+ end
+
+ user =
+ if banner = params["header"] do
+ with %Plug.Upload{} <- banner,
+ {:ok, object} <- ActivityPub.upload(banner),
+ new_info <- Map.put(user.info, "banner", object.data),
+ change <- User.info_changeset(user, %{info: new_info}),
+ {:ok, user} <- User.update_and_set_cache(change) do
+ user
+ else
+ _e -> user
+ end
else
- _e -> user
+ user
end
- else
- user
- end
with changeset <- User.update_changeset(user, params),
{:ok, user} <- User.update_and_set_cache(changeset) do
if original_user != user do
CommonAPI.update(user)
end
- json conn, AccountView.render("account.json", %{user: user})
+
+ json(conn, AccountView.render("account.json", %{user: user}))
else
_e ->
conn
@@ -88,9 +94,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
account = AccountView.render("account.json", %{user: user})
json(conn, account)
else
- _e -> conn
- |> put_status(404)
- |> json(%{error: "Can't find user"})
+ _e ->
+ conn
+ |> put_status(404)
+ |> json(%{error: "Can't find user"})
end
end
@@ -98,16 +105,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def masto_instance(conn, _params) do
response = %{
- uri: Web.base_url,
+ uri: Web.base_url(),
title: Keyword.get(@instance, :name),
description: "A Pleroma instance, an alternative fediverse server",
version: Keyword.get(@instance, :version),
email: Keyword.get(@instance, :email),
urls: %{
- streaming_api: String.replace(Web.base_url, ["http","https"], "wss")
+ streaming_api: String.replace(Web.base_url(), ["http", "https"], "wss")
},
- stats: Stats.get_stats,
- thumbnail: Web.base_url <> "/instance/thumbnail.jpeg",
+ stats: Stats.get_stats(),
+ thumbnail: Web.base_url() <> "/instance/thumbnail.jpeg",
max_toot_chars: Keyword.get(@instance, :limit)
}
@@ -115,13 +122,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def peers(conn, _params) do
- json(conn, Stats.get_peers)
+ json(conn, Stats.get_peers())
end
defp mastodonized_emoji do
Pleroma.Formatter.get_custom_emoji()
|> Enum.map(fn {shortcode, relative_url} ->
- url = to_string URI.merge(Web.base_url(), relative_url)
+ url = to_string(URI.merge(Web.base_url(), relative_url))
+
%{
"shortcode" => shortcode,
"static_url" => url,
@@ -132,26 +140,30 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def custom_emojis(conn, _params) do
mastodon_emoji = mastodonized_emoji()
- json conn, mastodon_emoji
+ json(conn, mastodon_emoji)
end
defp add_link_headers(conn, method, activities, param \\ false) do
last = List.last(activities)
first = List.first(activities)
+
if last do
min = last.id
max = first.id
- {next_url, prev_url} = if param do
- {
- mastodon_api_url(Pleroma.Web.Endpoint, method, param, max_id: min),
- mastodon_api_url(Pleroma.Web.Endpoint, method, param, since_id: max)
- }
- else
- {
- mastodon_api_url(Pleroma.Web.Endpoint, method, max_id: min),
- mastodon_api_url(Pleroma.Web.Endpoint, method, since_id: max)
- }
- end
+
+ {next_url, prev_url} =
+ if param do
+ {
+ mastodon_api_url(Pleroma.Web.Endpoint, method, param, max_id: min),
+ mastodon_api_url(Pleroma.Web.Endpoint, method, param, since_id: max)
+ }
+ else
+ {
+ mastodon_api_url(Pleroma.Web.Endpoint, method, max_id: min),
+ mastodon_api_url(Pleroma.Web.Endpoint, method, since_id: max)
+ }
+ end
+
conn
|> put_resp_header("link", "<#{next_url}>; rel=\"next\", <#{prev_url}>; rel=\"prev\"")
else
@@ -160,13 +172,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def home_timeline(%{assigns: %{user: user}} = conn, params) do
- params = params
- |> Map.put("type", ["Create", "Announce"])
- |> Map.put("blocking_user", user)
- |> Map.put("user", user)
+ params =
+ params
+ |> Map.put("type", ["Create", "Announce"])
+ |> Map.put("blocking_user", user)
+ |> Map.put("user", user)
- activities = ActivityPub.fetch_activities([user.ap_id | user.following], params)
- |> Enum.reverse
+ activities =
+ ActivityPub.fetch_activities([user.ap_id | user.following], params)
+ |> Enum.reverse()
conn
|> add_link_headers(:home_timeline, activities)
@@ -174,13 +188,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def public_timeline(%{assigns: %{user: user}} = conn, params) do
- params = params
- |> Map.put("type", ["Create", "Announce"])
- |> Map.put("local_only", params["local"] in [true, "True", "true", "1"])
- |> Map.put("blocking_user", user)
+ params =
+ params
+ |> Map.put("type", ["Create", "Announce"])
+ |> Map.put("local_only", params["local"] in [true, "True", "true", "1"])
+ |> Map.put("blocking_user", user)
- activities = ActivityPub.fetch_public_activities(params)
- |> Enum.reverse
+ activities =
+ ActivityPub.fetch_public_activities(params)
+ |> Enum.reverse()
conn
|> add_link_headers(:public_timeline, activities)
@@ -189,13 +205,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def user_statuses(%{assigns: %{user: user}} = conn, params) do
with %User{ap_id: ap_id} <- Repo.get(User, params["id"]) do
- params = params
- |> Map.put("type", ["Create", "Announce"])
- |> Map.put("actor_id", ap_id)
- |> Map.put("whole_db", true)
+ params =
+ params
+ |> Map.put("type", ["Create", "Announce"])
+ |> Map.put("actor_id", ap_id)
+ |> Map.put("whole_db", true)
- activities = ActivityPub.fetch_public_activities(params)
- |> Enum.reverse
+ activities =
+ ActivityPub.fetch_public_activities(params)
+ |> Enum.reverse()
conn
|> add_link_headers(:user_statuses, activities, params["id"])
@@ -206,19 +224,39 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def get_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Repo.get(Activity, id),
true <- ActivityPub.visible_for_user?(activity, user) do
- render conn, StatusView, "status.json", %{activity: activity, for: user}
+ render(conn, StatusView, "status.json", %{activity: activity, for: user})
end
end
def get_context(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Repo.get(Activity, id),
- activities <- ActivityPub.fetch_activities_for_context(activity.data["context"], %{"blocking_user" => user, "user" => user}),
- activities <- activities |> Enum.filter(fn (%{id: aid}) -> to_string(aid) != to_string(id) end),
- activities <- activities |> Enum.filter(fn (%{data: %{"type" => type}}) -> type == "Create" end),
- grouped_activities <- Enum.group_by(activities, fn (%{id: id}) -> id < activity.id end) do
+ activities <-
+ ActivityPub.fetch_activities_for_context(activity.data["context"], %{
+ "blocking_user" => user,
+ "user" => user
+ }),
+ activities <-
+ activities |> Enum.filter(fn %{id: aid} -> to_string(aid) != to_string(id) end),
+ activities <-
+ activities |> Enum.filter(fn %{data: %{"type" => type}} -> type == "Create" end),
+ grouped_activities <- Enum.group_by(activities, fn %{id: id} -> id < activity.id end) do
result = %{
- ancestors: StatusView.render("index.json", for: user, activities: grouped_activities[true] || [], as: :activity) |> Enum.reverse,
- descendants: StatusView.render("index.json", for: user, activities: grouped_activities[false] || [], as: :activity) |> Enum.reverse,
+ ancestors:
+ StatusView.render(
+ "index.json",
+ for: user,
+ activities: grouped_activities[true] || [],
+ as: :activity
+ )
+ |> Enum.reverse(),
+ descendants:
+ StatusView.render(
+ "index.json",
+ for: user,
+ activities: grouped_activities[false] || [],
+ as: :activity
+ )
+ |> Enum.reverse()
}
json(conn, result)
@@ -226,12 +264,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def post_status(%{assigns: %{user: user}} = conn, %{"status" => _} = params) do
- params = params
- |> Map.put("in_reply_to_status_id", params["in_reply_to_id"])
- |> Map.put("no_attachment_links", true)
+ params =
+ params
+ |> Map.put("in_reply_to_status_id", params["in_reply_to_id"])
+ |> Map.put("no_attachment_links", true)
{:ok, activity} = CommonAPI.post(user, params)
- render conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}
+ render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity})
end
def delete_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
@@ -247,30 +286,32 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def reblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
with {:ok, announce, _activity} = CommonAPI.repeat(ap_id_or_id, user) do
- render conn, StatusView, "status.json", %{activity: announce, for: user, as: :activity}
+ render(conn, StatusView, "status.json", %{activity: announce, for: user, as: :activity})
end
end
def fav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
with {:ok, _fav, %{data: %{"id" => id}}} = CommonAPI.favorite(ap_id_or_id, user),
%Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
- render conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}
+ render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity})
end
end
def unfav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
with {:ok, %{data: %{"id" => id}}} = CommonAPI.unfavorite(ap_id_or_id, user),
%Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
- render conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity}
+ render(conn, StatusView, "status.json", %{activity: activity, for: user, as: :activity})
end
end
def notifications(%{assigns: %{user: user}} = conn, params) do
notifications = Notification.for_user(user, params)
- result = Enum.map(notifications, fn x ->
- render_notification(user, x)
- end)
- |> Enum.filter(&(&1))
+
+ result =
+ Enum.map(notifications, fn x ->
+ render_notification(user, x)
+ end)
+ |> Enum.filter(& &1)
conn
|> add_link_headers(:notifications, notifications)
@@ -306,27 +347,26 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def relationships(%{assigns: %{user: user}} = conn, %{"id" => id}) do
id = List.wrap(id)
- q = from u in User,
- where: u.id in ^id
+ q = from(u in User, where: u.id in ^id)
targets = Repo.all(q)
- render conn, AccountView, "relationships.json", %{user: user, targets: targets}
+ render(conn, AccountView, "relationships.json", %{user: user, targets: targets})
end
def upload(%{assigns: %{user: _}} = conn, %{"file" => file}) do
with {:ok, object} <- ActivityPub.upload(file) do
- data = object.data
- |> Map.put("id", object.id)
+ data =
+ object.data
+ |> Map.put("id", object.id)
- render conn, StatusView, "attachment.json", %{attachment: data}
+ render(conn, StatusView, "attachment.json", %{attachment: data})
end
end
def favourited_by(conn, %{"id" => id}) do
with %Activity{data: %{"object" => %{"likes" => likes}}} <- Repo.get(Activity, id) do
- q = from u in User,
- where: u.ap_id in ^likes
+ q = from(u in User, where: u.ap_id in ^likes)
users = Repo.all(q)
- render conn, AccountView, "accounts.json", %{users: users, as: :user}
+ render(conn, AccountView, "accounts.json", %{users: users, as: :user})
else
_ -> json(conn, [])
end
@@ -334,23 +374,24 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def reblogged_by(conn, %{"id" => id}) do
with %Activity{data: %{"object" => %{"announcements" => announces}}} <- Repo.get(Activity, id) do
- q = from u in User,
- where: u.ap_id in ^announces
+ q = from(u in User, where: u.ap_id in ^announces)
users = Repo.all(q)
- render conn, AccountView, "accounts.json", %{users: users, as: :user}
+ render(conn, AccountView, "accounts.json", %{users: users, as: :user})
else
_ -> json(conn, [])
end
end
def hashtag_timeline(%{assigns: %{user: user}} = conn, params) do
- params = params
- |> Map.put("type", "Create")
- |> Map.put("local_only", !!params["local"])
- |> Map.put("blocking_user", user)
+ params =
+ params
+ |> Map.put("type", "Create")
+ |> Map.put("local_only", !!params["local"])
+ |> Map.put("blocking_user", user)
- activities = ActivityPub.fetch_public_activities(params)
- |> Enum.reverse
+ activities =
+ ActivityPub.fetch_public_activities(params)
+ |> Enum.reverse()
conn
|> add_link_headers(:hashtag_timeline, activities, params["tag"])
@@ -361,14 +402,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def followers(conn, %{"id" => id}) do
with %User{} = user <- Repo.get(User, id),
{:ok, followers} <- User.get_followers(user) do
- render conn, AccountView, "accounts.json", %{users: followers, as: :user}
+ render(conn, AccountView, "accounts.json", %{users: followers, as: :user})
end
end
def following(conn, %{"id" => id}) do
with %User{} = user <- Repo.get(User, id),
{:ok, followers} <- User.get_friends(user) do
- render conn, AccountView, "accounts.json", %{users: followers, as: :user}
+ render(conn, AccountView, "accounts.json", %{users: followers, as: :user})
end
end
@@ -376,7 +417,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
with %User{} = followed <- Repo.get(User, id),
{:ok, follower} <- User.follow(follower, followed),
{:ok, _activity} <- ActivityPub.follow(follower, followed) do
- render conn, AccountView, "relationship.json", %{user: follower, target: followed}
+ render(conn, AccountView, "relationship.json", %{user: follower, target: followed})
else
{:error, message} ->
conn
@@ -389,7 +430,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
with %User{} = followed <- Repo.get_by(User, nickname: uri),
{:ok, follower} <- User.follow(follower, followed),
{:ok, _activity} <- ActivityPub.follow(follower, followed) do
- render conn, AccountView, "account.json", %{user: followed}
+ render(conn, AccountView, "account.json", %{user: followed})
else
{:error, message} ->
conn
@@ -401,20 +442,22 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
# TODO: Clean up and unify
def unfollow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
with %User{} = followed <- Repo.get(User, id),
- { :ok, follower, follow_activity } <- User.unfollow(follower, followed),
- { :ok, _activity } <- ActivityPub.insert(%{
- "type" => "Undo",
- "actor" => follower.ap_id,
- "object" => follow_activity.data["id"] # get latest Follow for these users
- }) do
- render conn, AccountView, "relationship.json", %{user: follower, target: followed}
+ {:ok, follower, follow_activity} <- User.unfollow(follower, followed),
+ {:ok, _activity} <-
+ ActivityPub.insert(%{
+ "type" => "Undo",
+ "actor" => follower.ap_id,
+ # get latest Follow for these users
+ "object" => follow_activity.data["id"]
+ }) do
+ render(conn, AccountView, "relationship.json", %{user: follower, target: followed})
end
end
def block(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
with %User{} = blocked <- Repo.get(User, id),
{:ok, blocker} <- User.block(blocker, blocked) do
- render conn, AccountView, "relationship.json", %{user: blocker, target: blocked}
+ render(conn, AccountView, "relationship.json", %{user: blocker, target: blocked})
else
{:error, message} ->
conn
@@ -426,7 +469,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def unblock(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
with %User{} = blocked <- Repo.get(User, id),
{:ok, blocker} <- User.unblock(blocker, blocked) do
- render conn, AccountView, "relationship.json", %{user: blocker, target: blocked}
+ render(conn, AccountView, "relationship.json", %{user: blocker, target: blocked})
else
{:error, message} ->
conn
@@ -438,7 +481,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
# TODO: Use proper query
def blocks(%{assigns: %{user: user}} = conn, _) do
with blocked_users <- user.info["blocks"] || [],
- accounts <- Enum.map(blocked_users, fn (ap_id) -> User.get_cached_by_ap_id(ap_id) end) do
+ accounts <- Enum.map(blocked_users, fn ap_id -> User.get_cached_by_ap_id(ap_id) end) do
res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)
json(conn, res)
end
@@ -447,23 +490,34 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
accounts = User.search(query, params["resolve"] == "true")
- fetched = if Regex.match?(~r/https?:/, query) do
- with {:ok, activities} <- OStatus.fetch_activity_from_url(query) do
- activities
- else
- _e -> []
- end
- end || []
+ fetched =
+ if Regex.match?(~r/https?:/, query) do
+ with {:ok, activities} <- OStatus.fetch_activity_from_url(query) do
+ activities
+ else
+ _e -> []
+ end
+ end || []
+
+ q =
+ from(
+ a in Activity,
+ where: fragment("?->>'type' = 'Create'", a.data),
+ where:
+ fragment(
+ "to_tsvector('english', ?->'object'->>'content') @@ plainto_tsquery('english', ?)",
+ a.data,
+ ^query
+ ),
+ limit: 20
+ )
- q = from a in Activity,
- where: fragment("?->>'type' = 'Create'", a.data),
- where: fragment("to_tsvector('english', ?->'object'->>'content') @@ plainto_tsquery('english', ?)", a.data, ^query),
- limit: 20
statuses = Repo.all(q) ++ fetched
res = %{
"accounts" => AccountView.render("accounts.json", users: accounts, for: user, as: :user),
- "statuses" => StatusView.render("index.json", activities: statuses, for: user, as: :activity),
+ "statuses" =>
+ StatusView.render("index.json", activities: statuses, for: user, as: :activity),
"hashtags" => []
}
@@ -479,94 +533,102 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def favourites(%{assigns: %{user: user}} = conn, _) do
- params = %{}
- |> Map.put("type", "Create")
- |> Map.put("favorited_by", user.ap_id)
- |> Map.put("blocking_user", user)
+ params =
+ %{}
+ |> Map.put("type", "Create")
+ |> Map.put("favorited_by", user.ap_id)
+ |> Map.put("blocking_user", user)
- activities = ActivityPub.fetch_public_activities(params)
- |> Enum.reverse
+ activities =
+ ActivityPub.fetch_public_activities(params)
+ |> Enum.reverse()
conn
|> render(StatusView, "index.json", %{activities: activities, for: user, as: :activity})
end
def index(%{assigns: %{user: user}} = conn, _params) do
- token = conn
- |> get_session(:oauth_token)
+ token =
+ conn
+ |> get_session(:oauth_token)
if user && token do
mastodon_emoji = mastodonized_emoji()
accounts = Map.put(%{}, user.id, AccountView.render("account.json", %{user: user}))
- initial_state = %{
- meta: %{
- streaming_api_base_url: String.replace(Pleroma.Web.Endpoint.static_url(), "http", "ws"),
- access_token: token,
- locale: "en",
- domain: Pleroma.Web.Endpoint.host(),
- admin: "1",
- me: "#{user.id}",
- unfollow_modal: false,
- boost_modal: false,
- delete_modal: true,
- auto_play_gif: false,
- reduce_motion: false
- },
- compose: %{
- me: "#{user.id}",
- default_privacy: "public",
- default_sensitive: false
- },
- media_attachments: %{
- accept_content_types: [
- ".jpg",
- ".jpeg",
- ".png",
- ".gif",
- ".webm",
- ".mp4",
- ".m4v",
- "image\/jpeg",
- "image\/png",
- "image\/gif",
- "video\/webm",
- "video\/mp4"
- ]
- },
- settings: %{
- onboarded: true,
- home: %{
- shows: %{
- reblog: true,
- reply: true
- }
+
+ initial_state =
+ %{
+ meta: %{
+ streaming_api_base_url:
+ String.replace(Pleroma.Web.Endpoint.static_url(), "http", "ws"),
+ access_token: token,
+ locale: "en",
+ domain: Pleroma.Web.Endpoint.host(),
+ admin: "1",
+ me: "#{user.id}",
+ unfollow_modal: false,
+ boost_modal: false,
+ delete_modal: true,
+ auto_play_gif: false,
+ reduce_motion: false
},
- notifications: %{
- alerts: %{
- follow: true,
- favourite: true,
- reblog: true,
- mention: true
- },
- shows: %{
- follow: true,
- favourite: true,
- reblog: true,
- mention: true
+ compose: %{
+ me: "#{user.id}",
+ default_privacy: "public",
+ default_sensitive: false
+ },
+ media_attachments: %{
+ accept_content_types: [
+ ".jpg",
+ ".jpeg",
+ ".png",
+ ".gif",
+ ".webm",
+ ".mp4",
+ ".m4v",
+ "image\/jpeg",
+ "image\/png",
+ "image\/gif",
+ "video\/webm",
+ "video\/mp4"
+ ]
+ },
+ settings: %{
+ onboarded: true,
+ home: %{
+ shows: %{
+ reblog: true,
+ reply: true
+ }
},
- sounds: %{
- follow: true,
- favourite: true,
- reblog: true,
- mention: true
+ notifications: %{
+ alerts: %{
+ follow: true,
+ favourite: true,
+ reblog: true,
+ mention: true
+ },
+ shows: %{
+ follow: true,
+ favourite: true,
+ reblog: true,
+ mention: true
+ },
+ sounds: %{
+ follow: true,
+ favourite: true,
+ reblog: true,
+ mention: true
+ }
}
- }
- },
- push_subscription: nil,
- accounts: accounts,
- custom_emojis: mastodon_emoji,
- char_limit: Keyword.get(@instance, :limit)
- } |> Jason.encode!
+ },
+ push_subscription: nil,
+ accounts: accounts,
+ custom_emojis: mastodon_emoji,
+ char_limit: Keyword.get(@instance, :limit)
+ }
+ |> Jason.encode!()
+
conn
|> put_layout(false)
|> render(MastodonView, "index.html", %{initial_state: initial_state})
@@ -586,12 +648,18 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
{:ok, app}
else
_e ->
- cs = App.register_changeset(%App{}, %{client_name: "Mastodon-Local", redirect_uris: ".", scopes: "read,write,follow"})
+ cs =
+ App.register_changeset(%App{}, %{
+ client_name: "Mastodon-Local",
+ redirect_uris: ".",
+ scopes: "read,write,follow"
+ })
+
Repo.insert(cs)
end
end
- def login_post(conn, %{"authorization" => %{ "name" => name, "password" => password}}) do
+ def login_post(conn, %{"authorization" => %{"name" => name, "password" => password}}) do
with %User{} = user <- User.get_cached_by_nickname(name),
true <- Pbkdf2.checkpw(password, user.password_hash),
{:ok, app} <- get_or_make_app(),
@@ -615,8 +683,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def relationship_noop(%{assigns: %{user: user}} = conn, %{"id" => id}) do
Logger.debug("Unimplemented, returning unmodified relationship")
+
with %User{} = target <- Repo.get(User, id) do
- render conn, AccountView, "relationship.json", %{user: user, target: target}
+ render(conn, AccountView, "relationship.json", %{user: user, target: target})
end
end
@@ -632,20 +701,53 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def render_notification(user, %{id: id, activity: activity, inserted_at: created_at} = _params) do
actor = User.get_cached_by_ap_id(activity.data["actor"])
- created_at = NaiveDateTime.to_iso8601(created_at)
- |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
+
+ created_at =
+ NaiveDateTime.to_iso8601(created_at)
+ |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false)
+
case activity.data["type"] do
"Create" ->
- %{id: id, type: "mention", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: activity, for: user})}
+ %{
+ id: id,
+ type: "mention",
+ created_at: created_at,
+ account: AccountView.render("account.json", %{user: actor}),
+ status: StatusView.render("status.json", %{activity: activity, for: user})
+ }
+
"Like" ->
liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
- %{id: id, type: "favourite", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: liked_activity, for: user})}
+
+ %{
+ id: id,
+ type: "favourite",
+ created_at: created_at,
+ account: AccountView.render("account.json", %{user: actor}),
+ status: StatusView.render("status.json", %{activity: liked_activity, for: user})
+ }
+
"Announce" ->
announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
- %{id: id, type: "reblog", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: announced_activity, for: user})}
+
+ %{
+ id: id,
+ type: "reblog",
+ created_at: created_at,
+ account: AccountView.render("account.json", %{user: actor}),
+ status: StatusView.render("status.json", %{activity: announced_activity, for: user})
+ }
+
"Follow" ->
- %{id: id, type: "follow", created_at: created_at, account: AccountView.render("account.json", %{user: actor})}
- _ -> nil
+ %{
+ id: id,
+ type: "follow",
+ created_at: created_at,
+ account: AccountView.render("account.json", %{user: actor})
+ }
+
+ _ ->
+ nil
end
end
end
diff --git a/lib/pleroma/web/mastodon_api/mastodon_socket.ex b/lib/pleroma/web/mastodon_api/mastodon_socket.ex
index c3bae5935..f3e062941 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_socket.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_socket.ex
@@ -4,17 +4,23 @@ defmodule Pleroma.Web.MastodonAPI.MastodonSocket do
alias Pleroma.Web.OAuth.Token
alias Pleroma.{User, Repo}
- transport :streaming, Phoenix.Transports.WebSocket.Raw,
- timeout: :infinity # We never receive data.
+ transport(
+ :streaming,
+ Phoenix.Transports.WebSocket.Raw,
+ # We never receive data.
+ timeout: :infinity
+ )
def connect(params, socket) do
with token when not is_nil(token) <- params["access_token"],
%Token{user_id: user_id} <- Repo.get_by(Token, token: token),
%User{} = user <- Repo.get(User, user_id),
stream when stream in ["public", "public:local", "user"] <- params["stream"] do
- socket = socket
- |> assign(:topic, params["stream"])
- |> assign(:user, user)
+ socket =
+ socket
+ |> assign(:topic, params["stream"])
+ |> assign(:user, user)
+
Pleroma.Web.Streamer.add_socket(params["stream"], socket)
{:ok, socket}
else
@@ -25,11 +31,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonSocket do
def id(_), do: nil
def handle(:text, message, _state) do
- #| :ok
- #| state
- #| {:text, message}
- #| {:text, message, state}
- #| {:close, "Goodbye!"}
+ # | :ok
+ # | state
+ # | {:text, message}
+ # | {:text, message, state}
+ # | {:close, "Goodbye!"}
{:text, message}
end
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index a4539d47e..bc5ae5da7 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -10,37 +10,52 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
defp get_replied_to_activities(activities) do
activities
|> Enum.map(fn
- (%{data: %{"type" => "Create", "object" => %{"inReplyTo" => inReplyTo}}}) ->
- (inReplyTo != "") && inReplyTo
- _ -> nil
+ %{data: %{"type" => "Create", "object" => %{"inReplyTo" => inReplyTo}}} ->
+ inReplyTo != "" && inReplyTo
+
+ _ ->
+ nil
end)
- |> Enum.filter(&(&1))
+ |> Enum.filter(& &1)
|> Activity.create_activity_by_object_id_query()
- |> Repo.all
- |> Enum.reduce(%{}, fn(activity, acc) -> Map.put(acc,activity.data["object"]["id"], activity) end)
+ |> Repo.all()
+ |> Enum.reduce(%{}, fn activity, acc ->
+ Map.put(acc, activity.data["object"]["id"], activity)
+ end)
end
def render("index.json", opts) do
replied_to_activities = get_replied_to_activities(opts.activities)
- render_many(opts.activities, StatusView, "status.json", Map.put(opts, :replied_to_activities, replied_to_activities))
+
+ render_many(
+ opts.activities,
+ StatusView,
+ "status.json",
+ Map.put(opts, :replied_to_activities, replied_to_activities)
+ )
end
- def render("status.json", %{activity: %{data: %{"type" => "Announce", "object" => object}} = activity} = opts) do
+ def render(
+ "status.json",
+ %{activity: %{data: %{"type" => "Announce", "object" => object}} = activity} = opts
+ ) do
user = User.get_cached_by_ap_id(activity.data["actor"])
created_at = Utils.to_masto_date(activity.data["published"])
reblogged = Activity.get_create_activity_by_object_ap_id(object)
reblogged = render("status.json", Map.put(opts, :activity, reblogged))
- mentions = activity.recipients
- |> Enum.map(fn (ap_id) -> User.get_cached_by_ap_id(ap_id) end)
- |> Enum.filter(&(&1))
- |> Enum.map(fn (user) -> AccountView.render("mention.json", %{user: user}) end)
+ mentions =
+ activity.recipients
+ |> Enum.map(fn ap_id -> User.get_cached_by_ap_id(ap_id) end)
+ |> Enum.filter(& &1)
+ |> Enum.map(fn user -> AccountView.render("mention.json", %{user: user}) end)
%{
id: to_string(activity.id),
uri: object,
- url: nil, # TODO: This might be wrong, check with mastodon.
+ # TODO: This might be wrong, check with mastodon.
+ url: nil,
account: AccountView.render("account.json", %{user: user}),
in_reply_to_id: nil,
in_reply_to_account_id: nil,
@@ -89,27 +104,30 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
tags = object["tag"] || []
sensitive = object["sensitive"] || Enum.member?(tags, "nsfw")
- mentions = activity.recipients
- |> Enum.map(fn (ap_id) -> User.get_cached_by_ap_id(ap_id) end)
- |> Enum.filter(&(&1))
- |> Enum.map(fn (user) -> AccountView.render("mention.json", %{user: user}) end)
+ mentions =
+ activity.recipients
+ |> Enum.map(fn ap_id -> User.get_cached_by_ap_id(ap_id) end)
+ |> Enum.filter(& &1)
+ |> Enum.map(fn user -> AccountView.render("mention.json", %{user: user}) end)
repeated = opts[:for] && opts[:for].ap_id in (object["announcements"] || [])
favorited = opts[:for] && opts[:for].ap_id in (object["likes"] || [])
- attachments = render_many(object["attachment"] || [], StatusView, "attachment.json", as: :attachment)
+ attachments =
+ render_many(object["attachment"] || [], StatusView, "attachment.json", as: :attachment)
created_at = Utils.to_masto_date(object["published"])
reply_to = get_reply_to(activity, opts)
reply_to_user = reply_to && User.get_cached_by_ap_id(reply_to.data["actor"])
- emojis = (activity.data["object"]["emoji"] || [])
- |> Enum.map(fn {name, url} ->
- name = HtmlSanitizeEx.strip_tags(name)
- url = HtmlSanitizeEx.strip_tags(url)
- %{ shortcode: name, url: url, static_url: url }
- end)
+ emojis =
+ (activity.data["object"]["emoji"] || [])
+ |> Enum.map(fn {name, url} ->
+ name = HtmlSanitizeEx.strip_tags(name)
+ url = HtmlSanitizeEx.strip_tags(url)
+ %{shortcode: name, url: url, static_url: url}
+ end)
%{
id: to_string(activity.id),
@@ -131,7 +149,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
visibility: get_visibility(object),
media_attachments: attachments |> Enum.take(4),
mentions: mentions,
- tags: [], # fix,
+ # fix,
+ tags: [],
application: %{
name: "Web",
website: nil
@@ -145,10 +164,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
public = "https://www.w3.org/ns/activitystreams#Public"
to = object["to"] || []
cc = object["cc"] || []
+
cond do
public in to -> "public"
public in cc -> "unlisted"
- Enum.any?(to, &(String.contains?(&1, "/followers"))) -> "private"
+ Enum.any?(to, &String.contains?(&1, "/followers")) -> "private"
true -> "direct"
end
end
@@ -156,14 +176,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
def render("attachment.json", %{attachment: attachment}) do
[%{"mediaType" => media_type, "href" => href} | _] = attachment["url"]
- type = cond do
- String.contains?(media_type, "image") -> "image"
- String.contains?(media_type, "video") -> "video"
- String.contains?(media_type, "audio") -> "audio"
- true -> "unknown"
- end
+ type =
+ cond do
+ String.contains?(media_type, "image") -> "image"
+ String.contains?(media_type, "video") -> "video"
+ String.contains?(media_type, "audio") -> "audio"
+ true -> "unknown"
+ end
- << hash_id::signed-32, _rest::binary >> = :crypto.hash(:md5, href)
+ <<hash_id::signed-32, _rest::binary>> = :crypto.hash(:md5, href)
%{
id: to_string(attachment["id"] || hash_id),
diff --git a/lib/pleroma/web/media_proxy/controller.ex b/lib/pleroma/web/media_proxy/controller.ex
index b0bbe8b64..8195a665e 100644
--- a/lib/pleroma/web/media_proxy/controller.ex
+++ b/lib/pleroma/web/media_proxy/controller.ex
@@ -4,47 +4,59 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
@httpoison Application.get_env(:pleroma, :httpoison)
- @max_body_length 25 * 1048576
+ @max_body_length 25 * 1_048_576
@cache_control %{
default: "public, max-age=1209600",
- error: "public, must-revalidate, max-age=160",
+ error: "public, must-revalidate, max-age=160"
}
def remote(conn, %{"sig" => sig, "url" => url}) do
config = Application.get_env(:pleroma, :media_proxy, [])
- with \
- true <- Keyword.get(config, :enabled, false),
- {:ok, url} <- Pleroma.Web.MediaProxy.decode_url(sig, url),
- {:ok, content_type, body} <- proxy_request(url)
- do
+
+ with true <- Keyword.get(config, :enabled, false),
+ {:ok, url} <- Pleroma.Web.MediaProxy.decode_url(sig, url),
+ {:ok, content_type, body} <- proxy_request(url) do
conn
|> put_resp_content_type(content_type)
|> set_cache_header(:default)
|> send_resp(200, body)
else
- false -> send_error(conn, 404)
- {:error, :invalid_signature} -> send_error(conn, 403)
- {:error, {:http, _, url}} -> redirect_or_error(conn, url, Keyword.get(config, :redirect_on_failure, true))
+ false ->
+ send_error(conn, 404)
+
+ {:error, :invalid_signature} ->
+ send_error(conn, 403)
+
+ {:error, {:http, _, url}} ->
+ redirect_or_error(conn, url, Keyword.get(config, :redirect_on_failure, true))
end
end
defp proxy_request(link) do
- headers = [{"user-agent", "Pleroma/MediaProxy; #{Pleroma.Web.base_url()} <#{Application.get_env(:pleroma, :instance)[:email]}>"}]
- options = @httpoison.process_request_options([:insecure, {:follow_redirect, true}]) ++ [{:pool, :default}]
- with \
- {:ok, 200, headers, client} <- :hackney.request(:get, link, headers, "", options),
- headers = Enum.into(headers, Map.new),
- {:ok, body} <- proxy_request_body(client),
- content_type <- proxy_request_content_type(headers, body)
- do
+ headers = [
+ {"user-agent",
+ "Pleroma/MediaProxy; #{Pleroma.Web.base_url()} <#{
+ Application.get_env(:pleroma, :instance)[:email]
+ }>"}
+ ]
+
+ options =
+ @httpoison.process_request_options([:insecure, {:follow_redirect, true}]) ++
+ [{:pool, :default}]
+
+ with {:ok, 200, headers, client} <- :hackney.request(:get, link, headers, "", options),
+ headers = Enum.into(headers, Map.new()),
+ {:ok, body} <- proxy_request_body(client),
+ content_type <- proxy_request_content_type(headers, body) do
{:ok, content_type, body}
else
{:ok, status, _, _} ->
- Logger.warn "MediaProxy: request failed, status #{status}, link: #{link}"
+ Logger.warn("MediaProxy: request failed, status #{status}, link: #{link}")
{:error, {:http, :bad_status, link}}
+
{:error, error} ->
- Logger.warn "MediaProxy: request failed, error #{inspect error}, link: #{link}"
+ Logger.warn("MediaProxy: request failed, error #{inspect(error)}, link: #{link}")
{:error, {:http, error, link}}
end
end
@@ -63,13 +75,15 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
end
defp proxy_request_body(client), do: proxy_request_body(client, <<>>)
+
defp proxy_request_body(client, body) when byte_size(body) < @max_body_length do
case :hackney.stream_body(client) do
- {:ok, data} -> proxy_request_body(client, <<body :: binary, data :: binary>>)
+ {:ok, data} -> proxy_request_body(client, <<body::binary, data::binary>>)
:done -> {:ok, body}
{:error, reason} -> {:error, reason}
end
end
+
defp proxy_request_body(client, _) do
:hackney.close(client)
{:error, :body_too_large}
@@ -80,5 +94,4 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do
defp proxy_request_content_type(headers, _body) do
headers["Content-Type"] || headers["content-type"] || "image/jpeg"
end
-
end
diff --git a/lib/pleroma/web/media_proxy/media_proxy.ex b/lib/pleroma/web/media_proxy/media_proxy.ex
index 23efc18fa..37718f48b 100644
--- a/lib/pleroma/web/media_proxy/media_proxy.ex
+++ b/lib/pleroma/web/media_proxy/media_proxy.ex
@@ -7,14 +7,15 @@ defmodule Pleroma.Web.MediaProxy do
def url(url) do
config = Application.get_env(:pleroma, :media_proxy, [])
- if !Keyword.get(config, :enabled, false) or String.starts_with?(url, Pleroma.Web.base_url) do
+
+ if !Keyword.get(config, :enabled, false) or String.starts_with?(url, Pleroma.Web.base_url()) do
url
else
secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base]
base64 = Base.url_encode64(url, @base64_opts)
sig = :crypto.hmac(:sha, secret, base64)
sig64 = sig |> Base.url_encode64(@base64_opts)
- Keyword.get(config, :base_url, Pleroma.Web.base_url) <> "/proxy/#{sig64}/#{base64}"
+ Keyword.get(config, :base_url, Pleroma.Web.base_url()) <> "/proxy/#{sig64}/#{base64}"
end
end
@@ -22,11 +23,11 @@ defmodule Pleroma.Web.MediaProxy do
secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base]
sig = Base.url_decode64!(sig, @base64_opts)
local_sig = :crypto.hmac(:sha, secret, url)
+
if local_sig == sig do
{:ok, Base.url_decode64!(url, @base64_opts)}
else
{:error, :invalid_signature}
end
end
-
end
diff --git a/lib/pleroma/web/oauth/app.ex b/lib/pleroma/web/oauth/app.ex
index ff52ba82e..b3273bc6e 100644
--- a/lib/pleroma/web/oauth/app.ex
+++ b/lib/pleroma/web/oauth/app.ex
@@ -3,25 +3,26 @@ defmodule Pleroma.Web.OAuth.App do
import Ecto.{Changeset}
schema "apps" do
- field :client_name, :string
- field :redirect_uris, :string
- field :scopes, :string
- field :website, :string
- field :client_id, :string
- field :client_secret, :string
+ field(:client_name, :string)
+ field(:redirect_uris, :string)
+ field(:scopes, :string)
+ field(:website, :string)
+ field(:client_id, :string)
+ field(:client_secret, :string)
timestamps()
end
def register_changeset(struct, params \\ %{}) do
- changeset = struct
- |> cast(params, [:client_name, :redirect_uris, :scopes, :website])
- |> validate_required([:client_name, :redirect_uris, :scopes])
+ changeset =
+ struct
+ |> cast(params, [:client_name, :redirect_uris, :scopes, :website])
+ |> validate_required([:client_name, :redirect_uris, :scopes])
if changeset.valid? do
changeset
- |> put_change(:client_id, :crypto.strong_rand_bytes(32) |> Base.url_encode64)
- |> put_change(:client_secret, :crypto.strong_rand_bytes(32) |> Base.url_encode64)
+ |> put_change(:client_id, :crypto.strong_rand_bytes(32) |> Base.url_encode64())
+ |> put_change(:client_secret, :crypto.strong_rand_bytes(32) |> Base.url_encode64())
else
changeset
end
diff --git a/lib/pleroma/web/oauth/authorization.ex b/lib/pleroma/web/oauth/authorization.ex
index 1ba5be602..94f44c9f2 100644
--- a/lib/pleroma/web/oauth/authorization.ex
+++ b/lib/pleroma/web/oauth/authorization.ex
@@ -7,24 +7,24 @@ defmodule Pleroma.Web.OAuth.Authorization do
import Ecto.{Changeset}
schema "oauth_authorizations" do
- field :token, :string
- field :valid_until, :naive_datetime
- field :used, :boolean, default: false
- belongs_to :user, Pleroma.User
- belongs_to :app, Pleroma.App
+ field(:token, :string)
+ field(:valid_until, :naive_datetime)
+ field(:used, :boolean, default: false)
+ belongs_to(:user, Pleroma.User)
+ belongs_to(:app, Pleroma.App)
timestamps()
end
def create_authorization(%App{} = app, %User{} = user) do
- token = :crypto.strong_rand_bytes(32) |> Base.url_encode64
+ token = :crypto.strong_rand_bytes(32) |> Base.url_encode64()
authorization = %Authorization{
token: token,
used: false,
user_id: user.id,
app_id: app.id,
- valid_until: NaiveDateTime.add(NaiveDateTime.utc_now, 60 * 10)
+ valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 60 * 10)
}
Repo.insert(authorization)
@@ -37,11 +37,12 @@ defmodule Pleroma.Web.OAuth.Authorization do
end
def use_token(%Authorization{used: false, valid_until: valid_until} = auth) do
- if NaiveDateTime.diff(NaiveDateTime.utc_now, valid_until) < 0 do
+ if NaiveDateTime.diff(NaiveDateTime.utc_now(), valid_until) < 0 do
Repo.update(use_changeset(auth, %{used: true}))
else
{:error, "token expired"}
end
end
+
def use_token(%Authorization{used: true}), do: {:error, "already used"}
end
diff --git a/lib/pleroma/web/oauth/fallback_controller.ex b/lib/pleroma/web/oauth/fallback_controller.ex
index daa110532..3927cdb64 100644
--- a/lib/pleroma/web/oauth/fallback_controller.ex
+++ b/lib/pleroma/web/oauth/fallback_controller.ex
@@ -1,12 +1,11 @@
defmodule Pleroma.Web.OAuth.FallbackController do
- use Pleroma.Web, :controller
- alias Pleroma.Web.OAuth.OAuthController
+ use Pleroma.Web, :controller
+ alias Pleroma.Web.OAuth.OAuthController
- # No user/password
- def call(conn, _) do
- conn
- |> put_flash(:error, "Invalid Username/Password")
- |> OAuthController.authorize(conn.params)
- end
-
-end \ No newline at end of file
+ # No user/password
+ def call(conn, _) do
+ conn
+ |> put_flash(:error, "Invalid Username/Password")
+ |> OAuthController.authorize(conn.params)
+ end
+end
diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex
index cebc18252..05f366611 100644
--- a/lib/pleroma/web/oauth/oauth_controller.ex
+++ b/lib/pleroma/web/oauth/oauth_controller.ex
@@ -5,38 +5,49 @@ defmodule Pleroma.Web.OAuth.OAuthController do
alias Pleroma.{Repo, User}
alias Comeonin.Pbkdf2
- plug :fetch_session
- plug :fetch_flash
+ plug(:fetch_session)
+ plug(:fetch_flash)
- action_fallback Pleroma.Web.OAuth.FallbackController
+ action_fallback(Pleroma.Web.OAuth.FallbackController)
def authorize(conn, params) do
- render conn, "show.html", %{
+ render(conn, "show.html", %{
response_type: params["response_type"],
client_id: params["client_id"],
scope: params["scope"],
redirect_uri: params["redirect_uri"],
state: params["state"]
- }
+ })
end
- def create_authorization(conn, %{"authorization" => %{"name" => name, "password" => password, "client_id" => client_id, "redirect_uri" => redirect_uri} = params}) do
+ def create_authorization(conn, %{
+ "authorization" =>
+ %{
+ "name" => name,
+ "password" => password,
+ "client_id" => client_id,
+ "redirect_uri" => redirect_uri
+ } = params
+ }) do
with %User{} = user <- User.get_cached_by_nickname(name),
true <- Pbkdf2.checkpw(password, user.password_hash),
%App{} = app <- Repo.get_by(App, client_id: client_id),
{:ok, auth} <- Authorization.create_authorization(app, user) do
if redirect_uri == "urn:ietf:wg:oauth:2.0:oob" do
- render conn, "results.html", %{
+ render(conn, "results.html", %{
auth: auth
- }
+ })
else
connector = if String.contains?(redirect_uri, "?"), do: "&", else: "?"
url = "#{redirect_uri}#{connector}code=#{auth.token}"
- url = if params["state"] do
- url <> "&state=#{params["state"]}"
- else
- url
- end
+
+ url =
+ if params["state"] do
+ url <> "&state=#{params["state"]}"
+ else
+ url
+ end
+
redirect(conn, external: url)
end
end
@@ -45,7 +56,12 @@ defmodule Pleroma.Web.OAuth.OAuthController do
# TODO
# - proper scope handling
def token_exchange(conn, %{"grant_type" => "authorization_code"} = params) do
- with %App{} = app <- Repo.get_by(App, client_id: params["client_id"], client_secret: params["client_secret"]),
+ with %App{} = app <-
+ Repo.get_by(
+ App,
+ client_id: params["client_id"],
+ client_secret: params["client_secret"]
+ ),
fixed_token = fix_padding(params["code"]),
%Authorization{} = auth <- Repo.get_by(Authorization, token: fixed_token, app_id: app.id),
{:ok, token} <- Token.exchange_token(app, auth) do
@@ -56,6 +72,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
expires_in: 60 * 10,
scope: "read write follow"
}
+
json(conn, response)
else
_error -> json(conn, %{error: "Invalid credentials"})
@@ -64,8 +81,16 @@ defmodule Pleroma.Web.OAuth.OAuthController do
# TODO
# - investigate a way to verify the user wants to grant read/write/follow once scope handling is done
- def token_exchange(conn, %{"grant_type" => "password", "name" => name, "password" => password} = params) do
- with %App{} = app <- Repo.get_by(App, client_id: params["client_id"], client_secret: params["client_secret"]),
+ def token_exchange(
+ conn,
+ %{"grant_type" => "password", "name" => name, "password" => password} = params
+ ) do
+ with %App{} = app <-
+ Repo.get_by(
+ App,
+ client_id: params["client_id"],
+ client_secret: params["client_secret"]
+ ),
%User{} = user <- User.get_cached_by_nickname(name),
true <- Pbkdf2.checkpw(password, user.password_hash),
{:ok, auth} <- Authorization.create_authorization(app, user),
@@ -77,6 +102,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
expires_in: 60 * 10,
scope: "read write follow"
}
+
json(conn, response)
else
_error -> json(conn, %{error: "Invalid credentials"})
@@ -86,6 +112,6 @@ defmodule Pleroma.Web.OAuth.OAuthController do
defp fix_padding(token) do
token
|> Base.url_decode64!(padding: false)
- |> Base.url_encode64
+ |> Base.url_encode64()
end
end
diff --git a/lib/pleroma/web/oauth/token.ex b/lib/pleroma/web/oauth/token.ex
index 828a966fb..65abd78c8 100644
--- a/lib/pleroma/web/oauth/token.ex
+++ b/lib/pleroma/web/oauth/token.ex
@@ -5,11 +5,11 @@ defmodule Pleroma.Web.OAuth.Token do
alias Pleroma.Web.OAuth.{Token, App, Authorization}
schema "oauth_tokens" do
- field :token, :string
- field :refresh_token, :string
- field :valid_until, :naive_datetime
- belongs_to :user, Pleroma.User
- belongs_to :app, Pleroma.App
+ field(:token, :string)
+ field(:refresh_token, :string)
+ field(:valid_until, :naive_datetime)
+ belongs_to(:user, Pleroma.User)
+ belongs_to(:app, Pleroma.App)
timestamps()
end
@@ -22,15 +22,15 @@ defmodule Pleroma.Web.OAuth.Token do
end
def create_token(%App{} = app, %User{} = user) do
- token = :crypto.strong_rand_bytes(32) |> Base.url_encode64
- refresh_token = :crypto.strong_rand_bytes(32) |> Base.url_encode64
+ token = :crypto.strong_rand_bytes(32) |> Base.url_encode64()
+ refresh_token = :crypto.strong_rand_bytes(32) |> Base.url_encode64()
token = %Token{
token: token,
refresh_token: refresh_token,
user_id: user.id,
app_id: app.id,
- valid_until: NaiveDateTime.add(NaiveDateTime.utc_now, 60 * 10)
+ valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 60 * 10)
}
Repo.insert(token)
diff --git a/lib/pleroma/web/ostatus/activity_representer.ex b/lib/pleroma/web/ostatus/activity_representer.ex
index c8ade52a4..2f28c456e 100644
--- a/lib/pleroma/web/ostatus/activity_representer.ex
+++ b/lib/pleroma/web/ostatus/activity_representer.ex
@@ -5,7 +5,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
require Logger
defp get_href(id) do
- with %Object{data: %{ "external_url" => external_url } }<- Object.get_cached_by_ap_id(id) do
+ with %Object{data: %{"external_url" => external_url}} <- Object.get_cached_by_ap_id(id) do
external_url
else
_e -> id
@@ -13,42 +13,60 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
end
defp get_in_reply_to(%{"object" => %{"inReplyTo" => in_reply_to}}) do
- [{:"thr:in-reply-to", [ref: to_charlist(in_reply_to), href: to_charlist(get_href(in_reply_to))], []}]
+ [
+ {:"thr:in-reply-to",
+ [ref: to_charlist(in_reply_to), href: to_charlist(get_href(in_reply_to))], []}
+ ]
end
defp get_in_reply_to(_), do: []
defp get_mentions(to) do
- Enum.map(to, fn (id) ->
+ Enum.map(to, fn id ->
cond do
# Special handling for the AP/Ostatus public collections
"https://www.w3.org/ns/activitystreams#Public" == id ->
- {:link, [rel: "mentioned", "ostatus:object-type": "http://activitystrea.ms/schema/1.0/collection", href: "http://activityschema.org/collection/public"], []}
+ {:link,
+ [
+ rel: "mentioned",
+ "ostatus:object-type": "http://activitystrea.ms/schema/1.0/collection",
+ href: "http://activityschema.org/collection/public"
+ ], []}
+
# Ostatus doesn't handle follower collections, ignore these.
- Regex.match?(~r/^#{Pleroma.Web.base_url}.+followers$/, id) ->
+ Regex.match?(~r/^#{Pleroma.Web.base_url()}.+followers$/, id) ->
[]
+
true ->
- {:link, [rel: "mentioned", "ostatus:object-type": "http://activitystrea.ms/schema/1.0/person", href: id], []}
+ {:link,
+ [
+ rel: "mentioned",
+ "ostatus:object-type": "http://activitystrea.ms/schema/1.0/person",
+ href: id
+ ], []}
end
end)
end
defp get_links(%{local: true, data: data}) do
- h = fn(str) -> [to_charlist(str)] end
+ h = fn str -> [to_charlist(str)] end
+
[
{:link, [type: ['application/atom+xml'], href: h.(data["object"]["id"]), rel: 'self'], []},
{:link, [type: ['text/html'], href: h.(data["object"]["id"]), rel: 'alternate'], []}
]
end
- defp get_links(%{local: false,
- data: %{
- "object" => %{
- "external_url" => external_url
- }
- }}) do
+ defp get_links(%{
+ local: false,
+ data: %{
+ "object" => %{
+ "external_url" => external_url
+ }
+ }
+ }) do
+ h = fn str -> [to_charlist(str)] end
- h = fn(str) -> [to_charlist(str)] end
[
{:link, [type: ['text/html'], href: h.(external_url), rel: 'alternate'], []}
]
@@ -57,60 +75,72 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
defp get_links(_activity), do: []
defp get_emoji_links(emojis) do
- Enum.map(emojis, fn({emoji, file}) ->
+ Enum.map(emojis, fn {emoji, file} ->
{:link, [name: to_charlist(emoji), rel: 'emoji', href: to_charlist(file)], []}
end)
end
def to_simple_form(activity, user, with_author \\ false)
+
def to_simple_form(%{data: %{"object" => %{"type" => "Note"}}} = activity, user, with_author) do
- h = fn(str) -> [to_charlist(str)] end
+ h = fn str -> [to_charlist(str)] end
updated_at = activity.data["object"]["published"]
inserted_at = activity.data["object"]["published"]
- attachments = Enum.map(activity.data["object"]["attachment"] || [], fn(attachment) ->
- url = hd(attachment["url"])
- {:link, [rel: 'enclosure', href: to_charlist(url["href"]), type: to_charlist(url["mediaType"])], []}
- end)
+ attachments =
+ Enum.map(activity.data["object"]["attachment"] || [], fn attachment ->
+ url = hd(attachment["url"])
+
+ {:link,
+ [rel: 'enclosure', href: to_charlist(url["href"]), type: to_charlist(url["mediaType"])],
+ []}
+ end)
in_reply_to = get_in_reply_to(activity.data)
author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: []
mentions = activity.recipients |> get_mentions
- categories = (activity.data["object"]["tag"] || [])
- |> Enum.map(fn (tag) ->
- if is_binary(tag) do
- {:category, [term: to_charlist(tag)], []}
- else
- nil
- end
- end)
- |> Enum.filter(&(&1))
+ categories =
+ (activity.data["object"]["tag"] || [])
+ |> Enum.map(fn tag ->
+ if is_binary(tag) do
+ {:category, [term: to_charlist(tag)], []}
+ else
+ nil
+ end
+ end)
+ |> Enum.filter(& &1)
emoji_links = get_emoji_links(activity.data["object"]["emoji"] || %{})
- summary = if activity.data["object"]["summary"] do
- [{:summary, [], h.(activity.data["object"]["summary"])}]
- else
- []
- end
+ summary =
+ if activity.data["object"]["summary"] do
+ [{:summary, [], h.(activity.data["object"]["summary"])}]
+ else
+ []
+ end
[
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/note']},
{:"activity:verb", ['http://activitystrea.ms/schema/1.0/post']},
- {:id, h.(activity.data["object"]["id"])}, # For notes, federate the object id.
+ # For notes, federate the object id.
+ {:id, h.(activity.data["object"]["id"])},
{:title, ['New note by #{user.nickname}']},
- {:content, [type: 'html'], h.(activity.data["object"]["content"] |> String.replace(~r/[\n\r]/, ""))},
+ {:content, [type: 'html'],
+ h.(activity.data["object"]["content"] |> String.replace(~r/[\n\r]/, ""))},
{:published, h.(inserted_at)},
{:updated, h.(updated_at)},
{:"ostatus:conversation", [ref: h.(activity.data["context"])], h.(activity.data["context"])},
- {:link, [ref: h.(activity.data["context"]), rel: 'ostatus:conversation'], []},
- ] ++ summary ++ get_links(activity) ++ categories ++ attachments ++ in_reply_to ++ author ++ mentions ++ emoji_links
+ {:link, [ref: h.(activity.data["context"]), rel: 'ostatus:conversation'], []}
+ ] ++
+ summary ++
+ get_links(activity) ++
+ categories ++ attachments ++ in_reply_to ++ author ++ mentions ++ emoji_links
end
def to_simple_form(%{data: %{"type" => "Like"}} = activity, user, with_author) do
- h = fn(str) -> [to_charlist(str)] end
+ h = fn str -> [to_charlist(str)] end
updated_at = activity.data["published"]
inserted_at = activity.data["published"]
@@ -126,10 +156,12 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
{:content, [type: 'html'], ['#{user.nickname} favorited something']},
{:published, h.(inserted_at)},
{:updated, h.(updated_at)},
- {:"activity:object", [
- {:"activity:object-type", ['http://activitystrea.ms/schema/1.0/note']},
- {:id, h.(activity.data["object"])}, # For notes, federate the object id.
- ]},
+ {:"activity:object",
+ [
+ {:"activity:object-type", ['http://activitystrea.ms/schema/1.0/note']},
+ # For notes, federate the object id.
+ {:id, h.(activity.data["object"])}
+ ]},
{:"ostatus:conversation", [ref: h.(activity.data["context"])], h.(activity.data["context"])},
{:link, [ref: h.(activity.data["context"]), rel: 'ostatus:conversation'], []},
{:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []},
@@ -138,7 +170,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
end
def to_simple_form(%{data: %{"type" => "Announce"}} = activity, user, with_author) do
- h = fn(str) -> [to_charlist(str)] end
+ h = fn str -> [to_charlist(str)] end
updated_at = activity.data["published"]
inserted_at = activity.data["published"]
@@ -152,6 +184,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
retweeted_xml = to_simple_form(retweeted_activity, retweeted_user, true)
mentions = activity.recipients |> get_mentions
+
[
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/activity']},
{:"activity:verb", ['http://activitystrea.ms/schema/1.0/share']},
@@ -168,7 +201,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
end
def to_simple_form(%{data: %{"type" => "Follow"}} = activity, user, with_author) do
- h = fn(str) -> [to_charlist(str)] end
+ h = fn str -> [to_charlist(str)] end
updated_at = activity.data["published"]
inserted_at = activity.data["published"]
@@ -176,26 +209,29 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
author = if with_author, do: [{:author, UserRepresenter.to_simple_form(user)}], else: []
mentions = (activity.recipients || []) |> get_mentions
+
[
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/activity']},
{:"activity:verb", ['http://activitystrea.ms/schema/1.0/follow']},
{:id, h.(activity.data["id"])},
{:title, ['#{user.nickname} started following #{activity.data["object"]}']},
- {:content, [type: 'html'], ['#{user.nickname} started following #{activity.data["object"]}']},
+ {:content, [type: 'html'],
+ ['#{user.nickname} started following #{activity.data["object"]}']},
{:published, h.(inserted_at)},
{:updated, h.(updated_at)},
- {:"activity:object", [
- {:"activity:object-type", ['http://activitystrea.ms/schema/1.0/person']},
- {:id, h.(activity.data["object"])},
- {:uri, h.(activity.data["object"])},
- ]},
- {:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []},
+ {:"activity:object",
+ [
+ {:"activity:object-type", ['http://activitystrea.ms/schema/1.0/person']},
+ {:id, h.(activity.data["object"])},
+ {:uri, h.(activity.data["object"])}
+ ]},
+ {:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []}
] ++ mentions ++ author
end
# Only undos of follow for now. Will need to get redone once there are more
def to_simple_form(%{data: %{"type" => "Undo"}} = activity, user, with_author) do
- h = fn(str) -> [to_charlist(str)] end
+ h = fn str -> [to_charlist(str)] end
updated_at = activity.data["published"]
inserted_at = activity.data["published"]
@@ -204,25 +240,28 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
follow_activity = Activity.get_by_ap_id(activity.data["object"])
mentions = (activity.recipients || []) |> get_mentions
+
[
{:"activity:object-type", ['http://activitystrea.ms/schema/1.0/activity']},
{:"activity:verb", ['http://activitystrea.ms/schema/1.0/unfollow']},
{:id, h.(activity.data["id"])},
{:title, ['#{user.nickname} stopped following #{follow_activity.data["object"]}']},
- {:content, [type: 'html'], ['#{user.nickname} stopped following #{follow_activity.data["object"]}']},
+ {:content, [type: 'html'],
+ ['#{user.nickname} stopped following #{follow_activity.data["object"]}']},
{:published, h.(inserted_at)},
{:updated, h.(updated_at)},
- {:"activity:object", [
- {:"activity:object-type", ['http://activitystrea.ms/schema/1.0/person']},
- {:id, h.(follow_activity.data["object"])},
- {:uri, h.(follow_activity.data["object"])},
- ]},
- {:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []},
+ {:"activity:object",
+ [
+ {:"activity:object-type", ['http://activitystrea.ms/schema/1.0/person']},
+ {:id, h.(follow_activity.data["object"])},
+ {:uri, h.(follow_activity.data["object"])}
+ ]},
+ {:link, [rel: 'self', type: ['application/atom+xml'], href: h.(activity.data["id"])], []}
] ++ mentions ++ author
end
def to_simple_form(%{data: %{"type" => "Delete"}} = activity, user, with_author) do
- h = fn(str) -> [to_charlist(str)] end
+ h = fn str -> [to_charlist(str)] end
updated_at = activity.data["published"]
inserted_at = activity.data["published"]
@@ -237,20 +276,24 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenter do
{:content, [type: 'html'], ['An object was deleted']},
{:published, h.(inserted_at)},
{:updated, h.(updated_at)}
- ] ++ author
+ ] ++ author
end
def to_simple_form(_, _, _), do: nil
def wrap_with_entry(simple_form) do
- [{
- :entry, [
- xmlns: 'http://www.w3.org/2005/Atom',
- "xmlns:thr": 'http://purl.org/syndication/thread/1.0',
- "xmlns:activity": 'http://activitystrea.ms/spec/1.0/',
- "xmlns:poco": 'http://portablecontacts.net/spec/1.0',
- "xmlns:ostatus": 'http://ostatus.org/schema/1.0'
- ], simple_form
- }]
+ [
+ {
+ :entry,
+ [
+ xmlns: 'http://www.w3.org/2005/Atom',
+ "xmlns:thr": 'http://purl.org/syndication/thread/1.0',
+ "xmlns:activity": 'http://activitystrea.ms/spec/1.0/',
+ "xmlns:poco": 'http://portablecontacts.net/spec/1.0',
+ "xmlns:ostatus": 'http://ostatus.org/schema/1.0'
+ ],
+ simple_form
+ }
+ ]
end
end
diff --git a/lib/pleroma/web/ostatus/feed_representer.ex b/lib/pleroma/web/ostatus/feed_representer.ex
index 8461b2b9f..279672673 100644
--- a/lib/pleroma/web/ostatus/feed_representer.ex
+++ b/lib/pleroma/web/ostatus/feed_representer.ex
@@ -5,44 +5,57 @@ defmodule Pleroma.Web.OStatus.FeedRepresenter do
alias Pleroma.Web.MediaProxy
def to_simple_form(user, activities, _users) do
- most_recent_update = (List.first(activities) || user).updated_at
- |> NaiveDateTime.to_iso8601
+ most_recent_update =
+ (List.first(activities) || user).updated_at
+ |> NaiveDateTime.to_iso8601()
- h = fn(str) -> [to_charlist(str)] end
+ h = fn str -> [to_charlist(str)] end
last_activity = List.last(activities)
- entries = activities
- |> Enum.map(fn(activity) ->
- {:entry, ActivityRepresenter.to_simple_form(activity, user)}
- end)
- |> Enum.filter(fn ({_, form}) -> form end)
+ entries =
+ activities
+ |> Enum.map(fn activity ->
+ {:entry, ActivityRepresenter.to_simple_form(activity, user)}
+ end)
+ |> Enum.filter(fn {_, form} -> form end)
- [{
- :feed, [
- xmlns: 'http://www.w3.org/2005/Atom',
- "xmlns:thr": 'http://purl.org/syndication/thread/1.0',
- "xmlns:activity": 'http://activitystrea.ms/spec/1.0/',
- "xmlns:poco": 'http://portablecontacts.net/spec/1.0',
- "xmlns:ostatus": 'http://ostatus.org/schema/1.0'
- ], [
- {:id, h.(OStatus.feed_path(user))},
- {:title, ['#{user.nickname}\'s timeline']},
- {:updated, h.(most_recent_update)},
- {:logo, [to_charlist(User.avatar_url(user) |> MediaProxy.url())]},
- {:link, [rel: 'hub', href: h.(OStatus.pubsub_path(user))], []},
- {:link, [rel: 'salmon', href: h.(OStatus.salmon_path(user))], []},
- {:link, [rel: 'self', href: h.(OStatus.feed_path(user)), type: 'application/atom+xml'], []},
- {:author, UserRepresenter.to_simple_form(user)},
- ] ++
- if last_activity do
- [{:link, [rel: 'next',
- href: to_charlist(OStatus.feed_path(user)) ++ '?max_id=' ++ to_charlist(last_activity.id),
- type: 'application/atom+xml'], []}]
- else
- []
- end
- ++ entries
- }]
+ [
+ {
+ :feed,
+ [
+ xmlns: 'http://www.w3.org/2005/Atom',
+ "xmlns:thr": 'http://purl.org/syndication/thread/1.0',
+ "xmlns:activity": 'http://activitystrea.ms/spec/1.0/',
+ "xmlns:poco": 'http://portablecontacts.net/spec/1.0',
+ "xmlns:ostatus": 'http://ostatus.org/schema/1.0'
+ ],
+ [
+ {:id, h.(OStatus.feed_path(user))},
+ {:title, ['#{user.nickname}\'s timeline']},
+ {:updated, h.(most_recent_update)},
+ {:logo, [to_charlist(User.avatar_url(user) |> MediaProxy.url())]},
+ {:link, [rel: 'hub', href: h.(OStatus.pubsub_path(user))], []},
+ {:link, [rel: 'salmon', href: h.(OStatus.salmon_path(user))], []},
+ {:link, [rel: 'self', href: h.(OStatus.feed_path(user)), type: 'application/atom+xml'],
+ []},
+ {:author, UserRepresenter.to_simple_form(user)}
+ ] ++
+ if last_activity do
+ [
+ {:link,
+ [
+ rel: 'next',
+ href:
+ to_charlist(OStatus.feed_path(user)) ++
+ '?max_id=' ++ to_charlist(last_activity.id),
+ type: 'application/atom+xml'
+ ], []}
+ ]
+ else
+ []
+ end ++ entries
+ }
+ ]
end
end
diff --git a/lib/pleroma/web/ostatus/handlers/follow_handler.ex b/lib/pleroma/web/ostatus/handlers/follow_handler.ex
index f5db5582b..162407e04 100644
--- a/lib/pleroma/web/ostatus/handlers/follow_handler.ex
+++ b/lib/pleroma/web/ostatus/handlers/follow_handler.ex
@@ -6,7 +6,8 @@ defmodule Pleroma.Web.OStatus.FollowHandler do
def handle(entry, doc) do
with {:ok, actor} <- OStatus.find_make_or_update_user(doc),
id when not is_nil(id) <- XML.string_from_xpath("/entry/id", entry),
- followed_uri when not is_nil(followed_uri) <- XML.string_from_xpath("/entry/activity:object/id", entry),
+ followed_uri when not is_nil(followed_uri) <-
+ XML.string_from_xpath("/entry/activity:object/id", entry),
{:ok, followed} <- OStatus.find_or_make_user(followed_uri),
{:ok, activity} <- ActivityPub.follow(actor, followed, id, false) do
User.follow(actor, followed)
diff --git a/lib/pleroma/web/ostatus/handlers/note_handler.ex b/lib/pleroma/web/ostatus/handlers/note_handler.ex
index 38f9fc478..b012abd51 100644
--- a/lib/pleroma/web/ostatus/handlers/note_handler.ex
+++ b/lib/pleroma/web/ostatus/handlers/note_handler.ex
@@ -13,49 +13,56 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
3. A newly generated context id.
"""
def get_context(entry, inReplyTo) do
- context = (
- XML.string_from_xpath("//ostatus:conversation[1]", entry)
- || XML.string_from_xpath("//ostatus:conversation[1]/@ref", entry)
- || "") |> String.trim
+ context =
+ (XML.string_from_xpath("//ostatus:conversation[1]", entry) ||
+ XML.string_from_xpath("//ostatus:conversation[1]/@ref", entry) || "")
+ |> String.trim()
with %{data: %{"context" => context}} <- Object.get_cached_by_ap_id(inReplyTo) do
context
- else _e ->
- if String.length(context) > 0 do
- context
- else
- Utils.generate_context_id
- end
+ else
+ _e ->
+ if String.length(context) > 0 do
+ context
+ else
+ Utils.generate_context_id()
+ end
end
end
def get_people_mentions(entry) do
- :xmerl_xpath.string('//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]', entry)
- |> Enum.map(fn(person) -> XML.string_from_xpath("@href", person) end)
+ :xmerl_xpath.string(
+ '//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]',
+ entry
+ )
+ |> Enum.map(fn person -> XML.string_from_xpath("@href", person) end)
end
def get_collection_mentions(entry) do
transmogrify = fn
- ("http://activityschema.org/collection/public") ->
+ "http://activityschema.org/collection/public" ->
"https://www.w3.org/ns/activitystreams#Public"
- (group) ->
+
+ group ->
group
end
- :xmerl_xpath.string('//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/collection"]', entry)
- |> Enum.map(fn(collection) -> XML.string_from_xpath("@href", collection) |> transmogrify.() end)
+ :xmerl_xpath.string(
+ '//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/collection"]',
+ entry
+ )
+ |> Enum.map(fn collection -> XML.string_from_xpath("@href", collection) |> transmogrify.() end)
end
def get_mentions(entry) do
- (get_people_mentions(entry)
- ++ get_collection_mentions(entry))
- |> Enum.filter(&(&1))
+ (get_people_mentions(entry) ++ get_collection_mentions(entry))
+ |> Enum.filter(& &1)
end
def get_emoji(entry) do
try do
:xmerl_xpath.string('//link[@rel="emoji"]', entry)
- |> Enum.reduce(%{}, fn(emoji, acc) ->
+ |> Enum.reduce(%{}, fn emoji, acc ->
Map.put(acc, XML.string_from_xpath("@name", emoji), XML.string_from_xpath("@href", emoji))
end)
rescue
@@ -79,7 +86,8 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
activity
else
_e ->
- with inReplyToHref when not is_nil(inReplyToHref) <- XML.string_from_xpath("//thr:in-reply-to[1]/@href", entry),
+ with inReplyToHref when not is_nil(inReplyToHref) <-
+ XML.string_from_xpath("//thr:in-reply-to[1]/@href", entry),
{:ok, [activity | _]} <- OStatus.fetch_activity_from_url(inReplyToHref) do
activity
else
@@ -107,16 +115,40 @@ defmodule Pleroma.Web.OStatus.NoteHandler do
date <- XML.string_from_xpath("//published", entry),
unlisted <- XML.string_from_xpath("//mastodon:scope", entry) == "unlisted",
cc <- if(unlisted, do: ["https://www.w3.org/ns/activitystreams#Public"], else: []),
- note <- CommonAPI.Utils.make_note_data(actor.ap_id, to, context, content_html, attachments, inReplyToActivity, [], cw),
+ note <-
+ CommonAPI.Utils.make_note_data(
+ actor.ap_id,
+ to,
+ context,
+ content_html,
+ attachments,
+ inReplyToActivity,
+ [],
+ cw
+ ),
note <- note |> Map.put("id", id) |> Map.put("tag", tags),
note <- note |> Map.put("published", date),
note <- note |> Map.put("emoji", get_emoji(entry)),
note <- add_external_url(note, entry),
note <- note |> Map.put("cc", cc),
# TODO: Handle this case in make_note_data
- note <- (if inReplyTo && !inReplyToActivity, do: note |> Map.put("inReplyTo", inReplyTo), else: note)
- do
- res = ActivityPub.create(%{to: to, actor: actor, context: context, object: note, published: date, local: false, additional: %{"cc" => cc}})
+ note <-
+ if(
+ inReplyTo && !inReplyToActivity,
+ do: note |> Map.put("inReplyTo", inReplyTo),
+ else: note
+ ) do
+ res =
+ ActivityPub.create(%{
+ to: to,
+ actor: actor,
+ context: context,
+ object: note,
+ published: date,
+ local: false,
+ additional: %{"cc" => cc}
+ })
+
User.increase_note_count(actor)
res
else
diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex
index f3ef4d690..5c4a1fd69 100644
--- a/lib/pleroma/web/ostatus/ostatus.ex
+++ b/lib/pleroma/web/ostatus/ostatus.ex
@@ -16,7 +16,7 @@ defmodule Pleroma.Web.OStatus do
end
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
@@ -24,48 +24,59 @@ defmodule Pleroma.Web.OStatus do
end
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) do
with doc when doc != :error <- parse_document(xml_string) do
entries = :xmerl_xpath.string('//entry', doc)
- activities = Enum.map(entries, fn (entry) ->
- {:xmlObj, :string, object_type} = :xmerl_xpath.string('string(/entry/activity:object-type[1])', entry)
- {:xmlObj, :string, verb} = :xmerl_xpath.string('string(/entry/activity:verb[1])', entry)
- Logger.debug("Handling #{verb}")
-
- try do
- case verb do
- 'http://activitystrea.ms/schema/1.0/delete' ->
- with {:ok, activity} <- DeleteHandler.handle_delete(entry, doc), do: activity
- 'http://activitystrea.ms/schema/1.0/follow' ->
- with {:ok, activity} <- FollowHandler.handle(entry, doc), do: activity
- 'http://activitystrea.ms/schema/1.0/share' ->
- with {:ok, activity, retweeted_activity} <- handle_share(entry, doc), do: [activity, retweeted_activity]
- 'http://activitystrea.ms/schema/1.0/favorite' ->
- with {:ok, activity, favorited_activity} <- handle_favorite(entry, doc), do: [activity, favorited_activity]
- _ ->
- case object_type do
- 'http://activitystrea.ms/schema/1.0/note' ->
- with {:ok, activity} <- NoteHandler.handle_note(entry, doc), do: activity
- 'http://activitystrea.ms/schema/1.0/comment' ->
- with {:ok, activity} <- NoteHandler.handle_note(entry, doc), do: activity
- _ ->
- Logger.error("Couldn't parse incoming document")
- nil
- end
+ activities =
+ Enum.map(entries, fn entry ->
+ {:xmlObj, :string, object_type} =
+ :xmerl_xpath.string('string(/entry/activity:object-type[1])', entry)
+
+ {:xmlObj, :string, verb} = :xmerl_xpath.string('string(/entry/activity:verb[1])', entry)
+ Logger.debug("Handling #{verb}")
+
+ try do
+ case verb do
+ 'http://activitystrea.ms/schema/1.0/delete' ->
+ with {:ok, activity} <- DeleteHandler.handle_delete(entry, doc), do: activity
+
+ 'http://activitystrea.ms/schema/1.0/follow' ->
+ with {:ok, activity} <- FollowHandler.handle(entry, doc), do: activity
+
+ 'http://activitystrea.ms/schema/1.0/share' ->
+ with {:ok, activity, retweeted_activity} <- handle_share(entry, doc),
+ do: [activity, retweeted_activity]
+
+ 'http://activitystrea.ms/schema/1.0/favorite' ->
+ with {:ok, activity, favorited_activity} <- handle_favorite(entry, doc),
+ do: [activity, favorited_activity]
+
+ _ ->
+ case object_type do
+ 'http://activitystrea.ms/schema/1.0/note' ->
+ with {:ok, activity} <- NoteHandler.handle_note(entry, doc), do: activity
+
+ 'http://activitystrea.ms/schema/1.0/comment' ->
+ with {:ok, activity} <- NoteHandler.handle_note(entry, doc), do: activity
+
+ _ ->
+ Logger.error("Couldn't parse incoming document")
+ nil
+ end
+ end
+ rescue
+ e ->
+ Logger.error("Error occured while handling activity")
+ Logger.error(xml_string)
+ Logger.error(inspect(e))
+ nil
end
- rescue
- e ->
- Logger.error("Error occured while handling activity")
- Logger.error(xml_string)
- Logger.error(inspect(e))
- nil
- end
- end)
- |> Enum.filter(&(&1))
+ end)
+ |> Enum.filter(& &1)
{:ok, activities}
else
@@ -113,15 +124,20 @@ defmodule Pleroma.Web.OStatus do
def get_or_try_fetching(entry) do
Logger.debug("Trying to get entry from db")
+
with id when not is_nil(id) <- string_from_xpath("//activity:object[1]/id", entry),
%Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id) do
{:ok, activity}
- else _ ->
+ else
+ _ ->
Logger.debug("Couldn't get, will try to fetch")
- with href when not is_nil(href) <- string_from_xpath("//activity:object[1]/link[@type=\"text/html\"]/@href", entry),
+
+ with href when not is_nil(href) <-
+ string_from_xpath("//activity:object[1]/link[@type=\"text/html\"]/@href", entry),
{:ok, [favorited_activity]} <- fetch_activity_from_url(href) do
{:ok, favorited_activity}
- else e -> Logger.debug("Couldn't find href: #{inspect(e)}")
+ else
+ e -> Logger.debug("Couldn't find href: #{inspect(e)}")
end
end
end
@@ -137,20 +153,22 @@ defmodule Pleroma.Web.OStatus do
def get_attachments(entry) do
:xmerl_xpath.string('/entry/link[@rel="enclosure"]', entry)
- |> Enum.map(fn (enclosure) ->
+ |> Enum.map(fn 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" => "Attachment",
- "url" => [%{
- "type" => "Link",
- "mediaType" => type,
- "href" => href
- }]
+ "url" => [
+ %{
+ "type" => "Link",
+ "mediaType" => type,
+ "href" => href
+ }
+ ]
}
end
end)
- |> Enum.filter(&(&1))
+ |> Enum.filter(& &1)
end
@doc """
@@ -166,14 +184,15 @@ defmodule Pleroma.Web.OStatus do
def get_cw(entry) do
with cw when not is_nil(cw) <- string_from_xpath("/*/summary", entry) do
cw
- else _e -> nil
+ else
+ _e -> nil
end
end
def get_tags(entry) do
:xmerl_xpath.string('//category', entry)
- |> Enum.map(fn (category) -> string_from_xpath("/category/@term", category) end)
- |> Enum.filter(&(&1))
+ |> Enum.map(fn category -> string_from_xpath("/category/@term", category) end)
+ |> Enum.filter(& &1)
|> Enum.map(&String.downcase/1)
end
@@ -184,6 +203,7 @@ defmodule Pleroma.Web.OStatus do
maybe_update_ostatus(doc, user)
end
end
+
def maybe_update_ostatus(doc, user) do
old_data = %{
avatar: user.avatar,
@@ -196,26 +216,33 @@ defmodule Pleroma.Web.OStatus do
avatar <- make_avatar_object(doc),
bio <- string_from_xpath("//author[1]/summary", doc),
name <- string_from_xpath("//author[1]/poco:displayName", doc),
- info <- Map.put(user.info, "banner", make_avatar_object(doc, "header") || user.info["banner"]),
- new_data <- %{avatar: avatar || old_data.avatar, name: name || old_data.name, bio: bio || old_data.bio, info: info || old_data.info},
+ info <-
+ Map.put(user.info, "banner", make_avatar_object(doc, "header") || user.info["banner"]),
+ new_data <- %{
+ avatar: avatar || old_data.avatar,
+ name: name || old_data.name,
+ bio: bio || old_data.bio,
+ info: info || old_data.info
+ },
false <- new_data == old_data do
change = Ecto.Changeset.change(user, new_data)
Repo.update(change)
- else _ ->
- {:ok, user}
+ else
+ _ ->
+ {:ok, user}
end
end
def find_make_or_update_user(doc) do
uri = string_from_xpath("//author/uri[1]", doc)
+
with {:ok, user} <- find_or_make_user(uri) do
maybe_update(doc, user)
end
end
def find_or_make_user(uri) do
- query = from user in User,
- where: user.ap_id == ^uri
+ query = from(user in User, where: user.ap_id == ^uri)
user = Repo.one(query)
@@ -236,10 +263,12 @@ defmodule Pleroma.Web.OStatus do
avatar: info["avatar"],
bio: info["bio"]
}
+
with false <- update,
%User{} = user <- User.get_by_ap_id(data.ap_id) do
{:ok, user}
- else _e -> User.insert_or_update_user(data)
+ else
+ _e -> User.insert_or_update_user(data)
end
end
end
@@ -252,12 +281,13 @@ defmodule Pleroma.Web.OStatus do
if href do
%{
"type" => "Image",
- "url" =>
- [%{
- "type" => "Link",
- "mediaType" => type,
- "href" => href
- }]
+ "url" => [
+ %{
+ "type" => "Link",
+ "mediaType" => type,
+ "href" => href
+ }
+ ]
}
else
nil
@@ -268,9 +298,10 @@ defmodule Pleroma.Web.OStatus do
with {:ok, webfinger_data} <- WebFinger.finger(username),
{:ok, feed_data} <- Websub.gather_feed_data(webfinger_data["topic"]) do
{:ok, Map.merge(webfinger_data, feed_data) |> Map.put("fqn", username)}
- else e ->
- Logger.debug(fn -> "Couldn't gather info for #{username}" end)
- {:error, e}
+ else
+ e ->
+ Logger.debug(fn -> "Couldn't gather info for #{username}" end)
+ {:error, e}
end
end
@@ -284,12 +315,15 @@ defmodule Pleroma.Web.OStatus do
Regex.match?(@mastodon_regex, body) ->
[[_, match]] = Regex.scan(@mastodon_regex, body)
{:ok, match}
+
Regex.match?(@gs_regex, body) ->
[[_, match]] = Regex.scan(@gs_regex, body)
{:ok, match}
+
Regex.match?(@gs_classic_regex, body) ->
[[_, match]] = Regex.scan(@gs_classic_regex, body)
{:ok, match}
+
true ->
Logger.debug(fn -> "Couldn't find Atom link in #{inspect(body)}" end)
{:error, "Couldn't find the Atom link"}
@@ -298,7 +332,14 @@ defmodule Pleroma.Web.OStatus do
def fetch_activity_from_atom_url(url) do
with true <- String.starts_with?(url, "http"),
- {:ok, %{body: body, status_code: code}} when code in 200..299 <- @httpoison.get(url, [Accept: "application/atom+xml"], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do
+ {:ok, %{body: body, status_code: code}} when code in 200..299 <-
+ @httpoison.get(
+ url,
+ [Accept: "application/atom+xml"],
+ follow_redirect: true,
+ timeout: 10000,
+ recv_timeout: 20000
+ ) do
Logger.debug("Got document from #{url}, handling...")
handle_incoming(body)
else
@@ -310,10 +351,12 @@ defmodule Pleroma.Web.OStatus do
def fetch_activity_from_html_url(url) do
Logger.debug("Trying to fetch #{url}")
+
with true <- String.starts_with?(url, "http"),
- {:ok, %{body: body}} <- @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000),
+ {:ok, %{body: body}} <-
+ @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000),
{:ok, atom_url} <- get_atom_url(body) do
- fetch_activity_from_atom_url(atom_url)
+ fetch_activity_from_atom_url(atom_url)
else
e ->
Logger.debug("Couldn't get #{url}: #{inspect(e)}")
@@ -326,9 +369,10 @@ defmodule Pleroma.Web.OStatus do
with {:ok, activities} when length(activities) > 0 <- fetch_activity_from_atom_url(url) do
{:ok, activities}
else
- _e -> with {:ok, activities} <- fetch_activity_from_html_url(url) do
- {:ok, activities}
- end
+ _e ->
+ with {:ok, activities} <- fetch_activity_from_html_url(url) do
+ {:ok, activities}
+ end
end
rescue
e ->
diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex
index 7e71c156c..a02f55fe6 100644
--- a/lib/pleroma/web/ostatus/ostatus_controller.ex
+++ b/lib/pleroma/web/ostatus/ostatus_controller.ex
@@ -16,23 +16,26 @@ defmodule Pleroma.Web.OStatus.OStatusController do
case get_format(conn) do
"html" -> Fallback.RedirectController.redirector(conn, nil)
"activity+json" -> ActivityPubController.user(conn, params)
- _ -> redirect conn, external: OStatus.feed_path(user)
+ _ -> redirect(conn, external: OStatus.feed_path(user))
end
end
def feed(conn, %{"nickname" => nickname} = params) do
user = User.get_cached_by_nickname(nickname)
- query_params = Map.take(params, ["max_id"])
- |> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id})
+ query_params =
+ Map.take(params, ["max_id"])
+ |> Map.merge(%{"whole_db" => true, "actor_id" => user.ap_id})
- activities = ActivityPub.fetch_public_activities(query_params)
- |> Enum.reverse
+ activities =
+ ActivityPub.fetch_public_activities(query_params)
+ |> Enum.reverse()
- response = user
- |> FeedRepresenter.to_simple_form(activities, [user])
- |> :xmerl.export_simple(:xmerl_xml)
- |> to_string
+ response =
+ user
+ |> FeedRepresenter.to_simple_form(activities, [user])
+ |> :xmerl.export_simple(:xmerl_xml)
+ |> to_string
conn
|> put_resp_content_type("application/atom+xml")
@@ -73,7 +76,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do
else
with id <- o_status_url(conn, :object, uuid),
%Activity{} = activity <- Activity.get_create_activity_by_object_ap_id(id),
- %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
+ %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
case get_format(conn) do
"html" -> redirect(conn, to: "/notice/#{activity.id}")
_ -> represent_activity(conn, activity, user)
@@ -96,24 +99,27 @@ defmodule Pleroma.Web.OStatus.OStatusController do
# TODO: Data leak
def notice(conn, %{"id" => id}) do
- with %Activity{} = activity <- Repo.get(Activity, id),
- %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
+ with %Activity{} = activity <- Repo.get(Activity, id),
+ %User{} = user <- User.get_cached_by_ap_id(activity.data["actor"]) do
case get_format(conn) do
"html" ->
conn
|> put_resp_content_type("text/html")
|> send_file(200, "priv/static/index.html")
- _ -> represent_activity(conn, activity, user)
+
+ _ ->
+ represent_activity(conn, activity, user)
end
end
end
defp represent_activity(conn, activity, user) do
- response = activity
- |> ActivityRepresenter.to_simple_form(user, true)
- |> ActivityRepresenter.wrap_with_entry
- |> :xmerl.export_simple(:xmerl_xml)
- |> to_string
+ response =
+ activity
+ |> ActivityRepresenter.to_simple_form(user, true)
+ |> ActivityRepresenter.wrap_with_entry()
+ |> :xmerl.export_simple(:xmerl_xml)
+ |> to_string
conn
|> put_resp_content_type("application/atom+xml")
diff --git a/lib/pleroma/web/ostatus/user_representer.ex b/lib/pleroma/web/ostatus/user_representer.ex
index 5af439c9d..2e696506e 100644
--- a/lib/pleroma/web/ostatus/user_representer.ex
+++ b/lib/pleroma/web/ostatus/user_representer.ex
@@ -1,22 +1,26 @@
defmodule Pleroma.Web.OStatus.UserRepresenter do
alias Pleroma.User
+
def to_simple_form(user) do
ap_id = to_charlist(user.ap_id)
nickname = to_charlist(user.nickname)
name = to_charlist(user.name)
bio = to_charlist(user.bio)
avatar_url = to_charlist(User.avatar_url(user))
- banner = if banner_url = User.banner_url(user) do
- [{:link, [rel: 'header', href: banner_url], []}]
- else
- []
- end
- ap_enabled = if user.local do
- [{:ap_enabled, ['true']}]
- else
- []
- end
+ banner =
+ if banner_url = User.banner_url(user) do
+ [{:link, [rel: 'header', href: banner_url], []}]
+ else
+ []
+ end
+
+ ap_enabled =
+ if user.local do
+ [{:ap_enabled, ['true']}]
+ else
+ []
+ end
[
{:id, [ap_id]},
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 22a5257d5..5f27f3caa 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -11,294 +11,305 @@ defmodule Pleroma.Web.Router do
end
pipeline :api do
- plug :accepts, ["json"]
- plug :fetch_session
- plug Pleroma.Plugs.OAuthPlug
- plug Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Router.user_fetcher/1, optional: true}
+ plug(:accepts, ["json"])
+ plug(:fetch_session)
+ plug(Pleroma.Plugs.OAuthPlug)
+ plug(Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Router.user_fetcher/1, optional: true})
end
pipeline :authenticated_api do
- plug :accepts, ["json"]
- plug :fetch_session
- plug Pleroma.Plugs.OAuthPlug
- plug Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Router.user_fetcher/1}
+ plug(:accepts, ["json"])
+ plug(:fetch_session)
+ plug(Pleroma.Plugs.OAuthPlug)
+ plug(Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Router.user_fetcher/1})
end
pipeline :mastodon_html do
- plug :accepts, ["html"]
- plug :fetch_session
- plug Pleroma.Plugs.OAuthPlug
- plug Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Router.user_fetcher/1, optional: true}
+ plug(:accepts, ["html"])
+ plug(:fetch_session)
+ plug(Pleroma.Plugs.OAuthPlug)
+ plug(Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Router.user_fetcher/1, optional: true})
end
pipeline :pleroma_html do
- plug :accepts, ["html"]
- plug :fetch_session
- plug Pleroma.Plugs.OAuthPlug
- plug Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Router.user_fetcher/1, optional: true}
+ plug(:accepts, ["html"])
+ plug(:fetch_session)
+ plug(Pleroma.Plugs.OAuthPlug)
+ plug(Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Router.user_fetcher/1, optional: true})
end
pipeline :well_known do
- plug :accepts, ["xml", "xrd+xml", "json", "jrd+json"]
+ plug(:accepts, ["xml", "xrd+xml", "json", "jrd+json"])
end
pipeline :config do
- plug :accepts, ["json", "xml"]
+ plug(:accepts, ["json", "xml"])
end
pipeline :oauth do
- plug :accepts, ["html", "json"]
+ plug(:accepts, ["html", "json"])
end
pipeline :pleroma_api do
- plug :accepts, ["html", "json"]
+ plug(:accepts, ["html", "json"])
end
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
- pipe_through :pleroma_api
- get "/password_reset/:token", UtilController, :show_password_reset
- post "/password_reset", UtilController, :password_reset
- get "/emoji", UtilController, :emoji
+ pipe_through(:pleroma_api)
+ get("/password_reset/:token", UtilController, :show_password_reset)
+ post("/password_reset", UtilController, :password_reset)
+ get("/emoji", UtilController, :emoji)
end
scope "/", Pleroma.Web.TwitterAPI do
- pipe_through :pleroma_html
- get "/ostatus_subscribe", UtilController, :remote_follow
- post "/ostatus_subscribe", UtilController, :do_remote_follow
- post "/main/ostatus", UtilController, :remote_subscribe
+ pipe_through(:pleroma_html)
+ get("/ostatus_subscribe", UtilController, :remote_follow)
+ post("/ostatus_subscribe", UtilController, :do_remote_follow)
+ post("/main/ostatus", UtilController, :remote_subscribe)
end
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
- pipe_through :authenticated_api
- post "/follow_import", UtilController, :follow_import
+ pipe_through(:authenticated_api)
+ post("/follow_import", UtilController, :follow_import)
end
scope "/oauth", Pleroma.Web.OAuth do
- get "/authorize", OAuthController, :authorize
- post "/authorize", OAuthController, :create_authorization
- post "/token", OAuthController, :token_exchange
+ get("/authorize", OAuthController, :authorize)
+ post("/authorize", OAuthController, :create_authorization)
+ post("/token", OAuthController, :token_exchange)
end
scope "/api/v1", Pleroma.Web.MastodonAPI do
- pipe_through :authenticated_api
+ pipe_through(:authenticated_api)
- patch "/accounts/update_credentials", MastodonAPIController, :update_credentials
- get "/accounts/verify_credentials", MastodonAPIController, :verify_credentials
- get "/accounts/relationships", MastodonAPIController, :relationships
- get "/accounts/search", MastodonAPIController, :account_search
- post "/accounts/:id/follow", MastodonAPIController, :follow
- post "/accounts/:id/unfollow", MastodonAPIController, :unfollow
- post "/accounts/:id/block", MastodonAPIController, :block
- post "/accounts/:id/unblock", MastodonAPIController, :unblock
- post "/accounts/:id/mute", MastodonAPIController, :relationship_noop
- post "/accounts/:id/unmute", MastodonAPIController, :relationship_noop
+ patch("/accounts/update_credentials", MastodonAPIController, :update_credentials)
+ get("/accounts/verify_credentials", MastodonAPIController, :verify_credentials)
+ get("/accounts/relationships", MastodonAPIController, :relationships)
+ get("/accounts/search", MastodonAPIController, :account_search)
+ post("/accounts/:id/follow", MastodonAPIController, :follow)
+ post("/accounts/:id/unfollow", MastodonAPIController, :unfollow)
+ post("/accounts/:id/block", MastodonAPIController, :block)
+ post("/accounts/:id/unblock", MastodonAPIController, :unblock)
+ post("/accounts/:id/mute", MastodonAPIController, :relationship_noop)
+ post("/accounts/:id/unmute", MastodonAPIController, :relationship_noop)
- post "/follows", MastodonAPIController, :follow
+ post("/follows", MastodonAPIController, :follow)
- get "/blocks", MastodonAPIController, :blocks
+ get("/blocks", MastodonAPIController, :blocks)
- get "/domain_blocks", MastodonAPIController, :empty_array
- get "/follow_requests", MastodonAPIController, :empty_array
- get "/mutes", MastodonAPIController, :empty_array
+ get("/domain_blocks", MastodonAPIController, :empty_array)
+ get("/follow_requests", MastodonAPIController, :empty_array)
+ get("/mutes", MastodonAPIController, :empty_array)
- get "/timelines/home", MastodonAPIController, :home_timeline
+ get("/timelines/home", MastodonAPIController, :home_timeline)
- get "/favourites", MastodonAPIController, :favourites
+ get("/favourites", MastodonAPIController, :favourites)
- post "/statuses", MastodonAPIController, :post_status
- delete "/statuses/:id", MastodonAPIController, :delete_status
+ post("/statuses", MastodonAPIController, :post_status)
+ delete("/statuses/:id", MastodonAPIController, :delete_status)
- post "/statuses/:id/reblog", MastodonAPIController, :reblog_status
- post "/statuses/:id/favourite", MastodonAPIController, :fav_status
- post "/statuses/:id/unfavourite", MastodonAPIController, :unfav_status
+ post("/statuses/:id/reblog", MastodonAPIController, :reblog_status)
+ post("/statuses/:id/favourite", MastodonAPIController, :fav_status)
+ post("/statuses/:id/unfavourite", MastodonAPIController, :unfav_status)
- post "/notifications/clear", MastodonAPIController, :clear_notifications
- post "/notifications/dismiss", MastodonAPIController, :dismiss_notification
- get "/notifications", MastodonAPIController, :notifications
- get "/notifications/:id", MastodonAPIController, :get_notification
+ post("/notifications/clear", MastodonAPIController, :clear_notifications)
+ post("/notifications/dismiss", MastodonAPIController, :dismiss_notification)
+ get("/notifications", MastodonAPIController, :notifications)
+ get("/notifications/:id", MastodonAPIController, :get_notification)
- post "/media", MastodonAPIController, :upload
+ post("/media", MastodonAPIController, :upload)
end
scope "/api/v1", Pleroma.Web.MastodonAPI do
- pipe_through :api
- get "/instance", MastodonAPIController, :masto_instance
- get "/instance/peers", MastodonAPIController, :peers
- post "/apps", MastodonAPIController, :create_app
- get "/custom_emojis", MastodonAPIController, :custom_emojis
-
- get "/timelines/public", MastodonAPIController, :public_timeline
- get "/timelines/tag/:tag", MastodonAPIController, :hashtag_timeline
-
- get "/statuses/:id", MastodonAPIController, :get_status
- get "/statuses/:id/context", MastodonAPIController, :get_context
- get "/statuses/:id/card", MastodonAPIController, :empty_object
- get "/statuses/:id/favourited_by", MastodonAPIController, :favourited_by
- get "/statuses/:id/reblogged_by", MastodonAPIController, :reblogged_by
-
- get "/accounts/:id/statuses", MastodonAPIController, :user_statuses
- get "/accounts/:id/followers", MastodonAPIController, :followers
- get "/accounts/:id/following", MastodonAPIController, :following
- get "/accounts/:id", MastodonAPIController, :user
-
- get "/search", MastodonAPIController, :search
+ pipe_through(:api)
+ get("/instance", MastodonAPIController, :masto_instance)
+ get("/instance/peers", MastodonAPIController, :peers)
+ post("/apps", MastodonAPIController, :create_app)
+ get("/custom_emojis", MastodonAPIController, :custom_emojis)
+
+ get("/timelines/public", MastodonAPIController, :public_timeline)
+ get("/timelines/tag/:tag", MastodonAPIController, :hashtag_timeline)
+
+ get("/statuses/:id", MastodonAPIController, :get_status)
+ get("/statuses/:id/context", MastodonAPIController, :get_context)
+ get("/statuses/:id/card", MastodonAPIController, :empty_object)
+ get("/statuses/:id/favourited_by", MastodonAPIController, :favourited_by)
+ get("/statuses/:id/reblogged_by", MastodonAPIController, :reblogged_by)
+
+ get("/accounts/:id/statuses", MastodonAPIController, :user_statuses)
+ get("/accounts/:id/followers", MastodonAPIController, :followers)
+ get("/accounts/:id/following", MastodonAPIController, :following)
+ get("/accounts/:id", MastodonAPIController, :user)
+
+ get("/search", MastodonAPIController, :search)
end
scope "/api", Pleroma.Web do
- pipe_through :config
+ pipe_through(:config)
- get "/help/test", TwitterAPI.UtilController, :help_test
- post "/help/test", TwitterAPI.UtilController, :help_test
- get "/statusnet/config", TwitterAPI.UtilController, :config
- get "/statusnet/version", TwitterAPI.UtilController, :version
+ get("/help/test", TwitterAPI.UtilController, :help_test)
+ post("/help/test", TwitterAPI.UtilController, :help_test)
+ get("/statusnet/config", TwitterAPI.UtilController, :config)
+ get("/statusnet/version", TwitterAPI.UtilController, :version)
end
@instance Application.get_env(:pleroma, :instance)
@registrations_open Keyword.get(@instance, :registrations_open)
scope "/api", Pleroma.Web do
- pipe_through :api
+ pipe_through(:api)
- get "/statuses/public_timeline", TwitterAPI.Controller, :public_timeline
- get "/statuses/public_and_external_timeline", TwitterAPI.Controller, :public_and_external_timeline
- get "/statuses/networkpublic_timeline", TwitterAPI.Controller, :public_and_external_timeline
- get "/statuses/user_timeline", TwitterAPI.Controller, :user_timeline
- get "/qvitter/statuses/user_timeline", TwitterAPI.Controller, :user_timeline
- get "/users/show", TwitterAPI.Controller, :show_user
+ get("/statuses/public_timeline", TwitterAPI.Controller, :public_timeline)
- get "/statuses/followers", TwitterAPI.Controller, :followers
- get "/statuses/friends", TwitterAPI.Controller, :friends
- get "/statuses/show/:id", TwitterAPI.Controller, :fetch_status
- get "/statusnet/conversation/:id", TwitterAPI.Controller, :fetch_conversation
+ get(
+ "/statuses/public_and_external_timeline",
+ TwitterAPI.Controller,
+ :public_and_external_timeline
+ )
+
+ get("/statuses/networkpublic_timeline", TwitterAPI.Controller, :public_and_external_timeline)
+ get("/statuses/user_timeline", TwitterAPI.Controller, :user_timeline)
+ get("/qvitter/statuses/user_timeline", TwitterAPI.Controller, :user_timeline)
+ get("/users/show", TwitterAPI.Controller, :show_user)
+
+ get("/statuses/followers", TwitterAPI.Controller, :followers)
+ get("/statuses/friends", TwitterAPI.Controller, :friends)
+ get("/statuses/show/:id", TwitterAPI.Controller, :fetch_status)
+ get("/statusnet/conversation/:id", TwitterAPI.Controller, :fetch_conversation)
if @registrations_open do
- post "/account/register", TwitterAPI.Controller, :register
+ post("/account/register", TwitterAPI.Controller, :register)
end
- get "/search", TwitterAPI.Controller, :search
- get "/statusnet/tags/timeline/:tag", TwitterAPI.Controller, :public_and_external_timeline
+ get("/search", TwitterAPI.Controller, :search)
+ get("/statusnet/tags/timeline/:tag", TwitterAPI.Controller, :public_and_external_timeline)
end
scope "/api", Pleroma.Web do
- pipe_through :authenticated_api
+ pipe_through(:authenticated_api)
- get "/account/verify_credentials", TwitterAPI.Controller, :verify_credentials
- post "/account/verify_credentials", TwitterAPI.Controller, :verify_credentials
+ get("/account/verify_credentials", TwitterAPI.Controller, :verify_credentials)
+ post("/account/verify_credentials", TwitterAPI.Controller, :verify_credentials)
- post "/account/update_profile", TwitterAPI.Controller, :update_profile
- post "/account/update_profile_banner", TwitterAPI.Controller, :update_banner
- post "/qvitter/update_background_image", TwitterAPI.Controller, :update_background
+ post("/account/update_profile", TwitterAPI.Controller, :update_profile)
+ post("/account/update_profile_banner", TwitterAPI.Controller, :update_banner)
+ post("/qvitter/update_background_image", TwitterAPI.Controller, :update_background)
- post "/account/most_recent_notification", TwitterAPI.Controller, :update_most_recent_notification
+ post(
+ "/account/most_recent_notification",
+ TwitterAPI.Controller,
+ :update_most_recent_notification
+ )
- get "/statuses/home_timeline", TwitterAPI.Controller, :friends_timeline
- get "/statuses/friends_timeline", TwitterAPI.Controller, :friends_timeline
- get "/statuses/mentions", TwitterAPI.Controller, :mentions_timeline
- get "/statuses/mentions_timeline", TwitterAPI.Controller, :mentions_timeline
+ get("/statuses/home_timeline", TwitterAPI.Controller, :friends_timeline)
+ get("/statuses/friends_timeline", TwitterAPI.Controller, :friends_timeline)
+ get("/statuses/mentions", TwitterAPI.Controller, :mentions_timeline)
+ get("/statuses/mentions_timeline", TwitterAPI.Controller, :mentions_timeline)
- post "/statuses/update", TwitterAPI.Controller, :status_update
- post "/statuses/retweet/:id", TwitterAPI.Controller, :retweet
- post "/statuses/destroy/:id", TwitterAPI.Controller, :delete_post
+ post("/statuses/update", TwitterAPI.Controller, :status_update)
+ post("/statuses/retweet/:id", TwitterAPI.Controller, :retweet)
+ post("/statuses/destroy/:id", TwitterAPI.Controller, :delete_post)
- post "/friendships/create", TwitterAPI.Controller, :follow
- post "/friendships/destroy", TwitterAPI.Controller, :unfollow
- post "/blocks/create", TwitterAPI.Controller, :block
- post "/blocks/destroy", TwitterAPI.Controller, :unblock
+ post("/friendships/create", TwitterAPI.Controller, :follow)
+ post("/friendships/destroy", TwitterAPI.Controller, :unfollow)
+ post("/blocks/create", TwitterAPI.Controller, :block)
+ post("/blocks/destroy", TwitterAPI.Controller, :unblock)
- post "/statusnet/media/upload", TwitterAPI.Controller, :upload
- post "/media/upload", TwitterAPI.Controller, :upload_json
+ post("/statusnet/media/upload", TwitterAPI.Controller, :upload)
+ post("/media/upload", TwitterAPI.Controller, :upload_json)
- post "/favorites/create/:id", TwitterAPI.Controller, :favorite
- post "/favorites/create", TwitterAPI.Controller, :favorite
- post "/favorites/destroy/:id", TwitterAPI.Controller, :unfavorite
+ post("/favorites/create/:id", TwitterAPI.Controller, :favorite)
+ post("/favorites/create", TwitterAPI.Controller, :favorite)
+ post("/favorites/destroy/:id", TwitterAPI.Controller, :unfavorite)
- post "/qvitter/update_avatar", TwitterAPI.Controller, :update_avatar
+ post("/qvitter/update_avatar", TwitterAPI.Controller, :update_avatar)
- get "/friends/ids", TwitterAPI.Controller, :friends_ids
- get "/friendships/no_retweets/ids", TwitterAPI.Controller, :empty_array
+ get("/friends/ids", TwitterAPI.Controller, :friends_ids)
+ get("/friendships/no_retweets/ids", TwitterAPI.Controller, :empty_array)
- get "/mutes/users/ids", TwitterAPI.Controller, :empty_array
+ get("/mutes/users/ids", TwitterAPI.Controller, :empty_array)
- get "/externalprofile/show", TwitterAPI.Controller, :external_profile
+ get("/externalprofile/show", TwitterAPI.Controller, :external_profile)
end
pipeline :ostatus do
- plug :accepts, ["xml", "atom", "html", "activity+json"]
+ plug(:accepts, ["xml", "atom", "html", "activity+json"])
end
scope "/", Pleroma.Web do
- pipe_through :ostatus
+ pipe_through(:ostatus)
- get "/objects/:uuid", OStatus.OStatusController, :object
- get "/activities/:uuid", OStatus.OStatusController, :activity
- get "/notice/:id", OStatus.OStatusController, :notice
- get "/users/:nickname/feed", OStatus.OStatusController, :feed
- get "/users/:nickname", OStatus.OStatusController, :feed_redirect
+ get("/objects/:uuid", OStatus.OStatusController, :object)
+ get("/activities/:uuid", OStatus.OStatusController, :activity)
+ get("/notice/:id", OStatus.OStatusController, :notice)
+ get("/users/:nickname/feed", OStatus.OStatusController, :feed)
+ get("/users/:nickname", OStatus.OStatusController, :feed_redirect)
if @federating do
- post "/users/:nickname/salmon", OStatus.OStatusController, :salmon_incoming
- post "/push/hub/:nickname", Websub.WebsubController, :websub_subscription_request
- get "/push/subscriptions/:id", Websub.WebsubController, :websub_subscription_confirmation
- post "/push/subscriptions/:id", Websub.WebsubController, :websub_incoming
+ post("/users/:nickname/salmon", OStatus.OStatusController, :salmon_incoming)
+ post("/push/hub/:nickname", Websub.WebsubController, :websub_subscription_request)
+ get("/push/subscriptions/:id", Websub.WebsubController, :websub_subscription_confirmation)
+ post("/push/subscriptions/:id", Websub.WebsubController, :websub_incoming)
end
-
end
pipeline :activitypub do
- plug :accepts, ["activity+json"]
- plug Pleroma.Web.Plugs.HTTPSignaturePlug
+ plug(:accepts, ["activity+json"])
+ plug(Pleroma.Web.Plugs.HTTPSignaturePlug)
end
scope "/", Pleroma.Web.ActivityPub do
# XXX: not really ostatus
- pipe_through :ostatus
+ pipe_through(:ostatus)
- get "/users/:nickname/followers", ActivityPubController, :followers
- get "/users/:nickname/following", ActivityPubController, :following
- get "/users/:nickname/outbox", ActivityPubController, :outbox
+ get("/users/:nickname/followers", ActivityPubController, :followers)
+ get("/users/:nickname/following", ActivityPubController, :following)
+ get("/users/:nickname/outbox", ActivityPubController, :outbox)
end
if @federating do
scope "/", Pleroma.Web.ActivityPub do
- pipe_through :activitypub
- post "/users/:nickname/inbox", ActivityPubController, :inbox
- post "/inbox", ActivityPubController, :inbox
+ pipe_through(:activitypub)
+ post("/users/:nickname/inbox", ActivityPubController, :inbox)
+ post("/inbox", ActivityPubController, :inbox)
end
scope "/.well-known", Pleroma.Web do
- pipe_through :well_known
+ pipe_through(:well_known)
- get "/host-meta", WebFinger.WebFingerController, :host_meta
- get "/webfinger", WebFinger.WebFingerController, :webfinger
+ get("/host-meta", WebFinger.WebFingerController, :host_meta)
+ get("/webfinger", WebFinger.WebFingerController, :webfinger)
end
end
scope "/", Pleroma.Web.MastodonAPI do
- pipe_through :mastodon_html
+ pipe_through(:mastodon_html)
- get "/web/login", MastodonAPIController, :login
- post "/web/login", MastodonAPIController, :login_post
- get "/web/*path", MastodonAPIController, :index
- delete "/auth/sign_out", MastodonAPIController, :logout
+ get("/web/login", MastodonAPIController, :login)
+ post("/web/login", MastodonAPIController, :login_post)
+ get("/web/*path", MastodonAPIController, :index)
+ delete("/auth/sign_out", MastodonAPIController, :logout)
end
pipeline :remote_media do
- plug :accepts, ["html"]
+ plug(:accepts, ["html"])
end
+
scope "/proxy/", Pleroma.Web.MediaProxy do
- pipe_through :remote_media
- get "/:sig/:url", MediaProxyController, :remote
+ pipe_through(:remote_media)
+ get("/:sig/:url", MediaProxyController, :remote)
end
scope "/", Fallback do
- get "/*path", RedirectController, :redirector
+ get("/*path", RedirectController, :redirector)
end
end
defmodule Fallback.RedirectController do
use Pleroma.Web, :controller
+
def redirector(conn, _params) do
- if Mix.env != :test do
+ if Mix.env() != :test do
conn
|> put_resp_content_type("text/html")
|> send_file(200, "priv/static/index.html")
diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex
index ab0f97d55..10542fd00 100644
--- a/lib/pleroma/web/salmon/salmon.ex
+++ b/lib/pleroma/web/salmon/salmon.ex
@@ -38,9 +38,10 @@ defmodule Pleroma.Web.Salmon do
def decode_and_validate(magickey, salmon) do
[data, type, encoding, alg, sig] = decode(salmon)
- signed_text = [data, type, encoding, alg]
- |> Enum.map(&Base.url_encode64/1)
- |> Enum.join(".")
+ signed_text =
+ [data, type, encoding, alg]
+ |> Enum.map(&Base.url_encode64/1)
+ |> Enum.join(".")
key = decode_key(magickey)
@@ -54,22 +55,23 @@ defmodule Pleroma.Web.Salmon do
end
def decode_key("RSA." <> magickey) do
- make_integer = fn(bin) ->
+ make_integer = fn bin ->
list = :erlang.binary_to_list(bin)
- Enum.reduce(list, 0, fn (el, acc) -> (acc <<< 8) ||| el end)
+ Enum.reduce(list, 0, fn el, acc -> acc <<< 8 ||| el end)
end
- [modulus, exponent] = magickey
- |> String.split(".")
- |> Enum.map(fn (n) -> Base.url_decode64!(n, padding: false) end)
- |> Enum.map(make_integer)
+ [modulus, exponent] =
+ magickey
+ |> String.split(".")
+ |> Enum.map(fn n -> Base.url_decode64!(n, padding: false) end)
+ |> Enum.map(make_integer)
{:RSAPublicKey, modulus, exponent}
end
def encode_key({:RSAPublicKey, modulus, exponent}) do
- modulus_enc = :binary.encode_unsigned(modulus) |> Base.url_encode64
- exponent_enc = :binary.encode_unsigned(exponent) |> Base.url_encode64
+ modulus_enc = :binary.encode_unsigned(modulus) |> Base.url_encode64()
+ exponent_enc = :binary.encode_unsigned(exponent) |> Base.url_encode64()
"RSA.#{modulus_enc}.#{exponent_enc}"
end
@@ -78,20 +80,25 @@ defmodule Pleroma.Web.Salmon do
# We try at compile time to generate natively an RSA key otherwise we fallback on the old way.
try do
_ = :public_key.generate_key({:rsa, 2048, 65537})
+
def generate_rsa_pem do
key = :public_key.generate_key({:rsa, 2048, 65537})
entry = :public_key.pem_entry_encode(:RSAPrivateKey, key)
- pem = :public_key.pem_encode([entry]) |> String.trim_trailing
+ pem = :public_key.pem_encode([entry]) |> String.trim_trailing()
{:ok, pem}
end
rescue
_ ->
def generate_rsa_pem do
port = Port.open({:spawn, "openssl genrsa"}, [:binary])
- {:ok, pem} = receive do
- {^port, {:data, pem}} -> {:ok, pem}
- end
+
+ {:ok, pem} =
+ receive do
+ {^port, {:data, pem}} -> {:ok, pem}
+ end
+
Port.close(port)
+
if Regex.match?(~r/RSA PRIVATE KEY/, pem) do
{:ok, pem}
else
@@ -113,17 +120,20 @@ defmodule Pleroma.Web.Salmon do
encoding = "base64url"
alg = "RSA-SHA256"
- signed_text = [doc, type, encoding, alg]
- |> Enum.map(&Base.url_encode64/1)
- |> Enum.join(".")
+ signed_text =
+ [doc, type, encoding, alg]
+ |> Enum.map(&Base.url_encode64/1)
+ |> Enum.join(".")
- signature = signed_text
- |> :public_key.sign(:sha256, private_key)
- |> to_string
- |> Base.url_encode64
+ signature =
+ signed_text
+ |> :public_key.sign(:sha256, private_key)
+ |> to_string
+ |> Base.url_encode64()
- doc_base64 = doc
- |> Base.url_encode64
+ doc_base64 =
+ doc
+ |> Base.url_encode64()
# Don't need proper xml building, these strings are safe to leave unescaped
salmon = """
@@ -141,20 +151,29 @@ defmodule Pleroma.Web.Salmon do
def remote_users(%{data: %{"to" => to} = data}) do
to = to ++ (data["cc"] || [])
+
to
- |> Enum.map(fn(id) -> User.get_cached_by_ap_id(id) end)
- |> Enum.filter(fn(user) -> user && !user.local end)
+ |> Enum.map(fn id -> User.get_cached_by_ap_id(id) end)
+ |> Enum.filter(fn user -> user && !user.local end)
end
defp send_to_user(%{info: %{"salmon" => salmon}}, feed, poster) do
- with {:ok, %{status_code: code}} <- poster.(salmon, feed, [{"Content-Type", "application/magic-envelope+xml"}], timeout: 10000, recv_timeout: 20000, hackney: [pool: :default]) do
+ with {:ok, %{status_code: code}} <-
+ poster.(
+ salmon,
+ feed,
+ [{"Content-Type", "application/magic-envelope+xml"}],
+ timeout: 10000,
+ recv_timeout: 20000,
+ hackney: [pool: :default]
+ ) do
Logger.debug(fn -> "Pushed to #{salmon}, code #{code}" end)
else
e -> Logger.debug(fn -> "Pushing Salmon to #{salmon} failed, #{inspect(e)}" end)
end
end
- defp send_to_user(_,_,_), do: nil
+ defp send_to_user(_, _, _), do: nil
@supported_activities [
"Create",
@@ -165,18 +184,21 @@ defmodule Pleroma.Web.Salmon do
"Delete"
]
def publish(user, activity, poster \\ &@httpoison.post/4)
- 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)
- |> ActivityRepresenter.wrap_with_entry
- |> :xmerl.export_simple(:xmerl_xml)
- |> to_string
+
+ 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)
+ |> ActivityRepresenter.wrap_with_entry()
+ |> :xmerl.export_simple(:xmerl_xml)
+ |> to_string
if feed do
{:ok, private, _} = keys_from_pem(keys)
{:ok, feed} = encode(private, feed)
remote_users(activity)
- |> Enum.each(fn(remote_user) ->
+ |> Enum.each(fn remote_user ->
Task.start(fn ->
Logger.debug(fn -> "Sending Salmon to #{remote_user.ap_id}" end)
send_to_user(remote_user, feed, poster)
diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex
index d81732a1a..10670e71f 100644
--- a/lib/pleroma/web/streamer.ex
+++ b/lib/pleroma/web/streamer.ex
@@ -5,9 +5,11 @@ defmodule Pleroma.Web.Streamer do
def start_link do
spawn(fn ->
- Process.sleep(1000 * 30) # 30 seconds
+ # 30 seconds
+ Process.sleep(1000 * 30)
GenServer.cast(__MODULE__, %{action: :ping})
end)
+
GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
end
@@ -25,39 +27,54 @@ defmodule Pleroma.Web.Streamer do
def handle_cast(%{action: :ping}, topics) do
Map.values(topics)
- |> List.flatten
- |> Enum.each(fn (socket) ->
+ |> List.flatten()
+ |> Enum.each(fn socket ->
Logger.debug("Sending keepalive ping")
- send socket.transport_pid, {:text, ""}
+ send(socket.transport_pid, {:text, ""})
end)
+
spawn(fn ->
- Process.sleep(1000 * 30) # 30 seconds
+ # 30 seconds
+ Process.sleep(1000 * 30)
GenServer.cast(__MODULE__, %{action: :ping})
end)
+
{:noreply, topics}
end
def handle_cast(%{action: :stream, topic: "user", item: %Notification{} = item}, topics) do
topic = "user:#{item.user_id}"
- Enum.each(topics[topic] || [], fn (socket) ->
- json = %{
- event: "notification",
- payload: Pleroma.Web.MastodonAPI.MastodonAPIController.render_notification(socket.assigns["user"], item) |> Jason.encode!
- } |> Jason.encode!
- send socket.transport_pid, {:text, json}
+ Enum.each(topics[topic] || [], fn socket ->
+ json =
+ %{
+ event: "notification",
+ payload:
+ Pleroma.Web.MastodonAPI.MastodonAPIController.render_notification(
+ socket.assigns["user"],
+ item
+ )
+ |> Jason.encode!()
+ }
+ |> Jason.encode!()
+
+ send(socket.transport_pid, {:text, json})
end)
+
{:noreply, topics}
end
def handle_cast(%{action: :stream, topic: "user", item: item}, topics) do
Logger.debug("Trying to push to users")
- recipient_topics = User.get_recipients_from_activity(item)
- |> Enum.map(fn (%{id: id}) -> "user:#{id}" end)
- Enum.each(recipient_topics, fn (topic) ->
+ recipient_topics =
+ User.get_recipients_from_activity(item)
+ |> Enum.map(fn %{id: id} -> "user:#{id}" end)
+
+ Enum.each(recipient_topics, fn topic ->
push_to_socket(topics, topic, item)
end)
+
{:noreply, topics}
end
@@ -92,13 +109,21 @@ defmodule Pleroma.Web.Streamer do
end
def push_to_socket(topics, topic, item) do
- Enum.each(topics[topic] || [], fn (socket) ->
- json = %{
- event: "update",
- payload: Pleroma.Web.MastodonAPI.StatusView.render("status.json", activity: item, for: socket.assigns[:user]) |> Jason.encode!
- } |> Jason.encode!
-
- send socket.transport_pid, {:text, json}
+ Enum.each(topics[topic] || [], fn socket ->
+ json =
+ %{
+ event: "update",
+ payload:
+ Pleroma.Web.MastodonAPI.StatusView.render(
+ "status.json",
+ activity: item,
+ for: socket.assigns[:user]
+ )
+ |> Jason.encode!()
+ }
+ |> Jason.encode!()
+
+ send(socket.transport_pid, {:text, json})
end)
end
diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
index 503719dbf..8f452c31c 100644
--- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex
+++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
@@ -11,21 +11,21 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
def show_password_reset(conn, %{"token" => token}) do
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
- %User{} = user <- Repo.get(User, token.user_id) do
- render conn, "password_reset.html", %{
+ %User{} = user <- Repo.get(User, token.user_id) do
+ render(conn, "password_reset.html", %{
token: token,
user: user
- }
+ })
else
- _e -> render conn, "invalid_token.html"
+ _e -> render(conn, "invalid_token.html")
end
end
def password_reset(conn, %{"data" => data}) do
with {:ok, _} <- PasswordResetToken.reset_password(data["token"], data) do
- render conn, "password_reset_success.html"
+ render(conn, "password_reset_success.html")
else
- _e -> render conn, "password_reset_failed.html"
+ _e -> render(conn, "password_reset_failed.html")
end
end
@@ -34,14 +34,19 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
end
def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do
- with %User{} = user <- User.get_cached_by_nickname(nick),
- avatar = User.avatar_url(user) do
+ with %User{} = user <- User.get_cached_by_nickname(nick), avatar = User.avatar_url(user) do
conn
|> render("subscribe.html", %{nickname: nick, avatar: avatar, error: false})
else
- _e -> render(conn, "subscribe.html", %{nickname: nick, avatar: nil, error: "Could not find user"})
+ _e ->
+ render(conn, "subscribe.html", %{
+ nickname: nick,
+ avatar: nil,
+ error: "Could not find user"
+ })
end
end
+
def remote_subscribe(conn, %{"user" => %{"nickname" => nick, "profile" => profile}}) do
with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile),
%User{ap_id: ap_id} <- User.get_cached_by_nickname(nick) do
@@ -49,7 +54,11 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
|> Phoenix.Controller.redirect(external: String.replace(template, "{uri}", ap_id))
else
_e ->
- render(conn, "subscribe.html", %{nickname: nick, avatar: nil, error: "Something went wrong."})
+ render(conn, "subscribe.html", %{
+ nickname: nick,
+ avatar: nil,
+ error: "Something went wrong."
+ })
end
end
@@ -64,17 +73,26 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
|> render("follow.html", %{error: err, acct: acct, avatar: avatar, name: name, id: id})
else
conn
- |> render("follow_login.html", %{error: false, acct: acct, avatar: avatar, name: name, id: id})
+ |> render("follow_login.html", %{
+ error: false,
+ acct: acct,
+ avatar: avatar,
+ name: name,
+ id: id
+ })
end
end
- def do_remote_follow(conn, %{"authorization" => %{"name" => username, "password" => password, "id" => id}}) do
+ def do_remote_follow(conn, %{
+ "authorization" => %{"name" => username, "password" => password, "id" => id}
+ }) do
followee = Repo.get(User, id)
avatar = User.avatar_url(followee)
name = followee.nickname
+
with %User{} = user <- User.get_cached_by_nickname(username),
true <- Pbkdf2.checkpw(password, user.password_hash),
- %User{} = followed <- Repo.get(User, id),
+ %User{} = followed <- Repo.get(User, id),
{:ok, follower} <- User.follow(user, followee),
{:ok, _activity} <- ActivityPub.follow(follower, followee) do
conn
@@ -82,9 +100,15 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
else
_e ->
conn
- |> render("follow_login.html", %{error: "Wrong username or password", id: id, name: name, avatar: avatar})
+ |> render("follow_login.html", %{
+ error: "Wrong username or password",
+ id: id,
+ name: name,
+ avatar: avatar
+ })
end
end
+
def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}}) do
with %User{} = followee <- Repo.get(User, id),
{:ok, follower} <- User.follow(user, followee),
@@ -93,9 +117,10 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
|> render("followed.html", %{error: false})
else
e ->
- Logger.debug("Remote follow failed with error #{inspect e}")
- conn
- |> render("followed.html", %{error: inspect(e)})
+ Logger.debug("Remote follow failed with error #{inspect(e)}")
+
+ conn
+ |> render("followed.html", %{error: inspect(e)})
end
end
@@ -107,60 +132,67 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
<config>
<site>
<name>#{Keyword.get(@instance, :name)}</name>
- <site>#{Web.base_url}</site>
+ <site>#{Web.base_url()}</site>
<textlimit>#{Keyword.get(@instance, :limit)}</textlimit>
<closed>#{!Keyword.get(@instance, :registrations_open)}</closed>
</site>
</config>
"""
+
conn
|> put_resp_content_type("application/xml")
|> send_resp(200, response)
+
_ ->
json(conn, %{
- site: %{
- name: Keyword.get(@instance, :name),
- server: Web.base_url,
- textlimit: to_string(Keyword.get(@instance, :limit)),
- closed: if(Keyword.get(@instance, :registrations_open), do: "0", else: "1")
- }
- })
+ site: %{
+ name: Keyword.get(@instance, :name),
+ server: Web.base_url(),
+ textlimit: to_string(Keyword.get(@instance, :limit)),
+ closed: if(Keyword.get(@instance, :registrations_open), do: "0", else: "1")
+ }
+ })
end
end
def version(conn, _params) do
version = Keyword.get(@instance, :version)
+
case get_format(conn) do
"xml" ->
response = "<version>#{version}</version>"
+
conn
|> put_resp_content_type("application/xml")
|> send_resp(200, response)
- _ -> json(conn, version)
+
+ _ ->
+ json(conn, version)
end
end
def emoji(conn, _params) do
- json conn, Enum.into(Formatter.get_custom_emoji(), %{})
+ json(conn, Enum.into(Formatter.get_custom_emoji(), %{}))
end
def follow_import(conn, %{"list" => %Plug.Upload{} = listfile}) do
follow_import(conn, %{"list" => File.read!(listfile.path)})
end
+
def follow_import(%{assigns: %{user: user}} = conn, %{"list" => list}) do
Task.start(fn ->
- String.split(list)
- |> Enum.map(fn nick ->
+ String.split(list)
+ |> Enum.map(fn nick ->
with %User{} = follower <- User.get_cached_by_ap_id(user.ap_id),
- %User{} = followed <- User.get_or_fetch_by_nickname(nick),
- {:ok, follower} <- User.follow(follower, followed) do
+ %User{} = followed <- User.get_or_fetch_by_nickname(nick),
+ {:ok, follower} <- User.follow(follower, followed) do
ActivityPub.follow(follower, followed)
else
- _e -> Logger.debug "follow_import: following #{nick} failed"
+ _e -> Logger.debug("follow_import: following #{nick} failed")
end
end)
end)
- json conn, "job started"
+ json(conn, "job started")
end
end
diff --git a/lib/pleroma/web/twitter_api/representers/activity_representer.ex b/lib/pleroma/web/twitter_api/representers/activity_representer.ex
index 73ae3422b..c216c606e 100644
--- a/lib/pleroma/web/twitter_api/representers/activity_representer.ex
+++ b/lib/pleroma/web/twitter_api/representers/activity_representer.ex
@@ -7,18 +7,22 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
alias Pleroma.Formatter
defp user_by_ap_id(user_list, ap_id) do
- Enum.find(user_list, fn (%{ap_id: user_id}) -> ap_id == user_id end)
+ Enum.find(user_list, fn %{ap_id: user_id} -> ap_id == user_id end)
end
- def to_map(%Activity{data: %{"type" => "Announce", "actor" => actor, "published" => created_at}} = activity,
- %{users: users, announced_activity: announced_activity} = opts) do
+ def to_map(
+ %Activity{data: %{"type" => "Announce", "actor" => actor, "published" => created_at}} =
+ activity,
+ %{users: users, announced_activity: announced_activity} = opts
+ ) do
user = user_by_ap_id(users, actor)
- created_at = created_at |> Utils.date_to_asctime
+ created_at = created_at |> Utils.date_to_asctime()
text = "#{user.nickname} retweeted a status."
announced_user = user_by_ap_id(users, announced_activity.data["actor"])
retweeted_status = to_map(announced_activity, Map.merge(%{user: announced_user}, opts))
+
%{
"id" => activity.id,
"user" => UserView.render("show.json", %{user: user, for: opts[:for]}),
@@ -35,9 +39,11 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
}
end
- def to_map(%Activity{data: %{"type" => "Like", "published" => created_at}} = activity,
- %{user: user, liked_activity: liked_activity} = opts) do
- created_at = created_at |> Utils.date_to_asctime
+ def to_map(
+ %Activity{data: %{"type" => "Like", "published" => created_at}} = activity,
+ %{user: user, liked_activity: liked_activity} = opts
+ ) do
+ created_at = created_at |> Utils.date_to_asctime()
text = "#{user.nickname} favorited a status."
@@ -56,12 +62,16 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
}
end
- def to_map(%Activity{data: %{"type" => "Follow", "object" => followed_id}} = activity, %{user: user} = opts) do
- created_at = activity.data["published"] || (DateTime.to_iso8601(activity.inserted_at))
- created_at = created_at |> Utils.date_to_asctime
+ def to_map(
+ %Activity{data: %{"type" => "Follow", "object" => followed_id}} = activity,
+ %{user: user} = opts
+ ) do
+ created_at = activity.data["published"] || DateTime.to_iso8601(activity.inserted_at)
+ created_at = created_at |> Utils.date_to_asctime()
followed = User.get_cached_by_ap_id(followed_id)
text = "#{user.nickname} started following #{followed.nickname}"
+
%{
"id" => activity.id,
"user" => UserView.render("show.json", %{user: user, for: opts[:for]}),
@@ -79,10 +89,16 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
# TODO:
# Make this more proper. Just a placeholder to not break the frontend.
- def to_map(%Activity{data: %{"type" => "Undo", "published" => created_at, "object" => undid_activity }} = activity, %{user: user} = opts) do
- created_at = created_at |> Utils.date_to_asctime
+ def to_map(
+ %Activity{
+ data: %{"type" => "Undo", "published" => created_at, "object" => undid_activity}
+ } = activity,
+ %{user: user} = opts
+ ) do
+ created_at = created_at |> Utils.date_to_asctime()
text = "#{user.nickname} undid the action at #{undid_activity}"
+
%{
"id" => activity.id,
"user" => UserView.render("show.json", %{user: user, for: opts[:for]}),
@@ -98,8 +114,12 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
}
end
- def to_map(%Activity{data: %{"type" => "Delete", "published" => created_at, "object" => _ }} = activity, %{user: user} = opts) do
- created_at = created_at |> Utils.date_to_asctime
+ def to_map(
+ %Activity{data: %{"type" => "Delete", "published" => created_at, "object" => _}} =
+ activity,
+ %{user: user} = opts
+ ) do
+ created_at = created_at |> Utils.date_to_asctime()
%{
"id" => activity.id,
@@ -107,7 +127,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
"user" => UserView.render("show.json", %{user: user, for: opts[:for]}),
"attentions" => [],
"statusnet_html" => "deleted notice {{tag",
- "text" => "deleted notice {{tag" ,
+ "text" => "deleted notice {{tag",
"is_local" => activity.local,
"is_post_verb" => false,
"created_at" => created_at,
@@ -117,8 +137,11 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
}
end
- def to_map(%Activity{data: %{"object" => %{"content" => content} = object}} = activity, %{user: user} = opts) do
- created_at = object["published"] |> Utils.date_to_asctime
+ def to_map(
+ %Activity{data: %{"object" => %{"content" => content} = object}} = activity,
+ %{user: user} = opts
+ ) do
+ created_at = object["published"] |> Utils.date_to_asctime()
like_count = object["like_count"] || 0
announcement_count = object["announcement_count"] || 0
favorited = opts[:for] && opts[:for].ap_id in (object["likes"] || [])
@@ -126,10 +149,11 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
mentions = opts[:mentioned] || []
- attentions = activity.recipients
- |> Enum.map(fn (ap_id) -> Enum.find(mentions, fn(user) -> ap_id == user.ap_id end) end)
- |> Enum.filter(&(&1))
- |> Enum.map(fn (user) -> UserView.render("show.json", %{user: user, for: opts[:for]}) end)
+ attentions =
+ activity.recipients
+ |> Enum.map(fn ap_id -> Enum.find(mentions, fn user -> ap_id == user.ap_id end) end)
+ |> Enum.filter(& &1)
+ |> Enum.map(fn user -> UserView.render("show.json", %{user: user, for: opts[:for]}) end)
conversation_id = conversation_id(activity)
@@ -139,14 +163,17 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
tags = if possibly_sensitive, do: Enum.uniq(["nsfw" | tags]), else: tags
summary = activity.data["object"]["summary"]
- content = if !!summary and summary != "" do
- "<span>#{activity.data["object"]["summary"]}</span><br />#{content}</span>"
- else
- content
- end
- html = HtmlSanitizeEx.basic_html(content)
- |> Formatter.emojify(object["emoji"])
+ content =
+ if !!summary and summary != "" do
+ "<span>#{activity.data["object"]["summary"]}</span><br />#{content}</span>"
+ else
+ content
+ end
+
+ html =
+ HtmlSanitizeEx.basic_html(content)
+ |> Formatter.emojify(object["emoji"])
%{
"id" => activity.id,
@@ -175,7 +202,8 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenter do
def conversation_id(activity) do
with context when not is_nil(context) <- activity.data["context"] do
TwitterAPI.context_to_conversation_id(context)
- else _e -> nil
+ else
+ _e -> nil
end
end
diff --git a/lib/pleroma/web/twitter_api/representers/base_representer.ex b/lib/pleroma/web/twitter_api/representers/base_representer.ex
index 75e00520c..f32a21d47 100644
--- a/lib/pleroma/web/twitter_api/representers/base_representer.ex
+++ b/lib/pleroma/web/twitter_api/representers/base_representer.ex
@@ -1,15 +1,18 @@
defmodule Pleroma.Web.TwitterAPI.Representers.BaseRepresenter do
defmacro __using__(_opts) do
quote do
- def to_json(object) do to_json(object, %{}) end
+ def to_json(object) do
+ to_json(object, %{})
+ end
+
def to_json(object, options) do
object
|> to_map(options)
- |> Jason.encode!
+ |> Jason.encode!()
end
def enum_to_list(enum, options) do
- mapping = fn (el) -> to_map(el, options) end
+ mapping = fn el -> to_map(el, options) end
Enum.map(enum, mapping)
end
@@ -17,11 +20,14 @@ defmodule Pleroma.Web.TwitterAPI.Representers.BaseRepresenter do
to_map(object, %{})
end
- def enum_to_json(enum) do enum_to_json(enum, %{}) end
+ def enum_to_json(enum) do
+ enum_to_json(enum, %{})
+ end
+
def enum_to_json(enum, options) do
enum
|> enum_to_list(options)
- |> Jason.encode!
+ |> Jason.encode!()
end
end
end
diff --git a/lib/pleroma/web/twitter_api/representers/object_representer.ex b/lib/pleroma/web/twitter_api/representers/object_representer.ex
index e2d653ba8..9af8a1691 100644
--- a/lib/pleroma/web/twitter_api/representers/object_representer.ex
+++ b/lib/pleroma/web/twitter_api/representers/object_representer.ex
@@ -4,6 +4,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ObjectRepresenter do
def to_map(%Object{data: %{"url" => [url | _]}} = object, _opts) do
data = object.data
+
%{
url: url["href"] |> Pleroma.Web.MediaProxy.url(),
mimetype: url["mediaType"],
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index 58801bc33..4eac8a8fd 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -13,37 +13,42 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
end
def fetch_friend_statuses(user, opts \\ %{}) do
- opts = opts
- |> Map.put("blocking_user", user)
- |> Map.put("user", user)
- |> Map.put("type", ["Create", "Announce", "Follow", "Like"])
+ opts =
+ opts
+ |> Map.put("blocking_user", user)
+ |> Map.put("user", user)
+ |> Map.put("type", ["Create", "Announce", "Follow", "Like"])
ActivityPub.fetch_activities([user.ap_id | user.following], opts)
|> activities_to_statuses(%{for: user})
end
def fetch_public_statuses(user, opts \\ %{}) do
- opts = opts
- |> Map.put("local_only", true)
- |> Map.put("blocking_user", user)
- |> Map.put("type", ["Create", "Announce", "Follow"])
+ opts =
+ opts
+ |> Map.put("local_only", true)
+ |> Map.put("blocking_user", user)
+ |> Map.put("type", ["Create", "Announce", "Follow"])
ActivityPub.fetch_public_activities(opts)
|> activities_to_statuses(%{for: user})
end
def fetch_public_and_external_statuses(user, opts \\ %{}) do
- opts = opts
- |> Map.put("blocking_user", user)
- |> Map.put("type", ["Create", "Announce", "Follow"])
+ opts =
+ opts
+ |> Map.put("blocking_user", user)
+ |> Map.put("type", ["Create", "Announce", "Follow"])
ActivityPub.fetch_public_activities(opts)
|> activities_to_statuses(%{for: user})
end
def fetch_user_statuses(user, opts \\ %{}) do
- opts = opts
- |> Map.put("type", ["Create"])
+ opts =
+ opts
+ |> Map.put("type", ["Create"])
+
ActivityPub.fetch_public_activities(opts)
|> activities_to_statuses(%{for: user})
end
@@ -55,12 +60,16 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
def fetch_conversation(user, id) do
with context when is_binary(context) <- conversation_id_to_context(id),
- activities <- ActivityPub.fetch_activities_for_context(context, %{"blocking_user" => user, "user" => user}),
- statuses <- activities |> activities_to_statuses(%{for: user})
- do
+ activities <-
+ ActivityPub.fetch_activities_for_context(context, %{
+ "blocking_user" => user,
+ "user" => user
+ }),
+ statuses <- activities |> activities_to_statuses(%{for: user}) do
statuses
- else _e ->
- []
+ else
+ _e ->
+ []
end
end
@@ -74,8 +83,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
def follow(%User{} = follower, params) do
with {:ok, %User{} = followed} <- get_user(params),
{:ok, follower} <- User.follow(follower, followed),
- {:ok, activity} <- ActivityPub.follow(follower, followed)
- do
+ {:ok, activity} <- ActivityPub.follow(follower, followed) do
{:ok, follower, followed, activity}
else
err -> err
@@ -83,16 +91,17 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
end
def unfollow(%User{} = follower, params) do
- with { :ok, %User{} = unfollowed } <- get_user(params),
- { :ok, follower, follow_activity } <- User.unfollow(follower, unfollowed),
- { :ok, _activity } <- ActivityPub.insert(%{
- "type" => "Undo",
- "actor" => follower.ap_id,
- "object" => follow_activity.data["id"], # get latest Follow for these users
- "published" => make_date()
- })
- do
- { :ok, follower, unfollowed }
+ with {:ok, %User{} = unfollowed} <- get_user(params),
+ {:ok, follower, follow_activity} <- User.unfollow(follower, unfollowed),
+ {:ok, _activity} <-
+ ActivityPub.insert(%{
+ "type" => "Undo",
+ "actor" => follower.ap_id,
+ # get latest Follow for these users
+ "object" => follow_activity.data["id"],
+ "published" => make_date()
+ }) do
+ {:ok, follower, unfollowed}
else
err -> err
end
@@ -100,8 +109,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
def block(%User{} = blocker, params) do
with {:ok, %User{} = blocked} <- get_user(params),
- {:ok, blocker} <- User.block(blocker, blocked)
- do
+ {:ok, blocker} <- User.block(blocker, blocked) do
{:ok, blocker, blocked}
else
err -> err
@@ -110,8 +118,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
def unblock(%User{} = blocker, params) do
with {:ok, %User{} = blocked} <- get_user(params),
- {:ok, blocker} <- User.unblock(blocker, blocked)
- do
+ {:ok, blocker} <- User.unblock(blocker, blocked) do
{:ok, blocker, blocked}
else
err -> err
@@ -163,13 +170,15 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
<atom:link rel="enclosure" href="#{href}" type="#{type}"></atom:link>
</rsp>
"""
+
"json" ->
%{
media_id: object.id,
media_id_string: "#{object.id}}",
media_url: href,
size: 0
- } |> Jason.encode!
+ }
+ |> Jason.encode!()
end
end
@@ -189,9 +198,11 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
{:ok, user}
else
{:error, changeset} ->
- errors = Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end)
- |> Jason.encode!
- {:error, %{error: errors}}
+ errors =
+ Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end)
+ |> Jason.encode!()
+
+ {:error, %{error: errors}}
end
end
@@ -209,16 +220,20 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
case target = get_by_id_or_nickname(user_id) do
nil ->
{:error, "No user with such user_id"}
+
_ ->
{:ok, target}
end
+
%{"screen_name" => nickname} ->
case target = Repo.get_by(User, nickname: nickname) do
nil ->
{:error, "No user with such screen_name"}
+
_ ->
{:ok, target}
end
+
_ ->
if user do
{:ok, user}
@@ -229,6 +244,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
end
defp parse_int(string, default)
+
defp parse_int(string, default) when is_binary(string) do
with {n, _} <- Integer.parse(string) do
n
@@ -236,6 +252,7 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
_e -> default
end
end
+
defp parse_int(_, default), do: default
def search(user, %{"q" => query} = params) do
@@ -243,19 +260,28 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
page = parse_int(params["page"], 1)
offset = (page - 1) * limit
- q = from a in Activity,
- where: fragment("?->>'type' = 'Create'", a.data),
- where: fragment("to_tsvector('english', ?->'object'->>'content') @@ plainto_tsquery('english', ?)", a.data, ^query),
- limit: ^limit,
- offset: ^offset,
- order_by: [desc: :inserted_at] # this one isn't indexed so psql won't take the wrong index.
+ q =
+ from(
+ a in Activity,
+ where: fragment("?->>'type' = 'Create'", a.data),
+ where:
+ fragment(
+ "to_tsvector('english', ?->'object'->>'content') @@ plainto_tsquery('english', ?)",
+ a.data,
+ ^query
+ ),
+ limit: ^limit,
+ offset: ^offset,
+ # this one isn't indexed so psql won't take the wrong index.
+ order_by: [desc: :inserted_at]
+ )
activities = Repo.all(q)
activities_to_statuses(activities, %{for: user})
end
defp activities_to_statuses(activities, opts) do
- Enum.map(activities, fn(activity) ->
+ Enum.map(activities, fn activity ->
activity_to_status(activity, opts)
end)
end
@@ -266,7 +292,10 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
user = User.get_cached_by_ap_id(actor)
[liked_activity] = Activity.all_by_object_ap_id(activity.data["object"])
- ActivityRepresenter.to_map(activity, Map.merge(opts, %{user: user, liked_activity: liked_activity}))
+ ActivityRepresenter.to_map(
+ activity,
+ Map.merge(opts, %{user: user, liked_activity: liked_activity})
+ )
end
# For announces, fetch the announced activity and the user.
@@ -276,7 +305,10 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
[announced_activity] = Activity.all_by_object_ap_id(activity.data["object"])
announced_actor = User.get_cached_by_ap_id(announced_activity.data["actor"])
- ActivityRepresenter.to_map(activity, Map.merge(opts, %{users: [user, announced_actor], announced_activity: announced_activity}))
+ ActivityRepresenter.to_map(
+ activity,
+ Map.merge(opts, %{users: [user, announced_actor], announced_activity: announced_activity})
+ )
end
defp activity_to_status(%Activity{data: %{"type" => "Delete"}} = activity, opts) do
@@ -289,32 +321,41 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
actor = get_in(activity.data, ["actor"])
user = User.get_cached_by_ap_id(actor)
# mentioned_users = Repo.all(from user in User, where: user.ap_id in ^activity.data["to"])
- mentioned_users = Enum.map(activity.recipients || [], fn (ap_id) ->
- if ap_id do
- User.get_cached_by_ap_id(ap_id)
- else
- nil
- end
- end)
- |> Enum.filter(&(&1))
+ mentioned_users =
+ Enum.map(activity.recipients || [], fn ap_id ->
+ if ap_id do
+ User.get_cached_by_ap_id(ap_id)
+ else
+ nil
+ end
+ end)
+ |> Enum.filter(& &1)
- ActivityRepresenter.to_map(activity, Map.merge(opts, %{user: user, mentioned: mentioned_users}))
+ ActivityRepresenter.to_map(
+ activity,
+ Map.merge(opts, %{user: user, mentioned: mentioned_users})
+ )
end
defp make_date do
- DateTime.utc_now() |> DateTime.to_iso8601
+ DateTime.utc_now() |> DateTime.to_iso8601()
end
def context_to_conversation_id(context) do
with %Object{id: id} <- Object.get_cached_by_ap_id(context) do
id
- else _e ->
+ else
+ _e ->
changeset = Object.context_mapping(context)
+
case Repo.insert(changeset) do
- {:ok, %{id: id}} -> id
+ {:ok, %{id: id}} ->
+ id
+
# This should be solved by an upsert, but it seems ecto
# has problems accessing the constraint inside the jsonb.
- {:error, _} -> Object.get_cached_by_ap_id(context).id
+ {:error, _} ->
+ Object.get_cached_by_ap_id(context).id
end
end
end
@@ -322,8 +363,9 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
def conversation_id_to_context(id) do
with %Object{data: %{"id" => context}} <- Repo.get(Object, id) do
context
- else _e ->
- {:error, "No such conversation"}
+ else
+ _e ->
+ {:error, "No such conversation"}
end
end
@@ -331,12 +373,15 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
with %User{} = user <- User.get_or_fetch(uri) do
spawn(fn ->
with url <- user.info["topic"],
- {:ok, %{body: body}} <- @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do
+ {:ok, %{body: body}} <-
+ @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do
OStatus.handle_incoming(body)
end
end)
+
{:ok, UserView.render("show.json", %{user: user, for: for_user})}
- else _e ->
+ else
+ _e ->
{:error, "Couldn't find user"}
end
end
diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
index a3c98a245..a8bcae5ba 100644
--- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
@@ -16,7 +16,8 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
def status_update(%{assigns: %{user: user}} = conn, %{"status" => _} = status_data) do
with media_ids <- extract_media_ids(status_data),
- {:ok, activity} <- TwitterAPI.create_status(user, Map.put(status_data, "media_ids", media_ids)) do
+ {:ok, activity} <-
+ TwitterAPI.create_status(user, Map.put(status_data, "media_ids", media_ids)) do
conn
|> json(ActivityRepresenter.to_map(activity, %{user: user}))
else
@@ -35,10 +36,10 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
defp extract_media_ids(status_data) do
with media_ids when not is_nil(media_ids) <- status_data["media_ids"],
split_ids <- String.split(media_ids, ","),
- clean_ids <- Enum.reject(split_ids, fn (id) -> String.length(id) == 0 end)
- do
- clean_ids
- else _e -> []
+ clean_ids <- Enum.reject(split_ids, fn id -> String.length(id) == 0 end) do
+ clean_ids
+ else
+ _e -> []
end
end
@@ -69,9 +70,9 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
def show_user(conn, params) do
with {:ok, shown} <- TwitterAPI.get_user(params) do
if user = conn.assigns.user do
- render conn, UserView, "show.json", %{user: shown, for: user}
+ render(conn, UserView, "show.json", %{user: shown, for: user})
else
- render conn, UserView, "show.json", %{user: shown}
+ render(conn, UserView, "show.json", %{user: shown})
end
else
{:error, msg} ->
@@ -83,9 +84,11 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
case TwitterAPI.get_user(user, params) do
{:ok, target_user} ->
params = Map.merge(params, %{"actor_id" => target_user.ap_id, "whole_db" => true})
- statuses = TwitterAPI.fetch_user_statuses(user, params)
+ statuses = TwitterAPI.fetch_user_statuses(user, params)
+
conn
- |> json_reply(200, statuses |> Jason.encode!)
+ |> json_reply(200, statuses |> Jason.encode!())
+
{:error, msg} ->
bad_request_reply(conn, msg)
end
@@ -103,29 +106,36 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
case TwitterAPI.follow(user, params) do
{:ok, user, followed, _activity} ->
render(conn, UserView, "show.json", %{user: followed, for: user})
- {:error, msg} -> forbidden_json_reply(conn, msg)
+
+ {:error, msg} ->
+ forbidden_json_reply(conn, msg)
end
end
def block(%{assigns: %{user: user}} = conn, params) do
case TwitterAPI.block(user, params) do
{:ok, user, blocked} ->
- render conn, UserView, "show.json", %{user: blocked, for: user}
- {:error, msg} -> forbidden_json_reply(conn, msg)
+ render(conn, UserView, "show.json", %{user: blocked, for: user})
+
+ {:error, msg} ->
+ forbidden_json_reply(conn, msg)
end
end
def unblock(%{assigns: %{user: user}} = conn, params) do
case TwitterAPI.unblock(user, params) do
{:ok, user, blocked} ->
- render conn, UserView, "show.json", %{user: blocked, for: user}
- {:error, msg} -> forbidden_json_reply(conn, msg)
+ render(conn, UserView, "show.json", %{user: blocked, for: user})
+
+ {:error, msg} ->
+ forbidden_json_reply(conn, msg)
end
end
def delete_post(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with {:ok, delete} <- CommonAPI.delete(id, user) do
json = ActivityRepresenter.to_json(delete, %{user: user, for: user})
+
conn
|> json_reply(200, json)
end
@@ -135,14 +145,16 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
case TwitterAPI.unfollow(user, params) do
{:ok, user, unfollowed} ->
render(conn, UserView, "show.json", %{user: unfollowed, for: user})
- {:error, msg} -> forbidden_json_reply(conn, msg)
+
+ {:error, msg} ->
+ forbidden_json_reply(conn, msg)
end
end
def fetch_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Repo.get(Activity, id),
true <- ActivityPub.visible_for_user?(activity, user) do
- render conn, ActivityView, "activity.json", %{activity: activity, for: user}
+ render(conn, ActivityView, "activity.json", %{activity: activity, for: user})
end
end
@@ -156,6 +168,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
def upload(conn, %{"media" => media}) do
response = TwitterAPI.upload(media)
+
conn
|> put_resp_content_type("application/atom+xml")
|> send_resp(200, response)
@@ -163,12 +176,14 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
def upload_json(conn, %{"media" => media}) do
response = TwitterAPI.upload(media, "json")
+
conn
|> json_reply(200, response)
end
def get_by_id_or_ap_id(id) do
activity = Repo.get(Activity, id) || Activity.get_create_activity_by_object_ap_id(id)
+
if activity.data["type"] == "Create" do
activity
else
@@ -199,8 +214,8 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
render(conn, UserView, "show.json", %{user: user})
else
{:error, errors} ->
- conn
- |> json_reply(400, Jason.encode!(errors))
+ conn
+ |> json_reply(400, Jason.encode!(errors))
end
end
@@ -219,8 +234,9 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
change <- User.info_changeset(user, %{info: new_info}),
{:ok, user} <- User.update_and_set_cache(change) do
CommonAPI.update(user)
- %{"url" => [ %{ "href" => href } | _ ]} = object.data
- response = %{ url: href } |> Jason.encode!
+ %{"url" => [%{"href" => href} | _]} = object.data
+ response = %{url: href} |> Jason.encode!()
+
conn
|> json_reply(200, response)
end
@@ -231,8 +247,9 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
new_info <- Map.put(user.info, "background", object.data),
change <- User.info_changeset(user, %{info: new_info}),
{:ok, _user} <- User.update_and_set_cache(change) do
- %{"url" => [ %{ "href" => href } | _ ]} = object.data
- response = %{ url: href } |> Jason.encode!
+ %{"url" => [%{"href" => href} | _]} = object.data
+ response = %{url: href} |> Jason.encode!()
+
conn
|> json_reply(200, response)
end
@@ -285,9 +302,10 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
def friends_ids(%{assigns: %{user: user}} = conn, _params) do
with {:ok, friends} <- User.get_friends(user) do
- ids = friends
- |> Enum.map(fn x -> x.id end)
- |> Jason.encode!
+ ids =
+ friends
+ |> Enum.map(fn x -> x.id end)
+ |> Jason.encode!()
json(conn, ids)
else
@@ -300,11 +318,12 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
end
def update_profile(%{assigns: %{user: user}} = conn, params) do
- params = if bio = params["description"] do
- Map.put(params, "bio", bio)
- else
- params
- end
+ params =
+ if bio = params["description"] do
+ Map.put(params, "bio", bio)
+ else
+ params
+ end
with changeset <- User.update_changeset(user, params),
{:ok, user} <- User.update_and_set_cache(changeset) do
@@ -339,6 +358,6 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
end
defp error_json(conn, error_message) do
- %{"error" => error_message, "request" => conn.request_path} |> Jason.encode!
+ %{"error" => error_message, "request" => conn.request_path} |> Jason.encode!()
end
end
diff --git a/lib/pleroma/web/twitter_api/views/activity_view.ex b/lib/pleroma/web/twitter_api/views/activity_view.ex
index 50d536d0e..1596b34dc 100644
--- a/lib/pleroma/web/twitter_api/views/activity_view.ex
+++ b/lib/pleroma/web/twitter_api/views/activity_view.ex
@@ -10,7 +10,7 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
def render("activity.json", %{activity: %{data: %{"type" => "Announce"}} = activity} = opts) do
user = User.get_by_ap_id(activity.data["actor"])
- created_at = activity.data["published"] |> Utils.date_to_asctime
+ created_at = activity.data["published"] |> Utils.date_to_asctime()
announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
text = "#{user.nickname} retweeted a status."
@@ -37,8 +37,10 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
def render("activity.json", %{activity: %{data: %{"type" => "Like"}} = activity} = opts) do
user = User.get_cached_by_ap_id(activity.data["actor"])
liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"])
- created_at = activity.data["published"]
- |> Utils.date_to_asctime
+
+ created_at =
+ activity.data["published"]
+ |> Utils.date_to_asctime()
text = "#{user.nickname} favorited a status."
@@ -57,20 +59,24 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
}
end
- def render("activity.json", %{activity: %{data: %{"type" => "Create", "object" => object}} = activity} = opts) do
+ def render(
+ "activity.json",
+ %{activity: %{data: %{"type" => "Create", "object" => object}} = activity} = opts
+ ) do
actor = get_in(activity.data, ["actor"])
user = User.get_cached_by_ap_id(actor)
- created_at = object["published"] |> Utils.date_to_asctime
+ created_at = object["published"] |> Utils.date_to_asctime()
like_count = object["like_count"] || 0
announcement_count = object["announcement_count"] || 0
favorited = opts[:for] && opts[:for].ap_id in (object["likes"] || [])
repeated = opts[:for] && opts[:for].ap_id in (object["announcements"] || [])
- attentions = activity.recipients
- |> Enum.map(fn (ap_id) -> User.get_cached_by_ap_id(ap_id) end)
- |> Enum.filter(&(&1))
- |> Enum.map(fn (user) -> UserView.render("show.json", %{user: user, for: opts[:for]}) end)
+ attentions =
+ activity.recipients
+ |> Enum.map(fn ap_id -> User.get_cached_by_ap_id(ap_id) end)
+ |> Enum.filter(& &1)
+ |> Enum.map(fn user -> UserView.render("show.json", %{user: user, for: opts[:for]}) end)
conversation_id = conversation_id(activity)
@@ -81,14 +87,17 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
summary = activity.data["object"]["summary"]
content = object["content"]
- content = if !!summary and summary != "" do
- "<span>#{activity.data["object"]["summary"]}</span><br />#{content}</span>"
- else
- content
- end
- html = HtmlSanitizeEx.basic_html(content)
- |> Formatter.emojify(object["emoji"])
+ content =
+ if !!summary and summary != "" do
+ "<span>#{activity.data["object"]["summary"]}</span><br />#{content}</span>"
+ else
+ content
+ end
+
+ html =
+ HtmlSanitizeEx.basic_html(content)
+ |> Formatter.emojify(object["emoji"])
%{
"id" => activity.id,
@@ -117,7 +126,8 @@ defmodule Pleroma.Web.TwitterAPI.ActivityView do
defp conversation_id(activity) do
with context when not is_nil(context) <- activity.data["context"] do
TwitterAPI.context_to_conversation_id(context)
- else _e -> nil
+ else
+ _e -> nil
end
end
end
diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex
index 6fb07f052..31527caae 100644
--- a/lib/pleroma/web/twitter_api/views/user_view.ex
+++ b/lib/pleroma/web/twitter_api/views/user_view.ex
@@ -14,20 +14,22 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
def render("user.json", %{user: user = %User{}} = assigns) do
image = User.avatar_url(user) |> MediaProxy.url()
- {following, follows_you, statusnet_blocking} = if assigns[:for] do
- {
- User.following?(assigns[:for], user),
- User.following?(user, assigns[:for]),
- User.blocks?(assigns[:for], user)
- }
- else
- {false, false, false}
- end
+
+ {following, follows_you, statusnet_blocking} =
+ if assigns[:for] do
+ {
+ User.following?(assigns[:for], user),
+ User.following?(user, assigns[:for]),
+ User.blocks?(assigns[:for], user)
+ }
+ else
+ {false, false, false}
+ end
user_info = User.get_cached_user_info(user)
data = %{
- "created_at" => user.inserted_at |> Utils.format_naive_asctime,
+ "created_at" => user.inserted_at |> Utils.format_naive_asctime(),
"description" => HtmlSanitizeEx.strip_tags(user.bio),
"favourites_count" => 0,
"followers_count" => user_info[:follower_count],
@@ -59,9 +61,14 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
end
end
- def render("short.json", %{user: %User{
- nickname: nickname, id: id, ap_id: ap_id, name: name
- }}) do
+ def render("short.json", %{
+ user: %User{
+ nickname: nickname,
+ id: id,
+ ap_id: ap_id,
+ name: name
+ }
+ }) do
%{
"fullname" => name,
"id" => id,
@@ -71,6 +78,6 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
}
end
- defp image_url(%{"url" => [ %{ "href" => href } | _ ]}), do: href
+ defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
defp image_url(_), do: nil
end
diff --git a/lib/pleroma/web/views/error_view.ex b/lib/pleroma/web/views/error_view.ex
index 6c589d3a1..7106031ae 100644
--- a/lib/pleroma/web/views/error_view.ex
+++ b/lib/pleroma/web/views/error_view.ex
@@ -12,6 +12,6 @@ defmodule Pleroma.Web.ErrorView do
# In case no render clause matches or no
# template is found, let's render it as 500
def template_not_found(_template, assigns) do
- render "500.json", assigns
+ render("500.json", assigns)
end
end
diff --git a/lib/pleroma/web/web.ex b/lib/pleroma/web/web.ex
index 2c343c2d7..b82242a78 100644
--- a/lib/pleroma/web/web.ex
+++ b/lib/pleroma/web/web.ex
@@ -26,8 +26,9 @@ defmodule Pleroma.Web do
def view do
quote do
- use Phoenix.View, root: "lib/pleroma/web/templates",
- namespace: Pleroma.Web
+ use Phoenix.View,
+ root: "lib/pleroma/web/templates",
+ namespace: Pleroma.Web
# Import convenience functions from controllers
import Phoenix.Controller, only: [get_csrf_token: 0, get_flash: 2, view_module: 1]
@@ -59,6 +60,6 @@ defmodule Pleroma.Web do
end
def base_url do
- Pleroma.Web.Endpoint.url
+ Pleroma.Web.Endpoint.url()
end
end
diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex
index 8edb89963..e45c0ed8d 100644
--- a/lib/pleroma/web/web_finger/web_finger.ex
+++ b/lib/pleroma/web/web_finger/web_finger.ex
@@ -8,43 +8,56 @@ defmodule Pleroma.Web.WebFinger do
require Logger
def host_meta do
- base_url = Web.base_url
+ base_url = Web.base_url()
+
{
- :XRD, %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
+ :XRD,
+ %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
{
- :Link, %{rel: "lrdd", type: "application/xrd+xml", template: "#{base_url}/.well-known/webfinger?resource={uri}"}
+ :Link,
+ %{
+ rel: "lrdd",
+ type: "application/xrd+xml",
+ template: "#{base_url}/.well-known/webfinger?resource={uri}"
+ }
}
}
- |> XmlBuilder.to_doc
+ |> XmlBuilder.to_doc()
end
def webfinger(resource, "JSON") do
- host = Pleroma.Web.Endpoint.host
+ host = Pleroma.Web.Endpoint.host()
regex = ~r/(acct:)?(?<username>\w+)@#{host}/
+
with %{"username" => username} <- Regex.named_captures(regex, resource) do
user = User.get_by_nickname(username)
{:ok, represent_user(user, "JSON")}
- else _e ->
- with user when not is_nil(user) <- User.get_cached_by_ap_id(resource) do
- {:ok, represent_user(user, "JSON")}
- else _e ->
- {:error, "Couldn't find user"}
- end
+ else
+ _e ->
+ with user when not is_nil(user) <- User.get_cached_by_ap_id(resource) do
+ {:ok, represent_user(user, "JSON")}
+ else
+ _e ->
+ {:error, "Couldn't find user"}
+ end
end
end
def webfinger(resource, "XML") do
- host = Pleroma.Web.Endpoint.host
+ host = Pleroma.Web.Endpoint.host()
regex = ~r/(acct:)?(?<username>\w+)@#{host}/
+
with %{"username" => username} <- Regex.named_captures(regex, resource) do
user = User.get_by_nickname(username)
{:ok, represent_user(user, "XML")}
- else _e ->
- with user when not is_nil(user) <- User.get_cached_by_ap_id(resource) do
- {:ok, represent_user(user, "XML")}
- else _e ->
- {:error, "Couldn't find user"}
- end
+ else
+ _e ->
+ with user when not is_nil(user) <- User.get_cached_by_ap_id(resource) do
+ {:ok, represent_user(user, "XML")}
+ else
+ _e ->
+ {:error, "Couldn't find user"}
+ end
end
end
@@ -52,16 +65,28 @@ defmodule Pleroma.Web.WebFinger do
{:ok, user} = ensure_keys_present(user)
{:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"])
magic_key = Salmon.encode_key(public)
+
%{
- "subject" => "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host}",
+ "subject" => "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}",
"aliases" => [user.ap_id],
"links" => [
- %{"rel" => "http://schemas.google.com/g/2010#updates-from", "type" => "application/atom+xml", "href" => OStatus.feed_path(user)},
- %{"rel" => "http://webfinger.net/rel/profile-page", "type" => "text/html", "href" => user.ap_id},
+ %{
+ "rel" => "http://schemas.google.com/g/2010#updates-from",
+ "type" => "application/atom+xml",
+ "href" => OStatus.feed_path(user)
+ },
+ %{
+ "rel" => "http://webfinger.net/rel/profile-page",
+ "type" => "text/html",
+ "href" => user.ap_id
+ },
%{"rel" => "salmon", "href" => OStatus.salmon_path(user)},
%{"rel" => "magic-public-key", "href" => "data:application/magic-public-key,#{magic_key}"},
%{"rel" => "self", "type" => "application/activity+json", "href" => user.ap_id},
- %{"rel" => "http://ostatus.org/schema/1.0/subscribe", "template" => OStatus.remote_follow_path()}
+ %{
+ "rel" => "http://ostatus.org/schema/1.0/subscribe",
+ "template" => OStatus.remote_follow_path()
+ }
]
}
end
@@ -70,30 +95,42 @@ defmodule Pleroma.Web.WebFinger do
{:ok, user} = ensure_keys_present(user)
{:ok, _private, public} = Salmon.keys_from_pem(user.info["keys"])
magic_key = Salmon.encode_key(public)
+
{
- :XRD, %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
+ :XRD,
+ %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},
[
- {:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host}"},
+ {:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}"},
{:Alias, user.ap_id},
- {:Link, %{rel: "http://schemas.google.com/g/2010#updates-from", type: "application/atom+xml", href: OStatus.feed_path(user)}},
- {:Link, %{rel: "http://webfinger.net/rel/profile-page", type: "text/html", href: user.ap_id}},
+ {:Link,
+ %{
+ rel: "http://schemas.google.com/g/2010#updates-from",
+ type: "application/atom+xml",
+ href: OStatus.feed_path(user)
+ }},
+ {:Link,
+ %{rel: "http://webfinger.net/rel/profile-page", type: "text/html", href: user.ap_id}},
{:Link, %{rel: "salmon", href: OStatus.salmon_path(user)}},
- {:Link, %{rel: "magic-public-key", href: "data:application/magic-public-key,#{magic_key}"}},
+ {:Link,
+ %{rel: "magic-public-key", href: "data:application/magic-public-key,#{magic_key}"}},
{:Link, %{rel: "self", type: "application/activity+json", href: user.ap_id}},
- {:Link, %{rel: "http://ostatus.org/schema/1.0/subscribe", template: OStatus.remote_follow_path()}}
+ {:Link,
+ %{rel: "http://ostatus.org/schema/1.0/subscribe", template: OStatus.remote_follow_path()}}
]
}
- |> XmlBuilder.to_doc
+ |> XmlBuilder.to_doc()
end
# This seems a better fit in Salmon
def ensure_keys_present(user) do
info = user.info || %{}
+
if info["keys"] do
{:ok, user}
else
- {:ok, pem} = Salmon.generate_rsa_pem
+ {:ok, pem} = Salmon.generate_rsa_pem()
info = Map.put(info, "keys", pem)
+
Ecto.Changeset.change(user, info: info)
|> User.update_and_set_cache()
end
@@ -102,11 +139,28 @@ defmodule Pleroma.Web.WebFinger do
defp webfinger_from_xml(doc) do
magic_key = XML.string_from_xpath(~s{//Link[@rel="magic-public-key"]/@href}, doc)
"data:application/magic-public-key," <> magic_key = magic_key
- topic = XML.string_from_xpath(~s{//Link[@rel="http://schemas.google.com/g/2010#updates-from"]/@href}, doc)
+
+ topic =
+ XML.string_from_xpath(
+ ~s{//Link[@rel="http://schemas.google.com/g/2010#updates-from"]/@href},
+ doc
+ )
+
subject = XML.string_from_xpath("//Subject", doc)
salmon = XML.string_from_xpath(~s{//Link[@rel="salmon"]/@href}, doc)
- subscribe_address = XML.string_from_xpath(~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template}, doc)
- ap_id = XML.string_from_xpath(~s{//Link[@rel="self" and @type="application/activity+json"]/@href}, doc)
+
+ subscribe_address =
+ XML.string_from_xpath(
+ ~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template},
+ doc
+ )
+
+ ap_id =
+ XML.string_from_xpath(
+ ~s{//Link[@rel="self" and @type="application/activity+json"]/@href},
+ doc
+ )
+
data = %{
"magic_key" => magic_key,
"topic" => topic,
@@ -115,41 +169,51 @@ defmodule Pleroma.Web.WebFinger do
"subscribe_address" => subscribe_address,
"ap_id" => ap_id
}
+
{:ok, data}
end
defp webfinger_from_json(doc) do
- data = Enum.reduce(doc["links"], %{"subject" => doc["subject"]}, fn (link, data) ->
- case {link["type"], link["rel"]} do
- {"application/activity+json", "self"} ->
- Map.put(data, "ap_id", link["href"])
- {_, "magic-public-key"} ->
- "data:application/magic-public-key," <> magic_key = link["href"]
- Map.put(data, "magic_key", magic_key)
- {"application/atom+xml", "http://schemas.google.com/g/2010#updates-from"} ->
- Map.put(data, "topic", link["href"])
- {_, "salmon"} ->
- Map.put(data, "salmon", link["href"])
- {_, "http://ostatus.org/schema/1.0/subscribe"} ->
- Map.put(data, "subscribe_address", link["template"])
- _ ->
- Logger.debug("Unhandled type: #{inspect(link["type"])}")
- data
- end
- end)
+ data =
+ Enum.reduce(doc["links"], %{"subject" => doc["subject"]}, fn link, data ->
+ case {link["type"], link["rel"]} do
+ {"application/activity+json", "self"} ->
+ Map.put(data, "ap_id", link["href"])
+
+ {_, "magic-public-key"} ->
+ "data:application/magic-public-key," <> magic_key = link["href"]
+ Map.put(data, "magic_key", magic_key)
+
+ {"application/atom+xml", "http://schemas.google.com/g/2010#updates-from"} ->
+ Map.put(data, "topic", link["href"])
+
+ {_, "salmon"} ->
+ Map.put(data, "salmon", link["href"])
+
+ {_, "http://ostatus.org/schema/1.0/subscribe"} ->
+ Map.put(data, "subscribe_address", link["template"])
+
+ _ ->
+ Logger.debug("Unhandled type: #{inspect(link["type"])}")
+ data
+ end
+ end)
+
{:ok, data}
end
def get_template_from_xml(body) do
xpath = "//Link[@rel='lrdd' and @type='application/xrd+xml']/@template"
+
with doc when doc != :error <- XML.parse_document(body),
- template when template != nil <- XML.string_from_xpath(xpath, doc) do
+ template when template != nil <- XML.string_from_xpath(xpath, doc) do
{:ok, template}
end
end
def find_lrdd_template(domain) do
- with {:ok, %{status_code: status_code, body: body}} when status_code in 200..299 <- @httpoison.get("http://#{domain}/.well-known/host-meta", [], follow_redirect: true) do
+ with {:ok, %{status_code: status_code, body: body}} when status_code in 200..299 <-
+ @httpoison.get("http://#{domain}/.well-known/host-meta", [], follow_redirect: true) do
get_template_from_xml(body)
else
_ ->
@@ -163,28 +227,38 @@ defmodule Pleroma.Web.WebFinger do
def finger(account) do
account = String.trim_leading(account, "@")
- domain = with [_name, domain] <- String.split(account, "@") do
- domain
- else _e ->
- URI.parse(account).host
- end
+
+ domain =
+ with [_name, domain] <- String.split(account, "@") do
+ domain
+ else
+ _e ->
+ URI.parse(account).host
+ end
case find_lrdd_template(domain) do
{:ok, template} ->
address = String.replace(template, "{uri}", URI.encode(account))
+
_ ->
address = "http://#{domain}/.well-known/webfinger?resource=acct:#{account}"
end
- with response <- @httpoison.get(address, ["Accept": "application/xrd+xml,application/jrd+json"], follow_redirect: true),
+ with response <-
+ @httpoison.get(
+ address,
+ [Accept: "application/xrd+xml,application/jrd+json"],
+ follow_redirect: true
+ ),
{:ok, %{status_code: status_code, body: body}} when status_code in 200..299 <- response do
- doc = XML.parse_document(body)
- if doc != :error do
- webfinger_from_xml(doc)
- else
- {:ok, doc} = Jason.decode(body)
- webfinger_from_json(doc)
- end
+ doc = XML.parse_document(body)
+
+ if doc != :error do
+ webfinger_from_xml(doc)
+ else
+ {:ok, doc} = Jason.decode(body)
+ webfinger_from_json(doc)
+ end
else
e ->
Logger.debug(fn -> "Couldn't finger #{account}" end)
diff --git a/lib/pleroma/web/web_finger/web_finger_controller.ex b/lib/pleroma/web/web_finger/web_finger_controller.ex
index eb54346c1..50d816256 100644
--- a/lib/pleroma/web/web_finger/web_finger_controller.ex
+++ b/lib/pleroma/web/web_finger/web_finger_controller.ex
@@ -4,7 +4,7 @@ defmodule Pleroma.Web.WebFinger.WebFingerController do
alias Pleroma.Web.WebFinger
def host_meta(conn, _params) do
- xml = WebFinger.host_meta
+ xml = WebFinger.host_meta()
conn
|> put_resp_content_type("application/xrd+xml")
@@ -21,12 +21,14 @@ defmodule Pleroma.Web.WebFinger.WebFingerController do
else
_e -> send_resp(conn, 404, "Couldn't find user")
end
+
n when n in ["json", "jrd+json"] ->
with {:ok, response} <- WebFinger.webfinger(resource, "JSON") do
json(conn, response)
else
_e -> send_resp(conn, 404, "Couldn't find user")
end
+
_ ->
send_resp(conn, 404, "Unsupported format")
end
diff --git a/lib/pleroma/web/websub/websub.ex b/lib/pleroma/web/websub/websub.ex
index 5caa8198c..e494811f9 100644
--- a/lib/pleroma/web/websub/websub.ex
+++ b/lib/pleroma/web/websub/websub.ex
@@ -26,15 +26,16 @@ defmodule Pleroma.Web.Websub do
url = hd(String.split(subscription.callback, "?"))
query = URI.parse(subscription.callback).query || ""
params = Map.merge(params, URI.decode_query(query))
- with {:ok, response} <- getter.(url, [], [params: params]),
- ^challenge <- response.body
- do
+
+ with {:ok, response} <- getter.(url, [], params: params),
+ ^challenge <- response.body do
changeset = Changeset.change(subscription, %{state: "active"})
Repo.update(changeset)
- else e ->
- Logger.debug("Couldn't verify subscription")
- Logger.debug(inspect(e))
- {:error, subscription}
+ else
+ e ->
+ Logger.debug("Couldn't verify subscription")
+ Logger.debug(inspect(e))
+ {:error, subscription}
end
end
@@ -46,17 +47,24 @@ defmodule Pleroma.Web.Websub do
"Undo",
"Delete"
]
- def publish(topic, user, %{data: %{"type" => type}} = activity) when type in @supported_activities do
+ def publish(topic, user, %{data: %{"type" => type}} = activity)
+ when type in @supported_activities do
# TODO: Only send to still valid subscriptions.
- query = from sub in WebsubServerSubscription,
- where: sub.topic == ^topic and sub.state == "active",
- where: fragment("? > NOW()", sub.valid_until)
+ query =
+ from(
+ sub in WebsubServerSubscription,
+ where: sub.topic == ^topic and sub.state == "active",
+ where: fragment("? > NOW()", sub.valid_until)
+ )
+
subscriptions = Repo.all(query)
- Enum.each(subscriptions, fn(sub) ->
- response = user
- |> FeedRepresenter.to_simple_form([activity], [user])
- |> :xmerl.export_simple(:xmerl_xml)
- |> to_string
+
+ Enum.each(subscriptions, fn sub ->
+ response =
+ user
+ |> FeedRepresenter.to_simple_form([activity], [user])
+ |> :xmerl.export_simple(:xmerl_xml)
+ |> to_string
data = %{
xml: response,
@@ -64,22 +72,24 @@ defmodule Pleroma.Web.Websub do
callback: sub.callback,
secret: sub.secret
}
+
Pleroma.Web.Federator.enqueue(:publish_single_websub, data)
end)
end
- def publish(_,_,_), do: ""
+
+ def publish(_, _, _), 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()
end
def incoming_subscription_request(user, %{"hub.mode" => "subscribe"} = params) do
with {:ok, topic} <- valid_topic(params, user),
{:ok, lease_time} <- lease_time(params),
secret <- params["hub.secret"],
- callback <- params["hub.callback"]
- do
+ callback <- params["hub.callback"] do
subscription = get_subscription(topic, callback)
+
data = %{
state: subscription.state || "requested",
topic: topic,
@@ -90,18 +100,20 @@ defmodule Pleroma.Web.Websub do
change = Changeset.change(subscription, data)
websub = Repo.insert_or_update!(change)
- change = Changeset.change(websub, %{valid_until:
- NaiveDateTime.add(websub.updated_at, lease_time)})
+ change =
+ Changeset.change(websub, %{valid_until: NaiveDateTime.add(websub.updated_at, lease_time)})
+
websub = Repo.update!(change)
Pleroma.Web.Federator.enqueue(:verify_websub, websub)
{:ok, websub}
- else {:error, reason} ->
- Logger.debug("Couldn't create subscription")
- Logger.debug(inspect(reason))
+ else
+ {:error, reason} ->
+ Logger.debug("Couldn't create subscription")
+ Logger.debug(inspect(reason))
- {:error, reason}
+ {:error, reason}
end
end
@@ -112,7 +124,8 @@ defmodule Pleroma.Web.Websub do
# Temp hack for mastodon.
defp lease_time(%{"hub.lease_seconds" => ""}) do
- {:ok, 60 * 60 * 24 * 3} # three days
+ # three days
+ {:ok, 60 * 60 * 24 * 3}
end
defp lease_time(%{"hub.lease_seconds" => lease_seconds}) do
@@ -120,7 +133,8 @@ defmodule Pleroma.Web.Websub do
end
defp lease_time(_) do
- {:ok, 60 * 60 * 24 * 3} # three days
+ # three days
+ {:ok, 60 * 60 * 24 * 3}
end
defp valid_topic(%{"hub.topic" => topic}, user) do
@@ -134,21 +148,26 @@ defmodule Pleroma.Web.Websub do
def subscribe(subscriber, subscribed, requester \\ &request_subscription/1) do
topic = subscribed.info["topic"]
# FIXME: Race condition, use transactions
- {:ok, subscription} = with subscription when not is_nil(subscription) <- Repo.get_by(WebsubClientSubscription, topic: topic) do
- subscribers = [subscriber.ap_id | subscription.subscribers] |> Enum.uniq
- change = Ecto.Changeset.change(subscription, %{subscribers: subscribers})
- Repo.update(change)
- else _e ->
- subscription = %WebsubClientSubscription{
- topic: topic,
- hub: subscribed.info["hub"],
- subscribers: [subscriber.ap_id],
- state: "requested",
- secret: :crypto.strong_rand_bytes(8) |> Base.url_encode64,
- user: subscribed
- }
- Repo.insert(subscription)
- end
+ {:ok, subscription} =
+ with subscription when not is_nil(subscription) <-
+ Repo.get_by(WebsubClientSubscription, topic: topic) do
+ subscribers = [subscriber.ap_id | subscription.subscribers] |> Enum.uniq()
+ change = Ecto.Changeset.change(subscription, %{subscribers: subscribers})
+ Repo.update(change)
+ else
+ _e ->
+ subscription = %WebsubClientSubscription{
+ topic: topic,
+ hub: subscribed.info["hub"],
+ subscribers: [subscriber.ap_id],
+ state: "requested",
+ secret: :crypto.strong_rand_bytes(8) |> Base.url_encode64(),
+ user: subscribed
+ }
+
+ Repo.insert(subscription)
+ end
+
requester.(subscription)
end
@@ -159,24 +178,25 @@ defmodule Pleroma.Web.Websub do
doc <- XML.parse_document(body),
uri when not is_nil(uri) <- XML.string_from_xpath("/feed/author[1]/uri", doc),
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)
preferredUsername = XML.string_from_xpath("/feed/author[1]/poco:preferredUsername", doc)
displayName = XML.string_from_xpath("/feed/author[1]/poco:displayName", doc)
avatar = OStatus.make_avatar_object(doc)
bio = XML.string_from_xpath("/feed/author[1]/summary", doc)
- {:ok, %{
- "uri" => uri,
- "hub" => hub,
- "nickname" => preferredUsername || name,
- "name" => displayName || name,
- "host" => URI.parse(uri).host,
- "avatar" => avatar,
- "bio" => bio
- }}
- else e ->
- {:error, e}
+ {:ok,
+ %{
+ "uri" => uri,
+ "hub" => hub,
+ "nickname" => preferredUsername || name,
+ "name" => displayName || name,
+ "host" => URI.parse(uri).host,
+ "avatar" => avatar,
+ "bio" => bio
+ }}
+ else
+ e ->
+ {:error, e}
end
end
@@ -190,43 +210,45 @@ defmodule Pleroma.Web.Websub do
# This checks once a second if we are confirmed yet
websub_checker = fn ->
- helper = fn (helper) ->
+ helper = fn helper ->
:timer.sleep(1000)
websub = Repo.get_by(WebsubClientSubscription, id: websub.id, state: "accepted")
if websub, do: websub, else: helper.(helper)
end
+
helper.(helper)
end
task = Task.async(websub_checker)
- with {:ok, %{status_code: 202}} <- poster.(websub.hub, {:form, data}, ["Content-type": "application/x-www-form-urlencoded"]),
+ with {:ok, %{status_code: 202}} <-
+ poster.(websub.hub, {:form, data}, "Content-type": "application/x-www-form-urlencoded"),
{:ok, websub} <- Task.yield(task, timeout) do
{:ok, websub}
- else e ->
- Task.shutdown(task)
+ else
+ e ->
+ Task.shutdown(task)
- change = Ecto.Changeset.change(websub, %{state: "rejected"})
- {:ok, websub} = Repo.update(change)
+ change = Ecto.Changeset.change(websub, %{state: "rejected"})
+ {:ok, websub} = Repo.update(change)
- Logger.debug(fn -> "Couldn't confirm subscription: #{inspect(websub)}" end)
- Logger.debug(fn -> "error: #{inspect(e)}" end)
+ Logger.debug(fn -> "Couldn't confirm subscription: #{inspect(websub)}" end)
+ Logger.debug(fn -> "error: #{inspect(e)}" end)
- {:error, websub}
+ {:error, websub}
end
end
def refresh_subscriptions(delta \\ 60 * 60 * 24) do
Logger.debug("Refreshing subscriptions")
- cut_off = NaiveDateTime.add(NaiveDateTime.utc_now, delta)
+ cut_off = NaiveDateTime.add(NaiveDateTime.utc_now(), delta)
- query = from sub in WebsubClientSubscription,
- where: sub.valid_until < ^cut_off
+ query = from(sub in WebsubClientSubscription, where: sub.valid_until < ^cut_off)
subs = Repo.all(query)
- Enum.each(subs, fn (sub) ->
+ Enum.each(subs, fn sub ->
Pleroma.Web.Federator.enqueue(:request_subscription, sub)
end)
end
diff --git a/lib/pleroma/web/websub/websub_client_subscription.ex b/lib/pleroma/web/websub/websub_client_subscription.ex
index c7a25ea22..8cea02939 100644
--- a/lib/pleroma/web/websub/websub_client_subscription.ex
+++ b/lib/pleroma/web/websub/websub_client_subscription.ex
@@ -3,13 +3,13 @@ defmodule Pleroma.Web.Websub.WebsubClientSubscription do
alias Pleroma.User
schema "websub_client_subscriptions" do
- field :topic, :string
- field :secret, :string
- field :valid_until, :naive_datetime
- field :state, :string
- field :subscribers, {:array, :string}, default: []
- field :hub, :string
- belongs_to :user, User
+ field(:topic, :string)
+ field(:secret, :string)
+ field(:valid_until, :naive_datetime)
+ field(:state, :string)
+ field(:subscribers, {:array, :string}, default: [])
+ field(:hub, :string)
+ belongs_to(:user, User)
timestamps()
end
diff --git a/lib/pleroma/web/websub/websub_controller.ex b/lib/pleroma/web/websub/websub_controller.ex
index 115b64902..590dd74a1 100644
--- a/lib/pleroma/web/websub/websub_controller.ex
+++ b/lib/pleroma/web/websub/websub_controller.ex
@@ -8,36 +8,49 @@ defmodule Pleroma.Web.Websub.WebsubController do
def websub_subscription_request(conn, %{"nickname" => nickname} = params) do
user = User.get_cached_by_nickname(nickname)
- with {:ok, _websub} <- Websub.incoming_subscription_request(user, params)
- do
+ with {:ok, _websub} <- Websub.incoming_subscription_request(user, params) do
conn
|> send_resp(202, "Accepted")
- else {:error, reason} ->
- conn
- |> send_resp(500, reason)
+ else
+ {:error, reason} ->
+ conn
+ |> send_resp(500, reason)
end
end
# TODO: Extract this into the Websub module
- def websub_subscription_confirmation(conn, %{"id" => id, "hub.mode" => "subscribe", "hub.challenge" => challenge, "hub.topic" => topic} = params) do
+ def websub_subscription_confirmation(
+ conn,
+ %{
+ "id" => id,
+ "hub.mode" => "subscribe",
+ "hub.challenge" => challenge,
+ "hub.topic" => topic
+ } = params
+ ) do
Logger.debug("Got WebSub confirmation")
Logger.debug(inspect(params))
- lease_seconds = if params["hub.lease_seconds"] do
- String.to_integer(params["hub.lease_seconds"])
- else
- # Guess 3 days
- 60 * 60 * 24 * 3
- end
- with %WebsubClientSubscription{} = websub <- Repo.get_by(WebsubClientSubscription, id: id, topic: topic) do
- valid_until = NaiveDateTime.add(NaiveDateTime.utc_now, lease_seconds)
+ lease_seconds =
+ if params["hub.lease_seconds"] do
+ String.to_integer(params["hub.lease_seconds"])
+ else
+ # Guess 3 days
+ 60 * 60 * 24 * 3
+ end
+
+ with %WebsubClientSubscription{} = websub <-
+ Repo.get_by(WebsubClientSubscription, id: id, topic: topic) do
+ valid_until = NaiveDateTime.add(NaiveDateTime.utc_now(), lease_seconds)
change = Ecto.Changeset.change(websub, %{state: "accepted", valid_until: valid_until})
{:ok, _websub} = Repo.update(change)
+
conn
|> send_resp(200, challenge)
- else _e ->
- conn
- |> send_resp(500, "Error")
+ else
+ _e ->
+ conn
+ |> send_resp(500, "Error")
end
end
@@ -48,12 +61,15 @@ defmodule Pleroma.Web.Websub.WebsubController do
{:ok, body, _conn} = read_body(conn),
^signature <- Websub.sign(websub.secret, body) do
Federator.enqueue(:incoming_doc, body)
+
conn
|> send_resp(200, "OK")
- else _e ->
- Logger.debug("Can't handle incoming subscription post")
- conn
- |> send_resp(500, "Error")
+ else
+ _e ->
+ Logger.debug("Can't handle incoming subscription post")
+
+ conn
+ |> send_resp(500, "Error")
end
end
end
diff --git a/lib/pleroma/web/websub/websub_server_subscription.ex b/lib/pleroma/web/websub/websub_server_subscription.ex
index a29dd5860..0e5248a73 100644
--- a/lib/pleroma/web/websub/websub_server_subscription.ex
+++ b/lib/pleroma/web/websub/websub_server_subscription.ex
@@ -2,11 +2,11 @@ defmodule Pleroma.Web.Websub.WebsubServerSubscription do
use Ecto.Schema
schema "websub_server_subscriptions" do
- field :topic, :string
- field :callback, :string
- field :secret, :string
- field :valid_until, :naive_datetime
- field :state, :string
+ field(:topic, :string)
+ field(:callback, :string)
+ field(:secret, :string)
+ field(:valid_until, :naive_datetime)
+ field(:state, :string)
timestamps()
end
diff --git a/lib/pleroma/web/xml/xml.ex b/lib/pleroma/web/xml/xml.ex
index 8b28a7e7d..b85712d65 100644
--- a/lib/pleroma/web/xml/xml.ex
+++ b/lib/pleroma/web/xml/xml.ex
@@ -2,21 +2,24 @@ defmodule Pleroma.Web.XML do
require Logger
def string_from_xpath(_, :error), do: nil
+
def string_from_xpath(xpath, doc) do
{:xmlObj, :string, res} = :xmerl_xpath.string('string(#{xpath})', doc)
- res = res
- |> to_string
- |> String.trim
+ res =
+ res
+ |> to_string
+ |> String.trim()
if res == "", do: nil, else: res
end
def parse_document(text) do
try do
- {doc, _rest} = text
- |> :binary.bin_to_list
- |> :xmerl_scan.string
+ {doc, _rest} =
+ text
+ |> :binary.bin_to_list()
+ |> :xmerl_scan.string()
doc
catch
diff --git a/lib/transports.ex b/lib/transports.ex
index a820aa778..42f645b21 100644
--- a/lib/transports.ex
+++ b/lib/transports.ex
@@ -1,8 +1,10 @@
defmodule Phoenix.Transports.WebSocket.Raw do
- import Plug.Conn, only: [
- fetch_query_params: 1,
- send_resp: 3
- ]
+ import Plug.Conn,
+ only: [
+ fetch_query_params: 1,
+ send_resp: 3
+ ]
+
alias Phoenix.Socket.Transport
def default_config do
@@ -16,21 +18,24 @@ defmodule Phoenix.Transports.WebSocket.Raw do
def init(%Plug.Conn{method: "GET"} = conn, {endpoint, handler, transport}) do
{_, opts} = handler.__transport__(transport)
- conn = conn
- |> fetch_query_params
- |> Transport.transport_log(opts[:transport_log])
- |> Transport.force_ssl(handler, endpoint, opts)
- |> Transport.check_origin(handler, endpoint, opts)
+ conn =
+ conn
+ |> fetch_query_params
+ |> Transport.transport_log(opts[:transport_log])
+ |> Transport.force_ssl(handler, endpoint, opts)
+ |> Transport.check_origin(handler, endpoint, opts)
case conn do
%{halted: false} = conn ->
case Transport.connect(endpoint, handler, transport, __MODULE__, nil, conn.params) do
{:ok, socket} ->
{:ok, conn, {__MODULE__, {socket, opts}}}
+
:error ->
send_resp(conn, :forbidden, "")
{:error, conn}
end
+
_ ->
{:error, conn}
end
@@ -52,16 +57,19 @@ defmodule Phoenix.Transports.WebSocket.Raw do
|> case do
{op, data} ->
{:reply, {op, data}, state}
+
{op, data, state} ->
{:reply, {op, data}, state}
+
%{} = state ->
{:ok, state}
+
_ ->
{:ok, state}
end
end
- def ws_info({_,_} = tuple, state) do
+ def ws_info({_, _} = tuple, state) do
{:reply, tuple, state}
end
diff --git a/lib/xml_builder.ex b/lib/xml_builder.ex
index 52358c437..88f8ce2a3 100644
--- a/lib/xml_builder.ex
+++ b/lib/xml_builder.ex
@@ -23,7 +23,7 @@ defmodule Pleroma.XmlBuilder do
for element <- content do
to_xml(element)
end
- |> Enum.join
+ |> Enum.join()
end
def to_xml(%NaiveDateTime{} = time) do
@@ -33,10 +33,12 @@ defmodule Pleroma.XmlBuilder do
def to_doc(content), do: ~s(<?xml version="1.0" encoding="UTF-8"?>) <> to_xml(content)
defp make_open_tag(tag, attributes) do
- attributes_string = for {attribute, value} <- attributes do
- "#{attribute}=\"#{value}\""
- end |> Enum.join(" ")
+ attributes_string =
+ for {attribute, value} <- attributes do
+ "#{attribute}=\"#{value}\""
+ end
+ |> Enum.join(" ")
- [tag, attributes_string] |> Enum.join(" ") |> String.trim
+ [tag, attributes_string] |> Enum.join(" ") |> String.trim()
end
end