2012-03-20 13 views
0

このユーザーのセッション中にユーザーの資格情報を変更する状況で素晴らしいコードスニペットが見つかりました。 hasCredential()メソッドのデフォルトは、ユーザーのセッションではなくデータベースを調べることです。ユーザーの資格情報は、ユーザーのセッション中にプログラムによって変更されることが多いため、私のニーズを完全に満たしています。だから私は本当にこの機能を維持する必要があります。 [A、B]又はおよび状況:[A、B]は、コードスニペットは、1つのインスタンスの、それが唯一のチェックとして失敗しない複数の資格情報を持っている状況、いずれかまたは事情しかしながら権限と資格情報[[AND OR]]がセッション資格情報ではなくデータベースをチェックするコードスニペットで機能しない

、 AND ORインスタンスのyamlセキュリティー・ファイルを読んでください。

ANDや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; 
} 

EDIT:

私は、私は以下のオリジナル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

関連する問題