aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--installation/pleroma.service2
-rw-r--r--lib/pleroma/activity.ex2
-rw-r--r--lib/pleroma/http/http.ex2
-rw-r--r--lib/pleroma/user.ex8
-rw-r--r--lib/pleroma/web/common_api/common_api.ex2
-rw-r--r--lib/pleroma/web/mastodon_api/views/account_view.ex84
-rw-r--r--lib/pleroma/web/salmon/salmon.ex18
-rw-r--r--lib/pleroma/web/twitter_api/twitter_api_controller.ex2
-rw-r--r--lib/pleroma/web/twitter_api/views/user_view.ex55
-rw-r--r--test/web/twitter_api/twitter_api_controller_test.exs60
10 files changed, 168 insertions, 67 deletions
diff --git a/installation/pleroma.service b/installation/pleroma.service
index 6955e5cc6..f1ed56cb3 100644
--- a/installation/pleroma.service
+++ b/installation/pleroma.service
@@ -21,6 +21,8 @@ ProtectSystem=full
PrivateDevices=false
; Ensures that the service process and all its children can never gain new privileges through execve().
NoNewPrivileges=true
+; Drops the sysadmin capability from the daemon.
+CapabilityBoundingSet=~CAP_SYS_ADMIN
[Install]
WantedBy=multi-user.target
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index 34b665765..a14d1e8c6 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -7,6 +7,8 @@ defmodule Pleroma.Activity do
alias Pleroma.{Repo, Activity, Notification}
import Ecto.Query
+ @type t :: %__MODULE__{}
+
# https://github.com/tootsuite/mastodon/blob/master/app/models/notification.rb#L19
@mastodon_notification_types %{
"Create" => "mention",
diff --git a/lib/pleroma/http/http.ex b/lib/pleroma/http/http.ex
index e572dfedf..32d9cf5aa 100644
--- a/lib/pleroma/http/http.ex
+++ b/lib/pleroma/http/http.ex
@@ -10,6 +10,8 @@ defmodule Pleroma.HTTP do
alias Pleroma.HTTP.Connection
alias Pleroma.HTTP.RequestBuilder, as: Builder
+ @type t :: __MODULE__
+
@doc """
Builds and perform http request.
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 1f6d4cc5e..5705098ea 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -49,6 +49,14 @@ defmodule Pleroma.User do
!Pleroma.Config.get([:instance, :account_activation_required])
end
+ def remote_or_auth_active?(%User{} = user), do: !user.local || auth_active?(user)
+
+ def visible_for?(%User{} = user, for_user \\ nil) do
+ User.remote_or_auth_active?(user) || (for_user && for_user.id == user.id) ||
+ User.superuser?(for_user)
+ end
+
+ def superuser?(nil), do: false
def superuser?(%User{} = user), do: user.info && User.Info.superuser?(user.info)
def avatar_url(user) do
diff --git a/lib/pleroma/web/common_api/common_api.ex b/lib/pleroma/web/common_api/common_api.ex
index 5e5821561..085a95172 100644
--- a/lib/pleroma/web/common_api/common_api.ex
+++ b/lib/pleroma/web/common_api/common_api.ex
@@ -102,7 +102,7 @@ defmodule Pleroma.Web.CommonAPI do
attachments,
tags,
get_content_type(data["content_type"]),
- data["no_attachment_links"]
+ Enum.member?([true, "true"], data["no_attachment_links"])
),
context <- make_context(inReplyTo),
cw <- data["spoiler_text"],
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index aaaae2035..555383503 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -11,10 +11,55 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
alias Pleroma.HTML
def render("accounts.json", %{users: users} = opts) do
- render_many(users, AccountView, "account.json", opts)
+ users
+ |> render_many(AccountView, "account.json", opts)
+ |> Enum.filter(&Enum.any?/1)
end
def render("account.json", %{user: user} = opts) do
+ if User.visible_for?(user, opts[:for]),
+ do: do_render("account.json", opts),
+ else: %{}
+ end
+
+ def render("mention.json", %{user: user}) do
+ %{
+ id: to_string(user.id),
+ acct: user.nickname,
+ username: username_from_nickname(user.nickname),
+ url: user.ap_id
+ }
+ end
+
+ def render("relationship.json", %{user: user, target: target}) do
+ follow_activity = Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(user, target)
+
+ requested =
+ if follow_activity do
+ follow_activity.data["state"] == "pending"
+ else
+ false
+ end
+
+ %{
+ id: to_string(target.id),
+ following: User.following?(user, target),
+ followed_by: User.following?(target, user),
+ blocking: User.blocks?(user, target),
+ muting: false,
+ muting_notifications: false,
+ requested: requested,
+ domain_blocking: false,
+ showing_reblogs: false,
+ endorsed: false
+ }
+ end
+
+ def render("relationships.json", %{user: user, targets: targets}) do
+ render_many(targets, AccountView, "relationship.json", user: user, as: :target)
+ end
+
+ defp do_render("account.json", %{user: user} = opts) do
image = User.avatar_url(user) |> MediaProxy.url()
header = User.banner_url(user) |> MediaProxy.url()
user_info = User.user_info(user)
@@ -72,43 +117,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
}
end
- def render("mention.json", %{user: user}) do
- %{
- id: to_string(user.id),
- acct: user.nickname,
- username: username_from_nickname(user.nickname),
- url: user.ap_id
- }
- end
-
- def render("relationship.json", %{user: user, target: target}) do
- follow_activity = Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(user, target)
-
- requested =
- if follow_activity do
- follow_activity.data["state"] == "pending"
- else
- false
- end
-
- %{
- id: to_string(target.id),
- following: User.following?(user, target),
- followed_by: User.following?(target, user),
- blocking: User.blocks?(user, target),
- muting: false,
- muting_notifications: false,
- requested: requested,
- domain_blocking: false,
- showing_reblogs: false,
- endorsed: false
- }
- end
-
- def render("relationships.json", %{user: user, targets: targets}) do
- render_many(targets, AccountView, "relationship.json", user: user, as: :target)
- end
-
defp username_from_nickname(string) when is_binary(string) do
hd(String.split(string, "@"))
end
diff --git a/lib/pleroma/web/salmon/salmon.ex b/lib/pleroma/web/salmon/salmon.ex
index 1dc514976..f7d2257eb 100644
--- a/lib/pleroma/web/salmon/salmon.ex
+++ b/lib/pleroma/web/salmon/salmon.ex
@@ -161,16 +161,21 @@ defmodule Pleroma.Web.Salmon do
|> Enum.filter(fn user -> user && !user.local end)
end
- defp send_to_user(%{info: %{salmon: salmon}}, feed, poster) do
+ # push an activity to remote accounts
+ #
+ defp send_to_user(%{info: %{salmon: salmon}}, feed, poster),
+ do: send_to_user(salmon, feed, poster)
+
+ defp send_to_user(url, feed, poster) when is_binary(url) do
with {:ok, %{status: code}} <-
poster.(
- salmon,
+ url,
feed,
[{"Content-Type", "application/magic-envelope+xml"}]
) do
- Logger.debug(fn -> "Pushed to #{salmon}, code #{code}" end)
+ Logger.debug(fn -> "Pushed to #{url}, code #{code}" end)
else
- e -> Logger.debug(fn -> "Pushing Salmon to #{salmon} failed, #{inspect(e)}" end)
+ e -> Logger.debug(fn -> "Pushing Salmon to #{url} failed, #{inspect(e)}" end)
end
end
@@ -184,6 +189,11 @@ defmodule Pleroma.Web.Salmon do
"Undo",
"Delete"
]
+
+ @doc """
+ Publishes an activity to remote accounts
+ """
+ @spec publish(User.t(), Pleroma.Activity.t(), Pleroma.HTTP.t()) :: none
def publish(user, activity, poster \\ &@httpoison.post/3)
def publish(%{info: %{keys: keys}} = user, %{data: %{"type" => type}} = activity, poster)
diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
index c11824afc..aebc3bff4 100644
--- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex
+++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex
@@ -670,7 +670,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
json_reply(conn, 403, json)
end
- def only_if_public_instance(conn = %{conn: %{assigns: %{user: _user}}}, _), do: conn
+ def only_if_public_instance(%{assigns: %{user: %User{}}} = conn, _), do: conn
def only_if_public_instance(conn, _) do
if Keyword.get(Application.get_env(:pleroma, :instance), :public) do
diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex
index 6e489624f..ede3c0d25 100644
--- a/lib/pleroma/web/twitter_api/views/user_view.ex
+++ b/lib/pleroma/web/twitter_api/views/user_view.ex
@@ -15,18 +15,44 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
end
def render("index.json", %{users: users, for: user}) do
- render_many(users, Pleroma.Web.TwitterAPI.UserView, "user.json", for: user)
+ users
+ |> render_many(Pleroma.Web.TwitterAPI.UserView, "user.json", for: user)
+ |> Enum.filter(&Enum.any?/1)
end
def render("user.json", %{user: user = %User{}} = assigns) do
+ if User.visible_for?(user, assigns[:for]),
+ do: do_render("user.json", assigns),
+ else: %{}
+ end
+
+ def render("short.json", %{
+ user: %User{
+ nickname: nickname,
+ id: id,
+ ap_id: ap_id,
+ name: name
+ }
+ }) do
+ %{
+ "fullname" => name,
+ "id" => id,
+ "ostatus_uri" => ap_id,
+ "profile_url" => ap_id,
+ "screen_name" => nickname
+ }
+ end
+
+ defp do_render("user.json", %{user: user = %User{}} = assigns) do
+ for_user = assigns[:for]
image = User.avatar_url(user) |> MediaProxy.url()
{following, follows_you, statusnet_blocking} =
- if assigns[:for] do
+ if for_user do
{
- User.following?(assigns[:for], user),
- User.following?(user, assigns[:for]),
- User.blocks?(assigns[:for], user)
+ User.following?(for_user, user),
+ User.following?(user, for_user),
+ User.blocks?(for_user, user)
}
else
{false, false, false}
@@ -51,7 +77,7 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
data = %{
"created_at" => user.inserted_at |> Utils.format_naive_asctime(),
"description" => HTML.strip_tags((user.bio || "") |> String.replace("<br>", "\n")),
- "description_html" => HTML.filter_tags(user.bio, User.html_filter_policy(assigns[:for])),
+ "description_html" => HTML.filter_tags(user.bio, User.html_filter_policy(for_user)),
"favourites_count" => 0,
"followers_count" => user_info[:follower_count],
"following" => following,
@@ -97,23 +123,6 @@ 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
- %{
- "fullname" => name,
- "id" => id,
- "ostatus_uri" => ap_id,
- "profile_url" => ap_id,
- "screen_name" => nickname
- }
- end
-
defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
defp image_url(_), do: nil
diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs
index e49d605bd..c41f615ac 100644
--- a/test/web/twitter_api/twitter_api_controller_test.exs
+++ b/test/web/twitter_api/twitter_api_controller_test.exs
@@ -112,6 +112,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
end
describe "GET /statuses/public_timeline.json" do
+ setup [:valid_user]
+
test "returns statuses", %{conn: conn} do
user = insert(:user)
activities = ActivityBuilder.insert_list(30, %{}, %{user: user})
@@ -145,14 +147,44 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
Application.put_env(:pleroma, :instance, instance)
end
+ test "returns 200 to authenticated request when the instance is not public",
+ %{conn: conn, user: user} do
+ instance =
+ Application.get_env(:pleroma, :instance)
+ |> Keyword.put(:public, false)
+
+ Application.put_env(:pleroma, :instance, instance)
+
+ conn
+ |> with_credentials(user.nickname, "test")
+ |> get("/api/statuses/public_timeline.json")
+ |> json_response(200)
+
+ instance =
+ Application.get_env(:pleroma, :instance)
+ |> Keyword.put(:public, true)
+
+ Application.put_env(:pleroma, :instance, instance)
+ end
+
test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
conn
|> get("/api/statuses/public_timeline.json")
|> json_response(200)
end
+
+ test "returns 200 to authenticated request when the instance is public",
+ %{conn: conn, user: user} do
+ conn
+ |> with_credentials(user.nickname, "test")
+ |> get("/api/statuses/public_timeline.json")
+ |> json_response(200)
+ end
end
describe "GET /statuses/public_and_external_timeline.json" do
+ setup [:valid_user]
+
test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
instance =
Application.get_env(:pleroma, :instance)
@@ -171,11 +203,39 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
Application.put_env(:pleroma, :instance, instance)
end
+ test "returns 200 to authenticated request when the instance is not public",
+ %{conn: conn, user: user} do
+ instance =
+ Application.get_env(:pleroma, :instance)
+ |> Keyword.put(:public, false)
+
+ Application.put_env(:pleroma, :instance, instance)
+
+ conn
+ |> with_credentials(user.nickname, "test")
+ |> get("/api/statuses/public_and_external_timeline.json")
+ |> json_response(200)
+
+ instance =
+ Application.get_env(:pleroma, :instance)
+ |> Keyword.put(:public, true)
+
+ Application.put_env(:pleroma, :instance, instance)
+ end
+
test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
conn
|> get("/api/statuses/public_and_external_timeline.json")
|> json_response(200)
end
+
+ test "returns 200 to authenticated request when the instance is public",
+ %{conn: conn, user: user} do
+ conn
+ |> with_credentials(user.nickname, "test")
+ |> get("/api/statuses/public_and_external_timeline.json")
+ |> json_response(200)
+ end
end
describe "GET /statuses/show/:id.json" do