2012-03-20 51 views
0

我發現這個很棒的代碼片段,在用戶會話期間更改用戶憑據的情況下工作得非常好。 hasCredential()方法默認爲查看數據庫而不是用戶的會話 - 這完全滿足我的需求(因爲用戶的憑證通常在用戶會話期間以編程方式更改)。所以我真的需要保持這個功能。但是,對於具有多個憑證的情況,或者是OR情況:[[A,B]]或AND情況:[A,B],代碼段失敗,因爲它只檢查一個實例,不檢查讀取AND OR實例的yaml安全文件。權限和憑證[[ANDOR]]不能與檢查數據庫而不是會話憑證的代碼片段配合使用

我正在尋找幫助,以便如何調整代碼片段以考慮AND OR yaml憑據權限。下面的代碼片段:

public function hasCredential($permission_name) 
{ 
//this overrides the default action (hasCredential) and instead of checking 
//the user's session, it now checks the database directly. 
if (!$this->isAuthenticated()) { 
    return false; 
} 
$gu = $this->getGuardUser(); 
$groups = $gu->getGroups(); 
$permissions = $gu->getPermissions(); 

$permission_names = array(); 
foreach($permissions as $permission) { 
    $permission_names[] = $permission->getName(); 
} 
foreach($groups as $group) { 
    $group_permissions = $group->getPermissions(); 
    foreach($group_permissions as $group_permission) { 
    $permission_names = array_merge($permission_names, array($group_permission->getName())); 
    } 
} 
$permission_names = array_unique($permission_names); 
return (in_array($permission_name, $permission_names)) ? true : false; 
} 

編輯:

我想我需要合併與下面的原hasCredential()上面的代碼,但我與邏輯掙扎:

public function hasCredential($credentials, $useAnd = true) 
{ 
if (null === $this->credentials) 
{ 
    return false; 
} 

if (!is_array($credentials)) 
{ 
    return in_array($credentials, $this->credentials); 
} 

// now we assume that $credentials is an array 
$test = false; 

foreach ($credentials as $credential) 
{ 
    // recursively check the credential with a switched AND/OR mode 
    $test = $this->hasCredential($credential, $useAnd ? false : true); 

    if ($useAnd) 
    { 
    $test = $test ? false : true; 
    } 

    if ($test) // either passed one in OR mode or failed one in AND mode 
    { 
    break; // the matter is settled 
    } 
} 

if ($useAnd) // in AND mode we succeed if $test is false 
{ 
    $test = $test ? false : true; 
} 

return $test; 
} 

回答

0

我想我找到了覆蓋sfGuardSecurityUser類中的原始代碼的hasCredential方法的正確實現。代碼要求底層GuardUser模型重新加載數據庫中的所有權限和組,並在檢查證書之前將這些憑證添加到SecurityUser對象。

/** 
* Returns whether or not the user has the given credential. 
* 
* EXTENDED to reload all permission so that changes take 
* immediate effect and user does not have to log out 
* 
* @param string $credential The credential name 
* @param boolean $useAnd Whether or not to use an AND condition 
* @return boolean 
*/ 
public function hasCredential($credential, $useAnd = true) 
{ 
    if (empty($credentials)) 
    { 
    return true; 
    } 

    if (!$this->getGuardUser()) 
    { 
    return false; 
    } 

    if ($this->getGuardUser()->getIsSuperAdmin()) 
    { 
    return true; 
    } 

    if (!$this->isAuthenticated()) { 
    return false; 
    } 

    $gu = $this->getGuardUser(); 
    $groups = $gu->getGroups(); 
    $permissions = $gu->getPermissions(); 

    $permission_names = array(); 
    foreach($permissions as $permission) { 
    $permission_names[] = $permission->getName(); 
    } 
    foreach($groups as $group) { 
    $group_permissions = $group->getPermissions(); 
    foreach($group_permissions as $group_permission) { 
     $permission_names = array_merge($permission_names, array($group_permission->getName())); 
    } 
    } 
    $permission_names = array_unique($permission_names); 

    if (!is_array($credentials)) 
    { 
    return in_array($credentials, $permission_names); 
    } 

    // now we assume that $credentials is an array 
    $test = false; 

    foreach ($credentials as $credential) 
    { 
    // recursively check the credential with a switched AND/OR mode 
    $test = $this->hasCredential($credential, $useAnd ? false : true); 

    if ($useAnd) 
    { 
     $test = $test ? false : true; 
    } 

    if ($test) // either passed one in OR mode or failed one in AND mode 
    { 
     break; // the matter is settled 
    } 
    } 

    if ($useAnd) // in AND mode we succeed if $test is false 
    { 
    $test = $test ? false : true; 
    } 

    return $test; 
} 
+0

您能否提供正確實施上述hasCrendential的路徑?對不起,這麼晚迴應。這仍然是一個問題,我剛剛找到你的答案。 – Patrick 2012-07-12 20:45:25