Merge branch 'develop' into feature/custom-runtime-modules

This commit is contained in:
Egor Kislitsyn 2019-12-13 01:51:52 +07:00
commit 7528322f83
69 changed files with 1129 additions and 1264 deletions

View file

@ -8,6 +8,7 @@ defmodule Pleroma.CaptchaTest do
import Tesla.Mock
alias Pleroma.Captcha.Kocaptcha
alias Pleroma.Captcha.Native
@ets_options [:ordered_set, :private, :named_table, {:read_concurrency, true}]
@ -43,4 +44,21 @@ defmodule Pleroma.CaptchaTest do
) == :ok
end
end
describe "Native" do
test "new and validate" do
new = Native.new()
assert %{
answer_data: answer,
token: token,
type: :native,
url: "data:image/png;base64," <> _
} = new
assert is_binary(answer)
assert :ok = Native.validate(token, answer, answer)
assert {:error, "Invalid CAPTCHA"} == Native.validate(token, answer, answer <> "foobar")
end
end
end

View file

@ -214,7 +214,7 @@ defmodule Pleroma.ModerationLogTest do
{:ok, _} =
ModerationLog.insert_log(%{
actor: moderator,
action: "report_response",
action: "report_note",
subject: report,
text: "look at this"
})
@ -222,7 +222,7 @@ defmodule Pleroma.ModerationLogTest do
log = Repo.one(ModerationLog)
assert log.data["message"] ==
"@#{moderator.nickname} responded with 'look at this' to report ##{report.id}"
"@#{moderator.nickname} added note 'look at this' to report ##{report.id}"
end
test "logging status sensitivity update", %{moderator: moderator} do

View file

@ -224,4 +224,42 @@ defmodule Pleroma.Plugs.OAuthScopesPlugTest do
assert f.(["admin:read"], ["write", "admin"]) == ["admin:read"]
end
end
describe "transform_scopes/2" do
clear_config([:auth, :enforce_oauth_admin_scope_usage])
setup do
{:ok, %{f: &OAuthScopesPlug.transform_scopes/2}}
end
test "with :admin option, prefixes all requested scopes with `admin:` " <>
"and [optionally] keeps only prefixed scopes, " <>
"depending on `[:auth, :enforce_oauth_admin_scope_usage]` setting",
%{f: f} do
Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false)
assert f.(["read"], %{admin: true}) == ["admin:read", "read"]
assert f.(["read", "write"], %{admin: true}) == [
"admin:read",
"read",
"admin:write",
"write"
]
Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], true)
assert f.(["read:accounts"], %{admin: true}) == ["admin:read:accounts"]
assert f.(["read", "write:reports"], %{admin: true}) == [
"admin:read",
"admin:write:reports"
]
end
test "with no supported options, returns unmodified scopes", %{f: f} do
assert f.(["read"], %{}) == ["read"]
assert f.(["read", "write"], %{}) == ["read", "write"]
end
end
end

View file

@ -8,36 +8,116 @@ defmodule Pleroma.Plugs.UserIsAdminPlugTest do
alias Pleroma.Plugs.UserIsAdminPlug
import Pleroma.Factory
test "accepts a user that is admin" do
user = insert(:user, is_admin: true)
describe "unless [:auth, :enforce_oauth_admin_scope_usage]," do
clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false)
end
conn =
build_conn()
|> assign(:user, user)
test "accepts a user that is an admin" do
user = insert(:user, is_admin: true)
ret_conn =
conn
|> UserIsAdminPlug.call(%{})
conn = assign(build_conn(), :user, user)
assert conn == ret_conn
ret_conn = UserIsAdminPlug.call(conn, %{})
assert conn == ret_conn
end
test "denies a user that isn't an admin" do
user = insert(:user)
conn =
build_conn()
|> assign(:user, user)
|> UserIsAdminPlug.call(%{})
assert conn.status == 403
end
test "denies when a user isn't set" do
conn = UserIsAdminPlug.call(build_conn(), %{})
assert conn.status == 403
end
end
test "denies a user that isn't admin" do
user = insert(:user)
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], true)
end
conn =
build_conn()
|> assign(:user, user)
|> UserIsAdminPlug.call(%{})
setup do
admin_user = insert(:user, is_admin: true)
non_admin_user = insert(:user, is_admin: false)
blank_user = nil
assert conn.status == 403
end
{:ok, %{users: [admin_user, non_admin_user, blank_user]}}
end
test "denies when a user isn't set" do
conn =
build_conn()
|> UserIsAdminPlug.call(%{})
test "if token has any of admin scopes, accepts a user that is an admin", %{conn: conn} do
user = insert(:user, is_admin: true)
token = insert(:oauth_token, user: user, scopes: ["admin:something"])
assert conn.status == 403
conn =
conn
|> assign(:user, user)
|> assign(:token, token)
ret_conn = UserIsAdminPlug.call(conn, %{})
assert conn == ret_conn
end
test "if token has any of admin scopes, denies a user that isn't an admin", %{conn: conn} do
user = insert(:user, is_admin: false)
token = insert(:oauth_token, user: user, scopes: ["admin:something"])
conn =
conn
|> assign(:user, user)
|> assign(:token, token)
|> UserIsAdminPlug.call(%{})
assert conn.status == 403
end
test "if token has any of admin scopes, denies when a user isn't set", %{conn: conn} do
token = insert(:oauth_token, scopes: ["admin:something"])
conn =
conn
|> assign(:user, nil)
|> assign(:token, token)
|> UserIsAdminPlug.call(%{})
assert conn.status == 403
end
test "if token lacks admin scopes, denies users regardless of is_admin flag",
%{users: users} do
for user <- users do
token = insert(:oauth_token, user: user)
conn =
build_conn()
|> assign(:user, user)
|> assign(:token, token)
|> UserIsAdminPlug.call(%{})
assert conn.status == 403
end
end
test "if token is missing, denies users regardless of is_admin flag", %{users: users} do
for user <- users do
conn =
build_conn()
|> assign(:user, user)
|> assign(:token, nil)
|> UserIsAdminPlug.call(%{})
assert conn.status == 403
end
end
end
end

View file

@ -914,6 +914,16 @@ defmodule Pleroma.UserTest do
refute User.blocks?(user, collateral_user)
end
test "follows take precedence over domain blocks" do
user = insert(:user)
good_eggo = insert(:user, %{ap_id: "https://meanies.social/user/cuteposter"})
{:ok, user} = User.block_domain(user, "meanies.social")
{:ok, user} = User.follow(user, good_eggo)
refute User.blocks?(user, good_eggo)
end
end
describe "blocks_import" do

View file

@ -608,6 +608,39 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
refute repeat_activity in activities
end
test "does return activities from followed users on blocked domains" do
domain = "meanies.social"
domain_user = insert(:user, %{ap_id: "https://#{domain}/@pundit"})
blocker = insert(:user)
{:ok, blocker} = User.follow(blocker, domain_user)
{:ok, blocker} = User.block_domain(blocker, domain)
assert User.following?(blocker, domain_user)
assert User.blocks_domain?(blocker, domain_user)
refute User.blocks?(blocker, domain_user)
note = insert(:note, %{data: %{"actor" => domain_user.ap_id}})
activity = insert(:note_activity, %{note: note})
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => blocker, "skip_preload" => true})
assert activity in activities
# And check that if the guy we DO follow boosts someone else from their domain,
# that should be hidden
another_user = insert(:user, %{ap_id: "https://#{domain}/@meanie2"})
bad_note = insert(:note, %{data: %{"actor" => another_user.ap_id}})
bad_activity = insert(:note_activity, %{note: bad_note})
{:ok, repeat_activity, _} = CommonAPI.repeat(bad_activity.id, domain_user)
activities =
ActivityPub.fetch_activities([], %{"blocking_user" => blocker, "skip_preload" => true})
refute repeat_activity in activities
end
test "doesn't return muted activities" do
activity_one = insert(:note_activity)
activity_two = insert(:note_activity)
@ -1592,6 +1625,38 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
end
describe "fetch_favourites/3" do
test "returns a favourite activities sorted by adds to favorite" do
user = insert(:user)
other_user = insert(:user)
user1 = insert(:user)
user2 = insert(:user)
{:ok, a1} = CommonAPI.post(user1, %{"status" => "bla"})
{:ok, _a2} = CommonAPI.post(user2, %{"status" => "traps are happy"})
{:ok, a3} = CommonAPI.post(user2, %{"status" => "Trees Are "})
{:ok, a4} = CommonAPI.post(user2, %{"status" => "Agent Smith "})
{:ok, a5} = CommonAPI.post(user1, %{"status" => "Red or Blue "})
{:ok, _, _} = CommonAPI.favorite(a4.id, user)
{:ok, _, _} = CommonAPI.favorite(a3.id, other_user)
Process.sleep(1000)
{:ok, _, _} = CommonAPI.favorite(a3.id, user)
{:ok, _, _} = CommonAPI.favorite(a5.id, other_user)
Process.sleep(1000)
{:ok, _, _} = CommonAPI.favorite(a5.id, user)
{:ok, _, _} = CommonAPI.favorite(a4.id, other_user)
Process.sleep(1000)
{:ok, _, _} = CommonAPI.favorite(a1.id, user)
{:ok, _, _} = CommonAPI.favorite(a1.id, other_user)
result = ActivityPub.fetch_favourites(user)
assert Enum.map(result, & &1.id) == [a1.id, a5.id, a3.id, a4.id]
result = ActivityPub.fetch_favourites(user, %{"limit" => 2})
assert Enum.map(result, & &1.id) == [a1.id, a5.id]
end
end
describe "Move activity" do
test "create" do
%{ap_id: old_ap_id} = old_user = insert(:user)

View file

@ -10,6 +10,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
alias Pleroma.HTML
alias Pleroma.ModerationLog
alias Pleroma.Repo
alias Pleroma.ReportNote
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.UserInviteToken
@ -25,6 +26,60 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
:ok
end
clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], false)
end
describe "with [:auth, :enforce_oauth_admin_scope_usage]," do
clear_config([:auth, :enforce_oauth_admin_scope_usage]) do
Pleroma.Config.put([:auth, :enforce_oauth_admin_scope_usage], true)
end
test "GET /api/pleroma/admin/users/:nickname requires admin:read:accounts or broader scope" do
user = insert(:user)
admin = insert(:user, is_admin: true)
url = "/api/pleroma/admin/users/#{user.nickname}"
good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
bad_token3 = nil
for good_token <- [good_token1, good_token2, good_token3] do
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, good_token)
|> get(url)
assert json_response(conn, 200)
end
for good_token <- [good_token1, good_token2, good_token3] do
conn =
build_conn()
|> assign(:user, nil)
|> assign(:token, good_token)
|> get(url)
assert json_response(conn, :forbidden)
end
for bad_token <- [bad_token1, bad_token2, bad_token3] do
conn =
build_conn()
|> assign(:user, admin)
|> assign(:token, bad_token)
|> get(url)
assert json_response(conn, :forbidden)
end
end
end
describe "DELETE /api/pleroma/admin/users" do
test "single user" do
admin = insert(:user, is_admin: true)
@ -98,7 +153,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == []
end
test "Cannot create user with exisiting email" do
test "Cannot create user with existing email" do
admin = insert(:user, is_admin: true)
user = insert(:user)
@ -129,7 +184,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
]
end
test "Cannot create user with exisiting nickname" do
test "Cannot create user with existing nickname" do
admin = insert(:user, is_admin: true)
user = insert(:user)
@ -1560,7 +1615,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|> assign(:user, user)
|> get("/api/pleroma/admin/reports")
assert json_response(conn, :forbidden) == %{"error" => "User is not admin."}
assert json_response(conn, :forbidden) ==
%{"error" => "User is not an admin or OAuth admin scope is not granted."}
end
test "returns 403 when requested by anonymous" do
@ -1776,61 +1832,6 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
end
describe "POST /api/pleroma/admin/reports/:id/respond" do
setup %{conn: conn} do
admin = insert(:user, is_admin: true)
%{conn: assign(conn, :user, admin), admin: admin}
end
test "returns created dm", %{conn: conn, admin: admin} do
[reporter, target_user] = insert_pair(:user)
activity = insert(:note_activity, user: target_user)
{:ok, %{id: report_id}} =
CommonAPI.report(reporter, %{
"account_id" => target_user.id,
"comment" => "I feel offended",
"status_ids" => [activity.id]
})
response =
conn
|> post("/api/pleroma/admin/reports/#{report_id}/respond", %{
"status" => "I will check it out"
})
|> json_response(:ok)
recipients = Enum.map(response["mentions"], & &1["username"])
assert reporter.nickname in recipients
assert response["content"] == "I will check it out"
assert response["visibility"] == "direct"
log_entry = Repo.one(ModerationLog)
assert ModerationLog.get_log_entry_message(log_entry) ==
"@#{admin.nickname} responded with 'I will check it out' to report ##{
response["id"]
}"
end
test "returns 400 when status is missing", %{conn: conn} do
conn = post(conn, "/api/pleroma/admin/reports/test/respond")
assert json_response(conn, :bad_request) == "Invalid parameters"
end
test "returns 404 when report id is invalid", %{conn: conn} do
conn =
post(conn, "/api/pleroma/admin/reports/test/respond", %{
"status" => "foo"
})
assert json_response(conn, :not_found) == "Not found"
end
end
describe "PUT /api/pleroma/admin/statuses/:id" do
setup %{conn: conn} do
admin = insert(:user, is_admin: true)
@ -3027,6 +3028,77 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
}"
end
end
describe "POST /reports/:id/notes" do
setup do
admin = insert(:user, is_admin: true)
[reporter, target_user] = insert_pair(:user)
activity = insert(:note_activity, user: target_user)
{:ok, %{id: report_id}} =
CommonAPI.report(reporter, %{
"account_id" => target_user.id,
"comment" => "I feel offended",
"status_ids" => [activity.id]
})
build_conn()
|> assign(:user, admin)
|> post("/api/pleroma/admin/reports/#{report_id}/notes", %{
content: "this is disgusting!"
})
build_conn()
|> assign(:user, admin)
|> post("/api/pleroma/admin/reports/#{report_id}/notes", %{
content: "this is disgusting2!"
})
%{
admin_id: admin.id,
report_id: report_id,
admin: admin
}
end
test "it creates report note", %{admin_id: admin_id, report_id: report_id} do
[note, _] = Repo.all(ReportNote)
assert %{
activity_id: ^report_id,
content: "this is disgusting!",
user_id: ^admin_id
} = note
end
test "it returns reports with notes", %{admin: admin} do
conn =
build_conn()
|> assign(:user, admin)
|> get("/api/pleroma/admin/reports")
response = json_response(conn, 200)
notes = hd(response["reports"])["notes"]
[note, _] = notes
assert note["user"]["nickname"] == admin.nickname
assert note["content"] == "this is disgusting!"
assert note["created_at"]
assert response["total"] == 1
end
test "it deletes the note", %{admin: admin, report_id: report_id} do
assert ReportNote |> Repo.all() |> length() == 2
[note, _] = Repo.all(ReportNote)
build_conn()
|> assign(:user, admin)
|> delete("/api/pleroma/admin/reports/#{report_id}/notes/#{note.id}")
assert ReportNote |> Repo.all() |> length() == 1
end
end
end
# Needed for testing

View file

@ -30,6 +30,7 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
Pleroma.Web.AdminAPI.AccountView.render("show.json", %{user: other_user})
),
statuses: [],
notes: [],
state: "open",
id: activity.id
}
@ -65,6 +66,7 @@ defmodule Pleroma.Web.AdminAPI.ReportViewTest do
),
statuses: [StatusView.render("show.json", %{activity: activity})],
state: "open",
notes: [],
id: report_activity.id
}

View file

@ -567,33 +567,41 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
end
describe "POST /oauth/authorize" do
test "redirects with oauth authorization" do
user = insert(:user)
app = insert(:oauth_app, scopes: ["read", "write", "follow"])
test "redirects with oauth authorization, " <>
"keeping only non-admin scopes for non-admin user" do
app = insert(:oauth_app, scopes: ["read", "write", "admin"])
redirect_uri = OAuthController.default_redirect_uri(app)
conn =
build_conn()
|> post("/oauth/authorize", %{
"authorization" => %{
"name" => user.nickname,
"password" => "test",
"client_id" => app.client_id,
"redirect_uri" => redirect_uri,
"scope" => "read:subscope write",
"state" => "statepassed"
}
})
non_admin = insert(:user, is_admin: false)
admin = insert(:user, is_admin: true)
target = redirected_to(conn)
assert target =~ redirect_uri
for {user, expected_scopes} <- %{
non_admin => ["read:subscope", "write"],
admin => ["read:subscope", "write", "admin"]
} do
conn =
build_conn()
|> post("/oauth/authorize", %{
"authorization" => %{
"name" => user.nickname,
"password" => "test",
"client_id" => app.client_id,
"redirect_uri" => redirect_uri,
"scope" => "read:subscope write admin",
"state" => "statepassed"
}
})
query = URI.parse(target).query |> URI.query_decoder() |> Map.new()
target = redirected_to(conn)
assert target =~ redirect_uri
assert %{"state" => "statepassed", "code" => code} = query
auth = Repo.get_by(Authorization, token: code)
assert auth
assert auth.scopes == ["read:subscope", "write"]
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 == expected_scopes
end
end
test "returns 401 for wrong credentials", %{conn: conn} do
@ -623,31 +631,34 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
assert result =~ "Invalid Username/Password"
end
test "returns 401 for missing scopes", %{conn: conn} do
user = insert(:user)
app = insert(:oauth_app)
test "returns 401 for missing scopes " <>
"(including all admin-only scopes for non-admin user)" do
user = insert(:user, is_admin: false)
app = insert(:oauth_app, scopes: ["read", "write", "admin"])
redirect_uri = OAuthController.default_redirect_uri(app)
result =
conn
|> post("/oauth/authorize", %{
"authorization" => %{
"name" => user.nickname,
"password" => "test",
"client_id" => app.client_id,
"redirect_uri" => redirect_uri,
"state" => "statepassed",
"scope" => ""
}
})
|> html_response(:unauthorized)
for scope_param <- ["", "admin:read admin:write"] do
result =
build_conn()
|> post("/oauth/authorize", %{
"authorization" => %{
"name" => user.nickname,
"password" => "test",
"client_id" => app.client_id,
"redirect_uri" => redirect_uri,
"state" => "statepassed",
"scope" => scope_param
}
})
|> html_response(:unauthorized)
# Keep the details
assert result =~ app.client_id
assert result =~ redirect_uri
# Keep the details
assert result =~ app.client_id
assert result =~ redirect_uri
# Error message
assert result =~ "This action is outside the authorized scopes"
# Error message
assert result =~ "This action is outside the authorized scopes"
end
end
test "returns 401 for scopes beyond app scopes hierarchy", %{conn: conn} do