Skip to content

Commit c1957e4

Browse files
committed
New command: m365 graph directoryextension add
1 parent 90e1ec6 commit c1957e4

File tree

5 files changed

+54
-36
lines changed

5 files changed

+54
-36
lines changed

docs/docs/cmd/graph/directoryextension/directoryextension-add.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import TabItem from '@theme/TabItem';
44

55
# graph directoryextension add
66

7-
Create a new directory extension
7+
Creates a new directory extension
88

99
## Usage
1010

@@ -30,7 +30,7 @@ m365 graph directoryextension add [options]
3030
`--dataType <dataType>`
3131
: The data type of the value the extension property can hold. Possible values are: `Binary`, `Boolean`, `DateTime`, `Integer`, `LargeInteger` and `String`.
3232

33-
`targetObjects <targetObjects>`
33+
`--targetObjects <targetObjects>`
3434
: Comma-separated list of Microsoft Graph resources that can use the extension. Possible values are: `User`, `Group`, `Application`, `AdministrativeUnit`, `Device` and `Organization`.
3535

3636
`--isMultiValued`

src/m365/graph/commands/directoryextension/directoryextension-add.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ describe(commands.DIRECTORYEXTENSION_ADD, () => {
6565

6666
before(() => {
6767
sinon.stub(auth, 'restoreAuth').resolves();
68-
sinon.stub(telemetry, 'trackEvent').returns();
68+
sinon.stub(telemetry, 'trackEvent').resolves();
6969
sinon.stub(pid, 'getProcessName').returns('');
7070
sinon.stub(session, 'getId').returns('');
7171
auth.connection.active = true;
@@ -248,7 +248,7 @@ describe(commands.DIRECTORYEXTENSION_ADD, () => {
248248
});
249249

250250
it('correctly creates a directory extension defined on the application specified by appId', async () => {
251-
sinon.stub(entraApp, 'getAppObjectIdFromAppId').resolves(appObjectId);
251+
sinon.stub(entraApp, 'getAppRegistrationByAppId').resolves({ id: appObjectId });
252252
sinon.stub(request, 'post').callsFake(async (opts) => {
253253
if (opts.url === `https://graph.microsoft.com/v1.0/applications/${appObjectId}/extensionProperties`) {
254254
return responseForMultiValued;
@@ -269,7 +269,7 @@ describe(commands.DIRECTORYEXTENSION_ADD, () => {
269269
});
270270

271271
it('correctly creates a directory extension defined on the application specified by appName', async () => {
272-
sinon.stub(entraApp, 'getAppObjectIdFromAppName').resolves(appObjectId);
272+
sinon.stub(entraApp, 'getAppRegistrationByAppName').resolves({ id: appObjectId });
273273
sinon.stub(request, 'post').callsFake(async (opts) => {
274274
if (opts.url === `https://graph.microsoft.com/v1.0/applications/${appObjectId}/extensionProperties`) {
275275
return responseWithMultipleTargets;

src/m365/graph/commands/directoryextension/directoryextension-add.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class GraphDirectoryExtensionAddCommand extends GraphCommand {
6262
const appObjectId = await this.getAppObjectId(args.options);
6363

6464
if (args.options.verbose) {
65-
await logger.logToStderr(`Adding directoroy extension to the app with id '${appObjectId}'...`);
65+
await logger.logToStderr(`Adding directory extension to the app with id '${appObjectId}'...`);
6666
}
6767

6868
const requestOptions: CliRequestOptions = {
@@ -94,10 +94,10 @@ class GraphDirectoryExtensionAddCommand extends GraphCommand {
9494
}
9595

9696
if (options.appId) {
97-
return await entraApp.getAppObjectIdFromAppId(options.appId);
97+
return (await entraApp.getAppRegistrationByAppId(options.appId, ["id"])).id!;
9898
}
9999

100-
return await entraApp.getAppObjectIdFromAppName(options.appName!);
100+
return (await entraApp.getAppRegistrationByAppName(options.appName!, ["id"])).id!;
101101
}
102102
}
103103

src/utils/entraApp.spec.ts

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ describe('utils/entraApp', () => {
1212
const appId = '7f5df2f4-9ed6-4df7-86d7-eefbfc4ab091';
1313
const appName = 'ContosoApp';
1414
const secondAppObjectId = 'fc33aa61-cf0e-1234-9506-f633347202ac';
15+
1516
afterEach(() => {
1617
sinonUtil.restore([
1718
request.get,
@@ -20,9 +21,9 @@ describe('utils/entraApp', () => {
2021
]);
2122
});
2223

23-
it('correctly get single app object id by appId using getAppObjectIdFromAppId', async () => {
24+
it('correctly get single app object id by appId using getAppRegistrationByAppId', async () => {
2425
sinon.stub(request, 'get').callsFake(async opts => {
25-
if (opts.url === `https://graph.microsoft.com/v1.0/applications?$filter=appId eq '${appId}'&$select=id`) {
26+
if (opts.url === `https://graph.microsoft.com/v1.0/applications?$filter=appId eq '${appId}'`) {
2627
return {
2728
value: [
2829
{
@@ -35,13 +36,13 @@ describe('utils/entraApp', () => {
3536
return 'Invalid Request';
3637
});
3738

38-
const actual = await entraApp.getAppObjectIdFromAppId(appId);
39-
assert.deepStrictEqual(actual, appObjectId);
39+
const actual = await entraApp.getAppRegistrationByAppId(appId);
40+
assert.deepStrictEqual(actual.id, appObjectId);
4041
});
4142

42-
it('correctly get single app object id by appId using getAppObjectIdFromAppName', async () => {
43+
it('correctly get single app object id by appId using getAppRegistrationByAppName', async () => {
4344
sinon.stub(request, 'get').callsFake(async opts => {
44-
if (opts.url === `https://graph.microsoft.com/v1.0/applications?$filter=displayName eq '${formatting.encodeQueryParameter(appName)}'&$select=id`) {
45+
if (opts.url === `https://graph.microsoft.com/v1.0/applications?$filter=displayName eq '${formatting.encodeQueryParameter(appName)}'`) {
4546
return {
4647
value: [
4748
{
@@ -54,11 +55,11 @@ describe('utils/entraApp', () => {
5455
return 'Invalid Request';
5556
});
5657

57-
const actual = await entraApp.getAppObjectIdFromAppName(appName);
58-
assert.deepStrictEqual(actual, appObjectId);
58+
const actual = await entraApp.getAppRegistrationByAppName(appName);
59+
assert.deepStrictEqual(actual.id, appObjectId);
5960
});
6061

61-
it('handles selecting single application when multiple applications with the specified name found using getAppObjectIdFromAppName and cli is set to prompt', async () => {
62+
it('handles selecting single application when multiple applications with the specified name found using getAppRegistrationByAppName and cli is set to prompt', async () => {
6263
sinon.stub(request, 'get').callsFake(async opts => {
6364
if (opts.url === `https://graph.microsoft.com/v1.0/applications?$filter=displayName eq '${formatting.encodeQueryParameter(appName)}'&$select=id`) {
6465
return {
@@ -74,23 +75,23 @@ describe('utils/entraApp', () => {
7475

7576
sinon.stub(cli, 'handleMultipleResultsFound').resolves({ id: secondAppObjectId });
7677

77-
const actual = await entraApp.getAppObjectIdFromAppName(appName);
78-
assert.deepStrictEqual(actual, secondAppObjectId);
78+
const actual = await entraApp.getAppRegistrationByAppName(appName, ['id']);
79+
assert.deepStrictEqual(actual.id, secondAppObjectId);
7980
});
8081

81-
it('throws error message when no application was found using getAppObjectIdFromAppId', async () => {
82+
it('throws error message when no application was found using getAppRegistrationByAppId', async () => {
8283
sinon.stub(request, 'get').callsFake(async (opts) => {
83-
if (opts.url === `https://graph.microsoft.com/v1.0/applications?$filter=appId eq '${appId}'&$select=id`) {
84+
if (opts.url === `https://graph.microsoft.com/v1.0/applications?$filter=appId eq '${appId}'&$select=id,displayName`) {
8485
return { value: [] };
8586
}
8687

8788
throw 'Invalid Request';
8889
});
8990

90-
await assert.rejects(entraApp.getAppObjectIdFromAppId(appId)), Error(`App with appId '${appId}' not found in Microsoft Entra ID`);
91+
await assert.rejects(entraApp.getAppRegistrationByAppId(appId, ['id', 'displayName'])), Error(`App with appId '${appId}' not found in Microsoft Entra ID`);
9192
});
9293

93-
it('throws error message when no application was found using getAppObjectIdFromAppName', async () => {
94+
it('throws error message when no application was found using getAppRegistrationByAppName', async () => {
9495
sinon.stub(request, 'get').callsFake(async (opts) => {
9596
if (opts.url === `https://graph.microsoft.com/v1.0/applications?$filter=displayName eq '${formatting.encodeQueryParameter(appName)}'&$select=id`) {
9697
return { value: [] };
@@ -99,10 +100,10 @@ describe('utils/entraApp', () => {
99100
throw 'Invalid Request';
100101
});
101102

102-
await assert.rejects(entraApp.getAppObjectIdFromAppName(appName)), Error(`App with name '${appName}' not found in Microsoft Entra ID`);
103+
await assert.rejects(entraApp.getAppRegistrationByAppName(appName,['id'])), Error(`App with name '${appName}' not found in Microsoft Entra ID`);
103104
});
104105

105-
it('throws error message when multiple applications were found using getAppObjectIdFromAppName', async () => {
106+
it('throws error message when multiple applications were found using getAppRegistrationByAppName', async () => {
106107
sinon.stub(cli, 'getSettingWithDefaultValue').callsFake((settingName, defaultValue) => {
107108
if (settingName === settingsNames.prompt) {
108109
return false;
@@ -112,18 +113,24 @@ describe('utils/entraApp', () => {
112113
});
113114

114115
sinon.stub(request, 'get').callsFake(async opts => {
115-
if (opts.url === `https://graph.microsoft.com/v1.0/applications?$filter=displayName eq '${formatting.encodeQueryParameter(appName)}'&$select=id`) {
116+
if (opts.url === `https://graph.microsoft.com/v1.0/applications?$filter=displayName eq '${formatting.encodeQueryParameter(appName)}'&$select=id,displayName`) {
116117
return {
117118
value: [
118-
{ id: appObjectId },
119-
{ id: secondAppObjectId }
119+
{
120+
id: appObjectId,
121+
displayName: appName
122+
},
123+
{
124+
id: secondAppObjectId,
125+
displayName: appName
126+
}
120127
]
121128
};
122129
}
123130

124131
return 'Invalid Request';
125132
});
126133

127-
await assert.rejects(entraApp.getAppObjectIdFromAppName(appName), Error(`Multiple apps with name '${appName}' found in Microsoft Entra ID. Found: ${appObjectId}, ${secondAppObjectId}.`));
134+
await assert.rejects(entraApp.getAppRegistrationByAppName(appName, ['id', 'displayName']), Error(`Multiple apps with name '${appName}' found in Microsoft Entra ID. Found: ${appObjectId}, ${secondAppObjectId}.`));
128135
});
129136
});

src/utils/entraApp.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -413,27 +413,38 @@ export const entraApp = {
413413

414414
return resolvedApis;
415415
},
416-
async getAppObjectIdFromAppId(appId: string): Promise<string> {
417-
const apps = await odata.getAllItems<Application>(`https://graph.microsoft.com/v1.0/applications?$filter=appId eq '${appId}'&$select=id`);
416+
async getAppRegistrationByAppId(appId: string, properties?: string[]): Promise<Application> {
417+
let url = `https://graph.microsoft.com/v1.0/applications?$filter=appId eq '${appId}'`;
418+
419+
if (properties) {
420+
url += `&$select=${properties.join(',')}`;
421+
}
422+
const apps = await odata.getAllItems<Application>(url);
418423

419424
if (apps.length === 0) {
420425
throw `App with appId '${appId}' not found in Microsoft Entra ID`;
421426
}
422427

423-
return apps[0].id!;
428+
return apps[0];
424429
},
425-
async getAppObjectIdFromAppName(appName: string): Promise<string> {
426-
const apps = await odata.getAllItems<Application>(`https://graph.microsoft.com/v1.0/applications?$filter=displayName eq '${formatting.encodeQueryParameter(appName)}'&$select=id`);
430+
async getAppRegistrationByAppName(appName: string, properties?: string[]): Promise<Application> {
431+
let url = `https://graph.microsoft.com/v1.0/applications?$filter=displayName eq '${formatting.encodeQueryParameter(appName)}'`;
432+
433+
if (properties) {
434+
url += `&$select=${properties.join(',')}`;
435+
}
436+
437+
const apps = await odata.getAllItems<Application>(url);
427438

428439
if (apps.length === 0) {
429440
throw `App with name '${appName}' not found in Microsoft Entra ID`;
430441
}
431442

432443
if (apps.length > 1) {
433444
const resultAsKeyValuePair = formatting.convertArrayToHashTable('id', apps);
434-
return (await cli.handleMultipleResultsFound<Application>(`Multiple apps with name '${appName}' found in Microsoft Entra ID.`, resultAsKeyValuePair)).id!;
445+
return await cli.handleMultipleResultsFound<Application>(`Multiple apps with name '${appName}' found in Microsoft Entra ID.`, resultAsKeyValuePair);
435446
}
436447

437-
return apps[0].id!;
448+
return apps[0];
438449
}
439450
};

0 commit comments

Comments
 (0)