Skip to content

Commit

Permalink
Add role rename subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
christophermaier committed Jun 24, 2016
1 parent c2fed58 commit 242735b
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/cog/commands/role.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule Cog.Commands.Role do
use Cog.Command.GenCommand.Base, bundle: Cog.embedded_bundle
require Cog.Commands.Helpers, as: Helpers

alias Cog.Commands.Role.{Create, Delete, Grant, Info, List, Revoke}
alias Cog.Commands.Role.{Create, Delete, Grant, Info, List, Rename, Revoke}

Helpers.usage :root, """
Manipulate authorization roles.
Expand All @@ -19,6 +19,7 @@ defmodule Cog.Commands.Role do
grant Grant a role to a group
info Get detailed information about a specific role
list List all roles (default)
rename Rename a role
revoke Revoke a role from a group
"""
Expand All @@ -34,6 +35,7 @@ defmodule Cog.Commands.Role do
rule "when command is #{Cog.embedded_bundle}:role with arg[0] == info must have #{Cog.embedded_bundle}:manage_roles"
rule "when command is #{Cog.embedded_bundle}:role with arg[0] == list must have #{Cog.embedded_bundle}:manage_roles"
rule "when command is #{Cog.embedded_bundle}:role with arg[0] == grant must have #{Cog.embedded_bundle}:manage_groups"
rule "when command is #{Cog.embedded_bundle}:role with arg[0] == rename must have #{Cog.embedded_bundle}:manage_roles"
rule "when command is #{Cog.embedded_bundle}:role with arg[0] == revoke must have #{Cog.embedded_bundle}:manage_groups"

def handle_message(req, state) do
Expand All @@ -45,6 +47,7 @@ defmodule Cog.Commands.Role do
"grant" -> Grant.grant(req, args)
"info" -> Info.info(req, args)
"list" -> List.list(req, args)
"rename" -> Rename.rename(req, args)
"revoke" -> Revoke.revoke(req, args)
nil ->
if Helpers.flag?(req.options, "help") do
Expand Down
48 changes: 48 additions & 0 deletions lib/cog/commands/role/rename.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
defmodule Cog.Commands.Role.Rename do
require Cog.Commands.Helpers, as: Helpers

alias Cog.Repository.Roles
alias Cog.Models.Role

Helpers.usage """
Rename a role
USAGE
role rename [FLAGS] <name> <new-name>
ARGS
name The role to rename
new-name The name you want to change to
FLAGS
-h, --help Display this usage info
EXAMPLES
role rename aws-admin cloud-commander
"""

def rename(%{options: %{"help" => true}}, _args),
do: show_usage
def rename(_req, [old, new]) when is_binary(old) and is_binary(new) do
case Roles.by_name(old) do
%Role{}=role ->
case Roles.rename(role, new) do
{:ok, role} ->
rendered = Cog.V1.RoleView.render("show.json", %{role: role})
{:ok, "role-rename", Map.put(rendered[:role], :old_name, old)}
{:error, _}=error ->
error
end
nil ->
{:error, {:resource_not_found, "role", old}}
end
end
def rename(_, [_,_]),
do: {:error, :wrong_type}
def rename(_, args) do
error = if length(args) > 2, do: :too_many_args, else: :not_enough_args
{:error, {error, 2}}
end

end
14 changes: 14 additions & 0 deletions lib/cog/repository/roles.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ defmodule Cog.Repository.Roles do
preload(role)
end

# We don't (yet) have need of general update
def rename(%Role{name: unquote(Cog.admin_role)=name}, _),
do: {:error, {:protected_role, name}}
def rename(%Role{}=role, new_name) do
case role
|> Role.changeset(%{name: new_name})
|> Repo.update do
{:ok, role} ->
{:ok, preload(role)}
{:error, _}=error ->
error
end
end

########################################################################

defp preload(role_or_roles),
Expand Down
1 change: 1 addition & 0 deletions lib/cog/templates/slack/role-rename.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Renamed role `{{old_name}}` to `{{name}}`
47 changes: 47 additions & 0 deletions test/integration/commands/role_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ defmodule Integration.Commands.RoleTest do
alias Cog.Repository.Roles
alias Cog.Repository.Groups

alias Cog.Models.Role

import DatabaseAssertions, only: [assert_role_is_granted: 2,
refute_role_is_granted: 2]

Expand Down Expand Up @@ -283,6 +285,51 @@ defmodule Integration.Commands.RoleTest do
assert_error_message_contains(response , "Unknown subcommand 'do-something'")
end

test "renaming a role works", %{user: user} do
%Role{id: id} = role("foo")

[payload] = payload_from(user, "operable:role rename foo bar")
assert %{id: ^id,
name: "bar",
old_name: "foo"} = payload

refute Roles.by_name("foo")
assert %Role{id: ^id} = Roles.by_name("bar")
end

test "the cog-admin role cannot be renamed", %{user: user} do
response = send_message(user, "@bot: operable:role rename cog-admin monkeys")
assert_error_message_contains(response , "Cannot alter protected role cog-admin")
end

test "renaming a non-existent role fails", %{user: user} do
response = send_message(user, "@bot: operable:role rename not-here monkeys")
assert_error_message_contains(response , "Could not find 'role' with the name 'not-here'")
end

test "renaming to an already-existing role fails", %{user: user} do
role("foo")
role("bar")

response = send_message(user, "@bot: operable:role rename foo bar")
assert_error_message_contains(response , "name has already been taken")
end

test "renaming requires a new name", %{user: user} do
response = send_message(user, "@bot: operable:role rename foo")
assert_error_message_contains(response , "Not enough args. Arguments required: exactly 2")
end

test "rename requires a role and a name", %{user: user} do
response = send_message(user, "@bot: operable:role rename")
assert_error_message_contains(response , "Not enough args. Arguments required: exactly 2")
end

test "renaming requires string arguments", %{user: user} do
response = send_message(user, "@bot: operable:role rename 123 456")
assert_error_message_contains(response , "Arguments must be strings")
end

########################################################################

# TODO: pull this out to adapter test
Expand Down

0 comments on commit 242735b

Please sign in to comment.