Skip to content

Commit

Permalink
Updates Power Automate commands to use new API endpoint. Closes #5715
Browse files Browse the repository at this point in the history
  • Loading branch information
martinlingstuyl authored and Adam-it committed Dec 17, 2023
1 parent 1c23854 commit 9860c95
Show file tree
Hide file tree
Showing 31 changed files with 241 additions and 117 deletions.
4 changes: 4 additions & 0 deletions src/Auth.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2083,6 +2083,10 @@ describe('Auth', () => {
assert.strictEqual(Auth.getResourceFromUrl('https://api.powerbi.com'), 'https://analysis.windows.net/powerbi/api');
});

it('correctly retrieves resource for https://api.flow.microsoft.com', () => {
assert.strictEqual(Auth.getResourceFromUrl('https://api.flow.microsoft.com'), 'https://management.azure.com/');
});

it('returns undefined if access token is not set when determining auth type', () => {
assert.strictEqual(accessToken.isAppOnlyAccessToken(''), undefined);
});
Expand Down
4 changes: 4 additions & 0 deletions src/Auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,10 @@ export class Auth {
resource = 'https://service.powerapps.com/';
}

if (resource === 'https://api.flow.microsoft.com') {
resource = 'https://management.azure.com/';
}

if (resource === 'https://api.powerbi.com') {
// api.powerbi.com is not a valid resource
// we need to use https://analysis.windows.net/powerbi/api instead
Expand Down
75 changes: 75 additions & 0 deletions src/m365/base/PowerAutomateCommand.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import assert from 'assert';
import sinon from 'sinon';
import auth, { CloudType } from '../../Auth.js';
import { CommandError } from '../../Command.js';
import { telemetry } from '../../telemetry.js';
import PowerAutomateCommand from './PowerAutomateCommand.js';

class MockCommand extends PowerAutomateCommand {
public get name(): string {
return 'mock';
}

public get description(): string {
return 'Mock command';
}

public async commandAction(): Promise<void> {
}

public commandHelp(): void {
}
}

describe('PowerAutomateCommand', () => {
const cmd = new MockCommand();
const cloudError = new CommandError(`Power Automate commands only support the public cloud at the moment. We'll add support for other clouds in the future. Sorry for the inconvenience.`);

before(() => {
sinon.stub(telemetry, 'trackEvent').returns();
});

after(() => {
sinon.restore();
});

it('returns correct resource', () => {
const command = new MockCommand();
assert.strictEqual((command as any).resource, 'https://api.flow.microsoft.com');
});

it(`doesn't throw error when not connected`, () => {
auth.service.connected = false;
(cmd as any).initAction({ options: {} }, {});
});

it('throws error when connected to USGov cloud', () => {
auth.service.connected = true;
auth.service.cloudType = CloudType.USGov;
assert.throws(() => (cmd as any).initAction({ options: {} }, {}), cloudError);
});

it('throws error when connected to USGovHigh cloud', () => {
auth.service.connected = true;
auth.service.cloudType = CloudType.USGovHigh;
assert.throws(() => (cmd as any).initAction({ options: {} }, {}), cloudError);
});

it('throws error when connected to USGovDoD cloud', () => {
auth.service.connected = true;
auth.service.cloudType = CloudType.USGovDoD;
assert.throws(() => (cmd as any).initAction({ options: {} }, {}), cloudError);
});

it('throws error when connected to China cloud', () => {
auth.service.connected = true;
auth.service.cloudType = CloudType.China;
assert.throws(() => (cmd as any).initAction({ options: {} }, {}), cloudError);
});

it(`doesn't throw error when connected to public cloud`, () => {
auth.service.connected = true;
auth.service.cloudType = CloudType.Public;
assert.doesNotThrow(() => (cmd as any).initAction({ options: {} }, {}));
});
});
22 changes: 22 additions & 0 deletions src/m365/base/PowerAutomateCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import auth, { CloudType } from '../../Auth.js';
import { Logger } from '../../cli/Logger.js';
import Command, { CommandArgs, CommandError } from '../../Command.js';

export default abstract class PowerAutomateCommand extends Command {
protected get resource(): string {
return 'https://api.flow.microsoft.com';
}

protected initAction(args: CommandArgs, logger: Logger): void {
super.initAction(args, logger);

if (!auth.service.connected) {
// we fail no login in the base command command class
return;
}

if (auth.service.cloudType !== CloudType.Public) {
throw new CommandError(`Power Automate commands only support the public cloud at the moment. We'll add support for other clouds in the future. Sorry for the inconvenience.`);
}
}
}
8 changes: 4 additions & 4 deletions src/m365/flow/commands/environment/environment-get.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ describe(commands.ENVIRONMENT_GET, () => {

it('retrieves information about the specified environment (debug)', async () => {
sinon.stub(request, 'get').callsFake(async opts => {
if ((opts.url === `https://management.azure.com/providers/Microsoft.ProcessSimple/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5?api-version=2016-11-01`)) {
if ((opts.url === `https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5?api-version=2016-11-01`)) {
return flowResponse;
}

Expand All @@ -139,7 +139,7 @@ describe(commands.ENVIRONMENT_GET, () => {

it('retrieves information about the specified environment', async () => {
sinon.stub(request, 'get').callsFake(async opts => {
if ((opts.url === `https://management.azure.com/providers/Microsoft.ProcessSimple/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5?api-version=2016-11-01`)) {
if ((opts.url === `https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5?api-version=2016-11-01`)) {
return flowResponse;
}

Expand All @@ -152,7 +152,7 @@ describe(commands.ENVIRONMENT_GET, () => {

it('retrieves information about the specified environment with output text', async () => {
sinon.stub(request, 'get').callsFake(async opts => {
if ((opts.url === `https://management.azure.com/providers/Microsoft.ProcessSimple/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5?api-version=2016-11-01`)) {
if ((opts.url === `https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5?api-version=2016-11-01`)) {
return flowResponse;
}

Expand All @@ -165,7 +165,7 @@ describe(commands.ENVIRONMENT_GET, () => {

it('retrieves information about the default environment', async () => {
sinon.stub(request, 'get').callsFake(async opts => {
if ((opts.url === `https://management.azure.com/providers/Microsoft.ProcessSimple/environments/~default?api-version=2016-11-01`)) {
if ((opts.url === `https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/~default?api-version=2016-11-01`)) {
return flowResponse;
}

Expand Down
6 changes: 3 additions & 3 deletions src/m365/flow/commands/environment/environment-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Logger } from '../../../../cli/Logger.js';
import GlobalOptions from '../../../../GlobalOptions.js';
import request, { CliRequestOptions } from '../../../../request.js';
import { formatting } from '../../../../utils/formatting.js';
import AzmgmtCommand from '../../../base/AzmgmtCommand.js';
import PowerAutomateCommand from '../../../base/PowerAutomateCommand.js';
import commands from '../../commands.js';
import { FlowEnvironmentDetails } from './FlowEnvironmentDetails.js';

Expand All @@ -14,7 +14,7 @@ interface Options extends GlobalOptions {
name?: string;
}

class FlowEnvironmentGetCommand extends AzmgmtCommand {
class FlowEnvironmentGetCommand extends PowerAutomateCommand {
public get name(): string {
return commands.ENVIRONMENT_GET;
}
Expand Down Expand Up @@ -55,7 +55,7 @@ class FlowEnvironmentGetCommand extends AzmgmtCommand {
await logger.logToStderr(`Retrieving information about Microsoft Flow environment ${args.options.name ?? ''}...`);
}

let requestUrl = `${this.resource}providers/Microsoft.ProcessSimple/environments/`;
let requestUrl = `${this.resource}/providers/Microsoft.ProcessSimple/environments/`;

if (args.options.name) {
requestUrl += `${formatting.encodeQueryParameter(args.options.name)}`;
Expand Down
6 changes: 3 additions & 3 deletions src/m365/flow/commands/environment/environment-list.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { CommandArgs } from '../../../../Command.js';
import { Logger } from '../../../../cli/Logger.js';
import { odata } from '../../../../utils/odata.js';
import AzmgmtCommand from '../../../base/AzmgmtCommand.js';
import PowerAutomateCommand from '../../../base/PowerAutomateCommand.js';
import commands from '../../commands.js';

class FlowEnvironmentListCommand extends AzmgmtCommand {
class FlowEnvironmentListCommand extends PowerAutomateCommand {
public get name(): string {
return commands.ENVIRONMENT_LIST;
}
Expand All @@ -23,7 +23,7 @@ class FlowEnvironmentListCommand extends AzmgmtCommand {
}

try {
const res = await odata.getAllItems<{ name: string, displayName: string; properties: { displayName: string } }>(`${this.resource}providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01`);
const res = await odata.getAllItems<{ name: string, displayName: string; properties: { displayName: string } }>(`${this.resource}/providers/Microsoft.ProcessSimple/environments?api-version=2016-11-01`);

if (res.length > 0) {
if (args.options.output !== 'json') {
Expand Down
4 changes: 2 additions & 2 deletions src/m365/flow/commands/flow-disable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe(commands.DISABLE, () => {
});

await command.action(logger, { options: { debug: true, name: '3989cb59-ce1a-4a5c-bb78-257c5c39381d', environmentName: 'Default-d87a7535-dd31-4437-bfe1-95340acd55c5' } });
assert.strictEqual(postStub.lastCall.args[0].url, 'https://management.azure.com/providers/Microsoft.ProcessSimple/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5/flows/3989cb59-ce1a-4a5c-bb78-257c5c39381d/stop?api-version=2016-11-01');
assert.strictEqual(postStub.lastCall.args[0].url, 'https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5/flows/3989cb59-ce1a-4a5c-bb78-257c5c39381d/stop?api-version=2016-11-01');
});

it('disables the specified flow as admin', async () => {
Expand All @@ -81,7 +81,7 @@ describe(commands.DISABLE, () => {
});

await assert.rejects(command.action(logger, { options: { name: '3989cb59-ce1a-4a5c-bb78-257c5c39381d', environmentName: 'Default-d87a7535-dd31-4437-bfe1-95340acd55c5', asAdmin: true } }));
assert.strictEqual(postStub.lastCall.args[0].url, 'https://management.azure.com/providers/Microsoft.ProcessSimple/scopes/admin/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5/flows/3989cb59-ce1a-4a5c-bb78-257c5c39381d/stop?api-version=2016-11-01');
assert.strictEqual(postStub.lastCall.args[0].url, 'https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/scopes/admin/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5/flows/3989cb59-ce1a-4a5c-bb78-257c5c39381d/stop?api-version=2016-11-01');
});

it('correctly handles no environment found', async () => {
Expand Down
6 changes: 3 additions & 3 deletions src/m365/flow/commands/flow-disable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Logger } from '../../../cli/Logger.js';
import GlobalOptions from '../../../GlobalOptions.js';
import request, { CliRequestOptions } from '../../../request.js';
import { formatting } from '../../../utils/formatting.js';
import AzmgmtCommand from '../../base/AzmgmtCommand.js';
import PowerAutomateCommand from '../../base/PowerAutomateCommand.js';
import commands from '../commands.js';

interface CommandArgs {
Expand All @@ -15,7 +15,7 @@ interface Options extends GlobalOptions {
asAdmin: boolean;
}

class FlowDisableCommand extends AzmgmtCommand {
class FlowDisableCommand extends PowerAutomateCommand {
public get name(): string {
return commands.DISABLE;
}
Expand Down Expand Up @@ -59,7 +59,7 @@ class FlowDisableCommand extends AzmgmtCommand {
}

const requestOptions: CliRequestOptions = {
url: `${this.resource}providers/Microsoft.ProcessSimple/${args.options.asAdmin ? 'scopes/admin/' : ''}environments/${formatting.encodeQueryParameter(args.options.environmentName)}/flows/${formatting.encodeQueryParameter(args.options.name)}/stop?api-version=2016-11-01`,
url: `${this.resource}/providers/Microsoft.ProcessSimple/${args.options.asAdmin ? 'scopes/admin/' : ''}environments/${formatting.encodeQueryParameter(args.options.environmentName)}/flows/${formatting.encodeQueryParameter(args.options.name)}/stop?api-version=2016-11-01`,
headers: {
accept: 'application/json'
},
Expand Down
4 changes: 2 additions & 2 deletions src/m365/flow/commands/flow-enable.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe(commands.ENABLE, () => {
});

await command.action(logger, { options: { debug: true, name: '3989cb59-ce1a-4a5c-bb78-257c5c39381d', environmentName: 'Default-d87a7535-dd31-4437-bfe1-95340acd55c5' } });
assert.strictEqual(postStub.lastCall.args[0].url, 'https://management.azure.com/providers/Microsoft.ProcessSimple/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5/flows/3989cb59-ce1a-4a5c-bb78-257c5c39381d/start?api-version=2016-11-01');
assert.strictEqual(postStub.lastCall.args[0].url, 'https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5/flows/3989cb59-ce1a-4a5c-bb78-257c5c39381d/start?api-version=2016-11-01');
});

it('enables the specified flow as admin', async () => {
Expand All @@ -82,7 +82,7 @@ describe(commands.ENABLE, () => {
});

await assert.rejects(command.action(logger, { options: { name: '3989cb59-ce1a-4a5c-bb78-257c5c39381d', environmentName: 'Default-d87a7535-dd31-4437-bfe1-95340acd55c5', asAdmin: true } }));
assert.strictEqual(postStub.lastCall.args[0].url, 'https://management.azure.com/providers/Microsoft.ProcessSimple/scopes/admin/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5/flows/3989cb59-ce1a-4a5c-bb78-257c5c39381d/start?api-version=2016-11-01');
assert.strictEqual(postStub.lastCall.args[0].url, 'https://api.flow.microsoft.com/providers/Microsoft.ProcessSimple/scopes/admin/environments/Default-d87a7535-dd31-4437-bfe1-95340acd55c5/flows/3989cb59-ce1a-4a5c-bb78-257c5c39381d/start?api-version=2016-11-01');
});

it('correctly handles no environment found', async () => {
Expand Down
6 changes: 3 additions & 3 deletions src/m365/flow/commands/flow-enable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Logger } from '../../../cli/Logger.js';
import GlobalOptions from '../../../GlobalOptions.js';
import request, { CliRequestOptions } from '../../../request.js';
import { formatting } from '../../../utils/formatting.js';
import AzmgmtCommand from '../../base/AzmgmtCommand.js';
import PowerAutomateCommand from '../../base/PowerAutomateCommand.js';
import commands from '../commands.js';

interface CommandArgs {
Expand All @@ -15,7 +15,7 @@ interface Options extends GlobalOptions {
asAdmin: boolean;
}

class FlowEnableCommand extends AzmgmtCommand {
class FlowEnableCommand extends PowerAutomateCommand {
public get name(): string {
return commands.ENABLE;
}
Expand Down Expand Up @@ -59,7 +59,7 @@ class FlowEnableCommand extends AzmgmtCommand {
}

const requestOptions: CliRequestOptions = {
url: `${this.resource}providers/Microsoft.ProcessSimple/${args.options.asAdmin ? 'scopes/admin/' : ''}environments/${formatting.encodeQueryParameter(args.options.environmentName)}/flows/${formatting.encodeQueryParameter(args.options.name)}/start?api-version=2016-11-01`,
url: `${this.resource}/providers/Microsoft.ProcessSimple/${args.options.asAdmin ? 'scopes/admin/' : ''}environments/${formatting.encodeQueryParameter(args.options.environmentName)}/flows/${formatting.encodeQueryParameter(args.options.name)}/start?api-version=2016-11-01`,
headers: {
accept: 'application/json'
},
Expand Down
Loading

0 comments on commit 9860c95

Please sign in to comment.