MDL-63395 user: Fix profile visibility check.

It needs to be done in user_get_user_details as well.
This commit is contained in:
Ilya Tregubov
2025-08-07 10:31:15 +07:00
committed by Huong Nguyen
parent 9ec4f4b386
commit be2c290b2f
+59 -32
View File
@@ -296,18 +296,41 @@ function user_get_user_details($user, $course = null, array $userfields = array(
$userfields[] = 'fullname';
}
// Callback check for plugins to allow or prevent access.
$forceallow = true;
$currentuser = ($user->id == $USER->id);
$isadmin = is_siteadmin($USER);
if (!$currentuser) {
$forceallow = false;
$callbackresult = user_process_profile_callbacks($user, $course);
if ($callbackresult === core_user::VIEWPROFILE_PREVENT) {
return null; // Access denied.
} else if ($callbackresult === core_user::VIEWPROFILE_FORCE_ALLOW) {
$forceallow = true;
}
}
if (!empty($course)) {
$context = context_course::instance($course->id);
$usercontext = context_user::instance($user->id);
$canviewdetailscap = (has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext));
} else {
$context = context_user::instance($user->id);
$usercontext = $context;
$canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext);
}
$currentuser = ($user->id == $USER->id);
$isadmin = is_siteadmin($USER);
if (!$forceallow) {
// Existing capability checks.
if (!empty($course)) {
$canviewdetailscap = (has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext));
} else {
$canviewdetailscap = has_capability('moodle/user:viewdetails', $usercontext);
}
if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) {
// Skip this user details.
return null;
}
}
// This does not need to include custom profile fields as it is only used to check specific
// fields below.
@@ -331,11 +354,6 @@ function user_get_user_details($user, $course = null, array $userfields = array(
$canaccessallgroups = false;
}
if (!$currentuser && !$canviewdetailscap && !has_coursecontact_role($user->id)) {
// Skip this user details.
return null;
}
$userdetails = array();
$userdetails['id'] = $user->id;
@@ -1162,29 +1180,10 @@ function user_can_view_profile($user, $course = null, $usercontext = null) {
}
// Use callbacks so that (primarily) local plugins can prevent or allow profile access.
$forceallow = false;
$plugintypes = get_plugins_with_function('control_view_profile');
foreach ($plugintypes as $plugins) {
foreach ($plugins as $pluginfunction) {
$result = $pluginfunction($user, $course, $usercontext);
switch ($result) {
case core_user::VIEWPROFILE_DO_NOT_PREVENT:
// If the plugin doesn't stop access, just continue to next plugin or use
// default behaviour.
break;
case core_user::VIEWPROFILE_FORCE_ALLOW:
// Record that we are definitely going to allow it (unless another plugin
// returns _PREVENT).
$forceallow = true;
break;
case core_user::VIEWPROFILE_PREVENT:
// If any plugin returns PREVENT then we return false, regardless of what
// other plugins said.
return false;
}
}
}
if ($forceallow) {
$callbackresult = user_process_profile_callbacks($user, $course, $usercontext);
if ($callbackresult === core_user::VIEWPROFILE_PREVENT) {
return false; // Access denied.
} else if ($callbackresult === core_user::VIEWPROFILE_FORCE_ALLOW) {
return true;
}
@@ -1230,6 +1229,34 @@ function user_can_view_profile($user, $course = null, $usercontext = null) {
return false;
}
/**
* Process plugin callbacks for profile visibility.
*
* @param stdClass $user The user whose profile is being checked.
* @param stdClass|null $course The course context, if applicable.
* @param context|null $usercontext The user context, if applicable.
* @return int One of the core_user::VIEWPROFILE_* constants.
*/
function user_process_profile_callbacks(stdClass $user, ?stdClass $course = null, ?stdClass $usercontext = null): int {
$plugintypes = get_plugins_with_function('control_view_profile');
$forceallow = false;
foreach ($plugintypes as $plugins) {
foreach ($plugins as $pluginfunction) {
$result = $pluginfunction($user, $course, $usercontext);
switch ($result) {
case core_user::VIEWPROFILE_FORCE_ALLOW:
$forceallow = true;
break;
case core_user::VIEWPROFILE_PREVENT:
return core_user::VIEWPROFILE_PREVENT;
}
}
}
return $forceallow ? core_user::VIEWPROFILE_FORCE_ALLOW : core_user::VIEWPROFILE_DO_NOT_PREVENT;
}
/**
* Returns users tagged with a specified tag.
*