UNPKG

@pnp/cli-microsoft365

Version:

Manage Microsoft 365 and SharePoint Framework projects on any platform

152 lines • 7.13 kB
import os from 'os'; import { z } from 'zod'; import { cli } from '../../../../cli/cli.js'; import { globalOptionsZod } from '../../../../Command.js'; import request from '../../../../request.js'; import { formatting } from '../../../../utils/formatting.js'; import { validation } from '../../../../utils/validation.js'; import GraphCommand from '../../../base/GraphCommand.js'; import commands from '../../commands.js'; export const options = z.strictObject({ ...globalOptionsZod.shape, appId: z.uuid().optional(), appObjectId: z.uuid().optional(), appDisplayName: z.string().optional(), resource: z.string().alias('r'), scopes: z.string().transform((value) => value.split(',').map(String)).alias('s'), force: z.boolean().optional().alias('f') }); class EntraAppRoleAssignmentRemoveCommand extends GraphCommand { get name() { return commands.APPROLEASSIGNMENT_REMOVE; } get description() { return 'Deletes an app role assignment for the specified Entra Application Registration'; } get schema() { return options; } getRefinedSchema(schema) { return schema .refine(options => [options.appId, options.appObjectId, options.appDisplayName].filter(o => o !== undefined).length === 1, { error: 'Specify either appId, appObjectId, or appDisplayName', params: { customCode: 'optionSet', options: ['appId', 'appObjectId', 'appDisplayName'] } }); } async commandAction(logger, args) { const removeAppRoleAssignment = async () => { let sp; // get the service principal associated with the appId let spMatchQuery; if (args.options.appId) { spMatchQuery = `appId eq '${formatting.encodeQueryParameter(args.options.appId)}'`; } else if (args.options.appObjectId) { spMatchQuery = `id eq '${formatting.encodeQueryParameter(args.options.appObjectId)}'`; } else { spMatchQuery = `displayName eq '${formatting.encodeQueryParameter(args.options.appDisplayName)}'`; } try { let resp = await this.getServicePrincipalForApp(spMatchQuery); if (!resp.value.length) { throw 'app registration not found'; } sp = resp.value[0]; let resource = formatting.encodeQueryParameter(args.options.resource); // try resolve aliases that the user might enter since these are seen in the Azure portal switch (args.options.resource.toLocaleLowerCase()) { case 'sharepoint': resource = 'Office 365 SharePoint Online'; break; case 'intune': resource = 'Microsoft Intune API'; break; case 'exchange': resource = 'Office 365 Exchange Online'; break; } // will perform resource name, appId or objectId search let filter = `$filter=(displayName eq '${resource}' or startswith(displayName,'${resource}'))`; if (validation.isValidGuid(resource)) { filter += ` or appId eq '${resource}' or id eq '${resource}'`; } const requestOptions = { url: `${this.resource}/v1.0/servicePrincipals?${filter}`, headers: { 'accept': 'application/json' }, responseType: 'json' }; resp = await request.get(requestOptions); if (!resp.value.length) { throw 'Resource not found'; } const appRolesToBeDeleted = []; const appRolesFound = resp.value[0].appRoles; if (!appRolesFound.length) { throw `The resource '${args.options.resource}' does not have any application permissions available.`; } for (const scope of args.options.scopes) { const existingRoles = appRolesFound.filter((role) => { return role.value.toLocaleLowerCase() === scope.toLocaleLowerCase().trim(); }); if (!existingRoles.length) { // the role specified in the scopes option does not belong to the found service principles // throw an error and show list with available roles (scopes) let availableRoles = ''; appRolesFound.map((r) => availableRoles += `${os.EOL}${r.value}`); throw `The scope value '${scope}' you have specified does not exist for ${args.options.resource}. ${os.EOL}Available scopes (application permissions) are: ${availableRoles}`; } appRolesToBeDeleted.push(existingRoles[0]); } const tasks = []; for (const appRole of appRolesToBeDeleted) { const appRoleAssignment = sp.appRoleAssignments.filter((role) => role.appRoleId === appRole.id); if (!appRoleAssignment.length) { throw 'App role assignment not found'; } tasks.push(this.removeAppRoleAssignmentForServicePrincipal(sp.id, appRoleAssignment[0].id)); } await Promise.all(tasks); } catch (err) { this.handleRejectedODataJsonPromise(err); } }; if (args.options.force) { await removeAppRoleAssignment(); } else { const result = await cli.promptForConfirmation({ message: `Are you sure you want to remove the appRoleAssignment with scope(s) ${args.options.scopes} for resource ${args.options.resource}?` }); if (result) { await removeAppRoleAssignment(); } } } async getServicePrincipalForApp(filterParam) { const spRequestOptions = { url: `${this.resource}/v1.0/servicePrincipals?$expand=appRoleAssignments&$filter=${filterParam}`, headers: { accept: 'application/json' }, responseType: 'json' }; return request.get(spRequestOptions); } async removeAppRoleAssignmentForServicePrincipal(spId, appRoleAssignmentId) { const spRequestOptions = { url: `${this.resource}/v1.0/servicePrincipals/${spId}/appRoleAssignments/${appRoleAssignmentId}`, headers: { 'accept': 'application/json;odata.metadata=none' }, responseType: 'json' }; return request.delete(spRequestOptions); } } export default new EntraAppRoleAssignmentRemoveCommand(); //# sourceMappingURL=approleassignment-remove.js.map