mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
fix(ux): Redirect to policies/new after creating Resource (#5938)
Fixes a UX issue somewhat introduced by https://github.com/firezone/firezone/pull/5870 where we changed behavior to make the redirect consistent with other CRUD operations. The behavior we had prior to https://github.com/firezone/firezone/pull/5870 was to redirect to Resource show, but feedback from customer (which makes sense) is that you almost _always_ create a Policy after creating a Resource, so this PR streamlines the hot path flow there. This has occurred to a couple users in Discord as well, so by taking them directly to policies/new it hopefully make clear the user needs to create a Policy after creating a Resource. This papercut occurred while customer was demo'ing Firezone to another potential customer. Fixes #5929 cc @jameswinegar
This commit is contained in:
@@ -43,7 +43,7 @@ defmodule Domain.Policies.Policy.Changeset do
|
||||
|> unique_constraint(
|
||||
:base,
|
||||
name: :policies_account_id_resource_id_actor_group_id_index,
|
||||
message: "Policy with Group and Resource already exists"
|
||||
message: "Policy for the selected Group and Resource already exists"
|
||||
)
|
||||
|> assoc_constraint(:resource)
|
||||
|> assoc_constraint(:actor_group)
|
||||
|
||||
@@ -74,6 +74,11 @@ defmodule Web.Actors.Components do
|
||||
placeholder="Role"
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-xs text-gray-500">
|
||||
Select <strong>Admin</strong>
|
||||
to grant this user access to the admin portal. Otherwise, select <strong>User</strong>
|
||||
to limit access to the Client apps only.
|
||||
</p>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
@@ -160,29 +165,6 @@ defmodule Web.Actors.Components do
|
||||
"""
|
||||
end
|
||||
|
||||
def option(assigns) do
|
||||
~H"""
|
||||
<div>
|
||||
<div class="flex items-center mb-4">
|
||||
<input
|
||||
id={"idp-option-#{@type}"}
|
||||
type="radio"
|
||||
name="next"
|
||||
value={next_step_path(@type, @account)}
|
||||
class={~w[w-4 h-4 border-neutral-300]}
|
||||
required
|
||||
/>
|
||||
<label for={"idp-option-#{@type}"} class="block ml-2 text-lg text-neutral-900">
|
||||
<%= @name %>
|
||||
</label>
|
||||
</div>
|
||||
<p class="ml-6 mb-6 text-sm text-neutral-500">
|
||||
<%= @description %>
|
||||
</p>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def next_step_path(:service_account, account) do
|
||||
~p"/#{account}/actors/service_accounts/new"
|
||||
end
|
||||
|
||||
@@ -18,9 +18,7 @@ defmodule Web.Actors.New do
|
||||
<.breadcrumb path={~p"/#{@account}/actors/new"}>Add</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Add Actor
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:content>
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<h2 class="mb-4 text-xl text-neutral-900">Choose type</h2>
|
||||
@@ -29,22 +27,65 @@ defmodule Web.Actors.New do
|
||||
<fieldset>
|
||||
<legend class="sr-only">Choose Actor Type</legend>
|
||||
|
||||
<.option
|
||||
account={@account}
|
||||
type={:user}
|
||||
name="User"
|
||||
description="Admin or regular user accounts can be used to sign in to Firezone and access private resources."
|
||||
/>
|
||||
<.option
|
||||
account={@account}
|
||||
type={:service_account}
|
||||
name="Service Account"
|
||||
description="Service accounts can be used for headless clients or to access Firezone APIs."
|
||||
/>
|
||||
<ul class="grid w-full gap-6 md:grid-cols-2">
|
||||
<li>
|
||||
<.input
|
||||
id="idp-option-user"
|
||||
type="radio_button_group"
|
||||
name="next"
|
||||
value={next_step_path(:user, @account)}
|
||||
checked={false}
|
||||
required
|
||||
/>
|
||||
<label for="idp-option-user" class={~w[
|
||||
inline-flex items-center justify-between w-full
|
||||
p-5 text-gray-500 bg-white border border-gray-200
|
||||
rounded cursor-pointer peer-checked:border-accent-500
|
||||
peer-checked:text-accent-500 hover:text-gray-600 hover:bg-gray-100
|
||||
]}>
|
||||
<div class="block">
|
||||
<div class="w-full font-semibold mb-3">
|
||||
<.icon name="hero-user" class="w-5 h-5 mr-1" /> User
|
||||
</div>
|
||||
<div class="w-full text-sm">
|
||||
User accounts can sign in to the Firezone Client apps or to
|
||||
the admin portal depending on their role.
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<.input
|
||||
id="idp-option-service_account"
|
||||
type="radio_button_group"
|
||||
name="next"
|
||||
value={next_step_path(:service_account, @account)}
|
||||
checked={false}
|
||||
required
|
||||
/>
|
||||
<label for="idp-option-service_account" class={~w[
|
||||
inline-flex items-center justify-between w-full
|
||||
p-5 text-gray-500 bg-white border border-gray-200
|
||||
rounded cursor-pointer peer-checked:border-accent-500
|
||||
peer-checked:text-accent-500 hover:text-gray-600 hover:bg-gray-100
|
||||
]}>
|
||||
<div class="block">
|
||||
<div class="w-full font-semibold mb-3">
|
||||
<.icon name="hero-server" class="w-5 h-5 mr-1" /> Service Account
|
||||
</div>
|
||||
<div class="w-full text-sm">
|
||||
Service accounts are used to authenticate headless Clients on
|
||||
machines where a user isn't physically present.
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</fieldset>
|
||||
</div>
|
||||
<.submit_button>
|
||||
Next: Create Actor
|
||||
Next: Actor Details
|
||||
</.submit_button>
|
||||
</.form>
|
||||
</div>
|
||||
|
||||
@@ -24,13 +24,11 @@ defmodule Web.Actors.ServiceAccounts.New do
|
||||
</.breadcrumbs>
|
||||
|
||||
<.section>
|
||||
<:title>
|
||||
Create Actor
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:content>
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<h2 class="mb-4 text-xl text-neutral-900">
|
||||
Create a Service Account
|
||||
Service Account details
|
||||
</h2>
|
||||
<.flash kind={:error} flash={@flash} />
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
@@ -38,7 +36,7 @@ defmodule Web.Actors.ServiceAccounts.New do
|
||||
<.actor_form form={@form} type={:service_account} subject={@subject} />
|
||||
</div>
|
||||
<.submit_button>
|
||||
Create
|
||||
Next: Create Token
|
||||
</.submit_button>
|
||||
</.form>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
defmodule Web.Actors.ServiceAccounts.NewIdentity do
|
||||
use Web, :live_view
|
||||
import Web.Actors.Components
|
||||
alias Domain.{Auth, Actors, Tokens}
|
||||
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
@@ -41,12 +40,10 @@ defmodule Web.Actors.ServiceAccounts.NewIdentity do
|
||||
</.breadcrumbs>
|
||||
|
||||
<.section>
|
||||
<:title>
|
||||
Create <%= actor_type(@actor.type) %> Token
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:content>
|
||||
<div :if={is_nil(@encoded_token)} class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<h2 class="mb-4 text-xl text-neutral-900">Create a Token</h2>
|
||||
<h2 class="mb-4 text-xl text-neutral-900">Token details</h2>
|
||||
<.flash kind={:error} flash={@flash} />
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
@@ -75,14 +72,20 @@ defmodule Web.Actors.ServiceAccounts.NewIdentity do
|
||||
<div :if={not is_nil(@encoded_token)} class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<div class="text-xl mb-2">
|
||||
Your API token (will be shown only once):
|
||||
Your Service Account token
|
||||
</div>
|
||||
<div>
|
||||
<.code_block id="code-sample-docker" class="w-full mw-1/2 rounded" phx-no-format><%= @encoded_token %></.code_block>
|
||||
<p class="mt-2 text-xs text-gray-500">
|
||||
Store this in a safe place. <strong>It won't be shown again.</strong>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<.code_block id="code-sample-docker" class="w-full mw-1/2 rounded" phx-no-format><%= @encoded_token %></.code_block>
|
||||
|
||||
<.button icon="hero-arrow-uturn-left" navigate={~p"/#{@account}/actors/#{@actor}"}>
|
||||
Back to Actor
|
||||
</.button>
|
||||
<div class="flex justify-start">
|
||||
<.button icon="hero-arrow-uturn-left" navigate={~p"/#{@account}/actors/#{@actor}"}>
|
||||
Back to Service Account
|
||||
</.button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</:content>
|
||||
|
||||
@@ -24,19 +24,17 @@ defmodule Web.Actors.Users.New do
|
||||
</.breadcrumbs>
|
||||
|
||||
<.section>
|
||||
<:title>
|
||||
Create Actor
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:content>
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<h2 class="mb-4 text-xl text-neutral-900">Create a User</h2>
|
||||
<h2 class="mb-4 text-xl text-neutral-900">User details</h2>
|
||||
<.flash kind={:error} flash={@flash} />
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<.actor_form form={@form} type={:user} subject={@subject} />
|
||||
</div>
|
||||
<.submit_button>
|
||||
Create
|
||||
Next: Add an Identity
|
||||
</.submit_button>
|
||||
</.form>
|
||||
</div>
|
||||
|
||||
@@ -51,12 +51,10 @@ defmodule Web.Actors.Users.NewIdentity do
|
||||
</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Create <%= actor_type(@actor.type) %> Identity
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:content>
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<h2 class="mb-4 text-xl text-neutral-900">Create an Identity</h2>
|
||||
<h2 class="mb-4 text-xl text-neutral-900">Identity details</h2>
|
||||
<.flash kind={:error} flash={@flash} />
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
@@ -74,11 +72,18 @@ defmodule Web.Actors.Users.NewIdentity do
|
||||
placeholder="Provider"
|
||||
required
|
||||
/>
|
||||
<p class="mt-2 text-xs text-gray-500">
|
||||
Select the provider to use for signing in.
|
||||
</p>
|
||||
</div>
|
||||
<.provider_form :if={@provider} form={@form} provider={@provider} />
|
||||
</div>
|
||||
<.submit_button>
|
||||
Save
|
||||
<%= if @next_step == "edit_groups" do %>
|
||||
Next: Select Group Memberships
|
||||
<% else %>
|
||||
Create Identity
|
||||
<% end %>
|
||||
</.submit_button>
|
||||
</.form>
|
||||
</div>
|
||||
|
||||
@@ -21,25 +21,24 @@ defmodule Web.Groups.New do
|
||||
<.breadcrumb path={~p"/#{@account}/groups/new"}>Add</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Create Group
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:content>
|
||||
<div class="py-8 px-4 mx-auto max-w-2xl lg:py-16">
|
||||
<h2 class="mb-4 text-xl text-neutral-900">
|
||||
Group details
|
||||
</h2>
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
<.input type="hidden" field={@form[:type]} value="static" />
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<div>
|
||||
<.input
|
||||
label="Group name"
|
||||
field={@form[:name]}
|
||||
placeholder="Enter a name for this Group, e.g. Engineering"
|
||||
required
|
||||
/>
|
||||
<.input label="Name" field={@form[:name]} placeholder="E.g. Engineering" required />
|
||||
<p class="text-sm mt-2 text-neutral-600">
|
||||
Enter a name for this Group.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<.submit_button>
|
||||
Save
|
||||
Next: Select Members
|
||||
</.submit_button>
|
||||
</.form>
|
||||
</div>
|
||||
|
||||
@@ -34,12 +34,10 @@ defmodule Web.Policies.New do
|
||||
<.breadcrumb path={~p"/#{@account}/policies/new"}>Add Policy</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Add Policy
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:content>
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<h2 class="mb-4 text-xl text-neutral-900">Details</h2>
|
||||
<h2 class="mb-4 text-xl text-neutral-900">Policy details</h2>
|
||||
<div
|
||||
:if={@actor_groups == []}
|
||||
class={[
|
||||
@@ -107,9 +105,11 @@ defmodule Web.Policies.New do
|
||||
/>
|
||||
</div>
|
||||
|
||||
<.submit_button phx-disable-with="Creating Policy..." class="w-full">
|
||||
Create Policy
|
||||
</.submit_button>
|
||||
<div class="flex justify-end">
|
||||
<.submit_button phx-disable-with="Creating Policy..." class="w-full">
|
||||
Create Policy
|
||||
</.submit_button>
|
||||
</div>
|
||||
</.form>
|
||||
</div>
|
||||
</:content>
|
||||
@@ -141,12 +141,29 @@ defmodule Web.Policies.New do
|
||||
Map.delete(params, "conditions")
|
||||
end
|
||||
|
||||
with {:ok, policy} <- Policies.create_policy(params, socket.assigns.subject) do
|
||||
if site_id = socket.assigns.params["site_id"] do
|
||||
{:noreply,
|
||||
push_navigate(socket, to: ~p"/#{socket.assigns.account}/sites/#{site_id}?#resources")}
|
||||
else
|
||||
{:noreply, push_navigate(socket, to: ~p"/#{socket.assigns.account}/policies/#{policy}")}
|
||||
with {:ok, _policy} <- Policies.create_policy(params, socket.assigns.subject) do
|
||||
cond do
|
||||
site_id = socket.assigns.params["site_id"] ->
|
||||
# Created from Add Resource from Site
|
||||
{:noreply,
|
||||
push_navigate(socket, to: ~p"/#{socket.assigns.account}/sites/#{site_id}?#resources")}
|
||||
|
||||
resource_id = socket.assigns.resource_id ->
|
||||
# Created from Add Resource from Resources
|
||||
{:noreply,
|
||||
push_navigate(socket, to: ~p"/#{socket.assigns.account}/resources/#{resource_id}")}
|
||||
|
||||
actor_group_id = socket.assigns.actor_group_id ->
|
||||
# Created from Add Policy from Actor Group
|
||||
{:noreply,
|
||||
push_navigate(socket, to: ~p"/#{socket.assigns.account}/groups/#{actor_group_id}")}
|
||||
|
||||
true ->
|
||||
# Created from Add Policy from Policies
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Policy created successfully.")
|
||||
|> push_navigate(to: ~p"/#{socket.assigns.account}/policies")}
|
||||
end
|
||||
else
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
|
||||
@@ -26,9 +26,7 @@ defmodule Web.RelayGroups.New do
|
||||
<.breadcrumb path={~p"/#{@account}/relay_groups/new"}>Add</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Add Relay Instance Group
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:content>
|
||||
<div class="py-8 px-4 mx-auto max-w-2xl lg:py-16">
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
|
||||
@@ -28,9 +28,7 @@ defmodule Web.Resources.New do
|
||||
<.breadcrumb path={~p"/#{@account}/resources/new"}>Add Resource</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Add Resource
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
|
||||
<:content>
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
@@ -236,11 +234,16 @@ defmodule Web.Resources.New do
|
||||
if site_id = socket.assigns.params["site_id"] do
|
||||
{:noreply,
|
||||
socket
|
||||
|> push_navigate(to: ~p"/#{socket.assigns.account}/sites/#{site_id}")}
|
||||
|> push_navigate(
|
||||
to:
|
||||
~p"/#{socket.assigns.account}/policies/new?resource_id=#{resource}&site_id=#{site_id}"
|
||||
)}
|
||||
else
|
||||
{:noreply,
|
||||
socket
|
||||
|> push_navigate(to: ~p"/#{socket.assigns.account}/resources")}
|
||||
|> push_navigate(
|
||||
to: ~p"/#{socket.assigns.account}/policies/new?resource_id=#{resource}"
|
||||
)}
|
||||
end
|
||||
|
||||
{:error, changeset} ->
|
||||
|
||||
@@ -50,14 +50,24 @@ defmodule Web.Settings.ApiClients.Components do
|
||||
~H"""
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<div class="text-xl mb-2">
|
||||
Your API token (will be shown only once):
|
||||
Your API Token:
|
||||
</div>
|
||||
|
||||
<.code_block id="code-api-token" class="w-full mw-1/2 rounded" phx-no-format><%= @encoded_token %></.code_block>
|
||||
<div>
|
||||
<.code_block id="code-api-token" class="w-full mw-1/2 rounded" phx-no-format><%= @encoded_token %></.code_block>
|
||||
<p class="mt-2 text-xs text-gray-500">
|
||||
Store this in a safe place. <strong>It won't be shown again.</strong>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<.button icon="hero-arrow-uturn-left" navigate={~p"/#{@account}/settings/api_clients/#{@actor}"}>
|
||||
Back to API Client
|
||||
</.button>
|
||||
<div class="flex justify-start">
|
||||
<.button
|
||||
icon="hero-arrow-uturn-left"
|
||||
navigate={~p"/#{@account}/settings/api_clients/#{@actor}"}
|
||||
>
|
||||
Back to API Client
|
||||
</.button>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
@@ -54,9 +54,11 @@ defmodule Web.Settings.ApiClients.Index do
|
||||
<.section>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:help>
|
||||
API Clients are used to manage Firezone configuration through a REST API. See the
|
||||
<a class={link_style()} href="https://firezone.dev/kb/reference/rest-api">REST API docs</a>
|
||||
for more info.
|
||||
API Clients are used to manage Firezone configuration through a REST API. See our
|
||||
<.link navigate="https://api.firezone.dev/swaggerui" class={link_style()}>
|
||||
OpenAPI-powered docs
|
||||
</.link>
|
||||
for more information.
|
||||
</:help>
|
||||
|
||||
<:action>
|
||||
|
||||
@@ -12,7 +12,7 @@ defmodule Web.Settings.ApiClients.New do
|
||||
socket =
|
||||
assign(socket,
|
||||
form: to_form(changeset),
|
||||
page_title: "New API Client"
|
||||
page_title: "Add an API Client"
|
||||
)
|
||||
|
||||
{:ok, socket, temporary_assigns: [form: %Phoenix.HTML.Form{}]}
|
||||
@@ -30,7 +30,7 @@ defmodule Web.Settings.ApiClients.New do
|
||||
<:content>
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<h2 class="mb-4 text-xl text-neutral-900">
|
||||
Create API Client
|
||||
API Client details
|
||||
</h2>
|
||||
<.flash kind={:error} flash={@flash} />
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
@@ -38,7 +38,7 @@ defmodule Web.Settings.ApiClients.New do
|
||||
<.api_client_form form={@form} type={:api_client} subject={@subject} />
|
||||
</div>
|
||||
<.submit_button>
|
||||
Create
|
||||
Next: Add a token
|
||||
</.submit_button>
|
||||
</.form>
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,7 @@ defmodule Web.Settings.ApiClients.NewToken do
|
||||
actor: actor,
|
||||
encoded_token: nil,
|
||||
form: to_form(changeset),
|
||||
page_title: "Create API Token"
|
||||
page_title: "Add an API Token"
|
||||
)
|
||||
|
||||
{:ok, socket, temporary_assigns: [form: %Phoenix.HTML.Form{}]}
|
||||
@@ -42,14 +42,14 @@ defmodule Web.Settings.ApiClients.NewToken do
|
||||
<:content>
|
||||
<div class="max-w-2xl px-4 py-8 mx-auto lg:py-16">
|
||||
<div :if={is_nil(@encoded_token)}>
|
||||
<h2 class="mb-4 text-xl text-neutral-900">Create Token</h2>
|
||||
<h2 class="mb-4 text-xl text-neutral-900">API Token details</h2>
|
||||
<.flash kind={:error} flash={@flash} />
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<.api_token_form form={@form} />
|
||||
</div>
|
||||
<.submit_button>
|
||||
Create
|
||||
Create API Token
|
||||
</.submit_button>
|
||||
</.form>
|
||||
</div>
|
||||
|
||||
@@ -17,7 +17,7 @@ defmodule Web.Settings.IdentityProviders.GoogleWorkspace.New do
|
||||
assign(socket,
|
||||
id: id,
|
||||
form: to_form(changeset),
|
||||
page_title: "New Identity Provider"
|
||||
page_title: "New Identity Provider: Google Workspace"
|
||||
)
|
||||
|
||||
{:ok, socket, temporary_assigns: [form: %Phoenix.HTML.Form{}]}
|
||||
@@ -37,9 +37,7 @@ defmodule Web.Settings.IdentityProviders.GoogleWorkspace.New do
|
||||
</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Add a new Google Workspace Identity Provider
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:help>
|
||||
For a more detailed guide on setting up Firezone with Google Workspace, please <.link
|
||||
href="https://www.firezone.dev/kb/authenticate/google"
|
||||
|
||||
@@ -17,7 +17,7 @@ defmodule Web.Settings.IdentityProviders.JumpCloud.New do
|
||||
assign(socket,
|
||||
id: id,
|
||||
form: to_form(changeset),
|
||||
page_title: "New Identity Provider"
|
||||
page_title: "New Identity Provider: JumpCloud"
|
||||
)
|
||||
|
||||
{:ok, socket, temporary_assigns: [form: %Phoenix.HTML.Form{}]}
|
||||
@@ -37,9 +37,7 @@ defmodule Web.Settings.IdentityProviders.JumpCloud.New do
|
||||
</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Add a new JumpCloud Identity Provider
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:help>
|
||||
For a more detailed guide on setting up Firezone with JumpCloud, please <.link
|
||||
href="https://www.firezone.dev/kb/authenticate/jumpcloud"
|
||||
|
||||
@@ -17,7 +17,7 @@ defmodule Web.Settings.IdentityProviders.MicrosoftEntra.New do
|
||||
assign(socket,
|
||||
id: id,
|
||||
form: to_form(changeset),
|
||||
page_title: "New Identity Provider"
|
||||
page_title: "New Identity Provider: Microsoft Entra"
|
||||
)
|
||||
|
||||
{:ok, socket, temporary_assigns: [form: %Phoenix.HTML.Form{}]}
|
||||
@@ -37,9 +37,7 @@ defmodule Web.Settings.IdentityProviders.MicrosoftEntra.New do
|
||||
</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Add a new Microsoft Entra ID Identity Provider
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:help>
|
||||
For a more detailed guide on setting up Firezone with Microsoft Entra ID, please <.link
|
||||
href="https://www.firezone.dev/kb/authenticate/entra"
|
||||
|
||||
@@ -33,9 +33,7 @@ defmodule Web.Settings.IdentityProviders.New do
|
||||
</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Add a new Identity Provider
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:help>
|
||||
Set up SSO authentication using your own identity provider. Directory sync
|
||||
also available for certain providers. <br /> Learn more about
|
||||
|
||||
@@ -17,7 +17,7 @@ defmodule Web.Settings.IdentityProviders.Okta.New do
|
||||
assign(socket,
|
||||
id: id,
|
||||
form: to_form(changeset),
|
||||
page_title: "New Identity Provider"
|
||||
page_title: "New Identity Provider: Okta"
|
||||
)
|
||||
|
||||
{:ok, socket, temporary_assigns: [form: %Phoenix.HTML.Form{}]}
|
||||
@@ -37,9 +37,7 @@ defmodule Web.Settings.IdentityProviders.Okta.New do
|
||||
</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Add a new Okta Identity Provider
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:help>
|
||||
For a more detailed guide on setting up Firezone with Okta, please <.link
|
||||
href="https://www.firezone.dev/kb/authenticate/okta"
|
||||
|
||||
@@ -17,7 +17,7 @@ defmodule Web.Settings.IdentityProviders.OpenIDConnect.New do
|
||||
assign(socket,
|
||||
id: id,
|
||||
form: to_form(changeset),
|
||||
page_title: "New Identity Provider",
|
||||
page_title: "New Identity Provider: OpenID Connect",
|
||||
provider: params["provider"]
|
||||
)
|
||||
|
||||
@@ -38,9 +38,7 @@ defmodule Web.Settings.IdentityProviders.OpenIDConnect.New do
|
||||
</.breadcrumb>
|
||||
</.breadcrumbs>
|
||||
<.section>
|
||||
<:title>
|
||||
Add a new OpenID Connect Identity Provider
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:content>
|
||||
<.provider_form account={@account} id={@id} form={@form} show_sync_msg={!!@provider} />
|
||||
</:content>
|
||||
|
||||
@@ -16,15 +16,21 @@ defmodule Web.Sites.New do
|
||||
</.breadcrumbs>
|
||||
|
||||
<.section>
|
||||
<:title>
|
||||
Add a new Site
|
||||
</:title>
|
||||
<:title><%= @page_title %></:title>
|
||||
<:content>
|
||||
<.flash kind={:error} flash={@flash} />
|
||||
<div class="py-8 px-4 mx-auto max-w-2xl lg:py-16">
|
||||
<h2 class="mb-6 text-xl text-neutral-900">
|
||||
Site details
|
||||
</h2>
|
||||
<.form for={@form} phx-change={:change} phx-submit={:submit}>
|
||||
<div class="grid gap-4 mb-4 sm:grid-cols-1 sm:gap-6 sm:mb-6">
|
||||
<.input label="Name" field={@form[:name]} placeholder="Name of this Site" required />
|
||||
<div>
|
||||
<.input label="Name" field={@form[:name]} placeholder="Name of this Site" required />
|
||||
<p class="mt-2 text-xs text-neutral-500">
|
||||
Enter a name for this Site.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<.submit_button>
|
||||
Create
|
||||
|
||||
@@ -210,11 +210,11 @@ defmodule Web.Live.Policies.NewTest do
|
||||
|> form("form", policy: attrs)
|
||||
|> render_submit()
|
||||
|> form_validation_errors() == %{
|
||||
"policy[base]" => ["Policy with Group and Resource already exists"]
|
||||
"policy[base]" => ["Policy for the selected Group and Resource already exists"]
|
||||
}
|
||||
end
|
||||
|
||||
test "creates a new policy on valid attrs and redirects to policy page", %{
|
||||
test "creates a new policy on valid attrs and redirects to policies page", %{
|
||||
account: account,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
@@ -236,9 +236,10 @@ defmodule Web.Live.Policies.NewTest do
|
||||
|> form("form", policy: attrs)
|
||||
|> render_submit()
|
||||
|
||||
assert policy = Repo.get_by(Domain.Policies.Policy, attrs)
|
||||
assert Repo.get_by(Domain.Policies.Policy, attrs)
|
||||
|
||||
assert assert_redirect(lv, ~p"/#{account}/policies/#{policy}")
|
||||
flash = assert_redirect(lv, ~p"/#{account}/policies")
|
||||
assert flash["info"] == "Policy created successfully."
|
||||
end
|
||||
|
||||
test "creates a new policy with conditions", %{
|
||||
@@ -301,7 +302,7 @@ defmodule Web.Live.Policies.NewTest do
|
||||
}
|
||||
]
|
||||
|
||||
assert assert_redirect(lv, ~p"/#{account}/policies/#{policy}")
|
||||
assert assert_redirect(lv, ~p"/#{account}/resources/#{resource}")
|
||||
end
|
||||
|
||||
test "creates a new policy on valid attrs and pre-set resource_id", %{
|
||||
@@ -327,7 +328,7 @@ defmodule Web.Live.Policies.NewTest do
|
||||
policy = Repo.get_by(Domain.Policies.Policy, attrs)
|
||||
assert policy.resource_id == resource.id
|
||||
|
||||
assert assert_redirect(lv, ~p"/#{account}/policies/#{policy}")
|
||||
assert assert_redirect(lv, ~p"/#{account}/resources/#{resource}")
|
||||
end
|
||||
|
||||
test "removes conditions in the backend when policy_conditions is false", %{
|
||||
@@ -368,7 +369,35 @@ defmodule Web.Live.Policies.NewTest do
|
||||
assert policy.resource_id == resource.id
|
||||
assert policy.conditions == []
|
||||
|
||||
assert assert_redirect(lv, ~p"/#{account}/policies/#{policy}")
|
||||
assert_redirect(lv, ~p"/#{account}/resources/#{resource}")
|
||||
end
|
||||
|
||||
test "redirects back to actor group when a new policy is created with pre-set actor_group_id",
|
||||
%{
|
||||
account: account,
|
||||
identity: identity,
|
||||
conn: conn
|
||||
} do
|
||||
group = Fixtures.Actors.create_group(account: account)
|
||||
resource = Fixtures.Resources.create_resource(account: account)
|
||||
|
||||
Fixtures.Gateways.create_group(account: account)
|
||||
|
||||
attrs = %{actor_group_id: group.id}
|
||||
|
||||
{:ok, lv, _html} =
|
||||
conn
|
||||
|> authorize_conn(identity)
|
||||
|> live(~p"/#{account}/policies/new?actor_group_id=#{group}")
|
||||
|
||||
assert lv
|
||||
|> form("form", policy: attrs)
|
||||
|> render_submit()
|
||||
|
||||
policy = Repo.get_by(Domain.Policies.Policy, attrs)
|
||||
assert policy.resource_id == resource.id
|
||||
|
||||
assert assert_redirect(lv, ~p"/#{account}/groups/#{group}")
|
||||
end
|
||||
|
||||
test "redirects back to site when a new policy is created with pre-set site_id", %{
|
||||
|
||||
@@ -407,7 +407,7 @@ defmodule Web.Live.Resources.NewTest do
|
||||
|
||||
resource = Repo.get_by(Domain.Resources.Resource, %{name: attrs.name, address: attrs.address})
|
||||
|
||||
flash = assert_redirect(lv, ~p"/#{account}/resources")
|
||||
flash = assert_redirect(lv, ~p"/#{account}/policies/new?resource_id=#{resource}")
|
||||
assert flash["info"] == "Resource #{resource.name} created successfully."
|
||||
end
|
||||
|
||||
@@ -449,7 +449,9 @@ defmodule Web.Live.Resources.NewTest do
|
||||
|
||||
resource = Repo.get_by(Domain.Resources.Resource, %{name: attrs.name, address: attrs.address})
|
||||
|
||||
flash = assert_redirect(lv, ~p"/#{account}/sites/#{group}")
|
||||
flash =
|
||||
assert_redirect(lv, ~p"/#{account}/policies/new?resource_id=#{resource}&site_id=#{group}")
|
||||
|
||||
assert flash["info"] == "Resource #{resource.name} created successfully."
|
||||
end
|
||||
|
||||
@@ -516,7 +518,10 @@ defmodule Web.Live.Resources.NewTest do
|
||||
assert %{connections: [connection]} = Repo.preload(resource, :connections)
|
||||
assert connection.gateway_group_id == group.id
|
||||
|
||||
assert assert_redirect(lv, ~p"/#{account}/sites/#{group}")
|
||||
assert assert_redirect(
|
||||
lv,
|
||||
~p"/#{account}/policies/new?resource_id=#{resource}&site_id=#{group}"
|
||||
)
|
||||
end
|
||||
|
||||
test "prevents saving resource if traffic filters set when traffic filters disabled", %{
|
||||
|
||||
@@ -137,7 +137,9 @@ defmodule Web.Live.Settings.ApiClient.NewTokenTest do
|
||||
|> form("form", token: attrs)
|
||||
|> render_submit()
|
||||
|
||||
assert html =~ "Your API token (will be shown only once)"
|
||||
assert html =~ "Your API Token"
|
||||
assert html =~ "Store this in a safe place."
|
||||
assert html =~ "It won't be shown again."
|
||||
|
||||
assert Floki.find(html, "code")
|
||||
|> element_to_text()
|
||||
|
||||
Reference in New Issue
Block a user