I have in my cloak section in my Resource, defined an encrypted attribute
cloak do
# the vault to use to encrypt them
vault(CheckD.DomainModifiers.Security.Vault)
# the attributes to encrypt
attributes([:message])
# This is just equivalent to always providing `load: fields` on all calls
decrypt_by_default([:message])
end
I’m trying to do empty the message attribute in an action
update :reject do
change set_attribute(:message, %{}) # this is an encrypted field
change set_attribute(:status, :rejected)
change set_attribute(:actioned_at, &DateTime.utc_now/0)
end
Ah, right right. So the way you do this is different. We replace the accepted attribute with a correspondingly named argument. What you should do instead is make a custom change that uses AshCloak.encrypt_and_set(changeset, attribute, value)
defmodule CheckD.DomainModifiers.SetEncryptedAttribute do
use Ash.Resource.Change
def change(changeset, opts, context) do
changeset |> AshCloak.encrypt_and_set(opts[:attribute], opts[:value])
end
def atomic(changeset, opts, context), do: {:ok, change(changeset, opts, context)}
end
My use
update :reject do
change {CheckD.DomainModifiers.SetEncryptedAttribute, attribute: :message, value: %{}}
change set_attribute(:status, :rejected)
change set_attribute(:actioned_at, &DateTime.utc_now/0)
end
now while the above SetEncryptedAttribute works, it is assumed that the input :attribute is configured as encryptable, or else a Runtime Error is thrown.
I think a better option would either be
a Util function is_attribute_encryptable to check if that attribute is configured for encryption. OR
the AshCloak.encrypt_and_set throws a catchable error.