diff --git a/.travis.yml b/.travis.yml index 799bd5d9f5014..ff2b674cffb14 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,6 +16,9 @@ php: - 7.1 - 5.6 +addons: + postgresql: "9.3" + services: - redis-server @@ -114,7 +117,7 @@ before_script: # The wwwroot and dataroot. sed -i \ - -e "s%http://example.com/moodle%http://localhost%" \ + -e "s%http://example.com/moodle%https://localhost%" \ -e "s%/home/example/moodledata%/home/travis/roots/base%" \ config.php ; diff --git a/admin/environment.xml b/admin/environment.xml index 38207edf1c25b..f87521126df07 100644 --- a/admin/environment.xml +++ b/admin/environment.xml @@ -1905,4 +1905,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/admin/tool/mobile/tests/externallib_test.php b/admin/tool/mobile/tests/externallib_test.php index be10099c031b6..04c0e2437b5cb 100644 --- a/admin/tool/mobile/tests/externallib_test.php +++ b/admin/tool/mobile/tests/externallib_test.php @@ -183,9 +183,6 @@ public function test_get_autologin_key() { $this->assertTrue(isset($token->privatetoken)); // Enable requeriments. - $CFG->httpswwwroot = str_replace('http:', 'https:', $CFG->httpswwwroot); // Mock https. - $CFG->enablewebservices = 1; - $CFG->enablemobilewebservice = 1; $_GET['wstoken'] = $token->token; // Mock parameters. // Even if we force the password change for the current user we should be able to retrieve the key. @@ -212,8 +209,13 @@ public function test_get_autologin_key() { * Test get_autologin_key missing ws. */ public function test_get_autologin_key_missing_ws() { + global $CFG; $this->resetAfterTest(true); + // Need to disable webservices to verify that's checked. + $CFG->enablewebservices = 0; + $CFG->enablemobilewebservice = 0; + $this->setAdminUser(); $this->expectException('moodle_exception'); $this->expectExceptionMessage(get_string('enablewsdescription', 'webservice')); @@ -226,10 +228,12 @@ public function test_get_autologin_key_missing_ws() { public function test_get_autologin_key_missing_https() { global $CFG; + // Need to simulate a non HTTPS site here. + $CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot); + $CFG->httpswwwroot = str_replace('https:', 'http:', $CFG->wwwroot); + $this->resetAfterTest(true); $this->setAdminUser(); - $CFG->enablewebservices = 1; - $CFG->enablemobilewebservice = 1; $this->expectException('moodle_exception'); $this->expectExceptionMessage(get_string('httpsrequired', 'tool_mobile')); @@ -244,9 +248,6 @@ public function test_get_autologin_key_missing_admin() { $this->resetAfterTest(true); $this->setAdminUser(); - $CFG->enablewebservices = 1; - $CFG->enablemobilewebservice = 1; - $CFG->httpswwwroot = str_replace('http:', 'https:', $CFG->httpswwwroot); $this->expectException('moodle_exception'); $this->expectExceptionMessage(get_string('autologinnotallowedtoadmins', 'tool_mobile')); @@ -262,9 +263,6 @@ public function test_get_autologin_key_missing_locked() { $this->resetAfterTest(true); $user = $this->getDataGenerator()->create_user(); $this->setUser($user); - $CFG->enablewebservices = 1; - $CFG->enablemobilewebservice = 1; - $CFG->httpswwwroot = str_replace('http:', 'https:', $CFG->httpswwwroot); $service = $DB->get_record('external_services', array('shortname' => MOODLE_OFFICIAL_MOBILE_SERVICE)); diff --git a/enrol/lti/tests/helper_test.php b/enrol/lti/tests/helper_test.php index 09c58042694b9..a601cf7f9d81e 100644 --- a/enrol/lti/tests/helper_test.php +++ b/enrol/lti/tests/helper_test.php @@ -260,7 +260,7 @@ public function test_get_launch_url() { $id = $tool1->id; $launchurl = \enrol_lti\helper::get_launch_url($id); - $this->assertEquals('http://www.example.com/moodle/enrol/lti/tool.php?id=' . $id, $launchurl->out()); + $this->assertEquals('https://www.example.com/moodle/enrol/lti/tool.php?id=' . $id, $launchurl->out()); } /** @@ -281,13 +281,13 @@ public function test_get_cartridge_url() { $id = $tool1->id; $token = \enrol_lti\helper::generate_cartridge_token($id); $launchurl = \enrol_lti\helper::get_cartridge_url($tool1); - $this->assertEquals('http://www.example.com/moodle/enrol/lti/cartridge.php?id=' . $id . '&token=' . $token, + $this->assertEquals('https://www.example.com/moodle/enrol/lti/cartridge.php?id=' . $id . '&token=' . $token, $launchurl->out()); $CFG->slasharguments = true; $launchurl = \enrol_lti\helper::get_cartridge_url($tool1); - $this->assertEquals('http://www.example.com/moodle/enrol/lti/cartridge.php/' . $id . '/' . $token . '/cartridge.xml', + $this->assertEquals('https://www.example.com/moodle/enrol/lti/cartridge.php/' . $id . '/' . $token . '/cartridge.xml', $launchurl->out()); $CFG->slasharguments = $slasharguments; @@ -311,13 +311,13 @@ public function test_get_proxy_url() { $id = $tool1->id; $token = \enrol_lti\helper::generate_proxy_token($id); $launchurl = \enrol_lti\helper::get_proxy_url($tool1); - $this->assertEquals('http://www.example.com/moodle/enrol/lti/proxy.php?id=' . $id . '&token=' . $token, + $this->assertEquals('https://www.example.com/moodle/enrol/lti/proxy.php?id=' . $id . '&token=' . $token, $launchurl->out()); $CFG->slasharguments = true; $launchurl = \enrol_lti\helper::get_proxy_url($tool1); - $this->assertEquals('http://www.example.com/moodle/enrol/lti/proxy.php/' . $id . '/' . $token . '/', + $this->assertEquals('https://www.example.com/moodle/enrol/lti/proxy.php/' . $id . '/' . $token . '/', $launchurl->out()); $CFG->slasharguments = $slasharguments; diff --git a/files/tests/externallib_test.php b/files/tests/externallib_test.php index 76cf28b76c548..b652e6d074b09 100644 --- a/files/tests/externallib_test.php +++ b/files/tests/externallib_test.php @@ -271,7 +271,7 @@ public function test_get_files() { 'itemid' => $itemid, 'filepath' => '/', 'filename' => 'Simple4.txt', - 'url' => 'http://www.example.com/moodle/pluginfile.php/'.$context->id.'/mod_data/content/'.$itemid.'/Simple4.txt', + 'url' => 'https://www.example.com/moodle/pluginfile.php/'.$context->id.'/mod_data/content/'.$itemid.'/Simple4.txt', 'isdir' => false, 'timemodified' => $timemodified, 'timecreated' => $timecreated, diff --git a/filter/emoticon/tests/filter_test.php b/filter/emoticon/tests/filter_test.php index 8cb2ee3d9ec90..da3576a541932 100644 --- a/filter/emoticon/tests/filter_test.php +++ b/filter/emoticon/tests/filter_test.php @@ -54,7 +54,7 @@ public function test_filter_emoticon_formats() { $this->assertEquals($expected, $filter->filter('(grr)', $options)); // And texts matching target formats are filtered. - $expected = 'angry'; + $expected = 'angry'; $options = array('originalformat' => FORMAT_HTML); // Only FORMAT_HTML is filtered, see {@link testable_filter_emoticon}. $this->assertEquals($expected, $filter->filter('(grr)', $options)); } diff --git a/lang/en/admin.php b/lang/en/admin.php index 25b13734dd0c9..2df58ebef2a17 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -622,6 +622,7 @@ It is recommended to install local copy of free GeoLite2 City database from MaxMind.
IP address location is displayed on simple map or using Google Maps. Please note that you need to have a Google account and apply for free Google Maps API key to enable interactive maps.'; $string['iplookupmaxmindnote'] = 'This product includes GeoLite2 data created by MaxMind, available from http://www.maxmind.com.'; +$string['ishttpswarning'] = 'It has been detected that your site is not secured using HTTPS. For increased security and improved integrations with other systems is highly recommended to migrate your site to HTTPS.'; $string['keeptagnamecase'] = 'Keep tag name casing'; $string['lang'] = 'Default language'; $string['langcache'] = 'Cache language menu'; @@ -800,6 +801,7 @@ $string['onlynoreply'] = 'Only when from a no-reply address'; $string['opcacherecommended'] = 'PHP opcode caching improves performance and lowers memory requirements, OPcache extension is recommended and fully supported.'; $string['opensslrecommended'] = 'Installing the optional OpenSSL library is highly recommended -- it enables Moodle Networking functionality.'; +$string['opensslrequired'] = 'The OpenSSL PHP extension is now required by Moodle to provide stronger cryptographic services.'; $string['opentogoogle'] = 'Open to Google'; $string['optionalmaintenancemessage'] = 'Optional maintenance message'; $string['order1'] = 'First'; diff --git a/lib/outputrequirementslib.php b/lib/outputrequirementslib.php index 1406e40af65fb..04062459b95ad 100644 --- a/lib/outputrequirementslib.php +++ b/lib/outputrequirementslib.php @@ -180,7 +180,7 @@ public function __construct() { $this->yui3loader = new stdClass(); $this->YUI_config = new YUI_config(); - if (is_https()) { + if (is_https() && !empty($CFG->useexternalyui)) { // On HTTPS sites all JS must be loaded from https sites, // YUI CDN does not support https yet, sorry. $CFG->useexternalyui = 0; diff --git a/lib/phpunit/bootstrap.php b/lib/phpunit/bootstrap.php index aa92af8e62abb..b035236df1e34 100644 --- a/lib/phpunit/bootstrap.php +++ b/lib/phpunit/bootstrap.php @@ -170,7 +170,7 @@ } // override CFG settings if necessary and throw away extra CFG settings -$CFG->wwwroot = 'http://www.example.com/moodle'; +$CFG->wwwroot = 'https://www.example.com/moodle'; $CFG->dataroot = $CFG->phpunit_dataroot; $CFG->prefix = $CFG->phpunit_prefix; $CFG->dbtype = isset($CFG->phpunit_dbtype) ? $CFG->phpunit_dbtype : $CFG->dbtype; diff --git a/lib/tests/configonlylib_test.php b/lib/tests/configonlylib_test.php index ef2be8247f913..2dc10cca40c2f 100644 --- a/lib/tests/configonlylib_test.php +++ b/lib/tests/configonlylib_test.php @@ -93,7 +93,7 @@ public function test_min_get_slash_argument() { global $CFG; $this->resetAfterTest(); - $this->assertEquals('http://www.example.com/moodle', $CFG->wwwroot); + $this->assertEquals('https://www.example.com/moodle', $CFG->wwwroot); $_SERVER = array(); $_SERVER['SERVER_SOFTWARE'] = 'Apache/2.2.22 (Unix)'; diff --git a/lib/tests/filter_manager_test.php b/lib/tests/filter_manager_test.php index cf987110275a9..275070bd7d394 100644 --- a/lib/tests/filter_manager_test.php +++ b/lib/tests/filter_manager_test.php @@ -54,7 +54,7 @@ protected function filter_text($text, $skipfilters) { public function test_filter_normal() { $this->resetAfterTest(); filter_set_global_state('emoticon', TEXTFILTER_ON); - $this->assertRegExp('~^

smile

$~', + $this->assertRegExp('~^

smile

$~', $this->filter_text('

:-)

', array())); } @@ -68,7 +68,7 @@ public function test_one_filter_disabled() { public function test_disabling_other_filter_does_not_break_it() { $this->resetAfterTest(); filter_set_global_state('emoticon', TEXTFILTER_ON); - $this->assertRegExp('~^

smile

$~', + $this->assertRegExp('~^

smile

$~', $this->filter_text('

:-)

', array('urltolink'))); } @@ -76,7 +76,7 @@ public function test_one_filter_of_two_disabled() { $this->resetAfterTest(); filter_set_global_state('emoticon', TEXTFILTER_ON); filter_set_global_state('urltolink', TEXTFILTER_ON); - $this->assertRegExp('~^

smile http://google.com/

$~', + $this->assertRegExp('~^

smile http://google.com/

$~', $this->filter_text('

:-) http://google.com/

', array('glossary', 'urltolink'))); } } diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php index 4e1324cbd0a3c..e59a5ee702e7d 100644 --- a/lib/tests/moodlelib_test.php +++ b/lib/tests/moodlelib_test.php @@ -625,12 +625,25 @@ public function test_clean_param_localurl() { $this->assertSame('/just/a/path', clean_param('/just/a/path', PARAM_LOCALURL)); $this->assertSame('course/view.php?id=3', clean_param('course/view.php?id=3', PARAM_LOCALURL)); - // Local absolute HTTPS. + // Local absolute HTTPS in a non HTTPS site. + $CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot); // Need to simulate non-https site. $httpsroot = str_replace('http:', 'https:', $CFG->wwwroot); - $CFG->loginhttps = false; + $CFG->loginhttps = false; // Not allowed. $this->assertSame('', clean_param($httpsroot, PARAM_LOCALURL)); $this->assertSame('', clean_param($httpsroot . '/with/something?else=true', PARAM_LOCALURL)); - $CFG->loginhttps = true; + $CFG->loginhttps = true; // Allowed. + $this->assertSame($httpsroot, clean_param($httpsroot, PARAM_LOCALURL)); + $this->assertSame($httpsroot . '/with/something?else=true', + clean_param($httpsroot . '/with/something?else=true', PARAM_LOCALURL)); + + // Local absolute HTTPS in a HTTPS site. + $CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot); + $httpsroot = $CFG->wwwroot; + $CFG->loginhttps = false; // Always allowed. + $this->assertSame($httpsroot, clean_param($httpsroot, PARAM_LOCALURL)); + $this->assertSame($httpsroot . '/with/something?else=true', + clean_param($httpsroot . '/with/something?else=true', PARAM_LOCALURL)); + $CFG->loginhttps = true; // Always allowed. $this->assertSame($httpsroot, clean_param($httpsroot, PARAM_LOCALURL)); $this->assertSame($httpsroot . '/with/something?else=true', clean_param($httpsroot . '/with/something?else=true', PARAM_LOCALURL)); diff --git a/lib/tests/outputcomponents_test.php b/lib/tests/outputcomponents_test.php index db7764602a5b0..0cf59b5d0f947 100644 --- a/lib/tests/outputcomponents_test.php +++ b/lib/tests/outputcomponents_test.php @@ -125,7 +125,7 @@ public function test_get_url() { $this->assertEquals(1, $CFG->slasharguments); $this->assertEquals(1, $CFG->themerev); $this->assertEquals(0, $CFG->themedesignermode); - $this->assertSame('http://www.example.com/moodle', $CFG->wwwroot); + $this->assertSame('https://www.example.com/moodle', $CFG->wwwroot); $this->assertSame($CFG->wwwroot, $CFG->httpswwwroot); $this->assertEquals(0, $CFG->enablegravatar); $this->assertSame('mm', $CFG->gravatardefaulturl); @@ -205,6 +205,10 @@ public function test_get_url() { $up3 = new user_picture($user3); $this->assertSame($CFG->wwwroot.'/theme/image.php/boost/core/1/u/f2', $up3->get_url($page, $renderer)->out(false)); + // Http version. + $CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot); + $CFG->httpswwwroot = str_replace('https:', 'http:', $CFG->wwwroot); + // Verify defaults to misteryman (mm). $up2 = new user_picture($user2); $this->assertSame('http://www.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?s=35&d=mm', $up2->get_url($page, $renderer)->out(false)); diff --git a/lib/tests/setuplib_test.php b/lib/tests/setuplib_test.php index 54ada2db0f998..357a6d7bae871 100644 --- a/lib/tests/setuplib_test.php +++ b/lib/tests/setuplib_test.php @@ -359,7 +359,6 @@ public function test_get_exception_info_link() { $initialloginhttps = $CFG->loginhttps; $httpswwwroot = str_replace('http:', 'https:', $CFG->wwwroot); - $CFG->loginhttps = false; // Simple local URL. $url = $CFG->wwwroot . '/something/here?really=yes'; @@ -373,14 +372,31 @@ public function test_get_exception_info_link() { $infos = $this->get_exception_info($exception); $this->assertSame($CFG->wwwroot . '/', $infos->link); - // HTTPS URL when login HTTPS is not enabled. + // HTTPS URL when login HTTPS is not enabled and site is HTTP. + $CFG->loginhttps = false; + $CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot); $url = $httpswwwroot . '/something/here?really=yes'; $exception = new moodle_exception('none', 'error', $url); $infos = $this->get_exception_info($exception); $this->assertSame($CFG->wwwroot . '/', $infos->link); - // HTTPS URL with login HTTPS. + // HTTPS URL when login HTTPS is not enabled and site is HTTPS. + $CFG->wwwroot = str_replace('http:', 'https:', $CFG->wwwroot); + $url = $httpswwwroot . '/something/here?really=yes'; + $exception = new moodle_exception('none', 'error', $url); + $infos = $this->get_exception_info($exception); + $this->assertSame($url, $infos->link); + + // HTTPS URL when login HTTPS enabled and site is HTTP. $CFG->loginhttps = true; + $CFG->wwwroot = str_replace('https:', 'http:', $CFG->wwwroot); + $url = $httpswwwroot . '/something/here?really=yes'; + $exception = new moodle_exception('none', 'error', $url); + $infos = $this->get_exception_info($exception); + $this->assertSame($url, $infos->link); + + // HTTPS URL when login HTTPS enabled and site is HTTPS. + $CFG->wwwroot = str_replace('http:', 'https:', $CFG->wwwroot); $url = $httpswwwroot . '/something/here?really=yes'; $exception = new moodle_exception('none', 'error', $url); $infos = $this->get_exception_info($exception); @@ -416,13 +432,6 @@ public function test_get_exception_info_link() { $infos = $this->get_exception_info($exception); $this->assertSame($url, $infos->link); - // Internal HTTPS link from fromurl without login HTTPS. - $CFG->loginhttps = false; - $SESSION->fromurl = $httpswwwroot . '/something/here?really=yes'; - $exception = new moodle_exception('none'); - $infos = $this->get_exception_info($exception); - $this->assertSame($CFG->wwwroot . '/', $infos->link); - // External link from fromurl. $SESSION->fromurl = 'http://moodle.org/something/here?really=yes'; $exception = new moodle_exception('none'); diff --git a/lib/tests/weblib_format_text_test.php b/lib/tests/weblib_format_text_test.php index 23b2b3b4f1a2f..2fede1e35eb8b 100644 --- a/lib/tests/weblib_format_text_test.php +++ b/lib/tests/weblib_format_text_test.php @@ -38,7 +38,7 @@ public function test_format_text_format_html() { $this->resetAfterTest(); filter_set_global_state('emoticon', TEXTFILTER_ON); $this->assertRegExp('~^

smile

$~', + 'src="https://www.example.com/moodle/theme/image.php/_s/boost/core/1/s/smiley" />

$~', format_text('

:-)

', FORMAT_HTML)); } @@ -68,7 +68,7 @@ public function test_format_text_format_markdown() { $this->resetAfterTest(); filter_set_global_state('emoticon', TEXTFILTER_ON); $this->assertRegExp('~^

smile' . + 'src="https://www.example.com/moodle/theme/image.php/_s/boost/core/1/s/smiley" />' . '

\n$~', format_text('*:-)*', FORMAT_MARKDOWN)); } @@ -85,7 +85,7 @@ public function test_format_text_format_moodle() { filter_set_global_state('emoticon', TEXTFILTER_ON); $this->assertRegExp('~^

' . 'smile

$~', + 'src="https://www.example.com/moodle/theme/image.php/_s/boost/core/1/s/smiley" />

$~', format_text('

:-)

', FORMAT_MOODLE)); } diff --git a/lib/upgrade.txt b/lib/upgrade.txt index 34dda8ec0c082..f23f9e74b9257 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -3,6 +3,10 @@ information provided here is intended especially for developers. === 3.3 === +* PHPUnit's bootstrap has been changed to use HTTPS wwwroot (https://www.example.com/moodle) from previous HTTP version. Any + existing test expecting the old HTTP URLs will need to be switched to the new HTTPS value (reference: MDL-54901). +* The information returned by the idp list has changed. This is usually only rendered by the login page and login block. + The icon attribute is removed and an iconurl attribute has been added. * Support added for a new type of external file: FILE_CONTROLLED_LINK. This is an external file that Moodle can control the permissions. Moodle makes files read-only but can grant temporary write access. When accessing a URL, the info from file_browser::get_file_info will be checked to determine if the user has write access, diff --git a/lib/upgradelib.php b/lib/upgradelib.php index 5dcc7932391b9..2cdd6eb34a415 100644 --- a/lib/upgradelib.php +++ b/lib/upgradelib.php @@ -2255,6 +2255,27 @@ function check_mysql_incomplete_unicode_support(environment_results $result) { return null; } +/** + * Check if the site is being served using an ssl url. + * + * Note this does not really perform any request neither looks for proxies or + * other situations. Just looks to wwwroot and warn if it's not using https. + * + * @param environment_results $result $result + * @return environment_results|null updated results object, or null if the site is https. + */ +function check_is_https(environment_results $result) { + global $CFG; + + // Only if is defined, non-empty and whatever core tell us. + if (!empty($CFG->wwwroot) && !is_https()) { + $result->setInfo('site not https'); + $result->setStatus(false); + return $result; + } + return null; +} + /** * Upgrade the minmaxgrade setting. * diff --git a/mod/forum/tests/mail_test.php b/mod/forum/tests/mail_test.php index d77a9df07f2db..d9c299fde1779 100644 --- a/mod/forum/tests/mail_test.php +++ b/mod/forum/tests/mail_test.php @@ -933,7 +933,7 @@ public function forum_post_email_templates_provider() { '~{$a', '~&(amp|lt|gt|quot|\#039);(?!course)', 'Attachment example.txt:\n' . - 'http://www.example.com/moodle/pluginfile.php/\d*/mod_forum/attachment/\d*/example.txt\n', + 'https://www.example.com/moodle/pluginfile.php/\d*/mod_forum/attachment/\d*/example.txt\n', 'Hello Moodle', 'Moodle Forum', 'Welcome.*Moodle', 'Love Moodle', '1\d1' ), ), @@ -992,10 +992,10 @@ public function forum_post_email_templates_provider() { '~{$a', '~&(amp|lt|gt|quot|\#039);(?!course)', 'Attachment example.txt:\n' . - 'http://www.example.com/moodle/pluginfile.php/\d*/mod_forum/attachment/\d*/example.txt\n', + 'https://www.example.com/moodle/pluginfile.php/\d*/mod_forum/attachment/\d*/example.txt\n', 'Text and image', 'Moodle Forum', 'Welcome to Moodle, *\n.*' - .'http://www.example.com/moodle/pluginfile.php/\d+/mod_forum/post/\d+/' + .'https://www.example.com/moodle/pluginfile.php/\d+/mod_forum/post/\d+/' .'Screen%20Shot%202016-03-22%20at%205\.54\.36%20AM%20%281%29\.png *\n.*!', 'Love Moodle', '1\d1'); $textcases['Text mail with text+image message i.e. @@PLUGINFILE@@ token handling'] = array('data' => $newcase); @@ -1041,7 +1041,7 @@ public function forum_post_email_templates_provider() { '
( *\n *)?\n.*HTML text and image', '>Moodle Forum', '

Welcome to Moodle, ' - .'!

', '>Love Moodle', '>1\d1');