PDA

View Full Version : ساده و پیچیده مشکلی با ACL



cybercoder
سه شنبه 01 دی 1388, 15:49 عصر
من ACL رو در حالت CRUD تنظیم کردم و می تونم کلیه node های موجود رو از لحاظ سطح دسترسی مدیریت کنم اما

چطور می توان فقط node هایی رو واکشی کرد که کاربر جاری مجوز _read آن ها را دارد؟

اصلا هم والد ها مهم نیستند فقط در سطح فرزندان مهمه

maysamscript
یک شنبه 06 دی 1388, 21:25 عصر
شما باید دسترسی کاربر جاری را روی کلیه node ها بررسی کنید. سپس لیستی از نود های مجاز پیدا میشه. این لیست را میتونید به شرط تابع find اضافه کنید. یه چیزی شبیه این:


function _allow_cats($type='*'){
if($this->user==NULL) return array();
$user_id = $this->user['User']['id'];
$cats = $this->Category->find('all',array('recursive'=>-1));
$cat_list = null;
foreach($cats as $cat){
$cat_id = $cat['Category']['id'];
$check = $this->Acl->check(array('model' => 'User', 'foreign_key' => $user_id), array('model' => 'Category', 'foreign_key' => $cat_id));
if($check){
$cat_list[] = $cat_id;
}
}
return $cat_list;
}


function _set(){
$allow_cat = $this->_allow_cats();
$this->Category->recursive = -1;
$select= $this->Category->find('all',array('conditions'=>array('Category.id'=>$allow_cat,'lft+1 = rght')));}

اگر توضیح بیشتری لازمه بگید

cybercoder
دوشنبه 07 دی 1388, 17:06 عصر
به این شکل که شما می فرمایید سربار زیاده و اصلا بهینه نیست.
توجه کنید:


چطور می توان فقط node هایی رو واکشی کرد که کاربر جاری مجوز _read آن ها را دارد؟

شما اول همه رو واکشی می کنید بعد تک به تک چک می کنید که اگر دسترسی هست به آرایه دیگه ای اضافه بشه.
به این پرس و جو هم دقت کنید:


SELECT * FROM posts WHERE id IN(
SELECT foreign_key FROM acos
WHERE id IN(
SELECT aco_id FROM aros_acos WHERE
aro_id=(SELECT id FROM aros WHERE alias='User:username')
AND
aco_id IN (SELECT id FROM acos WHERE model='Post')
AND
_read=1
)
)
اگر این پرس و جو را بتوان به خورد تابع find یا paginate داد به سادگی قابل حله.

maysamscript
دوشنبه 07 دی 1388, 18:01 عصر
اگر این پرس و جو را بتوان به خورد تابع find یا paginate داد به سادگی قابل حله. شما باید از یک sub-query در کاندیشن find استفاده کنید.
مثال:

$conditionsSubQuery['"User2"."status"'] = 'B';

$dbo = $this->User->getDataSource();
$subQuery = $dbo->buildStatement(
array(
'fields' => array('"User2"."id"'),
'table' => $dbo->fullTableName($this->User),
'alias' => 'User2',
'limit' => null,
'offset' => null,
'joins' => array(),
'conditions' => $conditionsSubQuery,
'order' => null,
'group' => null
),
$this->User
);
$subQuery = ' "User"."id" NOT IN (' . $subQuery . ') ';
$subQueryExpression = $dbo->expression($subQuery);

$conditions[] = $subQueryExpression;

$this->User->find('all', compact('conditions'));

این کد تولید میشود:

SELECT
"User"."id" AS "User__id",
"User"."name" AS "User__name",
"User"."status" AS "User__status"
FROM
"users" AS "User"
WHERE
"User"."id" NOT IN (
SELECT
"User2"."id"
FROM
"users" AS "User2"
WHERE
"User2"."status" = 'B'
)
توضیحات بیشتر:
http://book.cakephp.org/view/74/Complex-Find-Conditions

cybercoder
جمعه 11 دی 1388, 23:57 عصر
راستش من از این روش سر در نمیارم قبلا هم هرچی سعی کردم نتونستم پرس و جوی تو درتو بیش از دو تا زیر جستجو باهاش در بیارم
اما با استفاده از Join و Semi Join باید بشه همین پرس و جو رو انجام داد باید وقت بذارم روش