mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
refactor(portal): Use appropriate access token for Google IdP (#8478)
Why: * Previously, when running a directory sync with the Google Workspace IdP adapter, if a service account had been configured but there was a problem getting an access token for the service account, the sync job would fall back to using a personal access token. We no longer want to rely on any personal access token once a service account has been configured. This commit will make sure that if a service account is configured there is no way to fall back to any personal access token. Fixes #8409
This commit is contained in:
@@ -71,7 +71,39 @@ defmodule Domain.Auth.Adapters.GoogleWorkspace do
|
||||
OpenIDConnect.sign_out(provider, identity, redirect_url)
|
||||
end
|
||||
|
||||
def fetch_service_account_token(%Provider{} = provider) do
|
||||
def fetch_access_token(%Provider{} = provider) do
|
||||
case GoogleWorkspace.fetch_service_account_access_token(provider) do
|
||||
{:ok, access_token} ->
|
||||
{:ok, access_token}
|
||||
|
||||
{:error, :missing_service_account_key} ->
|
||||
{:ok, provider.adapter_state["access_token"]}
|
||||
|
||||
{:error, {401, _response} = reason} ->
|
||||
Logger.warning("401 while fetching service account access token",
|
||||
account_id: provider.account_id,
|
||||
account_slug: provider.account.slug,
|
||||
provider_id: provider.id,
|
||||
provider_adapter: provider.adapter,
|
||||
reason: inspect(reason)
|
||||
)
|
||||
|
||||
{:error, reason}
|
||||
|
||||
{:error, reason} ->
|
||||
Logger.error("Failed to fetch service account access token",
|
||||
account_id: provider.account_id,
|
||||
account_slug: provider.account.slug,
|
||||
provider_id: provider.id,
|
||||
provider_adapter: provider.adapter,
|
||||
reason: inspect(reason)
|
||||
)
|
||||
|
||||
{:error, reason}
|
||||
end
|
||||
end
|
||||
|
||||
def fetch_service_account_access_token(%Provider{} = provider) do
|
||||
key = provider.adapter_config["service_account_json_key"]
|
||||
sub = provider.adapter_state["userinfo"]["sub"]
|
||||
|
||||
|
||||
@@ -23,36 +23,16 @@ defmodule Domain.Auth.Adapters.GoogleWorkspace.Jobs.SyncDirectory do
|
||||
end
|
||||
|
||||
def gather_provider_data(provider, task_supervisor_pid) do
|
||||
access_token =
|
||||
with {:ok, access_token} <- GoogleWorkspace.fetch_service_account_token(provider) do
|
||||
access_token
|
||||
else
|
||||
{:error, :missing_service_account_key} ->
|
||||
provider.adapter_state["access_token"]
|
||||
case GoogleWorkspace.fetch_access_token(provider) do
|
||||
{:ok, access_token} ->
|
||||
gather_directory_data(task_supervisor_pid, access_token)
|
||||
|
||||
{:error, {401, _response} = reason} ->
|
||||
Logger.warning("Failed to fetch service account token",
|
||||
account_id: provider.account_id,
|
||||
account_slug: provider.account.slug,
|
||||
provider_id: provider.id,
|
||||
provider_adapter: provider.adapter,
|
||||
reason: inspect(reason)
|
||||
)
|
||||
|
||||
provider.adapter_state["access_token"]
|
||||
|
||||
{:error, reason} ->
|
||||
Logger.error("Failed to fetch service account token",
|
||||
reason: inspect(reason),
|
||||
account_id: provider.account_id,
|
||||
account_slug: provider.account.slug,
|
||||
provider_id: provider.id,
|
||||
provider_adapter: provider.adapter
|
||||
)
|
||||
|
||||
provider.adapter_state["access_token"]
|
||||
end
|
||||
{:error, reason} ->
|
||||
{:error, "Failed to fetch access token", inspect(reason)}
|
||||
end
|
||||
end
|
||||
|
||||
defp gather_directory_data(task_supervisor_pid, access_token) do
|
||||
async_results =
|
||||
DirectorySync.run_async_requests(task_supervisor_pid,
|
||||
users: fn ->
|
||||
|
||||
@@ -48,7 +48,7 @@ defmodule Domain.Auth.Adapters.GoogleWorkspace.Jobs.SyncDirectoryTest do
|
||||
%{req_headers: [{"authorization", "Bearer GOOGLE_0AUTH_ACCESS_TOKEN"} | _]}}
|
||||
end
|
||||
|
||||
test "uses admin user token as a fallback when service account is not configured" do
|
||||
test "does not use admin user token when service account is set" do
|
||||
bypass = Bypass.open()
|
||||
GoogleWorkspaceDirectory.override_token_endpoint("http://localhost:#{bypass.port}/")
|
||||
|
||||
@@ -65,14 +65,12 @@ defmodule Domain.Auth.Adapters.GoogleWorkspace.Jobs.SyncDirectoryTest do
|
||||
end)
|
||||
|
||||
GoogleWorkspaceDirectory.override_endpoint_url("http://localhost:#{bypass.port}/")
|
||||
GoogleWorkspaceDirectory.mock_groups_list_endpoint(bypass, [])
|
||||
GoogleWorkspaceDirectory.mock_organization_units_list_endpoint(bypass, [])
|
||||
GoogleWorkspaceDirectory.mock_users_list_endpoint(bypass, [])
|
||||
|
||||
{:ok, pid} = Task.Supervisor.start_link()
|
||||
|
||||
assert execute(%{task_supervisor: pid}) == :ok
|
||||
|
||||
assert_receive {:bypass_request,
|
||||
refute_receive {:bypass_request,
|
||||
%{req_headers: [{"authorization", "Bearer OIDC_ACCESS_TOKEN"} | _]}}
|
||||
end
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ defmodule Domain.Auth.Adapters.GoogleWorkspaceTest do
|
||||
end
|
||||
end
|
||||
|
||||
describe "fetch_service_account_token/1" do
|
||||
describe "fetch_service_account_access_token/1" do
|
||||
test "generates a valid JWT" do
|
||||
Bypass.open()
|
||||
|> Mocks.GoogleWorkspaceDirectory.mock_token_endpoint()
|
||||
@@ -147,7 +147,7 @@ defmodule Domain.Auth.Adapters.GoogleWorkspaceTest do
|
||||
{provider, _bypass} = Fixtures.Auth.start_and_create_google_workspace_provider()
|
||||
provider = Repo.get!(Auth.Provider, provider.id)
|
||||
|
||||
assert fetch_service_account_token(provider) == {:ok, "GOOGLE_0AUTH_ACCESS_TOKEN"}
|
||||
assert fetch_service_account_access_token(provider) == {:ok, "GOOGLE_0AUTH_ACCESS_TOKEN"}
|
||||
end
|
||||
|
||||
test "returns error when API is not available" do
|
||||
@@ -158,7 +158,7 @@ defmodule Domain.Auth.Adapters.GoogleWorkspaceTest do
|
||||
{provider, _bypass} = Fixtures.Auth.start_and_create_google_workspace_provider()
|
||||
provider = Repo.get!(Auth.Provider, provider.id)
|
||||
|
||||
assert fetch_service_account_token(provider) ==
|
||||
assert fetch_service_account_access_token(provider) ==
|
||||
{:error, %Mint.TransportError{reason: :econnrefused}}
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user