diff --git a/packages/ctl/ctl.js b/packages/ctl/ctl.js index 74351e37..beb4159a 100755 --- a/packages/ctl/ctl.js +++ b/packages/ctl/ctl.js @@ -368,7 +368,11 @@ roleCommands.add(new libCommand.Command({ yargs.options({ "name": { describe: "New name for role", nargs: 1, type: "string" }, "description": { describe: "New description for role", nargs: 1, type: "string" }, - "permissions": { describe: "New permissions for role", array: true, type: "string" }, + "set-perms": { describe: "Set permissions for role", array: true, type: "string" }, + "add-perms": { describe: "Add permissions to role", array: true, type: "string", conflicts: "set-perms" }, + "remove-perms": { + describe: "Remove permissions from role", array: true, type: "string", conflicts: "set-perms", + }, "grant-default": { describe: "Add default permissions to role", nargs: 0, type: "boolean" }, }); }], @@ -381,8 +385,18 @@ roleCommands.add(new libCommand.Command({ if (args.description !== undefined) { role.description = args.description; } - if (args.permissions !== undefined) { - role.permissions = args.permissions; + if (args.addPerms) { + role.permissions = role.permissions.concat(args.addPerms); + } + if (args.removePerms) { + let perms = new Set(role.permissions); + for (let perm of args.removePerms) { + perms.delete(perm); + } + role.permissions = [...perms]; + } + if (args.setPerms !== undefined) { + role.permissions = args.setPerms; } await libLink.messages.updateRole.send(control, role); diff --git a/test/integration/clusterio.js b/test/integration/clusterio.js index 550c8fd7..3ab0ffb4 100644 --- a/test/integration/clusterio.js +++ b/test/integration/clusterio.js @@ -4,6 +4,7 @@ const fs = require("fs-extra"); const path = require("path"); const libLink = require("@clusterio/lib/link"); +const libUsers = require("@clusterio/lib/users"); const { slowTest, get, exec, execCtl, sendRcon, getControl, instancesDir } = require("./index"); @@ -282,16 +283,40 @@ describe("Integration of Clusterio", function() { describe("role edit", function() { it("should modify the given role", async function() { - let args = "--name new --description \"A new role\" --permissions"; + let args = "--name new --description \"A new role\" --set-perms"; await execCtl(`role edit temp ${args}`); let result = await libLink.messages.listRoles.send(getControl()); let newRole = result.list.find(role => role.name === "new"); assert.deepEqual(newRole, { id: 5, name: "new", description: "A new role", permissions: [] }); }); + it("should add permissions with --add-perms", async function() { + let args = "--name new --add-perms core.slave.list core.instance.list"; + await execCtl(`role edit new ${args}`); + let result = await libLink.messages.listRoles.send(getControl()); + let newRole = result.list.find(role => role.name === "new"); + assert.deepEqual(newRole.permissions, ["core.slave.list", "core.instance.list"]); + }); + it("should remove permissions with --remove-perms", async function() { + let args = "--name new --remove-perms core.slave.list"; + await execCtl(`role edit new ${args}`); + let result = await libLink.messages.listRoles.send(getControl()); + let newRole = result.list.find(role => role.name === "new"); + assert.deepEqual(newRole.permissions, ["core.instance.list"]); + }); + it("should grant default permissions with --grant-default", async function() { + await execCtl("role edit new --grant-default"); + let result = await libLink.messages.listRoles.send(getControl()); + let newRole = result.list.find(role => role.name === "new"); + let defaultPermissions = [...libUsers.permissions.values()] + .filter(p => p.grantByDefault) + .map(p => p.name) + ; + assert.deepEqual(new Set(newRole.permissions), new Set(defaultPermissions)); + }); }); describe("role delete", function() { - it("should modify the given role", async function() { + it("should delete the given role", async function() { await execCtl("role delete new"); let result = await libLink.messages.listRoles.send(getControl()); let newRole = result.list.find(role => role.name === "new");