diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/emails/admin_email_test.exs | 4 | ||||
| -rw-r--r-- | test/plugs/oauth_scopes_plug_test.exs | 237 | ||||
| -rw-r--r-- | test/signature_test.exs | 5 | ||||
| -rw-r--r-- | test/support/factory.ex | 1 | ||||
| -rw-r--r-- | test/user_test.exs | 8 | ||||
| -rw-r--r-- | test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs | 5 | ||||
| -rw-r--r-- | test/web/oauth/oauth_controller_test.exs | 6 | ||||
| -rw-r--r-- | test/web/twitter_api/util_controller_test.exs | 10 | 
8 files changed, 192 insertions, 84 deletions
| diff --git a/test/emails/admin_email_test.exs b/test/emails/admin_email_test.exs index 31eac5f12..02c277a33 100644 --- a/test/emails/admin_email_test.exs +++ b/test/emails/admin_email_test.exs @@ -19,8 +19,8 @@ defmodule Pleroma.Emails.AdminEmailTest do        AdminEmail.report(to_user, reporter, account, [%{name: "Test", id: "12"}], "Test comment")      status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, "12") -    reporter_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :feed_redirect, reporter.nickname) -    account_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :feed_redirect, account.nickname) +    reporter_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :feed_redirect, reporter.id) +    account_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :feed_redirect, account.id)      assert res.to == [{to_user.name, to_user.email}]      assert res.from == {config[:name], config[:notify_email]} diff --git a/test/plugs/oauth_scopes_plug_test.exs b/test/plugs/oauth_scopes_plug_test.exs index 6a13ea811..be6d1340b 100644 --- a/test/plugs/oauth_scopes_plug_test.exs +++ b/test/plugs/oauth_scopes_plug_test.exs @@ -5,24 +5,48 @@  defmodule Pleroma.Plugs.OAuthScopesPlugTest do    use Pleroma.Web.ConnCase, async: true +  alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug    alias Pleroma.Plugs.OAuthScopesPlug    alias Pleroma.Repo +  import Mock    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"]}) +  setup_with_mocks([{EnsurePublicOrAuthenticatedPlug, [], [call: fn conn, _ -> conn end]}]) do +    :ok +  end -    refute conn.halted -    assert conn.assigns[:user] +  describe "when `assigns[:token]` is nil, " do +    test "with :skip_instance_privacy_check option, proceeds with no op", %{conn: conn} do +      conn = +        conn +        |> assign(:user, insert(:user)) +        |> OAuthScopesPlug.call(%{scopes: ["read"], skip_instance_privacy_check: true}) + +      refute conn.halted +      assert conn.assigns[:user] + +      refute called(EnsurePublicOrAuthenticatedPlug.call(conn, :_)) +    end + +    test "without :skip_instance_privacy_check option, calls EnsurePublicOrAuthenticatedPlug", %{ +      conn: conn +    } do +      conn = +        conn +        |> assign(:user, insert(:user)) +        |> OAuthScopesPlug.call(%{scopes: ["read"]}) + +      refute conn.halted +      assert conn.assigns[:user] + +      assert called(EnsurePublicOrAuthenticatedPlug.call(conn, :_)) +    end    end -  test "proceeds with no op if `token.scopes` fulfill specified 'any of' conditions", %{ -    conn: conn -  } do +  test "if `token.scopes` fulfills specified 'any of' conditions, " <> +         "proceeds with no op", +       %{conn: conn} do      token = insert(:oauth_token, scopes: ["read", "write"]) |> Repo.preload(:user)      conn = @@ -35,9 +59,9 @@ defmodule Pleroma.Plugs.OAuthScopesPlugTest do      assert conn.assigns[:user]    end -  test "proceeds with no op if `token.scopes` fulfill specified 'all of' conditions", %{ -    conn: conn -  } do +  test "if `token.scopes` fulfills specified 'all of' conditions, " <> +         "proceeds with no op", +       %{conn: conn} do      token = insert(:oauth_token, scopes: ["scope1", "scope2", "scope3"]) |> Repo.preload(:user)      conn = @@ -50,73 +74,154 @@ defmodule Pleroma.Plugs.OAuthScopesPlugTest do      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) +  describe "with `fallback: :proceed_unauthenticated` option, " do +    test "if `token.scopes` doesn't fulfill specified 'any of' conditions, " <> +           "clears `assigns[:user]` and calls EnsurePublicOrAuthenticatedPlug", +         %{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] + +      assert called(EnsurePublicOrAuthenticatedPlug.call(conn, :_)) +    end + +    test "if `token.scopes` doesn't fulfill specified 'all of' conditions, " <> +           "clears `assigns[:user] and calls EnsurePublicOrAuthenticatedPlug", +         %{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] + +      assert called(EnsurePublicOrAuthenticatedPlug.call(conn, :_)) +    end + +    test "with :skip_instance_privacy_check option, " <> +           "if `token.scopes` doesn't fulfill specified conditions, " <> +           "clears `assigns[:user]` and does not call EnsurePublicOrAuthenticatedPlug", +         %{conn: conn} do +      token = insert(:oauth_token, scopes: ["read:statuses", "write"]) |> Repo.preload(:user) + +      conn = +        conn +        |> assign(:user, token.user) +        |> assign(:token, token) +        |> OAuthScopesPlug.call(%{ +          scopes: ["read"], +          fallback: :proceed_unauthenticated, +          skip_instance_privacy_check: true +        }) + +      refute conn.halted +      refute conn.assigns[:user] + +      refute called(EnsurePublicOrAuthenticatedPlug.call(conn, :_)) +    end +  end -    conn = -      conn -      |> assign(:user, token.user) -      |> assign(:token, token) -      |> OAuthScopesPlug.call(%{scopes: ["follow"], fallback: :proceed_unauthenticated}) +  describe "without :fallback option, " do +    test "if `token.scopes` does not fulfill specified 'any of' conditions, " <> +           "returns 403 and halts", +         %{conn: conn} do +      token = insert(:oauth_token, scopes: ["read", "write"]) +      any_of_scopes = ["follow"] -    refute conn.halted -    refute conn.assigns[:user] -  end +      conn = +        conn +        |> assign(:token, token) +        |> OAuthScopesPlug.call(%{scopes: any_of_scopes}) -  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) +      assert conn.halted +      assert 403 == conn.status -    conn = -      conn -      |> assign(:user, token.user) -      |> assign(:token, token) -      |> OAuthScopesPlug.call(%{ -        scopes: ["read", "follow"], -        op: :&, -        fallback: :proceed_unauthenticated -      }) +      expected_error = "Insufficient permissions: #{Enum.join(any_of_scopes, ", ")}." +      assert Jason.encode!(%{error: expected_error}) == conn.resp_body +    end -    refute conn.halted -    refute conn.assigns[:user] -  end +    test "if `token.scopes` does not fulfill specified 'all of' conditions, " <> +           "returns 403 and halts", +         %{conn: conn} do +      token = insert(:oauth_token, scopes: ["read", "write"]) +      all_of_scopes = ["write", "follow"] -  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: all_of_scopes, op: :&}) -    conn = -      conn -      |> assign(:token, token) -      |> OAuthScopesPlug.call(%{scopes: any_of_scopes}) +      assert conn.halted +      assert 403 == conn.status -    assert conn.halted -    assert 403 == conn.status +      expected_error = +        "Insufficient permissions: #{Enum.join(all_of_scopes -- token.scopes, ", ")}." -    expected_error = "Insufficient permissions: #{Enum.join(any_of_scopes, ", ")}." -    assert Jason.encode!(%{error: expected_error}) == conn.resp_body +      assert Jason.encode!(%{error: expected_error}) == conn.resp_body +    end    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"] +  describe "with hierarchical scopes, " do +    test "if `token.scopes` fulfills specified 'any of' conditions, " <> +           "proceeds with no op", +         %{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:something"]}) + +      refute conn.halted +      assert conn.assigns[:user] +    end + +    test "if `token.scopes` fulfills specified 'all of' conditions, " <> +           "proceeds with no op", +         %{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: ["scope1:subscope", "scope2:subscope"], op: :&}) + +      refute conn.halted +      assert conn.assigns[:user] +    end +  end -    conn = -      conn -      |> assign(:token, token) -      |> OAuthScopesPlug.call(%{scopes: all_of_scopes, op: :&}) +  describe "filter_descendants/2" do +    test "filters scopes which directly match or are ancestors of supported scopes" do +      f = fn scopes, supported_scopes -> +        OAuthScopesPlug.filter_descendants(scopes, supported_scopes) +      end + +      assert f.(["read", "follow"], ["write", "read"]) == ["read"] -    assert conn.halted -    assert 403 == conn.status +      assert f.(["read", "write:something", "follow"], ["write", "read"]) == +               ["read", "write:something"] -    expected_error = -      "Insufficient permissions: #{Enum.join(all_of_scopes -- token.scopes, ", ")}." +      assert f.(["admin:read"], ["write", "read"]) == [] -    assert Jason.encode!(%{error: expected_error}) == conn.resp_body +      assert f.(["admin:read"], ["write", "admin"]) == ["admin:read"] +    end    end  end diff --git a/test/signature_test.exs b/test/signature_test.exs index d5bf63d7d..96c8ba07a 100644 --- a/test/signature_test.exs +++ b/test/signature_test.exs @@ -80,7 +80,7 @@ defmodule Pleroma.SignatureTest do        user =          insert(:user, %{            ap_id: "https://mastodon.social/users/lambadalambda", -          info: %{keys: @private_key} +          keys: @private_key          })        assert Signature.sign( @@ -94,8 +94,7 @@ defmodule Pleroma.SignatureTest do      end      test "it returns error" do -      user = -        insert(:user, %{ap_id: "https://mastodon.social/users/lambadalambda", info: %{keys: ""}}) +      user = insert(:user, %{ap_id: "https://mastodon.social/users/lambadalambda", keys: ""})        assert Signature.sign(                 user, diff --git a/test/support/factory.ex b/test/support/factory.ex index 4f3244025..b180844cd 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -324,6 +324,7 @@ defmodule Pleroma.Factory do      %Pleroma.Web.OAuth.Token{        token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(), +      scopes: ["read"],        refresh_token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(),        user: build(:user),        app_id: oauth_app.id, diff --git a/test/user_test.exs b/test/user_test.exs index 1bc853c94..ae21286e4 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -1457,15 +1457,15 @@ defmodule Pleroma.UserTest do    describe "ensure_keys_present" do      test "it creates keys for a user and stores them in info" do        user = insert(:user) -      refute is_binary(user.info.keys) +      refute is_binary(user.keys)        {:ok, user} = User.ensure_keys_present(user) -      assert is_binary(user.info.keys) +      assert is_binary(user.keys)      end      test "it doesn't create keys if there already are some" do -      user = insert(:user, %{info: %{keys: "xxx"}}) +      user = insert(:user, keys: "xxx")        {:ok, user} = User.ensure_keys_present(user) -      assert user.info.keys == "xxx" +      assert user.keys == "xxx"      end    end diff --git a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs index 599cd61c8..618031b40 100644 --- a/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs +++ b/test/web/mastodon_api/controllers/account_controller/update_credentials_test.exs @@ -272,7 +272,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do        assert user_response["pleroma"]["background_image"]      end -    test "requires 'write' permission", %{conn: conn} do +    test "requires 'write:accounts' permission", %{conn: conn} do        token1 = insert(:oauth_token, scopes: ["read"])        token2 = insert(:oauth_token, scopes: ["write", "follow"]) @@ -283,7 +283,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do            |> patch("/api/v1/accounts/update_credentials", %{})          if token == token1 do -          assert %{"error" => "Insufficient permissions: write."} == json_response(conn, 403) +          assert %{"error" => "Insufficient permissions: write:accounts."} == +                   json_response(conn, 403)          else            assert json_response(conn, 200)          end diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs index 4d0741d14..41aaf6189 100644 --- a/test/web/oauth/oauth_controller_test.exs +++ b/test/web/oauth/oauth_controller_test.exs @@ -557,7 +557,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do              "password" => "test",              "client_id" => app.client_id,              "redirect_uri" => redirect_uri, -            "scope" => "read write", +            "scope" => "read:subscope write",              "state" => "statepassed"            }          }) @@ -570,7 +570,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do        assert %{"state" => "statepassed", "code" => code} = query        auth = Repo.get_by(Authorization, token: code)        assert auth -      assert auth.scopes == ["read", "write"] +      assert auth.scopes == ["read:subscope", "write"]      end      test "returns 401 for wrong credentials", %{conn: conn} do @@ -627,7 +627,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do        assert result =~ "This action is outside the authorized scopes"      end -    test "returns 401 for scopes beyond app scopes", %{conn: conn} do +    test "returns 401 for scopes beyond app scopes hierarchy", %{conn: conn} do        user = insert(:user)        app = insert(:oauth_app, scopes: ["read", "write"])        redirect_uri = OAuthController.default_redirect_uri(app) diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs index 56e318182..9d4cb70f0 100644 --- a/test/web/twitter_api/util_controller_test.exs +++ b/test/web/twitter_api/util_controller_test.exs @@ -81,19 +81,21 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do        assert response == "job started"      end -    test "requires 'follow' permission", %{conn: conn} do +    test "requires 'follow' or 'write:follows' permissions", %{conn: conn} do        token1 = insert(:oauth_token, scopes: ["read", "write"])        token2 = insert(:oauth_token, scopes: ["follow"]) +      token3 = insert(:oauth_token, scopes: ["something"])        another_user = insert(:user) -      for token <- [token1, token2] do +      for token <- [token1, token2, token3] 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) +        if token == token3 do +          assert %{"error" => "Insufficient permissions: follow | write:follows."} == +                   json_response(conn, 403)          else            assert json_response(conn, 200)          end | 
