Initial commit on Forgejo
Fresh repository history for elektrine/tarakan hosted at https://git.elektrine.com/elektrine/tarakan.
This commit is contained in:
commit
af6077b9c3
455 changed files with 78366 additions and 0 deletions
121
test/tarakan_web/controllers/github_auth_controller_test.exs
Normal file
121
test/tarakan_web/controllers/github_auth_controller_test.exs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
defmodule TarakanWeb.GitHubAuthControllerTest do
|
||||
use TarakanWeb.ConnCase
|
||||
|
||||
alias Tarakan.Accounts
|
||||
|
||||
test "starts GitHub authorization with state and PKCE", %{conn: conn} do
|
||||
conn = get(conn, ~p"/auth/github?return_to=/")
|
||||
|
||||
location = redirected_to(conn, 302)
|
||||
query = location |> URI.parse() |> Map.fetch!(:query) |> URI.decode_query()
|
||||
|
||||
assert String.starts_with?(location, "https://github.com/login/oauth/authorize?")
|
||||
assert query["client_id"] == "test-client-id"
|
||||
assert query["code_challenge_method"] == "S256"
|
||||
assert query["code_challenge"]
|
||||
assert query["state"] == get_session(conn, :github_oauth_state)
|
||||
assert get_session(conn, :github_oauth_verifier)
|
||||
end
|
||||
|
||||
test "creates a session after GitHub authorizes the user", %{conn: conn} do
|
||||
authorization_conn = get(conn, ~p"/auth/github?return_to=/")
|
||||
state = get_session(authorization_conn, :github_oauth_state)
|
||||
|
||||
callback_conn =
|
||||
authorization_conn
|
||||
|> recycle()
|
||||
|> get(~p"/auth/github/callback?code=valid-code&state=#{state}")
|
||||
|
||||
assert redirected_to(callback_conn) == "/"
|
||||
token = get_session(callback_conn, :account_token)
|
||||
assert {account, _inserted_at} = Accounts.get_account_by_session_token(token)
|
||||
assert account.handle == "tarakantester"
|
||||
assert is_nil(account.display_name)
|
||||
assert is_nil(account.email)
|
||||
refute get_session(callback_conn, :github_oauth_state)
|
||||
refute get_session(callback_conn, :github_oauth_verifier)
|
||||
|
||||
assert Tarakan.Repo.get_by!(Tarakan.Accounts.Identity,
|
||||
account_id: account.id,
|
||||
provider: "github"
|
||||
)
|
||||
end
|
||||
|
||||
test "rejects a callback with an invalid state", %{conn: conn} do
|
||||
authorization_conn = get(conn, ~p"/auth/github")
|
||||
|
||||
callback_conn =
|
||||
authorization_conn
|
||||
|> recycle()
|
||||
|> get(~p"/auth/github/callback?code=valid-code&state=wrong-state")
|
||||
|
||||
assert redirected_to(callback_conn) == "/"
|
||||
refute get_session(callback_conn, :account_token)
|
||||
end
|
||||
|
||||
test "links GitHub to the signed-in Tarakan account", %{conn: conn} do
|
||||
account = account_fixture()
|
||||
|
||||
authorization_conn =
|
||||
conn
|
||||
|> log_in_account(account)
|
||||
|> get(~p"/auth/github?return_to=/accounts/settings")
|
||||
|
||||
state = get_session(authorization_conn, :github_oauth_state)
|
||||
|
||||
callback_conn =
|
||||
authorization_conn
|
||||
|> recycle()
|
||||
|> get(~p"/auth/github/callback?code=valid-code&state=#{state}")
|
||||
|
||||
assert redirected_to(callback_conn) == "/accounts/settings"
|
||||
token = get_session(callback_conn, :account_token)
|
||||
assert {linked_account, _inserted_at} = Accounts.get_account_by_session_token(token)
|
||||
assert linked_account.id == account.id
|
||||
|
||||
assert Tarakan.Repo.get_by!(Tarakan.Accounts.Identity,
|
||||
account_id: account.id,
|
||||
provider: "github"
|
||||
)
|
||||
end
|
||||
|
||||
test "refuses to link an identity from a stale signed-in session", %{conn: conn} do
|
||||
account = account_fixture()
|
||||
stale_at = DateTime.add(DateTime.utc_now(:second), -9 * 60, :minute)
|
||||
|
||||
authorization_conn =
|
||||
conn
|
||||
|> log_in_account(account, token_authenticated_at: stale_at)
|
||||
|> get(~p"/auth/github?return_to=/accounts/settings")
|
||||
|
||||
state = get_session(authorization_conn, :github_oauth_state)
|
||||
|
||||
callback_conn =
|
||||
authorization_conn
|
||||
|> recycle()
|
||||
|> get(~p"/auth/github/callback?code=valid-code&state=#{state}")
|
||||
|
||||
assert redirected_to(callback_conn) == "/accounts/settings"
|
||||
|
||||
refute Tarakan.Repo.get_by(Tarakan.Accounts.Identity,
|
||||
account_id: account.id,
|
||||
provider: "github"
|
||||
)
|
||||
end
|
||||
|
||||
test "does not retain a malicious return path in the OAuth session" do
|
||||
for return_to <- ["//attacker.example", "/\\attacker.example", "/%255cattacker.example"] do
|
||||
query = URI.encode_query(%{"return_to" => return_to})
|
||||
authorization_conn = get(build_conn(), "/auth/github?#{query}")
|
||||
|
||||
assert get_session(authorization_conn, :github_oauth_return_to) == "/"
|
||||
end
|
||||
end
|
||||
|
||||
test "signs the current user out", %{conn: conn} do
|
||||
conn = conn |> log_in_account(account_fixture()) |> delete(~p"/accounts/log-out")
|
||||
|
||||
assert redirected_to(conn) == "/"
|
||||
refute get_session(conn, :account_token)
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue