tests consistency

This commit is contained in:
Alexander Strizhakov 2020-06-23 18:16:47 +03:00
commit 7dffaef479
No known key found for this signature in database
GPG key ID: 022896A53AEF1381
258 changed files with 38 additions and 37 deletions

View file

@ -0,0 +1,242 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Auth.AuthControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
describe "do_oauth_check" do
test "serves with proper OAuth token (fulfilling requested scopes)" do
%{conn: good_token_conn, user: user} = oauth_access(["read"])
assert %{"user_id" => user.id} ==
good_token_conn
|> get("/test/authenticated_api/do_oauth_check")
|> json_response(200)
# Unintended usage (:api) — use with :authenticated_api instead
assert %{"user_id" => user.id} ==
good_token_conn
|> get("/test/api/do_oauth_check")
|> json_response(200)
end
test "fails on no token / missing scope(s)" do
%{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
bad_token_conn
|> get("/test/authenticated_api/do_oauth_check")
|> json_response(403)
bad_token_conn
|> assign(:token, nil)
|> get("/test/api/do_oauth_check")
|> json_response(403)
end
end
describe "fallback_oauth_check" do
test "serves with proper OAuth token (fulfilling requested scopes)" do
%{conn: good_token_conn, user: user} = oauth_access(["read"])
assert %{"user_id" => user.id} ==
good_token_conn
|> get("/test/api/fallback_oauth_check")
|> json_response(200)
# Unintended usage (:authenticated_api) — use with :api instead
assert %{"user_id" => user.id} ==
good_token_conn
|> get("/test/authenticated_api/fallback_oauth_check")
|> json_response(200)
end
test "for :api on public instance, drops :user and renders on no token / missing scope(s)" do
clear_config([:instance, :public], true)
%{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
assert %{"user_id" => nil} ==
bad_token_conn
|> get("/test/api/fallback_oauth_check")
|> json_response(200)
assert %{"user_id" => nil} ==
bad_token_conn
|> assign(:token, nil)
|> get("/test/api/fallback_oauth_check")
|> json_response(200)
end
test "for :api on private instance, fails on no token / missing scope(s)" do
clear_config([:instance, :public], false)
%{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
bad_token_conn
|> get("/test/api/fallback_oauth_check")
|> json_response(403)
bad_token_conn
|> assign(:token, nil)
|> get("/test/api/fallback_oauth_check")
|> json_response(403)
end
end
describe "skip_oauth_check" do
test "for :authenticated_api, serves if :user is set (regardless of token / token scopes)" do
user = insert(:user)
assert %{"user_id" => user.id} ==
build_conn()
|> assign(:user, user)
|> get("/test/authenticated_api/skip_oauth_check")
|> json_response(200)
%{conn: bad_token_conn, user: user} = oauth_access(["irrelevant_scope"])
assert %{"user_id" => user.id} ==
bad_token_conn
|> get("/test/authenticated_api/skip_oauth_check")
|> json_response(200)
end
test "serves via :api on public instance if :user is not set" do
clear_config([:instance, :public], true)
assert %{"user_id" => nil} ==
build_conn()
|> get("/test/api/skip_oauth_check")
|> json_response(200)
build_conn()
|> get("/test/authenticated_api/skip_oauth_check")
|> json_response(403)
end
test "fails on private instance if :user is not set" do
clear_config([:instance, :public], false)
build_conn()
|> get("/test/api/skip_oauth_check")
|> json_response(403)
build_conn()
|> get("/test/authenticated_api/skip_oauth_check")
|> json_response(403)
end
end
describe "fallback_oauth_skip_publicity_check" do
test "serves with proper OAuth token (fulfilling requested scopes)" do
%{conn: good_token_conn, user: user} = oauth_access(["read"])
assert %{"user_id" => user.id} ==
good_token_conn
|> get("/test/api/fallback_oauth_skip_publicity_check")
|> json_response(200)
# Unintended usage (:authenticated_api)
assert %{"user_id" => user.id} ==
good_token_conn
|> get("/test/authenticated_api/fallback_oauth_skip_publicity_check")
|> json_response(200)
end
test "for :api on private / public instance, drops :user and renders on token issue" do
%{conn: bad_token_conn} = oauth_access(["irrelevant_scope"])
for is_public <- [true, false] do
clear_config([:instance, :public], is_public)
assert %{"user_id" => nil} ==
bad_token_conn
|> get("/test/api/fallback_oauth_skip_publicity_check")
|> json_response(200)
assert %{"user_id" => nil} ==
bad_token_conn
|> assign(:token, nil)
|> get("/test/api/fallback_oauth_skip_publicity_check")
|> json_response(200)
end
end
end
describe "skip_oauth_skip_publicity_check" do
test "for :authenticated_api, serves if :user is set (regardless of token / token scopes)" do
user = insert(:user)
assert %{"user_id" => user.id} ==
build_conn()
|> assign(:user, user)
|> get("/test/authenticated_api/skip_oauth_skip_publicity_check")
|> json_response(200)
%{conn: bad_token_conn, user: user} = oauth_access(["irrelevant_scope"])
assert %{"user_id" => user.id} ==
bad_token_conn
|> get("/test/authenticated_api/skip_oauth_skip_publicity_check")
|> json_response(200)
end
test "for :api, serves on private and public instances regardless of whether :user is set" do
user = insert(:user)
for is_public <- [true, false] do
clear_config([:instance, :public], is_public)
assert %{"user_id" => nil} ==
build_conn()
|> get("/test/api/skip_oauth_skip_publicity_check")
|> json_response(200)
assert %{"user_id" => user.id} ==
build_conn()
|> assign(:user, user)
|> get("/test/api/skip_oauth_skip_publicity_check")
|> json_response(200)
end
end
end
describe "missing_oauth_check_definition" do
def test_missing_oauth_check_definition_failure(endpoint, expected_error) do
%{conn: conn} = oauth_access(["read", "write", "follow", "push", "admin"])
assert %{"error" => expected_error} ==
conn
|> get(endpoint)
|> json_response(403)
end
test "fails if served via :authenticated_api" do
test_missing_oauth_check_definition_failure(
"/test/authenticated_api/missing_oauth_check_definition",
"Security violation: OAuth scopes check was neither handled nor explicitly skipped."
)
end
test "fails if served via :api and the instance is private" do
clear_config([:instance, :public], false)
test_missing_oauth_check_definition_failure(
"/test/api/missing_oauth_check_definition",
"This resource requires authentication."
)
end
test "succeeds with dropped :user if served via :api on public instance" do
%{conn: conn} = oauth_access(["read", "write", "follow", "push", "admin"])
assert %{"user_id" => nil} ==
conn
|> get("/test/api/missing_oauth_check_definition")
|> json_response(200)
end
end
end

View file

@ -0,0 +1,42 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Auth.AuthenticatorTest do
use Pleroma.Web.ConnCase
alias Pleroma.Web.Auth.Authenticator
import Pleroma.Factory
describe "fetch_user/1" do
test "returns user by name" do
user = insert(:user)
assert Authenticator.fetch_user(user.nickname) == user
end
test "returns user by email" do
user = insert(:user)
assert Authenticator.fetch_user(user.email) == user
end
test "returns nil" do
assert Authenticator.fetch_user("email") == nil
end
end
describe "fetch_credentials/1" do
test "returns name and password from authorization params" do
params = %{"authorization" => %{"name" => "test", "password" => "test-pass"}}
assert Authenticator.fetch_credentials(params) == {:ok, {"test", "test-pass"}}
end
test "returns name and password with grant_type 'password'" do
params = %{"grant_type" => "password", "username" => "test", "password" => "test-pass"}
assert Authenticator.fetch_credentials(params) == {:ok, {"test", "test-pass"}}
end
test "returns error" do
assert Authenticator.fetch_credentials(%{}) == {:error, :invalid_credentials}
end
end
end

View file

@ -0,0 +1,46 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Auth.BasicAuthTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
test "with HTTP Basic Auth used, grants access to OAuth scope-restricted endpoints", %{
conn: conn
} do
user = insert(:user)
assert Pbkdf2.verify_pass("test", user.password_hash)
basic_auth_contents =
(URI.encode_www_form(user.nickname) <> ":" <> URI.encode_www_form("test"))
|> Base.encode64()
# Succeeds with HTTP Basic Auth
response =
conn
|> put_req_header("authorization", "Basic " <> basic_auth_contents)
|> get("/api/v1/accounts/verify_credentials")
|> json_response(200)
user_nickname = user.nickname
assert %{"username" => ^user_nickname} = response
# Succeeds with a properly scoped OAuth token
valid_token = insert(:oauth_token, scopes: ["read:accounts"])
conn
|> put_req_header("authorization", "Bearer #{valid_token.token}")
|> get("/api/v1/accounts/verify_credentials")
|> json_response(200)
# Fails with a wrong-scoped OAuth token (proof of restriction)
invalid_token = insert(:oauth_token, scopes: ["read:something"])
conn
|> put_req_header("authorization", "Bearer #{invalid_token.token}")
|> get("/api/v1/accounts/verify_credentials")
|> json_response(403)
end
end

View file

@ -0,0 +1,48 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Auth.PleromaAuthenticatorTest do
use Pleroma.Web.ConnCase
alias Pleroma.Web.Auth.PleromaAuthenticator
import Pleroma.Factory
setup do
password = "testpassword"
name = "AgentSmith"
user = insert(:user, nickname: name, password_hash: Pbkdf2.hash_pwd_salt(password))
{:ok, [user: user, name: name, password: password]}
end
test "get_user/authorization", %{name: name, password: password} do
name = name <> "1"
user = insert(:user, nickname: name, password_hash: Bcrypt.hash_pwd_salt(password))
params = %{"authorization" => %{"name" => name, "password" => password}}
res = PleromaAuthenticator.get_user(%Plug.Conn{params: params})
assert {:ok, returned_user} = res
assert returned_user.id == user.id
assert "$pbkdf2" <> _ = returned_user.password_hash
end
test "get_user/authorization with invalid password", %{name: name} do
params = %{"authorization" => %{"name" => name, "password" => "password"}}
res = PleromaAuthenticator.get_user(%Plug.Conn{params: params})
assert {:error, {:checkpw, false}} == res
end
test "get_user/grant_type_password", %{user: user, name: name, password: password} do
params = %{"grant_type" => "password", "username" => name, "password" => password}
res = PleromaAuthenticator.get_user(%Plug.Conn{params: params})
assert {:ok, user} == res
end
test "error credintails" do
res = PleromaAuthenticator.get_user(%Plug.Conn{params: %{}})
assert {:error, :invalid_credentials} == res
end
end

View file

@ -0,0 +1,51 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.Auth.TOTPAuthenticatorTest do
use Pleroma.Web.ConnCase
alias Pleroma.MFA
alias Pleroma.MFA.BackupCodes
alias Pleroma.MFA.TOTP
alias Pleroma.Web.Auth.TOTPAuthenticator
import Pleroma.Factory
test "verify token" do
otp_secret = TOTP.generate_secret()
otp_token = TOTP.generate_token(otp_secret)
user =
insert(:user,
multi_factor_authentication_settings: %MFA.Settings{
enabled: true,
totp: %MFA.Settings.TOTP{secret: otp_secret, confirmed: true}
}
)
assert TOTPAuthenticator.verify(otp_token, user) == {:ok, :pass}
assert TOTPAuthenticator.verify(nil, user) == {:error, :invalid_token}
assert TOTPAuthenticator.verify("", user) == {:error, :invalid_token}
end
test "checks backup codes" do
[code | _] = backup_codes = BackupCodes.generate()
hashed_codes =
backup_codes
|> Enum.map(&Pbkdf2.hash_pwd_salt(&1))
user =
insert(:user,
multi_factor_authentication_settings: %MFA.Settings{
enabled: true,
backup_codes: hashed_codes,
totp: %MFA.Settings.TOTP{secret: "otp_secret", confirmed: true}
}
)
assert TOTPAuthenticator.verify_recovery_code(user, code) == {:ok, :pass}
refute TOTPAuthenticator.verify_recovery_code(code, refresh_record(user)) == {:ok, :pass}
end
end