From b7dcbe4996dc64815e8eb83da4c82b62bb68bc69 Mon Sep 17 00:00:00 2001 From: William Ruemmele Date: Thu, 12 Nov 2020 11:07:29 -0700 Subject: [PATCH] fix: once through fixing up config files/readme/commands --- .circleci/config.yml | 1 + COMMANDS.md | 193 ++++++++++++-- README.md | 239 ++++++++++++++---- messages/create.json | 2 - messages/permset.assign.json | 2 +- package.json | 2 +- src/commands/{ => force}/user/create.ts | 7 +- src/commands/{ => force}/user/display.ts | 11 +- src/commands/{ => force}/user/list.ts | 21 +- .../{ => force}/user/password/generate.ts | 18 +- .../{ => force}/user/permset/assign.ts | 21 +- test/commands/user/create.test.ts | 8 +- test/commands/user/display.test.ts | 4 +- test/commands/user/list.test.ts | 2 +- test/commands/user/password/generate.test.ts | 8 +- test/commands/user/permset/assign.test.ts | 24 +- 16 files changed, 419 insertions(+), 144 deletions(-) rename src/commands/{ => force}/user/create.ts (95%) rename src/commands/{ => force}/user/display.ts (91%) rename src/commands/{ => force}/user/list.ts (89%) rename src/commands/{ => force}/user/password/generate.ts (85%) rename src/commands/{ => force}/user/permset/assign.ts (87%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6089196f..907fbb29 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,6 +18,7 @@ workflows: name: node-12 - release-management/release-package: sign: true + github-release: true requires: - node-latest filters: diff --git a/COMMANDS.md b/COMMANDS.md index 823de81e..782e1dd4 100644 --- a/COMMANDS.md +++ b/COMMANDS.md @@ -2,40 +2,195 @@ A list of the available commands -- [`sfdx hello:org [-n ] [-f] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`](#sfdx-helloorg--n-string--f--v-string--u-string---apiversion-string---json---loglevel-tracedebuginfowarnerrorfataltracedebuginfowarnerrorfatal) +- sfdx force:user:list [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] -## `sfdx hello:org [-n ] [-f] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` +## `sfdx force:user:list [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` -print a greeting and your org IDs +lists all users of a scratch org ``` USAGE - $ sfdx hello:org [-n ] [-f] [-v ] [-u ] [--apiversion ] [--json] [--loglevel + $ sfdx force:user:list [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] OPTIONS - -f, --force example boolean flag - -n, --name=name name to print + -u, --targetusername=targetusername username or alias for the + target org; overrides + default target org - -u, --targetusername=targetusername username or alias for the target - org; overrides default target org + -v, --targetdevhubusername=targetdevhubusername username or alias for the + dev hub org; overrides + default dev hub org - -v, --targetdevhubusername=targetdevhubusername username or alias for the dev hub - org; overrides default dev hub org + --apiversion=apiversion override the api version + used for api requests made + by this command - --apiversion=apiversion override the api version used for - api requests made by this command + --json format output as json + + --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging + level for this command + invocation + +EXAMPLES + sfdx force:user:list + sfdx force:user:list -u me@my.org --json + sfdx force:user:list --json > tmp/MyUserList.json +``` + +- sfdx force:user:display [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +## `sfdx force:user:display [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` + +displays information about a user of a scratch org + +``` +USAGE + $ sfdx force:user:display [-v ] [-u ] [--apiversion ] [--json] [--loglevel + trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +OPTIONS + -u, --targetusername=targetusername username or alias for the + target org; overrides + default target org + + -v, --targetdevhubusername=targetdevhubusername username or alias for the + dev hub org; overrides + default dev hub org + + --apiversion=apiversion override the api version + used for api requests made + by this command --json format output as json - --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging level for - this command invocation + --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging + level for this command + invocation EXAMPLES - $ sfdx hello:org --targetusername myOrg@example.com --targetdevhubusername devhub@org.com - Hello world! This is org: MyOrg and I will be around until Tue Mar 20 2018! - My hub org id is: 00Dxx000000001234 + sfdx force:user:display + sfdx force:user:display -u me@my.org --json +``` + +- sfdx force:user:create [name=value...] [-a ] [-f ] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +## `sfdx force:user:create [name=value...] [-a ] [-f ] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` + +create a user for a scratch org + +```USAGE + $ sfdx force:user:create [name=value...] [-a ] [-f ] [-v ] [-u ] [--apiversion + ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +OPTIONS + -a, --alias=alias set an alias for the created + username to reference within + the CLI + + -f, --definitionfile=definitionfile file path to a user + definition + + -u, --targetusername=targetusername username or alias for the + target org; overrides + default target org + + -v, --targetdevhubusername=targetdevhubusername username or alias for the + dev hub org; overrides + default dev hub org + + --apiversion=apiversion override the api version + used for api requests made + by this command + + --json format output as json + + --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging + level for this command + invocation + +EXAMPLES + sfdx force:user:create + sfdx force:user:create -a testuser1 -f config/project-user-def.json + sfdx force:user:create username=testuser1@my.org email=me@my.org permsets=DreamHouse + sfdx force:user:create -f config/project-user-def.json email=me@my.org generatepassword=true +``` - $ sfdx hello:org --name myname --targetusername myOrg@example.com - Hello myname! This is org: MyOrg and I will be around until Tue Mar 20 2018! +- force:user:password:generate [-o ] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +## `force:user:password:generate [-o ] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` + +generate a password for scratch org users + +``` +USAGE + $ sfdx force:user:password:generate [-o ] [-v ] [-u ] [--apiversion ] [--json] + [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +OPTIONS + -o, --onbehalfof=onbehalfof comma-separated list of + usernames or aliases to + assign the password to + + -u, --targetusername=targetusername username or alias for the + target org; overrides + default target org + + -v, --targetdevhubusername=targetdevhubusername username or alias for the + dev hub org; overrides + default dev hub org + + --apiversion=apiversion override the api version + used for api requests made + by this command + + --json format output as json + + --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging + level for this command + invocation + +EXAMPLES + sfdx force:user:password:generate + sfdx force:user:password:generate -u me@my.org --json + sfdx force:user:password:generate -o "user1@my.org,user2@my.org,user3@my.org" +``` + +- sfdx force:user:permset:assign -n [-o ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +## `sfdx force:user:permset:assign -n [-o ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` + +assign a permission set to one or more users of an org + +``` +USAGE + $ sfdx force:user:permset:assign -n [-o ] [-u ] [--apiversion ] [--json] + [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +OPTIONS + -n, --permsetname=permsetname (required) the name of the + permission set to assign + + -o, --onbehalfof=onbehalfof comma-separated list of + usernames or aliases to + assign the permission set to + + -u, --targetusername=targetusername username or alias for the + target org; overrides + default target org + + --apiversion=apiversion override the api version + used for api requests made + by this command + + --json format output as json + + --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging + level for this command + invocation + +EXAMPLES + sfdx force:user:permset:assign -n DreamHouse + sfdx force:user:permset:assign -n DreamHouse -u me@my.org + sfdx force:user:permset:assign -n DreamHouse -o "user1@my.org,user2,user3" ``` diff --git a/README.md b/README.md index a21e565f..dfc30289 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,14 @@ -# plugin-<REPLACE ME> +# plugin-user -Change above to before finalizing - -<REPLACE ME DESCRIPTION START> - -This repository provides a template for creating a plugin for the Salesforce CLI. To convert this template to a working plugin: - -1. Clone this repo -2. Delete the .git folder -3. Replace filler values - a) Every instance of `` can be directly substitued for the name of the new plugin. However beware, things like github paths are for the salesforcecli Github organization - b) Search for case-matching `REPLACE` to find other filler values, such as for the plugin description -4. Use `git init` to set up the desired git information -5. Follow the getting started steps below until the `sfdx hello:org` commmand is functioning -6. In order to prevent build failures on the intial build, you will need to do the following: - 1. `npm publish` - 2. `git tag v1.0.0 ; git push origin v1.0.0` - -<REPLACE ME DESCRIPTION END> - -### Everything past here is only a suggestion as to what should be in your specific plugin's descsription. +Commands to interact with Users and Permission Sets in a scratch org ## Getting Started -To use, install the [Salesforce CLI](https://developer.salesforce.com/tools/sfdxcli) and run the following commands. - -``` -Verify the CLI is installed - $ sfdx (-v | --version) -Install the plugin - $ sfdx plugins:install -To run a command - $ sfdx [command] -``` - To build the plugin locally, make sure to have yarn installed and run the following commands: ``` Clone the repository - $ git clone git@github.com:salesforcecli/plugin- + $ git clone git@github.com:salesforcecli/plugin-user Install the dependencies and compile $ yarn install $ yarn prepack @@ -52,18 +22,18 @@ To verify We recommend using the Visual Studio Code (VS Code) IDE for your plugin development. Included in the `.vscode` directory of this plugin is a `launch.json` config file, which allows you to attach a debugger to the node process when running your commands. -To debug the `hello:org` command: +To debug the `force:user:list` command: If you linked your plugin to the sfdx cli, call your command with the `dev-suspend` switch: ```sh-session -$ sfdx hello:org -u myOrg@example.com --dev-suspend +$ force:user:list -u myOrg@example.com --dev-suspend ``` Alternatively, to call your command using the `bin/run` script, set the `NODE_OPTIONS` environment variable to `--inspect-brk` when starting the debugger: ```sh-session -$ NODE_OPTIONS=--inspect-brk bin/run hello:org -u myOrg@example.com +$ NODE_OPTIONS=--inspect-brk bin/run force:user:list -u myOrg@example.com ``` 2. Set some breakpoints in your command code @@ -71,45 +41,202 @@ $ NODE_OPTIONS=--inspect-brk bin/run hello:org -u myOrg@example.com 4. In the upper left hand corner of VS Code, verify that the "Attach to Remote" launch configuration has been chosen. 5. Hit the green play button to the left of the "Attach to Remote" launch configuration window. The debugger should now be suspended on the first line of the program. 6. Hit the green play button at the top middle of VS Code (this play button will be to the right of the play button that you clicked in step #5). -

+ ![how to debug](.images/vscodeScreenshot.png) Congrats, you are debugging! ## Commands -- [`sfdx hello:org [-n ] [-f] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]`](#sfdx-helloorg--n-string--f--v-string--u-string---apiversion-string---json---loglevel-tracedebuginfowarnerrorfataltracedebuginfowarnerrorfatal) +A list of the available commands + +- sfdx force:user:list [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] -## `sfdx hello:org [-n ] [-f] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` +## `sfdx force:user:list [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` -print a greeting and your org IDs +lists all users of a scratch org ``` USAGE - $ sfdx hello:org [-n ] [-f] [-v ] [-u ] [--apiversion ] [--json] [--loglevel + $ sfdx force:user:list [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] OPTIONS - -f, --force example boolean flag - -n, --name=name name to print + -u, --targetusername=targetusername username or alias for the + target org; overrides + default target org + + -v, --targetdevhubusername=targetdevhubusername username or alias for the + dev hub org; overrides + default dev hub org + + --apiversion=apiversion override the api version + used for api requests made + by this command + + --json format output as json + + --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging + level for this command + invocation + +EXAMPLES + sfdx force:user:list + sfdx force:user:list -u me@my.org --json + sfdx force:user:list --json > tmp/MyUserList.json +``` + +- sfdx force:user:display [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] - -u, --targetusername=targetusername username or alias for the target - org; overrides default target org +## `sfdx force:user:display [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` - -v, --targetdevhubusername=targetdevhubusername username or alias for the dev hub - org; overrides default dev hub org +displays information about a user of a scratch org - --apiversion=apiversion override the api version used for - api requests made by this command +``` +USAGE + $ sfdx force:user:display [-v ] [-u ] [--apiversion ] [--json] [--loglevel + trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +OPTIONS + -u, --targetusername=targetusername username or alias for the + target org; overrides + default target org + + -v, --targetdevhubusername=targetdevhubusername username or alias for the + dev hub org; overrides + default dev hub org + + --apiversion=apiversion override the api version + used for api requests made + by this command --json format output as json - --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging level for - this command invocation + --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging + level for this command + invocation EXAMPLES - $ sfdx hello:org --targetusername myOrg@example.com --targetdevhubusername devhub@org.com - Hello world! This is org: MyOrg and I will be around until Tue Mar 20 2018! - My hub org id is: 00Dxx000000001234 + sfdx force:user:display + sfdx force:user:display -u me@my.org --json +``` + +- sfdx force:user:create [name=value...] [-a ] [-f ] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +## `sfdx force:user:create [name=value...] [-a ] [-f ] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` - $ sfdx hello:org --name myname --targetusername myOrg@example.com - Hello myname! This is org: MyOrg and I will be around until Tue Mar 20 2018! +create a user for a scratch org + +```USAGE + $ sfdx force:user:create [name=value...] [-a ] [-f ] [-v ] [-u ] [--apiversion + ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +OPTIONS + -a, --alias=alias set an alias for the created + username to reference within + the CLI + + -f, --definitionfile=definitionfile file path to a user + definition + + -u, --targetusername=targetusername username or alias for the + target org; overrides + default target org + + -v, --targetdevhubusername=targetdevhubusername username or alias for the + dev hub org; overrides + default dev hub org + + --apiversion=apiversion override the api version + used for api requests made + by this command + + --json format output as json + + --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging + level for this command + invocation + +EXAMPLES + sfdx force:user:create + sfdx force:user:create -a testuser1 -f config/project-user-def.json + sfdx force:user:create username=testuser1@my.org email=me@my.org permsets=DreamHouse + sfdx force:user:create -f config/project-user-def.json email=me@my.org generatepassword=true +``` + +- force:user:password:generate [-o ] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +## `force:user:password:generate [-o ] [-v ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` + +generate a password for scratch org users + +``` +USAGE + $ sfdx force:user:password:generate [-o ] [-v ] [-u ] [--apiversion ] [--json] + [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +OPTIONS + -o, --onbehalfof=onbehalfof comma-separated list of + usernames or aliases to + assign the password to + + -u, --targetusername=targetusername username or alias for the + target org; overrides + default target org + + -v, --targetdevhubusername=targetdevhubusername username or alias for the + dev hub org; overrides + default dev hub org + + --apiversion=apiversion override the api version + used for api requests made + by this command + + --json format output as json + + --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging + level for this command + invocation + +EXAMPLES + sfdx force:user:password:generate + sfdx force:user:password:generate -u me@my.org --json + sfdx force:user:password:generate -o "user1@my.org,user2@my.org,user3@my.org" +``` + +- sfdx force:user:permset:assign -n [-o ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +## `sfdx force:user:permset:assign -n [-o ] [-u ] [--apiversion ] [--json] [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL]` + +assign a permission set to one or more users of an org + +``` +USAGE + $ sfdx force:user:permset:assign -n [-o ] [-u ] [--apiversion ] [--json] + [--loglevel trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL] + +OPTIONS + -n, --permsetname=permsetname (required) the name of the + permission set to assign + + -o, --onbehalfof=onbehalfof comma-separated list of + usernames or aliases to + assign the permission set to + + -u, --targetusername=targetusername username or alias for the + target org; overrides + default target org + + --apiversion=apiversion override the api version + used for api requests made + by this command + + --json format output as json + + --loglevel=(trace|debug|info|warn|error|fatal|TRACE|DEBUG|INFO|WARN|ERROR|FATAL) [default: warn] logging + level for this command + invocation + +EXAMPLES + sfdx force:user:permset:assign -n DreamHouse + sfdx force:user:permset:assign -n DreamHouse -u me@my.org + sfdx force:user:permset:assign -n DreamHouse -o "user1@my.org,user2,user3" ``` diff --git a/messages/create.json b/messages/create.json index 55fee98f..9b295721 100644 --- a/messages/create.json +++ b/messages/create.json @@ -10,9 +10,7 @@ "alias": "set an alias for the created username to reference within the CLI", "definitionfile": "file path to a user definition" }, - "userNotCreated": "User must be created before %s", "licenseLimitExceeded": "There are no available user licenses for the user profile \"%s\".", "duplicateUsername": "The username \"%s\" already exists in this or another Salesforce org. Usernames must be unique across all Salesforce orgs.", - "profileNameNotFound": "Profile name \"%s\" not found in target org. Do you need to push source?", "success": "Successfully created user \"%s\" with ID %s for org %s.%sYou can see more details about this user by running \"sfdx force:user:display -u %s\"." } diff --git a/messages/permset.assign.json b/messages/permset.assign.json index 1d1f9662..6788e733 100644 --- a/messages/permset.assign.json +++ b/messages/permset.assign.json @@ -7,6 +7,6 @@ ], "flags": { "onBehalfOf": "comma-separated list of usernames or aliases to assign the permission set to", - "name": "TEST DESC" + "permsetName": "the name of the permission set to assign" } } diff --git a/package.json b/package.json index 37ce2ae1..6f3ef69c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@salesforce/plugin-user", - "description": "A template repository for sfdx plugins", + "description": "Commands to interact with Users and Permission Sets", "version": "1.0.0", "author": "Salesforce", "bugs": "https://github.com/forcedotcom/cli/issues", diff --git a/src/commands/user/create.ts b/src/commands/force/user/create.ts similarity index 95% rename from src/commands/user/create.ts rename to src/commands/force/user/create.ts index 119b47a1..5b8e6da4 100644 --- a/src/commands/user/create.ts +++ b/src/commands/force/user/create.ts @@ -7,6 +7,7 @@ import * as os from 'os'; import { Aliases, + AuthInfo, Connection, DefaultUserFields, fs, @@ -51,6 +52,7 @@ export class UserCreateCommand extends SfdxCommand { }; public logger: Logger; public org: Org; + private user: User; private successes: SuccessMsg[]; private failures: FailureMsg[]; @@ -62,7 +64,7 @@ export class UserCreateCommand extends SfdxCommand { }); const user: User = await User.create({ org: this.org }); - // merge defaults with provided values from cli -> file -> defaults + // merge defaults with provided values with cli > file > defaults const fields: UserFields = await this.aggregateFields(defaultUserFields.getFields()); try { @@ -71,6 +73,7 @@ export class UserCreateCommand extends SfdxCommand { await this.catchCreateUser(e, fields); } + // because we overload the UserField in the aggregateFields method these entries could possibly be there const permsets: string = fields['permsets']; const generatepassword: string = fields['varargs']; @@ -94,7 +97,7 @@ export class UserCreateCommand extends SfdxCommand { if (generatepassword === 'true') { try { const password = User.generatePasswordUtf8(); - // await this.user.assignPassword(await AuthInfo.create({ username: fields.username }), password); + await this.user.assignPassword(await AuthInfo.create({ username: fields.username }), password); password.value((pass: Buffer) => { this.successes.push({ name: 'Password Assignment', diff --git a/src/commands/user/display.ts b/src/commands/force/user/display.ts similarity index 91% rename from src/commands/user/display.ts rename to src/commands/force/user/display.ts index d0c57d6e..b8484db9 100644 --- a/src/commands/user/display.ts +++ b/src/commands/force/user/display.ts @@ -14,7 +14,7 @@ import { get } from '@salesforce/ts-types'; Messages.importMessagesDirectory(__dirname); const messages = Messages.loadMessages('@salesforce/plugin-user', 'display'); -type row = { +type Row = { Key: string; Value: string; }; @@ -26,7 +26,7 @@ export class UserDisplayCommand extends SfdxCommand { public static readonly requiresDevhubUsername = true; public logger: Logger; - public async run(): Promise { + public async run(): Promise { this.logger = await Logger.child(this.constructor.name); const username: string = this.org.getUsername(); @@ -35,15 +35,13 @@ export class UserDisplayCommand extends SfdxCommand { const userAuthData: AuthFields = userAuthDataArray.find((uat) => uat.getFields().username === username).getFields(); const conn: Connection = this.org.getConnection(); - const PROFILE_NAME_QUERY = `SELECT name FROM Profile WHERE Id IN (SELECT profileid FROM User WHERE username='${username}')`; - const USER_QUERY = `SELECT id FROM User WHERE username='${username}'`; - let profileName: string = userAuthData.userProfileName; let userId: string = userAuthData.userId; try { // the user executing this command may not have access to the Profile sObject. if (!profileName) { + const PROFILE_NAME_QUERY = `SELECT name FROM Profile WHERE Id IN (SELECT profileid FROM User WHERE username='${username}')`; profileName = get(await conn.query(PROFILE_NAME_QUERY), 'records[0].Name') as string; } } catch (err) { @@ -55,6 +53,7 @@ export class UserDisplayCommand extends SfdxCommand { try { if (!userId) { + const USER_QUERY = `SELECT id FROM User WHERE username='${username}'`; userId = get(await conn.query(USER_QUERY), 'records[0].Id') as string; } } catch (err) { @@ -64,7 +63,7 @@ export class UserDisplayCommand extends SfdxCommand { ); } - const rows: row[] = [ + const rows: Row[] = [ { Key: 'Access Token', Value: conn.accessToken }, { Key: 'Id', Value: userId }, { Key: 'Instance Url', Value: userAuthData.instanceUrl }, diff --git a/src/commands/user/list.ts b/src/commands/force/user/list.ts similarity index 89% rename from src/commands/user/list.ts rename to src/commands/force/user/list.ts index 08570696..7ce91e14 100644 --- a/src/commands/user/list.ts +++ b/src/commands/force/user/list.ts @@ -57,19 +57,18 @@ export class UserListCommand extends SfdxCommand { }; }); - const trimmedList = authList.map((auth) => { - return { - Default: auth.defaultMarker, - Alias: auth.alias, - Username: auth.username, - 'Profile Name': auth.profileName, - 'User ID': auth.userId, - }; - }); + const columns = { + columns: [ + { key: 'defaultMarker', label: 'Default' }, + { key: 'alias', label: 'Alias' }, + { key: 'username', label: 'Username' }, + { key: 'profileName', label: 'Profile Name' }, + { key: 'userId', label: 'User Id' }, + ], + }; - const columns = ['Default', 'Alias', 'Username', 'Profile Name', 'User ID']; this.ux.styledHeader(`Users in org ${this.org.getOrgId()}`); - this.ux.table(trimmedList, columns); + this.ux.table(authList, columns); return Promise.resolve(authList); } diff --git a/src/commands/user/password/generate.ts b/src/commands/force/user/password/generate.ts similarity index 85% rename from src/commands/user/password/generate.ts rename to src/commands/force/user/password/generate.ts index 0f5ae297..9ac60f8f 100644 --- a/src/commands/user/password/generate.ts +++ b/src/commands/force/user/password/generate.ts @@ -27,24 +27,24 @@ export class UserPasswordGenerateCommand extends SfdxCommand { description: messages.getMessage('flags.onBehalfOf'), }), }; - public org: Org; + private usernames: string[]; private passwordData: PasswordData[] = []; public async run(): Promise { - // split the usernames, trim them down, and then join them back if (this.flags.onbehalfof) { - this.usernames = this.flags.onbehalfof.join(',').trim().split(','); + // trim the usernames to avoid whitespace + this.usernames = this.flags.onbehalfof.map((user) => user.trim()); } else { this.usernames = [this.org.getUsername()]; } - for (let username of this.usernames) { + for (const username of this.usernames) { try { // Convert any aliases to usernames - // fetch will return undefined if no Alias for that name - username = (await Aliases.fetch(username)) || username; + // fetch will return undefined if there's no Alias for that name + const aliasOrUsername = (await Aliases.fetch(username)) || username; const authInfo: AuthInfo = await AuthInfo.create({ username }); const connection: Connection = await Connection.create({ authInfo }); @@ -56,7 +56,7 @@ export class UserPasswordGenerateCommand extends SfdxCommand { authInfo.getFields().userId = fields.id; await user.assignPassword(authInfo, password); password.value((pass) => { - this.passwordData.push({ username, password: pass.toString('utf-8') }); + this.passwordData.push({ username: aliasOrUsername, password: pass.toString('utf-8') }); }); } catch (e) { if (e.message.includes('Cannot set password for self')) { @@ -73,8 +73,8 @@ export class UserPasswordGenerateCommand extends SfdxCommand { private print(): void { if (this.passwordData) { - const successMsg = messages.getMessage('success', [this.passwordData[0].password, this.usernames[0]]); - const viewMsg = messages.getMessage('viewWithCommand', [this.usernames[0]]); + const successMsg = messages.getMessage('success', [this.passwordData[0].password, this.passwordData[0].username]); + const viewMsg = messages.getMessage('viewWithCommand', [this.passwordData[0].username]); this.ux.log(`${successMsg}${os.EOL}${viewMsg}`); } else { this.ux.log(messages.getMessage('successMultiple', [os.EOL])); diff --git a/src/commands/user/permset/assign.ts b/src/commands/force/user/permset/assign.ts similarity index 87% rename from src/commands/user/permset/assign.ts rename to src/commands/force/user/permset/assign.ts index 00c22094..3ba1015a 100644 --- a/src/commands/user/permset/assign.ts +++ b/src/commands/force/user/permset/assign.ts @@ -22,6 +22,11 @@ type FailureMsg = { message: string; }; +type Result = { + successes: SuccessMsg[]; + failures: FailureMsg[]; +}; + export class UserPermsetAssignCommand extends SfdxCommand { public static readonly description = messages.getMessage('description'); public static readonly examples = messages.getMessage('examples').split(os.EOL); @@ -29,7 +34,7 @@ export class UserPermsetAssignCommand extends SfdxCommand { public static readonly flagsConfig: FlagsConfig = { permsetname: flags.string({ char: 'n', - description: messages.getMessage('flags.name'), + description: messages.getMessage('flags.permsetName'), required: true, }), onbehalfof: flags.array({ @@ -41,10 +46,11 @@ export class UserPermsetAssignCommand extends SfdxCommand { private readonly successes: SuccessMsg[] = []; private readonly failures: FailureMsg[] = []; - public async run(): Promise<{ successes: SuccessMsg[]; failures: FailureMsg[] }> { + public async run(): Promise { try { if (this.flags.onbehalfof) { - this.usernames = this.flags.onbehalfof.join(',').trim().split(','); + // trim the usernames to avoid whitespace + this.usernames = this.flags.onbehalfof.map((user) => user.trim()); } else { this.usernames = [this.org.getUsername()]; } @@ -60,7 +66,7 @@ export class UserPermsetAssignCommand extends SfdxCommand { const fields: UserFields = await user.retrieve(username); try { - await user.assignPermissionSets(fields.id, this.flags.permsetname.split(',')); + await user.assignPermissionSets(fields.id, this.flags.permsetname); this.successes.push({ name: aliasOrUsername, value: this.flags.permsetname, @@ -78,7 +84,12 @@ export class UserPermsetAssignCommand extends SfdxCommand { this.print(); - return Promise.resolve({ successes: this.successes, failures: this.failures }); + const result: Result = { + successes: this.successes, + failures: this.failures, + }; + + return Promise.resolve(result); } private print(): void { diff --git a/test/commands/user/create.test.ts b/test/commands/user/create.test.ts index 4a766254..bddb70e3 100644 --- a/test/commands/user/create.test.ts +++ b/test/commands/user/create.test.ts @@ -55,7 +55,7 @@ describe('force:user:create', () => { }) .stdout() .command([ - 'user:create', + 'force:user:create', '--json', '--targetusername', 'testUser1@test.com', @@ -86,7 +86,7 @@ describe('force:user:create', () => { }) .stdout() .command([ - 'user:create', + 'force:user:create', '--json', '--definitionfile', 'parent/child/file.json', @@ -123,7 +123,7 @@ describe('force:user:create', () => { }) .stdout() .command([ - 'user:create', + 'force:user:create', '--json', '--targetusername', 'testUser1@test.com', @@ -143,7 +143,7 @@ describe('force:user:create', () => { }) .stdout() .command([ - 'user:create', + 'force:user:create', '--json', '--targetusername', 'testUser1@test.com', diff --git a/test/commands/user/display.test.ts b/test/commands/user/display.test.ts index d9b03df5..f3db37a4 100644 --- a/test/commands/user/display.test.ts +++ b/test/commands/user/display.test.ts @@ -63,7 +63,7 @@ describe('force:user:display', () => { }) .stdout() .command([ - 'user:display', + 'force:user:display', '--json', '--targetusername', 'testUser1@test.com', @@ -116,7 +116,7 @@ describe('force:user:display', () => { }) .stdout() .command([ - 'user:display', + 'force:user:display', '--json', '--targetusername', 'testUser1@test.com', diff --git a/test/commands/user/list.test.ts b/test/commands/user/list.test.ts index 382ba74c..27c70e61 100644 --- a/test/commands/user/list.test.ts +++ b/test/commands/user/list.test.ts @@ -66,7 +66,7 @@ describe('force:user:list', () => { }) .stdout() .command([ - 'user:list', + 'force:user:list', '--json', '--targetusername', 'testUser1@test.com', diff --git a/test/commands/user/password/generate.test.ts b/test/commands/user/password/generate.test.ts index 6bf274a8..bf483c89 100644 --- a/test/commands/user/password/generate.test.ts +++ b/test/commands/user/password/generate.test.ts @@ -52,7 +52,7 @@ describe('force:user:password:generate', () => { await prepareStubs(); }) .stdout() - .command(['user:password:generate', '--json', '--onbehalfof', 'testUser1@test.com, testUser2@test.com']) + .command(['force:user:password:generate', '--json', '--onbehalfof', 'testUser1@test.com, testUser2@test.com']) .it('should generate a new password for the user', (ctx) => { // testUser1@test.com is aliased to testUser const expected = [ @@ -61,7 +61,7 @@ describe('force:user:password:generate', () => { password: 'abc', }, { - username: ' testUser2@test.com', + username: 'testUser2@test.com', password: 'abc', }, ]; @@ -72,7 +72,7 @@ describe('force:user:password:generate', () => { test .do(() => prepareStubs()) .stdout() - .command(['user:password:generate', '--json']) + .command(['force:user:password:generate', '--json']) .it('should generate a new password for the default user', (ctx) => { const expected = [{ username: 'defaultusername@test.com', password: 'abc' }]; const result = JSON.parse(ctx.stdout).result; @@ -83,7 +83,7 @@ describe('force:user:password:generate', () => { .do(async () => await prepareStubs(true)) .stdout() - .command(['user:password:generate', '--json']) + .command(['force:user:password:generate', '--json']) .it('should throw the correct errror with warning message', (ctx) => { const result = JSON.parse(ctx.stdout); expect(result.message).to.equal(messages.getMessage('noSelfSetError')); diff --git a/test/commands/user/permset/assign.test.ts b/test/commands/user/permset/assign.test.ts index 1b24df61..6065838b 100644 --- a/test/commands/user/permset/assign.test.ts +++ b/test/commands/user/permset/assign.test.ts @@ -43,7 +43,7 @@ describe('force:user:permset:assign', () => { }) .stdout() .command([ - 'user:permset:assign', + 'force:user:permset:assign', '--json', '--onbehalfof', 'testUser1@test.com, testUser2@test.com', @@ -58,7 +58,7 @@ describe('force:user:permset:assign', () => { value: 'DreamHouse', }, { - name: ' testUser2@test.com', + name: 'testUser2@test.com', value: 'DreamHouse', }, ]; @@ -66,30 +66,12 @@ describe('force:user:permset:assign', () => { expect(result.successes).to.deep.equal(expected); }); - test - .do(async () => { - await prepareStubs(); - }) - .stdout() - .command(['user:permset:assign', '--json', '--permsetname', 'DreamHouse, PERM2']) - .it('should assign both permsets to the default user', (ctx) => { - // testUser1@test.com is aliased to testUser - const expected = [ - { - name: 'defaultusername@test.com', - value: 'DreamHouse, PERM2', - }, - ]; - const result = JSON.parse(ctx.stdout).result; - expect(result.successes).to.deep.equal(expected); - }); - test .do(async () => { await prepareStubs(true); }) .stdout() - .command(['user:permset:assign', '--json', '--permsetname', 'PERM2']) + .command(['force:user:permset:assign', '--json', '--permsetname', 'PERM2']) .it('should fail with the correct error message', (ctx) => { // testUser1@test.com is aliased to testUser const expected = [