mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
accesslib: has_cap_fad() respect local-context-wins permissions rule
The initial implementation of has_cap_fad() just added the permission values regardless of the locality of the context. This patch adds support (read: fixes bug) for the "local context wins" rule. Additionally, it removes a related bug where we were exiting early if we found a CAP_PROHIBIT, ignoring the $doanything flag.
This commit is contained in:
parent
5b9e50caf0
commit
c7a8ec8cf0
@ -483,6 +483,15 @@ function path_inaccessdata($path, $ad) {
|
||||
* course you'll have techer+defaultloggedinuser.
|
||||
* We try to mimic that in switchrole.
|
||||
*
|
||||
* Local-most role definition and role-assignment wins
|
||||
* ---------------------------------------------------
|
||||
* So if the local context has said 'allow', it wins
|
||||
* over a high-level context that says 'deny'.
|
||||
* This is applied when walking rdefs, and RAs.
|
||||
* Only at the same context the values are SUM()med.
|
||||
*
|
||||
* The exception is CAP_PROHIBIT.
|
||||
*
|
||||
* "Guest default role" exception
|
||||
* ------------------------------
|
||||
*
|
||||
@ -530,7 +539,7 @@ function has_cap_fad($capability, $context, $ad, $doanything) {
|
||||
|
||||
$cc = count($contexts);
|
||||
|
||||
$can = false;
|
||||
$can = 0;
|
||||
|
||||
//
|
||||
// role-switches loop
|
||||
@ -557,10 +566,13 @@ function has_cap_fad($capability, $context, $ad, $doanything) {
|
||||
$capctxp = $contexts[$m];
|
||||
if (isset($ad['rdef']["{$capctxp}:$roleid"][$capability])) {
|
||||
$perm = $ad['rdef']["{$capctxp}:$roleid"][$capability];
|
||||
if ($perm === CAP_PROHIBIT) {
|
||||
return false;
|
||||
} else {
|
||||
$can += $perm;
|
||||
// The most local permission (first to set) wins
|
||||
// the only exception is CAP_PROHIBIT
|
||||
if ($can === 0) {
|
||||
$can = $perm;
|
||||
} elseif ($perm == CAP_PROHIBIT) {
|
||||
$can = $perm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -595,8 +607,10 @@ function has_cap_fad($capability, $context, $ad, $doanything) {
|
||||
// Found role assignments on this leaf
|
||||
$ras = $ad['ra'][$ctxp];
|
||||
$rc = count($ras);
|
||||
$ctxcan = 0;
|
||||
for ($rn=0;$rn<$rc;$rn++) {
|
||||
$roleid = $ras[$rn];
|
||||
$roleid = $ras[$rn];
|
||||
$rolecan = 0;
|
||||
// Walk the path for capabilities
|
||||
// from the bottom up...
|
||||
for ($m=$cc-1;$m>=0;$m--) {
|
||||
@ -612,13 +626,28 @@ function has_cap_fad($capability, $context, $ad, $doanything) {
|
||||
}
|
||||
if (isset($ad['rdef']["{$capctxp}:$roleid"][$capability])) {
|
||||
$perm = $ad['rdef']["{$capctxp}:$roleid"][$capability];
|
||||
if ($perm === CAP_PROHIBIT) {
|
||||
return false;
|
||||
} else {
|
||||
$can += $perm;
|
||||
// The most local permission (first to set) wins
|
||||
// the only exception is CAP_PROHIBIT
|
||||
if ($rolecan === 0) {
|
||||
$rolecan = $perm;
|
||||
} elseif ($perm == CAP_PROHIBIT) {
|
||||
$rolecan = $perm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Permissions at the same
|
||||
// ctxlevel are added together
|
||||
$ctxcan += $rolecan;
|
||||
}
|
||||
// The most local RAs with a defined
|
||||
// permission ($ctxcan) win, except
|
||||
// for CAP_PROHIBIT
|
||||
if ($can === 0) {
|
||||
$can = $ctxcan;
|
||||
} elseif ($ctxcan == CAP_PROHIBIT) {
|
||||
$can = $ctxcan;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -628,7 +657,7 @@ function has_cap_fad($capability, $context, $ad, $doanything) {
|
||||
// didn't find it as an explicit cap,
|
||||
// but maybe the user candoanything in this context...
|
||||
return has_cap_fad('moodle/site:doanything', $context,
|
||||
$ad, false);
|
||||
$ad, false);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user