aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/plugs/oauth_scopes_plug.ex9
-rw-r--r--lib/pleroma/uploaders/mdii.ex37
-rw-r--r--lib/pleroma/user.ex59
-rw-r--r--lib/pleroma/web/activity_pub/relay.ex4
-rw-r--r--lib/pleroma/web/masto_fe_controller.ex25
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex2
-rw-r--r--lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex9
-rw-r--r--lib/pleroma/web/twitter_api/controllers/util_controller.ex57
8 files changed, 110 insertions, 92 deletions
diff --git a/lib/pleroma/plugs/oauth_scopes_plug.ex b/lib/pleroma/plugs/oauth_scopes_plug.ex
index 174a8389c..07c0f7fdb 100644
--- a/lib/pleroma/plugs/oauth_scopes_plug.ex
+++ b/lib/pleroma/plugs/oauth_scopes_plug.ex
@@ -18,16 +18,13 @@ defmodule Pleroma.Plugs.OAuthScopesPlug do
token = assigns[:token]
scopes = transform_scopes(scopes, options)
- matched_scopes = token && filter_descendants(scopes, token.scopes)
+ matched_scopes = (token && filter_descendants(scopes, token.scopes)) || []
cond do
- is_nil(token) ->
- maybe_perform_instance_privacy_check(conn, options)
-
- op == :| && Enum.any?(matched_scopes) ->
+ token && op == :| && Enum.any?(matched_scopes) ->
conn
- op == :& && matched_scopes == scopes ->
+ token && op == :& && matched_scopes == scopes ->
conn
options[:fallback] == :proceed_unauthenticated ->
diff --git a/lib/pleroma/uploaders/mdii.ex b/lib/pleroma/uploaders/mdii.ex
deleted file mode 100644
index c36f3d61d..000000000
--- a/lib/pleroma/uploaders/mdii.ex
+++ /dev/null
@@ -1,37 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Uploaders.MDII do
- @moduledoc "Represents uploader for https://github.com/hakaba-hitoyo/minimal-digital-image-infrastructure"
-
- alias Pleroma.Config
- alias Pleroma.HTTP
-
- @behaviour Pleroma.Uploaders.Uploader
-
- # MDII-hosted images are never passed through the MediaPlug; only local media.
- # Delegate to Pleroma.Uploaders.Local
- def get_file(file) do
- Pleroma.Uploaders.Local.get_file(file)
- end
-
- def put_file(upload) do
- cgi = Config.get([Pleroma.Uploaders.MDII, :cgi])
- files = Config.get([Pleroma.Uploaders.MDII, :files])
-
- {:ok, file_data} = File.read(upload.tempfile)
-
- extension = String.split(upload.name, ".") |> List.last()
- query = "#{cgi}?#{extension}"
-
- with {:ok, %{status: 200, body: body}} <-
- HTTP.post(query, file_data, [], adapter: [pool: :default]) do
- remote_file_name = String.split(body) |> List.first()
- public_url = "#{files}/#{remote_file_name}.#{extension}"
- {:ok, {:url, public_url}}
- else
- _ -> Pleroma.Uploaders.Local.put_file(upload)
- end
- end
-end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 706aee2ff..2e225415c 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -1430,20 +1430,47 @@ defmodule Pleroma.User do
Creates an internal service actor by URI if missing.
Optionally takes nickname for addressing.
"""
- def get_or_create_service_actor_by_ap_id(uri, nickname \\ nil) do
- with user when is_nil(user) <- get_cached_by_ap_id(uri) do
- {:ok, user} =
- %User{
- invisible: true,
- local: true,
- ap_id: uri,
- nickname: nickname,
- follower_address: uri <> "/followers"
- }
- |> Repo.insert()
+ @spec get_or_create_service_actor_by_ap_id(String.t(), String.t()) :: User.t() | nil
+ def get_or_create_service_actor_by_ap_id(uri, nickname) do
+ {_, user} =
+ case get_cached_by_ap_id(uri) do
+ nil ->
+ with {:error, %{errors: errors}} <- create_service_actor(uri, nickname) do
+ Logger.error("Cannot create service actor: #{uri}/.\n#{inspect(errors)}")
+ {:error, nil}
+ end
- user
- end
+ %User{invisible: false} = user ->
+ set_invisible(user)
+
+ user ->
+ {:ok, user}
+ end
+
+ user
+ end
+
+ @spec set_invisible(User.t()) :: {:ok, User.t()}
+ defp set_invisible(user) do
+ user
+ |> change(%{invisible: true})
+ |> update_and_set_cache()
+ end
+
+ @spec create_service_actor(String.t(), String.t()) ::
+ {:ok, User.t()} | {:error, Ecto.Changeset.t()}
+ defp create_service_actor(uri, nickname) do
+ %User{
+ invisible: true,
+ local: true,
+ ap_id: uri,
+ nickname: nickname,
+ follower_address: uri <> "/followers"
+ }
+ |> change
+ |> unique_constraint(:nickname)
+ |> Repo.insert()
+ |> set_cache()
end
# AP style
@@ -1855,9 +1882,9 @@ defmodule Pleroma.User do
])
with {:ok, updated_user} <- update_and_set_cache(changeset) do
- if user.is_admin && !updated_user.is_admin do
- # Tokens & authorizations containing any admin scopes must be revoked (revoking all).
- # This is an extra safety measure (tokens' admin scopes won't be accepted for non-admins).
+ if user.is_admin != updated_user.is_admin do
+ # Admin status change results in change of accessible OAuth scopes, and instead of changing
+ # already issued tokens we revoke them, requiring user to sign in again
global_sign_out(user)
end
diff --git a/lib/pleroma/web/activity_pub/relay.ex b/lib/pleroma/web/activity_pub/relay.ex
index 99a804568..48a1b71e0 100644
--- a/lib/pleroma/web/activity_pub/relay.ex
+++ b/lib/pleroma/web/activity_pub/relay.ex
@@ -9,10 +9,12 @@ defmodule Pleroma.Web.ActivityPub.Relay do
alias Pleroma.Web.ActivityPub.ActivityPub
require Logger
+ @relay_nickname "relay"
+
def get_actor do
actor =
relay_ap_id()
- |> User.get_or_create_service_actor_by_ap_id()
+ |> User.get_or_create_service_actor_by_ap_id(@relay_nickname)
actor
end
diff --git a/lib/pleroma/web/masto_fe_controller.ex b/lib/pleroma/web/masto_fe_controller.ex
index ca261ad6e..9f7e4943c 100644
--- a/lib/pleroma/web/masto_fe_controller.ex
+++ b/lib/pleroma/web/masto_fe_controller.ex
@@ -20,18 +20,21 @@ defmodule Pleroma.Web.MastoFEController do
plug(Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug when action != :index)
@doc "GET /web/*path"
- def index(%{assigns: %{user: user}} = conn, _params) do
- token = get_session(conn, :oauth_token)
+ def index(%{assigns: %{user: user, token: token}} = conn, _params)
+ when not is_nil(user) and not is_nil(token) do
+ conn
+ |> put_layout(false)
+ |> render("index.html",
+ token: token.token,
+ user: user,
+ custom_emojis: Pleroma.Emoji.get_all()
+ )
+ end
- if user && token do
- conn
- |> put_layout(false)
- |> render("index.html", token: token, user: user, custom_emojis: Pleroma.Emoji.get_all())
- else
- conn
- |> put_session(:return_to, conn.request_path)
- |> redirect(to: "/web/login")
- end
+ def index(conn, _params) do
+ conn
+ |> put_session(:return_to, conn.request_path)
+ |> redirect(to: "/web/login")
end
@doc "GET /web/manifest.json"
diff --git a/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex b/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex
index 69dfa92e3..0bbf84fd3 100644
--- a/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/emoji_api_controller.ex
@@ -52,7 +52,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
@doc """
Lists the packs available on the instance as JSON.
- The information is public and does not require authentification. The format is
+ The information is public and does not require authentication. The format is
a map of "pack directory name" to pack.json contents.
"""
def list_packs(conn, _params) do
diff --git a/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex b/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
index 8fed3f5bb..772c535a4 100644
--- a/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
+++ b/lib/pleroma/web/pleroma_api/controllers/pleroma_api_controller.ex
@@ -22,7 +22,14 @@ defmodule Pleroma.Web.PleromaAPI.PleromaAPIController do
plug(
OAuthScopesPlug,
- %{scopes: ["read:statuses"]} when action in [:conversation, :conversation_statuses]
+ %{scopes: ["read:statuses"]}
+ when action in [:conversation, :conversation_statuses, :emoji_reactions_by]
+ )
+
+ plug(
+ OAuthScopesPlug,
+ %{scopes: ["write:statuses"]}
+ when action in [:react_with_emoji, :unreact_with_emoji]
)
plug(
diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
index 799dd17ae..c35e393c0 100644
--- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex
+++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
@@ -22,7 +22,14 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
plug(
OAuthScopesPlug,
%{scopes: ["follow", "write:follows"]}
- when action in [:do_remote_follow, :follow_import]
+ when action == :follow_import
+ )
+
+ # 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 == :do_remote_follow
)
plug(OAuthScopesPlug, %{scopes: ["follow", "write:blocks"]} when action == :blocks_import)
@@ -113,6 +120,28 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
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
@@ -146,24 +175,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
end
end
- def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}}) 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"})
+ def do_remote_follow(%{assigns: %{user: nil}} = conn, _) do
+ render(conn, "followed.html", %{error: "Insufficient permissions: follow | write:follows."})
+ end
- e ->
- Logger.debug("Remote follow failed with error #{inspect(e)}")
- render(conn, "followed.html", %{error: "Something went wrong."})
- 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
@@ -346,7 +363,9 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
end
def delete_account(%{assigns: %{user: user}} = conn, params) do
- case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
+ password = params["password"] || ""
+
+ case CommonAPI.Utils.confirm_current_password(user, password) do
{:ok, user} ->
User.delete(user)
json(conn, %{status: "success"})