mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
Render deleted entities on fetch (#2692)
Since we have flows we should either delete the flow when the related entity is deleted (making them not very useful) or allow viewing deleted entities properly marking them and removing all action buttons in the UI: <img width="1728" alt="Screenshot 2023-11-22 at 13 41 51" src="https://github.com/firezone/firezone/assets/1877644/ae7f14b9-9607-4de0-a90f-049faf7e4374"> <img width="1728" alt="Screenshot 2023-11-22 at 13 41 54" src="https://github.com/firezone/firezone/assets/1877644/491f8e1f-6aad-459b-b038-6100c25b3bf4"> <img width="1728" alt="Screenshot 2023-11-22 at 13 41 48" src="https://github.com/firezone/firezone/assets/1877644/9200e521-0d92-41b5-9197-355353f09a50"> <img width="1728" alt="Screenshot 2023-11-22 at 13 07 47" src="https://github.com/firezone/firezone/assets/1877644/dca59bbd-9771-4b06-b32b-f17cf0047520"> This change only affects fetching relation by ID (eg. `actors/:id`), rest of pages (index, edit) will not show deleted entities unless they are a critical relation (eg. for Policy to work both actor group and resource are needed): <img width="1728" alt="Screenshot 2023-11-22 at 13 42 23" src="https://github.com/firezone/firezone/assets/1877644/d8b15011-838a-477d-97c8-5c7109299cb9"> Closes #2681 Signed-off-by: Andrew Dryga <andrew@dryga.com>
This commit is contained in:
@@ -29,7 +29,8 @@ defmodule Domain.Actors do
|
||||
true <- Validator.valid_uuid?(id) do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
Group.Query.by_id(id)
|
||||
Group.Query.all()
|
||||
|> Group.Query.by_id(id)
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.fetch()
|
||||
|> case do
|
||||
@@ -47,7 +48,7 @@ defmodule Domain.Actors do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
{:ok, groups} =
|
||||
Group.Query.all()
|
||||
Group.Query.not_deleted()
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.list()
|
||||
|
||||
@@ -153,7 +154,8 @@ defmodule Domain.Actors do
|
||||
true <- Validator.valid_uuid?(id) do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
Actor.Query.by_id(id)
|
||||
Actor.Query.all()
|
||||
|> Actor.Query.by_id(id)
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.fetch()
|
||||
|> case do
|
||||
@@ -185,7 +187,7 @@ defmodule Domain.Actors do
|
||||
|
||||
with :ok <- Auth.ensure_has_permissions(subject, Authorizer.manage_actors_permission()) do
|
||||
{:ok, actors} =
|
||||
Actor.Query.all()
|
||||
Actor.Query.not_deleted()
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.list()
|
||||
|
||||
|
||||
@@ -3,10 +3,14 @@ defmodule Domain.Actors.Actor.Query do
|
||||
|
||||
def all do
|
||||
from(actors in Domain.Actors.Actor, as: :actors)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
all()
|
||||
|> where([actors: actors], is_nil(actors.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id)
|
||||
def by_id(queryable \\ not_deleted(), id)
|
||||
|
||||
def by_id(queryable, {:in, ids}) do
|
||||
where(queryable, [actors: actors], actors.id in ^ids)
|
||||
@@ -20,19 +24,19 @@ defmodule Domain.Actors.Actor.Query do
|
||||
where(queryable, [actors: actors], actors.id == ^id)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [actors: actors], actors.account_id == ^account_id)
|
||||
end
|
||||
|
||||
def by_type(queryable \\ all(), type) do
|
||||
def by_type(queryable \\ not_deleted(), type) do
|
||||
where(queryable, [actors: actors], actors.type == ^type)
|
||||
end
|
||||
|
||||
def not_disabled(queryable \\ all()) do
|
||||
def not_disabled(queryable \\ not_deleted()) do
|
||||
where(queryable, [actors: actors], is_nil(actors.disabled_at))
|
||||
end
|
||||
|
||||
def preload_few_groups_for_each_actor(queryable \\ all(), limit) do
|
||||
def preload_few_groups_for_each_actor(queryable \\ not_deleted(), limit) do
|
||||
queryable
|
||||
|> with_joined_memberships(limit)
|
||||
|> with_joined_groups()
|
||||
@@ -49,7 +53,10 @@ defmodule Domain.Actors.Actor.Query do
|
||||
Domain.Actors.Membership.Query.all()
|
||||
|> where([memberships: memberships], memberships.actor_id == parent_as(:actors).id)
|
||||
# we need second join to exclude soft deleted actors before applying a limit
|
||||
|> join(:inner, [memberships: memberships], groups in ^Domain.Actors.Group.Query.all(),
|
||||
|> join(
|
||||
:inner,
|
||||
[memberships: memberships],
|
||||
groups in ^Domain.Actors.Group.Query.not_deleted(),
|
||||
on: groups.id == memberships.group_id
|
||||
)
|
||||
|> select([memberships: memberships], memberships.group_id)
|
||||
@@ -70,18 +77,22 @@ defmodule Domain.Actors.Actor.Query do
|
||||
)
|
||||
end
|
||||
|
||||
def with_joined_groups(queryable \\ all()) do
|
||||
join(queryable, :left, [memberships: memberships], groups in ^Domain.Actors.Group.Query.all(),
|
||||
def with_joined_groups(queryable \\ not_deleted()) do
|
||||
join(
|
||||
queryable,
|
||||
:left,
|
||||
[memberships: memberships],
|
||||
groups in ^Domain.Actors.Group.Query.not_deleted(),
|
||||
on: groups.id == memberships.group_id,
|
||||
as: :groups
|
||||
)
|
||||
end
|
||||
|
||||
def lock(queryable \\ all()) do
|
||||
def lock(queryable \\ not_deleted()) do
|
||||
lock(queryable, "FOR UPDATE")
|
||||
end
|
||||
|
||||
def with_assoc(queryable \\ all(), qual \\ :left, assoc) do
|
||||
def with_assoc(queryable \\ not_deleted(), qual \\ :left, assoc) do
|
||||
with_named_binding(queryable, assoc, fn query, binding ->
|
||||
join(query, qual, [actors: actors], a in assoc(actors, ^binding), as: ^binding)
|
||||
end)
|
||||
|
||||
@@ -5,7 +5,7 @@ defmodule Domain.Actors.Group do
|
||||
field :name, :string
|
||||
|
||||
# Those fields will be set for groups we synced from IdP's
|
||||
belongs_to :provider, Domain.Auth.Provider, where: [deleted_at: nil]
|
||||
belongs_to :provider, Domain.Auth.Provider
|
||||
field :provider_identifier, :string
|
||||
|
||||
has_many :policies, Domain.Policies.Policy,
|
||||
|
||||
@@ -3,10 +3,14 @@ defmodule Domain.Actors.Group.Query do
|
||||
|
||||
def all do
|
||||
from(groups in Domain.Actors.Group, as: :groups)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
all()
|
||||
|> where([groups: groups], is_nil(groups.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id)
|
||||
def by_id(queryable \\ not_deleted(), id)
|
||||
|
||||
def by_id(queryable, {:in, ids}) do
|
||||
where(queryable, [groups: groups], groups.id in ^ids)
|
||||
@@ -16,19 +20,19 @@ defmodule Domain.Actors.Group.Query do
|
||||
where(queryable, [groups: groups], groups.id == ^id)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [groups: groups], groups.account_id == ^account_id)
|
||||
end
|
||||
|
||||
def by_provider_id(queryable \\ all(), provider_id) do
|
||||
def by_provider_id(queryable \\ not_deleted(), provider_id) do
|
||||
where(queryable, [groups: groups], groups.provider_id == ^provider_id)
|
||||
end
|
||||
|
||||
def by_not_empty_provider_id(queryable \\ all()) do
|
||||
def by_not_empty_provider_id(queryable \\ not_deleted()) do
|
||||
where(queryable, [groups: groups], not is_nil(groups.provider_id))
|
||||
end
|
||||
|
||||
def by_provider_identifier(queryable \\ all(), provider_identifier)
|
||||
def by_provider_identifier(queryable \\ not_deleted(), provider_identifier)
|
||||
|
||||
def by_provider_identifier(queryable, {:in, provider_identifiers}) do
|
||||
where(queryable, [groups: groups], groups.provider_identifier in ^provider_identifiers)
|
||||
@@ -38,7 +42,7 @@ defmodule Domain.Actors.Group.Query do
|
||||
where(queryable, [groups: groups], groups.provider_identifier == ^provider_identifier)
|
||||
end
|
||||
|
||||
def group_by_provider_id(queryable \\ all()) do
|
||||
def group_by_provider_id(queryable \\ not_deleted()) do
|
||||
queryable
|
||||
|> group_by([groups: groups], groups.provider_id)
|
||||
|> where([groups: groups], not is_nil(groups.provider_id))
|
||||
@@ -48,7 +52,7 @@ defmodule Domain.Actors.Group.Query do
|
||||
})
|
||||
end
|
||||
|
||||
def preload_few_actors_for_each_group(queryable \\ all(), limit) do
|
||||
def preload_few_actors_for_each_group(queryable \\ not_deleted(), limit) do
|
||||
queryable
|
||||
|> with_joined_memberships(limit)
|
||||
|> with_joined_actors()
|
||||
@@ -71,7 +75,10 @@ defmodule Domain.Actors.Group.Query do
|
||||
Domain.Actors.Membership.Query.all()
|
||||
|> where([memberships: memberships], memberships.group_id == parent_as(:groups).id)
|
||||
# we need second join to exclude soft deleted actors before applying a limit
|
||||
|> join(:inner, [memberships: memberships], actors in ^Domain.Actors.Actor.Query.all(),
|
||||
|> join(
|
||||
:inner,
|
||||
[memberships: memberships],
|
||||
actors in ^Domain.Actors.Actor.Query.not_deleted(),
|
||||
on: actors.id == memberships.actor_id
|
||||
)
|
||||
|> select([memberships: memberships], memberships.actor_id)
|
||||
@@ -92,14 +99,18 @@ defmodule Domain.Actors.Group.Query do
|
||||
)
|
||||
end
|
||||
|
||||
def with_joined_actors(queryable \\ all()) do
|
||||
join(queryable, :left, [memberships: memberships], actors in ^Domain.Actors.Actor.Query.all(),
|
||||
def with_joined_actors(queryable \\ not_deleted()) do
|
||||
join(
|
||||
queryable,
|
||||
:left,
|
||||
[memberships: memberships],
|
||||
actors in ^Domain.Actors.Actor.Query.not_deleted(),
|
||||
on: actors.id == memberships.actor_id,
|
||||
as: :actors
|
||||
)
|
||||
end
|
||||
|
||||
def lock(queryable \\ all()) do
|
||||
def lock(queryable \\ not_deleted()) do
|
||||
lock(queryable, "FOR UPDATE")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -69,14 +69,14 @@ defmodule Domain.Actors.Membership.Query do
|
||||
end
|
||||
|
||||
def with_joined_actors(queryable \\ all()) do
|
||||
join(queryable, :inner, [memberships: memberships], actors in ^Actor.Query.all(),
|
||||
join(queryable, :inner, [memberships: memberships], actors in ^Actor.Query.not_deleted(),
|
||||
on: actors.id == memberships.actor_id,
|
||||
as: :actors
|
||||
)
|
||||
end
|
||||
|
||||
def with_joined_groups(queryable \\ all()) do
|
||||
join(queryable, :inner, [memberships: memberships], groups in ^Group.Query.all(),
|
||||
join(queryable, :inner, [memberships: memberships], groups in ^Group.Query.not_deleted(),
|
||||
on: groups.id == memberships.group_id,
|
||||
as: :groups
|
||||
)
|
||||
|
||||
@@ -3,10 +3,14 @@ defmodule Domain.Auth.Identity.Query do
|
||||
|
||||
def all do
|
||||
from(identities in Domain.Auth.Identity, as: :identities)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
all()
|
||||
|> where([identities: identities], is_nil(identities.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id)
|
||||
def by_id(queryable \\ not_deleted(), id)
|
||||
|
||||
def by_id(queryable, {:not, id}) do
|
||||
where(queryable, [identities: identities], identities.id != ^id)
|
||||
@@ -16,26 +20,26 @@ defmodule Domain.Auth.Identity.Query do
|
||||
where(queryable, [identities: identities], identities.id == ^id)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [identities: identities], identities.account_id == ^account_id)
|
||||
end
|
||||
|
||||
def by_actor_id(queryable \\ all(), actor_id) do
|
||||
def by_actor_id(queryable \\ not_deleted(), actor_id) do
|
||||
where(queryable, [identities: identities], identities.actor_id == ^actor_id)
|
||||
end
|
||||
|
||||
def by_provider_id(queryable \\ all(), provider_id) do
|
||||
def by_provider_id(queryable \\ not_deleted(), provider_id) do
|
||||
queryable
|
||||
|> where([identities: identities], identities.provider_id == ^provider_id)
|
||||
|> with_assoc(:inner, :provider)
|
||||
|> where([provider: provider], is_nil(provider.disabled_at) and is_nil(provider.deleted_at))
|
||||
end
|
||||
|
||||
def by_adapter(queryable \\ all(), adapter) do
|
||||
def by_adapter(queryable \\ not_deleted(), adapter) do
|
||||
where(queryable, [identities: identities], identities.adapter == ^adapter)
|
||||
end
|
||||
|
||||
def by_provider_identifier(queryable \\ all(), provider_identifier)
|
||||
def by_provider_identifier(queryable \\ not_deleted(), provider_identifier)
|
||||
|
||||
def by_provider_identifier(queryable, {:in, provider_identifiers}) do
|
||||
where(
|
||||
@@ -53,7 +57,7 @@ defmodule Domain.Auth.Identity.Query do
|
||||
)
|
||||
end
|
||||
|
||||
def by_id_or_provider_identifier(queryable \\ all(), id_or_provider_identifier) do
|
||||
def by_id_or_provider_identifier(queryable \\ not_deleted(), id_or_provider_identifier) do
|
||||
if Domain.Validator.valid_uuid?(id_or_provider_identifier) do
|
||||
where(
|
||||
queryable,
|
||||
@@ -66,18 +70,18 @@ defmodule Domain.Auth.Identity.Query do
|
||||
end
|
||||
end
|
||||
|
||||
def not_disabled(queryable \\ all()) do
|
||||
def not_disabled(queryable \\ not_deleted()) do
|
||||
queryable
|
||||
|> join(:inner, [identities: identities], actors in assoc(identities, :actor), as: :actors)
|
||||
|> where([actors: actors], is_nil(actors.deleted_at))
|
||||
|> where([actors: actors], is_nil(actors.disabled_at))
|
||||
end
|
||||
|
||||
def lock(queryable \\ all()) do
|
||||
def lock(queryable \\ not_deleted()) do
|
||||
lock(queryable, "FOR UPDATE")
|
||||
end
|
||||
|
||||
def group_by_provider_id(queryable \\ all()) do
|
||||
def group_by_provider_id(queryable \\ not_deleted()) do
|
||||
queryable
|
||||
|> group_by([identities: identities], identities.provider_id)
|
||||
|> select([identities: identities], %{
|
||||
@@ -86,13 +90,13 @@ defmodule Domain.Auth.Identity.Query do
|
||||
})
|
||||
end
|
||||
|
||||
def with_preloaded_assoc(queryable \\ all(), type \\ :left, assoc) do
|
||||
def with_preloaded_assoc(queryable \\ not_deleted(), type \\ :left, assoc) do
|
||||
queryable
|
||||
|> with_assoc(type, assoc)
|
||||
|> preload([{^assoc, assoc}], [{^assoc, assoc}])
|
||||
end
|
||||
|
||||
def with_assoc(queryable \\ all(), type \\ :left, assoc) do
|
||||
def with_assoc(queryable \\ not_deleted(), type \\ :left, assoc) do
|
||||
with_named_binding(queryable, assoc, fn query, binding ->
|
||||
join(query, type, [identities: identities], a in assoc(identities, ^binding), as: ^binding)
|
||||
end)
|
||||
|
||||
@@ -3,10 +3,14 @@ defmodule Domain.Auth.Provider.Query do
|
||||
|
||||
def all do
|
||||
from(provider in Domain.Auth.Provider, as: :provider)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
all()
|
||||
|> where([provider: provider], is_nil(provider.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id)
|
||||
def by_id(queryable \\ not_deleted(), id)
|
||||
|
||||
def by_id(queryable, {:not, id}) do
|
||||
where(queryable, [provider: provider], provider.id != ^id)
|
||||
@@ -16,7 +20,7 @@ defmodule Domain.Auth.Provider.Query do
|
||||
where(queryable, [provider: provider], provider.id == ^id)
|
||||
end
|
||||
|
||||
def by_adapter(queryable \\ all(), adapter)
|
||||
def by_adapter(queryable \\ not_deleted(), adapter)
|
||||
|
||||
def by_adapter(queryable, {:not_in, adapters}) do
|
||||
where(queryable, [provider: provider], provider.adapter not in ^adapters)
|
||||
@@ -26,7 +30,7 @@ defmodule Domain.Auth.Provider.Query do
|
||||
where(queryable, [provider: provider], provider.adapter == ^adapter)
|
||||
end
|
||||
|
||||
def last_synced_at(queryable \\ all(), {:lt, datetime}) do
|
||||
def last_synced_at(queryable \\ not_deleted(), {:lt, datetime}) do
|
||||
where(
|
||||
queryable,
|
||||
[provider: provider],
|
||||
@@ -34,7 +38,7 @@ defmodule Domain.Auth.Provider.Query do
|
||||
)
|
||||
end
|
||||
|
||||
def by_non_empty_refresh_token(queryable \\ all()) do
|
||||
def by_non_empty_refresh_token(queryable \\ not_deleted()) do
|
||||
where(
|
||||
queryable,
|
||||
[provider: provider],
|
||||
@@ -42,7 +46,7 @@ defmodule Domain.Auth.Provider.Query do
|
||||
)
|
||||
end
|
||||
|
||||
def token_expires_at(queryable \\ all(), {:lt, datetime}) do
|
||||
def token_expires_at(queryable \\ not_deleted(), {:lt, datetime}) do
|
||||
where(
|
||||
queryable,
|
||||
[provider: provider],
|
||||
@@ -50,19 +54,19 @@ defmodule Domain.Auth.Provider.Query do
|
||||
)
|
||||
end
|
||||
|
||||
def by_provisioner(queryable \\ all(), provisioner) do
|
||||
def by_provisioner(queryable \\ not_deleted(), provisioner) do
|
||||
where(queryable, [provider: provider], provider.provisioner == ^provisioner)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [provider: provider], provider.account_id == ^account_id)
|
||||
end
|
||||
|
||||
def not_disabled(queryable \\ all()) do
|
||||
def not_disabled(queryable \\ not_deleted()) do
|
||||
where(queryable, [provider: provider], is_nil(provider.disabled_at))
|
||||
end
|
||||
|
||||
def lock(queryable \\ all()) do
|
||||
def lock(queryable \\ not_deleted()) do
|
||||
lock(queryable, "FOR UPDATE")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -38,7 +38,8 @@ defmodule Domain.Clients do
|
||||
true <- Validator.valid_uuid?(id) do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
Client.Query.by_id(id)
|
||||
Client.Query.all()
|
||||
|> Client.Query.by_id(id)
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.fetch()
|
||||
|> case do
|
||||
@@ -80,7 +81,7 @@ defmodule Domain.Clients do
|
||||
|
||||
with :ok <- Auth.ensure_has_permissions(subject, required_permissions) do
|
||||
{:ok, clients} =
|
||||
Client.Query.all()
|
||||
Client.Query.not_deleted()
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.list()
|
||||
|
||||
|
||||
@@ -3,26 +3,30 @@ defmodule Domain.Clients.Client.Query do
|
||||
|
||||
def all do
|
||||
from(clients in Domain.Clients.Client, as: :clients)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
all()
|
||||
|> where([clients: clients], is_nil(clients.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id) do
|
||||
def by_id(queryable \\ not_deleted(), id) do
|
||||
where(queryable, [clients: clients], clients.id == ^id)
|
||||
end
|
||||
|
||||
def by_actor_id(queryable \\ all(), actor_id) do
|
||||
def by_actor_id(queryable \\ not_deleted(), actor_id) do
|
||||
where(queryable, [clients: clients], clients.actor_id == ^actor_id)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [clients: clients], clients.account_id == ^account_id)
|
||||
end
|
||||
|
||||
def returning_all(queryable \\ all()) do
|
||||
def returning_not_deleted(queryable \\ not_deleted()) do
|
||||
select(queryable, [clients: clients], clients)
|
||||
end
|
||||
|
||||
def with_preloaded_actor(queryable \\ all()) do
|
||||
def with_preloaded_actor(queryable \\ not_deleted()) do
|
||||
with_named_binding(queryable, :actor, fn queryable, binding ->
|
||||
queryable
|
||||
|> join(:inner, [clients: clients], actor in assoc(clients, ^binding), as: ^binding)
|
||||
@@ -30,7 +34,7 @@ defmodule Domain.Clients.Client.Query do
|
||||
end)
|
||||
end
|
||||
|
||||
def with_preloaded_identity(queryable \\ all()) do
|
||||
def with_preloaded_identity(queryable \\ not_deleted()) do
|
||||
with_named_binding(queryable, :identity, fn queryable, binding ->
|
||||
queryable
|
||||
|> join(:inner, [clients: clients], identity in assoc(clients, ^binding), as: ^binding)
|
||||
|
||||
@@ -42,7 +42,8 @@ defmodule Domain.Gateways do
|
||||
true <- Validator.valid_uuid?(id) do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
Group.Query.by_id(id)
|
||||
Group.Query.all()
|
||||
|> Group.Query.by_id(id)
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.fetch()
|
||||
|> case do
|
||||
@@ -68,7 +69,7 @@ defmodule Domain.Gateways do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
{:ok, groups} =
|
||||
Group.Query.all()
|
||||
Group.Query.not_deleted()
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.list()
|
||||
|
||||
@@ -193,7 +194,8 @@ defmodule Domain.Gateways do
|
||||
true <- Validator.valid_uuid?(id) do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
Gateway.Query.by_id(id)
|
||||
Gateway.Query.all()
|
||||
|> Gateway.Query.by_id(id)
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.fetch()
|
||||
|> case do
|
||||
@@ -228,7 +230,7 @@ defmodule Domain.Gateways do
|
||||
|
||||
with :ok <- Auth.ensure_has_permissions(subject, Authorizer.manage_gateways_permission()) do
|
||||
{:ok, gateways} =
|
||||
Gateway.Query.all()
|
||||
Gateway.Query.not_deleted()
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.list()
|
||||
|
||||
@@ -263,7 +265,7 @@ defmodule Domain.Gateways do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
{:ok, gateways} =
|
||||
Gateway.Query.all()
|
||||
Gateway.Query.not_deleted()
|
||||
|> Gateway.Query.by_group_id(group.id)
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.list()
|
||||
|
||||
@@ -3,40 +3,44 @@ defmodule Domain.Gateways.Gateway.Query do
|
||||
|
||||
def all do
|
||||
from(gateways in Domain.Gateways.Gateway, as: :gateways)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
all()
|
||||
|> where([gateways: gateways], is_nil(gateways.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id) do
|
||||
def by_id(queryable \\ not_deleted(), id) do
|
||||
where(queryable, [gateways: gateways], gateways.id == ^id)
|
||||
end
|
||||
|
||||
def by_ids(queryable \\ all(), ids) do
|
||||
def by_ids(queryable \\ not_deleted(), ids) do
|
||||
where(queryable, [gateways: gateways], gateways.id in ^ids)
|
||||
end
|
||||
|
||||
def by_user_id(queryable \\ all(), user_id) do
|
||||
def by_user_id(queryable \\ not_deleted(), user_id) do
|
||||
where(queryable, [gateways: gateways], gateways.user_id == ^user_id)
|
||||
end
|
||||
|
||||
def by_group_id(queryable \\ all(), group_id) do
|
||||
def by_group_id(queryable \\ not_deleted(), group_id) do
|
||||
where(queryable, [gateways: gateways], gateways.group_id == ^group_id)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [gateways: gateways], gateways.account_id == ^account_id)
|
||||
end
|
||||
|
||||
def by_resource_id(queryable \\ all(), resource_id) do
|
||||
def by_resource_id(queryable \\ not_deleted(), resource_id) do
|
||||
queryable
|
||||
|> with_joined_connections()
|
||||
|> where([connections: connections], connections.resource_id == ^resource_id)
|
||||
end
|
||||
|
||||
def returning_all(queryable \\ all()) do
|
||||
def returning_not_deleted(queryable \\ not_deleted()) do
|
||||
select(queryable, [gateways: gateways], gateways)
|
||||
end
|
||||
|
||||
def with_joined_connections(queryable \\ all()) do
|
||||
def with_joined_connections(queryable \\ not_deleted()) do
|
||||
with_named_binding(queryable, :connections, fn queryable, binding ->
|
||||
queryable
|
||||
|> join(
|
||||
@@ -49,7 +53,7 @@ defmodule Domain.Gateways.Gateway.Query do
|
||||
end)
|
||||
end
|
||||
|
||||
def with_preloaded_user(queryable \\ all()) do
|
||||
def with_preloaded_user(queryable \\ not_deleted()) do
|
||||
with_named_binding(queryable, :user, fn queryable, binding ->
|
||||
queryable
|
||||
|> join(:inner, [gateways: gateways], user in assoc(gateways, ^binding), as: ^binding)
|
||||
|
||||
@@ -3,14 +3,18 @@ defmodule Domain.Gateways.Group.Query do
|
||||
|
||||
def all do
|
||||
from(groups in Domain.Gateways.Group, as: :groups)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
all()
|
||||
|> where([groups: groups], is_nil(groups.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id) do
|
||||
def by_id(queryable \\ not_deleted(), id) do
|
||||
where(queryable, [groups: groups], groups.id == ^id)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [groups: groups], groups.account_id == ^account_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
defmodule Domain.Gateways.Token.Query do
|
||||
use Domain, :query
|
||||
|
||||
def all do
|
||||
def not_deleted do
|
||||
from(token in Domain.Gateways.Token, as: :token)
|
||||
|> where([token: token], is_nil(token.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id) do
|
||||
def by_id(queryable \\ not_deleted(), id) do
|
||||
where(queryable, [token: token], token.id == ^id)
|
||||
end
|
||||
|
||||
def by_group_id(queryable \\ all(), group_id) do
|
||||
def by_group_id(queryable \\ not_deleted(), group_id) do
|
||||
where(queryable, [token: token], token.group_id == ^group_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,7 +15,8 @@ defmodule Domain.Policies do
|
||||
|
||||
with :ok <- Auth.ensure_has_permissions(subject, required_permissions),
|
||||
true <- Validator.valid_uuid?(id) do
|
||||
Policy.Query.by_id(id)
|
||||
Policy.Query.all()
|
||||
|> Policy.Query.by_id(id)
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.fetch()
|
||||
|> case do
|
||||
@@ -40,7 +41,7 @@ defmodule Domain.Policies do
|
||||
|
||||
with :ok <- Auth.ensure_has_permissions(subject, required_permissions) do
|
||||
{:ok, policies} =
|
||||
Policy.Query.all()
|
||||
Policy.Query.not_deleted()
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.list()
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ defmodule Domain.Policies.Policy do
|
||||
schema "policies" do
|
||||
field :description, :string
|
||||
|
||||
belongs_to :actor_group, Domain.Actors.Group, where: [deleted_at: nil]
|
||||
belongs_to :resource, Domain.Resources.Resource, where: [deleted_at: nil]
|
||||
belongs_to :actor_group, Domain.Actors.Group
|
||||
belongs_to :resource, Domain.Resources.Resource
|
||||
belongs_to :account, Domain.Accounts.Account
|
||||
|
||||
field :created_by, Ecto.Enum, values: ~w[identity]a
|
||||
|
||||
@@ -3,6 +3,10 @@ defmodule Domain.Policies.Policy.Query do
|
||||
|
||||
def all do
|
||||
from(policies in Domain.Policies.Policy, as: :policies)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
from(policies in Domain.Policies.Policy, as: :policies)
|
||||
|> where([policies: policies], is_nil(policies.deleted_at))
|
||||
|> with_joined_actor_group()
|
||||
|> where([actor_group: actor_group], is_nil(actor_group.deleted_at))
|
||||
@@ -10,29 +14,29 @@ defmodule Domain.Policies.Policy.Query do
|
||||
|> where([resource: resource], is_nil(resource.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id) do
|
||||
def by_id(queryable \\ not_deleted(), id) do
|
||||
where(queryable, [policies: policies], policies.id == ^id)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [policies: policies], policies.account_id == ^account_id)
|
||||
end
|
||||
|
||||
def by_resource_id(queryable \\ all(), resource_id) do
|
||||
def by_resource_id(queryable \\ not_deleted(), resource_id) do
|
||||
where(queryable, [policies: policies], policies.resource_id == ^resource_id)
|
||||
end
|
||||
|
||||
def by_resource_ids(queryable \\ all(), resource_ids) do
|
||||
def by_resource_ids(queryable \\ not_deleted(), resource_ids) do
|
||||
where(queryable, [policies: policies], policies.resource_id in ^resource_ids)
|
||||
end
|
||||
|
||||
def by_actor_id(queryable \\ all(), actor_id) do
|
||||
def by_actor_id(queryable \\ not_deleted(), actor_id) do
|
||||
queryable
|
||||
|> with_joined_memberships()
|
||||
|> where([memberships: memberships], memberships.actor_id == ^actor_id)
|
||||
end
|
||||
|
||||
def count_by_resource_id(queryable \\ all()) do
|
||||
def count_by_resource_id(queryable \\ not_deleted()) do
|
||||
queryable
|
||||
|> group_by([policies: policies], policies.resource_id)
|
||||
|> select([policies: policies], %{
|
||||
@@ -41,7 +45,7 @@ defmodule Domain.Policies.Policy.Query do
|
||||
})
|
||||
end
|
||||
|
||||
def with_joined_actor_group(queryable \\ all()) do
|
||||
def with_joined_actor_group(queryable \\ not_deleted()) do
|
||||
with_named_binding(queryable, :actor_group, fn queryable, binding ->
|
||||
join(queryable, :inner, [policies: policies], actor_group in assoc(policies, ^binding),
|
||||
as: ^binding
|
||||
@@ -49,7 +53,7 @@ defmodule Domain.Policies.Policy.Query do
|
||||
end)
|
||||
end
|
||||
|
||||
def with_joined_resource(queryable \\ all()) do
|
||||
def with_joined_resource(queryable \\ not_deleted()) do
|
||||
with_named_binding(queryable, :resource, fn queryable, binding ->
|
||||
join(queryable, :inner, [policies: policies], resource in assoc(policies, ^binding),
|
||||
as: ^binding
|
||||
@@ -57,7 +61,7 @@ defmodule Domain.Policies.Policy.Query do
|
||||
end)
|
||||
end
|
||||
|
||||
def with_joined_memberships(queryable \\ all()) do
|
||||
def with_joined_memberships(queryable \\ not_deleted()) do
|
||||
queryable
|
||||
|> with_joined_actor_group()
|
||||
|> with_named_binding(:memberships, fn queryable, binding ->
|
||||
|
||||
@@ -21,7 +21,8 @@ defmodule Domain.Relays do
|
||||
true <- Validator.valid_uuid?(id) do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
Group.Query.by_id(id)
|
||||
Group.Query.all()
|
||||
|> Group.Query.by_id(id)
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.fetch()
|
||||
|> case do
|
||||
@@ -47,7 +48,7 @@ defmodule Domain.Relays do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
{:ok, groups} =
|
||||
Group.Query.all()
|
||||
Group.Query.not_deleted()
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.list()
|
||||
|
||||
@@ -186,7 +187,8 @@ defmodule Domain.Relays do
|
||||
true <- Validator.valid_uuid?(id) do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
Relay.Query.by_id(id)
|
||||
Relay.Query.all()
|
||||
|> Relay.Query.by_id(id)
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.fetch()
|
||||
|> case do
|
||||
@@ -221,7 +223,7 @@ defmodule Domain.Relays do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
{:ok, relays} =
|
||||
Relay.Query.all()
|
||||
Relay.Query.not_deleted()
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.list()
|
||||
|
||||
|
||||
@@ -3,18 +3,22 @@ defmodule Domain.Relays.Group.Query do
|
||||
|
||||
def all do
|
||||
from(groups in Domain.Relays.Group, as: :groups)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
all()
|
||||
|> where([groups: groups], is_nil(groups.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id) do
|
||||
def by_id(queryable \\ not_deleted(), id) do
|
||||
where(queryable, [groups: groups], groups.id == ^id)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [groups: groups], groups.account_id == ^account_id)
|
||||
end
|
||||
|
||||
def global_or_by_account_id(queryable \\ all(), account_id) do
|
||||
def global_or_by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(
|
||||
queryable,
|
||||
[groups: groups],
|
||||
|
||||
@@ -3,26 +3,30 @@ defmodule Domain.Relays.Relay.Query do
|
||||
|
||||
def all do
|
||||
from(relays in Domain.Relays.Relay, as: :relays)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
all()
|
||||
|> where([relays: relays], is_nil(relays.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id) do
|
||||
def by_id(queryable \\ not_deleted(), id) do
|
||||
where(queryable, [relays: relays], relays.id == ^id)
|
||||
end
|
||||
|
||||
def by_ids(queryable \\ all(), ids) do
|
||||
def by_ids(queryable \\ not_deleted(), ids) do
|
||||
where(queryable, [relays: relays], relays.id in ^ids)
|
||||
end
|
||||
|
||||
def by_user_id(queryable \\ all(), user_id) do
|
||||
def by_user_id(queryable \\ not_deleted(), user_id) do
|
||||
where(queryable, [relays: relays], relays.user_id == ^user_id)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [relays: relays], relays.account_id == ^account_id)
|
||||
end
|
||||
|
||||
def public(queryable \\ all()) do
|
||||
def public(queryable \\ not_deleted()) do
|
||||
where(
|
||||
queryable,
|
||||
[relays: relays],
|
||||
@@ -30,7 +34,7 @@ defmodule Domain.Relays.Relay.Query do
|
||||
)
|
||||
end
|
||||
|
||||
def public_or_by_account_id(queryable \\ all(), account_id) do
|
||||
def public_or_by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(
|
||||
queryable,
|
||||
[relays: relays],
|
||||
@@ -38,7 +42,7 @@ defmodule Domain.Relays.Relay.Query do
|
||||
)
|
||||
end
|
||||
|
||||
def global_or_by_account_id(queryable \\ all(), account_id) do
|
||||
def global_or_by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(
|
||||
queryable,
|
||||
[relays: relays],
|
||||
@@ -46,11 +50,11 @@ defmodule Domain.Relays.Relay.Query do
|
||||
)
|
||||
end
|
||||
|
||||
def returning_all(queryable \\ all()) do
|
||||
def returning_not_deleted(queryable \\ not_deleted()) do
|
||||
select(queryable, [relays: relays], relays)
|
||||
end
|
||||
|
||||
def with_preloaded_user(queryable \\ all()) do
|
||||
def with_preloaded_user(queryable \\ not_deleted()) do
|
||||
with_named_binding(queryable, :user, fn queryable, binding ->
|
||||
queryable
|
||||
|> join(:inner, [relays: relays], user in assoc(relays, ^binding), as: ^binding)
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
defmodule Domain.Relays.Token.Query do
|
||||
use Domain, :query
|
||||
|
||||
def all do
|
||||
def not_deleted do
|
||||
from(token in Domain.Relays.Token, as: :token)
|
||||
|> where([token: token], is_nil(token.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id) do
|
||||
def by_id(queryable \\ not_deleted(), id) do
|
||||
where(queryable, [token: token], token.id == ^id)
|
||||
end
|
||||
|
||||
def by_group_id(queryable \\ all(), group_id) do
|
||||
def by_group_id(queryable \\ not_deleted(), group_id) do
|
||||
where(queryable, [token: token], token.group_id == ^group_id)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,7 +15,8 @@ defmodule Domain.Resources do
|
||||
|
||||
with :ok <- Auth.ensure_has_permissions(subject, required_permissions),
|
||||
true <- Validator.valid_uuid?(id) do
|
||||
Resource.Query.by_id(id)
|
||||
Resource.Query.all()
|
||||
|> Resource.Query.by_id(id)
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.fetch()
|
||||
|> case do
|
||||
@@ -77,7 +78,7 @@ defmodule Domain.Resources do
|
||||
{preload, _opts} = Keyword.pop(opts, :preload, [])
|
||||
|
||||
{:ok, resources} =
|
||||
Resource.Query.all()
|
||||
Resource.Query.not_deleted()
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Repo.list()
|
||||
|
||||
@@ -95,7 +96,7 @@ defmodule Domain.Resources do
|
||||
|
||||
with :ok <- Auth.ensure_has_permissions(subject, required_permissions) do
|
||||
count =
|
||||
Resource.Query.all()
|
||||
Resource.Query.not_deleted()
|
||||
|> Authorizer.for_subject(subject)
|
||||
|> Resource.Query.by_gateway_group_id(gateway.group_id)
|
||||
|> Repo.aggregate(:count)
|
||||
@@ -114,7 +115,7 @@ defmodule Domain.Resources do
|
||||
|
||||
with :ok <- Auth.ensure_has_permissions(subject, required_permissions) do
|
||||
resources =
|
||||
Resource.Query.all()
|
||||
Resource.Query.not_deleted()
|
||||
|> Resource.Query.by_account_id(subject.account.id)
|
||||
|> Resource.Query.by_gateway_group_id(gateway.group_id)
|
||||
|> Repo.all()
|
||||
|
||||
@@ -3,10 +3,14 @@ defmodule Domain.Resources.Resource.Query do
|
||||
|
||||
def all do
|
||||
from(resources in Domain.Resources.Resource, as: :resources)
|
||||
end
|
||||
|
||||
def not_deleted do
|
||||
all()
|
||||
|> where([resources: resources], is_nil(resources.deleted_at))
|
||||
end
|
||||
|
||||
def by_id(queryable \\ all(), id)
|
||||
def by_id(queryable \\ not_deleted(), id)
|
||||
|
||||
def by_id(queryable, {:in, ids}) do
|
||||
where(queryable, [resources: resources], resources.id in ^ids)
|
||||
@@ -16,11 +20,11 @@ defmodule Domain.Resources.Resource.Query do
|
||||
where(queryable, [resources: resources], resources.id == ^id)
|
||||
end
|
||||
|
||||
def by_account_id(queryable \\ all(), account_id) do
|
||||
def by_account_id(queryable \\ not_deleted(), account_id) do
|
||||
where(queryable, [resources: resources], resources.account_id == ^account_id)
|
||||
end
|
||||
|
||||
def by_authorized_actor_id(queryable \\ all(), actor_id) do
|
||||
def by_authorized_actor_id(queryable \\ not_deleted(), actor_id) do
|
||||
subquery = Domain.Policies.Policy.Query.by_actor_id(actor_id)
|
||||
|
||||
queryable
|
||||
@@ -37,7 +41,7 @@ defmodule Domain.Resources.Resource.Query do
|
||||
|> select_merge([authorized_by_policies: policies], %{authorized_by_policy: policies})
|
||||
end
|
||||
|
||||
def preload_few_actor_groups_for_each_resource(queryable \\ all(), limit) do
|
||||
def preload_few_actor_groups_for_each_resource(queryable \\ not_deleted(), limit) do
|
||||
queryable
|
||||
|> with_joined_actor_groups(limit)
|
||||
|> with_joined_policies_counts()
|
||||
@@ -53,13 +57,13 @@ defmodule Domain.Resources.Resource.Query do
|
||||
|
||||
def with_joined_actor_groups(queryable, limit) do
|
||||
policies_subquery =
|
||||
Domain.Policies.Policy.Query.all()
|
||||
Domain.Policies.Policy.Query.not_deleted()
|
||||
|> where([policies: policies], policies.resource_id == parent_as(:resources).id)
|
||||
|> select([policies: policies], policies.actor_group_id)
|
||||
|> limit(^limit)
|
||||
|
||||
actor_groups_subquery =
|
||||
Domain.Actors.Group.Query.all()
|
||||
Domain.Actors.Group.Query.not_deleted()
|
||||
|> where([groups: groups], groups.id in subquery(policies_subquery))
|
||||
|
||||
join(
|
||||
@@ -81,13 +85,13 @@ defmodule Domain.Resources.Resource.Query do
|
||||
)
|
||||
end
|
||||
|
||||
def by_gateway_group_id(queryable \\ all(), gateway_group_id) do
|
||||
def by_gateway_group_id(queryable \\ not_deleted(), gateway_group_id) do
|
||||
queryable
|
||||
|> with_joined_connections()
|
||||
|> where([connections: connections], connections.gateway_group_id == ^gateway_group_id)
|
||||
end
|
||||
|
||||
def with_joined_connections(queryable \\ all()) do
|
||||
def with_joined_connections(queryable \\ not_deleted()) do
|
||||
with_named_binding(queryable, :connections, fn queryable, binding ->
|
||||
queryable
|
||||
|> join(
|
||||
|
||||
@@ -30,7 +30,7 @@ defmodule Domain.ActorsTest do
|
||||
assert fetch_group_by_id(group.id, subject) == {:error, :not_found}
|
||||
end
|
||||
|
||||
test "does not return deleted groups", %{
|
||||
test "returns deleted groups", %{
|
||||
account: account,
|
||||
subject: subject
|
||||
} do
|
||||
@@ -38,7 +38,8 @@ defmodule Domain.ActorsTest do
|
||||
Fixtures.Actors.create_group(account: account)
|
||||
|> Fixtures.Actors.delete_group()
|
||||
|
||||
assert fetch_group_by_id(group.id, subject) == {:error, :not_found}
|
||||
assert {:ok, fetched_group} = fetch_group_by_id(group.id, subject)
|
||||
assert fetched_group.id == group.id
|
||||
end
|
||||
|
||||
test "returns group by id", %{account: account, subject: subject} do
|
||||
@@ -497,7 +498,7 @@ defmodule Domain.ActorsTest do
|
||||
|
||||
assert Enum.all?(["G:GROUP_ID1", "OU:OU_ID1"], &(&1 in delete))
|
||||
assert Repo.aggregate(Actors.Group, :count) == 2
|
||||
assert Repo.aggregate(Actors.Group.Query.all(), :count) == 0
|
||||
assert Repo.aggregate(Actors.Group.Query.not_deleted(), :count) == 0
|
||||
|
||||
assert Enum.empty?(group_ids_by_provider_identifier)
|
||||
end
|
||||
@@ -1871,8 +1872,8 @@ defmodule Domain.ActorsTest do
|
||||
assert {:ok, actor} = delete_actor(actor_to_delete, subject)
|
||||
assert actor.deleted_at
|
||||
|
||||
assert Repo.aggregate(Domain.Clients.Client.Query.all(), :count) == 0
|
||||
assert Repo.aggregate(Domain.Auth.Identity.Query.all(), :count) == 1
|
||||
assert Repo.aggregate(Domain.Clients.Client.Query.not_deleted(), :count) == 0
|
||||
assert Repo.aggregate(Domain.Auth.Identity.Query.not_deleted(), :count) == 1
|
||||
end
|
||||
|
||||
test "returns error when trying to delete the last admin actor" do
|
||||
|
||||
@@ -1258,7 +1258,7 @@ defmodule Domain.AuthTest do
|
||||
|
||||
assert Enum.all?(provider_identifiers, &(&1 in delete))
|
||||
assert Repo.aggregate(Auth.Identity, :count) == 2
|
||||
assert Repo.aggregate(Auth.Identity.Query.all(), :count) == 0
|
||||
assert Repo.aggregate(Auth.Identity.Query.not_deleted(), :count) == 0
|
||||
|
||||
assert Enum.empty?(actor_ids_by_provider_identifier)
|
||||
end
|
||||
@@ -1798,7 +1798,7 @@ defmodule Domain.AuthTest do
|
||||
|
||||
assert Repo.aggregate(Auth.Identity.Query.all(), :count) == 3
|
||||
assert delete_actor_identities(actor) == :ok
|
||||
assert Repo.aggregate(Auth.Identity.Query.all(), :count) == 0
|
||||
assert Repo.aggregate(Auth.Identity.Query.not_deleted(), :count) == 0
|
||||
end
|
||||
|
||||
test "does not remove identities that belong to another actor", %{
|
||||
|
||||
@@ -55,7 +55,7 @@ defmodule Domain.ClientsTest do
|
||||
assert fetch_client_by_id("foo", subject) == {:error, :not_found}
|
||||
end
|
||||
|
||||
test "does not return deleted clients", %{
|
||||
test "returns deleted clients", %{
|
||||
unprivileged_actor: actor,
|
||||
unprivileged_subject: subject
|
||||
} do
|
||||
@@ -63,7 +63,7 @@ defmodule Domain.ClientsTest do
|
||||
Fixtures.Clients.create_client(actor: actor)
|
||||
|> Fixtures.Clients.delete_client()
|
||||
|
||||
assert fetch_client_by_id(client.id, subject) == {:error, :not_found}
|
||||
assert {:ok, _client} = fetch_client_by_id(client.id, subject)
|
||||
end
|
||||
|
||||
test "returns client by id", %{unprivileged_actor: actor, unprivileged_subject: subject} do
|
||||
@@ -702,9 +702,9 @@ defmodule Domain.ClientsTest do
|
||||
Fixtures.Clients.create_client(actor: actor)
|
||||
Fixtures.Clients.create_client(actor: actor)
|
||||
|
||||
assert Repo.aggregate(Clients.Client.Query.all(), :count) == 3
|
||||
assert Repo.aggregate(Clients.Client.Query.not_deleted(), :count) == 3
|
||||
assert delete_actor_clients(actor) == :ok
|
||||
assert Repo.aggregate(Clients.Client.Query.all(), :count) == 0
|
||||
assert Repo.aggregate(Clients.Client.Query.not_deleted(), :count) == 0
|
||||
end
|
||||
|
||||
test "does not remove clients that belong to another actor" do
|
||||
|
||||
@@ -29,7 +29,7 @@ defmodule Domain.GatewaysTest do
|
||||
assert fetch_group_by_id(group.id, subject) == {:error, :not_found}
|
||||
end
|
||||
|
||||
test "does not return deleted groups", %{
|
||||
test "returns deleted groups", %{
|
||||
account: account,
|
||||
subject: subject
|
||||
} do
|
||||
@@ -37,7 +37,8 @@ defmodule Domain.GatewaysTest do
|
||||
Fixtures.Gateways.create_group(account: account)
|
||||
|> Fixtures.Gateways.delete_group()
|
||||
|
||||
assert fetch_group_by_id(group.id, subject) == {:error, :not_found}
|
||||
assert {:ok, fetched_group} = fetch_group_by_id(group.id, subject)
|
||||
assert fetched_group.id == group.id
|
||||
end
|
||||
|
||||
test "returns group by id", %{account: account, subject: subject} do
|
||||
@@ -387,7 +388,7 @@ defmodule Domain.GatewaysTest do
|
||||
assert fetch_gateway_by_id(gateway.id, subject) == {:error, :not_found}
|
||||
end
|
||||
|
||||
test "does not return deleted gateways", %{
|
||||
test "returns deleted gateways", %{
|
||||
account: account,
|
||||
subject: subject
|
||||
} do
|
||||
@@ -395,7 +396,7 @@ defmodule Domain.GatewaysTest do
|
||||
Fixtures.Gateways.create_gateway(account: account)
|
||||
|> Fixtures.Gateways.delete_gateway()
|
||||
|
||||
assert fetch_gateway_by_id(gateway.id, subject) == {:error, :not_found}
|
||||
assert fetch_gateway_by_id(gateway.id, subject) == {:ok, gateway}
|
||||
end
|
||||
|
||||
test "returns gateway by id", %{account: account, subject: subject} do
|
||||
|
||||
@@ -34,12 +34,13 @@ defmodule Domain.PoliciesTest do
|
||||
assert fetched_policy.id == policy.id
|
||||
end
|
||||
|
||||
test "does not return deleted policy", %{account: account, subject: subject} do
|
||||
test "returns deleted policies", %{account: account, subject: subject} do
|
||||
{:ok, policy} =
|
||||
Fixtures.Policies.create_policy(account: account)
|
||||
|> delete_policy(subject)
|
||||
|
||||
assert fetch_policy_by_id(policy.id, subject) == {:error, :not_found}
|
||||
assert {:ok, fetched_policy} = fetch_policy_by_id(policy.id, subject)
|
||||
assert fetched_policy.id == policy.id
|
||||
end
|
||||
|
||||
test "does not return policies in other accounts", %{subject: subject} do
|
||||
|
||||
@@ -29,7 +29,7 @@ defmodule Domain.RelaysTest do
|
||||
assert fetch_group_by_id(group.id, subject) == {:error, :not_found}
|
||||
end
|
||||
|
||||
test "does not return deleted groups", %{
|
||||
test "returns deleted groups", %{
|
||||
account: account,
|
||||
subject: subject
|
||||
} do
|
||||
@@ -37,7 +37,8 @@ defmodule Domain.RelaysTest do
|
||||
Fixtures.Relays.create_group(account: account)
|
||||
|> Fixtures.Relays.delete_group()
|
||||
|
||||
assert fetch_group_by_id(group.id, subject) == {:error, :not_found}
|
||||
assert {:ok, fetched_group} = fetch_group_by_id(group.id, subject)
|
||||
assert fetched_group.id == group.id
|
||||
end
|
||||
|
||||
test "returns group by id", %{account: account, subject: subject} do
|
||||
@@ -409,7 +410,7 @@ defmodule Domain.RelaysTest do
|
||||
assert fetch_relay_by_id(relay.id, subject) == {:error, :not_found}
|
||||
end
|
||||
|
||||
test "does not return deleted relays", %{
|
||||
test "returns deleted relays", %{
|
||||
account: account,
|
||||
subject: subject
|
||||
} do
|
||||
@@ -417,7 +418,7 @@ defmodule Domain.RelaysTest do
|
||||
Fixtures.Relays.create_relay(account: account)
|
||||
|> Fixtures.Relays.delete_relay()
|
||||
|
||||
assert fetch_relay_by_id(relay.id, subject) == {:error, :not_found}
|
||||
assert {:ok, _relay} = fetch_relay_by_id(relay.id, subject)
|
||||
end
|
||||
|
||||
test "returns relay by id", %{account: account, subject: subject} do
|
||||
|
||||
@@ -60,12 +60,12 @@ defmodule Domain.ResourcesTest do
|
||||
refute is_nil(fetched_resource.authorized_by_policy)
|
||||
end
|
||||
|
||||
test "does not return deleted resources", %{account: account, subject: subject} do
|
||||
test "returns deleted resources", %{account: account, subject: subject} do
|
||||
{:ok, resource} =
|
||||
Fixtures.Resources.create_resource(account: account)
|
||||
|> delete_resource(subject)
|
||||
|
||||
assert fetch_resource_by_id(resource.id, subject) == {:error, :not_found}
|
||||
assert {:ok, _resource} = fetch_resource_by_id(resource.id, subject)
|
||||
end
|
||||
|
||||
test "does not return resources in other accounts", %{subject: subject} do
|
||||
|
||||
@@ -6,6 +6,7 @@ defmodule Web.Actors.Edit do
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
with {:ok, actor} <-
|
||||
Actors.fetch_actor_by_id(id, socket.assigns.subject, preload: [:memberships]),
|
||||
nil <- actor.deleted_at,
|
||||
{:ok, groups} <- Actors.list_groups(socket.assigns.subject) do
|
||||
changeset = Actors.change_actor(actor)
|
||||
|
||||
@@ -19,7 +20,7 @@ defmodule Web.Actors.Edit do
|
||||
page_title: "Edit actor #{actor.name}"
|
||||
]}
|
||||
else
|
||||
{:error, _reason} -> raise Web.LiveErrors.NotFoundError
|
||||
_other -> raise Web.LiveErrors.NotFoundError
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ defmodule Web.Actors.Show do
|
||||
flow_activities_enabled?: Domain.Config.flow_activities_enabled?()
|
||||
)}
|
||||
else
|
||||
{:error, _reason} -> raise Web.LiveErrors.NotFoundError
|
||||
_other -> raise Web.LiveErrors.NotFoundError
|
||||
end
|
||||
end
|
||||
|
||||
@@ -42,8 +42,9 @@ defmodule Web.Actors.Show do
|
||||
<:title>
|
||||
<%= actor_type(@actor.type) %>: <span class="font-bold"><%= @actor.name %></span>
|
||||
<span :if={@actor.id == @subject.actor.id} class="text-gray-400">(you)</span>
|
||||
<span :if={not is_nil(@actor.deleted_at)} class="text-red-600">(deleted)</span>
|
||||
</:title>
|
||||
<:action>
|
||||
<:action :if={is_nil(@actor.deleted_at)}>
|
||||
<.edit_button navigate={~p"/#{@account}/actors/#{@actor}/edit"}>
|
||||
Edit <%= actor_type(@actor.type) %>
|
||||
</.edit_button>
|
||||
@@ -90,7 +91,7 @@ defmodule Web.Actors.Show do
|
||||
|
||||
<.section>
|
||||
<:title>Authentication Identities</:title>
|
||||
<:action>
|
||||
<:action :if={is_nil(@actor.deleted_at)}>
|
||||
<.add_button
|
||||
:if={@actor.type == :service_account}
|
||||
navigate={~p"/#{@account}/actors/service_accounts/#{@actor}/new_identity"}
|
||||
@@ -98,7 +99,7 @@ defmodule Web.Actors.Show do
|
||||
Create Token
|
||||
</.add_button>
|
||||
</:action>
|
||||
<:action>
|
||||
<:action :if={is_nil(@actor.deleted_at)}>
|
||||
<.add_button
|
||||
:if={@actor.type != :service_account}
|
||||
navigate={~p"/#{@account}/actors/users/#{@actor}/new_identity"}
|
||||
@@ -139,13 +140,13 @@ defmodule Web.Actors.Show do
|
||||
No authentication identities to display
|
||||
</div>
|
||||
<.add_button
|
||||
:if={@actor.type == :service_account}
|
||||
:if={is_nil(@actor.deleted_at) and @actor.type == :service_account}
|
||||
navigate={~p"/#{@account}/actors/service_accounts/#{@actor}/new_identity"}
|
||||
>
|
||||
Create Token
|
||||
</.add_button>
|
||||
<.add_button
|
||||
:if={@actor.type != :service_account}
|
||||
:if={is_nil(@actor.deleted_at) and @actor.type != :service_account}
|
||||
navigate={~p"/#{@account}/actors/users/#{@actor}/new_identity"}
|
||||
>
|
||||
Create Identity
|
||||
@@ -175,9 +176,6 @@ defmodule Web.Actors.Show do
|
||||
</:col>
|
||||
<:empty>
|
||||
<div class="text-center text-slate-500 p-4">No clients to display</div>
|
||||
<div class="text-center text-slate-500 mb-4">
|
||||
Clients are created automatically when user connects to a resource.
|
||||
</div>
|
||||
</:empty>
|
||||
</.table>
|
||||
</:content>
|
||||
@@ -231,7 +229,7 @@ defmodule Web.Actors.Show do
|
||||
</:content>
|
||||
</.section>
|
||||
|
||||
<.danger_zone>
|
||||
<.danger_zone :if={is_nil(@actor.deleted_at)}>
|
||||
<:action>
|
||||
<.delete_button
|
||||
:if={not Actors.actor_synced?(@actor)}
|
||||
|
||||
@@ -3,11 +3,12 @@ defmodule Web.Clients.Edit do
|
||||
alias Domain.Clients
|
||||
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
with {:ok, client} <- Clients.fetch_client_by_id(id, socket.assigns.subject) do
|
||||
with {:ok, client} <- Clients.fetch_client_by_id(id, socket.assigns.subject),
|
||||
nil <- client.deleted_at do
|
||||
changeset = Clients.change_client(client)
|
||||
{:ok, assign(socket, client: client, form: to_form(changeset))}
|
||||
else
|
||||
{:error, _reason} -> raise Web.LiveErrors.NotFoundError
|
||||
_other -> raise Web.LiveErrors.NotFoundError
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -37,8 +37,9 @@ defmodule Web.Clients.Show do
|
||||
<.section>
|
||||
<:title>
|
||||
Client Details
|
||||
<span :if={not is_nil(@client.deleted_at)} class="text-red-600">(deleted)</span>
|
||||
</:title>
|
||||
<:action>
|
||||
<:action :if={is_nil(@client.deleted_at)}>
|
||||
<.edit_button navigate={~p"/#{@account}/clients/#{@client}/edit"}>
|
||||
Edit Client
|
||||
</.edit_button>
|
||||
@@ -143,7 +144,7 @@ defmodule Web.Clients.Show do
|
||||
</:content>
|
||||
</.section>
|
||||
|
||||
<.danger_zone>
|
||||
<.danger_zone :if={is_nil(@client.deleted_at)}>
|
||||
<:action>
|
||||
<.delete_button
|
||||
phx-click="delete"
|
||||
|
||||
@@ -36,6 +36,7 @@ defmodule Web.Gateways.Show do
|
||||
<.section>
|
||||
<:title>
|
||||
Gateway: <code><%= @gateway.name %></code>
|
||||
<span :if={not is_nil(@gateway.deleted_at)} class="text-red-600">(deleted)</span>
|
||||
</:title>
|
||||
<:content>
|
||||
<.vertical_table id="gateway">
|
||||
@@ -102,7 +103,7 @@ defmodule Web.Gateways.Show do
|
||||
</:content>
|
||||
</.section>
|
||||
|
||||
<.danger_zone>
|
||||
<.danger_zone :if={is_nil(@gateway.deleted_at)}>
|
||||
<:action>
|
||||
<.delete_button
|
||||
phx-click="delete"
|
||||
|
||||
@@ -5,6 +5,7 @@ defmodule Web.Groups.Edit do
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
with {:ok, group} <-
|
||||
Actors.fetch_group_by_id(id, socket.assigns.subject, preload: [:memberships]),
|
||||
nil <- group.deleted_at,
|
||||
false <- Actors.group_synced?(group) do
|
||||
changeset = Actors.change_group(group)
|
||||
{:ok, assign(socket, group: group, form: to_form(changeset))}
|
||||
|
||||
@@ -6,6 +6,7 @@ defmodule Web.Groups.EditActors do
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
with {:ok, group} <-
|
||||
Actors.fetch_group_by_id(id, socket.assigns.subject, preload: [:memberships]),
|
||||
nil <- group.deleted_at,
|
||||
false <- Actors.group_synced?(group),
|
||||
{:ok, actors} <-
|
||||
Actors.list_actors(socket.assigns.subject, preload: [identities: :provider]) do
|
||||
|
||||
@@ -31,8 +31,9 @@ defmodule Web.Groups.Show do
|
||||
<.section>
|
||||
<:title>
|
||||
Group: <code><%= @group.name %></code>
|
||||
<span :if={not is_nil(@group.deleted_at)} class="text-red-600">(deleted)</span>
|
||||
</:title>
|
||||
<:action>
|
||||
<:action :if={is_nil(@group.deleted_at)}>
|
||||
<.edit_button
|
||||
:if={not Actors.group_synced?(@group)}
|
||||
navigate={~p"/#{@account}/groups/#{@group}/edit"}
|
||||
@@ -58,7 +59,7 @@ defmodule Web.Groups.Show do
|
||||
|
||||
<.section>
|
||||
<:title>Actors</:title>
|
||||
<:action>
|
||||
<:action :if={is_nil(@group.deleted_at)}>
|
||||
<.edit_button
|
||||
:if={not Actors.group_synced?(@group)}
|
||||
navigate={~p"/#{@account}/groups/#{@group}/edit_actors"}
|
||||
@@ -85,7 +86,7 @@ defmodule Web.Groups.Show do
|
||||
No actors in group
|
||||
</div>
|
||||
<.edit_button
|
||||
:if={not Actors.group_synced?(@group)}
|
||||
:if={is_nil(@group.deleted_at)}
|
||||
navigate={~p"/#{@account}/groups/#{@group}/edit"}
|
||||
>
|
||||
Edit Group
|
||||
@@ -100,7 +101,7 @@ defmodule Web.Groups.Show do
|
||||
</:content>
|
||||
</.section>
|
||||
|
||||
<.danger_zone>
|
||||
<.danger_zone :if={is_nil(@group.deleted_at)}>
|
||||
<:action>
|
||||
<.delete_button
|
||||
phx-click="delete"
|
||||
|
||||
@@ -7,7 +7,8 @@ defmodule Web.Policies.Edit do
|
||||
with {:ok, policy} <-
|
||||
Policies.fetch_policy_by_id(id, socket.assigns.subject,
|
||||
preload: [:actor_group, :resource]
|
||||
) do
|
||||
),
|
||||
nil <- policy.deleted_at do
|
||||
form = to_form(Policies.Policy.Changeset.update(policy, %{}))
|
||||
socket = assign(socket, policy: policy, page_title: "Edit Policy", form: form)
|
||||
{:ok, socket, temporary_assigns: [form: %Phoenix.HTML.Form{}]}
|
||||
|
||||
@@ -38,8 +38,9 @@ defmodule Web.Policies.Show do
|
||||
<.section>
|
||||
<:title>
|
||||
<%= @page_title %>: <code><%= @policy.id %></code>
|
||||
<span :if={not is_nil(@policy.deleted_at)} class="text-red-600">(deleted)</span>
|
||||
</:title>
|
||||
<:action>
|
||||
<:action :if={is_nil(@policy.deleted_at)}>
|
||||
<.edit_button navigate={~p"/#{@account}/policies/#{@policy}/edit"}>
|
||||
Edit Policy
|
||||
</.edit_button>
|
||||
@@ -62,6 +63,9 @@ defmodule Web.Policies.Show do
|
||||
<.link navigate={~p"/#{@account}/groups/#{@policy.actor_group_id}"} class={link_style()}>
|
||||
<%= @policy.actor_group.name %>
|
||||
</.link>
|
||||
<span :if={not is_nil(@policy.actor_group.deleted_at)} class="text-red-600">
|
||||
(deleted)
|
||||
</span>
|
||||
</:value>
|
||||
</.vertical_table_row>
|
||||
<.vertical_table_row>
|
||||
@@ -72,6 +76,9 @@ defmodule Web.Policies.Show do
|
||||
<.link navigate={~p"/#{@account}/resources/#{@policy.resource_id}"} class={link_style()}>
|
||||
<%= @policy.resource.name %>
|
||||
</.link>
|
||||
<span :if={not is_nil(@policy.resource.deleted_at)} class="text-red-600">
|
||||
(deleted)
|
||||
</span>
|
||||
</:value>
|
||||
</.vertical_table_row>
|
||||
<.vertical_table_row>
|
||||
@@ -140,7 +147,7 @@ defmodule Web.Policies.Show do
|
||||
</:content>
|
||||
</.section>
|
||||
|
||||
<.danger_zone>
|
||||
<.danger_zone :if={is_nil(@policy.deleted_at)}>
|
||||
<:action>
|
||||
<.delete_button
|
||||
phx-click="delete"
|
||||
|
||||
@@ -4,7 +4,8 @@ defmodule Web.RelayGroups.Edit do
|
||||
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
with true <- Domain.Config.self_hosted_relays_enabled?(),
|
||||
{:ok, group} <- Relays.fetch_group_by_id(id, socket.assigns.subject) do
|
||||
{:ok, group} <- Relays.fetch_group_by_id(id, socket.assigns.subject),
|
||||
nil <- group.deleted_at do
|
||||
changeset = Relays.change_group(group)
|
||||
{:ok, assign(socket, group: group, form: to_form(changeset))}
|
||||
else
|
||||
|
||||
@@ -30,8 +30,9 @@ defmodule Web.RelayGroups.Show do
|
||||
<.section>
|
||||
<:title>
|
||||
Relay Instance Group: <code><%= @group.name %></code>
|
||||
<span :if={not is_nil(@group.deleted_at)} class="text-red-600">(deleted)</span>
|
||||
</:title>
|
||||
<:action :if={@group.account_id}>
|
||||
<:action :if={not is_nil(@group.account_id) and is_nil(@group.deleted_at)}>
|
||||
<.edit_button navigate={~p"/#{@account}/relay_groups/#{@group}/edit"}>
|
||||
Edit Instance Group
|
||||
</.edit_button>
|
||||
@@ -56,7 +57,7 @@ defmodule Web.RelayGroups.Show do
|
||||
|
||||
<.section>
|
||||
<:title>Relays</:title>
|
||||
<:action>
|
||||
<:action :if={not is_nil(@group.account_id) and is_nil(@group.deleted_at)}>
|
||||
<.add_button navigate={~p"/#{@account}/relay_groups/#{@group}/new_token"}>
|
||||
Deploy
|
||||
</.add_button>
|
||||
@@ -94,7 +95,7 @@ defmodule Web.RelayGroups.Show do
|
||||
</:content>
|
||||
</.section>
|
||||
|
||||
<.danger_zone>
|
||||
<.danger_zone :if={not is_nil(@group.account_id) and is_nil(@group.deleted_at)}>
|
||||
<:action :if={@group.account_id}>
|
||||
<.delete_button
|
||||
phx-click="delete"
|
||||
|
||||
@@ -43,6 +43,7 @@ defmodule Web.Relays.Show do
|
||||
<code><%= @relay.ipv4 %></code>
|
||||
</:item>
|
||||
</.intersperse_blocks>
|
||||
<span :if={not is_nil(@relay.deleted_at)} class="text-red-600">(deleted)</span>
|
||||
</:title>
|
||||
<:content>
|
||||
<div class="bg-white overflow-hidden">
|
||||
@@ -112,9 +113,9 @@ defmodule Web.Relays.Show do
|
||||
</:content>
|
||||
</.section>
|
||||
|
||||
<.danger_zone>
|
||||
<.danger_zone :if={is_nil(@relay.deleted_at)}>
|
||||
<:action :if={@relay.account_id}>
|
||||
<.delete_button phx-click="delete">
|
||||
<.delete_button phx-click="delete" data-confirm="Are you sure you want to delete this relay?">
|
||||
Delete Relay
|
||||
</.delete_button>
|
||||
</:action>
|
||||
|
||||
@@ -6,6 +6,7 @@ defmodule Web.Resources.Edit do
|
||||
def mount(%{"id" => id} = params, _session, socket) do
|
||||
with {:ok, resource} <-
|
||||
Resources.fetch_resource_by_id(id, socket.assigns.subject, preload: :gateway_groups),
|
||||
nil <- resource.deleted_at,
|
||||
{:ok, gateway_groups} <- Gateways.list_groups(socket.assigns.subject) do
|
||||
form = Resources.change_resource(resource, socket.assigns.subject) |> to_form()
|
||||
|
||||
|
||||
@@ -41,8 +41,9 @@ defmodule Web.Resources.Show do
|
||||
<.section>
|
||||
<:title>
|
||||
Resource: <code><%= @resource.name %></code>
|
||||
<span :if={not is_nil(@resource.deleted_at)} class="text-red-600">(deleted)</span>
|
||||
</:title>
|
||||
<:action>
|
||||
<:action :if={is_nil(@resource.deleted_at)}>
|
||||
<.edit_button navigate={~p"/#{@account}/resources/#{@resource.id}/edit?#{@params}"}>
|
||||
Edit Resource
|
||||
</.edit_button>
|
||||
@@ -232,7 +233,7 @@ defmodule Web.Resources.Show do
|
||||
</:content>
|
||||
</.section>
|
||||
|
||||
<.danger_zone>
|
||||
<.danger_zone :if={is_nil(@resource.deleted_at)}>
|
||||
<:action>
|
||||
<.delete_button
|
||||
data-confirm="Are you sure want to delete this resource?"
|
||||
|
||||
@@ -4,11 +4,12 @@ defmodule Web.Sites.Edit do
|
||||
alias Domain.Gateways
|
||||
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
with {:ok, group} <- Gateways.fetch_group_by_id(id, socket.assigns.subject) do
|
||||
with {:ok, group} <- Gateways.fetch_group_by_id(id, socket.assigns.subject),
|
||||
nil <- group.deleted_at do
|
||||
changeset = Gateways.change_group(group)
|
||||
{:ok, assign(socket, group: group, form: to_form(changeset))}
|
||||
else
|
||||
{:error, _reason} -> raise Web.LiveErrors.NotFoundError
|
||||
_other -> raise Web.LiveErrors.NotFoundError
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -46,8 +46,9 @@ defmodule Web.Sites.Show do
|
||||
<.section>
|
||||
<:title>
|
||||
Site: <code><%= @group.name %></code>
|
||||
<span :if={not is_nil(@group.deleted_at)} class="text-red-600">(deleted)</span>
|
||||
</:title>
|
||||
<:action>
|
||||
<:action :if={is_nil(@group.deleted_at)}>
|
||||
<.edit_button navigate={~p"/#{@account}/sites/#{@group}/edit"}>
|
||||
Edit Site
|
||||
</.edit_button>
|
||||
@@ -80,7 +81,7 @@ defmodule Web.Sites.Show do
|
||||
see all <.icon name="hero-arrow-right" class="w-2 h-2" />
|
||||
</.link>
|
||||
</:title>
|
||||
<:action>
|
||||
<:action :if={is_nil(@group.deleted_at)}>
|
||||
<.add_button navigate={~p"/#{@account}/sites/#{@group}/new_token"}>
|
||||
Deploy
|
||||
</.add_button>
|
||||
@@ -112,12 +113,12 @@ defmodule Web.Sites.Show do
|
||||
<div class="pb-4">
|
||||
No gateways to display.
|
||||
</div>
|
||||
<div class="pb-4">
|
||||
<div :if={is_nil(@group.deleted_at)} class="pb-4">
|
||||
<.add_button navigate={~p"/#{@account}/sites/#{@group}/new_token"}>
|
||||
Deploy a Gateway
|
||||
</.add_button>
|
||||
</div>
|
||||
<div>
|
||||
<div :if={is_nil(@group.deleted_at)}>
|
||||
<p>
|
||||
Deploy gateways to terminate connections to your site's resources. All gateways deployed within a site must be able to reach all its resources.
|
||||
</p>
|
||||
@@ -133,7 +134,7 @@ defmodule Web.Sites.Show do
|
||||
<:title>
|
||||
Resources
|
||||
</:title>
|
||||
<:action>
|
||||
<:action :if={is_nil(@group.deleted_at)}>
|
||||
<.add_button navigate={~p"/#{@account}/resources/new?site_id=#{@group}"}>
|
||||
Create
|
||||
</.add_button>
|
||||
@@ -212,7 +213,7 @@ defmodule Web.Sites.Show do
|
||||
</:content>
|
||||
</.section>
|
||||
|
||||
<.danger_zone>
|
||||
<.danger_zone :if={is_nil(@group.deleted_at)}>
|
||||
<:action>
|
||||
<.delete_button
|
||||
phx-click="delete"
|
||||
|
||||
@@ -14,20 +14,26 @@ defmodule Web.Live.Actors.ShowTest do
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when actor is deleted", %{conn: conn} do
|
||||
test "renders deleted actor without action buttons", %{conn: conn} do
|
||||
account = Fixtures.Accounts.create_account()
|
||||
|
||||
actor =
|
||||
Fixtures.Actors.create_actor(type: :account_admin_user, account: account)
|
||||
|> Fixtures.Actors.delete()
|
||||
|
||||
identity = Fixtures.Auth.create_identity(account: account, actor: actor)
|
||||
auth_actor = Fixtures.Actors.create_actor(type: :account_admin_user, account: account)
|
||||
auth_identity = Fixtures.Auth.create_identity(account: account, actor: auth_actor)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> authorize_conn(auth_identity)
|
||||
|> live(~p"/#{account}/actors/#{actor}")
|
||||
end
|
||||
|
||||
assert html =~ "(deleted)"
|
||||
refute html =~ "Danger Zone"
|
||||
refute html =~ "Add"
|
||||
refute html =~ "Edit"
|
||||
refute html =~ "Deploy"
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{conn: conn} do
|
||||
@@ -46,7 +52,7 @@ defmodule Web.Live.Actors.ShowTest do
|
||||
assert breadcrumbs =~ actor.name
|
||||
end
|
||||
|
||||
test "renders logs table", %{
|
||||
test "renders flows table", %{
|
||||
conn: conn
|
||||
} do
|
||||
account = Fixtures.Accounts.create_account()
|
||||
@@ -85,6 +91,87 @@ defmodule Web.Live.Actors.ShowTest do
|
||||
"#{flow.gateway.group.name}-#{flow.gateway.name} (189.172.73.153)"
|
||||
end
|
||||
|
||||
test "renders flows even for deleted policies", %{
|
||||
conn: conn
|
||||
} do
|
||||
account = Fixtures.Accounts.create_account()
|
||||
actor = Fixtures.Actors.create_actor(type: :account_admin_user, account: account)
|
||||
identity = Fixtures.Auth.create_identity(account: account, actor: actor)
|
||||
client = Fixtures.Clients.create_client(account: account, actor: actor)
|
||||
|
||||
flow =
|
||||
Fixtures.Flows.create_flow(
|
||||
account: account,
|
||||
client: client
|
||||
)
|
||||
|
||||
flow = Repo.preload(flow, [:client, gateway: [:group], policy: [:actor_group, :resource]])
|
||||
Fixtures.Policies.delete_policy(flow.policy)
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/actors/#{actor}")
|
||||
|
||||
[row] =
|
||||
lv
|
||||
|> element("#flows")
|
||||
|> render()
|
||||
|> table_to_map()
|
||||
|
||||
assert row["authorized at"]
|
||||
assert row["expires at"]
|
||||
assert row["policy"] =~ flow.policy.actor_group.name
|
||||
assert row["policy"] =~ flow.policy.resource.name
|
||||
|
||||
assert row["client (ip)"] ==
|
||||
"#{flow.client.name} (#{client.last_seen_remote_ip})"
|
||||
|
||||
assert row["gateway (ip)"] ==
|
||||
"#{flow.gateway.group.name}-#{flow.gateway.name} (189.172.73.153)"
|
||||
end
|
||||
|
||||
test "renders flows even for deleted policy assocs", %{
|
||||
conn: conn
|
||||
} do
|
||||
account = Fixtures.Accounts.create_account()
|
||||
actor = Fixtures.Actors.create_actor(type: :account_admin_user, account: account)
|
||||
identity = Fixtures.Auth.create_identity(account: account, actor: actor)
|
||||
client = Fixtures.Clients.create_client(account: account, actor: actor)
|
||||
|
||||
flow =
|
||||
Fixtures.Flows.create_flow(
|
||||
account: account,
|
||||
client: client
|
||||
)
|
||||
|
||||
flow = Repo.preload(flow, [:client, gateway: [:group], policy: [:actor_group, :resource]])
|
||||
Fixtures.Actors.delete_group(flow.policy.actor_group)
|
||||
Fixtures.Resources.delete_resource(flow.policy.resource)
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/actors/#{actor}")
|
||||
|
||||
[row] =
|
||||
lv
|
||||
|> element("#flows")
|
||||
|> render()
|
||||
|> table_to_map()
|
||||
|
||||
assert row["authorized at"]
|
||||
assert row["expires at"]
|
||||
assert row["policy"] =~ flow.policy.actor_group.name
|
||||
assert row["policy"] =~ flow.policy.resource.name
|
||||
|
||||
assert row["client (ip)"] ==
|
||||
"#{flow.client.name} (#{client.last_seen_remote_ip})"
|
||||
|
||||
assert row["gateway (ip)"] ==
|
||||
"#{flow.gateway.group.name}-#{flow.gateway.name} (189.172.73.153)"
|
||||
end
|
||||
|
||||
describe "users" do
|
||||
setup do
|
||||
account = Fixtures.Accounts.create_account()
|
||||
|
||||
@@ -32,7 +32,7 @@ defmodule Web.Live.Clients.ShowTest do
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when client is deleted", %{
|
||||
test "renders deleted client without action buttons", %{
|
||||
account: account,
|
||||
client: client,
|
||||
identity: identity,
|
||||
@@ -40,11 +40,17 @@ defmodule Web.Live.Clients.ShowTest do
|
||||
} do
|
||||
client = Fixtures.Clients.delete_client(client)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/clients/#{client}")
|
||||
end
|
||||
|
||||
assert html =~ "(deleted)"
|
||||
refute html =~ "Danger Zone"
|
||||
refute html =~ "Add"
|
||||
refute html =~ "Delete"
|
||||
refute html =~ "Edit"
|
||||
refute html =~ "Deploy"
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
@@ -112,7 +118,7 @@ defmodule Web.Live.Clients.ShowTest do
|
||||
|> Map.fetch!("owner") =~ actor.name
|
||||
end
|
||||
|
||||
test "renders logs table", %{
|
||||
test "renders flows table", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
client: client,
|
||||
@@ -147,6 +153,79 @@ defmodule Web.Live.Clients.ShowTest do
|
||||
"#{flow.gateway.group.name}-#{flow.gateway.name} (189.172.73.153)"
|
||||
end
|
||||
|
||||
test "renders flows even for deleted policies", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
client: client,
|
||||
conn: conn
|
||||
} do
|
||||
flow =
|
||||
Fixtures.Flows.create_flow(
|
||||
account: account,
|
||||
client: client
|
||||
)
|
||||
|
||||
flow = Repo.preload(flow, [:client, gateway: [:group], policy: [:actor_group, :resource]])
|
||||
Fixtures.Policies.delete_policy(flow.policy)
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/clients/#{client}")
|
||||
|
||||
[row] =
|
||||
lv
|
||||
|> element("#flows")
|
||||
|> render()
|
||||
|> table_to_map()
|
||||
|
||||
assert row["authorized at"]
|
||||
assert row["expires at"]
|
||||
assert row["remote ip"] == to_string(client.last_seen_remote_ip)
|
||||
assert row["policy"] =~ flow.policy.actor_group.name
|
||||
assert row["policy"] =~ flow.policy.resource.name
|
||||
|
||||
assert row["gateway (ip)"] ==
|
||||
"#{flow.gateway.group.name}-#{flow.gateway.name} (189.172.73.153)"
|
||||
end
|
||||
|
||||
test "renders flows even for deleted policy assocs", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
client: client,
|
||||
conn: conn
|
||||
} do
|
||||
flow =
|
||||
Fixtures.Flows.create_flow(
|
||||
account: account,
|
||||
client: client
|
||||
)
|
||||
|
||||
flow = Repo.preload(flow, [:client, gateway: [:group], policy: [:actor_group, :resource]])
|
||||
Fixtures.Actors.delete_group(flow.policy.actor_group)
|
||||
Fixtures.Resources.delete_resource(flow.policy.resource)
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/clients/#{client}")
|
||||
|
||||
[row] =
|
||||
lv
|
||||
|> element("#flows")
|
||||
|> render()
|
||||
|> table_to_map()
|
||||
|
||||
assert row["authorized at"]
|
||||
assert row["expires at"]
|
||||
assert row["remote ip"] == to_string(client.last_seen_remote_ip)
|
||||
assert row["policy"] =~ flow.policy.actor_group.name
|
||||
assert row["policy"] =~ flow.policy.resource.name
|
||||
|
||||
assert row["gateway (ip)"] ==
|
||||
"#{flow.gateway.group.name}-#{flow.gateway.name} (189.172.73.153)"
|
||||
end
|
||||
|
||||
test "allows editing clients", %{
|
||||
account: account,
|
||||
client: client,
|
||||
|
||||
@@ -33,7 +33,7 @@ defmodule Web.Live.Gateways.ShowTest do
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when gateway is deleted", %{
|
||||
test "renders deleted gateway without action buttons", %{
|
||||
account: account,
|
||||
gateway: gateway,
|
||||
identity: identity,
|
||||
@@ -41,11 +41,16 @@ defmodule Web.Live.Gateways.ShowTest do
|
||||
} do
|
||||
gateway = Fixtures.Gateways.delete_gateway(gateway)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/gateways/#{gateway}")
|
||||
end
|
||||
|
||||
assert html =~ "(deleted)"
|
||||
refute html =~ "Danger Zone"
|
||||
refute html =~ "Add"
|
||||
refute html =~ "Delete"
|
||||
refute html =~ "Edit"
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
|
||||
@@ -30,7 +30,7 @@ defmodule Web.Live.Groups.ShowTest do
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when group is deleted", %{
|
||||
test "renders deleted group without action buttons", %{
|
||||
account: account,
|
||||
group: group,
|
||||
identity: identity,
|
||||
@@ -38,11 +38,17 @@ defmodule Web.Live.Groups.ShowTest do
|
||||
} do
|
||||
group = Fixtures.Actors.delete_group(group)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/groups/#{group}")
|
||||
end
|
||||
|
||||
assert html =~ "(deleted)"
|
||||
refute html =~ "Danger Zone"
|
||||
refute html =~ "Add"
|
||||
refute html =~ "Delete"
|
||||
refute html =~ "Edit"
|
||||
refute html =~ "Deploy"
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
|
||||
@@ -43,7 +43,7 @@ defmodule Web.Live.Policies.ShowTest do
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when gateway is deleted", %{
|
||||
test "renders deleted gateway group without action buttons", %{
|
||||
account: account,
|
||||
policy: policy,
|
||||
identity: identity,
|
||||
@@ -51,11 +51,17 @@ defmodule Web.Live.Policies.ShowTest do
|
||||
} do
|
||||
policy = Fixtures.Policies.delete_policy(policy)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}")
|
||||
end
|
||||
|
||||
assert html =~ "(deleted)"
|
||||
refute html =~ "Danger Zone"
|
||||
refute html =~ "Add"
|
||||
refute html =~ "Delete"
|
||||
refute html =~ "Edit"
|
||||
refute html =~ "Deploy"
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
|
||||
@@ -35,7 +35,7 @@ defmodule Web.Live.RelayGroups.ShowTest do
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when relay is deleted", %{
|
||||
test "renders deleted relay without action buttons", %{
|
||||
account: account,
|
||||
group: group,
|
||||
identity: identity,
|
||||
@@ -43,11 +43,17 @@ defmodule Web.Live.RelayGroups.ShowTest do
|
||||
} do
|
||||
group = Fixtures.Relays.delete_group(group)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/relay_groups/#{group}")
|
||||
end
|
||||
|
||||
assert html =~ "(deleted)"
|
||||
refute html =~ "Danger Zone"
|
||||
refute html =~ "Add"
|
||||
refute html =~ "Delete"
|
||||
refute html =~ "Edit"
|
||||
refute html =~ "Deploy"
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
|
||||
@@ -33,7 +33,7 @@ defmodule Web.Live.Relays.ShowTest do
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when relay is deleted", %{
|
||||
test "renders deleted relay without action buttons", %{
|
||||
account: account,
|
||||
relay: relay,
|
||||
identity: identity,
|
||||
@@ -41,11 +41,16 @@ defmodule Web.Live.Relays.ShowTest do
|
||||
} do
|
||||
relay = Fixtures.Relays.delete_relay(relay)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/relays/#{relay}")
|
||||
end
|
||||
|
||||
assert html =~ "(deleted)"
|
||||
refute html =~ "Danger Zone"
|
||||
refute html =~ "Add"
|
||||
refute html =~ "Delete"
|
||||
refute html =~ "Edit"
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
|
||||
@@ -43,7 +43,7 @@ defmodule Web.Live.Resources.ShowTest do
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when resource is deleted", %{
|
||||
test "renders deleted resource without action buttons", %{
|
||||
account: account,
|
||||
resource: resource,
|
||||
identity: identity,
|
||||
@@ -51,11 +51,16 @@ defmodule Web.Live.Resources.ShowTest do
|
||||
} do
|
||||
resource = Fixtures.Resources.delete_resource(resource)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/resources/#{resource}")
|
||||
end
|
||||
|
||||
assert html =~ "(deleted)"
|
||||
refute html =~ "Danger Zone"
|
||||
refute html =~ "Delete"
|
||||
refute html =~ "Edit"
|
||||
refute html =~ "Deploy"
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
defmodule Web.Live.Nav.SidebarTest do
|
||||
defmodule Web.SidebarTest do
|
||||
use Web.ConnCase, async: true
|
||||
|
||||
setup do
|
||||
@@ -35,7 +35,7 @@ defmodule Web.Live.Sites.ShowTest do
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when gateway is deleted", %{
|
||||
test "renders deleted gateway group without action buttons", %{
|
||||
account: account,
|
||||
group: group,
|
||||
identity: identity,
|
||||
@@ -43,11 +43,17 @@ defmodule Web.Live.Sites.ShowTest do
|
||||
} do
|
||||
group = Fixtures.Gateways.delete_group(group)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/sites/#{group}")
|
||||
end
|
||||
|
||||
assert html =~ "(deleted)"
|
||||
refute html =~ "Danger Zone"
|
||||
refute html =~ "Add"
|
||||
refute html =~ "Delete"
|
||||
refute html =~ "Edit"
|
||||
refute html =~ "Deploy"
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
|
||||
Reference in New Issue
Block a user