Skip to content

Commit 3acbb67

Browse files
author
Robert Adams
committed
Throw exceptions instead of returning errors
1 parent 0788f4e commit 3acbb67

File tree

3 files changed

+51
-18
lines changed

3 files changed

+51
-18
lines changed

lib/ssh_client_key_api.ex

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
defmodule SSHClientKeyAPI do
2+
alias SSHClientKeyAPI.KeyError
23

34
@behaviour :ssh_client_key_api
45
@key_algorithms :ssh.default_algorithms()[:public_key]
@@ -103,23 +104,25 @@ defmodule SSHClientKeyAPI do
103104
end
104105

105106
def user_key(alg, _) do
106-
message = "unsupported user key algorithm #{inspect alg}"
107-
IO.puts(message)
108-
{:error, message}
107+
raise KeyError, {:unsupported_algorithm, alg}
108+
end
109+
110+
defp decode_pem_entry(nil, _phrase) do
111+
raise KeyError, {:unsupported_algorithm, :unknown}
109112
end
110113

111114
defp decode_pem_entry({_type, _data, :not_encrypted} = entry, _) do
112115
{:ok, :public_key.pem_entry_decode(entry)}
113116
end
114117

115-
defp decode_pem_entry({_type, _data, _cipher_info}, nil) do
116-
{:error, "passphrase needed for protected key"}
118+
defp decode_pem_entry({_type, _data, {alg, _}}, nil) do
119+
raise KeyError, {:passphrase_required, alg}
117120
end
118121

119-
defp decode_pem_entry({_type, _data, _cipher_info} = entry, phrase) do
120-
{:ok, :public_key.pem_entry_decode(entry, phrase)}
122+
defp decode_pem_entry({_type, _data, {alg, _}} = entry, phrase) do
123+
{:ok, :public_key.pem_entry_decode(entry, phrase)}
121124
rescue
122-
_e in MatchError -> {:error, "passphrase for protected key is invalid"}
125+
_e in MatchError -> raise KeyError, {:incorrect_passphrase, alg}
123126
end
124127

125128
defp identity_data(opts) do

lib/ssh_client_key_api/key_error.ex

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
defmodule SSHClientKeyAPI.KeyError do
2+
defexception [:reason, :algorithm]
3+
4+
def exception({reason, algo}), do: %__MODULE__{reason: reason, algorithm: algo}
5+
6+
def exception(reason), do: %__MODULE__{reason: reason}
7+
8+
def message(%__MODULE__{reason: :unsupported_algorithm}), do: "key algorithm is not supported"
9+
10+
def message(%__MODULE__{reason: :passphrase_required}),
11+
do: "passphrase required for protected key"
12+
13+
def message(%__MODULE__{reason: :incorrect_passphrase}),
14+
do: "passphrase invalid for protected key"
15+
16+
def message(%__MODULE__{reason: :unsupported_algorithm, algorithm: algo}),
17+
do: "key algorithm is not supported: #{algo}"
18+
end

test/ssh_client_key_api_test.exs

+22-10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ defmodule SSHClientKeyAPITest do
22
use ExUnit.Case
33

44
alias SSHClientKeyAPI
5+
alias SSHClientKeyAPI.KeyError
56

67
@private_key """
78
-----BEGIN RSA PRIVATE KEY-----
@@ -132,19 +133,30 @@ FSlw/QlRe3XqAJDRtHyiI2d4JIPFcOjZQSF7fURYPEKaRRtQRvSaI0D9fYwuRZDY
132133
end
133134

134135
test "user key returns error if passphrase is missing for protected key", %{protected_key: protected_key} do
135-
result = SSHClientKeyAPI.user_key(
136-
:"ssh-dss",
137-
[key_cb_private: [identity: protected_key, identity_data: IO.binread(protected_key, :all)]]
138-
)
139-
assert {:error, _} = result
136+
assert_raise KeyError, ~r/passphrase required/, fn ->
137+
SSHClientKeyAPI.user_key(
138+
:"ssh-dss",
139+
[key_cb_private: [identity: protected_key, identity_data: IO.binread(protected_key, :all)]]
140+
)
141+
end
140142
end
141143

142144
test "user key returns error if passphrase is incorrect for protected key", %{protected_key: protected_key} do
143-
result = SSHClientKeyAPI.user_key(
144-
:"ssh-dss",
145-
[key_cb_private: [passphrase: 'wrong', identity: protected_key, identity_data: IO.binread(protected_key, :all)]]
146-
)
147-
assert {:error, _} = result
145+
assert_raise KeyError, ~r/passphrase invalid/, fn ->
146+
SSHClientKeyAPI.user_key(
147+
:"ssh-dss",
148+
[key_cb_private: [passphrase: 'wrong', identity: protected_key, identity_data: IO.binread(protected_key, :all)]]
149+
)
150+
end
151+
end
152+
153+
test "user key returns error if trying to use unsupported algorithm", %{protected_key: protected_key} do
154+
assert_raise KeyError, ~r/not supported/, fn ->
155+
SSHClientKeyAPI.user_key(
156+
:"ssh-scooby-doo",
157+
[key_cb_private: [passphrase: 'wrong', identity: protected_key, identity_data: IO.binread(protected_key, :all)]]
158+
)
159+
end
148160
end
149161

150162
test "with correct passphrase, user key returns contents of protected key", %{protected_key: protected_key} do

0 commit comments

Comments
 (0)