2017-02-02 01:14:58 +08:00
|
|
|
-module('Elixir.RabbitMQ.CLI.Ctl.Commands.AddUaaKeyCommand').
|
|
|
|
|
|
|
|
|
|
-behaviour('Elixir.RabbitMQ.CLI.CommandBehaviour').
|
|
|
|
|
|
|
|
|
|
-export([
|
|
|
|
|
usage/0,
|
|
|
|
|
validate/2,
|
|
|
|
|
merge_defaults/2,
|
|
|
|
|
banner/2,
|
|
|
|
|
run/2,
|
|
|
|
|
switches/0,
|
|
|
|
|
aliases/0,
|
|
|
|
|
output/2,
|
|
|
|
|
formatter/0
|
|
|
|
|
]).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
usage() ->
|
2017-09-20 23:40:56 +08:00
|
|
|
<<"add_uaa_key <name> [--json=<json_key>] [--pem=<public_key>] [--pem_file=<pem_file>]">>.
|
2017-02-02 01:14:58 +08:00
|
|
|
|
|
|
|
|
switches() ->
|
|
|
|
|
[{json, string},
|
2017-09-20 23:40:56 +08:00
|
|
|
{pem, string},
|
|
|
|
|
{pem_file, string}].
|
2017-02-02 01:14:58 +08:00
|
|
|
|
|
|
|
|
aliases() -> [].
|
|
|
|
|
|
|
|
|
|
validate([], _Options) -> {validation_failure, not_enough_args};
|
|
|
|
|
validate([_,_|_], _Options) -> {validation_failure, too_many_args};
|
|
|
|
|
validate([_], Options) ->
|
|
|
|
|
Json = maps:get(json, Options, undefined),
|
|
|
|
|
Pem = maps:get(pem, Options, undefined),
|
2017-09-20 23:40:56 +08:00
|
|
|
PemFile = maps:get(pem_file, Options, undefined),
|
|
|
|
|
case {is_binary(Json), is_binary(Pem), is_binary(PemFile)} of
|
|
|
|
|
{false, false, false} ->
|
2017-02-02 01:14:58 +08:00
|
|
|
{validation_failure,
|
|
|
|
|
{bad_argument, <<"No key specified">>}};
|
2017-09-20 23:40:56 +08:00
|
|
|
{true, false, false} ->
|
2017-02-02 20:25:38 +08:00
|
|
|
validate_json(Json);
|
2017-09-20 23:40:56 +08:00
|
|
|
{false, true, false} ->
|
|
|
|
|
validate_pem(Pem);
|
|
|
|
|
{false, false, true} ->
|
|
|
|
|
validate_pem_file(PemFile);
|
|
|
|
|
{_, _, _} ->
|
|
|
|
|
{validation_failure,
|
|
|
|
|
{bad_argument, <<"There can be only one key type">>}}
|
2017-02-02 01:14:58 +08:00
|
|
|
end.
|
|
|
|
|
|
2017-02-02 20:25:38 +08:00
|
|
|
validate_json(Json) ->
|
2017-02-02 01:14:58 +08:00
|
|
|
case rabbit_json:try_decode(Json) of
|
2017-02-02 19:29:25 +08:00
|
|
|
{ok, _} ->
|
2018-06-22 00:07:35 +08:00
|
|
|
case uaa_jwt:verify_signing_key(json, Json) of
|
2017-02-02 19:29:25 +08:00
|
|
|
ok -> ok;
|
2017-02-02 20:25:38 +08:00
|
|
|
{error, {fields_missing_for_kty, Kty}} ->
|
|
|
|
|
{validation_failure,
|
|
|
|
|
{bad_argument,
|
|
|
|
|
<<"Key fields are missing fot kty \"", Kty/binary, "\"">>}};
|
2017-02-02 19:29:25 +08:00
|
|
|
{error, unknown_kty} ->
|
|
|
|
|
{validation_failure,
|
2017-02-02 20:25:38 +08:00
|
|
|
{bad_argument, <<"\"kty\" field is invalid">>}};
|
|
|
|
|
{error, no_kty} ->
|
|
|
|
|
{validation_failure,
|
|
|
|
|
{bad_argument, <<"Json key should contain \"kty\" field">>}};
|
2017-02-02 19:29:25 +08:00
|
|
|
{error, Err} ->
|
|
|
|
|
{validation_failure, {bad_argument, Err}}
|
|
|
|
|
end;
|
2017-02-16 23:58:39 +08:00
|
|
|
{error, _} ->
|
|
|
|
|
{validation_failure, {bad_argument, <<"Invalid JSON">>}};
|
2017-02-02 19:29:25 +08:00
|
|
|
error ->
|
|
|
|
|
{validation_failure, {bad_argument, <<"Invalid JSON">>}}
|
2017-02-02 01:14:58 +08:00
|
|
|
end.
|
|
|
|
|
|
2017-09-20 23:40:56 +08:00
|
|
|
validate_pem(Pem) ->
|
2018-06-22 00:07:35 +08:00
|
|
|
case uaa_jwt:verify_signing_key(pem, Pem) of
|
2017-09-20 23:40:56 +08:00
|
|
|
ok -> ok;
|
|
|
|
|
{error, invalid_pem_string} ->
|
|
|
|
|
{validation_failure, <<"Unable to read a key from the PEM string">>};
|
|
|
|
|
{error, Err} ->
|
|
|
|
|
{validation_failure, Err}
|
|
|
|
|
end.
|
|
|
|
|
|
|
|
|
|
validate_pem_file(PemFile) ->
|
2018-06-22 00:07:35 +08:00
|
|
|
case uaa_jwt:verify_signing_key(pem_file, PemFile) of
|
2017-02-02 19:29:25 +08:00
|
|
|
ok -> ok;
|
|
|
|
|
{error, enoent} ->
|
|
|
|
|
{validation_failure, {bad_argument, <<"PEM file not found">>}};
|
|
|
|
|
{error, invalid_pem_file} ->
|
|
|
|
|
{validation_failure, <<"Unable to read a key from the PEM file">>};
|
|
|
|
|
{error, Err} ->
|
|
|
|
|
{validation_failure, Err}
|
2017-02-02 01:14:58 +08:00
|
|
|
end.
|
|
|
|
|
|
2017-09-20 23:40:56 +08:00
|
|
|
merge_defaults(Args, #{pem_file := FileName} = Options) ->
|
2017-02-02 01:14:58 +08:00
|
|
|
AbsFileName = filename:absname(FileName),
|
2017-09-20 23:40:56 +08:00
|
|
|
{Args, Options#{pem_file := AbsFileName}};
|
2017-02-02 01:14:58 +08:00
|
|
|
merge_defaults(Args, Options) -> {Args, Options}.
|
|
|
|
|
|
|
|
|
|
banner([Name], #{json := Json}) ->
|
|
|
|
|
<<"Adding UAA signing key \"",
|
|
|
|
|
Name/binary,
|
|
|
|
|
"\" in JSON format: \"",
|
|
|
|
|
Json/binary, "\"">>;
|
|
|
|
|
banner([Name], #{pem := Pem}) ->
|
2017-09-20 23:40:56 +08:00
|
|
|
<<"Adding UAA signing key \"",
|
|
|
|
|
Name/binary,
|
|
|
|
|
"\" public key: \"",
|
|
|
|
|
Pem/binary, "\"">>;
|
|
|
|
|
banner([Name], #{pem_file := PemFile}) ->
|
2017-02-02 01:14:58 +08:00
|
|
|
<<"Adding UAA signing key \"",
|
|
|
|
|
Name/binary,
|
|
|
|
|
"\" filename: \"",
|
2017-09-20 23:40:56 +08:00
|
|
|
PemFile/binary, "\"">>.
|
2017-02-02 01:14:58 +08:00
|
|
|
|
|
|
|
|
run([Name], #{node := Node} = Options) ->
|
|
|
|
|
{Type, Value} = case Options of
|
2017-09-20 23:40:56 +08:00
|
|
|
#{json := Json} -> {json, Json};
|
|
|
|
|
#{pem := Pem} -> {pem, Pem};
|
|
|
|
|
#{pem_file := PemFile} -> {pem_file, PemFile}
|
2017-02-02 01:14:58 +08:00
|
|
|
end,
|
|
|
|
|
case rabbit_misc:rpc_call(Node,
|
2018-06-22 00:07:35 +08:00
|
|
|
uaa_jwt, add_signing_key,
|
2017-02-02 01:14:58 +08:00
|
|
|
[Name, Type, Value]) of
|
|
|
|
|
{ok, _Keys} -> ok;
|
|
|
|
|
{error, Err} -> {error, Err}
|
|
|
|
|
end.
|
|
|
|
|
|
2019-07-10 21:47:57 +08:00
|
|
|
output(E, _Opts) ->
|
2019-07-10 21:12:48 +08:00
|
|
|
'Elixir.RabbitMQ.CLI.DefaultOutput':output(E).
|
2017-02-02 01:14:58 +08:00
|
|
|
|
|
|
|
|
formatter() -> 'Elixir.RabbitMQ.CLI.Formatters.Erlang'.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|