aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/integration/mastodon_websocket_test.exs2
-rw-r--r--test/plugs/oauth_scopes_plug_test.exs122
-rw-r--r--test/support/factory.ex2
-rw-r--r--test/user_test.exs23
-rw-r--r--test/web/activity_pub/activity_pub_controller_test.exs83
-rw-r--r--test/web/activity_pub/activity_pub_test.exs75
-rw-r--r--test/web/admin_api/admin_api_controller_test.exs48
-rw-r--r--test/web/common_api/common_api_test.exs31
-rw-r--r--test/web/mastodon_api/mastodon_api_controller_test.exs139
-rw-r--r--test/web/mastodon_api/status_view_test.exs2
-rw-r--r--test/web/oauth/authorization_test.exs46
-rw-r--r--test/web/oauth/oauth_controller_test.exs95
-rw-r--r--test/web/oauth/token_test.exs12
-rw-r--r--test/web/twitter_api/twitter_api_controller_test.exs34
-rw-r--r--test/web/twitter_api/util_controller_test.exs19
-rw-r--r--test/web/views/error_view_test.exs9
16 files changed, 670 insertions, 72 deletions
diff --git a/test/integration/mastodon_websocket_test.exs b/test/integration/mastodon_websocket_test.exs
index 2e385f5ad..0c513b6e7 100644
--- a/test/integration/mastodon_websocket_test.exs
+++ b/test/integration/mastodon_websocket_test.exs
@@ -80,7 +80,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
Pleroma.Repo.insert(
OAuth.App.register_changeset(%OAuth.App{}, %{
client_name: "client",
- scopes: "scope",
+ scopes: ["scope"],
redirect_uris: "url"
})
)
diff --git a/test/plugs/oauth_scopes_plug_test.exs b/test/plugs/oauth_scopes_plug_test.exs
new file mode 100644
index 000000000..f328026df
--- /dev/null
+++ b/test/plugs/oauth_scopes_plug_test.exs
@@ -0,0 +1,122 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Plugs.OAuthScopesPlugTest do
+ use Pleroma.Web.ConnCase, async: true
+
+ alias Pleroma.Plugs.OAuthScopesPlug
+ alias Pleroma.Repo
+
+ import Pleroma.Factory
+
+ test "proceeds with no op if `assigns[:token]` is nil", %{conn: conn} do
+ conn =
+ conn
+ |> assign(:user, insert(:user))
+ |> OAuthScopesPlug.call(%{scopes: ["read"]})
+
+ refute conn.halted
+ assert conn.assigns[:user]
+ end
+
+ test "proceeds with no op if `token.scopes` fulfill specified 'any of' conditions", %{
+ conn: conn
+ } do
+ token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
+
+ conn =
+ conn
+ |> assign(:user, token.user)
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: ["read"]})
+
+ refute conn.halted
+ assert conn.assigns[:user]
+ end
+
+ test "proceeds with no op if `token.scopes` fulfill specified 'all of' conditions", %{
+ conn: conn
+ } do
+ token = insert(:oauth_token, scopes: ["scope1", "scope2", "scope3"]) |> Repo.preload(:user)
+
+ conn =
+ conn
+ |> assign(:user, token.user)
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: ["scope2", "scope3"], op: :&})
+
+ refute conn.halted
+ assert conn.assigns[:user]
+ end
+
+ test "proceeds with cleared `assigns[:user]` if `token.scopes` doesn't fulfill specified 'any of' conditions " <>
+ "and `fallback: :proceed_unauthenticated` option is specified",
+ %{conn: conn} do
+ token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
+
+ conn =
+ conn
+ |> assign(:user, token.user)
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: ["follow"], fallback: :proceed_unauthenticated})
+
+ refute conn.halted
+ refute conn.assigns[:user]
+ end
+
+ test "proceeds with cleared `assigns[:user]` if `token.scopes` doesn't fulfill specified 'all of' conditions " <>
+ "and `fallback: :proceed_unauthenticated` option is specified",
+ %{conn: conn} do
+ token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)
+
+ conn =
+ conn
+ |> assign(:user, token.user)
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{
+ scopes: ["read", "follow"],
+ op: :&,
+ fallback: :proceed_unauthenticated
+ })
+
+ refute conn.halted
+ refute conn.assigns[:user]
+ end
+
+ test "returns 403 and halts in case of no :fallback option and `token.scopes` not fulfilling specified 'any of' conditions",
+ %{conn: conn} do
+ token = insert(:oauth_token, scopes: ["read", "write"])
+ any_of_scopes = ["follow"]
+
+ conn =
+ conn
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: any_of_scopes})
+
+ assert conn.halted
+ assert 403 == conn.status
+
+ expected_error = "Insufficient permissions: #{Enum.join(any_of_scopes, ", ")}."
+ assert Jason.encode!(%{error: expected_error}) == conn.resp_body
+ end
+
+ test "returns 403 and halts in case of no :fallback option and `token.scopes` not fulfilling specified 'all of' conditions",
+ %{conn: conn} do
+ token = insert(:oauth_token, scopes: ["read", "write"])
+ all_of_scopes = ["write", "follow"]
+
+ conn =
+ conn
+ |> assign(:token, token)
+ |> OAuthScopesPlug.call(%{scopes: all_of_scopes, op: :&})
+
+ assert conn.halted
+ assert 403 == conn.status
+
+ expected_error =
+ "Insufficient permissions: #{Enum.join(all_of_scopes -- token.scopes, ", ")}."
+
+ assert Jason.encode!(%{error: expected_error}) == conn.resp_body
+ end
+end
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 7a91549f5..d1956d1cd 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -214,7 +214,7 @@ defmodule Pleroma.Factory do
%Pleroma.Web.OAuth.App{
client_name: "Some client",
redirect_uris: "https://example.com/callback",
- scopes: "read",
+ scopes: ["read", "write", "follow", "push"],
website: "https://example.com",
client_id: "aaabbb==",
client_secret: "aaa;/&bbb"
diff --git a/test/user_test.exs b/test/user_test.exs
index 92991d063..0b1c39ecf 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -594,6 +594,29 @@ defmodule Pleroma.UserTest do
end
end
+ describe "mutes" do
+ test "it mutes people" do
+ user = insert(:user)
+ muted_user = insert(:user)
+
+ refute User.mutes?(user, muted_user)
+
+ {:ok, user} = User.mute(user, muted_user)
+
+ assert User.mutes?(user, muted_user)
+ end
+
+ test "it unmutes users" do
+ user = insert(:user)
+ muted_user = insert(:user)
+
+ {:ok, user} = User.mute(user, muted_user)
+ {:ok, user} = User.unmute(user, muted_user)
+
+ refute User.mutes?(user, muted_user)
+ end
+ end
+
describe "blocks" do
test "it blocks people" do
user = insert(:user)
diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs
index 398bedf77..6bd4493f5 100644
--- a/test/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/web/activity_pub/activity_pub_controller_test.exs
@@ -41,7 +41,24 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
end
describe "/users/:nickname" do
- test "it returns a json representation of the user", %{conn: conn} do
+ test "it returns a json representation of the user with accept application/json", %{
+ conn: conn
+ } do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> put_req_header("accept", "application/json")
+ |> get("/users/#{user.nickname}")
+
+ user = Repo.get(User, user.id)
+
+ assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
+ end
+
+ test "it returns a json representation of the user with accept application/activity+json", %{
+ conn: conn
+ } do
user = insert(:user)
conn =
@@ -53,10 +70,43 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
end
+
+ test "it returns a json representation of the user with accept application/ld+json", %{
+ conn: conn
+ } do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> put_req_header(
+ "accept",
+ "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
+ )
+ |> get("/users/#{user.nickname}")
+
+ user = Repo.get(User, user.id)
+
+ assert json_response(conn, 200) == UserView.render("user.json", %{user: user})
+ end
end
describe "/object/:uuid" do
- test "it returns a json representation of the object", %{conn: conn} do
+ test "it returns a json representation of the object with accept application/json", %{
+ conn: conn
+ } do
+ note = insert(:note)
+ uuid = String.split(note.data["id"], "/") |> List.last()
+
+ conn =
+ conn
+ |> put_req_header("accept", "application/json")
+ |> get("/objects/#{uuid}")
+
+ assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
+ end
+
+ test "it returns a json representation of the object with accept application/activity+json",
+ %{conn: conn} do
note = insert(:note)
uuid = String.split(note.data["id"], "/") |> List.last()
@@ -68,6 +118,23 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
end
+ test "it returns a json representation of the object with accept application/ld+json", %{
+ conn: conn
+ } do
+ note = insert(:note)
+ uuid = String.split(note.data["id"], "/") |> List.last()
+
+ conn =
+ conn
+ |> put_req_header(
+ "accept",
+ "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
+ )
+ |> get("/objects/#{uuid}")
+
+ assert json_response(conn, 200) == ObjectView.render("object.json", %{object: note})
+ end
+
test "it returns 404 for non-public messages", %{conn: conn} do
note = insert(:direct_note)
uuid = String.split(note.data["id"], "/") |> List.last()
@@ -237,6 +304,18 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
end
describe "/users/:nickname/outbox" do
+ test "it will not bomb when there is no activity", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> put_req_header("accept", "application/activity+json")
+ |> get("/users/#{user.nickname}/outbox")
+
+ result = json_response(conn, 200)
+ assert user.ap_id <> "/outbox" == result["id"]
+ end
+
test "it returns a note activity in a collection", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index a6f8b822a..11262c523 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -1,5 +1,5 @@
# Pleroma: A lightweight social networking server
-# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
@@ -277,6 +277,48 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert Enum.member?(activities, activity_one)
end
+ test "doesn't return muted activities" do
+ activity_one = insert(:note_activity)
+ activity_two = insert(:note_activity)
+ activity_three = insert(:note_activity)
+ user = insert(:user)
+ booster = insert(:user)
+ {:ok, user} = User.mute(user, %User{ap_id: activity_one.data["actor"]})
+
+ activities = ActivityPub.fetch_activities([], %{"muting_user" => user})
+
+ assert Enum.member?(activities, activity_two)
+ assert Enum.member?(activities, activity_three)
+ refute Enum.member?(activities, activity_one)
+
+ {:ok, user} = User.unmute(user, %User{ap_id: activity_one.data["actor"]})
+
+ activities = ActivityPub.fetch_activities([], %{"muting_user" => user})
+
+ assert Enum.member?(activities, activity_two)
+ assert Enum.member?(activities, activity_three)
+ assert Enum.member?(activities, activity_one)
+
+ {:ok, user} = User.mute(user, %User{ap_id: activity_three.data["actor"]})
+ {:ok, _announce, %{data: %{"id" => id}}} = CommonAPI.repeat(activity_three.id, booster)
+ %Activity{} = boost_activity = Activity.get_create_by_object_ap_id(id)
+ activity_three = Repo.get(Activity, activity_three.id)
+
+ activities = ActivityPub.fetch_activities([], %{"muting_user" => user})
+
+ assert Enum.member?(activities, activity_two)
+ refute Enum.member?(activities, activity_three)
+ refute Enum.member?(activities, boost_activity)
+ assert Enum.member?(activities, activity_one)
+
+ activities = ActivityPub.fetch_activities([], %{"muting_user" => nil})
+
+ assert Enum.member?(activities, activity_two)
+ assert Enum.member?(activities, activity_three)
+ assert Enum.member?(activities, boost_activity)
+ assert Enum.member?(activities, activity_one)
+ end
+
test "excludes reblogs on request" do
user = insert(:user)
{:ok, expected_activity} = ActivityBuilder.insert(%{"type" => "Create"}, %{:user => user})
@@ -700,6 +742,37 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
assert 3 = length(activities)
end
+ test "it can create a Flag activity" do
+ reporter = insert(:user)
+ target_account = insert(:user)
+ {:ok, activity} = CommonAPI.post(target_account, %{"status" => "foobar"})
+ context = Utils.generate_context_id()
+ content = "foobar"
+
+ reporter_ap_id = reporter.ap_id
+ target_ap_id = target_account.ap_id
+ activity_ap_id = activity.data["id"]
+
+ assert {:ok, activity} =
+ ActivityPub.flag(%{
+ actor: reporter,
+ context: context,
+ account: target_account,
+ statuses: [activity],
+ content: content
+ })
+
+ assert %Activity{
+ actor: ^reporter_ap_id,
+ data: %{
+ "type" => "Flag",
+ "content" => ^content,
+ "context" => ^context,
+ "object" => [^target_ap_id, ^activity_ap_id]
+ }
+ } = activity
+ end
+
describe "publish_one/1" do
test_with_mock "calls `Instances.set_reachable` on successful federation if `unreachable_since` is not specified",
Instances,
diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs
index a27c26f95..9fbaaba39 100644
--- a/test/web/admin_api/admin_api_controller_test.exs
+++ b/test/web/admin_api/admin_api_controller_test.exs
@@ -159,6 +159,54 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
end
+ describe "PUT /api/pleroma/admin/activation_status" do
+ setup %{conn: conn} do
+ admin = insert(:user, info: %{is_admin: true})
+
+ conn =
+ conn
+ |> assign(:user, admin)
+ |> put_req_header("accept", "application/json")
+
+ %{conn: conn}
+ end
+
+ test "deactivates the user", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> put("/api/pleroma/admin/activation_status/#{user.nickname}", %{status: false})
+
+ user = Repo.get(User, user.id)
+ assert user.info.deactivated == true
+ assert json_response(conn, :no_content)
+ end
+
+ test "activates the user", %{conn: conn} do
+ user = insert(:user, info: %{deactivated: true})
+
+ conn =
+ conn
+ |> put("/api/pleroma/admin/activation_status/#{user.nickname}", %{status: true})
+
+ user = Repo.get(User, user.id)
+ assert user.info.deactivated == false
+ assert json_response(conn, :no_content)
+ end
+
+ test "returns 403 when requested by a non-admin", %{conn: conn} do
+ user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> put("/api/pleroma/admin/activation_status/#{user.nickname}", %{status: false})
+
+ assert json_response(conn, :forbidden)
+ end
+ end
+
describe "POST /api/pleroma/admin/email_invite, with valid config" do
setup do
registrations_open = Pleroma.Config.get([:instance, :registrations_open])
diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs
index 870648fb5..9ba320f59 100644
--- a/test/web/common_api/common_api_test.exs
+++ b/test/web/common_api/common_api_test.exs
@@ -190,4 +190,35 @@ defmodule Pleroma.Web.CommonAPITest do
{:error, _} = CommonAPI.add_mute(user, activity)
end
end
+
+ describe "reports" do
+ test "creates a report" do
+ reporter = insert(:user)
+ target_user = insert(:user)
+
+ {:ok, activity} = CommonAPI.post(target_user, %{"status" => "foobar"})
+
+ reporter_ap_id = reporter.ap_id
+ target_ap_id = target_user.ap_id
+ activity_ap_id = activity.data["id"]
+ comment = "foobar"
+
+ report_data = %{
+ "account_id" => target_user.id,
+ "comment" => comment,
+ "status_ids" => [activity.id]
+ }
+
+ assert {:ok, flag_activity} = CommonAPI.report(reporter, report_data)
+
+ assert %Activity{
+ actor: ^reporter_ap_id,
+ data: %{
+ "type" => "Flag",
+ "content" => ^comment,
+ "object" => [^target_ap_id, ^activity_ap_id]
+ }
+ } = flag_activity
+ end
+ end
end
diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs
index e43bc4508..3dfbc8669 100644
--- a/test/web/mastodon_api/mastodon_api_controller_test.exs
+++ b/test/web/mastodon_api/mastodon_api_controller_test.exs
@@ -1206,6 +1206,42 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert id == to_string(other_user.id)
end
+ test "muting / unmuting a user", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> post("/api/v1/accounts/#{other_user.id}/mute")
+
+ assert %{"id" => _id, "muting" => true} = json_response(conn, 200)
+
+ user = Repo.get(User, user.id)
+
+ conn =
+ build_conn()
+ |> assign(:user, user)
+ |> post("/api/v1/accounts/#{other_user.id}/unmute")
+
+ assert %{"id" => _id, "muting" => false} = json_response(conn, 200)
+ end
+
+ test "getting a list of mutes", %{conn: conn} do
+ user = insert(:user)
+ other_user = insert(:user)
+
+ {:ok, user} = User.mute(user, other_user)
+
+ conn =
+ conn
+ |> assign(:user, user)
+ |> get("/api/v1/mutes")
+
+ other_user_id = to_string(other_user.id)
+ assert [%{"id" => ^other_user_id}] = json_response(conn, 200)
+ end
+
test "blocking / unblocking a user", %{conn: conn} do
user = insert(:user)
other_user = insert(:user)
@@ -1282,26 +1318,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert "even.worse.site" in domain_blocks
end
- test "unimplemented mute endpoints" do
+ test "unimplemented follow_requests, blocks, domain blocks" do
user = insert(:user)
- other_user = insert(:user)
- ["mute", "unmute"]
- |> Enum.each(fn endpoint ->
- conn =
- build_conn()
- |> assign(:user, user)
- |> post("/api/v1/accounts/#{other_user.id}/#{endpoint}")
-
- assert %{"id" => id} = json_response(conn, 200)
- assert id == to_string(other_user.id)
- end)
- end
-
- test "unimplemented mutes, follow_requests, blocks, domain blocks" do
- user = insert(:user)
-
- ["blocks", "domain_blocks", "mutes", "follow_requests"]
+ ["blocks", "domain_blocks", "follow_requests"]
|> Enum.each(fn endpoint ->
conn =
build_conn()
@@ -1536,6 +1556,24 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert user_response = json_response(conn, 200)
assert user_response["header"] != User.banner_url(user)
end
+
+ test "requires 'write' permission", %{conn: conn} do
+ token1 = insert(:oauth_token, scopes: ["read"])
+ token2 = insert(:oauth_token, scopes: ["write", "follow"])
+
+ for token <- [token1, token2] do
+ conn =
+ conn
+ |> put_req_header("authorization", "Bearer #{token.token}")
+ |> patch("/api/v1/accounts/update_credentials", %{})
+
+ if token == token1 do
+ assert %{"error" => "Insufficient permissions: write."} == json_response(conn, 403)
+ else
+ assert json_response(conn, 200)
+ end
+ end
+ end
end
test "get instance information", %{conn: conn} do
@@ -1817,4 +1855,69 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert json_response(set_flavour, 200) == json_response(get_new_flavour, 200)
end
+
+ describe "reports" do
+ setup do
+ reporter = insert(:user)
+ target_user = insert(:user)
+
+ {:ok, activity} = CommonAPI.post(target_user, %{"status" => "foobar"})
+
+ [reporter: reporter, target_user: target_user, activity: activity]
+ end
+
+ test "submit a basic report", %{conn: conn, reporter: reporter, target_user: target_user} do
+ assert %{"action_taken" => false, "id" => _} =
+ conn
+ |> assign(:user, reporter)
+ |> post("/api/v1/reports", %{"account_id" => target_user.id})
+ |> json_response(200)
+ end
+
+ test "submit a report with statuses and comment", %{
+ conn: conn,
+ reporter: reporter,
+ target_user: target_user,
+ activity: activity
+ } do
+ assert %{"action_taken" => false, "id" => _} =
+ conn
+ |> assign(:user, reporter)
+ |> post("/api/v1/reports", %{
+ "account_id" => target_user.id,
+ "status_ids" => [activity.id],
+ "comment" => "bad status!"
+ })
+ |> json_response(200)
+ end
+
+ test "accound_id is required", %{
+ conn: conn,
+ reporter: reporter,
+ activity: activity
+ } do
+ assert %{"error" => "Valid `account_id` required"} =
+ conn
+ |> assign(:user, reporter)
+ |> post("/api/v1/reports", %{"status_ids" => [activity.id]})
+ |> json_response(400)
+ end
+
+ test "comment must be up to the size specified in the config", %{
+ conn: conn,
+ reporter: reporter,
+ target_user: target_user
+ } do
+ max_size = Pleroma.Config.get([:instance, :max_report_comment_size], 1000)
+ comment = String.pad_trailing("a", max_size + 1, "a")
+
+ error = %{"error" => "Comment must be up to #{max_size} characters"}
+
+ assert ^error =
+ conn
+ |> assign(:user, reporter)
+ |> post("/api/v1/reports", %{"account_id" => target_user.id, "comment" => comment})
+ |> json_response(400)
+ end
+ end
end
diff --git a/test/web/mastodon_api/status_view_test.exs b/test/web/mastodon_api/status_view_test.exs
index 0dc9c538c..3412a6be2 100644
--- a/test/web/mastodon_api/status_view_test.exs
+++ b/test/web/mastodon_api/status_view_test.exs
@@ -81,7 +81,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
expected = %{
id: to_string(note.id),
uri: note.data["object"]["id"],
- url: note.data["object"]["id"],
+ url: Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, note),
account: AccountView.render("account.json", %{user: user}),
in_reply_to_id: nil,
in_reply_to_account_id: nil,
diff --git a/test/web/oauth/authorization_test.exs b/test/web/oauth/authorization_test.exs
index 81618e935..306db2e62 100644
--- a/test/web/oauth/authorization_test.exs
+++ b/test/web/oauth/authorization_test.exs
@@ -8,36 +8,37 @@ defmodule Pleroma.Web.OAuth.AuthorizationTest do
alias Pleroma.Web.OAuth.App
import Pleroma.Factory
- test "create an authorization token for a valid app" do
+ setup do
{:ok, app} =
Repo.insert(
App.register_changeset(%App{}, %{
client_name: "client",
- scopes: "scope",
+ scopes: ["read", "write"],
redirect_uris: "url"
})
)
+ %{app: app}
+ end
+
+ test "create an authorization token for a valid app", %{app: app} do
user = insert(:user)
- {:ok, auth} = Authorization.create_authorization(app, user)
+ {:ok, auth1} = Authorization.create_authorization(app, user)
+ assert auth1.scopes == app.scopes
- assert auth.user_id == user.id
- assert auth.app_id == app.id
- assert String.length(auth.token) > 10
- assert auth.used == false
- end
+ {:ok, auth2} = Authorization.create_authorization(app, user, ["read"])
+ assert auth2.scopes == ["read"]
- test "use up a token" do
- {:ok, app} =
- Repo.insert(
- App.register_changeset(%App{}, %{
- client_name: "client",
- scopes: "scope",
- redirect_uris: "url"
- })
- )
+ for auth <- [auth1, auth2] do
+ assert auth.user_id == user.id
+ assert auth.app_id == app.id
+ assert String.length(auth.token) > 10
+ assert auth.used == false
+ end
+ end
+ test "use up a token", %{app: app} do
user = insert(:user)
{:ok, auth} = Authorization.create_authorization(app, user)
@@ -61,16 +62,7 @@ defmodule Pleroma.Web.OAuth.AuthorizationTest do
assert {:error, "token expired"} == Authorization.use_token(expired_auth)
end
- test "delete authorizations" do
- {:ok, app} =
- Repo.insert(
- App.register_changeset(%App{}, %{
- client_name: "client",
- scopes: "scope",
- redirect_uris: "url"
- })
- )
-
+ test "delete authorizations", %{app: app} do
user = insert(:user)
{:ok, auth} = Authorization.create_authorization(app, user)
diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs
index 2315f9a34..53d83e6e8 100644
--- a/test/web/oauth/oauth_controller_test.exs
+++ b/test/web/oauth/oauth_controller_test.exs
@@ -12,7 +12,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
test "redirects with oauth authorization" do
user = insert(:user)
- app = insert(:oauth_app)
+ app = insert(:oauth_app, scopes: ["read", "write", "follow"])
conn =
build_conn()
@@ -22,6 +22,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
"password" => "test",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
+ "scope" => "read write",
"state" => "statepassed"
}
})
@@ -32,10 +33,12 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
query = URI.parse(target).query |> URI.query_decoder() |> Map.new()
assert %{"state" => "statepassed", "code" => code} = query
- assert Repo.get_by(Authorization, token: code)
+ auth = Repo.get_by(Authorization, token: code)
+ assert auth
+ assert auth.scopes == ["read", "write"]
end
- test "correctly handles wrong credentials", %{conn: conn} do
+ test "returns 401 for wrong credentials", %{conn: conn} do
user = insert(:user)
app = insert(:oauth_app)
@@ -47,7 +50,8 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
"password" => "wrong",
"client_id" => app.client_id,
"redirect_uri" => app.redirect_uris,
- "state" => "statepassed"
+ "state" => "statepassed",
+ "scope" => Enum.join(app.scopes, " ")
}
})
|> html_response(:unauthorized)
@@ -57,14 +61,66 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
assert result =~ app.redirect_uris
# Error message
- assert result =~ "Invalid"
+ assert result =~ "Invalid Username/Password"
end
- test "issues a token for an all-body request" do
+ test "returns 401 for missing scopes", %{conn: conn} do
user = insert(:user)
app = insert(:oauth_app)
- {:ok, auth} = Authorization.create_authorization(app, user)
+ 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 =~ "Permissions not specified"
+ 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 =~ "Permissions not specified"
+ 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()
@@ -77,15 +133,19 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
})
assert %{"access_token" => token} = json_response(conn, 200)
- assert Repo.get_by(Token, token: token)
+
+ token = Repo.get_by(Token, token: token)
+ assert token
+ assert token.scopes == auth.scopes
end
- test "issues a token for `password` grant_type with valid credentials" do
+ 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)
+ app = insert(:oauth_app, scopes: ["read", "write"])
+ # Note: "scope" param is intentionally omitted
conn =
build_conn()
|> post("/oauth/token", %{
@@ -97,14 +157,18 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
})
assert %{"access_token" => token} = json_response(conn, 200)
- assert Repo.get_by(Token, token: token)
+
+ 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)
+ app = insert(:oauth_app, scopes: ["scope1", "scope2"])
- {:ok, auth} = Authorization.create_authorization(app, user)
+ {:ok, auth} = Authorization.create_authorization(app, user, ["scope2"])
+ assert auth.scopes == ["scope2"]
app_encoded =
(URI.encode_www_form(app.client_id) <> ":" <> URI.encode_www_form(app.client_secret))
@@ -120,7 +184,10 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
})
assert %{"access_token" => token} = json_response(conn, 200)
- assert Repo.get_by(Token, token: token)
+
+ token = Repo.get_by(Token, token: token)
+ assert token
+ assert token.scopes == ["scope2"]
end
test "rejects token exchange with invalid client credentials" do
diff --git a/test/web/oauth/token_test.exs b/test/web/oauth/token_test.exs
index 4dab4a308..62444a0fa 100644
--- a/test/web/oauth/token_test.exs
+++ b/test/web/oauth/token_test.exs
@@ -11,24 +11,26 @@ defmodule Pleroma.Web.OAuth.TokenTest do
import Pleroma.Factory
- test "exchanges a auth token for an access token" do
+ test "exchanges a auth token for an access token, preserving `scopes`" do
{:ok, app} =
Repo.insert(
App.register_changeset(%App{}, %{
client_name: "client",
- scopes: "scope",
+ scopes: ["read", "write"],
redirect_uris: "url"
})
)
user = insert(:user)
- {:ok, auth} = Authorization.create_authorization(app, user)
+ {:ok, auth} = Authorization.create_authorization(app, user, ["read"])
+ assert auth.scopes == ["read"]
{:ok, token} = Token.exchange_token(app, auth)
assert token.app_id == app.id
assert token.user_id == user.id
+ assert token.scopes == auth.scopes
assert String.length(token.token) > 10
assert String.length(token.refresh_token) > 10
@@ -41,7 +43,7 @@ defmodule Pleroma.Web.OAuth.TokenTest do
Repo.insert(
App.register_changeset(%App{}, %{
client_name: "client1",
- scopes: "scope",
+ scopes: ["scope"],
redirect_uris: "url"
})
)
@@ -50,7 +52,7 @@ defmodule Pleroma.Web.OAuth.TokenTest do
Repo.insert(
App.register_changeset(%App{}, %{
client_name: "client2",
- scopes: "scope",
+ scopes: ["scope"],
redirect_uris: "url"
})
)
diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs
index 1571ab68e..05a832967 100644
--- a/test/web/twitter_api/twitter_api_controller_test.exs
+++ b/test/web/twitter_api/twitter_api_controller_test.exs
@@ -14,6 +14,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
alias Pleroma.Notification
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.OAuth.Token
+ alias Pleroma.Web.TwitterAPI.Controller
alias Pleroma.Web.TwitterAPI.UserView
alias Pleroma.Web.TwitterAPI.NotificationView
alias Pleroma.Web.CommonAPI
@@ -22,6 +23,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
alias Ecto.Changeset
import Pleroma.Factory
+ import Mock
@banner "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
@@ -187,6 +189,20 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|> get("/api/statuses/public_timeline.json")
|> json_response(200)
end
+
+ test_with_mock "treats user as unauthenticated if `assigns[:token]` is present but lacks `read` permission",
+ Controller,
+ [:passthrough],
+ [] do
+ token = insert(:oauth_token, scopes: ["write"])
+
+ build_conn()
+ |> put_req_header("authorization", "Bearer #{token.token}")
+ |> get("/api/statuses/public_timeline.json")
+ |> json_response(200)
+
+ assert called(Controller.public_timeline(%{assigns: %{user: nil}}, :_))
+ end
end
describe "GET /statuses/public_and_external_timeline.json" do
@@ -1690,6 +1706,24 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert [relationship] = json_response(conn, 200)
assert other_user.id == relationship["id"]
end
+
+ test "requires 'read' permission", %{conn: conn} do
+ token1 = insert(:oauth_token, scopes: ["write"])
+ token2 = insert(:oauth_token, scopes: ["read"])
+
+ for token <- [token1, token2] do
+ conn =
+ conn
+ |> put_req_header("authorization", "Bearer #{token.token}")
+ |> get("/api/pleroma/friend_requests")
+
+ if token == token1 do
+ assert %{"error" => "Insufficient permissions: read."} == json_response(conn, 403)
+ else
+ assert json_response(conn, 200)
+ end
+ end
+ end
end
describe "POST /api/pleroma/friendships/approve" do
diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs
index 007d7d8e6..fc762ab18 100644
--- a/test/web/twitter_api/util_controller_test.exs
+++ b/test/web/twitter_api/util_controller_test.exs
@@ -16,6 +16,25 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
assert response == "job started"
end
+
+ test "requires 'follow' permission", %{conn: conn} do
+ token1 = insert(:oauth_token, scopes: ["read", "write"])
+ token2 = insert(:oauth_token, scopes: ["follow"])
+ another_user = insert(:user)
+
+ for token <- [token1, token2] do
+ conn =
+ conn
+ |> put_req_header("authorization", "Bearer #{token.token}")
+ |> post("/api/pleroma/follow_import", %{"list" => "#{another_user.ap_id}"})
+
+ if token == token1 do
+ assert %{"error" => "Insufficient permissions: follow."} == json_response(conn, 403)
+ else
+ assert json_response(conn, 200)
+ end
+ end
+ end
end
describe "POST /api/pleroma/blocks_import" do
diff --git a/test/web/views/error_view_test.exs b/test/web/views/error_view_test.exs
index 16a0c8cef..d529fd2c3 100644
--- a/test/web/views/error_view_test.exs
+++ b/test/web/views/error_view_test.exs
@@ -14,11 +14,16 @@ defmodule Pleroma.Web.ErrorViewTest do
test "render 500.json" do
assert render(Pleroma.Web.ErrorView, "500.json", []) ==
- %{errors: %{detail: "Internal server error"}}
+ %{errors: %{detail: "Internal server error", reason: "nil"}}
end
test "render any other" do
assert render(Pleroma.Web.ErrorView, "505.json", []) ==
- %{errors: %{detail: "Internal server error"}}
+ %{errors: %{detail: "Internal server error", reason: "nil"}}
+ end
+
+ test "render 500.json with reason" do
+ assert render(Pleroma.Web.ErrorView, "500.json", reason: "test reason") ==
+ %{errors: %{detail: "Internal server error", reason: "\"test reason\""}}
end
end