mirror of
https://github.com/mgerb/classic-wow-forums
synced 2026-01-11 01:22:49 +00:00
authentication with persistence working
This commit is contained in:
81
lib/myapp/data/user.ex
Normal file
81
lib/myapp/data/user.ex
Normal file
@@ -0,0 +1,81 @@
|
||||
defmodule MyApp.Data.User do
|
||||
use Ecto.Schema
|
||||
import Ecto.Query
|
||||
import Ecto.Changeset
|
||||
alias MyApp.Repo
|
||||
alias MyApp.Data
|
||||
|
||||
@derive {Poison.Encoder, except: [:__meta__]}
|
||||
schema "user" do
|
||||
field :battle_net_id, :integer
|
||||
field :battletag, :string
|
||||
timestamps()
|
||||
end
|
||||
|
||||
def changeset(user, params \\ %{}) do
|
||||
user
|
||||
|> cast(params, [:battle_net_id, :battletag])
|
||||
|> validate_required([:battle_net_id, :battletag])
|
||||
|> unique_constraint(:battle_net_id)
|
||||
end
|
||||
|
||||
@spec get_user(integer) :: nil | map
|
||||
defp get_user(battle_net_id) do
|
||||
query = from u in "user",
|
||||
where: u.battle_net_id == ^battle_net_id,
|
||||
select: [:id, :battle_net_id, :battletag]
|
||||
Repo.one(query)
|
||||
end
|
||||
|
||||
# insert user info in database - if not exists - update battletag if it has changed
|
||||
@spec upsert_user(%{"battle_net_id": integer, "battletag": String.t} | tuple) :: {:ok, map} | {:error, any}
|
||||
def upsert_user(params) when is_map(params) do
|
||||
# check for current user in database
|
||||
case get_user(Map.get(params, "battle_net_id")) do
|
||||
nil -> insert_user(params)
|
||||
user ->
|
||||
# update user if battletag has changed
|
||||
if Map.get(user, :battletag) != Map.get(params, "battletag") do
|
||||
update_battletag(user, params)
|
||||
else
|
||||
{:ok, user}
|
||||
end
|
||||
end
|
||||
|> add_access_token(Map.get(params, "access_token"))
|
||||
end
|
||||
def upsert_user({:ok, params}), do: upsert_user(params)
|
||||
def upsert_user({:error, error}), do: {:error, error}
|
||||
|
||||
# need to add token back to map because we don't store it in the database
|
||||
defp add_access_token({:error, error}, _), do: {:error, error}
|
||||
defp add_access_token({:ok, user}, access_token) do
|
||||
{:ok, Map.merge(user, %{access_token: access_token})}
|
||||
end
|
||||
|
||||
defp insert_user(params) do
|
||||
cs = changeset(%Data.User{}, params)
|
||||
cs
|
||||
|> Repo.insert
|
||||
|> process_insert_or_update
|
||||
end
|
||||
|
||||
# it's possible for a user's battle tag to change - if so update it
|
||||
defp update_battletag(user, params) do
|
||||
cs = Data.User.changeset(Map.merge(%Data.User{}, user), %{battletag: Map.get(params, "battletag")})
|
||||
cs
|
||||
|> Repo.update
|
||||
|> process_insert_or_update
|
||||
end
|
||||
|
||||
defp process_insert_or_update({:error, changeset}), do: {:error, map_changeset(changeset)}
|
||||
defp process_insert_or_update({:ok, user}) do
|
||||
{:ok, Map.take(user, [:id, :battle_net_id, :battletag])} # only grab the fields we need
|
||||
end
|
||||
|
||||
defp map_changeset(changeset) do
|
||||
Enum.map(changeset.errors, fn {key, val} ->
|
||||
%{key => elem(val, 0)}
|
||||
end)
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user