defmodule LiveBeats.Accounts do import Ecto.Query import Ecto.Changeset alias LiveBeats.Repo alias LiveBeats.Accounts.{User, Identity} @admin_emails ["chris@chrismccord.com"] def list_users(opts) do Repo.all(from u in User, limit: ^Keyword.fetch!(opts, :limit)) end def admin?(%User{} = user), do: user.email in @admin_emails ## Database getters @doc """ Gets a user by email. ## Examples iex> get_user_by_email("foo@example.com") %User{} iex> get_user_by_email("unknown@example.com") nil """ def get_user_by_email(email) when is_binary(email) do Repo.get_by(User, email: email) end @doc """ Gets a single user. Raises `Ecto.NoResultsError` if the User does not exist. ## Examples iex> get_user!(123) %User{} iex> get_user!(456) ** (Ecto.NoResultsError) """ def get_user!(id), do: Repo.get!(User, id) ## User registration @doc """ Registers a user from their GithHub information. """ def register_github_user(primary_email, info, emails, token) do if user = get_user_by_provider(:github, primary_email) do update_github_token(user, token) else info |> User.github_registration_changeset(primary_email, emails, token) |> Repo.insert() end end def get_user_by_provider(provider, email) when provider in [:github] do query = from(u in User, join: i in assoc(u, :identities), where: i.provider == ^to_string(provider) and fragment("lower(?)", u.email) == ^String.downcase(email) ) Repo.one(query) end def change_settings(%User{} = user, attrs) do User.settings_changeset(user, attrs) end def update_settings(%User{} = user, attrs) do user |> change_settings(attrs) |> Repo.update() end defp update_github_token(%User{} = user, new_token) do identity = Repo.one!(from(i in Identity, where: i.user_id == ^user.id and i.provider == "github")) {:ok, _} = identity |> change() |> put_change(:provider_token, new_token) |> Repo.update() {:ok, Repo.preload(user, :identities, force: true)} end end