私の見方では、ACL は魔法のようなものではありません。例: ACL は、製品を追加/編集/削除するアクセス権を持つユーザーを通知するアクセス許可を管理できます..しかし、クエリを変更して、定義されたアクセス許可に従って製品をフィルタリングすることはできません (「部門 A のユーザーは、部門 A の製品を参照してください」..実際にはそれは嘘です。ACL はそれを管理できますが、製品を追加するたびに ACO を作成し、AROS_ACOS テーブルに権限を設定する必要があるため、実用的ではない可能性があります。また、AROS はツリー構造であるため、データのクエリを計画している場合、簡単に悪夢になる可能性があります。
グループのみの ACLを使用して、特定のページ/アクションへのアクセスを制御し、次のようなルールを作成します。
- 「部門長は、ページ「製品リスト」にアクセスして、製品を追加/削除/変更できます」
- 「管理者はすべてのページにアクセスできます」
- 「他のユーザーは「製品リスト」にアクセスでき、製品を追加できますが、削除することはできません」
接続しているユーザーに応じてクエリを調整するので、「製品リスト」ページのコントローラーで次のようにします。
- 接続されたユーザーが部門長に属している場合は、すべての製品を選択します。
product.department_id=connected_user.department_id
- 接続ユーザーが管理者の場合は、すべての製品を選択します
クエリが多すぎて、何千もの if 文を実行したくない場合は、コンポーネントや動作を作成するかfind()
、app_model
. アイデアは、すべてのクエリをキャッチし、クエリで使用されているモデルの 1 つに「department_id」というフィールドがあるかどうかを確認し、ある場合はmodel.department_id=connected_user.department_id
条件をクエリに追加することです。
複数の言語で表示できる 1 つの Web サイトに対してこれを行いました。各言語には独自のユーザー、データ、ログなどがあり、すべての情報を表示できる管理者が 1 人います。
幸運を!
編集済み:
私が使用する動作は次のとおりです。
<?php
class LocalizableBehavior extends ModelBehavior {
/**
* Filter query conditions with the correct `type' field condition.
*/
function beforeFind(&$model, $query)
{
/**
* Condition for the paginators that uses joins
*/
if(isset($query['joins']) && !empty($query['joins'])){
foreach($query['joins'] as $key => $joinTable){
if(ClassRegistry::init($joinTable['alias'])->hasField('lang')){
$query['joins'][$key]['conditions'][] = $joinTable['alias'].".lang = '".$_SESSION['lang']."'";
}
}
}
/**
* condition for the normal find queries
*/
if($model->hasField('lang') && $model->name != "User"){
$query['conditions'][$model->name.'.lang'] = $_SESSION['lang'];
}
return $query;
}
}
?>
クエリを変更して、現在の言語 ($_SESSION['lang']) に一致する条件を追加します。コントローラーでは、LocalizableBehavior をアタッチし、いつものように find メソッドを使用するだけです。
$this->Products->find('all');