SharePoint の権限を CSOM のオブジェクト視点で見る

SharePoint のコンテンツは大別すると、サイト、リスト、アイテムの３種類に分けられます。
そして、それらのコンテンツには、ユーザー、または、グループ毎に権限が割り当てられています。

本投稿では、サイトの権限を例に挙げて、SharePoint の権限と CSOM のオブジェクトを紐づけて、CSOM のオブジェクトへの理解を深めることを目的とします。

# 環境
* .NET Framework 4.6.1
* Microsoft.SharePointOnline.CSOM 16.1.19515.12000
* SharePointPnPCoreOnline 3.16.1912

# サンプルコード
* [SecurableObjectSample.cs](https://github.com/shibatea/sp-csom-library-sample/blob/master/Csom.Library.Sample/SecurableObjectSample.cs)
* [WebSample.cs](https://github.com/shibatea/sp-csom-library-sample/blob/master/Csom.Library.Sample/WebSample.cs)

# サイトの権限
[サイトのコンテンツ] > [サイトの設定] > [サイトの権限] を開くと、以下のような画面が表示されます。サイトの権限画面に表示される内容を CSOM のオブジェクトに置き換えると以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89309/03193ed2-3039-2366-8e15-14b7ee890491.png)

* RoleAssignmentCollection … サイトの権限を割り当てられたユーザー（グループ）の一覧
* RoleAssignment … サイトの権限を割り当てられたユーザー（グループ）の単位
* Principal … ユーザー（グループ）のこと
* RoleDefinitionBindingCollection … ユーザー（グループ）に割り当てられたアクセス許可レベルの一覧
* RoleDefinition … アクセス許可レベルの単位

# アクセス許可レベル
サイトの権限画面の [権限] タブから [アクセス許可レベル] をクリックすると、以下のような画面が表示されます。アクセス許可レベル画面に表示される内容を CSOM のオブジェクトに置き換えると以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89309/b5da8987-35f7-b54b-1e75-af15c0d6f976.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89309/18635610-63ea-8362-0ece-06411a0cb49e.png)

* RoleDefinitionCollection … アクセス許可レベル一覧
* RoleDefinition … アクセス許可レベルの単位
* RoleType … アクセス許可レベルの種別（既定のアクセス許可レベル以外は None）
* BasePermissions … アクセス許可レベルに含まれる権限一覧（PermissionKind の論理OR演算結果）
* PermissionKind … アクセス許可レベルに含める権限の単位

# CSOM でサイトの権限を出力
SharePoint コンテンツに割り当てられた権限情報を出力するサンプルコードです。
SecurableObject クラスを継承するサイト（Web）、リスト（List）、アイテム（ListItem）クラスで流用することができます。

```csharp
securableObject.EnsureProperties(
    // オブジェクトの権限を読み込む
    w => w.RoleAssignments.Include(
        r => r.Member.Title,
        r => r.Member.PrincipalType,
        // 対象オブジェクトの権限を与えられたユーザー or SPグループのアクセス許可レベルを読み込む
        r => r.RoleDefinitionBindings.Include(
            d => d.BasePermissions,
            d => d.Name,
            d => d.RoleTypeKind)));

// 対象オブジェクトの権限を出力
foreach (var roleAssignment in securableObject.RoleAssignments)
{
    foreach (var roleDefinition in roleAssignment.RoleDefinitionBindings)
    {
        Console.WriteLine($"{roleAssignment.Member.Title} " +
                          $"| {roleAssignment.Member.PrincipalType} " +
                          $"| {roleDefinition.RoleTypeKind} " +
                          $"| {roleDefinition.BasePermissions.GetHashCode()} " +
                          $"| {roleDefinition.Name}");
    }
}

// 出力結果
// ContosoCommunication 所有者 | SharePointGroup | Administrator | 2147483646 | フル コントロール
// ContosoCommunication 所有者 | SharePointGroup | WebDesigner | 1012866479 | デザイン
// ContosoCommunication 閲覧者 | SharePointGroup | Reader | 138613009 | 閲覧
// ContosoCommunication メンバー | SharePointGroup | Editor | 1011031199 | 編集
// user 100 | User | None | 1011029151 | 投稿コピー
```

# CSOM でサイトのアクセス許可レベルを出力
サイトのアクセス許可レベルを出力するサンプルコードです。
アクセス許可レベルはトップサイトで定義されています。参照するだけであれば何れかのサイト（Web）クラスのオブジェクトから取得できます。

```csharp
web.EnsureProperties(
    // サイトのアクセス許可レベルを読み込む
    w => w.RoleDefinitions.Include(
        r => r.RoleTypeKind,
        r => r.BasePermissions,
        r => r.Name,
        r => r.Description));

// サイトのアクセス許可レベルを出力
foreach (var roleDefinition in web.RoleDefinitions)
{
    Console.WriteLine($"{roleDefinition.RoleTypeKind} " +
                      $"| {roleDefinition.BasePermissions.GetHashCode()} " +
                      $"| {roleDefinition.Name} |" +
                      $"| {roleDefinition.Description}");
}

// 出力結果
// Administrator | 2147483646 | フル コントロール || 完全な制御が可能です。
// WebDesigner | 1012866479 | デザイン || 表示、追加、更新、削除、承認、カスタマイズができます。
// Editor | 1011031199 | 編集 || リストを追加、編集、削除できます。リスト アイテムとドキュメントを表示、追加、更新、削除できます。
// Contributor | 1011029151 | 投稿 || リスト アイテムとドキュメントを表示、追加、更新、および削除できます。
// Reader | 138613009 | 閲覧 || ページとリスト アイテム の表示、およびドキュメントのダウンロードができます。
// Guest | 134287408 | 制限付きアクセス || 権限を与えられている場合は、特定のリスト、ドキュメント ライブラリ、リスト アイテム、フォルダー、またはドキュメントを表示できます。
// None | 1011029151 | 投稿コピー ||
```

# 参照
[SharePoint の権限レベルについて | Microsoft Docs](https://docs.microsoft.com/ja-jp/sharepoint/understanding-permission-levels)