meta/lib/recycledcloud/accounts/key.ex

48 lines
1.4 KiB
Elixir

defmodule RecycledCloud.Accounts.Key do
use Ecto.Schema
import Ecto.Changeset
schema "keys" do
field :comment, :string
field :value, :string
field :fingerprint, :string
belongs_to :user, RecycledCloud.Accounts.User
timestamps()
end
def process_ssh_key(changeset, value_field, fingerprint_field, comment_field) do
raw_value = get_field(changeset, value_field)
comment = get_field(changeset, comment_field)
with {:is_valid, true} <- {:is_valid, changeset.valid?},
[{pk, attrs}] <- :public_key.ssh_decode(raw_value, :public_key) do
fingerprint = :public_key.ssh_hostkey_fingerprint(pk) |> List.to_string
changeset = put_change(changeset, fingerprint_field, fingerprint)
# Fetch comment from key, if not provided.
embedded_comment = attrs
|> Enum.into(%{})
|> Map.get(:comment)
case {comment, embedded_comment} do
{nil, nil} -> changeset
{nil, new_comment} ->
put_change(changeset, comment_field, List.to_string(new_comment))
{_, _} -> changeset
end
else
{:is_valid, false} -> changeset
_ -> add_error(changeset, value_field, "key is invalid")
end
end
@doc false
def changeset(key, attrs) do
key
|> cast(attrs, [:comment, :value])
|> validate_required([:value])
|> process_ssh_key(:value, :fingerprint, :comment)
end
end