harden invite changesets

This commit is contained in:
shibao 2022-07-04 21:09:55 -04:00
parent ee6266be3f
commit dce04e4d7f
9 changed files with 46 additions and 44 deletions

View File

@ -100,15 +100,14 @@ defmodule Cannery.Invites do
""" """
@spec create_invite(User.t(), attrs :: map()) :: @spec create_invite(User.t(), attrs :: map()) ::
{:ok, Invite.t()} | {:error, Changeset.t(Invite.new_invite())} {:ok, Invite.t()} | {:error, Changeset.t(Invite.new_invite())}
def create_invite(%User{id: user_id, role: :admin}, attrs) do def create_invite(%User{role: :admin} = user, attrs) do
token = token =
:crypto.strong_rand_bytes(@invite_token_length) :crypto.strong_rand_bytes(@invite_token_length)
|> Base.url_encode64() |> Base.url_encode64()
|> binary_part(0, @invite_token_length) |> binary_part(0, @invite_token_length)
attrs = attrs |> Map.merge(%{"user_id" => user_id, "token" => token}) attrs = attrs |> Map.put("token", token)
%Invite{} |> Invite.create_changeset(user, attrs) |> Repo.insert()
%Invite{} |> Invite.create_changeset(attrs) |> Repo.insert()
end end
@doc """ @doc """
@ -155,19 +154,4 @@ defmodule Cannery.Invites do
""" """
@spec delete_invite!(Invite.t(), User.t()) :: Invite.t() @spec delete_invite!(Invite.t(), User.t()) :: Invite.t()
def delete_invite!(invite, %User{role: :admin}), do: invite |> Repo.delete!() def delete_invite!(invite, %User{role: :admin}), do: invite |> Repo.delete!()
@doc """
Returns an `%Changeset{}` for tracking invite changes.
## Examples
iex> change_invite(invite)
%Changeset{data: %Invite{}}
"""
@spec change_invite(Invite.t() | Invite.new_invite()) ::
Changeset.t(Invite.t() | Invite.new_invite())
@spec change_invite(Invite.t() | Invite.new_invite(), attrs :: map()) ::
Changeset.t(Invite.t() | Invite.new_invite())
def change_invite(invite, attrs \\ %{}), do: invite |> Invite.update_changeset(attrs)
end end

View File

@ -38,10 +38,11 @@ defmodule Cannery.Invites.Invite do
@type id :: UUID.t() @type id :: UUID.t()
@doc false @doc false
@spec create_changeset(new_invite(), attrs :: map()) :: Changeset.t(new_invite()) @spec create_changeset(new_invite(), User.t(), attrs :: map()) :: Changeset.t(new_invite())
def create_changeset(invite, attrs) do def create_changeset(invite, %User{id: user_id}, attrs) do
invite invite
|> cast(attrs, [:name, :token, :uses_left, :disabled_at, :user_id]) |> change(user_id: user_id)
|> cast(attrs, [:name, :token, :uses_left, :disabled_at])
|> validate_required([:name, :token, :user_id]) |> validate_required([:name, :token, :user_id])
|> validate_number(:uses_left, greater_than_or_equal_to: 0) |> validate_number(:uses_left, greater_than_or_equal_to: 0)
end end

View File

@ -13,23 +13,44 @@ defmodule CanneryWeb.InviteLive.FormComponent do
%{:invite => Invite.t(), :current_user => User.t(), optional(any) => any}, %{:invite => Invite.t(), :current_user => User.t(), optional(any) => any},
Socket.t() Socket.t()
) :: {:ok, Socket.t()} ) :: {:ok, Socket.t()}
def update(%{invite: invite} = assigns, socket) do def update(%{invite: _invite} = assigns, socket) do
{:ok, socket |> assign(assigns) |> assign(:changeset, Invites.change_invite(invite))} {:ok, socket |> assign(assigns) |> assign_changeset(%{})}
end end
@impl true @impl true
def handle_event( def handle_event("validate", %{"invite" => invite_params}, socket) do
"validate", {:noreply, socket |> assign_changeset(invite_params)}
%{"invite" => invite_params},
%{assigns: %{invite: invite}} = socket
) do
{:noreply, socket |> assign(:changeset, invite |> Invites.change_invite(invite_params))}
end end
def handle_event("save", %{"invite" => invite_params}, %{assigns: %{action: action}} = socket) do def handle_event("save", %{"invite" => invite_params}, %{assigns: %{action: action}} = socket) do
save_invite(socket, action, invite_params) save_invite(socket, action, invite_params)
end end
defp assign_changeset(
%{assigns: %{action: action, current_user: user, invite: invite}} = socket,
invite_params
) do
changeset_action =
case action do
:new -> :insert
:edit -> :update
end
changeset =
case action do
:new -> invite |> Invite.create_changeset(user, invite_params)
:edit -> invite |> Invite.update_changeset(invite_params)
end
changeset =
case changeset |> Changeset.apply_action(changeset_action) do
{:ok, _data} -> changeset
{:error, changeset} -> changeset
end
socket |> assign(:changeset, changeset)
end
defp save_invite( defp save_invite(
%{assigns: %{current_user: current_user, invite: invite, return_to: return_to}} = socket, %{assigns: %{current_user: current_user, invite: invite, return_to: return_to}} = socket,
:edit, :edit,

View File

@ -26,7 +26,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_type_live/form_component.ex:85 #: lib/cannery_web/live/ammo_type_live/form_component.ex:85
#: lib/cannery_web/live/container_live/form_component.ex:85 #: lib/cannery_web/live/container_live/form_component.ex:85
#: lib/cannery_web/live/invite_live/form_component.ex:59 #: lib/cannery_web/live/invite_live/form_component.ex:80
#: lib/cannery_web/live/tag_live/form_component.ex:126 #: lib/cannery_web/live/tag_live/form_component.ex:126
msgid "%{name} created successfully" msgid "%{name} created successfully"
msgstr "%{name} erfolgreich erstellt" msgstr "%{name} erfolgreich erstellt"
@ -64,7 +64,7 @@ msgstr "%{name} erfolgreich aktualisiert"
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67 #: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:67 #: lib/cannery_web/live/container_live/form_component.ex:67
#: lib/cannery_web/live/invite_live/form_component.ex:41 #: lib/cannery_web/live/invite_live/form_component.ex:62
#: lib/cannery_web/live/tag_live/form_component.ex:108 #: lib/cannery_web/live/tag_live/form_component.ex:108
msgid "%{name} updated successfully" msgid "%{name} updated successfully"
msgstr "%{name} erfolgreich aktualisiert" msgstr "%{name} erfolgreich aktualisiert"

View File

@ -14,7 +14,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_type_live/form_component.ex:85 #: lib/cannery_web/live/ammo_type_live/form_component.ex:85
#: lib/cannery_web/live/container_live/form_component.ex:85 #: lib/cannery_web/live/container_live/form_component.ex:85
#: lib/cannery_web/live/invite_live/form_component.ex:59 #: lib/cannery_web/live/invite_live/form_component.ex:80
#: lib/cannery_web/live/tag_live/form_component.ex:126 #: lib/cannery_web/live/tag_live/form_component.ex:126
msgid "%{name} created successfully" msgid "%{name} created successfully"
msgstr "" msgstr ""
@ -52,7 +52,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67 #: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:67 #: lib/cannery_web/live/container_live/form_component.ex:67
#: lib/cannery_web/live/invite_live/form_component.ex:41 #: lib/cannery_web/live/invite_live/form_component.ex:62
#: lib/cannery_web/live/tag_live/form_component.ex:108 #: lib/cannery_web/live/tag_live/form_component.ex:108
msgid "%{name} updated successfully" msgid "%{name} updated successfully"
msgstr "" msgstr ""

View File

@ -24,7 +24,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_type_live/form_component.ex:85 #: lib/cannery_web/live/ammo_type_live/form_component.ex:85
#: lib/cannery_web/live/container_live/form_component.ex:85 #: lib/cannery_web/live/container_live/form_component.ex:85
#: lib/cannery_web/live/invite_live/form_component.ex:59 #: lib/cannery_web/live/invite_live/form_component.ex:80
#: lib/cannery_web/live/tag_live/form_component.ex:126 #: lib/cannery_web/live/tag_live/form_component.ex:126
msgid "%{name} created successfully" msgid "%{name} created successfully"
msgstr "" msgstr ""
@ -62,7 +62,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67 #: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:67 #: lib/cannery_web/live/container_live/form_component.ex:67
#: lib/cannery_web/live/invite_live/form_component.ex:41 #: lib/cannery_web/live/invite_live/form_component.ex:62
#: lib/cannery_web/live/tag_live/form_component.ex:108 #: lib/cannery_web/live/tag_live/form_component.ex:108
msgid "%{name} updated successfully" msgid "%{name} updated successfully"
msgstr "" msgstr ""

View File

@ -26,7 +26,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_type_live/form_component.ex:85 #: lib/cannery_web/live/ammo_type_live/form_component.ex:85
#: lib/cannery_web/live/container_live/form_component.ex:85 #: lib/cannery_web/live/container_live/form_component.ex:85
#: lib/cannery_web/live/invite_live/form_component.ex:59 #: lib/cannery_web/live/invite_live/form_component.ex:80
#: lib/cannery_web/live/tag_live/form_component.ex:126 #: lib/cannery_web/live/tag_live/form_component.ex:126
msgid "%{name} created successfully" msgid "%{name} created successfully"
msgstr "%{name} créé· avec succès" msgstr "%{name} créé· avec succès"
@ -64,7 +64,7 @@ msgstr "%{name} mis à jour avec succès"
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67 #: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:67 #: lib/cannery_web/live/container_live/form_component.ex:67
#: lib/cannery_web/live/invite_live/form_component.ex:41 #: lib/cannery_web/live/invite_live/form_component.ex:62
#: lib/cannery_web/live/tag_live/form_component.ex:108 #: lib/cannery_web/live/tag_live/form_component.ex:108
msgid "%{name} updated successfully" msgid "%{name} updated successfully"
msgstr "%{name} mis à jour avec succès" msgstr "%{name} mis à jour avec succès"

View File

@ -13,7 +13,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_type_live/form_component.ex:85 #: lib/cannery_web/live/ammo_type_live/form_component.ex:85
#: lib/cannery_web/live/container_live/form_component.ex:85 #: lib/cannery_web/live/container_live/form_component.ex:85
#: lib/cannery_web/live/invite_live/form_component.ex:59 #: lib/cannery_web/live/invite_live/form_component.ex:80
#: lib/cannery_web/live/tag_live/form_component.ex:126 #: lib/cannery_web/live/tag_live/form_component.ex:126
msgid "%{name} created successfully" msgid "%{name} created successfully"
msgstr "" msgstr ""
@ -51,7 +51,7 @@ msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/cannery_web/live/ammo_type_live/form_component.ex:67 #: lib/cannery_web/live/ammo_type_live/form_component.ex:67
#: lib/cannery_web/live/container_live/form_component.ex:67 #: lib/cannery_web/live/container_live/form_component.ex:67
#: lib/cannery_web/live/invite_live/form_component.ex:41 #: lib/cannery_web/live/invite_live/form_component.ex:62
#: lib/cannery_web/live/tag_live/form_component.ex:108 #: lib/cannery_web/live/tag_live/form_component.ex:108
msgid "%{name} updated successfully" msgid "%{name} updated successfully"
msgstr "" msgstr ""

View File

@ -68,9 +68,5 @@ defmodule Cannery.InvitesTest do
assert {:ok, %Invite{}} = Invites.delete_invite(invite, current_user) assert {:ok, %Invite{}} = Invites.delete_invite(invite, current_user)
assert_raise Ecto.NoResultsError, fn -> Invites.get_invite!(invite.id, current_user) end assert_raise Ecto.NoResultsError, fn -> Invites.get_invite!(invite.id, current_user) end
end end
test "change_invite/1 returns a invite changeset", %{invite: invite} do
assert %Changeset{} = Invites.change_invite(invite)
end
end end
end end