MDL-67095 core_h5p: Prevent synchronous access to save the same h5p

When deploying a new H5P resource we need to ensure that
we don't start deploying the same H5P in another thread
(e.g. for another session/user).
This commit is contained in:
cescobedo 2020-04-02 16:18:12 +02:00
parent 788dfb9c7d
commit e84ce938d9
2 changed files with 16 additions and 2 deletions

View file

@ -28,6 +28,7 @@ defined('MOODLE_INTERNAL') || die();
use core_h5p\local\library\autoloader;
use core_xapi\local\statement\item_activity;
use core\lock\lock_config;
/**
* H5P player class, for displaying any local H5P content.
@ -337,8 +338,20 @@ class player {
// content-type libraries exist, to avoid users without the h5p:updatelibraries capability upload malicious content.
$onlyupdatelibs = !helper::can_update_library($file);
// Validate and store the H5P content before displaying it.
$h5pid = helper::save_h5p($this->factory, $file, $config, $onlyupdatelibs, false);
// Start lock to prevent synchronous access to save the same h5p.
$lockfactory = lock_config::get_lock_factory('core_h5p');
$lockkey = 'core_h5p_' . $pathnamehash;
if ($lock = $lockfactory->get_lock($lockkey, 10)) {
try {
// Validate and store the H5P content before displaying it.
$h5pid = helper::save_h5p($this->factory, $file, $config, $onlyupdatelibs, false);
} finally {
$lock->release();
}
} else {
$this->core->h5pF->setErrorMessage(get_string('lockh5pdeploy', 'core_h5p'));
return false;
};
if (!$h5pid && $file->get_userid() != $USER->id && has_capability('moodle/h5p:updatelibraries', $this->context)) {
// The user has permission to update libraries but the package has been uploaded by a different
// user without this permission. Check if there is some missing required library error.