サイトゲストユーザと標準オブジェクトの作成権限についての検証を行いました。Spring'20でサイトゲストユーザの権限周りの仕様変更がありました。サポートに困りますと問い合わせしたりして、「この変更は絶対です。更新権限は付与できなくなります」と回答を確認したりしたあとに、さすがに無理か..とUPDATE権限については諦めることにしました。
(ちなみにSummer'20までは従来の権限仕様を引き続き適用できます。)
このときに考えたのはUPDATEはできなくなるのでINSERT処理のみで対処しようということです。というのも同じく仕様変更であった「ゲストユーザによって作成されたレコードのデフォルトの所有者への割り当て」という設定を見て作成権限は引き続き使えるんだなと判断したためです。
・・で、Summer'20に向けてゲストユーザに対しての非公開設定などの必要な設定を有効化してINSERT処理を実行した結果はこちらです。
DmlExcetpion = insufficient access rights on cross-reference id
ということで権限設定をしっかり調整しないとINSERT処理もできない状態でした。あっちを試してこっちを試してだと検証が大変なのでまず権限付与が一切無い状態を用意して検証することにしました。
権限付与なしの状態を作成
共有設定
取引先 / 取引先責任者 / 商談の権限を非公開寄りに設定しました。
ゲストユーザのレコードアクセス権を保護も有効化。
共有ルールも未設定の状態です。
サイト設定
「ゲストユーザによって作成されたレコードのデフォルトの所有者への割り当て」の機能もONにします。(設定ページではなぜか英語。割り当て先はシステム管理者ユーザをセット)
サイトゲストユーザのプロファイル設定
オブジェクトは参照権限から除外した状態にします。
項目レベルセキュリティ
必須項目以外の権限を除外した状態で確認します。
検証方法
ボタンクリック時に取引先の取引先名と都道県のみセットしてINSERTするシンプルな処理を実行して確認します。
検証結果
この状態の結果は最初に貼ったキャプチャの通りです。『insufficient access rights on cross-reference id』エラーが発生します。ここから検証を行っていきたいと思います。
オブジェクトの参照権限と作成権限を付与
サイトゲストユーザのプロファイル設定で取引先の作成権限を付与します。
項目レベルセキュリティもセット。
実行結果はこちら。権限エラーとなります。キャッシュとかあるかもしれないのでブラウザを変えてシークレットウィンドウで試しましたが解決せず。
どうやらオブジェクトの作成権限ではダメなようです。これはおそらく作成後の所有者がデフォルトで管理者ユーザになるためと思います。
共有ルールを付与
デフォルトセットされる所有者のアクセス権限があれば作成できると思ったため、共有ルールでユーザのアクセス権限を付与しました。警告メッセージが英語ですが、このDE組織の設定の問題と思います。(他の組織だとちゃんと日本語表示されてました。)
共有ルールが適用されるのを確認してから検証します。
実行結果はこちら。
所有者がシステム管理者で作成者がゲストユーザの取引先データが無事に登録できました。
全然関係ありませんが検証用にと取引先名にセットしたシステム日時が日本時間じゃないのがちょっと気になりました。ゲストユーザのページに行くとタイムゾーンがグリニッジ標準時になっていたのでそれが原因です。ゲストユーザ利用時には必要な場合は変更しておくと良さそうです。
タイムゾーンを直すとちゃんと日本時間で処理してくれます。
ひとまずこれでゲストユーザでもINSERT処理を実行できることを確認できました。つづいて他のオブジェクトも検証します。
・・・とその前に一点気になった箇所があるのでそちらを検証しました。オブジェクトの作成権限は必要あったのか?という点です。
オブジェクトの作成権限を除外
こんな感じで権限をOFF。
実行結果はこちら。
普通に作成できました。
本題では無いのでサラッと記載しますがApexの処理はシステム権限で実行されるためオブジェクトの権限はスルーされます。必要な場合は項目のアクセス権限などをチェックしてエラーにする判定処理を実装する必要があります。
ということでINSERT処理に必要なのはユーザのアクセス権限であることを確認できました。
取引先に紐付く取引先責任者の作成
続いて取引先に紐付く取引先責任者の作成です。確認したいのは親オブジェクトに紐付く子オブジェクトのデータ登録。
実行結果です。
001は取引先IDだったので、取引先のアクセス権限が無いとのことかと思います。取引先責任者の共有ルールは親レコードに紐付くなので取引先へのアクセス権限があれば問題ないはず。
取引先レコードのINSERTの検証で参照権限さえあれば問題ないことを確認しましたので、同様に取引先に共有ルールを付与します。条件は作成者IDです。所有者は内部ユーザにデフォルトセットされますが、作成者は変わりません。あまり好ましくないですが、IDの文字列を直接セットして対応しました。
実行結果です。・・・アクセス権限エラー解決せず。
この場合はオブジェクトの権限設定が必要なのかもしれない。追加してみました。
・・・エラー。
取引先の共有がうまく行っていないのかも。すべての取引先が条件に一致するように変更します。
エラー解決せず。。
が一つ原因を思いつきました。プロセスビルダーの処理です。
DE組織だったので検証用のやつが有効化となってました。処理内容を見るとChatter投稿というゲストユーザじゃ実行できないやつ。取引先INSERTでは動かなかったけど取引先責任者のINSERT処理ではなぜか動いたのかも・・・。
と思い無効にした後に再度試してみました。
・・・・プロセスビルダー関係無し。。というかプロセスビルダーとかでエラーになるとすればトリガとかワークフローを今後追加していったらクラッシュするんじゃないかと思います。
※追記:取引先責任者責任者のINSERTはwithout sharingの宣言で正常に実行できました。権限を親レコードを引き継ぐだとうまくいくようです。ただ商談はやはりうまくいきませんでした。同じく抜け穴があるかもしれませんが、しんどいだけなので調査はこれで終了。
結論
サイトゲストユーザでは取引先責任者の登録ができない...ように見えます...。仮にできたとしてもトリガなどの追加時に影響反映が大きそうです。フォーム入力で取引先/取引先責任者/商談と必要なデータが一発でできるのは業務上すごく便利だったのですが、仕様変更後はそこも諦める必要がありそうに思いました。
アイデアとしてはカスタムオブジェクト(一レコードに収まる形)でデータ登録を行い、スケジュールバッチで取引先/取引先責任者/商談に変換するような処理を行うのが現実的な気がしました。ただスケジュールバッチを最短で動かしたとしても5分に一回ぐらいの実行となると思うのでリアルタイムでの作成ができません。すごく不便になるためできればこの手段は取りたくないと思いました。・・・ですが今回検証して権限設定でも解決できなそうなので、リアルタイム性を捨ててバッチ処理によるデータ変換が必要になるのかなと思います。
要望
この仕様変更やめてほしいです。
・・・はさすがに無理ですが正直代替案は欲しかった。UPDATE処理は諦めましたがINSERT処理はできてほしかったです。(トリガとかの影響は受けない形で実現してほしい)
それか非同期処理で良いのでゲストユーザ作成後に、内部ユーザの権限で処理を実行できるようにしてくれればなんとかなったんじゃないかと思います。(無茶振りですが..)
仕様変更に伴うサイトゲストユーザと標準オブジェクトの作成権限についての検証はこんな感じでした。