mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 08:56:36 +02:00
MDL-35238 Compare the ZIP package content hash with the expected value
The expected value is returned as a part of available update info (requires API version 1.1).
This commit is contained in:
parent
85d7516313
commit
6b75106a75
3 changed files with 37 additions and 2 deletions
|
@ -1407,6 +1407,8 @@ class available_update_info {
|
||||||
public $url = null;
|
public $url = null;
|
||||||
/** @var string|null optional URL of a ZIP package that can be downloaded and installed */
|
/** @var string|null optional URL of a ZIP package that can be downloaded and installed */
|
||||||
public $download = null;
|
public $download = null;
|
||||||
|
/** @var string|null of self::download is set, then this must be the MD5 hash of the ZIP */
|
||||||
|
public $downloadmd5 = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates new instance of the class
|
* Creates new instance of the class
|
||||||
|
@ -1529,7 +1531,7 @@ class available_update_deployer {
|
||||||
*
|
*
|
||||||
* All instances of {@link available_update_info} class always provide at least the
|
* All instances of {@link available_update_info} class always provide at least the
|
||||||
* component name and component version. Additionally, we also need the URL to download
|
* component name and component version. Additionally, we also need the URL to download
|
||||||
* the ZIP package from.
|
* the ZIP package from and MD5 hash of the ZIP's content.
|
||||||
*
|
*
|
||||||
* @param available_update_info $info
|
* @param available_update_info $info
|
||||||
* @return bool
|
* @return bool
|
||||||
|
@ -1540,6 +1542,10 @@ class available_update_deployer {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (empty($info->downloadmd5)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1626,6 +1632,7 @@ class available_update_deployer {
|
||||||
'name' => $pluginname,
|
'name' => $pluginname,
|
||||||
'typeroot' => $pluginrootpaths[$plugintype],
|
'typeroot' => $pluginrootpaths[$plugintype],
|
||||||
'package' => $info->download,
|
'package' => $info->download,
|
||||||
|
'md5' => $info->downloadmd5,
|
||||||
'dataroot' => $CFG->dataroot,
|
'dataroot' => $CFG->dataroot,
|
||||||
'dirroot' => $CFG->dirroot,
|
'dirroot' => $CFG->dirroot,
|
||||||
'passfile' => $passfile,
|
'passfile' => $passfile,
|
||||||
|
|
19
mdeploy.php
19
mdeploy.php
|
@ -45,6 +45,7 @@ class download_file_exception extends Exception {}
|
||||||
class backup_folder_exception extends Exception {}
|
class backup_folder_exception extends Exception {}
|
||||||
class zip_exception extends Exception {}
|
class zip_exception extends Exception {}
|
||||||
class filesystem_exception extends Exception {}
|
class filesystem_exception extends Exception {}
|
||||||
|
class checksum_exception extends Exception {}
|
||||||
|
|
||||||
|
|
||||||
// Various support classes /////////////////////////////////////////////////////
|
// Various support classes /////////////////////////////////////////////////////
|
||||||
|
@ -118,6 +119,7 @@ class input_manager extends singleton_pattern {
|
||||||
const TYPE_RAW = 'raw'; // Raw value, keep as is
|
const TYPE_RAW = 'raw'; // Raw value, keep as is
|
||||||
const TYPE_URL = 'url'; // URL to a file
|
const TYPE_URL = 'url'; // URL to a file
|
||||||
const TYPE_PLUGIN = 'plugin'; // Plugin name
|
const TYPE_PLUGIN = 'plugin'; // Plugin name
|
||||||
|
const TYPE_MD5 = 'md5'; // MD5 hash
|
||||||
|
|
||||||
/** @var input_cli_provider|input_http_provider the provider of the input */
|
/** @var input_cli_provider|input_http_provider the provider of the input */
|
||||||
protected $inputprovider = null;
|
protected $inputprovider = null;
|
||||||
|
@ -173,6 +175,7 @@ class input_manager extends singleton_pattern {
|
||||||
array('d', 'dataroot', input_manager::TYPE_PATH, 'Full path to the dataroot (moodledata) directory'),
|
array('d', 'dataroot', input_manager::TYPE_PATH, 'Full path to the dataroot (moodledata) directory'),
|
||||||
array('h', 'help', input_manager::TYPE_FLAG, 'Prints usage information'),
|
array('h', 'help', input_manager::TYPE_FLAG, 'Prints usage information'),
|
||||||
array('i', 'install', input_manager::TYPE_FLAG, 'Installation mode'),
|
array('i', 'install', input_manager::TYPE_FLAG, 'Installation mode'),
|
||||||
|
array('m', 'md5', input_manager::TYPE_MD5, 'Expected MD5 hash of the ZIP package to deploy'),
|
||||||
array('n', 'name', input_manager::TYPE_PLUGIN, 'Plugin name (the name of its folder)'),
|
array('n', 'name', input_manager::TYPE_PLUGIN, 'Plugin name (the name of its folder)'),
|
||||||
array('p', 'package', input_manager::TYPE_URL, 'URL to the ZIP package to deploy'),
|
array('p', 'package', input_manager::TYPE_URL, 'URL to the ZIP package to deploy'),
|
||||||
array('r', 'typeroot', input_manager::TYPE_PATH, 'Full path of the container for this plugin type'),
|
array('r', 'typeroot', input_manager::TYPE_PATH, 'Full path of the container for this plugin type'),
|
||||||
|
@ -288,6 +291,12 @@ class input_manager extends singleton_pattern {
|
||||||
}
|
}
|
||||||
return $raw;
|
return $raw;
|
||||||
|
|
||||||
|
case input_manager::TYPE_MD5:
|
||||||
|
if (!preg_match('/^[a-f0-9]{32}$/', $raw)) {
|
||||||
|
throw new invalid_option_exception('Invalid MD5 hash format');
|
||||||
|
}
|
||||||
|
return $raw;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new invalid_coding_exception('Unknown option type.');
|
throw new invalid_coding_exception('Unknown option type.');
|
||||||
|
|
||||||
|
@ -654,9 +663,17 @@ class worker extends singleton_pattern {
|
||||||
} else {
|
} else {
|
||||||
$this->log('cURL error ' . $this->curlerrno . ' ' . $this->curlerror);
|
$this->log('cURL error ' . $this->curlerrno . ' ' . $this->curlerror);
|
||||||
$this->log('Unable to download the file');
|
$this->log('Unable to download the file');
|
||||||
|
throw new download_file_exception('Unable to download the ZIP package');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare MD5 checksum of the ZIP file - TODO
|
// Compare MD5 checksum of the ZIP file
|
||||||
|
$md5remote = $this->input->get_option('md5');
|
||||||
|
$md5local = md5_file($target);
|
||||||
|
|
||||||
|
if ($md5local !== $md5remote) {
|
||||||
|
$this->log('MD5 checksum failed. Expected: '.$md5remote.' Got: '.$md5local);
|
||||||
|
throw new checksum_exception('MD5 checksum failed');
|
||||||
|
}
|
||||||
|
|
||||||
// Backup the current version of the plugin
|
// Backup the current version of the plugin
|
||||||
$plugintyperoot = $this->input->get_option('typeroot');
|
$plugintyperoot = $this->input->get_option('typeroot');
|
||||||
|
|
|
@ -135,6 +135,8 @@ class mdeploytest extends PHPUnit_Framework_TestCase {
|
||||||
'https://moodle.org/plugins/download.php/1292/mod_stampcoll_moodle23_2012062201.zip'
|
'https://moodle.org/plugins/download.php/1292/mod_stampcoll_moodle23_2012062201.zip'
|
||||||
),
|
),
|
||||||
array('file:///etc/passwd', input_manager::TYPE_URL, ''),
|
array('file:///etc/passwd', input_manager::TYPE_URL, ''),
|
||||||
|
|
||||||
|
array('5e8d2ea4f50d154730100b1645fbad67', input_manager::TYPE_MD5, '5e8d2ea4f50d154730100b1645fbad67'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +157,15 @@ class mdeploytest extends PHPUnit_Framework_TestCase {
|
||||||
$input->cast_value($o, input_manager::TYPE_INT); // must throw exception
|
$input->cast_value($o, input_manager::TYPE_INT); // must throw exception
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException invalid_option_exception
|
||||||
|
*/
|
||||||
|
public function test_cast_invalid_md5_value() {
|
||||||
|
$input = testable_input_manager::instance();
|
||||||
|
$invalid = 'this is not a valid md5 hash';
|
||||||
|
$input->cast_value($invalid, input_manager::TYPE_MD5); // must throw exception
|
||||||
|
}
|
||||||
|
|
||||||
public function test_has_option() {
|
public function test_has_option() {
|
||||||
$provider = input_fake_provider::instance();
|
$provider = input_fake_provider::instance();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue