Packages
rebar3_hex
2.1.0
7.1.0
7.0.11
7.0.10
7.0.9
7.0.8
7.0.7
7.0.6
7.0.5
7.0.4
7.0.3
7.0.2
7.0.1
7.0.0
6.11.9
6.11.8
6.11.7
6.11.6
6.11.5
6.11.4
6.11.3
6.11.2
6.11.1
6.11.0
6.10.3
6.10.2
6.10.1
6.10.0
6.9.6
6.9.5
6.9.4
6.9.3
6.9.2
6.9.1
6.9.0
6.8.0
6.7.0
6.6.0
6.5.0
6.4.0
6.3.0
6.2.0
6.1.0
6.0.0
4.1.0
4.0.0
3.1.0
3.0.0
2.5.1
2.5.0
2.4.0
2.3.0
2.2.0
2.1.0
2.0.0
1.20.0
1.19.0
1.18.0
1.17.0
1.16.0
1.15.0
1.14.0
1.13.0
1.12.0
1.11.0
1.10.0
1.9.1
1.9.0
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.3
1.6.1
1.6.0
1.5.0
1.4.0
1.3.0
1.2.0
1.1.0
0.9.0
0.8.0
0.7.0
0.6.0
0.5.1
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
Hex.pm plugin for rebar3
Current section
Files
Jump to
Current section
Files
src/rebar3_hex_user.erl
-module(rebar3_hex_user).
-export([init/1
,do/1
,format_error/1]).
-export([hex_register/0
,whoami/0
,auth/0
,deauth/0
,reset_password/0]).
-include("rebar3_hex.hrl").
-define(PROVIDER, user).
-define(DEPS, []).
-define(ENDPOINT, "users").
%% ===================================================================
%% Public API
%% ===================================================================
-spec init(rebar_state:t()) -> {ok, rebar_state:t()}.
init(State) ->
Provider = providers:create([
{name, ?PROVIDER},
{module, ?MODULE},
{namespace, hex},
{bare, true},
{deps, ?DEPS},
{example, "rebar3 hex user <command>"},
{short_desc, "Hex user tasks"},
{desc, ""},
{opts, []}
]),
State1 = rebar_state:add_provider(State, Provider),
{ok, State1}.
-spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}.
do(State) ->
case rebar_state:command_args(State) of
["register"] ->
hex_register(),
{ok, State};
["whoami"] ->
whoami(),
{ok, State};
["auth"] ->
auth(),
{ok, State};
["deauth"] ->
deauth(),
{ok, State};
["reset_password"] ->
reset_password(),
{ok, State};
[] ->
{ok, State}
end.
-spec format_error(any()) -> iolist().
format_error(Reason) ->
io_lib:format("~p", [Reason]).
hex_register() ->
Username = list_to_binary(ec_talk:ask_default("Username:", string, "")),
Email = list_to_binary(ec_talk:ask_default("Email:", string, "")),
case get_password() of
<<"">> ->
error;
Password ->
PasswordConfirm = get_password(confirm),
case Password =:= PasswordConfirm of
true ->
ec_talk:say("Registering..."),
create_user(Username, Email, Password);
false ->
error
end
end.
whoami() ->
Username = rebar3_hex_config:username(),
ec_talk:say(Username).
auth() ->
Username = list_to_binary(ec_talk:ask_default("Username:", string, "")),
Password = get_password(),
generate_key(Username, Password).
deauth() ->
Username = rebar3_hex_config:username(),
Config = rebar3_hex_config:read(),
rebar3_hex_config:write(lists:keydelete(username, 1, lists:keydelete(key, 1, Config))),
ec_talk:say("User `~s` removed from the local machine. "
"To authenticate again, run `rebar3 hex user auth` "
"or create a new user with `rebar3 hex user register`", [Username]).
reset_password() ->
User = ec_talk:ask_default("Username or Email:", string, ""),
ok = rebar3_hex_http:post_map(filename:join([?ENDPOINT, User, "reset"]), [], maps:new()).
%% Internal functions
get_password() ->
get_password(<<"Password: ">>).
-define(OP_PUTC, 0).
get_password(confirm) ->
get_password(<<"Password (confirm): ">>);
get_password(Msg) ->
case io:setopts([binary, {echo, false}]) of
ok ->
PwLine = io:get_line(Msg),
ok = io:setopts([binary, {echo, true}]),
io:format("\n"),
[Pw | _] = binary:split(PwLine, <<"\n">>),
Pw;
_ ->
error_logger:tty(false),
Port = open_port({spawn, "tty_sl -e"}, [binary, eof]),
port_command(Port, <<?OP_PUTC, Msg/binary>>),
receive
{Port, {data, PwLine}} ->
[Pw | _] = binary:split(PwLine, <<"\n">>),
port_command(Port, <<?OP_PUTC, $\n>>),
port_close(Port),
error_logger:tty(true),
Pw
end
end.
create_user(Username, Email, Password) ->
case new(Username, Email, Password) of
{ok, _} ->
generate_key(Username, Password),
ec_talk:say("You are required to confirm your email to access your account, "
"a confirmation email has been sent to ~s", [Email]);
{error, StatusCode, _} ->
ec_talk:say("Registration of user ~s failed (~p)", [Username, StatusCode]),
error
end.
generate_key(Username, Password) ->
ec_talk:say("Generating API key..."),
{ok, Name} = inet:gethostname(),
case new_key(list_to_binary(Name), Username, Password) of
{ok, Body} ->
update_config(Username, Body);
{error, StatusCode, Body} ->
ec_talk:say("Generation of API key failed (~p)", [StatusCode]),
{error, Body}
end.
new(Username, Email, Password) ->
rebar3_hex_http:post_map(?ENDPOINT, []
,maps:from_list([{<<"username">>, Username}
,{<<"email">>, Email}
,{<<"password">>, Password}])).
new_key(Name, Username, Password) ->
Auth = base64:encode_to_string(<<Username/binary, ":", Password/binary>>),
rebar3_hex_http:post_map("keys", "Basic "++Auth, maps:from_list([{<<"name">>, Name}])).
update_config(Username, Body)->
Secret = maps:get(<<"secret">>, Body),
rebar3_hex_config:update([{username, Username}, {key, Secret}]).