Packages

Extensible Elixir OTP Application for storing files through a unified API. Backends currently exist for the local filesystem, SFTP and the Amazon S3 API.

Current section

Files

Jump to
belt test provider sftp_test.exs
Raw

test/provider/sftp_test.exs

defmodule Belt.Test.Provider.SFTP do
use Belt.Test.Provider,
provider: Belt.Provider.SFTP
@daemon_host "localhost"
@daemon_port 8900
@user "edna"
@password "Th31maElłen"
setup_all do
dir = create_tmp_dir()
storage_dir = Path.join(dir, "storage")
config_dir = Path.join(dir, "config")
[storage_dir, config_dir] |> Enum.each(&File.mkdir(&1))
#Create host key
key_path = Path.join(config_dir, "ssh_host_rsa_key")
{_, 0} = System.cmd("ssh-keygen", ["-m", "PEM", "-t", "rsa", "-N", "", "-f", key_path])
host_key = load_public_key(key_path <> ".pub")
#Create user key
user_key_path = Path.join(config_dir, "ssh_user_key")
{_, 0} = System.cmd("ssh-keygen", ["-m", "PEM", "-t", "rsa", "-N", "", "-f", user_key_path])
File.cp(user_key_path <> ".pub", Path.join(config_dir, "authorized_keys"))
user_key = load_key(user_key_path)
#:timer.sleep 5000
#SSH Daemon configuration
passwords = [{@user |> to_charlist(), @password |> to_charlist()}]
subsystem_spec = :ssh_sftpd.subsystem_spec(
cwd: storage_dir |> String.to_charlist(),
root: storage_dir |> String.to_charlist())
ssh_daemon_opts = [subsystems: [subsystem_spec],
system_dir: config_dir |> to_charlist(),
user_dir: config_dir |> to_charlist(),
user_passwords: passwords
]
:ssh.start()
{:ok, ssh_daemon} = :ssh.daemon(@daemon_port, ssh_daemon_opts)
on_exit(fn ->
:ssh.stop_daemon(ssh_daemon)
File.rm_rf(dir)
end)
{:ok, dir: dir, host_key: host_key, user_key: user_key}
end
def config_opts(_context) do
[host: @daemon_host,
user: @user,
password: @password,
port: @daemon_port,
verify_host_key: false,
base_url: "https://example.org"]
end
@pem_regex ~r/[-]+BEGIN RSA PRIVATE KEY.*END RSA PRIVATE KEY[-]+\n/s
defp load_key(path) do
file_contents = File.read!(path)
Regex.run(@pem_regex, file_contents)
|> List.first()
|> :public_key.pem_decode()
|> List.first()
|> :public_key.pem_entry_decode()
end
defp load_public_key(path) do
File.read!(path)
|> :public_key.ssh_decode(:public_key)
|> List.first()
|> elem(0)
end
test "using keys",
%{provider: provider, host_key: host_key, user_key: user_key} = context do
host_key = :public_key.ssh_hostkey_fingerprint(:sha256, host_key)
|> to_string()
user_key = [:public_key.pem_entry_encode(:RSAPrivateKey, user_key)]
|> :public_key.pem_encode()
|> to_string()
config_opts = config_opts(context)
|> Keyword.delete(:user)
|> Keyword.delete(:password)
|> Keyword.put(:user_key, user_key)
|> Keyword.put(:verify_host_key, true)
|> Keyword.put(:host_key, host_key)
{:ok, config} = provider.new(config_opts)
assert {:ok, _} = Belt.list_files(config)
end
test "get default config" do
defaults = [host: "example.org", user: "foo", password: "bar"]
Application.put_env(:belt, Belt.Provider.SFTP, default: defaults)
{:ok, config} = Belt.Provider.SFTP.default()
Enum.each(defaults, fn({key, val}) ->
assert Map.get(config, key) == val
end)
end
end