Skip to content
Open
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
71 changes: 71 additions & 0 deletions docs/docs/cmd/spo/file/file-roleassignment-list.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import Global from '../../_global.mdx';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# spo file roleassignment list

Lists all role assignments from a specific file

## Usage

```sh
m365 spo file roleassignment list [options]
```

## Options

```md definition-list
`-u, --webUrl <webUrl>`
: URL of the site where the file is located.

`--fileUrl [fileUrl]`
: The server- or site-relative decoded URL of the file. Specify either `fileUrl` or `fileId` but not both.

`-i, --fileId [fileId]`
: The UniqueId (GUID) of the file. Specify either `fileUrl` or `fileId` but not both.
Comment on lines +21 to +25
```

<Global />

## Examples

List all role assignments of a file specified by URL.

```sh
m365 spo file roleassignment list --webUrl "https://contoso.sharepoint.com/sites/Marketing" --fileUrl "/Branding/Logos/Contoso.jpg"
```

List all role assignments of a file specified by ID.

```sh
m365 spo file roleassignment list --webUrl "https://contoso.sharepoint.com/sites/Marketing" --fileId "04796e10-cb5f-4aa3-a438-bc06028a9073"
```

## Response

<Tabs>
<TabItem value="JSON">

```json
```

</TabItem>
<TabItem value="Text">

```text
```

</TabItem>
<TabItem value="CSV">

```csv
```

</TabItem>
<TabItem value="Markdown">

```md
```

</TabItem>
</Tabs>
5 changes: 5 additions & 0 deletions docs/src/config/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2771,6 +2771,11 @@ const sidebars: SidebarsConfig = {
label: 'file roleassignment add',
id: 'cmd/spo/file/file-roleassignment-add'
},
{
type: 'doc',
label: 'file roleassignment list',
id: 'cmd/spo/file/file-roleassignment-list'
},
{
type: 'doc',
label: 'file roleassignment remove',
Expand Down
1 change: 1 addition & 0 deletions src/m365/spo/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export default {
FILE_RETENTIONLABEL_ENSURE: `${prefix} file retentionlabel ensure`,
FILE_RETENTIONLABEL_REMOVE: `${prefix} file retentionlabel remove`,
FILE_ROLEASSIGNMENT_ADD: `${prefix} file roleassignment add`,
FILE_ROLEASSIGNMENT_LIST: `${prefix} file roleassignment list`,
FILE_ROLEASSIGNMENT_REMOVE: `${prefix} file roleassignment remove`,
FILE_ROLEINHERITANCE_BREAK: `${prefix} file roleinheritance break`,
FILE_ROLEINHERITANCE_RESET: `${prefix} file roleinheritance reset`,
Expand Down
115 changes: 77 additions & 38 deletions src/m365/spo/commands/file/file-get.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,81 @@ import { sinonUtil } from '../../../../utils/sinonUtil.js';
import commands from '../../commands.js';
import command from './file-get.js';
import { settingsNames } from '../../../../settingsNames.js';
import { spo } from '../../../../utils/spo.js';

describe(commands.FILE_GET, () => {
const fileRoleAssignmentsResponse = {
value: [{
"Member": {
"Id": 3,
"IsHiddenInUI": false,
"LoginName": "Communication site Owners",
"Title": "Communication site Owners",
"PrincipalType": 8,
"AllowMembersEditMembership": false,
"AllowRequestToJoinLeave": false,
"AutoAcceptRequestToJoinLeave": false,
"Description": null,
"OnlyAllowMembersViewMembership": false,
"OwnerTitle": "Communication site Owners",
"RequestToJoinLeaveEmailSetting": ""
},
"RoleDefinitionBindings": [
{
"BasePermissions": {
"High": "2147483647",
"Low": "4294967295"
},
"Description": "Has full control.",
"Hidden": false,
"Id": 1073741829,
"Name": "Full Control",
"Order": 1,
"RoleTypeKind": 5,
"BasePermissionsValue": [
"ViewListItems",
"AddListItems",
"EditListItems",
"DeleteListItems",
"ApproveItems",
"OpenItems",
"ViewVersions",
"DeleteVersions",
"CancelCheckout",
"ManagePersonalViews",
"ManageLists",
"ViewFormPages",
"AnonymousSearchAccessList",
"Open",
"ViewPages",
"AddAndCustomizePages",
"ApplyThemeAndBorder",
"ApplyStyleSheets",
"ViewUsageData",
"CreateSSCSite",
"ManageSubwebs",
"CreateGroups",
"ManagePermissions",
"BrowseDirectories",
"BrowseUserInfo",
"AddDelPrivateWebParts",
"UpdatePersonalWebParts",
"ManageWeb",
"AnonymousSearchAccessWebLists",
"UseClientIntegration",
"UseRemoteAPIs",
"ManageAlerts",
"CreateAlerts",
"EditMyUserInfo",
"EnumeratePermissions"
],
"RoleTypeKindValue": "Administrator"
}
],
"PrincipalId": 3
}]
};

let log: any[];
let logger: Logger;
let loggerLogSpy: sinon.SinonSpy;
Expand Down Expand Up @@ -51,6 +124,7 @@ describe(commands.FILE_GET, () => {
sinonUtil.restore([
request.get,
fs.createWriteStream,
spo.getFileRoleAssignments,
cli.getSettingWithDefaultValue
]);
});
Expand Down Expand Up @@ -275,8 +349,10 @@ describe(commands.FILE_GET, () => {
});

it('retrieves and prints all details of file as ListItem object with permissions', async () => {
sinon.stub(spo, 'getFileRoleAssignments').resolves(fileRoleAssignmentsResponse.value);

sinon.stub(request, 'get').callsFake(async (opts) => {
if ((opts.url as string).indexOf('?$expand=ListItemAllFields') > -1) {
if (opts.url === "https://contoso.sharepoint.com/sites/project-x/_api/web/GetFileById('b2307a39-e878-458b-bc90-03bc578531d6')?$expand=ListItemAllFields") {
return {
"ListItemAllFields": {
"FileSystemObjectType": 0,
Expand Down Expand Up @@ -320,43 +396,6 @@ describe(commands.FILE_GET, () => {
};
}

if (opts.url === `https://contoso.sharepoint.com/sites/project-x/_api/web/GetFileByServerRelativePath(DecodedUrl='/sites/project-x/Documents/Test1.docx')/ListItemAllFields/RoleAssignments?$expand=Member,RoleDefinitionBindings`) {
return {
value: [
{
"Member": {
"Id": 3,
"IsHiddenInUI": false,
"LoginName": "Communication site Owners",
"Title": "Communication site Owners",
"PrincipalType": 8,
"AllowMembersEditMembership": false,
"AllowRequestToJoinLeave": false,
"AutoAcceptRequestToJoinLeave": false,
"Description": null,
"OnlyAllowMembersViewMembership": false,
"OwnerTitle": "Communication site Owners",
"RequestToJoinLeaveEmailSetting": ""
},
"RoleDefinitionBindings": [
{
"BasePermissions": {
"High": "2147483647",
"Low": "4294967295"
},
"Description": "Has full control.",
"Hidden": false,
"Id": 1073741829,
"Name": "Full Control",
"Order": 1,
"RoleTypeKind": 5
}
],
"PrincipalId": 3
}]
};
}

throw 'Invalid request';
});

Expand Down
11 changes: 4 additions & 7 deletions src/m365/spo/commands/file/file-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { validation } from '../../../../utils/validation.js';
import SpoCommand from '../../../base/SpoCommand.js';
import commands from '../../commands.js';
import { FileProperties } from './FileProperties.js';
import { spo } from '../../../../utils/spo.js';

interface CommandArgs {
options: Options;
Expand Down Expand Up @@ -212,14 +213,10 @@ class SpoFileGetCommand extends SpoCommand {
const fileProperties: FileProperties = JSON.parse(JSON.stringify(file));

if (args.options.withPermissions) {
requestOptions.url = `${args.options.webUrl}/_api/web/GetFileByServerRelativePath(DecodedUrl='${file.ServerRelativeUrl}')/ListItemAllFields/RoleAssignments?$expand=Member,RoleDefinitionBindings`;
const response = await request.get<{ value: any[] }>(requestOptions);
response.value.forEach((r: any) => {
r.RoleDefinitionBindings = formatting.setFriendlyPermissions(r.RoleDefinitionBindings);
});
fileProperties.RoleAssignments = response.value;
const fileRoleAssignments = await spo.getFileRoleAssignments(args.options.webUrl, file.ServerRelativeUrl);
fileProperties.RoleAssignments = fileRoleAssignments;
if (args.options.asListItem) {
fileProperties.ListItemAllFields.RoleAssignments = response.value;
fileProperties.ListItemAllFields.RoleAssignments = fileRoleAssignments;
}
}

Expand Down
Loading
Loading