Skip to content

Commit

Permalink
Move hex.key tasks to hex.user
Browse files Browse the repository at this point in the history
Fixes: hexpm#305
  • Loading branch information
milmazz committed Dec 26, 2016
1 parent 1aa5d55 commit 727026f
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 171 deletions.
94 changes: 7 additions & 87 deletions lib/mix/tasks/hex/key.ex
Original file line number Diff line number Diff line change
@@ -1,95 +1,15 @@
defmodule Mix.Tasks.Hex.Key do
use Mix.Task
alias Mix.Hex.Utils

@shortdoc "Manages Hex API key"
@moduledoc false

@moduledoc """
Removes or lists API keys associated with your account.
### Remove key
Removes given API key from account.
The key can no longer be used to authenticate API requests.
mix hex.key remove key_name
To remove all API keys from your account, pass the `--all` option.
mix hex.key remove --all
### List keys
Lists all API keys associated with your account.
mix hex.key list
"""

@switches [all: :boolean]

def run(args) do
def run(_) do
Hex.start
{opts, args, _} = OptionParser.parse(args, switches: @switches)
config = Hex.Config.read
all? = Keyword.get(opts, :all, false)

case args do
["remove", key] ->
auth = Utils.auth_info(config)
remove_key(key, auth)
["remove"] when all? ->
auth = Utils.auth_info(config)
remove_all_keys(auth)
["list"] ->
auth = Utils.auth_info(config)
list_keys(auth)
_ ->
Mix.raise """
Invalid arguments, expected one of:
mix hex.key remove KEY
mix hex.key remove --all
mix hex.key list
"""
end
end

defp remove_key(key, auth) do
Hex.Shell.info "Removing key #{key}..."
case Hex.API.Key.delete(key, auth) do
{200, %{"name" => ^key, "authing_key" => true}, _headers} ->
Mix.Tasks.Hex.User.run(["deauth"])
:ok
{code, _body, _headers} when code in 200..299 ->
:ok
{code, body, _headers} ->
Hex.Shell.error "Key removal failed"
Hex.Utils.print_error_result(code, body)
end
end

defp remove_all_keys(auth) do
Hex.Shell.info "Removing all keys..."
case Hex.API.Key.delete_all(auth) do
{code, %{"name" => _, "authing_key" => true}, _headers} when code in 200..299 ->
Mix.Tasks.Hex.User.run(["deauth"])
:ok
{code, body, _headers} ->
Hex.Shell.error "Key removal failed"
Hex.Utils.print_error_result(code, body)
end
end

defp list_keys(auth) do
case Hex.API.Key.get(auth) do
{code, body, _headers} when code in 200..299 ->
values = Enum.map(body, fn %{"name" => name, "inserted_at" => time} ->
[name, time]
end)
Utils.print_table(["Name", "Created at"], values)
{code, body, _headers} ->
Hex.Shell.error "Key fetching failed"
Hex.Utils.print_error_result(code, body)
end
deprecation_msg = """
[deprecation] The mix hex.key task is deprecated, please use:
mix hex.user
"""
Mix.raise deprecation_msg
end
end
100 changes: 86 additions & 14 deletions lib/mix/tasks/hex/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,26 @@ defmodule Mix.Tasks.Hex.User do
mix hex.user passphrase
### Remove key
Removes given API key from account.
The key can no longer be used to authenticate API requests.
mix hex.user key --remove key_name
### Remove all keys
Remove all API keys from your account.
mix hex.user key --remove-all
### List keys
Lists all API keys associated with your account.
mix hex.user key --list-keys
### Test authentication
Tests if authentication works with the stored API key.
Expand All @@ -46,25 +66,30 @@ defmodule Mix.Tasks.Hex.User do
mix hex.user reset password
"""

@switches [remove_all: :boolean, remove: :string, list_keys: :boolean]

def run(args) do
Hex.start
{_, args, _} = OptionParser.parse(args, switches: [])
config = Hex.Config.read()
{opts, args, _} = OptionParser.parse(args, switches: @switches)

case args do
["register"] ->
register()
["whoami"] ->
whoami()
whoami(config)
["auth"] ->
create_key()
["deauth"] ->
deauth()
deauth(config)
["passphrase"] ->
passphrase()
passphrase(config)
["reset", "password"] ->
reset_password()
["test"] ->
test()
test(config)
["key"] ->
process_key_task(opts, config)
_ ->
Mix.raise """
Invalid arguments, expected one of:
Expand All @@ -73,12 +98,18 @@ defmodule Mix.Tasks.Hex.User do
mix hex.user whoami
mix hex.user deauth
mix hex.user reset password
mix hex.user key --remove-all
mix hex.user key --remove KEY_NAME
mix hex.user key --list-keys
"""
end
end

defp whoami do
config = Hex.Config.read
defp process_key_task([remove_all: true], config), do: remove_all_keys(config)
defp process_key_task([remove: key], config), do: remove_key(key, config)
defp process_key_task([list_keys: true], config), do: list_keys(config)

defp whoami(config) do
username = local_user(config)
Hex.Shell.info(username)
end
Expand All @@ -96,8 +127,7 @@ defmodule Mix.Tasks.Hex.User do
end
end

defp deauth do
config = Hex.Config.read
defp deauth(config) do
username = local_user(config)

config
Expand All @@ -109,9 +139,7 @@ defmodule Mix.Tasks.Hex.User do
"or create a new user with `mix hex.user register`"
end

defp passphrase do
config = Hex.Config.read

defp passphrase(config) do
key = cond do
encrypted_key = config[:encrypted_key] ->
Utils.decrypt_key(encrypted_key, "Current passphrase")
Expand Down Expand Up @@ -160,9 +188,53 @@ defmodule Mix.Tasks.Hex.User do
Utils.generate_key(username, password)
end

defp remove_all_keys(config) do
auth = Utils.auth_info(config)

Hex.Shell.info "Removing all keys..."
case Hex.API.Key.delete_all(auth) do
{code, %{"name" => _, "authing_key" => true}, _headers} when code in 200..299 ->
Mix.Tasks.Hex.User.run(["deauth"])
:ok
{code, body, _headers} ->
Hex.Shell.error "Key removal failed"
Hex.Utils.print_error_result(code, body)
end
end

defp remove_key(key, config) do
auth = Utils.auth_info(config)

Hex.Shell.info "Removing key #{key}..."
case Hex.API.Key.delete(key, auth) do
{200, %{"name" => ^key, "authing_key" => true}, _headers} ->
Mix.Tasks.Hex.User.run(["deauth"])
:ok
{code, _body, _headers} when code in 200..299 ->
:ok
{code, body, _headers} ->
Hex.Shell.error "Key removal failed"
Hex.Utils.print_error_result(code, body)
end
end

defp list_keys(config) do
auth = Utils.auth_info(config)

case Hex.API.Key.get(auth) do
{code, body, _headers} when code in 200..299 ->
values = Enum.map(body, fn %{"name" => name, "inserted_at" => time} ->
[name, time]
end)
Utils.print_table(["Name", "Created at"], values)
{code, body, _headers} ->
Hex.Shell.error "Key fetching failed"
Hex.Utils.print_error_result(code, body)
end
end

# TODO
defp test do
config = Hex.Config.read
defp test(config) do
username = local_user(config)
auth = Utils.auth_info(config)

Expand Down
77 changes: 7 additions & 70 deletions test/mix/tasks/hex/key_test.exs
Original file line number Diff line number Diff line change
@@ -1,77 +1,14 @@
defmodule Mix.Tasks.Hex.KeyTest do
use HexTest.Case
@moduletag :integration

test "list keys" do
in_tmp fn ->
Hex.State.put(:home, System.cwd!)
test "mix hex.key task is deprecated" do
deprecation_msg = """
[deprecation] The mix hex.key task is deprecated, please use:
mix hex.user
"""

auth = HexWeb.new_user("list_keys", "list_keys@mail.com", "password", "list_keys")
Hex.Config.update(auth)

assert {200, [%{"name" => "list_keys"}], _} = Hex.API.Key.get(auth)

send self(), {:mix_shell_input, :prompt, "password"}
Mix.Tasks.Hex.Key.run(["list"])
assert_received {:mix_shell, :info, ["list_keys" <> _]}
end
end

test "remove key" do
in_tmp fn ->
Hex.State.put(:home, System.cwd!)

auth_a = HexWeb.new_user("remove_key", "remove_key@mail.com", "password", "remove_key_a")
auth_b = HexWeb.new_key("remove_key", "password", "remove_key_b")
Hex.Config.update(auth_a)

assert {200, _, _} = Hex.API.Key.get(auth_a)
assert {200, _, _} = Hex.API.Key.get(auth_b)

send self(), {:mix_shell_input, :prompt, "password"}
Mix.Tasks.Hex.Key.run(["remove", "remove_key_b"])
assert_received {:mix_shell, :info, ["Removing key remove_key_b..."]}

assert {200, _, _} = Hex.API.Key.get(auth_a)
assert {401, _, _} = Hex.API.Key.get(auth_b)

send self(), {:mix_shell_input, :prompt, "password"}
Mix.Tasks.Hex.Key.run(["remove", "remove_key_a"])
assert_received {:mix_shell, :info, ["Removing key remove_key_a..."]}
assert_received {:mix_shell, :info, ["User `remove_key` removed from the local machine. To authenticate again, run `mix hex.user auth` or create a new user with `mix hex.user register`"]}

assert {401, _, _} = Hex.API.Key.get(auth_a)

config = Hex.Config.read
refute config[:username]
refute config[:key]
refute config[:encrypted_key]
end
end

test "remove all keys" do
in_tmp fn ->
Hex.State.put(:home, System.cwd!)

auth_a = HexWeb.new_user("remove_all_keys", "remove_all_keys@mail.com", "password", "remove_all_keys_a")
auth_b = HexWeb.new_key("remove_all_keys", "password", "remove_all_keys_b")
Hex.Config.update(auth_a)

assert {200, _, _} = Hex.API.Key.get(auth_a)
assert {200, _, _} = Hex.API.Key.get(auth_b)

send self(), {:mix_shell_input, :prompt, "password"}
Mix.Tasks.Hex.Key.run(["remove", "--all"])
assert_received {:mix_shell, :info, ["Removing all keys..."]}
assert_received {:mix_shell, :info, ["User `remove_all_keys` removed from the local machine. To authenticate again, run `mix hex.user auth` or create a new user with `mix hex.user register`"]}

assert {401, _, _} = Hex.API.Key.get(auth_a)
assert {401, _, _} = Hex.API.Key.get(auth_b)

config = Hex.Config.read
refute config[:username]
refute config[:key]
refute config[:encrypted_key]
assert_raise Mix.Error, deprecation_msg, fn ->
Mix.Tasks.Hex.Key.run([""])
end
end
end
Loading

0 comments on commit 727026f

Please sign in to comment.