Users can now register beacon monitors on the settings page. Each monitor gets a unique random token the remote program will use to authenticate its reports. Name is the only user-supplied field for now; more will be added as the monitor protocol is defined. Also adds :gen_smtp to deps. Swoosh's SMTP adapter depends on :mimemail which lives in that package, and production was 500'ing when trying to send confirmation emails without it.
74 lines
1.9 KiB
Elixir
74 lines
1.9 KiB
Elixir
defmodule Microwaveprop.BeaconMonitors do
|
|
@moduledoc """
|
|
The BeaconMonitors context: manages the monitor stations a user
|
|
has registered. Each monitor has a unique random token the remote
|
|
program uses to authenticate its reports.
|
|
"""
|
|
|
|
import Ecto.Query
|
|
|
|
alias Microwaveprop.Accounts.User
|
|
alias Microwaveprop.BeaconMonitors.BeaconMonitor
|
|
alias Microwaveprop.Repo
|
|
|
|
@token_bytes 32
|
|
|
|
@doc """
|
|
Returns all monitors for the given user, newest first.
|
|
"""
|
|
def list_monitors_for_user(%User{id: user_id}) do
|
|
Repo.all(
|
|
from m in BeaconMonitor,
|
|
where: m.user_id == ^user_id,
|
|
order_by: [desc: m.inserted_at]
|
|
)
|
|
end
|
|
|
|
@doc """
|
|
Creates a new monitor for the given user with a freshly generated token.
|
|
"""
|
|
def create_monitor(%User{} = user, attrs) do
|
|
%BeaconMonitor{user_id: user.id, token: generate_token()}
|
|
|> BeaconMonitor.changeset(attrs)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
@doc """
|
|
Deletes a monitor owned by the given user.
|
|
|
|
Returns `{:error, :not_found}` if the monitor does not exist or
|
|
belongs to another user.
|
|
"""
|
|
def delete_monitor(%User{id: user_id}, monitor_id) do
|
|
query =
|
|
from m in BeaconMonitor,
|
|
where: m.id == ^monitor_id and m.user_id == ^user_id
|
|
|
|
case Repo.one(query) do
|
|
nil -> {:error, :not_found}
|
|
monitor -> Repo.delete(monitor)
|
|
end
|
|
rescue
|
|
Ecto.Query.CastError -> {:error, :not_found}
|
|
end
|
|
|
|
@doc """
|
|
Looks up a monitor by its token. Returns nil if not found.
|
|
"""
|
|
def get_monitor_by_token(token) when is_binary(token) do
|
|
Repo.get_by(BeaconMonitor, token: token)
|
|
end
|
|
|
|
@doc """
|
|
Returns a blank changeset for rendering the new-monitor form.
|
|
"""
|
|
def change_monitor(attrs \\ %{}) do
|
|
BeaconMonitor.changeset(%BeaconMonitor{}, attrs)
|
|
end
|
|
|
|
defp generate_token do
|
|
@token_bytes
|
|
|> :crypto.strong_rand_bytes()
|
|
|> Base.url_encode64(padding: false)
|
|
end
|
|
end
|