UNPKG

ci-sf-plugin

Version:

Set of commands making CI and dev's life easier.

124 lines 6.66 kB
/* * Copyright (c) 2020, salesforce.com, inc. * All rights reserved. * Licensed under the BSD 3-Clause license. * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause */ import * as os from 'os'; import * as util from 'util'; import * as childProcess from 'child_process'; import { readFileSync } from 'fs'; import { SfCommand, Flags, requiredOrgFlagWithDeprecations } from '@salesforce/sf-plugins-core'; import { Messages, SfError } from '@salesforce/core'; import { ux } from '@oclif/core'; // promisify child process const execSync = util.promisify(childProcess.exec); // Initialize Messages with the current plugin directory Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); // Load the specific messages for this file. Messages from @salesforce/command, @salesforce/core, // or any library that is using the messages framework can also be loaded this way. const messages = Messages.loadMessages('ci-sf-plugin', 'user.assign.profile'); export default class Profile extends SfCommand { static description = messages.getMessage('commandDescription'); static examples = messages.getMessage('examples').split(os.EOL); static flags = { 'target-org': requiredOrgFlagWithDeprecations, // flag with a value (-n, --name=VALUE) 'profile-name': Flags.string({ char: 'n', description: messages.getMessage('profilenameFlagDescription') }), 'ci-config-file': Flags.file({ char: 'x', default: 'ciconfig.json', description: messages.getMessage('ciconfigfileFlagDescription') }) }; // Set this to true if your command requires a project workspace; 'requiresProject' is false by default static requiresProject = false; async run() { try { const { flags } = await this.parse(Profile); // fetch needed flags const targetOrgUsername = flags['target-org'].getUsername(); const profileNameFlag = flags['profile-name']; const ciConfigFileFlag = flags['ci-config-file']; ux.action.start(messages.getMessage('infoAssigningProfile', [targetOrgUsername]), 'in progress', { stdout: true }); // load configuration let profile; if (profileNameFlag) { profile = profileNameFlag; } else { const config = JSON.parse(readFileSync(ciConfigFileFlag, 'utf-8')); if (!config.profile) { throw new Error(`'profile' property is missing in the '${ciConfigFileFlag}' file, or is blank.`); } profile = config.profile; } const output = { stdout: [], stderr: [] }; // build the command, with --json to see details, get profile ID const queryIdStr = `sf data query --query "SELECT Id FROM Profile WHERE Name = '${profile}'" --target-org ${targetOrgUsername} --json`; const queryIdPromise = execSync(queryIdStr, { encoding: 'utf8', maxBuffer: 1024 * 1024 }); const queryIdResultJson = JSON.parse((await queryIdPromise).stdout).result?.records[0]; process.stdout.write(`Profile '${profile}' has Id=${queryIdResultJson?.Id}.`); const profileId = queryIdResultJson?.Id; // create tmp user const tmpUsername = `tmp-${Date.now()}_${targetOrgUsername}`; const tmpUserCreateStr = `sf org create user --target-org ${targetOrgUsername} Username="${tmpUsername}" LastName="tmpUser" profileName="System Administrator"`; const tmpUserCreatePromise = execSync(tmpUserCreateStr, { encoding: 'utf8', maxBuffer: 1024 * 1024 }); tmpUserCreatePromise.child.stdout.on('data', (data) => { if (data?.trim()) { process.stdout.write(data); } }); tmpUserCreatePromise.child.stderr.on('data', (data) => { if (data?.trim()) { process.stderr.write(data.trim()); } }); const tmpUserCreateOutput = await tmpUserCreatePromise; output.stdout.push(tmpUserCreateOutput.stdout); output.stderr.push(tmpUserCreateOutput.stderr); // change profile of targetOrgUsername using tmpUsername const updateProfileStr = `sf data update record --sobject User --where "Username=${targetOrgUsername}" --values "ProfileId='${profileId}'" --target-org ${tmpUsername}`; const updateProfilePromise = execSync(updateProfileStr, { encoding: 'utf8', maxBuffer: 1024 * 1024 }); updateProfilePromise.child.stdout.on('data', (data) => { if (data?.trim()) { process.stdout.write(data); } }); updateProfilePromise.child.stderr.on('data', (data) => { if (data?.trim() && data.trim() !== 'Success') { process.stderr.write(`Assign profile to the '${targetOrgUsername}' user: ${data.trim()}`); } }); const updateProfileOutput = await updateProfilePromise; output.stdout.push(updateProfileOutput.stdout); output.stderr.push(updateProfileOutput.stderr); // deactivate our tmp user const deactivateTmpUserStr = `sf data update record --sobject User --where "Username=${tmpUsername}" --values "IsActive=false" --target-org ${targetOrgUsername}`; const deactivateTmpUserPromise = execSync(deactivateTmpUserStr, { encoding: 'utf8', maxBuffer: 1024 * 1024 }); deactivateTmpUserPromise.child.stdout.on('data', (data) => { if (data?.trim()) { process.stdout.write(data); } }); deactivateTmpUserPromise.child.stderr.on('data', (data) => { if (data?.trim() && data.trim() !== 'Success') { process.stderr.write('Deactivate tmp user: ' + data.trim()); } }); const deactivateTmpUserOutput = await deactivateTmpUserPromise; output.stdout.push(deactivateTmpUserOutput.stdout); output.stderr.push(deactivateTmpUserOutput.stderr); ux.action.stop('done'); // Return an object return { output }; } catch (error) { ux.action.stop('failed'); throw new SfError(messages.getMessage('errorAssignmentFailed', [JSON.stringify(error, null, 2)])); } } } //# sourceMappingURL=profile.js.map