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 @@ def salmon_path(user) 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 09104fc86..63dbd6245 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -28,6 +28,13 @@ def user_fetcher(username) 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 @@ def user_fetcher(username) 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
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 %>
+
Error fetching user
+<% else %>
+ Remote follow
+
+ <%= @name %>
+ <%= 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 %>
+ <%= @error %>
+<% end %>
+Log in to follow
+<%= @name %>
+
+<%= form_for @conn, util_path(@conn, :do_remote_follow), [as: "authorization"], fn f -> %>
+<%= text_input f, :name, placeholder: "Username" %>
+
+<%= password_input f, :password, placeholder: "Password" %>
+
+<%= 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 %>
+Error following account
+<% else %>
+Account followed!
+<% 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 @@ def help_test(conn, _params) 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/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 @@ def represent_user(user) 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