Packages
potionx
0.2.18
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.0
0.2.18
0.2.17
0.2.16
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.1.1
0.1.0
Potionx is a set of generators and functions that speeds up the process of setting up and deploying a full-stack application that uses Elixir with GraphQL for the server-side component and Vue for the frontend component.
Current section
Files
Jump to
Current section
Files
lib/potionx/pow/pow_assent_context.ex
defmodule Potionx.PowAssent.Context do
use PowAssent.Ecto.UserIdentities.Context
defp convert_params(params) when is_map(params) do
params
|> Enum.map(&convert_param/1)
|> :maps.from_list()
end
defp convert_param({:uid, value}), do: convert_param({"uid", value})
defp convert_param({"uid", value}) when is_integer(value), do: convert_param({"uid", Integer.to_string(value)})
defp convert_param({key, value}) when is_atom(key), do: {Atom.to_string(key), value}
defp convert_param({key, value}) when is_binary(key), do: {key, value}
@doc """
Inserts a changeset to the database.
If succesful, the returned row will be reloaded from the database.
"""
def do_insert(changeset, config, user) do
opts = repo_opts(config, [:prefix])
changeset
|> Pow.Config.repo!(config).insert(opts)
|> reload_after_write(config, user)
end
@doc """
Updates a changeset in the database.
If succesful, the returned row will be reloaded from the database.
"""
def do_update(changeset, config, user) do
opts = repo_opts(config, [:prefix])
changeset
|> Pow.Config.repo!(config).update(opts)
|> reload_after_write(config, user)
end
defp get_for_user(user, %{"uid" => uid, "provider" => provider}, config) do
user_identity = Ecto.build_assoc(user, :user_identities).__struct__
repo!(config).get_by(user_identity, [user_id: user.id, provider: provider, uid: uid], repo_opts(config, [:prefix]))
end
defp insert_identity(user, user_identity_params, config) do
user_identity = Ecto.build_assoc(user, :user_identities)
user_identity
|> user_identity.__struct__.changeset(user_identity_params)
|> do_insert(config, user)
end
defp reload_after_write({:error, changeset}, _config, _user), do: {:error, changeset}
defp reload_after_write({:ok, struct}, config, user) do
# When ecto updates/inserts, has_many :through associations are set to nil.
# So we'll just reload when writes happen.
Pow.Operations.reload(user, config) || raise "Record does not exist: #{inspect user}"
{:ok, struct}
end
defp repo_opts(config, opts) do
config
|> Pow.Config.get(:repo_opts, [])
|> Keyword.take(opts)
end
defp unique_constraint_error?(errors, field) do
Enum.find_value(errors, false, fn
{^field, {_msg, [constraint: :unique, constraint_name: _name]}} -> true
_any -> false
end)
end
defp update_identity(user, user_identity, additional_params, config) do
user_identity
|> user_identity.__struct__.changeset(additional_params)
|> do_update(config, user)
end
@doc """
Upserts a user identity.
If a matching user identity already exists for the user, the identity will be updated,
otherwise a new identity is inserted.
Repo module will be fetched from config.
"""
def upsert(user, user_identity_params, config) do
params = convert_params(user_identity_params)
{uid_provider_params, additional_params} = Map.split(params, ["uid", "provider"])
user
|> get_for_user(uid_provider_params, config)
|> case do
nil -> insert_identity(user, params, config)
identity -> update_identity(user, identity, additional_params, config)
end
|> user_identity_bound_different_user_error()
end
defp user_identity_bound_different_user_error({:error, %{errors: errors} = changeset}) do
case unique_constraint_error?(errors, :uid_provider) do
true -> {:error, {:bound_to_different_user, changeset}}
false -> {:error, changeset}
end
end
defp user_identity_bound_different_user_error(any), do: any
defdelegate user!(config), to: Pow.Config
defdelegate repo!(config), to: Pow.Config
end