X-Git-Url: http://git.squeep.com/?a=blobdiff_plain;f=test%2Fpleroma%2Fweb%2Fo_auth%2Fo_auth_controller_test.exs;h=19a7dea60ef84e081806a804e7f4dd8f0d5d8c62;hb=b8be8192fbfe8c27b457094e8d64ccb1c3a29f7f;hp=0fdd5b8e9fb853e6cd2f4a84ef6eb1ad39030292;hpb=dc63aaf84f07a6f8042f43617d8ec356fed85cec;p=akkoma diff --git a/test/pleroma/web/o_auth/o_auth_controller_test.exs b/test/pleroma/web/o_auth/o_auth_controller_test.exs index 0fdd5b8e9..19a7dea60 100644 --- a/test/pleroma/web/o_auth/o_auth_controller_test.exs +++ b/test/pleroma/web/o_auth/o_auth_controller_test.exs @@ -494,6 +494,129 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do assert html_response(conn, 200) =~ ~s(type="submit") end + test "allows access if the user has a prior authorization but is authenticated with another client", + %{ + app: app, + conn: conn + } do + user = insert(:user) + token = insert(:oauth_token, app: app, user: user) + + other_app = insert(:oauth_app, redirect_uris: "https://other_redirect.url") + authorization = insert(:oauth_authorization, user: user, app: other_app) + _reusable_token = insert(:oauth_token, app: other_app, user: user) + + conn = + conn + |> AuthHelper.put_session_token(token.token) + |> AuthHelper.put_session_user(user.id) + |> get( + "/oauth/authorize", + %{ + "response_type" => "code", + "client_id" => other_app.client_id, + "redirect_uri" => OAuthController.default_redirect_uri(other_app), + "scope" => "read" + } + ) + + assert URI.decode(redirected_to(conn)) == + "https://other_redirect.url?code=#{authorization.token}" + end + + test "renders login page if the user has an authorization but no token", + %{ + app: app, + conn: conn + } do + user = insert(:user) + token = insert(:oauth_token, app: app, user: user) + + other_app = insert(:oauth_app, redirect_uris: "https://other_redirect.url") + _authorization = insert(:oauth_authorization, user: user, app: other_app) + + conn = + conn + |> AuthHelper.put_session_token(token.token) + |> AuthHelper.put_session_user(user.id) + |> get( + "/oauth/authorize", + %{ + "response_type" => "code", + "client_id" => other_app.client_id, + "redirect_uri" => OAuthController.default_redirect_uri(other_app), + "scope" => "read" + } + ) + + assert html_response(conn, 200) =~ ~s(type="submit") + end + + test "does not reuse other people's tokens", + %{ + app: app, + conn: conn + } do + user = insert(:user) + other_user = insert(:user) + token = insert(:oauth_token, app: app, user: user) + + other_app = insert(:oauth_app, redirect_uris: "https://other_redirect.url") + _authorization = insert(:oauth_authorization, user: other_user, app: other_app) + _reusable_token = insert(:oauth_token, app: other_app, user: other_user) + + conn = + conn + |> AuthHelper.put_session_token(token.token) + |> AuthHelper.put_session_user(user.id) + |> get( + "/oauth/authorize", + %{ + "response_type" => "code", + "client_id" => other_app.client_id, + "redirect_uri" => OAuthController.default_redirect_uri(other_app), + "scope" => "read" + } + ) + + assert html_response(conn, 200) =~ ~s(type="submit") + end + + test "does not reuse expired tokens", + %{ + app: app, + conn: conn + } do + user = insert(:user) + token = insert(:oauth_token, app: app, user: user) + + other_app = insert(:oauth_app, redirect_uris: "https://other_redirect.url") + _authorization = insert(:oauth_authorization, user: user, app: other_app) + + _reusable_token = + insert(:oauth_token, + app: other_app, + user: user, + valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), -100) + ) + + conn = + conn + |> AuthHelper.put_session_token(token.token) + |> AuthHelper.put_session_user(user.id) + |> get( + "/oauth/authorize", + %{ + "response_type" => "code", + "client_id" => other_app.client_id, + "redirect_uri" => OAuthController.default_redirect_uri(other_app), + "scope" => "read" + } + ) + + assert html_response(conn, 200) =~ ~s(type="submit") + end + test "with existing authentication and non-OOB `redirect_uri`, redirects to app with `token` and `state` params", %{ app: app, @@ -570,45 +693,76 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do describe "POST /oauth/authorize" do test "redirects with oauth authorization, " <> - "granting requested app-supported scopes to both admin- and non-admin users" do + "granting requested app-supported scopes to both admin users" do app_scopes = ["read", "write", "admin", "secret_scope"] app = insert(:oauth_app, scopes: app_scopes) redirect_uri = OAuthController.default_redirect_uri(app) + scopes_subset = ["read:subscope", "write", "admin"] + admin = insert(:user, is_admin: true) + + # In case scope param is missing, expecting _all_ app-supported scopes to be granted + conn = + post( + build_conn(), + "/oauth/authorize", + %{ + "authorization" => %{ + "name" => admin.nickname, + "password" => "test", + "client_id" => app.client_id, + "redirect_uri" => redirect_uri, + "scope" => scopes_subset, + "state" => "statepassed" + } + } + ) + + target = redirected_to(conn) + assert target =~ redirect_uri + + 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 == scopes_subset + end + + test "redirects with oauth authorization, " <> + "granting requested app-supported scopes for non-admin users" do + app_scopes = ["read", "write", "secret_scope", "admin"] + app = insert(:oauth_app, scopes: app_scopes) + redirect_uri = OAuthController.default_redirect_uri(app) non_admin = insert(:user, is_admin: false) - admin = insert(:user, is_admin: true) - scopes_subset = ["read:subscope", "write", "admin"] + scopes_subset = ["read:subscope", "write"] # In case scope param is missing, expecting _all_ app-supported scopes to be granted - for user <- [non_admin, admin], - {requested_scopes, expected_scopes} <- - %{scopes_subset => scopes_subset, nil: app_scopes} do - conn = - post( - build_conn(), - "/oauth/authorize", - %{ - "authorization" => %{ - "name" => user.nickname, - "password" => "test", - "client_id" => app.client_id, - "redirect_uri" => redirect_uri, - "scope" => requested_scopes, - "state" => "statepassed" - } + conn = + post( + build_conn(), + "/oauth/authorize", + %{ + "authorization" => %{ + "name" => non_admin.nickname, + "password" => "test", + "client_id" => app.client_id, + "redirect_uri" => redirect_uri, + "scope" => scopes_subset, + "state" => "statepassed" } - ) + } + ) - target = redirected_to(conn) - assert target =~ redirect_uri + target = redirected_to(conn) + assert target =~ redirect_uri - query = URI.parse(target).query |> URI.query_decoder() |> Map.new() + 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 + assert %{"state" => "statepassed", "code" => code} = query + auth = Repo.get_by(Authorization, token: code) + assert auth + assert auth.scopes == scopes_subset end test "authorize from cookie" do @@ -616,6 +770,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do app = insert(:oauth_app) oauth_token = insert(:oauth_token, user: user, app: app) redirect_uri = OAuthController.default_redirect_uri(app) + IO.inspect(app) conn = build_conn() @@ -708,6 +863,33 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do assert result =~ "Invalid Username/Password" end + test "returns 401 when attempting to use an admin scope with a non-admin", %{conn: conn} do + user = insert(:user) + app = insert(:oauth_app, scopes: ["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" => Enum.join(app.scopes, " ") + } + }) + |> html_response(:unauthorized) + + # Keep the details + assert result =~ app.client_id + assert result =~ redirect_uri + + # Error message + assert result =~ "outside of authorized scopes" + end + test "returns 401 for missing scopes" do user = insert(:user, is_admin: false) app = insert(:oauth_app, scopes: ["read", "write", "admin"]) @@ -732,7 +914,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do assert result =~ redirect_uri # Error message - assert result =~ "This action is outside the authorized scopes" + assert result =~ "This action is outside of authorized scopes" end test "returns 401 for scopes beyond app scopes hierarchy", %{conn: conn} do @@ -759,7 +941,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do assert result =~ redirect_uri # Error message - assert result =~ "This action is outside the authorized scopes" + assert result =~ "This action is outside of authorized scopes" end end