From b6bb4e81bb34f8273ac7ca5a42cd28197fe4845c Mon Sep 17 00:00:00 2001 From: Ruslan Kabalin Date: Mon, 12 Oct 2015 11:32:36 +0100 Subject: [PATCH] MDL-50887 antivirus: Use autoloaded classes. This implements the use of class autoloading for antivirus plugin. Base abstract class, exception class and manager are using namespace core\antivirus, this is because all three class files are located in /lib/classes/antivirus/ (see \core_component::classloader for convention details). --- .../clamav/{lib.php => classes/scanner.php} | 8 +- lib/antiviruslib.php | 189 ------------------ lib/classes/antivirus/manager.php | 104 ++++++++++ lib/classes/antivirus/scanner.php | 98 +++++++++ lib/classes/antivirus/scanner_exception.php | 49 +++++ lib/setup.php | 1 - 6 files changed, 256 insertions(+), 193 deletions(-) rename lib/antivirus/clamav/{lib.php => classes/scanner.php} (94%) delete mode 100644 lib/antiviruslib.php create mode 100644 lib/classes/antivirus/manager.php create mode 100644 lib/classes/antivirus/scanner.php create mode 100644 lib/classes/antivirus/scanner_exception.php diff --git a/lib/antivirus/clamav/lib.php b/lib/antivirus/clamav/classes/scanner.php similarity index 94% rename from lib/antivirus/clamav/lib.php rename to lib/antivirus/clamav/classes/scanner.php index 288950f29d7..b4d02fd22e6 100644 --- a/lib/antivirus/clamav/lib.php +++ b/lib/antivirus/clamav/classes/scanner.php @@ -22,6 +22,8 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ +namespace antivirus_clamav; + defined('MOODLE_INTERNAL') || die(); /** @@ -29,7 +31,7 @@ defined('MOODLE_INTERNAL') || die(); * @copyright 2015 Ruslan Kabalin, Lancaster University. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ -class antivirus_clamav extends antivirus { +class scanner extends \core\antivirus\scanner { /** * Are the necessary antivirus settings configured? * @@ -88,7 +90,7 @@ class antivirus_clamav extends antivirus { if ($deleteinfected) { unlink($file); } - throw new antivirus_exception('virusfounduser', '', array('filename' => $filename)); + throw new \core\antivirus\scanner_exception('virusfounduser', '', array('filename' => $filename)); } else { // Unknown problem. $notice = get_string('clamfailed', 'antivirus_clamav', $this->get_clam_error_code($return)); @@ -98,7 +100,7 @@ class antivirus_clamav extends antivirus { if ($deleteinfected) { unlink($file); } - throw new antivirus_exception('virusfounduser', '', array('filename' => $filename)); + throw new \core\antivirus\scanner_exception('virusfounduser', '', array('filename' => $filename)); } else { return; } diff --git a/lib/antiviruslib.php b/lib/antiviruslib.php deleted file mode 100644 index 91dae2b470b..00000000000 --- a/lib/antiviruslib.php +++ /dev/null @@ -1,189 +0,0 @@ -. - -/** - * Utility classes and functions for antivirus integration. - * - * @package core_antivirus - * @copyright 2015 Ruslan Kabalin, Lancaster University. - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -/** - * Returns list of enabled antiviruses. - * - * @return array Array ('antivirusname'=>stdClass antivirus object). - */ -function antiviruses_get_enabled() { - global $CFG; - - $active = array(); - if (empty($CFG->antiviruses)) { - return $active; - } - - foreach (explode(',', $CFG->antiviruses) as $e) { - if ($antivirus = antiviruses_get_antivirus($e)) { - if ($antivirus->is_configured()) { - $active[$e] = $antivirus; - } - } - } - return $active; -} - -/** - * Scan file using all enabled antiviruses, throws exception in case of infected file. - * - * @param string $file Full path to the file. - * @param string $filename Name of the file (could be different from physical file if temp file is used). - * @param bool $deleteinfected whether infected file needs to be deleted. - * @throws antivirus_exception If file is infected. - * @return void - */ -function antiviruses_scan_file($file, $filename, $deleteinfected) { - $antiviruses = antiviruses_get_enabled(); - foreach ($antiviruses as $antivirus) { - $antivirus->scan_file($file, $filename, $deleteinfected); - } -} - -/** - * Returns instance of antivirus. - * - * @param string $antivirusname name of antivirus. - * @return object|bool antivirus instance or false if does not exist. - */ -function antiviruses_get_antivirus($antivirusname) { - global $CFG; - - $libfile = "$CFG->libdir/antivirus/$antivirusname/lib.php"; - if (!file_exists($libfile)) { - return false; - } - require_once($libfile); - $classname = 'antivirus_' . $antivirusname; - if (!class_exists($classname)) { - return false; - } - return new $classname(); -} - -/** - * Get the list of available antiviruses. - * - * @return array Array ('antivirusname'=>'localised antivirus name'). - */ -function antiviruses_get_available() { - $antiviruses = array(); - foreach (core_component::get_plugin_list('antivirus') as $antivirusname => $dir) { - $antiviruses[$antivirusname] = get_string('pluginname', 'antivirus_'.$antivirusname); - } - return $antiviruses; -} - -/** - * Base abstract antivirus class. - * - * @package core - * @subpackage antivirus - * @copyright 2015 Ruslan Kabalin, Lancaster University. - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -abstract class antivirus { - /** @var stdClass the config for antivirus */ - protected $config; - - /** - * Class constructor. - * - * @return void. - */ - public function __construct() { - // Populate config variable, child class name is matching full plugin name, - // so we can use it directly to retrieve plugin configuration. - $this->config = get_config(get_class($this)); - } - - /** - * Are the antivirus settings configured? - * - * @return bool True if plugin has been configured. - */ - public abstract function is_configured(); - - /** - * Scan file, throws exception in case of infected file. - * - * @param string $file Full path to the file. - * @param string $filename Name of the file (could be different from physical file if temp file is used). - * @param bool $deleteinfected whether infected file needs to be deleted. - * @throws antivirus_exception If file is infected. - * @return void - */ - public abstract function scan_file($file, $filename, $deleteinfected); - - /** - * Email admins about antivirus scan outcomes. - * - * @param string $notice The body of the email to be sent. - * @return void - */ - public function message_admins($notice) { - - $site = get_site(); - - $subject = get_string('emailsubject', 'antivirus', format_string($site->fullname)); - $admins = get_admins(); - foreach ($admins as $admin) { - $eventdata = new stdClass(); - $eventdata->component = 'moodle'; - $eventdata->name = 'errors'; - $eventdata->userfrom = get_admin(); - $eventdata->userto = $admin; - $eventdata->subject = $subject; - $eventdata->fullmessage = $notice; - $eventdata->fullmessageformat = FORMAT_PLAIN; - $eventdata->fullmessagehtml = ''; - $eventdata->smallmessage = ''; - message_send($eventdata); - } - } -} - -/** - * An antivirus exception class. - * - * @package core - * @subpackage antivirus - * @copyright 2015 Ruslan Kabalin, Lancaster University. - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ -class antivirus_exception extends moodle_exception { - /** - * Constructs a new exception - * - * @param string $errorcode - * @param string $link - * @param mixed $a - * @param mixed $debuginfo - */ - public function __construct($errorcode, $link = '', $a = null, $debuginfo = null) { - parent::__construct($errorcode, 'antivirus', $link, $a, $debuginfo); - } -} diff --git a/lib/classes/antivirus/manager.php b/lib/classes/antivirus/manager.php new file mode 100644 index 00000000000..20b8cce6966 --- /dev/null +++ b/lib/classes/antivirus/manager.php @@ -0,0 +1,104 @@ +. + +/** + * Manager class for antivirus integration. + * + * @package core_antivirus + * @copyright 2015 Ruslan Kabalin, Lancaster University. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core\antivirus; + +defined('MOODLE_INTERNAL') || die(); + +/** + * Class used for various antivirus related stuff. + * + * @package core_antivirus + * @copyright 2015 Ruslan Kabalin, Lancaster University. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class manager { + /** + * Returns list of enabled antiviruses. + * + * @return array Array ('antivirusname'=>stdClass antivirus object). + */ + public static function antiviruses_get_enabled() { + global $CFG; + + $active = array(); + if (empty($CFG->antiviruses)) { + return $active; + } + + foreach (explode(',', $CFG->antiviruses) as $e) { + if ($antivirus = self::get_antivirus($e)) { + if ($antivirus->is_configured()) { + $active[$e] = $antivirus; + } + } + } + return $active; + } + + /** + * Scan file using all enabled antiviruses, throws exception in case of infected file. + * + * @param string $file Full path to the file. + * @param string $filename Name of the file (could be different from physical file if temp file is used). + * @param bool $deleteinfected whether infected file needs to be deleted. + * @throws \core_antivirus\scanner_exception If file is infected. + * @return void + */ + public static function antiviruses_scan_file($file, $filename, $deleteinfected) { + $antiviruses = antiviruses_get_enabled(); + foreach ($antiviruses as $antivirus) { + $antivirus->scan_file($file, $filename, $deleteinfected); + } + } + + /** + * Returns instance of antivirus. + * + * @param string $antivirusname name of antivirus. + * @return object|bool antivirus instance or false if does not exist. + */ + public static function get_antivirus($antivirusname) { + global $CFG; + + $classname = '\\antivirus_' . $antivirusname . '\\scanner'; + if (!class_exists($classname)) { + return false; + } + return new $classname(); + } + + /** + * Get the list of available antiviruses. + * + * @return array Array ('antivirusname'=>'localised antivirus name'). + */ + public static function antiviruses_get_available() { + $antiviruses = array(); + foreach (core_component::get_plugin_list('antivirus') as $antivirusname => $dir) { + $antiviruses[$antivirusname] = get_string('pluginname', 'antivirus_'.$antivirusname); + } + return $antiviruses; + } +} diff --git a/lib/classes/antivirus/scanner.php b/lib/classes/antivirus/scanner.php new file mode 100644 index 00000000000..64006fad726 --- /dev/null +++ b/lib/classes/antivirus/scanner.php @@ -0,0 +1,98 @@ +. + +/** + * Base class for antivirus integration. + * + * @package core_antivirus + * @copyright 2015 Ruslan Kabalin, Lancaster University. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core\antivirus; + +defined('MOODLE_INTERNAL') || die(); + +/** + * Base abstract antivirus scanner class. + * + * @package core + * @subpackage antivirus + * @copyright 2015 Ruslan Kabalin, Lancaster University. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +abstract class scanner { + /** @var stdClass the config for antivirus */ + protected $config; + + /** + * Class constructor. + * + * @return void. + */ + public function __construct() { + // Populate config variable, inheriting class namespace is matching + // full plugin name, so we can use it directly to retrieve plugin + // configuration. + $ref = new \ReflectionClass(get_class($this)); + $this->config = get_config($ref->getNamespaceName()); + } + + /** + * Are the antivirus settings configured? + * + * @return bool True if plugin has been configured. + */ + public abstract function is_configured(); + + /** + * Scan file, throws exception in case of infected file. + * + * @param string $file Full path to the file. + * @param string $filename Name of the file (could be different from physical file if temp file is used). + * @param bool $deleteinfected whether infected file needs to be deleted. + * @throws \core\antivirus\scanner_exception If file is infected. + * @return void + */ + public abstract function scan_file($file, $filename, $deleteinfected); + + /** + * Email admins about antivirus scan outcomes. + * + * @param string $notice The body of the email to be sent. + * @return void + */ + public function message_admins($notice) { + + $site = get_site(); + + $subject = get_string('emailsubject', 'antivirus', format_string($site->fullname)); + $admins = get_admins(); + foreach ($admins as $admin) { + $eventdata = new \stdClass(); + $eventdata->component = 'moodle'; + $eventdata->name = 'errors'; + $eventdata->userfrom = get_admin(); + $eventdata->userto = $admin; + $eventdata->subject = $subject; + $eventdata->fullmessage = $notice; + $eventdata->fullmessageformat = FORMAT_PLAIN; + $eventdata->fullmessagehtml = ''; + $eventdata->smallmessage = ''; + message_send($eventdata); + } + } +} \ No newline at end of file diff --git a/lib/classes/antivirus/scanner_exception.php b/lib/classes/antivirus/scanner_exception.php new file mode 100644 index 00000000000..138901ca0f0 --- /dev/null +++ b/lib/classes/antivirus/scanner_exception.php @@ -0,0 +1,49 @@ +. + +/** + * Exception for antivirus. + * + * @package core_antivirus + * @copyright 2015 Ruslan Kabalin, Lancaster University. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core\antivirus; + +defined('MOODLE_INTERNAL') || die(); + +/** + * An antivirus scanner exception class. + * + * @package core + * @subpackage antivirus + * @copyright 2015 Ruslan Kabalin, Lancaster University. + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class scanner_exception extends \moodle_exception { + /** + * Constructs a new exception + * + * @param string $errorcode + * @param string $link + * @param mixed $a + * @param mixed $debuginfo + */ + public function __construct($errorcode, $link = '', $a = null, $debuginfo = null) { + parent::__construct($errorcode, 'antivirus', $link, $a, $debuginfo); + } +} diff --git a/lib/setup.php b/lib/setup.php index 4bb4e6ae6b8..4c5930bc03f 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -607,7 +607,6 @@ require_once($CFG->libdir .'/editorlib.php'); // All text editor related f require_once($CFG->libdir .'/messagelib.php'); // Messagelib functions require_once($CFG->libdir .'/modinfolib.php'); // Cached information on course-module instances require_once($CFG->dirroot.'/cache/lib.php'); // Cache API -require_once($CFG->libdir .'/antiviruslib.php'); // Antivirus functions and classes. // make sure PHP is not severly misconfigured setup_validate_php_configuration();