Mix.install([
{:aws, "~> 0.13.3"},
{:hackney, "~> 1.18"},
{:kino, "~> 0.10.0"}
])
client =
AWS.Client.create("chea", "pizza", "us-west-1")
|> AWS.Client.put_endpoint("localstack:4566")
|> Map.put(:proto, "http")
defmodule KmsManage do
def find(client, alias_name) do
case list_aliases(client) do
[] ->
nil
{:error, error} ->
{:error, error}
aliases ->
aliases
|> Enum.find(%{}, fn %{"AliasName" => kms_alias} ->
kms_alias == alias_name
end)
|> Map.get("AliasName")
end
end
def find_or_create_alias(client, alias_name) do
case find(client, alias_name) do
nil ->
create_alias(client, alias_name)
{:error, error} ->
{:error, error}
alias_name ->
alias_name
end
end
def create_alias(client, alias_name) do
{:ok, %{"KeyMetadata" => %{"KeyId" => key_id}}, _body} =
AWS.KMS.create_key(client, %{"Description" => "Key for #{alias_name}"})
{:ok, _result, _body} =
AWS.KMS.create_alias(client, %{"AliasName" => alias_name, "TargetKeyId" => key_id})
alias_name
end
def list_aliases(client) do
case AWS.KMS.list_aliases(client, %{}) do
{:ok, %{"Aliases" => aliases}, _body} ->
aliases
{:error, error} ->
{:error, error}
end
end
end
form =
Kino.Control.form(
[
alias_to_create: Kino.Input.text("Create new alias")
],
submit: "Submit"
)
form
Kino.listen(form, fn event ->
KmsManage.find_or_create_alias(client, event.data.alias_to_create)
list = KmsManage.list_aliases(client)
Kino.render(Kino.DataTable.new(list))
end)
form =
Kino.Control.form(
[
alias_name: Kino.Input.text("Alias Name"),
payload: Kino.Input.textarea("Payload")
],
submit: "Submit"
)
form
encrypted = %{}
form
|> Kino.Control.stream()
|> Kino.listen(fn event ->
{:ok, %{"CiphertextBlob" => encrypted}, _} =
AWS.KMS.encrypt(client, %{
"Plaintext" => Base.encode64(event.data.payload),
"KeyId" => event.data.alias_name
})
Kino.render(encrypted)
end)