forked from AkkomaGang/akkoma
[#468] Added OAuth scopes-specific tests.
This commit is contained in:
parent
c0ecbf6669
commit
04ee877a20
6 changed files with 162 additions and 47 deletions
|
@ -1536,6 +1536,24 @@ test "updates the user's banner", %{conn: conn} do
|
||||||
assert user_response = json_response(conn, 200)
|
assert user_response = json_response(conn, 200)
|
||||||
assert user_response["header"] != User.banner_url(user)
|
assert user_response["header"] != User.banner_url(user)
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
test "get instance information", %{conn: conn} do
|
test "get instance information", %{conn: conn} do
|
||||||
|
|
|
@ -8,36 +8,37 @@ defmodule Pleroma.Web.OAuth.AuthorizationTest do
|
||||||
alias Pleroma.Web.OAuth.App
|
alias Pleroma.Web.OAuth.App
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
test "create an authorization token for a valid app" do
|
setup do
|
||||||
{:ok, app} =
|
{:ok, app} =
|
||||||
Repo.insert(
|
Repo.insert(
|
||||||
App.register_changeset(%App{}, %{
|
App.register_changeset(%App{}, %{
|
||||||
client_name: "client",
|
client_name: "client",
|
||||||
scopes: ["scope"],
|
scopes: ["read", "write"],
|
||||||
redirect_uris: "url"
|
redirect_uris: "url"
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
%{app: app}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "create an authorization token for a valid app", %{app: app} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
||||||
{:ok, auth} = Authorization.create_authorization(app, user)
|
{:ok, auth1} = Authorization.create_authorization(app, user)
|
||||||
|
assert auth1.scopes == app.scopes
|
||||||
|
|
||||||
|
{:ok, auth2} = Authorization.create_authorization(app, user, ["read"])
|
||||||
|
assert auth2.scopes == ["read"]
|
||||||
|
|
||||||
|
for auth <- [auth1, auth2] do
|
||||||
assert auth.user_id == user.id
|
assert auth.user_id == user.id
|
||||||
assert auth.app_id == app.id
|
assert auth.app_id == app.id
|
||||||
assert String.length(auth.token) > 10
|
assert String.length(auth.token) > 10
|
||||||
assert auth.used == false
|
assert auth.used == false
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "use up a token" do
|
test "use up a token", %{app: app} do
|
||||||
{:ok, app} =
|
|
||||||
Repo.insert(
|
|
||||||
App.register_changeset(%App{}, %{
|
|
||||||
client_name: "client",
|
|
||||||
scopes: ["scope"],
|
|
||||||
redirect_uris: "url"
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
||||||
{:ok, auth} = Authorization.create_authorization(app, user)
|
{:ok, auth} = Authorization.create_authorization(app, user)
|
||||||
|
@ -61,16 +62,7 @@ test "use up a token" do
|
||||||
assert {:error, "token expired"} == Authorization.use_token(expired_auth)
|
assert {:error, "token expired"} == Authorization.use_token(expired_auth)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "delete authorizations" do
|
test "delete authorizations", %{app: app} do
|
||||||
{:ok, app} =
|
|
||||||
Repo.insert(
|
|
||||||
App.register_changeset(%App{}, %{
|
|
||||||
client_name: "client",
|
|
||||||
scopes: ["scope"],
|
|
||||||
redirect_uris: "url"
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
||||||
{:ok, auth} = Authorization.create_authorization(app, user)
|
{:ok, auth} = Authorization.create_authorization(app, user)
|
||||||
|
|
|
@ -12,7 +12,7 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
|
||||||
|
|
||||||
test "redirects with oauth authorization" do
|
test "redirects with oauth authorization" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
app = insert(:oauth_app)
|
app = insert(:oauth_app, scopes: ["read", "write", "follow"])
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|
@ -22,7 +22,7 @@ test "redirects with oauth authorization" do
|
||||||
"password" => "test",
|
"password" => "test",
|
||||||
"client_id" => app.client_id,
|
"client_id" => app.client_id,
|
||||||
"redirect_uri" => app.redirect_uris,
|
"redirect_uri" => app.redirect_uris,
|
||||||
"scope" => Enum.join(app.scopes, " "),
|
"scope" => "read write",
|
||||||
"state" => "statepassed"
|
"state" => "statepassed"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -33,10 +33,12 @@ test "redirects with oauth authorization" do
|
||||||
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
|
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
|
end
|
||||||
|
|
||||||
test "correctly handles wrong credentials", %{conn: conn} do
|
test "returns 401 for wrong credentials", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
app = insert(:oauth_app)
|
app = insert(:oauth_app)
|
||||||
|
|
||||||
|
@ -48,7 +50,8 @@ test "correctly handles wrong credentials", %{conn: conn} do
|
||||||
"password" => "wrong",
|
"password" => "wrong",
|
||||||
"client_id" => app.client_id,
|
"client_id" => app.client_id,
|
||||||
"redirect_uri" => app.redirect_uris,
|
"redirect_uri" => app.redirect_uris,
|
||||||
"state" => "statepassed"
|
"state" => "statepassed",
|
||||||
|
"scope" => Enum.join(app.scopes, " ")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|> html_response(:unauthorized)
|
|> html_response(:unauthorized)
|
||||||
|
@ -58,14 +61,66 @@ test "correctly handles wrong credentials", %{conn: conn} do
|
||||||
assert result =~ app.redirect_uris
|
assert result =~ app.redirect_uris
|
||||||
|
|
||||||
# Error message
|
# Error message
|
||||||
assert result =~ "Invalid"
|
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 =~ "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
|
end
|
||||||
|
|
||||||
test "issues a token for an all-body request" do
|
test "issues a token for an all-body request" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
app = insert(:oauth_app)
|
app = insert(:oauth_app, scopes: ["read", "write"])
|
||||||
|
|
||||||
{:ok, auth} = Authorization.create_authorization(app, user)
|
{:ok, auth} = Authorization.create_authorization(app, user, ["write"])
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|
@ -78,15 +133,19 @@ test "issues a token for an all-body request" do
|
||||||
})
|
})
|
||||||
|
|
||||||
assert %{"access_token" => token} = json_response(conn, 200)
|
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
|
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"
|
password = "testpassword"
|
||||||
user = insert(:user, password_hash: Comeonin.Pbkdf2.hashpwsalt(password))
|
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 =
|
conn =
|
||||||
build_conn()
|
build_conn()
|
||||||
|> post("/oauth/token", %{
|
|> post("/oauth/token", %{
|
||||||
|
@ -98,14 +157,18 @@ test "issues a token for `password` grant_type with valid credentials" do
|
||||||
})
|
})
|
||||||
|
|
||||||
assert %{"access_token" => token} = json_response(conn, 200)
|
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
|
end
|
||||||
|
|
||||||
test "issues a token for request with HTTP basic auth client credentials" do
|
test "issues a token for request with HTTP basic auth client credentials" do
|
||||||
user = insert(:user)
|
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 =
|
app_encoded =
|
||||||
(URI.encode_www_form(app.client_id) <> ":" <> URI.encode_www_form(app.client_secret))
|
(URI.encode_www_form(app.client_id) <> ":" <> URI.encode_www_form(app.client_secret))
|
||||||
|
@ -121,7 +184,10 @@ test "issues a token for request with HTTP basic auth client credentials" do
|
||||||
})
|
})
|
||||||
|
|
||||||
assert %{"access_token" => token} = json_response(conn, 200)
|
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
|
end
|
||||||
|
|
||||||
test "rejects token exchange with invalid client credentials" do
|
test "rejects token exchange with invalid client credentials" do
|
||||||
|
|
|
@ -11,24 +11,26 @@ defmodule Pleroma.Web.OAuth.TokenTest do
|
||||||
|
|
||||||
import Pleroma.Factory
|
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} =
|
{:ok, app} =
|
||||||
Repo.insert(
|
Repo.insert(
|
||||||
App.register_changeset(%App{}, %{
|
App.register_changeset(%App{}, %{
|
||||||
client_name: "client",
|
client_name: "client",
|
||||||
scopes: ["scope"],
|
scopes: ["read", "write"],
|
||||||
redirect_uris: "url"
|
redirect_uris: "url"
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
user = insert(:user)
|
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)
|
{:ok, token} = Token.exchange_token(app, auth)
|
||||||
|
|
||||||
assert token.app_id == app.id
|
assert token.app_id == app.id
|
||||||
assert token.user_id == user.id
|
assert token.user_id == user.id
|
||||||
|
assert token.scopes == auth.scopes
|
||||||
assert String.length(token.token) > 10
|
assert String.length(token.token) > 10
|
||||||
assert String.length(token.refresh_token) > 10
|
assert String.length(token.refresh_token) > 10
|
||||||
|
|
||||||
|
|
|
@ -1690,6 +1690,24 @@ test "it lists friend requests" do
|
||||||
assert [relationship] = json_response(conn, 200)
|
assert [relationship] = json_response(conn, 200)
|
||||||
assert other_user.id == relationship["id"]
|
assert other_user.id == relationship["id"]
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe "POST /api/pleroma/friendships/approve" do
|
describe "POST /api/pleroma/friendships/approve" do
|
||||||
|
|
|
@ -16,6 +16,25 @@ test "it returns HTTP 200", %{conn: conn} do
|
||||||
|
|
||||||
assert response == "job started"
|
assert response == "job started"
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe "POST /api/pleroma/blocks_import" do
|
describe "POST /api/pleroma/blocks_import" do
|
||||||
|
|
Loading…
Reference in a new issue