mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
Update new/edit policy pages (#1946)
Why: * The new and edit policy pages had previously only been pulling live data from the DB, but had not been able to use the forms to create or update policies. This commit allows the forms to function as intended.
This commit is contained in:
@@ -80,6 +80,10 @@ defmodule Domain.Policies do
|
||||
end
|
||||
end
|
||||
|
||||
def new_policy(attrs, %Auth.Subject{} = subject) do
|
||||
Policy.Changeset.create(attrs, subject)
|
||||
end
|
||||
|
||||
def ensure_has_access_to(%Auth.Subject{} = subject, %Policy{} = policy) do
|
||||
if subject.account.id == policy.account_id do
|
||||
:ok
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
defmodule Domain.Repo.Migrations.UpdatePolicyIndexes do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
drop(index(:policies, [:account_id, :name], unique: true))
|
||||
drop(index(:policies, [:account_id, :resource_id, :actor_group_id], unique: true))
|
||||
|
||||
create(index(:policies, [:account_id, :name], unique: true, where: "deleted_at IS NULL"))
|
||||
|
||||
create(
|
||||
index(:policies, [:account_id, :resource_id, :actor_group_id],
|
||||
unique: true,
|
||||
where: "deleted_at IS NULL"
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -3,8 +3,11 @@ defmodule Domain.Fixtures.Accounts do
|
||||
alias Domain.Accounts
|
||||
|
||||
def account_attrs(attrs \\ %{}) do
|
||||
unique_num = unique_integer()
|
||||
|
||||
Enum.into(attrs, %{
|
||||
name: "acc-#{unique_integer()}"
|
||||
name: "acc-#{unique_num}",
|
||||
slug: "acc_#{unique_num}"
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
defmodule Domain.Fixtures.Policies do
|
||||
use Domain.Fixture
|
||||
alias Domain.Policies
|
||||
|
||||
def policy_attrs(attrs \\ %{}) do
|
||||
Enum.into(attrs, %{
|
||||
@@ -42,4 +43,17 @@ defmodule Domain.Fixtures.Policies do
|
||||
|
||||
policy
|
||||
end
|
||||
|
||||
def delete_policy(policy) do
|
||||
policy = Repo.preload(policy, :account)
|
||||
|
||||
subject =
|
||||
Fixtures.Auth.create_subject(
|
||||
account: policy.account,
|
||||
actor: [type: :account_admin_user]
|
||||
)
|
||||
|
||||
{:ok, policy} = Policies.delete_policy(policy, subject)
|
||||
policy
|
||||
end
|
||||
end
|
||||
|
||||
@@ -365,11 +365,12 @@ defmodule Web.FormComponents do
|
||||
|
||||
def delete_button(assigns) do
|
||||
~H"""
|
||||
<button
|
||||
type="button"
|
||||
class="text-red-600 inline-flex items-center hover:text-white border border-red-600 hover:bg-red-600 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:hover:bg-red-600 dark:focus:ring-red-900"
|
||||
{@rest}
|
||||
>
|
||||
<button type="button" class={~w[
|
||||
text-red-600 inline-flex items-center hover:text-white border border-red-600 hover:bg-red-600
|
||||
focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5
|
||||
text-center dark:border-red-500 dark:text-red-500 dark:hover:text-white dark:hover:bg-red-600
|
||||
dark:focus:ring-red-900
|
||||
]} {@rest}>
|
||||
<!-- XXX: Fix icon for dark mode -->
|
||||
<!-- <.icon name="hero-trash-solid" class="text-red-600 w-5 h-5 mr-1 -ml-1" /> -->
|
||||
<%= render_slot(@inner_block) %>
|
||||
|
||||
@@ -314,4 +314,22 @@ defmodule Web.TableComponents do
|
||||
</tr>
|
||||
"""
|
||||
end
|
||||
|
||||
@doc ~S"""
|
||||
This component is meant to be used with the table component. It renders a
|
||||
<.link> component that has a specific style for actions in a table.
|
||||
"""
|
||||
attr :navigate, :string, required: true
|
||||
slot :inner_block
|
||||
|
||||
def action_link(assigns) do
|
||||
~H"""
|
||||
<.link
|
||||
navigate={@navigate}
|
||||
class="block py-2 px-4 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
>
|
||||
<%= render_slot(@inner_block) %>
|
||||
</.link>
|
||||
"""
|
||||
end
|
||||
end
|
||||
|
||||
@@ -191,7 +191,7 @@ defmodule Web.AuthController do
|
||||
conn = put_session(conn, :client_csrf_token, params["client_csrf_token"])
|
||||
|
||||
redirect_url =
|
||||
url(~p"/#{provider.account_id}/sign_in/providers/#{provider.id}/handle_callback")
|
||||
url(~p"/#{account_id_or_slug}/sign_in/providers/#{provider.id}/handle_callback")
|
||||
|
||||
redirect_to_idp(conn, redirect_url, provider)
|
||||
else
|
||||
|
||||
@@ -54,6 +54,7 @@ defmodule Web.Auth.SignIn do
|
||||
<.providers_group_form
|
||||
adapter="openid_connect"
|
||||
providers={@providers_by_adapter[:openid_connect]}
|
||||
account={@account}
|
||||
params={@params}
|
||||
/>
|
||||
</:item>
|
||||
@@ -66,6 +67,7 @@ defmodule Web.Auth.SignIn do
|
||||
<.providers_group_form
|
||||
adapter="userpass"
|
||||
provider={List.first(@providers_by_adapter[:userpass])}
|
||||
account={@account}
|
||||
flash={@flash}
|
||||
params={@params}
|
||||
/>
|
||||
@@ -79,6 +81,7 @@ defmodule Web.Auth.SignIn do
|
||||
<.providers_group_form
|
||||
adapter="email"
|
||||
provider={List.first(@providers_by_adapter[:email])}
|
||||
account={@account}
|
||||
flash={@flash}
|
||||
params={@params}
|
||||
/>
|
||||
@@ -104,7 +107,12 @@ defmodule Web.Auth.SignIn do
|
||||
def providers_group_form(%{adapter: "openid_connect"} = assigns) do
|
||||
~H"""
|
||||
<div class="space-y-3 items-center">
|
||||
<.openid_connect_button :for={provider <- @providers} provider={provider} params={@params} />
|
||||
<.openid_connect_button
|
||||
:for={provider <- @providers}
|
||||
provider={provider}
|
||||
account={@account}
|
||||
params={@params}
|
||||
/>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
@@ -117,7 +125,7 @@ defmodule Web.Auth.SignIn do
|
||||
~H"""
|
||||
<.simple_form
|
||||
for={@userpass_form}
|
||||
action={~p"/#{@provider.account_id}/sign_in/providers/#{@provider.id}/verify_credentials"}
|
||||
action={~p"/#{@account}/sign_in/providers/#{@provider.id}/verify_credentials"}
|
||||
class="space-y-4 lg:space-y-6"
|
||||
id="userpass_form"
|
||||
phx-update="ignore"
|
||||
@@ -157,7 +165,7 @@ defmodule Web.Auth.SignIn do
|
||||
~H"""
|
||||
<.simple_form
|
||||
for={@email_form}
|
||||
action={~p"/#{@provider.account_id}/sign_in/providers/#{@provider.id}/request_magic_link"}
|
||||
action={~p"/#{@account}/sign_in/providers/#{@provider.id}/request_magic_link"}
|
||||
class="space-y-4 lg:space-y-6"
|
||||
id="email_form"
|
||||
phx-update="ignore"
|
||||
@@ -183,9 +191,7 @@ defmodule Web.Auth.SignIn do
|
||||
|
||||
def openid_connect_button(assigns) do
|
||||
~H"""
|
||||
<a
|
||||
href={~p"/#{@provider.account_id}/sign_in/providers/#{@provider}/redirect?#{@params}"}
|
||||
class={~w[
|
||||
<a href={~p"/#{@account}/sign_in/providers/#{@provider}/redirect?#{@params}"} class={~w[
|
||||
w-full inline-flex items-center justify-center py-2.5 px-5
|
||||
bg-white rounded-lg
|
||||
text-sm font-medium text-gray-900
|
||||
@@ -194,8 +200,7 @@ defmodule Web.Auth.SignIn do
|
||||
hover:bg-gray-100 hover:text-gray-900
|
||||
focus:z-10 focus:ring-4 focus:ring-gray-200
|
||||
dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400
|
||||
dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700]}
|
||||
>
|
||||
dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700]}>
|
||||
Log in with <%= @provider.name %>
|
||||
</a>
|
||||
"""
|
||||
|
||||
@@ -5,7 +5,9 @@ defmodule Web.Policies.Edit do
|
||||
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
with {:ok, policy} <- Policies.fetch_policy_by_id(id, socket.assigns.subject) do
|
||||
{:ok, assign(socket, policy: policy)}
|
||||
form = to_form(Policies.Policy.Changeset.update(policy, %{}))
|
||||
socket = assign(socket, policy: policy, form: form)
|
||||
{:ok, socket, temporary_assigns: [form: %Phoenix.HTML.Form{}]}
|
||||
else
|
||||
_other -> raise Web.LiveErrors.NotFoundError
|
||||
end
|
||||
@@ -31,31 +33,46 @@ defmodule Web.Policies.Edit do
|
||||
<section class="bg-white dark:bg-gray-900">
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<h2 class="mb-4 text-xl font-bold text-gray-900 dark:text-white">Edit Policy details</h2>
|
||||
<form action="#">
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<div>
|
||||
<.label for="name">
|
||||
Name
|
||||
</.label>
|
||||
<.input
|
||||
autocomplete="off"
|
||||
type="text"
|
||||
name="name"
|
||||
id="policy-name"
|
||||
placeholder="Name of Policy"
|
||||
value={@policy.name}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<.button type="submit" class="btn btn-primary">
|
||||
Save
|
||||
<.simple_form
|
||||
for={@form}
|
||||
class="space-y-4 lg:space-y-6"
|
||||
phx-submit="submit"
|
||||
phx-change="validate"
|
||||
>
|
||||
<.input
|
||||
field={@form[:name]}
|
||||
type="text"
|
||||
label="Policy Name"
|
||||
placeholder="Enter a Policy Name here"
|
||||
required
|
||||
phx-debounce="300"
|
||||
/>
|
||||
<:actions>
|
||||
<.button phx-disable-with="Updating Policy..." class="w-full">
|
||||
Update Policy
|
||||
</.button>
|
||||
</div>
|
||||
</form>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
</div>
|
||||
</section>
|
||||
"""
|
||||
end
|
||||
|
||||
def handle_event("validate", %{"policy" => policy_params}, socket) do
|
||||
changeset =
|
||||
Policies.Policy.Changeset.update(socket.assigns.policy, policy_params)
|
||||
|> Map.put(:action, :validate)
|
||||
|
||||
{:noreply, assign(socket, form: to_form(changeset))}
|
||||
end
|
||||
|
||||
def handle_event("submit", %{"policy" => policy_params}, socket) do
|
||||
with {:ok, policy} <-
|
||||
Policies.update_policy(socket.assigns.policy, policy_params, socket.assigns.subject) do
|
||||
{:noreply, redirect(socket, to: ~p"/#{socket.assigns.account}/policies/#{policy}")}
|
||||
else
|
||||
{:error, changeset} ->
|
||||
{:noreply, assign(socket, form: to_form(changeset))}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,9 +21,7 @@ defmodule Web.Policies.Index do
|
||||
All Policies
|
||||
</:title>
|
||||
<:actions>
|
||||
<.add_button navigate={~p"/#{@account}/policies/new"}>
|
||||
Add a new Policy
|
||||
</.add_button>
|
||||
<.add_button navigate={~p"/#{@account}/policies/new"}>Add Policy</.add_button>
|
||||
</:actions>
|
||||
</.header>
|
||||
<!-- Policies table -->
|
||||
@@ -51,13 +49,19 @@ defmodule Web.Policies.Index do
|
||||
<%= policy.resource.name %>
|
||||
</.link>
|
||||
</:col>
|
||||
<:action>
|
||||
<a
|
||||
href="#"
|
||||
class="block py-2 px-4 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
<:action :let={policy}>
|
||||
<.action_link navigate={~p"/#{@account}/policies/#{policy}/edit"}>
|
||||
Edit
|
||||
</.action_link>
|
||||
</:action>
|
||||
<:action :let={policy}>
|
||||
<div
|
||||
phx-click="delete"
|
||||
phx-value-id={policy.id}
|
||||
class="block py-2 px-4 cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
|
||||
>
|
||||
Delete
|
||||
</a>
|
||||
</div>
|
||||
</:action>
|
||||
</.table>
|
||||
<.paginator page={3} total_pages={100} collection_base_path={~p"/#{@account}/gateway_groups"} />
|
||||
@@ -88,4 +92,10 @@ defmodule Web.Policies.Index do
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def handle_event("delete", %{"id" => id}, socket) do
|
||||
{:ok, policy} = Policies.fetch_policy_by_id(id, socket.assigns.subject)
|
||||
{:ok, _} = Policies.delete_policy(policy, socket.assigns.subject)
|
||||
{:noreply, push_navigate(socket, to: ~p"/#{socket.assigns.account}/policies")}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
defmodule Web.Policies.New do
|
||||
use Web, :live_view
|
||||
|
||||
alias Domain.{Resources, Actors}
|
||||
alias Domain.{Resources, Actors, Policies}
|
||||
|
||||
def mount(_params, _session, socket) do
|
||||
with {:ok, resources} <- Resources.list_resources(socket.assigns.subject),
|
||||
{:ok, actor_groups} <- Actors.list_groups(socket.assigns.subject) do
|
||||
form = to_form(Policies.new_policy(%{}, socket.assigns.subject))
|
||||
|
||||
socket =
|
||||
assign(socket,
|
||||
resources: resources,
|
||||
actor_groups: actor_groups
|
||||
actor_groups: actor_groups,
|
||||
form: form
|
||||
)
|
||||
|
||||
{:ok, socket}
|
||||
{:ok, socket, temporary_assigns: [form: %Phoenix.HTML.Form{}]}
|
||||
else
|
||||
_other -> raise Web.LiveErrors.NotFoundError
|
||||
end
|
||||
@@ -33,53 +36,59 @@ defmodule Web.Policies.New do
|
||||
<section class="bg-white dark:bg-gray-900">
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<h2 class="mb-4 text-xl font-bold text-gray-900 dark:text-white">Policy details</h2>
|
||||
<form action="#">
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<div>
|
||||
<.label for="policy-name">
|
||||
Name
|
||||
</.label>
|
||||
<.input
|
||||
autocomplete="off"
|
||||
type="text"
|
||||
name="name"
|
||||
value=""
|
||||
id="policy-name"
|
||||
placeholder="Enter a name for this policy"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<.label for="group">
|
||||
Group
|
||||
</.label>
|
||||
|
||||
<.input
|
||||
type="select"
|
||||
options={Enum.map(@actor_groups, fn g -> [key: g.name, value: g.id] end)}
|
||||
name="actor_group"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<.label for="resource">
|
||||
Resource
|
||||
</.label>
|
||||
<.input
|
||||
type="select"
|
||||
options={Enum.map(@resources, fn r -> [key: r.name, value: r.id] end)}
|
||||
name="resource"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<.button type="submit">
|
||||
Save
|
||||
<.simple_form for={@form} phx-submit="submit" phx-change="validate">
|
||||
<.input
|
||||
field={@form[:name]}
|
||||
type="text"
|
||||
label="Policy Name"
|
||||
placeholder="Enter a Policy Name here"
|
||||
required
|
||||
phx-debounce="300"
|
||||
/>
|
||||
<.input
|
||||
field={@form[:actor_group_id]}
|
||||
label="Group"
|
||||
type="select"
|
||||
options={Enum.map(@actor_groups, fn g -> [key: g.name, value: g.id] end)}
|
||||
value={@form[:actor_group_id].value}
|
||||
required
|
||||
/>
|
||||
<.input
|
||||
field={@form[:resource_id]}
|
||||
label="Resource"
|
||||
type="select"
|
||||
options={Enum.map(@resources, fn r -> [key: r.name, value: r.id] end)}
|
||||
value={@form[:resource_id].value}
|
||||
required
|
||||
/>
|
||||
<.base_error form={@form} field={:base} />
|
||||
<:actions>
|
||||
<.button phx-disable-with="Creating Policy..." class="w-full">
|
||||
Create Policy
|
||||
</.button>
|
||||
</div>
|
||||
</form>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
</div>
|
||||
</section>
|
||||
"""
|
||||
end
|
||||
|
||||
def handle_event("validate", %{"policy" => policy_params}, socket) do
|
||||
form =
|
||||
Policies.new_policy(policy_params, socket.assigns.subject)
|
||||
|> Map.put(:action, :validate)
|
||||
|> to_form()
|
||||
|
||||
{:noreply, assign(socket, form: form)}
|
||||
end
|
||||
|
||||
def handle_event("submit", %{"policy" => policy_params}, socket) do
|
||||
with {:ok, policy} <- Policies.create_policy(policy_params, socket.assigns.subject) do
|
||||
{:noreply, redirect(socket, to: ~p"/#{socket.assigns.account}/policies/#{policy}")}
|
||||
else
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
form = to_form(changeset)
|
||||
{:noreply, assign(socket, form: form)}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,7 +37,7 @@ defmodule Web.Policies.Show do
|
||||
</.header>
|
||||
<!-- Show Policy -->
|
||||
<div class="bg-white dark:bg-gray-800 overflow-hidden">
|
||||
<.vertical_table>
|
||||
<.vertical_table id="policy">
|
||||
<.vertical_table_row>
|
||||
<:label>
|
||||
Name
|
||||
@@ -144,11 +144,16 @@ defmodule Web.Policies.Show do
|
||||
Danger zone
|
||||
</:title>
|
||||
<:actions>
|
||||
<.delete_button>
|
||||
<.delete_button phx-click="delete" phx-value-id={@policy.id}>
|
||||
Delete Policy
|
||||
</.delete_button>
|
||||
</:actions>
|
||||
</.header>
|
||||
"""
|
||||
end
|
||||
|
||||
def handle_event("delete", %{"id" => _policy_id}, socket) do
|
||||
{:ok, _} = Policies.delete_policy(socket.assigns.policy, socket.assigns.subject)
|
||||
{:noreply, push_navigate(socket, to: ~p"/#{socket.assigns.account}/policies")}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -79,7 +79,7 @@ defmodule Web.Settings.IdentityProviders.GoogleWorkspace.Show do
|
||||
</.button>
|
||||
<% end %>
|
||||
<.edit_button navigate={
|
||||
~p"/#{@provider.account_id}/settings/identity_providers/google_workspace/#{@provider}/redirect"
|
||||
~p"/#{@account}/settings/identity_providers/google_workspace/#{@provider}/redirect"
|
||||
}>
|
||||
Reconnect Identity Provider
|
||||
</.edit_button>
|
||||
|
||||
@@ -77,7 +77,7 @@ defmodule Web.Settings.IdentityProviders.OpenIDConnect.Show do
|
||||
Disable Identity Provider
|
||||
</.button>
|
||||
<.edit_button navigate={
|
||||
~p"/#{@provider.account_id}/settings/identity_providers/openid_connect/#{@provider}/redirect"
|
||||
~p"/#{@account}/settings/identity_providers/openid_connect/#{@provider}/redirect"
|
||||
}>
|
||||
Reconnect Identity Provider
|
||||
</.edit_button>
|
||||
|
||||
@@ -169,7 +169,7 @@ defmodule Web.AuthTest do
|
||||
|
||||
describe "ensure_authenticated/2" do
|
||||
setup context do
|
||||
%{conn: %{context.conn | path_params: %{"account_id_or_slug" => context.account.id}}}
|
||||
%{conn: %{context.conn | path_params: %{"account_id_or_slug" => context.account.slug}}}
|
||||
end
|
||||
|
||||
test "redirects if user is not authenticated", %{account: account, conn: conn} do
|
||||
@@ -179,7 +179,7 @@ defmodule Web.AuthTest do
|
||||
|> ensure_authenticated([])
|
||||
|
||||
assert conn.halted
|
||||
assert redirected_to(conn) == ~p"/#{account}/sign_in"
|
||||
assert redirected_to(conn) == ~p"/#{account.slug}/sign_in"
|
||||
|
||||
assert Phoenix.Flash.get(conn.assigns.flash, :error) ==
|
||||
"You must log in to access this page."
|
||||
@@ -342,14 +342,14 @@ defmodule Web.AuthTest do
|
||||
} do
|
||||
session_token = "invalid_token"
|
||||
session = conn |> put_session(:session_token, session_token) |> get_session()
|
||||
params = %{"account_id_or_slug" => subject.account.id}
|
||||
params = %{"account_id_or_slug" => subject.account.slug}
|
||||
|
||||
assert {:halt, updated_socket} =
|
||||
on_mount(:ensure_authenticated, params, session, socket)
|
||||
|
||||
assert is_nil(updated_socket.assigns.subject)
|
||||
|
||||
assert updated_socket.redirected == {:redirect, %{to: ~p"/#{subject.account}/sign_in"}}
|
||||
assert updated_socket.redirected == {:redirect, %{to: ~p"/#{subject.account.slug}/sign_in"}}
|
||||
end
|
||||
|
||||
test "redirects to login page if there isn't a session_token", %{
|
||||
@@ -358,14 +358,14 @@ defmodule Web.AuthTest do
|
||||
admin_subject: subject
|
||||
} do
|
||||
session = conn |> get_session()
|
||||
params = %{"account_id_or_slug" => subject.account.id}
|
||||
params = %{"account_id_or_slug" => subject.account.slug}
|
||||
|
||||
assert {:halt, updated_socket} =
|
||||
on_mount(:ensure_authenticated, params, session, socket)
|
||||
|
||||
assert is_nil(updated_socket.assigns.subject)
|
||||
|
||||
assert updated_socket.redirected == {:redirect, %{to: ~p"/#{subject.account}/sign_in"}}
|
||||
assert updated_socket.redirected == {:redirect, %{to: ~p"/#{subject.account.slug}/sign_in"}}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ defmodule Web.AuthControllerTest do
|
||||
conn =
|
||||
conn
|
||||
|> post(
|
||||
~p"/#{provider.account_id}/sign_in/providers/#{provider.id}/verify_credentials",
|
||||
~p"/#{account}/sign_in/providers/#{provider.id}/verify_credentials",
|
||||
%{
|
||||
"userpass" => %{
|
||||
"provider_identifier" => identity.provider_identifier,
|
||||
@@ -162,7 +162,7 @@ defmodule Web.AuthControllerTest do
|
||||
}
|
||||
)
|
||||
|
||||
assert redirected_to(conn) == "/#{account.slug}/dashboard"
|
||||
assert redirected_to(conn) == ~p"/#{account.slug}/dashboard"
|
||||
end
|
||||
|
||||
test "renews the session when credentials are valid", %{conn: conn} do
|
||||
@@ -372,7 +372,7 @@ defmodule Web.AuthControllerTest do
|
||||
assert email.subject == "Firezone Sign In Link"
|
||||
|
||||
verify_sign_in_token_path =
|
||||
"/#{account.id}/sign_in/providers/#{provider.id}/verify_sign_in_token"
|
||||
~p"/#{account.id}/sign_in/providers/#{provider.id}/verify_sign_in_token"
|
||||
|
||||
assert email.text_body =~ "#{verify_sign_in_token_path}"
|
||||
assert email.text_body =~ "identity_id=#{identity.id}"
|
||||
@@ -493,7 +493,7 @@ defmodule Web.AuthControllerTest do
|
||||
"secret" => "bar"
|
||||
})
|
||||
|
||||
assert redirected_to(conn) == "/#{account.id}/sign_in"
|
||||
assert redirected_to(conn) == ~p"/#{account}/sign_in"
|
||||
assert flash(conn, :error) == "The sign in link is invalid or expired."
|
||||
end
|
||||
|
||||
@@ -524,7 +524,7 @@ defmodule Web.AuthControllerTest do
|
||||
}
|
||||
)
|
||||
|
||||
assert redirected_to(conn) == "/#{account.id}/sign_in"
|
||||
assert redirected_to(conn) == ~p"/#{account}/sign_in"
|
||||
assert flash(conn, :error) == "The sign in link is invalid or expired."
|
||||
end
|
||||
|
||||
@@ -554,7 +554,7 @@ defmodule Web.AuthControllerTest do
|
||||
}
|
||||
)
|
||||
|
||||
assert redirected_to(conn) == "/#{account.id}/sign_in"
|
||||
assert redirected_to(conn) == ~p"/#{account}/sign_in"
|
||||
assert flash(conn, :error) == "The sign in link is invalid or expired."
|
||||
end
|
||||
|
||||
@@ -640,12 +640,12 @@ defmodule Web.AuthControllerTest do
|
||||
conn =
|
||||
conn
|
||||
|> put_session(:sign_in_nonce, sign_in_nonce)
|
||||
|> get(~p"/#{account}/sign_in/providers/#{provider}/verify_sign_in_token", %{
|
||||
|> get(~p"/#{account.id}/sign_in/providers/#{provider}/verify_sign_in_token", %{
|
||||
"identity_id" => identity.id,
|
||||
"secret" => email_token
|
||||
})
|
||||
|
||||
assert redirected_to(conn) == "/#{account.slug}/dashboard"
|
||||
assert redirected_to(conn) == ~p"/#{account.slug}/dashboard"
|
||||
end
|
||||
|
||||
test "redirects to the platform link when credentials are valid for account users", %{
|
||||
@@ -970,7 +970,7 @@ defmodule Web.AuthControllerTest do
|
||||
"code" => "MyFakeCode"
|
||||
})
|
||||
|
||||
assert redirected_to(conn) == "/#{account.slug}/dashboard"
|
||||
assert redirected_to(conn) == ~p"/#{account.slug}/dashboard"
|
||||
|
||||
assert %{
|
||||
"live_socket_id" => "actors_sessions:" <> socket_id,
|
||||
@@ -1085,7 +1085,7 @@ defmodule Web.AuthControllerTest do
|
||||
|> put_session(:preferred_locale, "en_US")
|
||||
|> get(~p"/#{account}/sign_out")
|
||||
|
||||
assert redirected_to(conn) =~ "/#{account.id}/sign_in"
|
||||
assert redirected_to(conn) == url(~p"/#{account}/sign_in")
|
||||
assert conn.private.plug_session == %{"preferred_locale" => "en_US"}
|
||||
|
||||
assert %{"fz_recent_account_ids" => fz_recent_account_ids} = conn.cookies
|
||||
@@ -1129,7 +1129,7 @@ defmodule Web.AuthControllerTest do
|
||||
|> put_session(:live_socket_id, live_socket_id)
|
||||
|> get(~p"/#{account}/sign_out")
|
||||
|
||||
assert redirected_to(conn) == "/#{account.id}/sign_in"
|
||||
assert redirected_to(conn) == ~p"/#{account}/sign_in"
|
||||
|
||||
assert_receive %Phoenix.Socket.Broadcast{event: "disconnect", topic: ^live_socket_id}
|
||||
end
|
||||
@@ -1172,7 +1172,7 @@ defmodule Web.AuthControllerTest do
|
||||
|> put_session(:preferred_locale, "en_US")
|
||||
|> get(~p"/#{account}/sign_out")
|
||||
|
||||
assert redirected_to(conn) =~ "/#{account.id}/sign_in"
|
||||
assert redirected_to(conn) == url(~p"/#{account}/sign_in")
|
||||
assert conn.private.plug_session == %{"preferred_locale" => "en_US"}
|
||||
|
||||
assert %{"fz_recent_account_ids" => fz_recent_account_ids} = conn.cookies
|
||||
@@ -1187,7 +1187,7 @@ defmodule Web.AuthControllerTest do
|
||||
|> put_session(:preferred_locale, "en_US")
|
||||
|> get(~p"/#{account}/sign_out")
|
||||
|
||||
assert redirected_to(conn) == "/#{account.id}/sign_in"
|
||||
assert redirected_to(conn) == ~p"/#{account}/sign_in"
|
||||
assert conn.private.plug_session == %{"preferred_locale" => "en_US"}
|
||||
|
||||
refute Map.has_key?(conn.cookies, "fz_recent_account_ids")
|
||||
|
||||
148
elixir/apps/web/test/web/live/policies/edit_test.exs
Normal file
148
elixir/apps/web/test/web/live/policies/edit_test.exs
Normal file
@@ -0,0 +1,148 @@
|
||||
defmodule Web.Live.Policies.EditTest do
|
||||
use Web.ConnCase, async: true
|
||||
|
||||
setup 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)
|
||||
|
||||
policy = Fixtures.Policies.create_policy(account: account)
|
||||
|
||||
%{
|
||||
account: account,
|
||||
actor: actor,
|
||||
identity: identity,
|
||||
policy: policy
|
||||
}
|
||||
end
|
||||
|
||||
test "redirects to sign in page for unauthorized user", %{
|
||||
account: account,
|
||||
policy: policy,
|
||||
conn: conn
|
||||
} do
|
||||
assert live(conn, ~p"/#{account}/policies/#{policy}/edit") ==
|
||||
{:error,
|
||||
{:redirect,
|
||||
%{
|
||||
to: ~p"/#{account}/sign_in",
|
||||
flash: %{"error" => "You must log in to access this page."}
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when policy is deleted", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
policy: policy,
|
||||
conn: conn
|
||||
} do
|
||||
Fixtures.Policies.delete_policy(policy)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}/edit")
|
||||
end
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
policy: policy,
|
||||
conn: conn
|
||||
} do
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}/edit")
|
||||
|
||||
assert item = Floki.find(html, "[aria-label='Breadcrumb']")
|
||||
breadcrumbs = String.trim(Floki.text(item))
|
||||
assert breadcrumbs =~ "Policies"
|
||||
assert breadcrumbs =~ policy.name
|
||||
assert breadcrumbs =~ "Edit"
|
||||
end
|
||||
|
||||
test "renders form", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
policy: policy,
|
||||
conn: conn
|
||||
} do
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}/edit")
|
||||
|
||||
form = form(lv, "form")
|
||||
|
||||
assert find_inputs(form) == ["policy[name]"]
|
||||
end
|
||||
|
||||
test "renders changeset errors on input change", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
policy: policy,
|
||||
conn: conn
|
||||
} do
|
||||
attrs = Fixtures.Policies.policy_attrs() |> Map.take([:name])
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}/edit")
|
||||
|
||||
lv
|
||||
|> form("form", policy: attrs)
|
||||
|> validate_change(%{policy: %{name: String.duplicate("a", 256)}}, fn form, _html ->
|
||||
assert form_validation_errors(form) == %{
|
||||
"policy[name]" => ["should be at most 255 character(s)"]
|
||||
}
|
||||
end)
|
||||
|> validate_change(%{policy: %{name: ""}}, fn form, _html ->
|
||||
assert form_validation_errors(form) == %{"policy[name]" => ["can't be blank"]}
|
||||
end)
|
||||
end
|
||||
|
||||
test "renders changeset errors on submit", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
policy: policy,
|
||||
conn: conn
|
||||
} do
|
||||
other_policy = Fixtures.Policies.create_policy(account: account)
|
||||
attrs = %{name: other_policy.name}
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}/edit")
|
||||
|
||||
assert lv
|
||||
|> form("form", policy: attrs)
|
||||
|> render_submit()
|
||||
|> form_validation_errors() == %{"policy[name]" => ["Policy Name already exists"]}
|
||||
end
|
||||
|
||||
test "updates a policy on valid attrs", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
policy: policy,
|
||||
conn: conn
|
||||
} do
|
||||
attrs = Fixtures.Policies.policy_attrs() |> Map.take([:name])
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}/edit")
|
||||
|
||||
assert lv
|
||||
|> form("form", policy: attrs)
|
||||
|> render_submit() ==
|
||||
{:error, {:redirect, %{to: ~p"/#{account}/policies/#{policy}"}}}
|
||||
|
||||
assert policy = Repo.get_by(Domain.Policies.Policy, id: policy.id)
|
||||
assert policy.name == attrs.name
|
||||
end
|
||||
end
|
||||
78
elixir/apps/web/test/web/live/policies/index_test.exs
Normal file
78
elixir/apps/web/test/web/live/policies/index_test.exs
Normal file
@@ -0,0 +1,78 @@
|
||||
defmodule Web.Live.Policies.IndexTest do
|
||||
use Web.ConnCase, async: true
|
||||
|
||||
setup do
|
||||
account = Fixtures.Accounts.create_account()
|
||||
identity = Fixtures.Auth.create_identity(account: account, actor: [type: :account_admin_user])
|
||||
|
||||
%{
|
||||
account: account,
|
||||
identity: identity
|
||||
}
|
||||
end
|
||||
|
||||
test "redirects to sign in page for unauthorized user", %{account: account, conn: conn} do
|
||||
assert live(conn, ~p"/#{account}/policies") ==
|
||||
{:error,
|
||||
{:redirect,
|
||||
%{
|
||||
to: ~p"/#{account}/sign_in",
|
||||
flash: %{"error" => "You must log in to access this page."}
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies")
|
||||
|
||||
assert item = Floki.find(html, "[aria-label='Breadcrumb']")
|
||||
breadcrumbs = String.trim(Floki.text(item))
|
||||
assert breadcrumbs =~ "Policies"
|
||||
end
|
||||
|
||||
test "renders add policy button", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies")
|
||||
|
||||
assert button = Floki.find(html, "a[href='/#{account.id}/policies/new']")
|
||||
assert Floki.text(button) =~ "Add Policy"
|
||||
end
|
||||
|
||||
test "renders policies table", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
policy =
|
||||
Fixtures.Policies.create_policy(account: account)
|
||||
|> Domain.Repo.preload(:actor_group)
|
||||
|> Domain.Repo.preload(:resource)
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies")
|
||||
|
||||
[rendered_policy | _] =
|
||||
lv
|
||||
|> element("#policies")
|
||||
|> render()
|
||||
|> table_to_map()
|
||||
|
||||
assert rendered_policy["name"] =~ policy.name
|
||||
assert rendered_policy["group"] =~ policy.actor_group.name
|
||||
assert rendered_policy["resource"] =~ policy.resource.name
|
||||
end
|
||||
end
|
||||
158
elixir/apps/web/test/web/live/policies/new_test.exs
Normal file
158
elixir/apps/web/test/web/live/policies/new_test.exs
Normal file
@@ -0,0 +1,158 @@
|
||||
defmodule Web.Live.Policies.NewTest do
|
||||
use Web.ConnCase, async: true
|
||||
|
||||
setup 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)
|
||||
|
||||
%{
|
||||
account: account,
|
||||
actor: actor,
|
||||
identity: identity
|
||||
}
|
||||
end
|
||||
|
||||
test "redirects to sign in page for unauthorized user", %{
|
||||
account: account,
|
||||
conn: conn
|
||||
} do
|
||||
assert live(conn, ~p"/#{account}/policies/new") ==
|
||||
{:error,
|
||||
{:redirect,
|
||||
%{
|
||||
to: ~p"/#{account}/sign_in",
|
||||
flash: %{"error" => "You must log in to access this page."}
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/new")
|
||||
|
||||
assert item = Floki.find(html, "[aria-label='Breadcrumb']")
|
||||
breadcrumbs = String.trim(Floki.text(item))
|
||||
assert breadcrumbs =~ "Policies"
|
||||
assert breadcrumbs =~ "Add"
|
||||
end
|
||||
|
||||
test "renders form", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/new")
|
||||
|
||||
form = form(lv, "form")
|
||||
|
||||
assert find_inputs(form) == [
|
||||
"policy[actor_group_id]",
|
||||
"policy[name]",
|
||||
"policy[resource_id]"
|
||||
]
|
||||
end
|
||||
|
||||
test "renders changeset errors on input change", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
group = Fixtures.Actors.create_group(account: account)
|
||||
resource = Fixtures.Resources.create_resource(account: account)
|
||||
|
||||
attrs =
|
||||
Fixtures.Policies.policy_attrs()
|
||||
|> Map.take([:name])
|
||||
|> Map.put(:actor_group_id, group.id)
|
||||
|> Map.put(:resource_id, resource.id)
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/new")
|
||||
|
||||
lv
|
||||
|> form("form", policy: attrs)
|
||||
|> validate_change(%{policy: %{name: String.duplicate("a", 256)}}, fn form, _html ->
|
||||
assert form_validation_errors(form) == %{
|
||||
"policy[name]" => ["should be at most 255 character(s)"]
|
||||
}
|
||||
end)
|
||||
|> validate_change(%{policy: %{name: ""}}, fn form, _html ->
|
||||
assert form_validation_errors(form) == %{
|
||||
"policy[name]" => ["can't be blank"]
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
test "renders changeset errors on submit", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
other_policy = Fixtures.Policies.create_policy(account: account)
|
||||
attrs = %{name: other_policy.name}
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/new")
|
||||
|
||||
assert lv
|
||||
|> form("form", policy: attrs)
|
||||
|> render_submit()
|
||||
|> form_validation_errors() == %{
|
||||
"policy[name]" => ["Policy Name already exists"]
|
||||
}
|
||||
|
||||
attrs = %{
|
||||
name: "unique",
|
||||
actor_group_id: other_policy.actor_group_id,
|
||||
resource_id: other_policy.resource_id
|
||||
}
|
||||
|
||||
assert lv
|
||||
|> form("form", policy: attrs)
|
||||
|> render_submit()
|
||||
|> form_validation_errors() == %{
|
||||
"policy[base]" => ["Policy with Group and Resource already exists"]
|
||||
}
|
||||
end
|
||||
|
||||
test "creates a new policy on valid attrs and redirects", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
group = Fixtures.Actors.create_group(account: account)
|
||||
resource = Fixtures.Resources.create_resource(account: account)
|
||||
|
||||
attrs =
|
||||
Fixtures.Policies.policy_attrs()
|
||||
|> Map.take([:name])
|
||||
|> Map.put(:actor_group_id, group.id)
|
||||
|> Map.put(:resource_id, resource.id)
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/new")
|
||||
|
||||
assert lv
|
||||
|> form("form", policy: attrs)
|
||||
|> render_submit()
|
||||
|
||||
policy = Repo.get_by(Domain.Policies.Policy, attrs)
|
||||
|
||||
assert assert_redirect(lv, ~p"/#{account}/policies/#{policy}")
|
||||
end
|
||||
end
|
||||
146
elixir/apps/web/test/web/live/policies/show_test.exs
Normal file
146
elixir/apps/web/test/web/live/policies/show_test.exs
Normal file
@@ -0,0 +1,146 @@
|
||||
defmodule Web.Live.Policies.ShowTest do
|
||||
use Web.ConnCase, async: true
|
||||
|
||||
setup 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)
|
||||
subject = Fixtures.Auth.create_subject(account: account, actor: actor, identity: identity)
|
||||
|
||||
policy = Fixtures.Policies.create_policy(account: account, subject: subject)
|
||||
|
||||
%{
|
||||
account: account,
|
||||
actor: actor,
|
||||
identity: identity,
|
||||
subject: subject,
|
||||
policy: policy
|
||||
}
|
||||
end
|
||||
|
||||
test "redirects to sign in page for unauthorized user", %{
|
||||
account: account,
|
||||
policy: policy,
|
||||
conn: conn
|
||||
} do
|
||||
assert live(conn, ~p"/#{account}/policies/#{policy}") ==
|
||||
{:error,
|
||||
{:redirect,
|
||||
%{
|
||||
to: ~p"/#{account}/sign_in",
|
||||
flash: %{"error" => "You must log in to access this page."}
|
||||
}}}
|
||||
end
|
||||
|
||||
test "renders not found error when gateway is deleted", %{
|
||||
account: account,
|
||||
policy: policy,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
policy = Fixtures.Policies.delete_policy(policy)
|
||||
|
||||
assert_raise Web.LiveErrors.NotFoundError, fn ->
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}")
|
||||
end
|
||||
end
|
||||
|
||||
test "renders breadcrumbs item", %{
|
||||
account: account,
|
||||
policy: policy,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
{:ok, _lv, html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}")
|
||||
|
||||
assert item = Floki.find(html, "[aria-label='Breadcrumb']")
|
||||
breadcrumbs = String.trim(Floki.text(item))
|
||||
assert breadcrumbs =~ "Policies"
|
||||
assert breadcrumbs =~ policy.name
|
||||
end
|
||||
|
||||
test "allows editing policy", %{
|
||||
account: account,
|
||||
policy: policy,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}")
|
||||
|
||||
assert lv
|
||||
|> element("a", "Edit Policy")
|
||||
|> render_click() ==
|
||||
{:error,
|
||||
{:live_redirect, %{to: ~p"/#{account}/policies/#{policy}/edit", kind: :push}}}
|
||||
end
|
||||
|
||||
test "renders policy details", %{
|
||||
account: account,
|
||||
actor: actor,
|
||||
identity: identity,
|
||||
policy: policy,
|
||||
conn: conn
|
||||
} do
|
||||
policy =
|
||||
policy
|
||||
|> Domain.Repo.preload(:actor_group)
|
||||
|> Domain.Repo.preload(:resource)
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}")
|
||||
|
||||
table =
|
||||
lv
|
||||
|> element("#policy")
|
||||
|> render()
|
||||
|> vertical_table_to_map()
|
||||
|
||||
assert table["name"] =~ policy.name
|
||||
assert table["group"] =~ policy.actor_group.name
|
||||
assert table["resource"] =~ policy.resource.name
|
||||
assert table["created"] =~ actor.name
|
||||
end
|
||||
|
||||
# TODO: Finish this test when logs are implemented
|
||||
# test "renders logs table", %{
|
||||
# account: account,
|
||||
# actor: actor,
|
||||
# identity: identity,
|
||||
# policy: policy,
|
||||
# conn: conn
|
||||
# } do
|
||||
# {:ok, lv, _html} =
|
||||
# conn
|
||||
# |> authorize_conn(identity)
|
||||
# |> live(~p"/#{account}/policies/#{policy}")
|
||||
# end
|
||||
|
||||
test "allows deleting policy", %{
|
||||
account: account,
|
||||
policy: policy,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/#{policy}")
|
||||
|
||||
assert lv
|
||||
|> element("button", "Delete Policy")
|
||||
|> render_click() ==
|
||||
{:error, {:live_redirect, %{to: ~p"/#{account}/policies", kind: :push}}}
|
||||
|
||||
assert Repo.get(Domain.Policies.Policy, policy.id).deleted_at
|
||||
end
|
||||
end
|
||||
@@ -48,7 +48,7 @@ defmodule Web.Live.Settings.IdentityProviders.GoogleWorkspace.Connect do
|
||||
~p"/#{account.id}/settings/identity_providers/google_workspace/#{provider_id}/redirect"
|
||||
)
|
||||
|
||||
assert redirected_to(conn) == "/#{account.id}/settings/identity_providers"
|
||||
assert redirected_to(conn) == ~p"/#{account}/settings/identity_providers"
|
||||
assert flash(conn, :error) == "Provider does not exist."
|
||||
end
|
||||
|
||||
@@ -74,7 +74,7 @@ defmodule Web.Live.Settings.IdentityProviders.GoogleWorkspace.Connect do
|
||||
|
||||
callback_url =
|
||||
url(
|
||||
~p"/#{account.id}/settings/identity_providers/google_workspace/#{provider.id}/handle_callback"
|
||||
~p"/#{account}/settings/identity_providers/google_workspace/#{provider.id}/handle_callback"
|
||||
)
|
||||
|
||||
{state, verifier} = conn.cookies["fz_auth_state_#{provider.id}"] |> :erlang.binary_to_term()
|
||||
|
||||
@@ -44,11 +44,9 @@ defmodule Web.Live.Settings.IdentityProviders.OpenIDConnect.Connect do
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> assign(:account, account)
|
||||
|> get(
|
||||
~p"/#{account.id}/settings/identity_providers/openid_connect/#{provider_id}/redirect"
|
||||
)
|
||||
|> get(~p"/#{account}/settings/identity_providers/openid_connect/#{provider_id}/redirect")
|
||||
|
||||
assert redirected_to(conn) == "/#{account.id}/settings/identity_providers"
|
||||
assert redirected_to(conn) == ~p"/#{account}/settings/identity_providers"
|
||||
assert flash(conn, :error) == "Provider does not exist."
|
||||
end
|
||||
|
||||
@@ -74,7 +72,7 @@ defmodule Web.Live.Settings.IdentityProviders.OpenIDConnect.Connect do
|
||||
|
||||
callback_url =
|
||||
url(
|
||||
~p"/#{account.id}/settings/identity_providers/openid_connect/#{provider.id}/handle_callback"
|
||||
~p"/#{account}/settings/identity_providers/openid_connect/#{provider.id}/handle_callback"
|
||||
)
|
||||
|
||||
{state, verifier} = conn.cookies["fz_auth_state_#{provider.id}"] |> :erlang.binary_to_term()
|
||||
|
||||
Reference in New Issue
Block a user