Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New command : tenant report settings set - closes #6247 #6548

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions docs/docs/cmd/tenant/report/report-settings-set.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import Global from '/docs/cmd/_global.mdx';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# report settings set

Update (adminReportSettings) tenant-level settings for Microsoft 365 reports

## Usage

```sh
m365 tenant report settings set [options]
```

## Options

```md definition-list
`-h, --hideUserInformation <hideUserInformation>`
: Determines whether all reports conceal user information such as usernames, groups, and sites.

`--verbose`
: Runs command with verbose logging

`--debug`
: Runs command with debug logging

```

<Global />

## Remarks

Please refer to the [Graph documentation page](https://learn.microsoft.com/en-in/graph/api/adminreportsettings-update?view=graph-rest-1.0&tabs=http).

:::note

This command returns a `204 No content` response code. To see the default logs, we recommed you to run the command with `---verbose or --debug` options

## Examples

Set `displayConcealedNames` to true.

```sh
m365 tenant report settings set --hideUserInformation true
```

Set `displayConcealedNames` to false.

```sh
m365 tenant report settings set --hideUserInformation false
```


## Response

:::note

This command returns a `204 No content` response code.

<Tabs>
<TabItem value="JSON">

```json
{

}
```
</TabItem>
</Tabs>
1 change: 1 addition & 0 deletions src/m365/tenant/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default {
REPORT_OFFICE365ACTIVATIONSUSERDETAIL: `${prefix} report office365activationsuserdetail`,
REPORT_OFFICE365ACTIVATIONSUSERCOUNTS: `${prefix} report office365activationsusercounts`,
REPORT_SERVICESUSERCOUNTS: `${prefix} report servicesusercounts`,
REPORT_TENANTSETTINGS_SET: `${prefix} report settings set`,
SECURITY_ALERTS_LIST: `${prefix} security alerts list`,
SERVICEANNOUNCEMENT_HEALTHISSUE_GET: `${prefix} serviceannouncement healthissue get`,
SERVICEANNOUNCEMENT_HEALTH_GET: `${prefix} serviceannouncement health get`,
Expand Down
97 changes: 97 additions & 0 deletions src/m365/tenant/commands/report/report-settings-set.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import assert from 'assert';
import sinon from 'sinon';
import auth from '../../../../Auth.js';
import { Logger } from '../../../../cli/Logger.js';
import { CommandError } from '../../../../Command.js';
import request from '../../../../request.js';
import { telemetry } from '../../../../telemetry.js';
import { pid } from '../../../../utils/pid.js';
import { session } from '../../../../utils/session.js';
import { sinonUtil } from '../../../../utils/sinonUtil.js';
import commands from '../../commands.js';
import command from './report-settings-set.js';

describe(commands.REPORT_TENANTSETTINGS_SET, () => {
let log: string[];
let logger: Logger;
let loggerLogSpy: sinon.SinonSpy;

before(() => {
sinon.stub(auth, 'restoreAuth').resolves();
sinon.stub(telemetry, 'trackEvent').returns();
sinon.stub(pid, 'getProcessName').returns('');
sinon.stub(session, 'getId').returns('');
auth.connection.active = true;
});

beforeEach(() => {
log = [];
logger = {
log: async (msg: string) => {
log.push(msg);
},
logRaw: async (msg: string) => {
log.push(msg);
},
logToStderr: async (msg: string) => {
log.push(msg);
}
};
loggerLogSpy = sinon.spy(logger, 'log');
});

afterEach(() => {
sinonUtil.restore([
request.patch
]);
});

after(() => {
sinon.restore();
auth.connection.active = false;
});

it('has correct name', () => {
assert.strictEqual(command.name, commands.REPORT_TENANTSETTINGS_SET);
});

it('has a description', () => {
assert.notStrictEqual(command.description, null);
});

it('logs a message when updating settings in verbose mode', async () => {
await command.action(logger, { options: { verbose: true, hideUserInformation: true } });
await command.action(logger, { options: { hideUserInformation: true } });
assert(loggerLogSpy.calledWith('Updating report settings...'));
});



it('patches the tenant settings report with the specified settings', async () => {
sinon.stub(request, 'patch').callsFake(async (opts) => {
if (opts.url === `https://graph.microsoft.com/v1.0/admin/reportSettings`) {
return Promise.resolve();
}
return Promise.reject('Invalid request');
});

await command.action(logger, {
options: { hideUserInformation: true }
});
});

it('handles error when retrieving tenant report settings failed', async () => {
sinon.stub(request, 'patch').callsFake(async (opts) => {
if (opts.url === `https://graph.microsoft.com/v1.0/admin/reportSettings`) {
throw { error: { message: 'An error has occurred' } };
}
throw `Invalid request`;
});

await assert.rejects(
command.action(logger, { options: {} } as any),
new CommandError('An error has occurred')
);
});

});
85 changes: 85 additions & 0 deletions src/m365/tenant/commands/report/report-settings-set.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//import { boolean } from 'zod';
import { Logger } from '../../../../cli/Logger.js';
import GlobalOptions from '../../../../GlobalOptions.js';
import request, { CliRequestOptions } from '../../../../request.js';
import GraphCommand from '../../../base/GraphCommand.js';
import commands from '../../commands.js';

interface CommandArgs {
options: Options;
}

interface Options extends GlobalOptions {
hideUserInformation: boolean;
}

class TenantReportSettingsSetCommand extends GraphCommand {
public get name(): string {
return commands.REPORT_TENANTSETTINGS_SET;
}

public get description(): string {
return 'Sets the tenant settings report';
}

constructor() {
super();

this.#initTelemetry();
this.#initOptions();
this.#initTypes();
}

#initTelemetry(): void {
this.telemetry.push((args: CommandArgs) => {
// Add unknown options to telemetry
const unknownOptions = Object.keys(this.getUnknownOptions(args.options));
const unknownOptionsObj = unknownOptions.reduce((obj, key) => ({ ...obj, [key]: true }), {});

Object.assign(this.telemetryProperties, {
hideUserInformation: typeof args.options.hideUserInformation !== 'undefined',
...unknownOptionsObj
});
});
}

#initOptions(): void {
this.options.unshift(
{
option: '-h, --hideUserInformation <hideUserInformation>',
autocomplete: ['true', 'false']
}
);
}


#initTypes(): void {
this.types.boolean.push('hideUserInformation');
}

public async commandAction(logger: Logger, args: CommandArgs): Promise<void> {
try {
if (this.verbose) {
await logger.logToStderr(`Updating report settings '${args.options.hideUserInformation}'...`);
}
const requestOptions: CliRequestOptions = {
url: `${this.resource}/v1.0/admin/reportSettings`,
headers: {
accept: 'application/json;odata.metadata=none',
'content-type': 'application/json'
},
responseType: 'json',
// displayConcealedNames If set to true, all reports conceal user information such as usernames, groups, and sites. If false, all reports show identifiable information
data: {
'displayConcealedNames': args.options.hideUserInformation
}
};
await request.patch(requestOptions);
}
catch (err) {
this.handleRejectedODataJsonPromise(err);
}
}
}

export default new TenantReportSettingsSetCommand();