4D 19 R8 では、堅牢な権限システムを導入し、データへのユーザーアクセスをきめ細かく制御できるようになりました。このシステムは、誰がアクセスするか、どのデータにアクセスするかによってデータを保護し、不正アクセスを制限してデータのセキュリティを確保します。
しかし、特定の条件に基づいて読み取りアクセスをさらに制限したいとしたらどうでしょうか。
そこで 4D 20 R5 の出番です。特定の基準に従って読み取りデータを制限できるようになりました。
実用的な使用例
パーミッションシステムを使うことで、適切な権限を持つ一部のユーザーに Customers データクラスへの読み取りアクセス権を与えることができます。これは有用ではありますが、この場合、Customersデータクラスの読み取りが許可されると、そのユーザーはすべての顧客を読み取ることができます。
たとえば、営業担当者が顧客との取引に使用するアプリケーションを想定してみましょう。機密性を保護するために、認証された営業担当者が管理する顧客のみに読み取りを制限する必要があるかもしれません。
もちろん、カスタム実装でこれを実現することもできますが、データを読み込む場所でその都度コード内で制限を適用しなければならず、煩雑で保守しにくいコードになりかねません。
そんな煩雑な作業は忘れて、制限の基準を一か所に一度だけ書く、それが一番楽ですね!
制限を実装する方法
タイトルからも明らかなように、このフィルターは ORDAで読み込まれたデータにのみ適用され、クラシック 4D によるクエリは対象外です。
該当する DataClassクラスにおいて、event キーワードを使って restrict() 関数を実装する必要があります。この関数は、関連するデータクラスのエンティティセレクションを返す必要があります。
実装では、エンティティセレクションを作成します。このエンティティセレクションは、query() や all() のような関数を使用してこのデータクラスからデータを読み取るときに、制限フィルターとして適用されます。詳細についてはドキュメントを参照して、フィルターが適用される関数を確認してください。
以下は、営業担当者が顧客と取引するために使用するアプリケーションの例です。読み込まれる顧客を、アプリケーションを使う営業担当者が管理する顧客に限定します。
このアプリケーションは 2つのコンテキストで使われます:
- Webサーバー
- クライアントサーバー
まず、データモデルは下図のとおりです:
Customers DataClass クラスです:
Class extends DataClass
Function event restrict() : cs.CustomersSelection
// セッションが存在する場合
If (Session#Null)
Case of
: (Session.storage.salesInfo#Null)
// 認証された営業担当者の客先のみが返されます
return This.query("sales.internalId = :1"; Session.storage.salesInfo.internalId)
// データエクスプローラーの場合
: (Session.hasPrivilege("WebAdmin"))
// フィルターは適用されません
return Null
Else
// 客先情報は取得できません
return This.newSelection()
End case
Else
// 客先情報は取得できません
return This.newSelection()
End if
Sessionオブジェクトは、Webコンテキストだけでなく、C/S コンテキストでも利用可能です (この新機能の詳細はこちら)。
- 営業担当者は識別子とパスワードで自分自身を認証します。認証された営業担当者の内部ID は Session に格納されます。restrict() 関数内では、この認証された営業担当者が管理する顧客のみのエンティティセレクションを返します。
- データエクスプローラーもこのフィルターをトリガーします (WebAdmin 権限を持つWebセッションを使用するため)。上のサンプルコードでは、Null を返すことで、データエクスプローラに全顧客へのアクセスを許可しています。
- その他のケースでは、セキュリティ上の理由から、顧客情報を取得できないように空の Customers エンティティセレクションを返します。
実際の動作
Webコンテキストでは、認証された営業担当者の internalId が Session に格納されています。/rest/Customers というリクエストが Webページで実行されると、この営業担当者の顧客だけが取得されます:
クライアントサーバーコンテキストでは、C/S でも利用可能になった Session オブジェクトのおかげで、認証された営業担当者がやはりセッションに格納されます。
全顧客データを取得する (Get all customers) ボタンをクリックすると、Customers.all() 関数が呼び出され、同じフィルターが適用されます。
HDI をダウンロードして、この強力な機能をさらにご確認ください!