UserRecordAccessオブジェクトでユーザのレコードアクセス権を判定する

今回はUserRecordAccess オブジェクトについてご紹介します。

はじめに

Apexで 「あるユーザが特定のレコードに対して参照権限があるか判定する」 という処理を実装することになった場合、どのようなロジックを考えますか?

まず、レコードの参照が可能となるパターンを把握する必要があります。システム管理者、レコードの所有者、共有先のユーザおよびグループのメンバー等々... すべてのパターンは Salesforce のヘルプトピック 「レコードへのアクセス権があるユーザの表示」 にまとめられていますが、パターン数が非常に多く、すべてを網羅したロジックを実装することは非常に困難です。 このようなケースで役に立つのが UserRecordAccess オブジェクトです。

UserRecordAccess オブジェクトとは

UserRecordAccess オブジェクトは、ユーザの一連のレコードに対するアクセス権を表すオブジェクトです。 以下の項目で構成されています。

UserId
ユーザのID
RecordId
レコードのID
HasReadAccess
ユーザのレコードに対する参照権限の有無 [true | false]
HasEditAccess
ユーザのレコードに対する編集権限の有無 [true | false]
HasDeleteAccess
ユーザのレコードに対する削除権限の有無 [true | false]
HasTransferAccess
ユーザのレコードに対する所有権を移行する権限の有無 [true | false]
HasAllAccess
ユーザのレコードに対するすべてのアクセス権 (参照、編集、削除およひ?所有権の移行) の有無 [true | false]
MaxAccessLevel
ユーザのレコードに対する最大レベルのアクセス権
[None | Read | Edit | Delete | Transfer | All]

以下のように、SOQLを使用してユーザのレコードに対するアクセス権を取得することができます。

UserRecordAccess オブジェクトの制限事項

UserRecordAccess オブジェクトへのクエリを実行するには、以下の条件を満たす必要があります。

1. 取得フィールドにレコードIDを含めること

前述のサンプルコードのように、SELECT ? FROM の間に必ず RecordId を含める必要があります。 また、取得フィールドが RecordId のみの場合は、WHERE 句に Has*Access = trueを指定する必要があります。

2. WHERE句でユーザID (UserId) の指定が必須、かつ 単一のユーザIDのみ指定可能

IN句を用いて複数のユーザIDを指定することができません。よって、1回のSOQLで取得できるのは1ユーザ分の情報のみです。

3. WHERE句でレコードID (RecordId) の指定が必須

単一のレコードID、もしくはIN句を用いての複数レコードIDの指定が必須です。 ※Summer'14 環境では RecordId の条件に Set 配列を指定するとレコード取得結果が0件になる不具合がありますが、Winter'15 で修正されます。なお List 配列を指定すれば問題ありません。

4. 取得可能はレコード数は1度に200件まで

レコード取得結果が200件を超えると QueryException が発生します。 そのため、あらかじめ200件を超えないように抽出条件を調整する必要があります。

おわりに

本記事の冒頭に挙げた課題で、複雑なロジックを組まなければいけないと思われた方は少なからずいらっしゃるのではないでしょうか。 (私もその一人です) Salesforce はバージョンアップを重ね、機能とともにオブジェクトの数もだいぶ増えましたが、便利なオブジェクトの1つとして覚えておくと良いでしょう。 [参考] UserRecordAccess - SOAP API Developer's Guide