最新のアプリケーション開発では、データアクセスの保護ときめ細かな管理が不可欠です。4Dのrestrictイベントのおかげで、ユーザのプロファイル、権限、セッション保存情報に基づいて、アクセス可能なデータを動的にフィルタリングすることが可能です。
このブログでは、特に4D Qodly Proとの統合において、このイベントを活用し、関連するデータのみが公開されるようにする方法を説明します。
Performance Review Application
restrict イベントを理解する
restrictイベントは、ORDAのデータクラスのエンティティに適用される自動フィルタリングメカニズムです。特定のコンテキスト(ユーザー情報、権限など)に基づいて、クエリー結果(all()、query()、API RESTアクセスなど)を制限するためにトリガーされます。
主な利点
- 動的フィルタリング:クエリが実行されるたびに、restrictで定義されたフィルターが自動的に適用されます。
- きめ細かなアクセス制御:アクセスを完全に制限することも、ユーザーの役割、権限、または地理的な場所や部署などのコンテキストデータに基づいて特定のレコードに制限することもできます。
- ロジックの分離:このフィルタリングの実装は、アプリケーションのビジネスロジックから独立しているため、メンテナンスやセキュリティアップデートが容易です。
詳細については、4D公式ドキュメントのエンティティフィルタリングに、この機能の包括的な概要が記載されています。
特権と制限:主な違い
4Dでは、アクセスコントロールは特権と 制限によって管理され、これらは安全できめ細かなデータアクセスを保証するために連携します。この2つのメカニズムの違いを理解することは、強固なセキュリティモデルを設計する上で非常に重要です。
特権:データ構造へのアクセスの制御
特権は、ユーザーがデータベース内のテーブル、フィールド、または関数にアクセスする権限があるかどうかを決定します。これは、データセットや機能全体へのアクセスを許可または拒否する、高レベルのアクセス制御メカニズムとして機能します。
使用例
- 基本ユーザは Employee テーブルへの読み取り専用アクセス権を持つが、レコードの編集や削除はできない。
- 管理者は、所属部署内の従業員レコードを変更できる追加権限を持つことができます。
- 人事管理者は、給与情報などの機密フィールドへのアクセス権が付与されますが、一般社員はそれらの詳細を見ることができません。
制限事項レコードレベルでのアクセス制限
特権が構造的なレベルでのアクセスを制御するのに対して、制限はユーザが認可されたテーブル内のどの特定のレコードを閲覧または操作できるかを決定します。on restrict イベントは、ユーザのコンテキストに基づいて動的にデータをフィルタリングし、ユーザが事前に定義されたセキュリティルールを尊重しながら、関連するレコードにのみアクセスできるようにします。
使用例
- 共同作業者は Employee テーブルの自分のレコードのみにアクセスできます。
- 管理者は、直属の部下のレコードを表示できます。
- 人事管理者は、すべての従業員を見ることができます。
使用例
例 1: 権限とセッションコンテキストを組み合わせてデータを制限する
この例では、Employeeデータクラス内でrestrictイベントを実装して、返される従業員リストをフィルタします。次のコードは、セッション情報と権限を使用してデータ・アクセスを決定する方法を示しています:
Function event restrict() : cs.EmployeeSelection
var $obj : Object
If (Session=Null)
$obj:=Storage
Else
$obj:=Session.storage
End if
Case of
: (Session.hasPrivilege("authentify"))
return This.all()
: (Session.hasPrivilege("generatePDF"))
return This.all()
: (Session.hasPrivilege("createReview"))
return This.all()
: (Session.hasPrivilege("webadmin"))
return This.all()
: ($obj.Employee.role="Collaborator")
return This.query("ID = :1"; $obj.Employee.ID)
: ($obj.Employee.role="Manager")
return This.query("ID_Supervisor = :1"; $obj.Employee.ID)
: (($obj.Employee.role="HR") && (Session.hasPrivilege("hr")))
return This.all()
Else
return This.newSelection()
End case
仕組み
- 特権ベースのフィルタリング:特権に基づくフィルタリング hasPrivilege() 関数は、ユーザーのセッションに特定の特権が含まれているかどうかを検証します。例えば、”hr “権限を持つ人事部社員は、すべての社員記録にアクセスできる。
- 一時的な役割の昇格:認証、ドキュメント生成、レビュー作成などのアクションに対して、特権昇格を行うことで、ユーザーのグローバル設定を変更することなく、一時的に拡張された権限を付与することができます。
- セッションベースのフィルタリング:ロールプロパティ(ストレージまたはセッションストレージに保存)によってアクセスレベルが決定されます。共同作業者は自分のレコードのみ、管理者は部下の従業員、人事担当者は全従業員を閲覧できます。
- セキュアデフォルトリターン:条件が満たされない場合、This.newSelection() は、ユーザーが無制限のアクセスではなく、データを受け取らないことを保証します。
注: webadmin権限は、4D の Data Explorer で使用されます。データエクスプローラからデータにアクセスしたい場合は、webadmin権限のケースを処理する必要があります。この例では、この特権がある場合にThis.all() を返すことで、データエクスプローラへのフルアクセスを許可しています。
例 2: 標準アクションまたは関数を使用した Qodly Studio での統合
この2番目の例では、ユーザのロールに基づいてReviewデータクラスのレビューへのアクセスを制限する方法を示します。
Function event restrict() : cs.ReviewSelection
var $obj : Object
If (Session=Null)
$obj:=Storage
Else
$obj:=Session.storage
End if
If ($obj.Employee.role=Null)
return Null
End if
Case of
: (($obj.Employee.role="HR") && (Session.hasPrivilege("hr")))
return This.all().orderBy("Date desc")
: ($obj.Employee.role="Manager")
return This.query("Employee.ID_Supervisor = :1"; $obj.Employee.ID).orderBy("Date desc")
: ($obj.Employee.role="Collaborator")
return This.query("ID_Employee = :1"; $obj.Employee.ID).orderBy("Date desc")
: (Session.hasPrivilege("webadmin"))
return This.all()
Else
return This.newSelection()
End case
標準的なアクションの使用
Qodlyアプリケーションのコラボレーターページでは、ユーザーはコラボレーターのロールを持ち、自分のレビューだけを参照することができます。
Qodly Studioでは、コラボレーターページのロードイベントでデータテーブルを埋める標準アクションAllを定義します。通常、標準アクションAllはすべてのレビューを取得します。しかし、レビューのデータクラスにrestrictイベントを追加しました。コラボレータのロールで認可されたレビューのみを取得します。
カスタム関数の使用
Managerページでは、”Manager “ロールを持つユーザは部下に関連するすべてのレビューを見ることができます。年や ステータスで結果を絞り込むための高度なフィルタリング機能を追加します。
Reviewデータクラスには、loadReviews関数があります:
exposed Function loadReviews($departement : cs.DepartementEntity; $year : Integer; $status : cs.ReviewStatusEntity) : cs.ReviewSelection
Case of
: (($departement=Null) && ($status=Null))
return This.query("Date >= :1 AND Date <= :2"; String($year)+"/01/01"; String($year)+"/12/31")
: (($departement#Null) && ($status=Null))
return This.query("Employee.ID_Departement = :1 AND Date >= :2 AND Date <= :3"; $departement.ID; String($year)+"/01/01"; String($year)+"/12/31")
: (($departement=Null) && ($status#Null))
return This.query("ID_Status = :1 AND Date >= :2 AND Date <= :3"; $status.ID; String($year)+"/01/01"; String($year)+"/12/31")
: (($departement#Null) && ($status#Null))
return This.query("Employee.ID_Departement = :1 AND ID_Status = :2 AND Date >= :3 AND Date <= :4"; $departement.ID; $status.ID; String($year)+"/01/01"; String($year)+"/12/31")
Else
return This.newSelection()
End case
Qodly Studioでは、この関数は年およびステータス・データ・ソースのデータ変更イベントでトリガーされます。
年入力の場合
ステータスのセレクトボックス
カスタマイズされたフィルターは、on restrictによって提供されるグローバル制限と組み合わされ、事前に定義されたセキュリティルールを尊重しながら結果を絞り込むことができます。
次へ
4Dのrestrictイベントは、データアクセスを動的に管理するための強力なツールです。ユーザー権限とセッションストレージを活用することで、ビジネスロジックを複雑にすることなく、きめ細かいアクセス制御を保証します。さらに、プロモートのような補完的なメカニズムとの統合やカスタムフィルタの追加により、特定の要件を満たすための柔軟性が向上します。
このトピックの理解を深めるには、ORDAエンティティの公式ドキュメントや、データフィルタリングに特化した4Dブログを参照してください。