Posted at
LIFULLDay 22

【Salesforce】SOQLでレコードに対する権限を一覧表示する

この記事はLIFULL Advent Calendar2018の22日目の記事です。

昨年LIFULLに転職し、Salesforceエンジニアとなりました。

そして初投稿・Qiitaデビューです。初投稿はSalesforceで何度も悩まされた権限管理について、SOQLを使って楽にしようというテーマで書いていきたいと思います。


共有オブジェクト

Salesforceには共有オブジェクトという権限を管理するオブジェクトがあります。

この共有オブジェクトはオブジェクトごとに1:1で存在し、標準オブジェクトには予め用意されていますが、カスタムオブジェクトを作成した場合は自動で作成されます。

管理画面上からはシステム管理者でさえも見えないシステムオブジェクトのため、結構存在や名前を忘れがちだったりします。共有オブジェクトの名前(API参照名)はこちら。

 ・標準オブジェクト:[ObjectName] + Share

  (例)Caseの場合:共有オブジェクトは「CaseShare」

 ・カスタムオブジェクト:[MyCustomObject] + __Share

  (例)Property__cの場合:共有オブジェクトは「Property__Share」'


共有オブジェクトが管理するアクセスレベル

オブジェクトによって項目名が異なりますが、Caseの場合は「CaseAccessLevel」という項目でアクセスレベルを保持しています。アクセスレベルは下記3つ。

  1. 【Read】参照のみ

  2. 【Edit】参照・編集可能

  3. 【All】参照・編集・移行・共有・削除可能


SOQLで権限を取得する

オブジェクトなのでSOQLで権限レコード取得することもできます。

例えば特定のケースレコードに対する編集権限を持つユーザやグループの一覧を取得したい場合。

SELECT CaseAccessLevel, RowCause, UserOrGroupId, UserOrGroup.Name FROM CaseShare WHERE CaseId = '{ケースID}' AND (CaseAccessLevel = 'All' OR CaseAccessLevel = 'Edit') LIMIT 100

特定のユーザもしくはグループが持つケースレコードの一覧を取得したい場合はこちら。

SELECT CaseAccessLevel, RowCause, CaseId, Case.RecordTypeId FROM CaseShare WHERE UserOrGroupId = '{ユーザもしくはグループID}' And Case.RecordTypeId = '{レコードタイプID}' LIMIT 1000


注意点

上記ように権限の一覧は簡単に取得ができますが「ユーザもしくはグループ」と何度も書いている通り、権限レコードはユーザ単位ではなく「ユーザもしくはグループ」単位で作成されます。そのためグループ内にどのユーザがいるのかは一覧上からは分かりません。

さらにやっかいなことに、グループはネストします。

例えば、キューが参照権限をもつレコードがあったとします。

このキューのメンバーが公開グループやロールの場合もよくあり、公開グループのメンバーにもロールを設定できるのでさらにネスト。メンバーがロール+ユーザなんてパターンもあります。


グループの階層構造

ただ、ロールにはユーザしか割り当てられないのでようやくここでネストが止まります。また公開グループにはキューは割り当てられません。

つまり、キュー>公開グループ>ロール>ユーザの最大4階層でしょうか。


グループメンバーを取得する

特定のユーザもしくはグループが持つケースレコードの一覧を取得したときに、グループ(SFID:00G)が取得された場合にグループメンバー一覧を表示するにはこちら。

グループオブジェクトの「Type」項目を取得することでそのグループがキュー、公開グループ、ロールなどなどが判別可能です。

SELECT UserOrGroupId, Group.Type FROM GroupMember WHERE GroupId = '{グループID}' LIMIT 1000

ちなみに、参照が張られていないのか共有オブジェクトと違って「UserOrGroup.Name」でユーザ氏名を取得することはできません。


最後に

上記SOQLを組み合わせたり応用することにより、特定のユーザが権限を持つレコードの一覧や、レコードの特定のレコードに対する権限を持つユーザ一覧の表示が可能です。

厳密にいうとロールがもたらす階層権限やオブジェクト自体に対する権限も組み合わせる必要がありますが、Salesforceの多様な設定により掌握困難な権限構造を可視化するには活用できるかもしれません。

今後はこの共有オブジェクトの仕組みをベースをにGUIの検索画面を作って簡単に権限一覧を表示したり、予期しない権限が付いていればアラートを出すツールなどを作って権限管理を楽にしていけたらと思います。

それではよいSalesforceライフを。