aboutsummaryrefslogtreecommitdiff
path: root/lib/pleroma/web
diff options
context:
space:
mode:
authorIvan Tashkinov <ivantashkinov@gmail.com>2020-01-15 18:12:08 +0300
committerIvan Tashkinov <ivantashkinov@gmail.com>2020-01-15 18:12:08 +0300
commit5304c8cd21d72d66e5e9dc9f057ffbbe027ef5fa (patch)
treed463c35ba67fe75d8eea92097db43650f5626129 /lib/pleroma/web
parent76c1948880687ed74e0275e51808c0ddc6be887d (diff)
parent1b233aa6531b26943bd78c5d4cd8e00f2e1d318e (diff)
downloadpleroma-5304c8cd21d72d66e5e9dc9f057ffbbe027ef5fa.tar.gz
Merge remote-tracking branch 'remotes/origin/develop' into 1478-oauth-admin-scopes-tweaks
Diffstat (limited to 'lib/pleroma/web')
-rw-r--r--lib/pleroma/web/activity_pub/publisher.ex4
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/notification_controller.ex17
-rw-r--r--lib/pleroma/web/mastodon_api/mastodon_api.ex8
-rw-r--r--lib/pleroma/web/metadata/utils.ex2
-rw-r--r--lib/pleroma/web/router.ex4
-rw-r--r--lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex11
-rw-r--r--lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex14
-rw-r--r--lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex (renamed from lib/pleroma/web/templates/twitter_api/util/followed.html.eex)0
-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/twitter_api/controllers/remote_follow_controller.ex112
-rw-r--r--lib/pleroma/web/twitter_api/controllers/util_controller.ex101
-rw-r--r--lib/pleroma/web/twitter_api/views/remote_follow_view.ex10
13 files changed, 179 insertions, 129 deletions
diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex
index db072bad2..e4e3ab44a 100644
--- a/lib/pleroma/web/activity_pub/publisher.ex
+++ b/lib/pleroma/web/activity_pub/publisher.ex
@@ -264,6 +264,10 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
"rel" => "self",
"type" => "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
"href" => user.ap_id
+ },
+ %{
+ "rel" => "http://ostatus.org/schema/1.0/subscribe",
+ "template" => "#{Pleroma.Web.base_url()}/ostatus_subscribe?acct={uri}"
}
]
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
index 16759be6a..f2508aca4 100644
--- a/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/notification_controller.ex
@@ -23,6 +23,23 @@ defmodule Pleroma.Web.MastodonAPI.NotificationController do
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug)
# GET /api/v1/notifications
+ def index(conn, %{"account_id" => account_id} = params) do
+ case Pleroma.User.get_cached_by_id(account_id) do
+ %{ap_id: account_ap_id} ->
+ params =
+ params
+ |> Map.delete("account_id")
+ |> Map.put("account_ap_id", account_ap_id)
+
+ index(conn, params)
+
+ _ ->
+ conn
+ |> put_status(:not_found)
+ |> json(%{"error" => "Account is not found"})
+ end
+ end
+
def index(%{assigns: %{user: user}} = conn, params) do
notifications = MastodonAPI.get_notifications(user, params)
diff --git a/lib/pleroma/web/mastodon_api/mastodon_api.ex b/lib/pleroma/web/mastodon_api/mastodon_api.ex
index b1816370e..390a2b190 100644
--- a/lib/pleroma/web/mastodon_api/mastodon_api.ex
+++ b/lib/pleroma/web/mastodon_api/mastodon_api.ex
@@ -56,6 +56,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
user
|> Notification.for_user_query(options)
|> restrict(:exclude_types, options)
+ |> restrict(:account_ap_id, options)
|> Pagination.fetch_paginated(params)
end
@@ -71,7 +72,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
exclude_visibilities: {:array, :string},
reblogs: :boolean,
with_muted: :boolean,
- with_move: :boolean
+ with_move: :boolean,
+ account_ap_id: :string
}
changeset = cast({%{}, param_types}, params, Map.keys(param_types))
@@ -88,5 +90,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do
|> where([q, a], not fragment("? @> ARRAY[?->>'type']::varchar[]", ^ap_types, a.data))
end
+ defp restrict(query, :account_ap_id, %{account_ap_id: account_ap_id}) do
+ where(query, [n, a], a.actor == ^account_ap_id)
+ end
+
defp restrict(query, _, _), do: query
end
diff --git a/lib/pleroma/web/metadata/utils.ex b/lib/pleroma/web/metadata/utils.ex
index 382ecf426..589d11901 100644
--- a/lib/pleroma/web/metadata/utils.ex
+++ b/lib/pleroma/web/metadata/utils.ex
@@ -15,6 +15,7 @@ defmodule Pleroma.Web.Metadata.Utils do
|> String.replace(~r/<br\s?\/?>/, " ")
|> HTML.get_cached_stripped_html_for_activity(object, "metadata")
|> Emoji.Formatter.demojify()
+ |> HtmlEntities.decode()
|> Formatter.truncate()
end
@@ -25,6 +26,7 @@ defmodule Pleroma.Web.Metadata.Utils do
|> String.replace(~r/<br\s?\/?>/, " ")
|> HTML.strip_tags()
|> Emoji.Formatter.demojify()
+ |> HtmlEntities.decode()
|> Formatter.truncate(max_length)
end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index f6c128283..9654ab8a3 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -229,9 +229,9 @@ defmodule Pleroma.Web.Router do
pipe_through(:pleroma_html)
post("/main/ostatus", UtilController, :remote_subscribe)
- get("/ostatus_subscribe", UtilController, :remote_follow)
+ get("/ostatus_subscribe", RemoteFollowController, :follow)
- post("/ostatus_subscribe", UtilController, :do_remote_follow)
+ post("/ostatus_subscribe", RemoteFollowController, :do_follow)
end
scope "/api/pleroma", Pleroma.Web.TwitterAPI do
diff --git a/lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex b/lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex
new file mode 100644
index 000000000..5ba192cd7
--- /dev/null
+++ b/lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex
@@ -0,0 +1,11 @@
+<%= if @error == :error do %>
+ <h2>Error fetching user</h2>
+<% else %>
+ <h2>Remote follow</h2>
+ <img height="128" width="128" src="<%= avatar_url(@followee) %>">
+ <p><%= @followee.nickname %></p>
+ <%= form_for @conn, remote_follow_path(@conn, :do_follow), [as: "user"], fn f -> %>
+ <%= hidden_input f, :id, value: @followee.id %>
+ <%= submit "Authorize" %>
+ <% end %>
+<% end %>
diff --git a/lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex b/lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex
new file mode 100644
index 000000000..df44988ee
--- /dev/null
+++ b/lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex
@@ -0,0 +1,14 @@
+<%= if @error do %>
+<h2><%= @error %></h2>
+<% end %>
+<h2>Log in to follow</h2>
+<p><%= @followee.nickname %></p>
+<img height="128" width="128" src="<%= avatar_url(@followee) %>">
+<%= form_for @conn, remote_follow_path(@conn, :do_follow), [as: "authorization"], fn f -> %>
+<%= text_input f, :name, placeholder: "Username", required: true %>
+<br>
+<%= password_input f, :password, placeholder: "Password", required: true %>
+<br>
+<%= hidden_input f, :id, value: @followee.id %>
+<%= submit "Authorize" %>
+<% end %>
diff --git a/lib/pleroma/web/templates/twitter_api/util/followed.html.eex b/lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex
index da473d502..da473d502 100644
--- a/lib/pleroma/web/templates/twitter_api/util/followed.html.eex
+++ b/lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex
diff --git a/lib/pleroma/web/templates/twitter_api/util/follow.html.eex b/lib/pleroma/web/templates/twitter_api/util/follow.html.eex
deleted file mode 100644
index 06359fa6c..000000000
--- a/lib/pleroma/web/templates/twitter_api/util/follow.html.eex
+++ /dev/null
@@ -1,11 +0,0 @@
-<%= 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
deleted file mode 100644
index 4e3a2be67..000000000
--- a/lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex
+++ /dev/null
@@ -1,14 +0,0 @@
-<%= 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/twitter_api/controllers/remote_follow_controller.ex b/lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex
new file mode 100644
index 000000000..e0d4d5632
--- /dev/null
+++ b/lib/pleroma/web/twitter_api/controllers/remote_follow_controller.ex
@@ -0,0 +1,112 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.TwitterAPI.RemoteFollowController do
+ use Pleroma.Web, :controller
+
+ require Logger
+
+ alias Pleroma.Activity
+ alias Pleroma.Object.Fetcher
+ alias Pleroma.Plugs.OAuthScopesPlug
+ alias Pleroma.User
+ alias Pleroma.Web.Auth.Authenticator
+ alias Pleroma.Web.CommonAPI
+
+ @status_types ["Article", "Event", "Note", "Video", "Page", "Question"]
+
+ # Note: follower can submit the form (with password auth) not being signed in (having no token)
+ plug(
+ OAuthScopesPlug,
+ %{fallback: :proceed_unauthenticated, scopes: ["follow", "write:follows"]}
+ when action in [:do_follow]
+ )
+
+ # GET /ostatus_subscribe
+ #
+ def follow(%{assigns: %{user: user}} = conn, %{"acct" => acct}) do
+ case is_status?(acct) do
+ true -> follow_status(conn, user, acct)
+ _ -> follow_account(conn, user, acct)
+ end
+ end
+
+ defp follow_status(conn, _user, acct) do
+ with {:ok, object} <- Fetcher.fetch_object_from_id(acct),
+ %Activity{id: activity_id} <- Activity.get_create_by_object_ap_id(object.data["id"]) do
+ redirect(conn, to: o_status_path(conn, :notice, activity_id))
+ else
+ error ->
+ handle_follow_error(conn, error)
+ end
+ end
+
+ defp follow_account(conn, user, acct) do
+ with {:ok, followee} <- User.get_or_fetch(acct) do
+ render(conn, follow_template(user), %{error: false, followee: followee, acct: acct})
+ else
+ {:error, _reason} ->
+ render(conn, follow_template(user), %{error: :error})
+ end
+ end
+
+ defp follow_template(%User{} = _user), do: "follow.html"
+ defp follow_template(_), do: "follow_login.html"
+
+ defp is_status?(acct) do
+ case Fetcher.fetch_and_contain_remote_object_from_id(acct) do
+ {:ok, %{"type" => type}} when type in @status_types ->
+ true
+
+ _ ->
+ false
+ end
+ end
+
+ # POST /ostatus_subscribe
+ #
+ def do_follow(%{assigns: %{user: %User{} = user}} = conn, %{"user" => %{"id" => id}}) do
+ with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
+ {:ok, _, _, _} <- CommonAPI.follow(user, followee) do
+ render(conn, "followed.html", %{error: false})
+ else
+ error ->
+ handle_follow_error(conn, error)
+ end
+ end
+
+ def do_follow(conn, %{"authorization" => %{"name" => _, "password" => _, "id" => id}}) do
+ with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
+ {_, {:ok, user}, _} <- {:auth, Authenticator.get_user(conn), followee},
+ {:ok, _, _, _} <- CommonAPI.follow(user, followee) do
+ render(conn, "followed.html", %{error: false})
+ else
+ error ->
+ handle_follow_error(conn, error)
+ end
+ end
+
+ def do_follow(%{assigns: %{user: nil}} = conn, _) do
+ Logger.debug("Insufficient permissions: follow | write:follows.")
+ render(conn, "followed.html", %{error: "Insufficient permissions: follow | write:follows."})
+ end
+
+ defp handle_follow_error(conn, {:auth, _, followee} = _) do
+ render(conn, "follow_login.html", %{error: "Wrong username or password", followee: followee})
+ end
+
+ defp handle_follow_error(conn, {:fetch_user, error} = _) do
+ Logger.debug("Remote follow failed with error #{inspect(error)}")
+ render(conn, "followed.html", %{error: "Could not find user"})
+ end
+
+ defp handle_follow_error(conn, {:error, "Could not follow user:" <> _} = _) do
+ render(conn, "followed.html", %{error: "Error following account"})
+ end
+
+ defp handle_follow_error(conn, error) do
+ Logger.debug("Remote follow failed with error #{inspect(error)}")
+ render(conn, "followed.html", %{error: "Something went wrong."})
+ 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 c35e393c0..f08b9d28c 100644
--- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex
+++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
@@ -7,12 +7,10 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
require Logger
- alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.Emoji
alias Pleroma.Healthcheck
alias Pleroma.Notification
- alias Pleroma.Plugs.AuthenticationPlug
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.User
alias Pleroma.Web
@@ -84,105 +82,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
end
end
- def remote_follow(%{assigns: %{user: user}} = conn, %{"acct" => acct}) do
- if is_status?(acct) do
- {:ok, object} = Pleroma.Object.Fetcher.fetch_object_from_id(acct)
- %Activity{id: activity_id} = Activity.get_create_by_object_ap_id(object.data["id"])
- redirect(conn, to: "/notice/#{activity_id}")
- else
- with {:ok, followee} <- User.get_or_fetch(acct) do
- conn
- |> render(follow_template(user), %{
- error: false,
- acct: acct,
- avatar: User.avatar_url(followee),
- name: followee.nickname,
- id: followee.id
- })
- else
- {:error, _reason} ->
- render(conn, follow_template(user), %{error: :error})
- end
- end
- end
-
- defp follow_template(%User{} = _user), do: "follow.html"
- defp follow_template(_), do: "follow_login.html"
-
- defp is_status?(acct) do
- case Pleroma.Object.Fetcher.fetch_and_contain_remote_object_from_id(acct) do
- {:ok, %{"type" => type}}
- when type in ["Article", "Event", "Note", "Video", "Page", "Question"] ->
- true
-
- _ ->
- false
- end
- end
-
- def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}})
- when not is_nil(user) do
- with {:fetch_user, %User{} = followee} <- {:fetch_user, User.get_cached_by_id(id)},
- {:ok, _follower, _followee, _activity} <- CommonAPI.follow(user, followee) do
- conn
- |> render("followed.html", %{error: false})
- else
- # Was already following user
- {:error, "Could not follow user:" <> _rest} ->
- render(conn, "followed.html", %{error: "Error following account"})
-
- {:fetch_user, error} ->
- Logger.debug("Remote follow failed with error #{inspect(error)}")
- render(conn, "followed.html", %{error: "Could not find user"})
-
- e ->
- Logger.debug("Remote follow failed with error #{inspect(e)}")
- render(conn, "followed.html", %{error: "Something went wrong."})
- end
- end
-
- # Note: "id" is the id of followee user, disregard incorrect placing under "authorization"
- def do_remote_follow(conn, %{
- "authorization" => %{"name" => username, "password" => password, "id" => id}
- }) do
- with %User{} = followee <- User.get_cached_by_id(id),
- {_, %User{} = user, _} <- {:auth, User.get_cached_by_nickname(username), followee},
- {_, true, _} <- {
- :auth,
- AuthenticationPlug.checkpw(password, user.password_hash),
- followee
- },
- {:ok, _follower, _followee, _activity} <- CommonAPI.follow(user, followee) do
- conn
- |> render("followed.html", %{error: false})
- else
- # Was already following user
- {:error, "Could not follow user:" <> _rest} ->
- render(conn, "followed.html", %{error: "Error following account"})
-
- {:auth, _, followee} ->
- conn
- |> render("follow_login.html", %{
- error: "Wrong username or password",
- id: id,
- name: followee.nickname,
- avatar: User.avatar_url(followee)
- })
-
- e ->
- Logger.debug("Remote follow failed with error #{inspect(e)}")
- render(conn, "followed.html", %{error: "Something went wrong."})
- end
- end
-
- def do_remote_follow(%{assigns: %{user: nil}} = conn, _) do
- render(conn, "followed.html", %{error: "Insufficient permissions: follow | write:follows."})
- end
-
- def do_remote_follow(conn, _) do
- render(conn, "followed.html", %{error: "Something went wrong."})
- end
-
def notifications_read(%{assigns: %{user: user}} = conn, %{"id" => notification_id}) do
with {:ok, _} <- Notification.read_one(user, notification_id) do
json(conn, %{status: "success"})
diff --git a/lib/pleroma/web/twitter_api/views/remote_follow_view.ex b/lib/pleroma/web/twitter_api/views/remote_follow_view.ex
new file mode 100644
index 000000000..d469c4726
--- /dev/null
+++ b/lib/pleroma/web/twitter_api/views/remote_follow_view.ex
@@ -0,0 +1,10 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.TwitterAPI.RemoteFollowView do
+ use Pleroma.Web, :view
+ import Phoenix.HTML.Form
+
+ defdelegate avatar_url(user), to: Pleroma.User
+end