aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJeff Becker <jeff@i2p.rocks>2018-01-24 13:15:54 -0500
committerJeff Becker <jeff@i2p.rocks>2018-01-24 13:15:54 -0500
commitdffde6631d105949b62c1ff27c22fefcb873b2e8 (patch)
treef486f66ae4067ec1bc0dec7f265765b6d35a9c58 /lib
parent1e185b9301ec85cd2aaeb1faf075aaa86f733373 (diff)
parent0f722a8c223c1953c9c9fb45e73cc9ace92839e2 (diff)
downloadpleroma-dffde6631d105949b62c1ff27c22fefcb873b2e8.tar.gz
Merge remote-tracking branch 'upstream/develop' into pr-upstream-http-proxy
Diffstat (limited to 'lib')
-rw-r--r--lib/mix/tasks/generate_config.ex11
-rw-r--r--lib/mix/tasks/sample_config.eex5
-rw-r--r--lib/pleroma/application.ex1
-rw-r--r--lib/pleroma/stats.ex42
-rw-r--r--lib/pleroma/user.ex4
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_api_controller.ex13
-rw-r--r--lib/pleroma/web/mastodon_api/views/account_view.ex6
-rw-r--r--lib/pleroma/web/ostatus/ostatus.ex4
-rw-r--r--lib/pleroma/web/router.ex14
-rw-r--r--lib/pleroma/web/templates/twitter_api/util/follow.html.eex11
-rw-r--r--lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex14
-rw-r--r--lib/pleroma/web/templates/twitter_api/util/followed.html.eex6
-rw-r--r--lib/pleroma/web/twitter_api/controllers/util_controller.ex48
-rw-r--r--lib/pleroma/web/twitter_api/twitter_api.ex10
-rw-r--r--lib/pleroma/web/twitter_api/views/user_view.ex2
-rw-r--r--lib/pleroma/web/web_finger/web_finger.ex3
16 files changed, 173 insertions, 21 deletions
diff --git a/lib/mix/tasks/generate_config.ex b/lib/mix/tasks/generate_config.ex
index f20f93e4d..2d962124f 100644
--- a/lib/mix/tasks/generate_config.ex
+++ b/lib/mix/tasks/generate_config.ex
@@ -8,11 +8,20 @@ defmodule Mix.Tasks.GenerateConfig do
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, 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)
diff --git a/lib/mix/tasks/sample_config.eex b/lib/mix/tasks/sample_config.eex
index 85a7c554e..9330fae2d 100644
--- a/lib/mix/tasks/sample_config.eex
+++ b/lib/mix/tasks/sample_config.eex
@@ -10,6 +10,11 @@ config :pleroma, :instance,
limit: 5000,
registrations_open: true
+config :pleroma, :media_proxy,
+ enabled: <%= mediaproxy %>,
+ redirect_on_failure: true,
+ base_url: "<%= proxy_url %>"
+
# Configure your database
config :pleroma, Pleroma.Repo,
adapter: Ecto.Adapters.Postgres,
diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex
index 2969ca3c4..cdfca8b1a 100644
--- a/lib/pleroma/application.ex
+++ b/lib/pleroma/application.ex
@@ -21,6 +21,7 @@ defmodule Pleroma.Application do
]]),
worker(Pleroma.Web.Federator, []),
worker(Pleroma.Web.ChatChannel.ChatChannelState, []),
+ worker(Pleroma.Stats, []),
]
++ if Mix.env == :test, do: [], else: [worker(Pleroma.Web.Streamer, [])]
diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex
new file mode 100644
index 000000000..0484f1a2d
--- /dev/null
+++ b/lib/pleroma/stats.ex
@@ -0,0 +1,42 @@
+defmodule Pleroma.Stats do
+ use Agent
+ import Ecto.Query
+ alias Pleroma.{User, Repo, Activity}
+
+ def start_link do
+ agent = Agent.start_link(fn -> {[], %{}} end, name: __MODULE__)
+ spawn(fn -> schedule_update() end)
+ agent
+ end
+
+ def get_stats do
+ Agent.get(__MODULE__, fn {_, stats} -> stats end)
+ end
+
+ def get_peers do
+ Agent.get(__MODULE__, fn {peers, _} -> peers end)
+ end
+
+ def schedule_update do
+ spawn(fn ->
+ Process.sleep(1000 * 60 * 60 * 1) # 1 hour
+ 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()
+ domain_count = Enum.count(peers)
+ status_query = from(u in User.local_user_query,
+ select: fragment("sum((?->>'note_count')::int)", u.info))
+ status_count = Repo.one(status_query) |> IO.inspect
+ 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)
+ end
+end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 09bcf0cb4..6ba2b165c 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -29,14 +29,14 @@ defmodule Pleroma.User do
def avatar_url(user) do
case user.avatar do
%{"url" => [%{"href" => href} | _]} -> href
- _ -> "https://placehold.it/48x48"
+ _ -> "#{Web.base_url()}/static/avi.png"
end
end
def banner_url(user) do
case user.info["banner"] do
%{"url" => [%{"href" => href} | _]} -> href
- _ -> nil
+ _ -> "#{Web.base_url()}/static/banner.png"
end
end
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
index ffa6f42c8..0615ac11a 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
@@ -1,6 +1,6 @@
defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
use Pleroma.Web, :controller
- alias Pleroma.{Repo, Activity, User, Notification}
+ alias Pleroma.{Repo, Activity, User, Notification, Stats}
alias Pleroma.Web
alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView}
alias Pleroma.Web.ActivityPub.ActivityPub
@@ -93,7 +93,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
@instance Application.get_env(:pleroma, :instance)
def masto_instance(conn, _params) do
- user_count = Repo.aggregate(User.local_user_query, :count, :id)
response = %{
uri: Web.base_url,
title: Keyword.get(@instance, :name),
@@ -103,17 +102,17 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
urls: %{
streaming_api: String.replace(Web.base_url, ["http","https"], "wss")
},
- stats: %{
- status_count: 2,
- user_count: user_count,
- domain_count: 3
- },
+ stats: Stats.get_stats,
max_toot_chars: Keyword.get(@instance, :limit)
}
json(conn, response)
end
+ def peers(conn, _params) do
+ json(conn, Stats.get_peers)
+ end
+
defp mastodonized_emoji do
Pleroma.Formatter.get_custom_emoji()
|> Enum.map(fn {shortcode, relative_url} ->
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index 1d5918988..d2a4dd366 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -5,19 +5,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MediaProxy
- defp image_url(%{"url" => [ %{ "href" => href } | _ ]}), do: href
- defp image_url(_), do: nil
-
def render("accounts.json", %{users: users} = opts) do
render_many(users, AccountView, "account.json", opts)
end
def render("account.json", %{user: user}) do
image = User.avatar_url(user) |> MediaProxy.url()
+ header = User.banner_url(user) |> MediaProxy.url()
user_info = User.user_info(user)
- header = (image_url(user.info["banner"]) || "https://placehold.it/700x335") |> MediaProxy.url()
-
%{
id: to_string(user.id),
username: hd(String.split(user.nickname, "@")),
diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex
index 745539b3e..e65cab3ed 100644
--- a/lib/pleroma/web/ostatus/ostatus.ex
+++ b/lib/pleroma/web/ostatus/ostatus.ex
@@ -22,6 +22,10 @@ defmodule Pleroma.Web.OStatus do
"#{user.ap_id}/salmon"
end
+ def remote_follow_path do
+ "#{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)
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 8e6681e68..63dbd6245 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -28,6 +28,13 @@ defmodule Pleroma.Web.Router do
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}
+ end
+
pipeline :well_known do
plug :accepts, ["xml", "xrd+xml"]
end
@@ -51,6 +58,12 @@ defmodule Pleroma.Web.Router do
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
+ end
+
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
pipe_through :authenticated_api
post "/follow_import", UtilController, :follow_import
@@ -106,6 +119,7 @@ defmodule Pleroma.Web.Router do
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
diff --git a/lib/pleroma/web/templates/twitter_api/util/follow.html.eex b/lib/pleroma/web/templates/twitter_api/util/follow.html.eex
new file mode 100644
index 000000000..06359fa6c
--- /dev/null
+++ b/lib/pleroma/web/templates/twitter_api/util/follow.html.eex
@@ -0,0 +1,11 @@
+<%= if @error == :error do %>
+ <h2>Error fetching user</h2>
+<% else %>
+ <h2>Remote follow</h2>
+ <img width="128" height="128" src="<%= @avatar %>">
+ <p><%= @name %></p>
+ <%= form_for @conn, util_path(@conn, :do_remote_follow), [as: "user"], fn f -> %>
+ <%= hidden_input f, :id, value: @id %>
+ <%= submit "Authorize" %>
+ <% end %>
+<% end %>
diff --git a/lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex b/lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex
new file mode 100644
index 000000000..4e3a2be67
--- /dev/null
+++ b/lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex
@@ -0,0 +1,14 @@
+<%= if @error do %>
+ <h2><%= @error %></h2>
+<% end %>
+<h2>Log in to follow</h2>
+<p><%= @name %></p>
+<img height="128" width="128" src="<%= @avatar %>">
+<%= form_for @conn, util_path(@conn, :do_remote_follow), [as: "authorization"], fn f -> %>
+<%= text_input f, :name, placeholder: "Username" %>
+<br>
+<%= password_input f, :password, placeholder: "Password" %>
+<br>
+<%= hidden_input f, :id, value: @id %>
+<%= submit "Authorize" %>
+<% end %>
diff --git a/lib/pleroma/web/templates/twitter_api/util/followed.html.eex b/lib/pleroma/web/templates/twitter_api/util/followed.html.eex
new file mode 100644
index 000000000..da473d502
--- /dev/null
+++ b/lib/pleroma/web/templates/twitter_api/util/followed.html.eex
@@ -0,0 +1,6 @@
+<%= if @error do %>
+<p>Error following account</p>
+<% else %>
+<h2>Account followed!</h2>
+<% end %>
+
diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
index 9d5654995..a1d56e3ab 100644
--- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex
+++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
@@ -2,6 +2,8 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
use Pleroma.Web, :controller
require Logger
alias Pleroma.Web
+ alias Pleroma.Web.OStatus
+ alias Comeonin.Pbkdf2
alias Pleroma.Formatter
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.{Repo, PasswordResetToken, User}
@@ -30,6 +32,52 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
json(conn, "ok")
end
+ def remote_follow(%{assigns: %{user: user}} = conn, %{"acct" => acct}) do
+ {err, followee} = OStatus.find_or_make_user(acct)
+ avatar = User.avatar_url(followee)
+ name = followee.nickname
+ id = followee.id
+
+ if !!user do
+ conn
+ |> 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})
+ end
+ end
+
+ 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),
+ {:ok, follower} <- User.follow(user, followee),
+ {:ok, _activity} <- ActivityPub.follow(follower, followee) do
+ conn
+ |> render("followed.html", %{error: false})
+ else
+ _e ->
+ conn
+ |> 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),
+ {:ok, _activity} <- ActivityPub.follow(follower, followee) do
+ conn
+ |> render("followed.html", %{error: false})
+ else
+ e ->
+ Logger.debug("Remote follow failed with error #{inspect e}")
+ conn
+ |> render("followed.html", %{error: inspect(e)})
+ end
+ end
+
@instance Application.get_env(:pleroma, :instance)
def config(conn, _params) do
case get_format(conn) do
diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex
index d04a81cd4..faecebde0 100644
--- a/lib/pleroma/web/twitter_api/twitter_api.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api.ex
@@ -316,10 +316,12 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
def get_external_profile(for_user, uri) do
with {:ok, %User{} = user} <- OStatus.find_or_make_user(uri) do
- with url <- user.info["topic"],
- {:ok, %{body: body}} <- @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do
- OStatus.handle_incoming(body)
- end
+ spawn(fn ->
+ with url <- user.info["topic"],
+ {: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 ->
{:error, "Couldn't find user"}
diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex
index cc6b450fb..1b995f42f 100644
--- a/lib/pleroma/web/twitter_api/views/user_view.ex
+++ b/lib/pleroma/web/twitter_api/views/user_view.ex
@@ -45,7 +45,7 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
"screen_name" => user.nickname,
"statuses_count" => user_info[:note_count],
"statusnet_profile_url" => user.ap_id,
- "cover_photo" => image_url(user.info["banner"]) |> MediaProxy.url(),
+ "cover_photo" => User.banner_url(user) |> MediaProxy.url(),
"background_image" => image_url(user.info["background"]) |> MediaProxy.url(),
}
diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex
index 026d2f98b..4ae3eab59 100644
--- a/lib/pleroma/web/web_finger/web_finger.ex
+++ b/lib/pleroma/web/web_finger/web_finger.ex
@@ -44,7 +44,8 @@ defmodule Pleroma.Web.WebFinger do
{: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: "http://ostatus.org/schema/1.0/subscribe", template: OStatus.remote_follow_path()}}
]
}
|> XmlBuilder.to_doc