mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
fix(portal): Fix update API endpoint for resources (#7493)
Why: * The API endpoint for updating Resources was using `Resources.fetch_resource_by_id_or_persistent_id`, however that function was fetching all Resources, which included deleted Resources. In order to prevent an API user from attempting to update a Resource that is deleted, a new function was added to fetch active Resources only. Fixes: #7492
This commit is contained in:
@@ -92,7 +92,7 @@ defmodule API.ResourceController do
|
||||
subject = conn.assigns.subject
|
||||
attrs = set_param_defaults(params)
|
||||
|
||||
with {:ok, resource} <- Resources.fetch_resource_by_id_or_persistent_id(id, subject) do
|
||||
with {:ok, resource} <- Resources.fetch_active_resource_by_id_or_persistent_id(id, subject) do
|
||||
case Resources.update_or_replace_resource(resource, attrs, subject) do
|
||||
{:updated, updated_resource} ->
|
||||
render(conn, :show, resource: updated_resource)
|
||||
|
||||
@@ -5,10 +5,14 @@ defmodule API.ResourceControllerTest do
|
||||
setup do
|
||||
account = Fixtures.Accounts.create_account()
|
||||
actor = Fixtures.Actors.create_actor(type: :api_client, account: account)
|
||||
identity = Fixtures.Auth.create_identity(account: account, actor: actor)
|
||||
subject = Fixtures.Auth.create_subject(identity: identity)
|
||||
|
||||
%{
|
||||
account: account,
|
||||
actor: actor
|
||||
actor: actor,
|
||||
identity: identity,
|
||||
subject: subject
|
||||
}
|
||||
end
|
||||
|
||||
@@ -195,6 +199,27 @@ defmodule API.ResourceControllerTest do
|
||||
assert resp == %{"error" => %{"reason" => "Bad Request"}}
|
||||
end
|
||||
|
||||
test "returns not found when resource is deleted", %{
|
||||
conn: conn,
|
||||
account: account,
|
||||
actor: actor,
|
||||
subject: subject
|
||||
} do
|
||||
resource = Fixtures.Resources.create_resource(%{account: account})
|
||||
Domain.Resources.delete_resource(resource, subject)
|
||||
|
||||
attrs = %{"name" => "Google"}
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> authorize_conn(actor)
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/resources/#{resource.id}", resource: attrs)
|
||||
|
||||
assert resp = json_response(conn, 404)
|
||||
assert resp == %{"error" => %{"reason" => "Not Found"}}
|
||||
end
|
||||
|
||||
test "updates a resource", %{conn: conn, account: account, actor: actor} do
|
||||
resource = Fixtures.Resources.create_resource(%{account: account})
|
||||
|
||||
|
||||
@@ -43,6 +43,26 @@ defmodule Domain.Resources do
|
||||
end
|
||||
end
|
||||
|
||||
def fetch_active_resource_by_id_or_persistent_id(id, %Auth.Subject{} = subject, opts \\ []) do
|
||||
required_permissions =
|
||||
{:one_of,
|
||||
[
|
||||
Authorizer.manage_resources_permission(),
|
||||
Authorizer.view_available_resources_permission()
|
||||
]}
|
||||
|
||||
with :ok <- Auth.ensure_has_permissions(subject, required_permissions),
|
||||
true <- Repo.valid_uuid?(id) do
|
||||
Resource.Query.not_deleted()
|
||||
|> Resource.Query.by_id_or_persistent_id(id)
|
||||
|> Authorizer.for_subject(Resource, subject)
|
||||
|> Repo.fetch(Resource.Query, opts)
|
||||
else
|
||||
false -> {:error, :not_found}
|
||||
other -> other
|
||||
end
|
||||
end
|
||||
|
||||
def fetch_and_authorize_resource_by_id(id, %Auth.Subject{} = subject, opts \\ []) do
|
||||
with :ok <-
|
||||
Auth.ensure_has_permissions(subject, Authorizer.view_available_resources_permission()),
|
||||
|
||||
Reference in New Issue
Block a user