トランザクションセキュリティポリシーに Apex を使用する
学習の目的
この単元を完了すると、次のことができるようになります。
- Apex を使用するトランザクションセキュリティポリシーの作成方法を説明する。
- トランザクションセキュリティポリシーを実装する Apex クラスの基本要素について説明する。
一緒にトレイルを進みましょう
エキスパートの説明を見ながらこのステップを実行したい場合は、次の動画をご覧ください。これは「Trail Together」(一緒にトレイル) シリーズの一部です。
(この動画は 17:20 の時点から始まります。戻して手順の最初から見直す場合はご注意ください。)
Apex を使用するポリシーを作成する
条件ビルダーは強力ですが、ロジックの分岐、データの照会、照会されたデータの反復処理など複雑な使用事例はどれもサポートしていません。このような事例では Apex クラスを使用して、トランザクションセキュリティポリシーでトリガーする条件を定義します。
ここでは、ユーザーがレポートで一度に参照またはエクスポートできるレコード数を 10 件に制限するトランザクションセキュリティポリシーを作成したいと考えています。ただし、データスチュワードはこれ以上のデータをエクスポートしなければならないことがあるため、データスチュワードプロファイルが設定されているユーザーは除外する必要があります。条件ビルダーを使用してこのロジックを実装することはできないため、代わりに Apex クラスを使用する必要があります。
まず、ポリシー自体を作成します。
- トランザクションセキュリティポリシーのメインページに戻り、[新規] をクリックします。
-
[Apex] をクリックし、[Next (次へ)] をクリックします。
-
[イベント] 項目で、[レポートイベント] を選択します。
-
[Apex Class (Apex クラス)] 項目で、[New Empty Apex Class (新しい空の Apex クラス)] を選択します。
-
[次へ] をクリックします。
-
[アクション] 項目で、[ブロック] を選択します。
-
[通知] 項目で、[メール通知] を選択し、受信者となるユーザーを選択します。誰かが大量のレコードをダウンロードしようとするたびに、ここで選択したユーザーがメールを受信します。アプリケーション内通知を有効にすることもできます。
- ポリシーに「Prevent Large Data Export」(大量データのエクスポートの防止) という名前を付けます。
- まだポリシーを有効にしないでください。この操作は Apex クラスの編集を終えた後で行います。
-
[完了] をクリックします。
トランザクションセキュリティポリシーのホームページに戻ります。この単元の前半で、ポリシーに新しい空の Apex クラスを作成することをどのように指定したか覚えていますか? 自動生成されるクラス名は、ポリシー名から空白を除去して EventCondition を追加したもので、この場合は PreventLargeDataExportEventCondition になります。この新しいクラスが [Apex 条件] 列にリストされます。
この Apex クラスには必要なコードがないため、新しいポリシーはまだ機能を果たしません。次のセクションでこの点に対処します。
Apex クラスを編集する
では、使用事例を実装する Apex コードを追加しましょう。実際にコードを記述する必要はないため、心配しなくても大丈夫です。用意されているコードの重要な部分について説明します。
- [Transaction Security Policies (トランザクションセキュリティポリシー)] メインページで、[Apex Condition (Apex 条件)] 列の [PreventLargeDataExportEventCondition] をクリックします。[設定] ページが表示され、Apex クラスを編集できます。
- ここで、テンプレートクラスを編集して、機能を果たす Apex コードを追加します。
-
[編集] をクリックします。
- 既存のコードを次のコードに置き換えます。
global class PreventLargeDataExportEventCondition implements TxnSecurity.EventCondition { public boolean evaluate(SObject event) { switch on event{ when ReportEvent reportEvent { return evaluate(reportEvent); } when null { // Don't take policy action when event is null return false; } when else{ // Don't take policy action when event is not handled return false; } } } /** * Handle evaluating ReportEvent */ private boolean evaluate(ReportEvent reportEvent){ Profile profile = [SELECT Name FROM Profile WHERE Id IN (SELECT profileId FROM User WHERE Id = :reportEvent.UserId)]; // Take policy action only if the user profile is not 'Data Steward' and // RowsProcessed greater than 10. if (!profile.Name.contains('Data Steward') && reportEvent.RowsProcessed > 10) { return true; } return false; } }
-
[保存] をクリックします。
これで、最初の Apex ベースのトランザクションセキュリティポリシーを使えるようになりました。ここで、新しいコードの機能について説明します。
Apex コードを理解する
ここでは PreventLargeDataExportEventCondition クラスの Apex コードをわかりやすい言葉で説明します。Apex の経験は必要ありませんが、プログラミングに関する一般的な知識があると役立ちます。
まず、使用事例を思い出します。次の両方の条件に該当する場合に、ポリシーアクション (この場合はブロック) がトリガーされます。
- ユーザーにデータスチュワードプロファイルが設定されていない。
- レコードが 10 件を超えるレポートをユーザーが参照またはエクスポートする。
PreventLargeDataExportEventCondition はこの使用事例を実装します。では、クラスの基本構造 (メソッドや実装インターフェースなど) から見ていきましょう。
- PreventLargeDataExportEventCondition クラスは、Apex ベースのトランザクションセキュリティポリシーに必要な TxnSecurity.EventCondition Apex インターフェースを実装します。
- TxnSecurity.EventCondition インターフェースには、evaluate(SObject) というメソッドが必要です。このメソッドは SObject パラメーターを取り、Boolean 値 (true/false) を返します。返された Boolean によってポリシーがトリガーされるか (true) 否か (false) が決まります。
- evaluate(SObject) メソッドで、switch ステートメントが渡された SObject をイベントに変換します。switch ステートメントを使用するということは、この同じメソッドで複数のイベント種別を処理できるということです。この例では、SObject が ReportEvent に変換されます。
- 次に ReportEvent が evaluate(ReportEvent) というヘルパーメソッドに渡されます。条件のテストはすべてここで行われます。
evaluate(ReportEvent) ヘルパーメソッドでこの使用事例の特定の条件を実装するため、このメソッドの Apex コードをさらに詳しく見てみましょう。
最初に、このコードがプロファイルオブジェクトとユーザーオブジェクトに SOQL クエリを実行して、イベントをトリガーしたユーザーのプロファイルを取得します。
Profile profile = [SELECT Name FROM Profile WHERE Id IN (SELECT profileId FROM User WHERE Id = :reportEvent.UserId)];
プロファイルが取得したら、条件をテストできます。プロファイル名に「Data Steward」という文字列が含まれず、かつ、イベントで処理される行が 10 を超えている場合、つまり、レコードが 10 件を超えるレポートをユーザーが参照またはエクスポートする場合は、この Apex コードが true を返します。
if (!profile.Name.contains('Data Steward') && reportEvent.RowsProcessed > 10) { return true; }
evaluate(ReportEvent) の最後の行に、条件が両方とも満たされていない場合はメソッドが false を返すことが指定されています。
return false;
新しい Apex クラスが実際にいつ実行されるのかを説明する前に、トランザクションセキュリティのしくみについて復習しておきましょう。イベントが発生し、そのイベントがトランザクションセキュリティでサポートされている場合は、そのイベントにポリシーが存在するかどうかがチェックされます。一致した場合は、そのイベントがポリシーをトリガーする条件を満たすかどうかを確認するために、Apex コードと条件ビルダーロジックのいずれかが実行されます。条件を満たした場合は、トランザクションセキュリティがアクションを実行し、そのポリシーの通知を発行します。
ここでの例に戻ると、トランザクションセキュリティが ReportEvent を取得した場合のみ、PreventLargeDataExportEventCondition が実行されます。MyDataLoaderLeadExportCondition によってイベントがポリシー条件を満たしていることが示された場合にのみ、トランザクションセキュリティがポリシーをトリガーします。このチェックプロセス全体が 1 秒足らずで行われます。
次のステップ
今回は、組織のレポートの使用状況を追跡するポリシーを作成する練習をしたため、次は、リストビューの使用状況やログインなど、追跡可能な他のイベントについても試してみてください。トランザクションセキュリティはさまざまな形で活用できるため、いろいろなものを監視できます。
ハンズオン Challenge の準備
ハンズオン Challenge では、Apex を使用してトランザクションセキュリティポリシーを作成します。以下は、Challenge で使用するコードです。Challenge では、このコードをさらに数か所変更するよう指示されます。
global class BlockLargeDataExportEventCondition implements TxnSecurity.EventCondition { public boolean evaluate(SObject event) { switch on event{ when ReportEvent reportEvent { return evaluate(reportEvent); } when null { // Don't take policy action when event is null return false; } when else{ // Don't take policy action when event is not handled return false; } } } /** * Handle evaluating ReportEvent */ private boolean evaluate(ReportEvent reportEvent){ Profile profile = [SELECT Name FROM Profile WHERE Id IN (SELECT profileId FROM User WHERE Id = :reportEvent.UserId)]; // Take policy action only if the user profile is not 'Data Steward' and // RowsProcessed greater than 10. if (!profile.Name.contains('Data Steward') && reportEvent.RowsProcessed > 10) { return true; } return false; } }
リソース