From dce04e4d7f312d55b6c393fb10345c888fcc4761 Mon Sep 17 00:00:00 2001 From: shibao Date: Mon, 4 Jul 2022 21:09:55 -0400 Subject: [PATCH] harden invite changesets --- lib/cannery/invites.ex | 22 ++--------- lib/cannery/invites/invite.ex | 7 ++-- .../live/invite_live/form_component.ex | 37 +++++++++++++++---- priv/gettext/de/LC_MESSAGES/prompts.po | 4 +- priv/gettext/en/LC_MESSAGES/prompts.po | 4 +- priv/gettext/es/LC_MESSAGES/prompts.po | 4 +- priv/gettext/fr/LC_MESSAGES/prompts.po | 4 +- priv/gettext/prompts.pot | 4 +- test/cannery/invites_test.exs | 4 -- 9 files changed, 46 insertions(+), 44 deletions(-) diff --git a/lib/cannery/invites.ex b/lib/cannery/invites.ex index f8788ad1..d962c70d 100644 --- a/lib/cannery/invites.ex +++ b/lib/cannery/invites.ex @@ -100,15 +100,14 @@ defmodule Cannery.Invites do """ @spec create_invite(User.t(), attrs :: map()) :: {: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 = :crypto.strong_rand_bytes(@invite_token_length) |> Base.url_encode64() |> binary_part(0, @invite_token_length) - attrs = attrs |> Map.merge(%{"user_id" => user_id, "token" => token}) - - %Invite{} |> Invite.create_changeset(attrs) |> Repo.insert() + attrs = attrs |> Map.put("token", token) + %Invite{} |> Invite.create_changeset(user, attrs) |> Repo.insert() end @doc """ @@ -155,19 +154,4 @@ defmodule Cannery.Invites do """ @spec delete_invite!(Invite.t(), User.t()) :: Invite.t() 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 diff --git a/lib/cannery/invites/invite.ex b/lib/cannery/invites/invite.ex index a0ea2c96..0289af0c 100644 --- a/lib/cannery/invites/invite.ex +++ b/lib/cannery/invites/invite.ex @@ -38,10 +38,11 @@ defmodule Cannery.Invites.Invite do @type id :: UUID.t() @doc false - @spec create_changeset(new_invite(), attrs :: map()) :: Changeset.t(new_invite()) - def create_changeset(invite, attrs) do + @spec create_changeset(new_invite(), User.t(), attrs :: map()) :: Changeset.t(new_invite()) + def create_changeset(invite, %User{id: user_id}, attrs) do 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_number(:uses_left, greater_than_or_equal_to: 0) end diff --git a/lib/cannery_web/live/invite_live/form_component.ex b/lib/cannery_web/live/invite_live/form_component.ex index 1cdf2027..3fd8b3c3 100644 --- a/lib/cannery_web/live/invite_live/form_component.ex +++ b/lib/cannery_web/live/invite_live/form_component.ex @@ -13,23 +13,44 @@ defmodule CanneryWeb.InviteLive.FormComponent do %{:invite => Invite.t(), :current_user => User.t(), optional(any) => any}, Socket.t() ) :: {:ok, Socket.t()} - def update(%{invite: invite} = assigns, socket) do - {:ok, socket |> assign(assigns) |> assign(:changeset, Invites.change_invite(invite))} + def update(%{invite: _invite} = assigns, socket) do + {:ok, socket |> assign(assigns) |> assign_changeset(%{})} end @impl true - def handle_event( - "validate", - %{"invite" => invite_params}, - %{assigns: %{invite: invite}} = socket - ) do - {:noreply, socket |> assign(:changeset, invite |> Invites.change_invite(invite_params))} + def handle_event("validate", %{"invite" => invite_params}, socket) do + {:noreply, socket |> assign_changeset(invite_params)} end def handle_event("save", %{"invite" => invite_params}, %{assigns: %{action: action}} = socket) do save_invite(socket, action, invite_params) 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( %{assigns: %{current_user: current_user, invite: invite, return_to: return_to}} = socket, :edit, diff --git a/priv/gettext/de/LC_MESSAGES/prompts.po b/priv/gettext/de/LC_MESSAGES/prompts.po index cb36e744..1917f9b3 100644 --- a/priv/gettext/de/LC_MESSAGES/prompts.po +++ b/priv/gettext/de/LC_MESSAGES/prompts.po @@ -26,7 +26,7 @@ msgstr "" #, elixir-autogen, elixir-format #: 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/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 msgid "%{name} created successfully" msgstr "%{name} erfolgreich erstellt" @@ -64,7 +64,7 @@ msgstr "%{name} erfolgreich aktualisiert" #, elixir-autogen, elixir-format #: 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/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 msgid "%{name} updated successfully" msgstr "%{name} erfolgreich aktualisiert" diff --git a/priv/gettext/en/LC_MESSAGES/prompts.po b/priv/gettext/en/LC_MESSAGES/prompts.po index 7138934c..fda3e2f9 100644 --- a/priv/gettext/en/LC_MESSAGES/prompts.po +++ b/priv/gettext/en/LC_MESSAGES/prompts.po @@ -14,7 +14,7 @@ msgstr "" #, elixir-autogen, elixir-format #: 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/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 msgid "%{name} created successfully" msgstr "" @@ -52,7 +52,7 @@ msgstr "" #, elixir-autogen, elixir-format #: 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/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 msgid "%{name} updated successfully" msgstr "" diff --git a/priv/gettext/es/LC_MESSAGES/prompts.po b/priv/gettext/es/LC_MESSAGES/prompts.po index 08b04c62..e80b683b 100644 --- a/priv/gettext/es/LC_MESSAGES/prompts.po +++ b/priv/gettext/es/LC_MESSAGES/prompts.po @@ -24,7 +24,7 @@ msgstr "" #, elixir-autogen, elixir-format #: 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/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 msgid "%{name} created successfully" msgstr "" @@ -62,7 +62,7 @@ msgstr "" #, elixir-autogen, elixir-format #: 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/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 msgid "%{name} updated successfully" msgstr "" diff --git a/priv/gettext/fr/LC_MESSAGES/prompts.po b/priv/gettext/fr/LC_MESSAGES/prompts.po index a6b1d7a9..ed795e49 100644 --- a/priv/gettext/fr/LC_MESSAGES/prompts.po +++ b/priv/gettext/fr/LC_MESSAGES/prompts.po @@ -26,7 +26,7 @@ msgstr "" #, elixir-autogen, elixir-format #: 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/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 msgid "%{name} created successfully" msgstr "%{name} créé· avec succès" @@ -64,7 +64,7 @@ msgstr "%{name} mis à jour avec succès" #, elixir-autogen, elixir-format #: 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/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 msgid "%{name} updated successfully" msgstr "%{name} mis à jour avec succès" diff --git a/priv/gettext/prompts.pot b/priv/gettext/prompts.pot index fe6e9e93..f3c3bc04 100644 --- a/priv/gettext/prompts.pot +++ b/priv/gettext/prompts.pot @@ -13,7 +13,7 @@ msgstr "" #, elixir-autogen, elixir-format #: 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/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 msgid "%{name} created successfully" msgstr "" @@ -51,7 +51,7 @@ msgstr "" #, elixir-autogen, elixir-format #: 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/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 msgid "%{name} updated successfully" msgstr "" diff --git a/test/cannery/invites_test.exs b/test/cannery/invites_test.exs index 4084dfd5..a3678002 100644 --- a/test/cannery/invites_test.exs +++ b/test/cannery/invites_test.exs @@ -68,9 +68,5 @@ defmodule Cannery.InvitesTest do assert {:ok, %Invite{}} = Invites.delete_invite(invite, current_user) assert_raise Ecto.NoResultsError, fn -> Invites.get_invite!(invite.id, current_user) end end - - test "change_invite/1 returns a invite changeset", %{invite: invite} do - assert %Changeset{} = Invites.change_invite(invite) - end end end