Merge remote-tracking branch 'remotes/upstream/develop' into twitter_oauth

# Conflicts:
#	lib/pleroma/web/oauth/oauth_controller.ex
#	lib/pleroma/web/router.ex
This commit is contained in:
Ivan Tashkinov 2019-04-02 14:05:34 +03:00
commit 37925cbe78
34 changed files with 561 additions and 416 deletions

View File

@ -6,7 +6,6 @@ defmodule Mix.Tasks.Pleroma.User do
use Mix.Task use Mix.Task
import Ecto.Changeset import Ecto.Changeset
alias Mix.Tasks.Pleroma.Common alias Mix.Tasks.Pleroma.Common
alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
@shortdoc "Manages Pleroma users" @shortdoc "Manages Pleroma users"
@ -202,7 +201,7 @@ def run(["unsubscribe", nickname]) do
{:ok, friends} = User.get_friends(user) {:ok, friends} = User.get_friends(user)
Enum.each(friends, fn friend -> Enum.each(friends, fn friend ->
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
Mix.shell().info("Unsubscribing #{friend.nickname} from #{user.nickname}") Mix.shell().info("Unsubscribing #{friend.nickname} from #{user.nickname}")
User.unfollow(user, friend) User.unfollow(user, friend)
@ -210,7 +209,7 @@ def run(["unsubscribe", nickname]) do
:timer.sleep(500) :timer.sleep(500)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
if Enum.empty?(user.following) do if Enum.empty?(user.following) do
Mix.shell().info("Successfully unsubscribed all followers from #{user.nickname}") Mix.shell().info("Successfully unsubscribed all followers from #{user.nickname}")

View File

@ -39,7 +39,7 @@ def used_changeset(struct) do
def reset_password(token, data) do def reset_password(token, data) do
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}), with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
%User{} = user <- Repo.get(User, token.user_id), %User{} = user <- User.get_by_id(token.user_id),
{:ok, _user} <- User.reset_password(user, data), {:ok, _user} <- User.reset_password(user, data),
{:ok, token} <- Repo.update(used_changeset(token)) do {:ok, token} <- Repo.update(used_changeset(token)) do
{:ok, token} {:ok, token}

View File

@ -46,7 +46,7 @@ def from_string(<<_::integer-size(128)>> = flake), do: flake
def from_string(string) when is_binary(string) and byte_size(string) < 18 do def from_string(string) when is_binary(string) and byte_size(string) < 18 do
case Integer.parse(string) do case Integer.parse(string) do
{id, _} -> <<0::integer-size(64), id::integer-size(64)>> {id, ""} -> <<0::integer-size(64), id::integer-size(64)>>
_ -> nil _ -> nil
end end
end end

View File

@ -38,7 +38,6 @@ def init([ip, port]) do
defmodule Pleroma.Gopher.Server.ProtocolHandler do defmodule Pleroma.Gopher.Server.ProtocolHandler do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.HTML alias Pleroma.HTML
alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.Visibility
@ -111,7 +110,7 @@ def response("/main/all") do
end end
def response("/notices/" <> id) do def response("/notices/" <> id) do
with %Activity{} = activity <- Repo.get(Activity, id), with %Activity{} = activity <- Activity.get_by_id(id),
true <- Visibility.is_public?(activity) do true <- Visibility.is_public?(activity) do
activities = activities =
ActivityPub.fetch_activities_for_context(activity.data["context"]) ActivityPub.fetch_activities_for_context(activity.data["context"])

View File

@ -80,7 +80,7 @@ def get_lists_from_activity(%Activity{actor: ap_id}) do
# Get lists to which the account belongs. # Get lists to which the account belongs.
def get_lists_account_belongs(%User{} = owner, account_id) do def get_lists_account_belongs(%User{} = owner, account_id) do
user = Repo.get(User, account_id) user = User.get_by_id(account_id)
query = query =
from( from(

View File

@ -1239,8 +1239,8 @@ def get_or_fetch(nickname), do: get_or_fetch_by_nickname(nickname)
# this is because we have synchronous follow APIs and need to simulate them # this is because we have synchronous follow APIs and need to simulate them
# with an async handshake # with an async handshake
def wait_and_refresh(_, %User{local: true} = a, %User{local: true} = b) do def wait_and_refresh(_, %User{local: true} = a, %User{local: true} = b) do
with %User{} = a <- Repo.get(User, a.id), with %User{} = a <- User.get_by_id(a.id),
%User{} = b <- Repo.get(User, b.id) do %User{} = b <- User.get_by_id(b.id) do
{:ok, a, b} {:ok, a, b}
else else
_e -> _e ->
@ -1250,8 +1250,8 @@ def wait_and_refresh(_, %User{local: true} = a, %User{local: true} = b) do
def wait_and_refresh(timeout, %User{} = a, %User{} = b) do def wait_and_refresh(timeout, %User{} = a, %User{} = b) do
with :ok <- :timer.sleep(timeout), with :ok <- :timer.sleep(timeout),
%User{} = a <- Repo.get(User, a.id), %User{} = a <- User.get_by_id(a.id),
%User{} = b <- Repo.get(User, b.id) do %User{} = b <- User.get_by_id(b.id) do
{:ok, a, b} {:ok, a, b}
else else
_e -> _e ->

View File

@ -354,7 +354,7 @@ def update_follow_state(
[state, actor, object] [state, actor, object]
) )
activity = Repo.get(Activity, activity.id) activity = Activity.get_by_id(activity.id)
{:ok, activity} {:ok, activity}
rescue rescue
e -> e ->

View File

@ -24,7 +24,7 @@ defmodule Pleroma.Web.UserSocket do
def connect(%{"token" => token}, socket) do def connect(%{"token" => token}, socket) do
with true <- Pleroma.Config.get([:chat, :enabled]), with true <- Pleroma.Config.get([:chat, :enabled]),
{:ok, user_id} <- Phoenix.Token.verify(socket, "user socket", token, max_age: 84_600), {:ok, user_id} <- Phoenix.Token.verify(socket, "user socket", token, max_age: 84_600),
%User{} = user <- Pleroma.Repo.get(User, user_id) do %User{} = user <- Pleroma.User.get_by_id(user_id) do
{:ok, assign(socket, :user_name, user.nickname)} {:ok, assign(socket, :user_name, user.nickname)}
else else
_e -> :error _e -> :error

View File

@ -31,7 +31,7 @@ def get_by_id_or_ap_id(id) do
def get_replied_to_activity(""), do: nil def get_replied_to_activity(""), do: nil
def get_replied_to_activity(id) when not is_nil(id) do def get_replied_to_activity(id) when not is_nil(id) do
Repo.get(Activity, id) Activity.get_by_id(id)
end end
def get_replied_to_activity(_), do: nil def get_replied_to_activity(_), do: nil
@ -275,7 +275,7 @@ defp shortname(name) do
end end
def confirm_current_password(user, password) do def confirm_current_password(user, password) do
with %User{local: true} = db_user <- Repo.get(User, user.id), with %User{local: true} = db_user <- User.get_by_id(user.id),
true <- Pbkdf2.checkpw(password, db_user.password_hash) do true <- Pbkdf2.checkpw(password, db_user.password_hash) do
{:ok, db_user} {:ok, db_user}
else else

View File

@ -5,6 +5,11 @@
defmodule Pleroma.Web.ControllerHelper do defmodule Pleroma.Web.ControllerHelper do
use Pleroma.Web, :controller use Pleroma.Web, :controller
# As in MastoAPI, per https://api.rubyonrails.org/classes/ActiveModel/Type/Boolean.html
@falsy_param_values [false, 0, "0", "f", "F", "false", "FALSE", "off", "OFF"]
def truthy_param?(blank_value) when blank_value in [nil, ""], do: nil
def truthy_param?(value), do: value not in @falsy_param_values
def oauth_scopes(params, default) do def oauth_scopes(params, default) do
# Note: `scopes` is used by Mastodon — supporting it but sticking to # Note: `scopes` is used by Mastodon — supporting it but sticking to
# OAuth's standard `scope` wherever we control it # OAuth's standard `scope` wherever we control it

View File

@ -285,7 +285,7 @@ def public_timeline(%{assigns: %{user: user}} = conn, params) do
end end
def user_statuses(%{assigns: %{user: reading_user}} = conn, params) do def user_statuses(%{assigns: %{user: reading_user}} = conn, params) do
with %User{} = user <- Repo.get(User, params["id"]) do with %User{} = user <- User.get_by_id(params["id"]) do
activities = ActivityPub.fetch_user_activities(user, reading_user, params) activities = ActivityPub.fetch_user_activities(user, reading_user, params)
conn conn
@ -319,7 +319,7 @@ def dm_timeline(%{assigns: %{user: user}} = conn, params) do
end end
def get_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do def get_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Repo.get(Activity, id), with %Activity{} = activity <- Activity.get_by_id(id),
true <- Visibility.visible_for_user?(activity, user) do true <- Visibility.visible_for_user?(activity, user) do
conn conn
|> put_view(StatusView) |> put_view(StatusView)
@ -328,7 +328,7 @@ def get_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
end end
def get_context(%{assigns: %{user: user}} = conn, %{"id" => id}) do def get_context(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Repo.get(Activity, id), with %Activity{} = activity <- Activity.get_by_id(id),
activities <- activities <-
ActivityPub.fetch_activities_for_context(activity.data["context"], %{ ActivityPub.fetch_activities_for_context(activity.data["context"], %{
"blocking_user" => user, "blocking_user" => user,
@ -460,7 +460,7 @@ def unpin_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
end end
def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Repo.get(Activity, id), with %Activity{} = activity <- Activity.get_by_id(id),
%User{} = user <- User.get_by_nickname(user.nickname), %User{} = user <- User.get_by_nickname(user.nickname),
true <- Visibility.visible_for_user?(activity, user), true <- Visibility.visible_for_user?(activity, user),
{:ok, user} <- User.bookmark(user, activity.data["object"]["id"]) do {:ok, user} <- User.bookmark(user, activity.data["object"]["id"]) do
@ -471,7 +471,7 @@ def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
end end
def unbookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do def unbookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Repo.get(Activity, id), with %Activity{} = activity <- Activity.get_by_id(id),
%User{} = user <- User.get_by_nickname(user.nickname), %User{} = user <- User.get_by_nickname(user.nickname),
true <- Visibility.visible_for_user?(activity, user), true <- Visibility.visible_for_user?(activity, user),
{:ok, user} <- User.unbookmark(user, activity.data["object"]["id"]) do {:ok, user} <- User.unbookmark(user, activity.data["object"]["id"]) do
@ -593,7 +593,7 @@ def upload(%{assigns: %{user: user}} = conn, %{"file" => file} = data) do
end end
def favourited_by(conn, %{"id" => id}) do def favourited_by(conn, %{"id" => id}) do
with %Activity{data: %{"object" => %{"likes" => likes}}} <- Repo.get(Activity, id) do with %Activity{data: %{"object" => %{"likes" => likes}}} <- Activity.get_by_id(id) do
q = from(u in User, where: u.ap_id in ^likes) q = from(u in User, where: u.ap_id in ^likes)
users = Repo.all(q) users = Repo.all(q)
@ -606,7 +606,7 @@ def favourited_by(conn, %{"id" => id}) do
end end
def reblogged_by(conn, %{"id" => id}) do def reblogged_by(conn, %{"id" => id}) do
with %Activity{data: %{"object" => %{"announcements" => announces}}} <- Repo.get(Activity, id) do with %Activity{data: %{"object" => %{"announcements" => announces}}} <- Activity.get_by_id(id) do
q = from(u in User, where: u.ap_id in ^announces) q = from(u in User, where: u.ap_id in ^announces)
users = Repo.all(q) users = Repo.all(q)
@ -657,7 +657,7 @@ def hashtag_timeline(%{assigns: %{user: user}} = conn, params) do
end end
def followers(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do def followers(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do
with %User{} = user <- Repo.get(User, id), with %User{} = user <- User.get_by_id(id),
followers <- MastodonAPI.get_followers(user, params) do followers <- MastodonAPI.get_followers(user, params) do
followers = followers =
cond do cond do
@ -674,7 +674,7 @@ def followers(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do
end end
def following(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do def following(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params) do
with %User{} = user <- Repo.get(User, id), with %User{} = user <- User.get_by_id(id),
followers <- MastodonAPI.get_friends(user, params) do followers <- MastodonAPI.get_friends(user, params) do
followers = followers =
cond do cond do
@ -699,7 +699,7 @@ def follow_requests(%{assigns: %{user: followed}} = conn, _params) do
end end
def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do
with %User{} = follower <- Repo.get(User, id), with %User{} = follower <- User.get_by_id(id),
{:ok, follower} <- CommonAPI.accept_follow_request(follower, followed) do {:ok, follower} <- CommonAPI.accept_follow_request(follower, followed) do
conn conn
|> put_view(AccountView) |> put_view(AccountView)
@ -713,7 +713,7 @@ def authorize_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}
end end
def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) do
with %User{} = follower <- Repo.get(User, id), with %User{} = follower <- User.get_by_id(id),
{:ok, follower} <- CommonAPI.reject_follow_request(follower, followed) do {:ok, follower} <- CommonAPI.reject_follow_request(follower, followed) do
conn conn
|> put_view(AccountView) |> put_view(AccountView)
@ -727,7 +727,7 @@ def reject_follow_request(%{assigns: %{user: followed}} = conn, %{"id" => id}) d
end end
def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
with %User{} = followed <- Repo.get(User, id), with %User{} = followed <- User.get_by_id(id),
false <- User.following?(follower, followed), false <- User.following?(follower, followed),
{:ok, follower, followed, _} <- CommonAPI.follow(follower, followed) do {:ok, follower, followed, _} <- CommonAPI.follow(follower, followed) do
conn conn
@ -769,7 +769,7 @@ def follow(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
end end
def unfollow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do def unfollow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
with %User{} = followed <- Repo.get(User, id), with %User{} = followed <- User.get_by_id(id),
{:ok, follower} <- CommonAPI.unfollow(follower, followed) do {:ok, follower} <- CommonAPI.unfollow(follower, followed) do
conn conn
|> put_view(AccountView) |> put_view(AccountView)
@ -778,7 +778,7 @@ def unfollow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
end end
def mute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do def mute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do
with %User{} = muted <- Repo.get(User, id), with %User{} = muted <- User.get_by_id(id),
{:ok, muter} <- User.mute(muter, muted) do {:ok, muter} <- User.mute(muter, muted) do
conn conn
|> put_view(AccountView) |> put_view(AccountView)
@ -792,7 +792,7 @@ def mute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do
end end
def unmute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do def unmute(%{assigns: %{user: muter}} = conn, %{"id" => id}) do
with %User{} = muted <- Repo.get(User, id), with %User{} = muted <- User.get_by_id(id),
{:ok, muter} <- User.unmute(muter, muted) do {:ok, muter} <- User.unmute(muter, muted) do
conn conn
|> put_view(AccountView) |> put_view(AccountView)
@ -813,7 +813,7 @@ def mutes(%{assigns: %{user: user}} = conn, _) do
end end
def block(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do def block(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
with %User{} = blocked <- Repo.get(User, id), with %User{} = blocked <- User.get_by_id(id),
{:ok, blocker} <- User.block(blocker, blocked), {:ok, blocker} <- User.block(blocker, blocked),
{:ok, _activity} <- ActivityPub.block(blocker, blocked) do {:ok, _activity} <- ActivityPub.block(blocker, blocked) do
conn conn
@ -828,7 +828,7 @@ def block(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
end end
def unblock(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do def unblock(%{assigns: %{user: blocker}} = conn, %{"id" => id}) do
with %User{} = blocked <- Repo.get(User, id), with %User{} = blocked <- User.get_by_id(id),
{:ok, blocker} <- User.unblock(blocker, blocked), {:ok, blocker} <- User.unblock(blocker, blocked),
{:ok, _activity} <- ActivityPub.unblock(blocker, blocked) do {:ok, _activity} <- ActivityPub.unblock(blocker, blocked) do
conn conn
@ -966,7 +966,7 @@ def favourites(%{assigns: %{user: user}} = conn, params) do
end end
def bookmarks(%{assigns: %{user: user}} = conn, _) do def bookmarks(%{assigns: %{user: user}} = conn, _) do
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
activities = activities =
user.bookmarks user.bookmarks
@ -1023,7 +1023,7 @@ def add_to_list(%{assigns: %{user: user}} = conn, %{"id" => id, "account_ids" =>
accounts accounts
|> Enum.each(fn account_id -> |> Enum.each(fn account_id ->
with %Pleroma.List{} = list <- Pleroma.List.get(id, user), with %Pleroma.List{} = list <- Pleroma.List.get(id, user),
%User{} = followed <- Repo.get(User, account_id) do %User{} = followed <- User.get_by_id(account_id) do
Pleroma.List.follow(list, followed) Pleroma.List.follow(list, followed)
end end
end) end)
@ -1035,7 +1035,7 @@ def remove_from_list(%{assigns: %{user: user}} = conn, %{"id" => id, "account_id
accounts accounts
|> Enum.each(fn account_id -> |> Enum.each(fn account_id ->
with %Pleroma.List{} = list <- Pleroma.List.get(id, user), with %Pleroma.List{} = list <- Pleroma.List.get(id, user),
%User{} = followed <- Repo.get(Pleroma.User, account_id) do %User{} = followed <- Pleroma.User.get_by_id(account_id) do
Pleroma.List.unfollow(list, followed) Pleroma.List.unfollow(list, followed)
end end
end) end)
@ -1249,16 +1249,22 @@ defp get_user_flavour(_) do
"glitch" "glitch"
end end
def login(conn, %{"code" => code}) do def login(%{assigns: %{user: %User{}}} = conn, _params) do
redirect(conn, to: local_mastodon_root_path(conn))
end
@doc "Local Mastodon FE login init action"
def login(conn, %{"code" => auth_token}) do
with {:ok, app} <- get_or_make_app(), with {:ok, app} <- get_or_make_app(),
%Authorization{} = auth <- Repo.get_by(Authorization, token: code, app_id: app.id), %Authorization{} = auth <- Repo.get_by(Authorization, token: auth_token, app_id: app.id),
{:ok, token} <- Token.exchange_token(app, auth) do {:ok, token} <- Token.exchange_token(app, auth) do
conn conn
|> put_session(:oauth_token, token.token) |> put_session(:oauth_token, token.token)
|> redirect(to: "/web/getting-started") |> redirect(to: local_mastodon_root_path(conn))
end end
end end
@doc "Local Mastodon FE callback action"
def login(conn, _) do def login(conn, _) do
with {:ok, app} <- get_or_make_app() do with {:ok, app} <- get_or_make_app() do
path = path =
@ -1276,6 +1282,8 @@ def login(conn, _) do
end end
end end
defp local_mastodon_root_path(conn), do: mastodon_api_path(conn, :index, ["getting-started"])
defp get_or_make_app do defp get_or_make_app do
find_attrs = %{client_name: @local_mastodon_name, redirect_uris: "."} find_attrs = %{client_name: @local_mastodon_name, redirect_uris: "."}
scopes = ["read", "write", "follow", "push"] scopes = ["read", "write", "follow", "push"]
@ -1312,7 +1320,7 @@ def logout(conn, _) do
def relationship_noop(%{assigns: %{user: user}} = conn, %{"id" => id}) do def relationship_noop(%{assigns: %{user: user}} = conn, %{"id" => id}) do
Logger.debug("Unimplemented, returning unmodified relationship") Logger.debug("Unimplemented, returning unmodified relationship")
with %User{} = target <- Repo.get(User, id) do with %User{} = target <- User.get_by_id(id) do
conn conn
|> put_view(AccountView) |> put_view(AccountView)
|> render("relationship.json", %{user: user, target: target}) |> render("relationship.json", %{user: user, target: target})
@ -1454,7 +1462,7 @@ def suggestions(%{assigns: %{user: user}} = conn, _) do
end end
def status_card(%{assigns: %{user: user}} = conn, %{"id" => status_id}) do def status_card(%{assigns: %{user: user}} = conn, %{"id" => status_id}) do
with %Activity{} = activity <- Repo.get(Activity, status_id), with %Activity{} = activity <- Activity.get_by_id(status_id),
true <- Visibility.visible_for_user?(activity, user) do true <- Visibility.visible_for_user?(activity, user) do
data = data =
StatusView.render( StatusView.render(

View File

@ -90,7 +90,7 @@ defp allow_request(stream, nil) when stream in @anonymous_streams do
# Authenticated streams. # Authenticated streams.
defp allow_request(stream, {"access_token", access_token}) when stream in @streams do defp allow_request(stream, {"access_token", access_token}) when stream in @streams do
with %Token{user_id: user_id} <- Repo.get_by(Token, token: access_token), with %Token{user_id: user_id} <- Repo.get_by(Token, token: access_token),
user = %User{} <- Repo.get(User, user_id) do user = %User{} <- User.get_by_id(user_id) do
{:ok, user} {:ok, user}
else else
_ -> {:error, 403} _ -> {:error, 403}

View File

@ -9,6 +9,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do
alias Pleroma.Repo alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.Auth.Authenticator alias Pleroma.Web.Auth.Authenticator
alias Pleroma.Web.ControllerHelper
alias Pleroma.Web.OAuth.App alias Pleroma.Web.OAuth.App
alias Pleroma.Web.OAuth.Authorization alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
@ -22,7 +23,28 @@ defmodule Pleroma.Web.OAuth.OAuthController do
action_fallback(Pleroma.Web.OAuth.FallbackController) action_fallback(Pleroma.Web.OAuth.FallbackController)
def authorize(conn, params) do def authorize(%{assigns: %{token: %Token{} = token}} = conn, params) do
if ControllerHelper.truthy_param?(params["force_login"]) do
do_authorize(conn, params)
else
redirect_uri =
if is_binary(params["redirect_uri"]) do
params["redirect_uri"]
else
app = Repo.preload(token, :app).app
app.redirect_uris
|> String.split()
|> Enum.at(0)
end
redirect(conn, external: redirect_uri(conn, redirect_uri))
end
end
def authorize(conn, params), do: do_authorize(conn, params)
defp do_authorize(conn, params) do
app = Repo.get_by(App, client_id: params["client_id"]) app = Repo.get_by(App, client_id: params["client_id"])
available_scopes = (app && app.scopes) || [] available_scopes = (app && app.scopes) || []
scopes = oauth_scopes(params, nil) || available_scopes scopes = oauth_scopes(params, nil) || available_scopes
@ -99,7 +121,7 @@ def token_exchange(conn, %{"grant_type" => "authorization_code"} = params) do
fixed_token = fix_padding(params["code"]), fixed_token = fix_padding(params["code"]),
%Authorization{} = auth <- %Authorization{} = auth <-
Repo.get_by(Authorization, token: fixed_token, app_id: app.id), Repo.get_by(Authorization, token: fixed_token, app_id: app.id),
%User{} = user <- Repo.get(User, auth.user_id), %User{} = user <- User.get_by_id(auth.user_id),
{:ok, token} <- Token.exchange_token(app, auth), {:ok, token} <- Token.exchange_token(app, auth),
{:ok, inserted_at} <- DateTime.from_naive(token.inserted_at, "Etc/UTC") do {:ok, inserted_at} <- DateTime.from_naive(token.inserted_at, "Etc/UTC") do
response = %{ response = %{

View File

@ -27,7 +27,7 @@ defmodule Pleroma.Web.OAuth.Token do
def exchange_token(app, auth) do def exchange_token(app, auth) do
with {:ok, auth} <- Authorization.use_token(auth), with {:ok, auth} <- Authorization.use_token(auth),
true <- auth.app_id == app.id do true <- auth.app_id == app.id do
create_token(app, Repo.get(User, auth.user_id), auth.scopes) create_token(app, User.get_by_id(auth.user_id), auth.scopes)
end end
end end

View File

@ -10,6 +10,11 @@ defmodule Pleroma.Web.Router do
plug(:fetch_session) plug(:fetch_session)
end end
pipeline :oauth do
plug(:fetch_session)
plug(Pleroma.Plugs.OAuthPlug)
end
pipeline :api do pipeline :api do
plug(:accepts, ["json"]) plug(:accepts, ["json"])
plug(:fetch_session) plug(:fetch_session)
@ -110,10 +115,6 @@ defmodule Pleroma.Web.Router do
plug(:accepts, ["json", "xml"]) plug(:accepts, ["json", "xml"])
end end
pipeline :oauth do
plug(:accepts, ["html", "json"])
end
pipeline :pleroma_api do pipeline :pleroma_api do
plug(:accepts, ["html", "json"]) plug(:accepts, ["html", "json"])
end end
@ -205,7 +206,11 @@ defmodule Pleroma.Web.Router do
end end
scope "/oauth", Pleroma.Web.OAuth do scope "/oauth", Pleroma.Web.OAuth do
get("/authorize", OAuthController, :authorize) scope [] do
pipe_through(:oauth)
get("/authorize", OAuthController, :authorize)
end
post("/authorize", OAuthController, :create_authorization) post("/authorize", OAuthController, :create_authorization)
post("/token", OAuthController, :token_exchange) post("/token", OAuthController, :token_exchange)
post("/revoke", OAuthController, :token_revoke) post("/revoke", OAuthController, :token_revoke)

View File

@ -8,7 +8,6 @@ defmodule Pleroma.Web.Streamer do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Notification alias Pleroma.Notification
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.ActivityPub.Visibility alias Pleroma.Web.ActivityPub.Visibility
@ -82,7 +81,7 @@ def handle_cast(%{action: :stream, topic: "list", item: item}, topics) do
_ -> _ ->
Pleroma.List.get_lists_from_activity(item) Pleroma.List.get_lists_from_activity(item)
|> Enum.filter(fn list -> |> Enum.filter(fn list ->
owner = Repo.get(User, list.user_id) owner = User.get_by_id(list.user_id)
Visibility.visible_for_user?(item, owner) Visibility.visible_for_user?(item, owner)
end) end)

View File

@ -21,7 +21,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
def show_password_reset(conn, %{"token" => token}) do def show_password_reset(conn, %{"token" => token}) do
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}), with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
%User{} = user <- Repo.get(User, token.user_id) do %User{} = user <- User.get_by_id(token.user_id) do
render(conn, "password_reset.html", %{ render(conn, "password_reset.html", %{
token: token, token: token,
user: user user: user
@ -96,13 +96,13 @@ def remote_follow(%{assigns: %{user: user}} = conn, %{"acct" => acct}) do
def do_remote_follow(conn, %{ def do_remote_follow(conn, %{
"authorization" => %{"name" => username, "password" => password, "id" => id} "authorization" => %{"name" => username, "password" => password, "id" => id}
}) do }) do
followee = Repo.get(User, id) followee = User.get_by_id(id)
avatar = User.avatar_url(followee) avatar = User.avatar_url(followee)
name = followee.nickname name = followee.nickname
with %User{} = user <- User.get_cached_by_nickname(username), with %User{} = user <- User.get_cached_by_nickname(username),
true <- Pbkdf2.checkpw(password, user.password_hash), true <- Pbkdf2.checkpw(password, user.password_hash),
%User{} = _followed <- Repo.get(User, id), %User{} = _followed <- User.get_by_id(id),
{:ok, follower} <- User.follow(user, followee), {:ok, follower} <- User.follow(user, followee),
{:ok, _activity} <- ActivityPub.follow(follower, followee) do {:ok, _activity} <- ActivityPub.follow(follower, followee) do
conn conn
@ -124,7 +124,7 @@ def do_remote_follow(conn, %{
end end
def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}}) do def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}}) do
with %User{} = followee <- Repo.get(User, id), with %User{} = followee <- User.get_by_id(id),
{:ok, follower} <- User.follow(user, followee), {:ok, follower} <- User.follow(user, followee),
{:ok, _activity} <- ActivityPub.follow(follower, followee) do {:ok, _activity} <- ActivityPub.follow(follower, followee) do
conn conn

View File

@ -20,7 +20,7 @@ def create_status(%User{} = user, %{"status" => _} = data) do
end end
def delete(%User{} = user, id) do def delete(%User{} = user, id) do
with %Activity{data: %{"type" => _type}} <- Repo.get(Activity, id), with %Activity{data: %{"type" => _type}} <- Activity.get_by_id(id),
{:ok, activity} <- CommonAPI.delete(id, user) do {:ok, activity} <- CommonAPI.delete(id, user) do
{:ok, activity} {:ok, activity}
end end

View File

@ -270,7 +270,7 @@ def unfollow(%{assigns: %{user: user}} = conn, params) do
end end
def fetch_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do def fetch_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
with %Activity{} = activity <- Repo.get(Activity, id), with %Activity{} = activity <- Activity.get_by_id(id),
true <- Visibility.visible_for_user?(activity, user) do true <- Visibility.visible_for_user?(activity, user) do
conn conn
|> put_view(ActivityView) |> put_view(ActivityView)
@ -342,7 +342,7 @@ def upload_json(%{assigns: %{user: user}} = conn, %{"media" => media}) do
end end
def get_by_id_or_ap_id(id) do def get_by_id_or_ap_id(id) do
activity = Repo.get(Activity, id) || Activity.get_create_by_object_ap_id(id) activity = Activity.get_by_id(id) || Activity.get_create_by_object_ap_id(id)
if activity.data["type"] == "Create" do if activity.data["type"] == "Create" do
activity activity
@ -434,7 +434,7 @@ def password_reset(conn, params) do
end end
def confirm_email(conn, %{"user_id" => uid, "token" => token}) do def confirm_email(conn, %{"user_id" => uid, "token" => token}) do
with %User{} = user <- Repo.get(User, uid), with %User{} = user <- User.get_by_id(uid),
true <- user.local, true <- user.local,
true <- user.info.confirmation_pending, true <- user.info.confirmation_pending,
true <- user.info.confirmation_token == token, true <- user.info.confirmation_token == token,
@ -587,7 +587,7 @@ def friend_requests(conn, params) do
def approve_friend_request(conn, %{"user_id" => uid} = _params) do def approve_friend_request(conn, %{"user_id" => uid} = _params) do
with followed <- conn.assigns[:user], with followed <- conn.assigns[:user],
%User{} = follower <- Repo.get(User, uid), %User{} = follower <- User.get_by_id(uid),
{:ok, follower} <- CommonAPI.accept_follow_request(follower, followed) do {:ok, follower} <- CommonAPI.accept_follow_request(follower, followed) do
conn conn
|> put_view(UserView) |> put_view(UserView)
@ -599,7 +599,7 @@ def approve_friend_request(conn, %{"user_id" => uid} = _params) do
def deny_friend_request(conn, %{"user_id" => uid} = _params) do def deny_friend_request(conn, %{"user_id" => uid} = _params) do
with followed <- conn.assigns[:user], with followed <- conn.assigns[:user],
%User{} = follower <- Repo.get(User, uid), %User{} = follower <- User.get_by_id(uid),
{:ok, follower} <- CommonAPI.reject_follow_request(follower, followed) do {:ok, follower} <- CommonAPI.reject_follow_request(follower, followed) do
conn conn
|> put_view(UserView) |> put_view(UserView)

View File

@ -216,7 +216,7 @@ def oauth_app_factory do
redirect_uris: "https://example.com/callback", redirect_uris: "https://example.com/callback",
scopes: ["read", "write", "follow", "push"], scopes: ["read", "write", "follow", "push"],
website: "https://example.com", website: "https://example.com",
client_id: "aaabbb==", client_id: Ecto.UUID.generate(),
client_secret: "aaa;/&bbb" client_secret: "aaa;/&bbb"
} }
end end

View File

@ -122,7 +122,7 @@ test "follow takes a user and another user" do
{:ok, user} = User.follow(user, followed) {:ok, user} = User.follow(user, followed)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
followed = User.get_by_ap_id(followed.ap_id) followed = User.get_by_ap_id(followed.ap_id)
assert followed.info.follower_count == 1 assert followed.info.follower_count == 1
@ -178,7 +178,7 @@ test "unfollow takes a user and another user" do
{:ok, user, _activity} = User.unfollow(user, followed) {:ok, user, _activity} = User.unfollow(user, followed)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert user.following == [] assert user.following == []
end end
@ -188,7 +188,7 @@ test "unfollow doesn't unfollow yourself" do
{:error, _} = User.unfollow(user, user) {:error, _} = User.unfollow(user, user)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert user.following == [user.ap_id] assert user.following == [user.ap_id]
end end
@ -200,6 +200,13 @@ test "test if a user is following another user" do
refute User.following?(followed, user) refute User.following?(followed, user)
end end
test "fetches correct profile for nickname beginning with number" do
# Use old-style integer ID to try to reproduce the problem
user = insert(:user, %{id: 1080})
userwithnumbers = insert(:user, %{nickname: "#{user.id}garbage"})
assert userwithnumbers == User.get_cached_by_nickname_or_id(userwithnumbers.nickname)
end
describe "user registration" do describe "user registration" do
@full_user_data %{ @full_user_data %{
bio: "A guy", bio: "A guy",
@ -679,7 +686,7 @@ test "blocks tear down cyclical follow relationships" do
assert User.following?(blocked, blocker) assert User.following?(blocked, blocker)
{:ok, blocker} = User.block(blocker, blocked) {:ok, blocker} = User.block(blocker, blocked)
blocked = Repo.get(User, blocked.id) blocked = User.get_by_id(blocked.id)
assert User.blocks?(blocker, blocked) assert User.blocks?(blocker, blocked)
@ -697,7 +704,7 @@ test "blocks tear down blocker->blocked follow relationships" do
refute User.following?(blocked, blocker) refute User.following?(blocked, blocker)
{:ok, blocker} = User.block(blocker, blocked) {:ok, blocker} = User.block(blocker, blocked)
blocked = Repo.get(User, blocked.id) blocked = User.get_by_id(blocked.id)
assert User.blocks?(blocker, blocked) assert User.blocks?(blocker, blocked)
@ -715,7 +722,7 @@ test "blocks tear down blocked->blocker follow relationships" do
assert User.following?(blocked, blocker) assert User.following?(blocked, blocker)
{:ok, blocker} = User.block(blocker, blocked) {:ok, blocker} = User.block(blocker, blocked)
blocked = Repo.get(User, blocked.id) blocked = User.get_by_id(blocked.id)
assert User.blocks?(blocker, blocked) assert User.blocks?(blocker, blocked)
@ -809,9 +816,9 @@ test ".delete deactivates a user, all follow relationships and all create activi
{:ok, _} = User.delete(user) {:ok, _} = User.delete(user)
followed = Repo.get(User, followed.id) followed = User.get_by_id(followed.id)
follower = Repo.get(User, follower.id) follower = User.get_by_id(follower.id)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert user.info.deactivated assert user.info.deactivated
@ -820,7 +827,7 @@ test ".delete deactivates a user, all follow relationships and all create activi
# TODO: Remove favorites, repeats, delete activities. # TODO: Remove favorites, repeats, delete activities.
refute Repo.get(Activity, activity.id) refute Activity.get_by_id(activity.id)
end end
test "get_public_key_for_ap_id fetches a user that's not in the db" do test "get_public_key_for_ap_id fetches a user that's not in the db" do

View File

@ -8,7 +8,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Instances alias Pleroma.Instances
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
alias Pleroma.Web.ActivityPub.ObjectView alias Pleroma.Web.ActivityPub.ObjectView
alias Pleroma.Web.ActivityPub.UserView alias Pleroma.Web.ActivityPub.UserView
@ -51,7 +50,7 @@ test "it returns a json representation of the user with accept application/json"
|> put_req_header("accept", "application/json") |> put_req_header("accept", "application/json")
|> get("/users/#{user.nickname}") |> get("/users/#{user.nickname}")
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert json_response(conn, 200) == UserView.render("user.json", %{user: user}) assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
end end
@ -66,7 +65,7 @@ test "it returns a json representation of the user with accept application/activ
|> put_req_header("accept", "application/activity+json") |> put_req_header("accept", "application/activity+json")
|> get("/users/#{user.nickname}") |> get("/users/#{user.nickname}")
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert json_response(conn, 200) == UserView.render("user.json", %{user: user}) assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
end end
@ -84,7 +83,7 @@ test "it returns a json representation of the user with accept application/ld+js
) )
|> get("/users/#{user.nickname}") |> get("/users/#{user.nickname}")
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert json_response(conn, 200) == UserView.render("user.json", %{user: user}) assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
end end
@ -543,7 +542,7 @@ test "it works for more than 10 users", %{conn: conn} do
user = insert(:user) user = insert(:user)
Enum.each(1..15, fn _ -> Enum.each(1..15, fn _ ->
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
other_user = insert(:user) other_user = insert(:user)
User.follow(user, other_user) User.follow(user, other_user)
end) end)

View File

@ -218,18 +218,18 @@ test "increases user note count only for public activities" do
user = insert(:user) user = insert(:user)
{:ok, _} = {:ok, _} =
CommonAPI.post(Repo.get(User, user.id), %{"status" => "1", "visibility" => "public"}) CommonAPI.post(User.get_by_id(user.id), %{"status" => "1", "visibility" => "public"})
{:ok, _} = {:ok, _} =
CommonAPI.post(Repo.get(User, user.id), %{"status" => "2", "visibility" => "unlisted"}) CommonAPI.post(User.get_by_id(user.id), %{"status" => "2", "visibility" => "unlisted"})
{:ok, _} = {:ok, _} =
CommonAPI.post(Repo.get(User, user.id), %{"status" => "2", "visibility" => "private"}) CommonAPI.post(User.get_by_id(user.id), %{"status" => "2", "visibility" => "private"})
{:ok, _} = {:ok, _} =
CommonAPI.post(Repo.get(User, user.id), %{"status" => "3", "visibility" => "direct"}) CommonAPI.post(User.get_by_id(user.id), %{"status" => "3", "visibility" => "direct"})
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert user.info.note_count == 2 assert user.info.note_count == 2
end end
@ -322,7 +322,7 @@ test "doesn't return blocked activities" do
{:ok, user} = User.block(user, %{ap_id: activity_three.data["actor"]}) {:ok, user} = User.block(user, %{ap_id: activity_three.data["actor"]})
{:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster) {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster)
%Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id) %Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
activity_three = Repo.get(Activity, activity_three.id) activity_three = Activity.get_by_id(activity_three.id)
activities = activities =
ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true}) ActivityPub.fetch_activities([], %{"blocking_user" => user, "skip_preload" => true})
@ -380,7 +380,7 @@ test "doesn't return muted activities" do
{:ok, user} = User.mute(user, %User{ap_id: activity_three.data["actor"]}) {:ok, user} = User.mute(user, %User{ap_id: activity_three.data["actor"]})
{:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster) {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster)
%Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id) %Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
activity_three = Repo.get(Activity, activity_three.id) activity_three = Activity.get_by_id(activity_three.id)
activities = activities =
ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true}) ActivityPub.fetch_activities([], %{"muting_user" => user, "skip_preload" => true})
@ -559,7 +559,7 @@ test "unliking a previously liked object" do
{:ok, _, _, object} = ActivityPub.unlike(user, object) {:ok, _, _, object} = ActivityPub.unlike(user, object)
assert object.data["like_count"] == 0 assert object.data["like_count"] == 0
assert Repo.get(Activity, like_activity.id) == nil assert Activity.get_by_id(like_activity.id) == nil
end end
end end
@ -610,7 +610,7 @@ test "unannouncing a previously announced object" do
assert unannounce_activity.data["actor"] == user.ap_id assert unannounce_activity.data["actor"] == user.ap_id
assert unannounce_activity.data["context"] == announce_activity.data["context"] assert unannounce_activity.data["context"] == announce_activity.data["context"]
assert Repo.get(Activity, announce_activity.id) == nil assert Activity.get_by_id(announce_activity.id) == nil
end end
end end
@ -749,7 +749,7 @@ test "it creates a delete activity and deletes the original object" do
assert delete.data["actor"] == note.data["actor"] assert delete.data["actor"] == note.data["actor"]
assert delete.data["object"] == note.data["object"]["id"] assert delete.data["object"] == note.data["object"]["id"]
assert Repo.get(Activity, delete.id) != nil assert Activity.get_by_id(delete.id) != nil
assert Repo.get(Object, object.id).data["type"] == "Tombstone" assert Repo.get(Object, object.id).data["type"] == "Tombstone"
end end
@ -758,23 +758,23 @@ test "decrements user note count only for public activities" do
user = insert(:user, info: %{note_count: 10}) user = insert(:user, info: %{note_count: 10})
{:ok, a1} = {:ok, a1} =
CommonAPI.post(Repo.get(User, user.id), %{"status" => "yeah", "visibility" => "public"}) CommonAPI.post(User.get_by_id(user.id), %{"status" => "yeah", "visibility" => "public"})
{:ok, a2} = {:ok, a2} =
CommonAPI.post(Repo.get(User, user.id), %{"status" => "yeah", "visibility" => "unlisted"}) CommonAPI.post(User.get_by_id(user.id), %{"status" => "yeah", "visibility" => "unlisted"})
{:ok, a3} = {:ok, a3} =
CommonAPI.post(Repo.get(User, user.id), %{"status" => "yeah", "visibility" => "private"}) CommonAPI.post(User.get_by_id(user.id), %{"status" => "yeah", "visibility" => "private"})
{:ok, a4} = {:ok, a4} =
CommonAPI.post(Repo.get(User, user.id), %{"status" => "yeah", "visibility" => "direct"}) CommonAPI.post(User.get_by_id(user.id), %{"status" => "yeah", "visibility" => "direct"})
{:ok, _} = a1.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete() {:ok, _} = a1.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete()
{:ok, _} = a2.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete() {:ok, _} = a2.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete()
{:ok, _} = a3.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete() {:ok, _} = a3.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete()
{:ok, _} = a4.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete() {:ok, _} = a4.data["object"]["id"] |> Object.get_by_ap_id() |> ActivityPub.delete()
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert user.info.note_count == 10 assert user.info.note_count == 10
end end

View File

@ -461,7 +461,7 @@ test "it works for incoming deletes" do
{:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data) {:ok, %Activity{local: false}} = Transmogrifier.handle_incoming(data)
refute Repo.get(Activity, activity.id) refute Activity.get_by_id(activity.id)
end end
test "it fails for incoming deletes with spoofed origin" do test "it fails for incoming deletes with spoofed origin" do
@ -481,7 +481,7 @@ test "it fails for incoming deletes with spoofed origin" do
:error = Transmogrifier.handle_incoming(data) :error = Transmogrifier.handle_incoming(data)
assert Repo.get(Activity, activity.id) assert Activity.get_by_id(activity.id)
end end
test "it works for incoming unannounces with an existing notice" do test "it works for incoming unannounces with an existing notice" do
@ -639,7 +639,7 @@ test "it works for incoming accepts which were pre-accepted" do
assert activity.data["object"] == follow_activity.data["id"] assert activity.data["object"] == follow_activity.data["id"]
follower = Repo.get(User, follower.id) follower = User.get_by_id(follower.id)
assert User.following?(follower, followed) == true assert User.following?(follower, followed) == true
end end
@ -661,7 +661,7 @@ test "it works for incoming accepts which were orphaned" do
{:ok, activity} = Transmogrifier.handle_incoming(accept_data) {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
assert activity.data["object"] == follow_activity.data["id"] assert activity.data["object"] == follow_activity.data["id"]
follower = Repo.get(User, follower.id) follower = User.get_by_id(follower.id)
assert User.following?(follower, followed) == true assert User.following?(follower, followed) == true
end end
@ -681,7 +681,7 @@ test "it works for incoming accepts which are referenced by IRI only" do
{:ok, activity} = Transmogrifier.handle_incoming(accept_data) {:ok, activity} = Transmogrifier.handle_incoming(accept_data)
assert activity.data["object"] == follow_activity.data["id"] assert activity.data["object"] == follow_activity.data["id"]
follower = Repo.get(User, follower.id) follower = User.get_by_id(follower.id)
assert User.following?(follower, followed) == true assert User.following?(follower, followed) == true
end end
@ -700,7 +700,7 @@ test "it fails for incoming accepts which cannot be correlated" do
:error = Transmogrifier.handle_incoming(accept_data) :error = Transmogrifier.handle_incoming(accept_data)
follower = Repo.get(User, follower.id) follower = User.get_by_id(follower.id)
refute User.following?(follower, followed) == true refute User.following?(follower, followed) == true
end end
@ -719,7 +719,7 @@ test "it fails for incoming rejects which cannot be correlated" do
:error = Transmogrifier.handle_incoming(accept_data) :error = Transmogrifier.handle_incoming(accept_data)
follower = Repo.get(User, follower.id) follower = User.get_by_id(follower.id)
refute User.following?(follower, followed) == true refute User.following?(follower, followed) == true
end end
@ -744,7 +744,7 @@ test "it works for incoming rejects which are orphaned" do
{:ok, activity} = Transmogrifier.handle_incoming(reject_data) {:ok, activity} = Transmogrifier.handle_incoming(reject_data)
refute activity.local refute activity.local
follower = Repo.get(User, follower.id) follower = User.get_by_id(follower.id)
assert User.following?(follower, followed) == false assert User.following?(follower, followed) == false
end end
@ -766,7 +766,7 @@ test "it works for incoming rejects which are referenced by IRI only" do
{:ok, %Activity{data: _}} = Transmogrifier.handle_incoming(reject_data) {:ok, %Activity{data: _}} = Transmogrifier.handle_incoming(reject_data)
follower = Repo.get(User, follower.id) follower = User.get_by_id(follower.id)
assert User.following?(follower, followed) == false assert User.following?(follower, followed) == false
end end
@ -1020,7 +1020,7 @@ test "it upgrades a user to activitypub" do
{:ok, unrelated_activity} = CommonAPI.post(user_two, %{"status" => "test"}) {:ok, unrelated_activity} = CommonAPI.post(user_two, %{"status" => "test"})
assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert user.info.note_count == 1 assert user.info.note_count == 1
{:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye") {:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
@ -1031,10 +1031,10 @@ test "it upgrades a user to activitypub" do
# Wait for the background task # Wait for the background task
:timer.sleep(1000) :timer.sleep(1000)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert user.info.note_count == 1 assert user.info.note_count == 1
activity = Repo.get(Activity, activity.id) activity = Activity.get_by_id(activity.id)
assert user.follower_address in activity.recipients assert user.follower_address in activity.recipients
assert %{ assert %{
@ -1057,10 +1057,10 @@ test "it upgrades a user to activitypub" do
refute "..." in activity.recipients refute "..." in activity.recipients
unrelated_activity = Repo.get(Activity, unrelated_activity.id) unrelated_activity = Activity.get_by_id(unrelated_activity.id)
refute user.follower_address in unrelated_activity.recipients refute user.follower_address in unrelated_activity.recipients
user_two = Repo.get(User, user_two.id) user_two = User.get_by_id(user_two.id)
assert user.follower_address in user_two.following assert user.follower_address in user_two.following
refute "..." in user_two.following refute "..." in user_two.following
end end

View File

@ -5,7 +5,6 @@
defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
use Pleroma.Web.ConnCase use Pleroma.Web.ConnCase
alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
import Pleroma.Factory import Pleroma.Factory
@ -101,13 +100,13 @@ test "it appends specified tags to users with specified nicknames", %{
user2: user2 user2: user2
} do } do
assert json_response(conn, :no_content) assert json_response(conn, :no_content)
assert Repo.get(User, user1.id).tags == ["x", "foo", "bar"] assert User.get_by_id(user1.id).tags == ["x", "foo", "bar"]
assert Repo.get(User, user2.id).tags == ["y", "foo", "bar"] assert User.get_by_id(user2.id).tags == ["y", "foo", "bar"]
end end
test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
assert json_response(conn, :no_content) assert json_response(conn, :no_content)
assert Repo.get(User, user3.id).tags == ["unchanged"] assert User.get_by_id(user3.id).tags == ["unchanged"]
end end
end end
@ -137,13 +136,13 @@ test "it removes specified tags from users with specified nicknames", %{
user2: user2 user2: user2
} do } do
assert json_response(conn, :no_content) assert json_response(conn, :no_content)
assert Repo.get(User, user1.id).tags == [] assert User.get_by_id(user1.id).tags == []
assert Repo.get(User, user2.id).tags == ["y"] assert User.get_by_id(user2.id).tags == ["y"]
end end
test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do
assert json_response(conn, :no_content) assert json_response(conn, :no_content)
assert Repo.get(User, user3.id).tags == ["unchanged"] assert User.get_by_id(user3.id).tags == ["unchanged"]
end end
end end
@ -213,7 +212,7 @@ test "deactivates the user", %{conn: conn} do
conn conn
|> put("/api/pleroma/admin/activation_status/#{user.nickname}", %{status: false}) |> put("/api/pleroma/admin/activation_status/#{user.nickname}", %{status: false})
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert user.info.deactivated == true assert user.info.deactivated == true
assert json_response(conn, :no_content) assert json_response(conn, :no_content)
end end
@ -225,7 +224,7 @@ test "activates the user", %{conn: conn} do
conn conn
|> put("/api/pleroma/admin/activation_status/#{user.nickname}", %{status: true}) |> put("/api/pleroma/admin/activation_status/#{user.nickname}", %{status: true})
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
assert user.info.deactivated == false assert user.info.deactivated == false
assert json_response(conn, :no_content) assert json_response(conn, :no_content)
end end

View File

@ -101,7 +101,7 @@ test "posting a status", %{conn: conn} do
assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} = assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} =
json_response(conn_one, 200) json_response(conn_one, 200)
assert Repo.get(Activity, id) assert Activity.get_by_id(id)
conn_two = conn_two =
conn conn
@ -140,7 +140,7 @@ test "posting a sensitive status", %{conn: conn} do
|> post("/api/v1/statuses", %{"status" => "cofe", "sensitive" => true}) |> post("/api/v1/statuses", %{"status" => "cofe", "sensitive" => true})
assert %{"content" => "cofe", "id" => id, "sensitive" => true} = json_response(conn, 200) assert %{"content" => "cofe", "id" => id, "sensitive" => true} = json_response(conn, 200)
assert Repo.get(Activity, id) assert Activity.get_by_id(id)
end end
test "posting a status with OGP link preview", %{conn: conn} do test "posting a status with OGP link preview", %{conn: conn} do
@ -155,7 +155,7 @@ test "posting a status with OGP link preview", %{conn: conn} do
}) })
assert %{"id" => id, "card" => %{"title" => "The Rock"}} = json_response(conn, 200) assert %{"id" => id, "card" => %{"title" => "The Rock"}} = json_response(conn, 200)
assert Repo.get(Activity, id) assert Activity.get_by_id(id)
Pleroma.Config.put([:rich_media, :enabled], false) Pleroma.Config.put([:rich_media, :enabled], false)
end end
@ -170,7 +170,7 @@ test "posting a direct status", %{conn: conn} do
|> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"}) |> post("api/v1/statuses", %{"status" => content, "visibility" => "direct"})
assert %{"id" => id, "visibility" => "direct"} = json_response(conn, 200) assert %{"id" => id, "visibility" => "direct"} = json_response(conn, 200)
assert activity = Repo.get(Activity, id) assert activity = Activity.get_by_id(id)
assert activity.recipients == [user2.ap_id, user1.ap_id] assert activity.recipients == [user2.ap_id, user1.ap_id]
assert activity.data["to"] == [user2.ap_id] assert activity.data["to"] == [user2.ap_id]
assert activity.data["cc"] == [] assert activity.data["cc"] == []
@ -289,7 +289,7 @@ test "replying to a status", %{conn: conn} do
assert %{"content" => "xD", "id" => id} = json_response(conn, 200) assert %{"content" => "xD", "id" => id} = json_response(conn, 200)
activity = Repo.get(Activity, id) activity = Activity.get_by_id(id)
assert activity.data["context"] == replied_to.data["context"] assert activity.data["context"] == replied_to.data["context"]
assert activity.data["object"]["inReplyToStatusId"] == replied_to.id assert activity.data["object"]["inReplyToStatusId"] == replied_to.id
@ -305,7 +305,7 @@ test "posting a status with an invalid in_reply_to_id", %{conn: conn} do
assert %{"content" => "xD", "id" => id} = json_response(conn, 200) assert %{"content" => "xD", "id" => id} = json_response(conn, 200)
activity = Repo.get(Activity, id) activity = Activity.get_by_id(id)
assert activity assert activity
end end
@ -404,7 +404,7 @@ test "when you created it", %{conn: conn} do
assert %{} = json_response(conn, 200) assert %{} = json_response(conn, 200)
refute Repo.get(Activity, activity.id) refute Activity.get_by_id(activity.id)
end end
test "when you didn't create it", %{conn: conn} do test "when you didn't create it", %{conn: conn} do
@ -418,7 +418,7 @@ test "when you didn't create it", %{conn: conn} do
assert %{"error" => _} = json_response(conn, 403) assert %{"error" => _} = json_response(conn, 403)
assert Repo.get(Activity, activity.id) == activity assert Activity.get_by_id(activity.id) == activity
end end
test "when you're an admin or moderator", %{conn: conn} do test "when you're an admin or moderator", %{conn: conn} do
@ -441,8 +441,8 @@ test "when you're an admin or moderator", %{conn: conn} do
assert %{} = json_response(res_conn, 200) assert %{} = json_response(res_conn, 200)
refute Repo.get(Activity, activity1.id) refute Activity.get_by_id(activity1.id)
refute Repo.get(Activity, activity2.id) refute Activity.get_by_id(activity2.id)
end end
end end
@ -1112,8 +1112,8 @@ test "/api/v1/follow_requests works" do
{:ok, _activity} = ActivityPub.follow(other_user, user) {:ok, _activity} = ActivityPub.follow(other_user, user)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
other_user = Repo.get(User, other_user.id) other_user = User.get_by_id(other_user.id)
assert User.following?(other_user, user) == false assert User.following?(other_user, user) == false
@ -1132,8 +1132,8 @@ test "/api/v1/follow_requests/:id/authorize works" do
{:ok, _activity} = ActivityPub.follow(other_user, user) {:ok, _activity} = ActivityPub.follow(other_user, user)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
other_user = Repo.get(User, other_user.id) other_user = User.get_by_id(other_user.id)
assert User.following?(other_user, user) == false assert User.following?(other_user, user) == false
@ -1145,8 +1145,8 @@ test "/api/v1/follow_requests/:id/authorize works" do
assert relationship = json_response(conn, 200) assert relationship = json_response(conn, 200)
assert to_string(other_user.id) == relationship["id"] assert to_string(other_user.id) == relationship["id"]
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
other_user = Repo.get(User, other_user.id) other_user = User.get_by_id(other_user.id)
assert User.following?(other_user, user) == true assert User.following?(other_user, user) == true
end end
@ -1169,7 +1169,7 @@ test "/api/v1/follow_requests/:id/reject works" do
{:ok, _activity} = ActivityPub.follow(other_user, user) {:ok, _activity} = ActivityPub.follow(other_user, user)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
conn = conn =
build_conn() build_conn()
@ -1179,8 +1179,8 @@ test "/api/v1/follow_requests/:id/reject works" do
assert relationship = json_response(conn, 200) assert relationship = json_response(conn, 200)
assert to_string(other_user.id) == relationship["id"] assert to_string(other_user.id) == relationship["id"]
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
other_user = Repo.get(User, other_user.id) other_user = User.get_by_id(other_user.id)
assert User.following?(other_user, user) == false assert User.following?(other_user, user) == false
end end
@ -1465,7 +1465,7 @@ test "following / unfollowing a user", %{conn: conn} do
assert %{"id" => _id, "following" => true} = json_response(conn, 200) assert %{"id" => _id, "following" => true} = json_response(conn, 200)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
conn = conn =
build_conn() build_conn()
@ -1474,7 +1474,7 @@ test "following / unfollowing a user", %{conn: conn} do
assert %{"id" => _id, "following" => false} = json_response(conn, 200) assert %{"id" => _id, "following" => false} = json_response(conn, 200)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
conn = conn =
build_conn() build_conn()
@ -1496,7 +1496,7 @@ test "muting / unmuting a user", %{conn: conn} do
assert %{"id" => _id, "muting" => true} = json_response(conn, 200) assert %{"id" => _id, "muting" => true} = json_response(conn, 200)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
conn = conn =
build_conn() build_conn()
@ -1532,7 +1532,7 @@ test "blocking / unblocking a user", %{conn: conn} do
assert %{"id" => _id, "blocking" => true} = json_response(conn, 200) assert %{"id" => _id, "blocking" => true} = json_response(conn, 200)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
conn = conn =
build_conn() build_conn()
@ -1889,7 +1889,7 @@ test "get instance stats", %{conn: conn} do
{:ok, _} = TwitterAPI.create_status(user, %{"status" => "cofe"}) {:ok, _} = TwitterAPI.create_status(user, %{"status" => "cofe"})
# Stats should count users with missing or nil `info.deactivated` value # Stats should count users with missing or nil `info.deactivated` value
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
info_change = Changeset.change(user.info, %{deactivated: nil}) info_change = Changeset.change(user.info, %{deactivated: nil})
{:ok, _user} = {:ok, _user} =
@ -2265,4 +2265,30 @@ test "preserves parameters in link headers", %{conn: conn} do
assert link_header =~ ~r/max_id=#{notification1.id}/ assert link_header =~ ~r/max_id=#{notification1.id}/
end end
end end
test "accounts fetches correct account for nicknames beginning with numbers", %{conn: conn} do
# Need to set an old-style integer ID to reproduce the problem
# (these are no longer assigned to new accounts but were preserved
# for existing accounts during the migration to flakeIDs)
user_one = insert(:user, %{id: 1212})
user_two = insert(:user, %{nickname: "#{user_one.id}garbage"})
resp_one =
conn
|> get("/api/v1/accounts/#{user_one.id}")
resp_two =
conn
|> get("/api/v1/accounts/#{user_two.nickname}")
resp_three =
conn
|> get("/api/v1/accounts/#{user_two.id}")
acc_one = json_response(resp_one, 200)
acc_two = json_response(resp_two, 200)
acc_three = json_response(resp_three, 200)
refute acc_one == acc_two
assert acc_two == acc_three
end
end end

View File

@ -21,7 +21,7 @@ test "Mention notification" do
mentioned_user = insert(:user) mentioned_user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{mentioned_user.nickname}"}) {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{mentioned_user.nickname}"})
{:ok, [notification]} = Notification.create_notifications(activity) {:ok, [notification]} = Notification.create_notifications(activity)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
expected = %{ expected = %{
id: to_string(notification.id), id: to_string(notification.id),
@ -44,7 +44,7 @@ test "Favourite notification" do
{:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"}) {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"})
{:ok, favorite_activity, _object} = CommonAPI.favorite(create_activity.id, another_user) {:ok, favorite_activity, _object} = CommonAPI.favorite(create_activity.id, another_user)
{:ok, [notification]} = Notification.create_notifications(favorite_activity) {:ok, [notification]} = Notification.create_notifications(favorite_activity)
create_activity = Repo.get(Activity, create_activity.id) create_activity = Activity.get_by_id(create_activity.id)
expected = %{ expected = %{
id: to_string(notification.id), id: to_string(notification.id),
@ -66,7 +66,7 @@ test "Reblog notification" do
{:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"}) {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"})
{:ok, reblog_activity, _object} = CommonAPI.repeat(create_activity.id, another_user) {:ok, reblog_activity, _object} = CommonAPI.repeat(create_activity.id, another_user)
{:ok, [notification]} = Notification.create_notifications(reblog_activity) {:ok, [notification]} = Notification.create_notifications(reblog_activity)
reblog_activity = Repo.get(Activity, create_activity.id) reblog_activity = Activity.get_by_id(create_activity.id)
expected = %{ expected = %{
id: to_string(notification.id), id: to_string(notification.id),

View File

@ -10,261 +10,339 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
alias Pleroma.Web.OAuth.Authorization alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.Token alias Pleroma.Web.OAuth.Token
test "redirects with oauth authorization" do describe "GET /oauth/authorize" do
user = insert(:user) setup do
app = insert(:oauth_app, scopes: ["read", "write", "follow"]) session_opts = [
store: :cookie,
key: "_test",
signing_salt: "cooldude"
]
conn = [
build_conn() app: insert(:oauth_app, redirect_uris: "https://redirect.url"),
|> post("/oauth/authorize", %{ conn:
"authorization" => %{ build_conn()
"name" => user.nickname, |> Plug.Session.call(Plug.Session.init(session_opts))
"password" => "test", |> fetch_session()
"client_id" => app.client_id, ]
"redirect_uri" => app.redirect_uris,
"scope" => "read write",
"state" => "statepassed"
}
})
target = redirected_to(conn)
assert target =~ app.redirect_uris
query = URI.parse(target).query |> URI.query_decoder() |> Map.new()
assert %{"state" => "statepassed", "code" => code} = query
auth = Repo.get_by(Authorization, token: code)
assert auth
assert auth.scopes == ["read", "write"]
end
test "returns 401 for wrong credentials", %{conn: conn} do
user = insert(:user)
app = insert(:oauth_app)
result =
conn
|> post("/oauth/authorize", %{
"authorization" => %{
"name" => user.nickname,
"password" => "wrong",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
"state" => "statepassed",
"scope" => Enum.join(app.scopes, " ")
}
})
|> html_response(:unauthorized)
# Keep the details
assert result =~ app.client_id
assert result =~ app.redirect_uris
# Error message
assert result =~ "Invalid Username/Password"
end
test "returns 401 for missing scopes", %{conn: conn} do
user = insert(:user)
app = insert(:oauth_app)
result =
conn
|> post("/oauth/authorize", %{
"authorization" => %{
"name" => user.nickname,
"password" => "test",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
"state" => "statepassed",
"scope" => ""
}
})
|> html_response(:unauthorized)
# Keep the details
assert result =~ app.client_id
assert result =~ app.redirect_uris
# Error message
assert result =~ "This action is outside the authorized scopes"
end
test "returns 401 for scopes beyond app scopes", %{conn: conn} do
user = insert(:user)
app = insert(:oauth_app, scopes: ["read", "write"])
result =
conn
|> post("/oauth/authorize", %{
"authorization" => %{
"name" => user.nickname,
"password" => "test",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
"state" => "statepassed",
"scope" => "read write follow"
}
})
|> html_response(:unauthorized)
# Keep the details
assert result =~ app.client_id
assert result =~ app.redirect_uris
# Error message
assert result =~ "This action is outside the authorized scopes"
end
test "issues a token for an all-body request" do
user = insert(:user)
app = insert(:oauth_app, scopes: ["read", "write"])
{:ok, auth} = Authorization.create_authorization(app, user, ["write"])
conn =
build_conn()
|> post("/oauth/token", %{
"grant_type" => "authorization_code",
"code" => auth.token,
"redirect_uri" => app.redirect_uris,
"client_id" => app.client_id,
"client_secret" => app.client_secret
})
assert %{"access_token" => token, "me" => ap_id} = json_response(conn, 200)
token = Repo.get_by(Token, token: token)
assert token
assert token.scopes == auth.scopes
assert user.ap_id == ap_id
end
test "issues a token for `password` grant_type with valid credentials, with full permissions by default" do
password = "testpassword"
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
app = insert(:oauth_app, scopes: ["read", "write"])
# Note: "scope" param is intentionally omitted
conn =
build_conn()
|> post("/oauth/token", %{
"grant_type" => "password",
"username" => user.nickname,
"password" => password,
"client_id" => app.client_id,
"client_secret" => app.client_secret
})
assert %{"access_token" => token} = json_response(conn, 200)
token = Repo.get_by(Token, token: token)
assert token
assert token.scopes == app.scopes
end
test "issues a token for request with HTTP basic auth client credentials" do
user = insert(:user)
app = insert(:oauth_app, scopes: ["scope1", "scope2", "scope3"])
{:ok, auth} = Authorization.create_authorization(app, user, ["scope1", "scope2"])
assert auth.scopes == ["scope1", "scope2"]
app_encoded =
(URI.encode_www_form(app.client_id) <> ":" <> URI.encode_www_form(app.client_secret))
|> Base.encode64()
conn =
build_conn()
|> put_req_header("authorization", "Basic " <> app_encoded)
|> post("/oauth/token", %{
"grant_type" => "authorization_code",
"code" => auth.token,
"redirect_uri" => app.redirect_uris
})
assert %{"access_token" => token, "scope" => scope} = json_response(conn, 200)
assert scope == "scope1 scope2"
token = Repo.get_by(Token, token: token)
assert token
assert token.scopes == ["scope1", "scope2"]
end
test "rejects token exchange with invalid client credentials" do
user = insert(:user)
app = insert(:oauth_app)
{:ok, auth} = Authorization.create_authorization(app, user)
conn =
build_conn()
|> put_req_header("authorization", "Basic JTIxOiVGMCU5RiVBNCVCNwo=")
|> post("/oauth/token", %{
"grant_type" => "authorization_code",
"code" => auth.token,
"redirect_uri" => app.redirect_uris
})
assert resp = json_response(conn, 400)
assert %{"error" => _} = resp
refute Map.has_key?(resp, "access_token")
end
test "rejects token exchange for valid credentials belonging to unconfirmed user and confirmation is required" do
setting = Pleroma.Config.get([:instance, :account_activation_required])
unless setting do
Pleroma.Config.put([:instance, :account_activation_required], true)
on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
end end
password = "testpassword" test "renders authentication page", %{app: app, conn: conn} do
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password)) conn =
info_change = Pleroma.User.Info.confirmation_changeset(user.info, :unconfirmed) get(
conn,
"/oauth/authorize",
%{
"response_type" => "code",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
"scope" => "read"
}
)
{:ok, user} = assert html_response(conn, 200) =~ ~s(type="submit")
user end
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(:info, info_change)
|> Repo.update()
refute Pleroma.User.auth_active?(user) test "renders authentication page if user is already authenticated but `force_login` is tru-ish",
%{app: app, conn: conn} do
token = insert(:oauth_token, app_id: app.id)
app = insert(:oauth_app) conn =
conn
|> put_session(:oauth_token, token.token)
|> get(
"/oauth/authorize",
%{
"response_type" => "code",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
"scope" => "read",
"force_login" => "true"
}
)
conn = assert html_response(conn, 200) =~ ~s(type="submit")
build_conn() end
|> post("/oauth/token", %{
"grant_type" => "password",
"username" => user.nickname,
"password" => password,
"client_id" => app.client_id,
"client_secret" => app.client_secret
})
assert resp = json_response(conn, 403) test "redirects to app if user is already authenticated", %{app: app, conn: conn} do
assert %{"error" => _} = resp token = insert(:oauth_token, app_id: app.id)
refute Map.has_key?(resp, "access_token")
conn =
conn
|> put_session(:oauth_token, token.token)
|> get(
"/oauth/authorize",
%{
"response_type" => "code",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
"scope" => "read"
}
)
assert redirected_to(conn) == "https://redirect.url"
end
end end
test "rejects an invalid authorization code" do describe "POST /oauth/authorize" do
app = insert(:oauth_app) test "redirects with oauth authorization" do
user = insert(:user)
app = insert(:oauth_app, scopes: ["read", "write", "follow"])
conn = conn =
build_conn() build_conn()
|> post("/oauth/token", %{ |> post("/oauth/authorize", %{
"grant_type" => "authorization_code", "authorization" => %{
"code" => "Imobviouslyinvalid", "name" => user.nickname,
"redirect_uri" => app.redirect_uris, "password" => "test",
"client_id" => app.client_id, "client_id" => app.client_id,
"client_secret" => app.client_secret "redirect_uri" => app.redirect_uris,
}) "scope" => "read write",
"state" => "statepassed"
}
})
assert resp = json_response(conn, 400) target = redirected_to(conn)
assert %{"error" => _} = json_response(conn, 400) assert target =~ app.redirect_uris
refute Map.has_key?(resp, "access_token")
query = URI.parse(target).query |> URI.query_decoder() |> Map.new()
assert %{"state" => "statepassed", "code" => code} = query
auth = Repo.get_by(Authorization, token: code)
assert auth
assert auth.scopes == ["read", "write"]
end
test "returns 401 for wrong credentials", %{conn: conn} do
user = insert(:user)
app = insert(:oauth_app)
result =
conn
|> post("/oauth/authorize", %{
"authorization" => %{
"name" => user.nickname,
"password" => "wrong",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
"state" => "statepassed",
"scope" => Enum.join(app.scopes, " ")
}
})
|> html_response(:unauthorized)
# Keep the details
assert result =~ app.client_id
assert result =~ app.redirect_uris
# Error message
assert result =~ "Invalid Username/Password"
end
test "returns 401 for missing scopes", %{conn: conn} do
user = insert(:user)
app = insert(:oauth_app)
result =
conn
|> post("/oauth/authorize", %{
"authorization" => %{
"name" => user.nickname,
"password" => "test",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
"state" => "statepassed",
"scope" => ""
}
})
|> html_response(:unauthorized)
# Keep the details
assert result =~ app.client_id
assert result =~ app.redirect_uris
# Error message
assert result =~ "This action is outside the authorized scopes"
end
test "returns 401 for scopes beyond app scopes", %{conn: conn} do
user = insert(:user)
app = insert(:oauth_app, scopes: ["read", "write"])
result =
conn
|> post("/oauth/authorize", %{
"authorization" => %{
"name" => user.nickname,
"password" => "test",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
"state" => "statepassed",
"scope" => "read write follow"
}
})
|> html_response(:unauthorized)
# Keep the details
assert result =~ app.client_id
assert result =~ app.redirect_uris
# Error message
assert result =~ "This action is outside the authorized scopes"
end
end
describe "POST /oauth/token" do
test "issues a token for an all-body request" do
user = insert(:user)
app = insert(:oauth_app, scopes: ["read", "write"])
{:ok, auth} = Authorization.create_authorization(app, user, ["write"])
conn =
build_conn()
|> post("/oauth/token", %{
"grant_type" => "authorization_code",
"code" => auth.token,
"redirect_uri" => app.redirect_uris,
"client_id" => app.client_id,
"client_secret" => app.client_secret
})
assert %{"access_token" => token, "me" => ap_id} = json_response(conn, 200)
token = Repo.get_by(Token, token: token)
assert token
assert token.scopes == auth.scopes
assert user.ap_id == ap_id
end
test "issues a token for `password` grant_type with valid credentials, with full permissions by default" do
password = "testpassword"
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
app = insert(:oauth_app, scopes: ["read", "write"])
# Note: "scope" param is intentionally omitted
conn =
build_conn()
|> post("/oauth/token", %{
"grant_type" => "password",
"username" => user.nickname,
"password" => password,
"client_id" => app.client_id,
"client_secret" => app.client_secret
})
assert %{"access_token" => token} = json_response(conn, 200)
token = Repo.get_by(Token, token: token)
assert token
assert token.scopes == app.scopes
end
test "issues a token for request with HTTP basic auth client credentials" do
user = insert(:user)
app = insert(:oauth_app, scopes: ["scope1", "scope2", "scope3"])
{:ok, auth} = Authorization.create_authorization(app, user, ["scope1", "scope2"])
assert auth.scopes == ["scope1", "scope2"]
app_encoded =
(URI.encode_www_form(app.client_id) <> ":" <> URI.encode_www_form(app.client_secret))
|> Base.encode64()
conn =
build_conn()
|> put_req_header("authorization", "Basic " <> app_encoded)
|> post("/oauth/token", %{
"grant_type" => "authorization_code",
"code" => auth.token,
"redirect_uri" => app.redirect_uris
})
assert %{"access_token" => token, "scope" => scope} = json_response(conn, 200)
assert scope == "scope1 scope2"
token = Repo.get_by(Token, token: token)
assert token
assert token.scopes == ["scope1", "scope2"]
end
test "rejects token exchange with invalid client credentials" do
user = insert(:user)
app = insert(:oauth_app)
{:ok, auth} = Authorization.create_authorization(app, user)
conn =
build_conn()
|> put_req_header("authorization", "Basic JTIxOiVGMCU5RiVBNCVCNwo=")
|> post("/oauth/token", %{
"grant_type" => "authorization_code",
"code" => auth.token,
"redirect_uri" => app.redirect_uris
})
assert resp = json_response(conn, 400)
assert %{"error" => _} = resp
refute Map.has_key?(resp, "access_token")
end
test "rejects token exchange for valid credentials belonging to unconfirmed user and confirmation is required" do
setting = Pleroma.Config.get([:instance, :account_activation_required])
unless setting do
Pleroma.Config.put([:instance, :account_activation_required], true)
on_exit(fn -> Pleroma.Config.put([:instance, :account_activation_required], setting) end)
end
password = "testpassword"
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
info_change = Pleroma.User.Info.confirmation_changeset(user.info, :unconfirmed)
{:ok, user} =
user
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(:info, info_change)
|> Repo.update()
refute Pleroma.User.auth_active?(user)
app = insert(:oauth_app)
conn =
build_conn()
|> post("/oauth/token", %{
"grant_type" => "password",
"username" => user.nickname,
"password" => password,
"client_id" => app.client_id,
"client_secret" => app.client_secret
})
assert resp = json_response(conn, 403)
assert %{"error" => _} = resp
refute Map.has_key?(resp, "access_token")
end
test "rejects an invalid authorization code" do
app = insert(:oauth_app)
conn =
build_conn()
|> post("/oauth/token", %{
"grant_type" => "authorization_code",
"code" => "Imobviouslyinvalid",
"redirect_uri" => app.redirect_uris,
"client_id" => app.client_id,
"client_secret" => app.client_secret
})
assert resp = json_response(conn, 400)
assert %{"error" => _} = json_response(conn, 400)
refute Map.has_key?(resp, "access_token")
end
end end
end end

View File

@ -116,10 +116,10 @@ test "an announce activity" do
{:ok, announce, _object} = ActivityPub.announce(user, object) {:ok, announce, _object} = ActivityPub.announce(user, object)
announce = Repo.get(Activity, announce.id) announce = Activity.get_by_id(announce.id)
note_user = User.get_cached_by_ap_id(note.data["actor"]) note_user = User.get_cached_by_ap_id(note.data["actor"])
note = Repo.get(Activity, note.id) note = Activity.get_by_id(note.id)
note_xml = note_xml =
ActivityRepresenter.to_simple_form(note, note_user, true) ActivityRepresenter.to_simple_form(note, note_user, true)

View File

@ -6,7 +6,6 @@ defmodule Pleroma.Web.OStatus.DeleteHandlingTest do
alias Pleroma.Activity alias Pleroma.Activity
alias Pleroma.Object alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus
setup do setup do
@ -32,10 +31,10 @@ test "it removes the mentioned activity" do
{:ok, [delete]} = OStatus.handle_incoming(incoming) {:ok, [delete]} = OStatus.handle_incoming(incoming)
refute Repo.get(Activity, note.id) refute Activity.get_by_id(note.id)
refute Repo.get(Activity, like.id) refute Activity.get_by_id(like.id)
assert Object.get_by_ap_id(note.data["object"]["id"]).data["type"] == "Tombstone" assert Object.get_by_ap_id(note.data["object"]["id"]).data["type"] == "Tombstone"
assert Repo.get(Activity, second_note.id) assert Activity.get_by_id(second_note.id)
assert Object.get_by_ap_id(second_note.data["object"]["id"]) assert Object.get_by_ap_id(second_note.data["object"]["id"])
assert delete.data["type"] == "Delete" assert delete.data["type"] == "Delete"

View File

@ -154,7 +154,7 @@ test "handle incoming retweets - GS, subscription" do
assert "https://pleroma.soykaf.com/users/lain" in activity.data["to"] assert "https://pleroma.soykaf.com/users/lain" in activity.data["to"]
refute activity.local refute activity.local
retweeted_activity = Repo.get(Activity, retweeted_activity.id) retweeted_activity = Activity.get_by_id(retweeted_activity.id)
assert retweeted_activity.data["type"] == "Create" assert retweeted_activity.data["type"] == "Create"
assert retweeted_activity.data["actor"] == "https://pleroma.soykaf.com/users/lain" assert retweeted_activity.data["actor"] == "https://pleroma.soykaf.com/users/lain"
refute retweeted_activity.local refute retweeted_activity.local
@ -181,7 +181,7 @@ test "handle incoming retweets - GS, subscription - local message" do
assert user.ap_id in activity.data["to"] assert user.ap_id in activity.data["to"]
refute activity.local refute activity.local
retweeted_activity = Repo.get(Activity, retweeted_activity.id) retweeted_activity = Activity.get_by_id(retweeted_activity.id)
assert note_activity.id == retweeted_activity.id assert note_activity.id == retweeted_activity.id
assert retweeted_activity.data["type"] == "Create" assert retweeted_activity.data["type"] == "Create"
assert retweeted_activity.data["actor"] == user.ap_id assert retweeted_activity.data["actor"] == user.ap_id
@ -344,7 +344,7 @@ test "tries to use the information in poco fields" do
{:ok, user} = OStatus.find_or_make_user(uri) {:ok, user} = OStatus.find_or_make_user(uri)
user = Repo.get(Pleroma.User, user.id) user = Pleroma.User.get_by_id(user.id)
assert user.name == "Constance Variable" assert user.name == "Constance Variable"
assert user.nickname == "lambadalambda@social.heldscal.la" assert user.nickname == "lambadalambda@social.heldscal.la"
assert user.local == false assert user.local == false

View File

@ -719,7 +719,7 @@ test "with credentials", %{conn: conn, user: current_user} do
|> with_credentials(current_user.nickname, "test") |> with_credentials(current_user.nickname, "test")
|> post("/api/friendships/create.json", %{user_id: followed.id}) |> post("/api/friendships/create.json", %{user_id: followed.id})
current_user = Repo.get(User, current_user.id) current_user = User.get_by_id(current_user.id)
assert User.ap_followers(followed) in current_user.following assert User.ap_followers(followed) in current_user.following
assert json_response(conn, 200) == assert json_response(conn, 200) ==
@ -734,8 +734,8 @@ test "for restricted account", %{conn: conn, user: current_user} do
|> with_credentials(current_user.nickname, "test") |> with_credentials(current_user.nickname, "test")
|> post("/api/friendships/create.json", %{user_id: followed.id}) |> post("/api/friendships/create.json", %{user_id: followed.id})
current_user = Repo.get(User, current_user.id) current_user = User.get_by_id(current_user.id)
followed = Repo.get(User, followed.id) followed = User.get_by_id(followed.id)
refute User.ap_followers(followed) in current_user.following refute User.ap_followers(followed) in current_user.following
@ -764,7 +764,7 @@ test "with credentials", %{conn: conn, user: current_user} do
|> with_credentials(current_user.nickname, "test") |> with_credentials(current_user.nickname, "test")
|> post("/api/friendships/destroy.json", %{user_id: followed.id}) |> post("/api/friendships/destroy.json", %{user_id: followed.id})
current_user = Repo.get(User, current_user.id) current_user = User.get_by_id(current_user.id)
assert current_user.following == [current_user.ap_id] assert current_user.following == [current_user.ap_id]
assert json_response(conn, 200) == assert json_response(conn, 200) ==
@ -788,7 +788,7 @@ test "with credentials", %{conn: conn, user: current_user} do
|> with_credentials(current_user.nickname, "test") |> with_credentials(current_user.nickname, "test")
|> post("/api/blocks/create.json", %{user_id: blocked.id}) |> post("/api/blocks/create.json", %{user_id: blocked.id})
current_user = Repo.get(User, current_user.id) current_user = User.get_by_id(current_user.id)
assert User.blocks?(current_user, blocked) assert User.blocks?(current_user, blocked)
assert json_response(conn, 200) == assert json_response(conn, 200) ==
@ -815,7 +815,7 @@ test "with credentials", %{conn: conn, user: current_user} do
|> with_credentials(current_user.nickname, "test") |> with_credentials(current_user.nickname, "test")
|> post("/api/blocks/destroy.json", %{user_id: blocked.id}) |> post("/api/blocks/destroy.json", %{user_id: blocked.id})
current_user = Repo.get(User, current_user.id) current_user = User.get_by_id(current_user.id)
assert current_user.info.blocks == [] assert current_user.info.blocks == []
assert json_response(conn, 200) == assert json_response(conn, 200) ==
@ -846,7 +846,7 @@ test "with credentials", %{conn: conn, user: current_user} do
|> with_credentials(current_user.nickname, "test") |> with_credentials(current_user.nickname, "test")
|> post("/api/qvitter/update_avatar.json", %{img: avatar_image}) |> post("/api/qvitter/update_avatar.json", %{img: avatar_image})
current_user = Repo.get(User, current_user.id) current_user = User.get_by_id(current_user.id)
assert is_map(current_user.avatar) assert is_map(current_user.avatar)
assert json_response(conn, 200) == assert json_response(conn, 200) ==
@ -954,7 +954,7 @@ test "with credentials", %{conn: conn, user: current_user} do
|> with_credentials(current_user.nickname, "test") |> with_credentials(current_user.nickname, "test")
|> post(request_path) |> post(request_path)
activity = Repo.get(Activity, note_activity.id) activity = Activity.get_by_id(note_activity.id)
activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"]) activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
assert json_response(response, 200) == assert json_response(response, 200) ==
@ -992,7 +992,7 @@ test "with credentials", %{conn: conn, user: current_user} do
|> with_credentials(current_user.nickname, "test") |> with_credentials(current_user.nickname, "test")
|> post(request_path) |> post(request_path)
activity = Repo.get(Activity, note_activity.id) activity = Activity.get_by_id(note_activity.id)
activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"]) activity_user = Repo.get_by(User, ap_id: note_activity.data["actor"])
assert json_response(response, 200) == assert json_response(response, 200) ==
@ -1109,7 +1109,7 @@ test "it redirects to root url", %{conn: conn, user: user} do
test "it confirms the user account", %{conn: conn, user: user} do test "it confirms the user account", %{conn: conn, user: user} do
get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}") get(conn, "/api/account/confirm_email/#{user.id}/#{user.info.confirmation_token}")
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
refute user.info.confirmation_pending refute user.info.confirmation_pending
refute user.info.confirmation_token refute user.info.confirmation_token
@ -1727,7 +1727,7 @@ test "with credentials, valid password and matching new password and confirmatio
}) })
assert json_response(conn, 200) == %{"status" => "success"} assert json_response(conn, 200) == %{"status" => "success"}
fetched_user = Repo.get(User, current_user.id) fetched_user = User.get_by_id(current_user.id)
assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true assert Pbkdf2.checkpw("newpass", fetched_user.password_hash) == true
end end
end end
@ -1768,8 +1768,8 @@ test "it lists friend requests" do
{:ok, _activity} = ActivityPub.follow(other_user, user) {:ok, _activity} = ActivityPub.follow(other_user, user)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
other_user = Repo.get(User, other_user.id) other_user = User.get_by_id(other_user.id)
assert User.following?(other_user, user) == false assert User.following?(other_user, user) == false
@ -1808,8 +1808,8 @@ test "it approves a friend request" do
{:ok, _activity} = ActivityPub.follow(other_user, user) {:ok, _activity} = ActivityPub.follow(other_user, user)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
other_user = Repo.get(User, other_user.id) other_user = User.get_by_id(other_user.id)
assert User.following?(other_user, user) == false assert User.following?(other_user, user) == false
@ -1831,8 +1831,8 @@ test "it denies a friend request" do
{:ok, _activity} = ActivityPub.follow(other_user, user) {:ok, _activity} = ActivityPub.follow(other_user, user)
user = Repo.get(User, user.id) user = User.get_by_id(user.id)
other_user = Repo.get(User, other_user.id) other_user = User.get_by_id(other_user.id)
assert User.following?(other_user, user) == false assert User.following?(other_user, user) == false

View File

@ -281,7 +281,7 @@ test "an announce activity" do
convo_id = Utils.context_to_conversation_id(activity.data["object"]["context"]) convo_id = Utils.context_to_conversation_id(activity.data["object"]["context"])
activity = Repo.get(Activity, activity.id) activity = Activity.get_by_id(activity.id)
result = ActivityView.render("activity.json", activity: announce) result = ActivityView.render("activity.json", activity: announce)

View File

@ -292,7 +292,7 @@ test "A blocked user for the blocker" do
} }
} }
blocker = Repo.get(User, blocker.id) blocker = User.get_by_id(blocker.id)
assert represented == UserView.render("show.json", %{user: user, for: blocker}) assert represented == UserView.render("show.json", %{user: user, for: blocker})
end end