-module(glm_vault@vault). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/glm_vault/vault.gleam"). -export([new_vault/1, decrypt/2, encrypt/3, get_int/2, set_int/3, get_float/2, set_float/3, get_bool/2, set_bool/3, get_string/2, set_string/3, get_keys/1]). -export_type([vault/0, vault_error/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -opaque vault() :: {vault, gleam@dict:dict(binary(), tom:toml())}. -type vault_error() :: {unable_to_serialize_unsupported_type, tom:toml()} | {unable_to_get_from_vault, tom:get_error()} | {unable_to_decrypt_file, glm_encrypted_file@openssl:open_ssl_error(), binary(), binary()} | {unable_to_encrypt_file, simplifile:file_error()} | {unable_to_get_from_dict, binary()} | {unable_to_parse_decrypted_plaintext, binary(), tom:parse_error()}. -file("src/glm_vault/vault.gleam", 21). ?DOC(" Create a new vault.\n"). -spec new_vault(gleam@dict:dict(binary(), tom:toml())) -> vault(). new_vault(Secrets) -> {vault, Secrets}. -file("src/glm_vault/vault.gleam", 36). ?DOC(" Decrypt an encrypted file and return a vault instance.\n"). -spec decrypt(binary(), binary()) -> {ok, vault()} | {error, vault_error()}. decrypt(Encrypted_file, Password_file) -> _pipe = glm_encrypted_file@openssl:decrypt(Encrypted_file, Password_file), _pipe@1 = gleam@result:map_error( _pipe, fun(_capture) -> {unable_to_decrypt_file, _capture, Encrypted_file, Password_file} end ), gleam@result:'try'(_pipe@1, fun(Plaintext) -> _pipe@2 = Plaintext, _pipe@3 = tom:parse(_pipe@2), _pipe@4 = gleam@result:map_error( _pipe@3, fun(_capture@1) -> {unable_to_parse_decrypted_plaintext, Plaintext, _capture@1} end ), gleam@result:map(_pipe@4, fun new_vault/1) end). -file("src/glm_vault/vault.gleam", 62). ?DOC( " Serialize a single item, so long as it is one of these supported datatypes: string, int, float, bool.\n" "\n" " Implementation details that should not concern the consumer:\n" " Items are serialized as `key = value` pairs in `toml` format.\n" ). -spec serialize_item(gleam@dict:dict(binary(), tom:toml()), binary()) -> {ok, binary()} | {error, vault_error()}. serialize_item(D, Key) -> gleam@result:'try'( begin _pipe = gleam_stdlib:map_get(D, Key), gleam@result:map_error( _pipe, fun(_) -> {unable_to_get_from_dict, Key} end ) end, fun(Value) -> case Value of {int, X} -> {ok, <<<>/binary, X@1/binary>>/binary, "\""/utf8>>}; {bool, X@2} -> {ok, <<<>/binary, (begin _pipe@3 = X@3, gleam_stdlib:float_to_string(_pipe@3) end)/binary>>}; T -> {error, {unable_to_serialize_unsupported_type, T}} end end ). -file("src/glm_vault/vault.gleam", 52). ?DOC( " Serialize dict that contains these datatypes: string, int, float, bool.\n" " Nested datatypes and arrays are not supported.\n" ). -spec serialize(gleam@dict:dict(binary(), tom:toml())) -> {ok, list(binary())} | {error, vault_error()}. serialize(D) -> _pipe = maps:keys(D), _pipe@1 = gleam@list:map(_pipe, fun(Key) -> serialize_item(D, Key) end), gleam@result:all(_pipe@1). -file("src/glm_vault/vault.gleam", 90). ?DOC( " Serialize a vault instance to a temporary file, then encrypt that file and delete the temporary file.\n" " Upon success, an encrypted file is created that contains the serialized contents of the vault.\n" ). -spec encrypt(vault(), binary(), binary()) -> {ok, nil} | {error, vault_error()}. encrypt(Vault, Encrypted_file, Password_file) -> Result = begin temporary:create( temporary:file(), fun(Temp_file) -> Rw = gleam@set:from_list([read, write]), None = gleam@set:from_list([]), gleam@result:'try'( simplifile:set_permissions( Temp_file, {file_permissions, Rw, None, None} ), fun(_) -> _ = begin _pipe = erlang:element(2, Vault), _pipe@1 = serialize(_pipe), _pipe@2 = gleam@result:map( _pipe@1, fun(_capture) -> gleam@string:join(_capture, <<"\n"/utf8>>) end ), _pipe@3 = gleam@result:map( _pipe@2, fun(_capture@1) -> simplifile:write(Temp_file, _capture@1) end ), gleam@result:map( _pipe@3, fun(_) -> _ = glm_encrypted_file@openssl:encrypt( Temp_file, Encrypted_file, Password_file ) end ) end, {ok, nil} end ) end ) end, case Result of {ok, _} -> {ok, nil}; {error, E} -> {error, {unable_to_encrypt_file, E}} end. -file("src/glm_vault/vault.gleam", 124). -spec get_int(vault(), binary()) -> {ok, integer()} | {error, vault_error()}. get_int(V, Key) -> _pipe = tom:get_int(erlang:element(2, V), [Key]), gleam@result:map_error( _pipe, fun(Field@0) -> {unable_to_get_from_vault, Field@0} end ). -file("src/glm_vault/vault.gleam", 129). -spec set_int(vault(), binary(), integer()) -> vault(). set_int(V, Key, Value) -> Secrets = gleam@dict:insert(erlang:element(2, V), Key, {int, Value}), {vault, Secrets}. -file("src/glm_vault/vault.gleam", 134). -spec get_float(vault(), binary()) -> {ok, float()} | {error, vault_error()}. get_float(V, Key) -> _pipe = tom:get_float(erlang:element(2, V), [Key]), gleam@result:map_error( _pipe, fun(Field@0) -> {unable_to_get_from_vault, Field@0} end ). -file("src/glm_vault/vault.gleam", 139). -spec set_float(vault(), binary(), float()) -> vault(). set_float(V, Key, Value) -> Secrets = gleam@dict:insert(erlang:element(2, V), Key, {float, Value}), {vault, Secrets}. -file("src/glm_vault/vault.gleam", 144). -spec get_bool(vault(), binary()) -> {ok, boolean()} | {error, vault_error()}. get_bool(V, Key) -> _pipe = tom:get_bool(erlang:element(2, V), [Key]), gleam@result:map_error( _pipe, fun(Field@0) -> {unable_to_get_from_vault, Field@0} end ). -file("src/glm_vault/vault.gleam", 149). -spec set_bool(vault(), binary(), boolean()) -> vault(). set_bool(V, Key, Value) -> Secrets = gleam@dict:insert(erlang:element(2, V), Key, {bool, Value}), {vault, Secrets}. -file("src/glm_vault/vault.gleam", 154). -spec get_string(vault(), binary()) -> {ok, binary()} | {error, vault_error()}. get_string(V, Key) -> _pipe = tom:get_string(erlang:element(2, V), [Key]), gleam@result:map_error( _pipe, fun(Field@0) -> {unable_to_get_from_vault, Field@0} end ). -file("src/glm_vault/vault.gleam", 159). -spec set_string(vault(), binary(), binary()) -> vault(). set_string(V, Key, Value) -> Secrets = gleam@dict:insert(erlang:element(2, V), Key, {string, Value}), {vault, Secrets}. -file("src/glm_vault/vault.gleam", 164). -spec get_keys(vault()) -> {ok, list(binary())} | {error, vault_error()}. get_keys(V) -> _pipe = maps:keys(erlang:element(2, V)), {ok, _pipe}.