diff --git a/.htaccess b/.htaccess index d79ee9f887..5e24a35743 100644 --- a/.htaccess +++ b/.htaccess @@ -45,6 +45,10 @@ Options -Indexes ModPagespeed Off + Header set X-Content-Type-Options "nosniff" + Header set X-XSS-Protection "1; mode=block" + Header set X-Robots-Tag "none" + Header set X-Frame-Options "SAMEORIGIN" Header set Cache-Control "max-age=7200, public" diff --git a/config/config.sample.php b/config/config.sample.php index 5099fae66c..4b902b306b 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -745,18 +745,6 @@ $CONFIG = array( * SSL */ -/** - * Change this to ``true`` to require HTTPS for all connections, and to reject - * HTTP requests. - */ -'forcessl' => false, - -/** - * Change this to ``true`` to require HTTPS connections also for all subdomains. - * Works only together when `forcessl` is set to true. - */ -'forceSSLforSubdomains' => false, - /** * Extra SSL options to be used for configuration. */ @@ -787,13 +775,6 @@ $CONFIG = array( */ 'theme' => '', -/** - * X-Frame-Restriction is a header which prevents browsers from showing the site - * inside an iframe. This is be used to prevent clickjacking. It is risky to - * disable this, so leave it set at ``true``. - */ -'xframe_restriction' => true, - /** * The default cipher for encrypting files. Currently AES-128-CFB and * AES-256-CFB are supported. diff --git a/core/js/core.json b/core/js/core.json index 7f3b313e89..b32ca5ca8f 100644 --- a/core/js/core.json +++ b/core/js/core.json @@ -24,6 +24,7 @@ "config.js", "multiselect.js", "oc-requesttoken.js", + "setupchecks.js", "../search/js/search.js" ] } diff --git a/core/js/js.js b/core/js/js.js index 1e9ae4cc69..f24694124a 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -210,6 +210,14 @@ var OC={ window.location = targetURL; }, + /** + * Protocol that is used to access this ownCloud instance + * @return {string} Used protocol + */ + getProtocol: function() { + return window.location.protocol.split(':')[0]; + }, + /** * get the absolute path to an image file * if no extension is given for the image, it will automatically decide diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js index 00e73162c5..d5bd1c465b 100644 --- a/core/js/setupchecks.js +++ b/core/js/setupchecks.js @@ -70,7 +70,101 @@ url: OC.generateUrl('settings/ajax/checksetup') }).then(afterCall, afterCall); return deferred.promise(); + }, + + /** + * Runs generic checks on the server side, the difference to dedicated + * methods is that we use the same XHR object for all checks to save + * requests. + * + * @return $.Deferred object resolved with an array of error messages + */ + checkGeneric: function() { + var self = this; + var deferred = $.Deferred(); + var afterCall = function(data, statusText, xhr) { + var messages = []; + messages = messages.concat(self._checkSecurityHeaders(xhr)); + messages = messages.concat(self._checkSSL(xhr)); + deferred.resolve(messages); + }; + + $.ajax({ + type: 'GET', + url: OC.generateUrl('heartbeat') + }).then(afterCall, afterCall); + + return deferred.promise(); + }, + + /** + * Runs check for some generic security headers on the server side + * + * @param {Object} xhr + * @return {Array} Array with error messages + */ + _checkSecurityHeaders: function(xhr) { + var messages = []; + + if (xhr.status === 200) { + var securityHeaders = { + 'X-XSS-Protection': '1; mode=block', + 'X-Content-Type-Options': 'nosniff', + 'X-Robots-Tag': 'none', + 'X-Frame-Options': 'SAMEORIGIN' + }; + + for (var header in securityHeaders) { + if(xhr.getResponseHeader(header) !== securityHeaders[header]) { + messages.push( + t('core', 'The "{header}" HTTP header is not configured to equal to "{expected}". This is a potential security risk and we recommend adjusting this setting.', {header: header, expected: securityHeaders[header]}) + ); + } + } + } else { + messages.push(t('core', 'Error occurred while checking server setup')); + } + + return messages; + }, + + /** + * Runs check for some SSL configuration issues on the server side + * + * @param {Object} xhr + * @return {Array} Array with error messages + */ + _checkSSL: function(xhr) { + var messages = []; + + if (xhr.status === 200) { + if(OC.getProtocol() === 'https') { + // Extract the value of 'Strict-Transport-Security' + var transportSecurityValidity = xhr.getResponseHeader('Strict-Transport-Security'); + if(transportSecurityValidity !== null && transportSecurityValidity.length > 8) { + var firstComma = transportSecurityValidity.indexOf(";"); + if(firstComma !== -1) { + transportSecurityValidity = transportSecurityValidity.substring(0, firstComma); + } else { + transportSecurityValidity = transportSecurityValidity.substring(8); + } + } + + if(isNaN(transportSecurityValidity) || transportSecurityValidity <= 2678399) { + messages.push( + t('core', 'The "Strict-Transport-Security" HTTP header is not configured to least "2,678,400" seconds. This is a potential security risk and we recommend adjusting this setting.') + ); + } + } else { + messages.push( + t('core', 'You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead.') + ); + } + } else { + messages.push(t('core', 'Error occurred while checking server setup')); + } + + return messages; } }; })(); - diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js new file mode 100644 index 0000000000..487e28a620 --- /dev/null +++ b/core/js/tests/specs/setupchecksSpec.js @@ -0,0 +1,337 @@ +/** + * Copyright (c) 2015 Lukas Reschke + * + * This file is licensed under the Affero General Public License version 3 + * or later. + * + * See the COPYING-README file. + * + */ + +describe('OC.SetupChecks tests', function() { + var suite = this; + var protocolStub; + + beforeEach( function(){ + protocolStub = sinon.stub(OC, 'getProtocol'); + suite.server = sinon.fakeServer.create(); + }); + + afterEach( function(){ + suite.server.restore(); + protocolStub.restore(); + }); + + describe('checkWebDAV', function() { + it('should fail with another response status code than 201 or 207', function(done) { + var async = OC.SetupChecks.checkWebDAV(); + + suite.server.requests[0].respond(200); + + async.done(function( data, s, x ){ + expect(data).toEqual(['Your web server is not yet set up properly to allow file synchronization because the WebDAV interface seems to be broken.']); + done(); + }); + }); + + it('should return no error with a response status code of 207', function(done) { + var async = OC.SetupChecks.checkWebDAV(); + + suite.server.requests[0].respond(207); + + async.done(function( data, s, x ){ + expect(data).toEqual([]); + done(); + }); + }); + + it('should return no error with a response status code of 401', function(done) { + var async = OC.SetupChecks.checkWebDAV(); + + suite.server.requests[0].respond(401); + + async.done(function( data, s, x ){ + expect(data).toEqual([]); + done(); + }); + }); + }); + + describe('checkSetup', function() { + it('should return an error if server has no internet connection', function(done) { + var async = OC.SetupChecks.checkSetup(); + + suite.server.requests[0].respond( + 200, + { + 'Content-Type': 'application/json' + }, + JSON.stringify({data: {serverHasInternetConnection: false}}) + ); + + async.done(function( data, s, x ){ + expect(data).toEqual(['This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features.', 'Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root.']); + done(); + }); + }); + + it('should return an error if server has no internet connection and data directory is not protected', function(done) { + var async = OC.SetupChecks.checkSetup(); + + suite.server.requests[0].respond( + 200, + { + 'Content-Type': 'application/json' + }, + JSON.stringify({data: {serverHasInternetConnection: false, dataDirectoryProtected: false}}) + ); + + async.done(function( data, s, x ){ + expect(data).toEqual(['This server has no working Internet connection. This means that some of the features like mounting external storage, notifications about updates or installation of third-party apps will not work. Accessing files remotely and sending of notification emails might not work, either. We suggest to enable Internet connection for this server if you want to have all features.', 'Your data directory and your files are probably accessible from the Internet. The .htaccess file is not working. We strongly suggest that you configure your web server in a way that the data directory is no longer accessible or you move the data directory outside the web server document root.']); + done(); + }); + }); + + it('should return an error if the response has no statuscode 200', function(done) { + var async = OC.SetupChecks.checkSetup(); + + suite.server.requests[0].respond( + 500, + { + 'Content-Type': 'application/json' + }, + JSON.stringify({data: {serverHasInternetConnection: false, dataDirectoryProtected: false}}) + ); + + async.done(function( data, s, x ){ + expect(data).toEqual(['Error occurred while checking server setup']); + done(); + }); + }); + }); + + describe('checkGeneric', function() { + it('should return an error if the response has no statuscode 200', function(done) { + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond( + 500, + { + 'Content-Type': 'application/json' + } + ); + + async.done(function( data, s, x ){ + expect(data).toEqual(['Error occurred while checking server setup', 'Error occurred while checking server setup']); + done(); + }); + }); + + it('should return all errors if all headers are missing', function(done) { + protocolStub.returns('https'); + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond( + 200, + { + 'Content-Type': 'application/json', + 'Strict-Transport-Security': '2678400' + } + ); + + async.done(function( data, s, x ){ + expect(data).toEqual(['The "X-XSS-Protection" HTTP header is not configured to equal to "1; mode=block". This is a potential security risk and we recommend adjusting this setting.', 'The "X-Content-Type-Options" HTTP header is not configured to equal to "nosniff". This is a potential security risk and we recommend adjusting this setting.', 'The "X-Robots-Tag" HTTP header is not configured to equal to "none". This is a potential security risk and we recommend adjusting this setting.', 'The "X-Frame-Options" HTTP header is not configured to equal to "SAMEORIGIN". This is a potential security risk and we recommend adjusting this setting.']); + done(); + }); + }); + + it('should return only some errors if just some headers are missing', function(done) { + protocolStub.returns('https'); + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond( + 200, + { + 'X-Robots-Tag': 'none', + 'X-Frame-Options': 'SAMEORIGIN', + 'Strict-Transport-Security': '2678400' + + } + ); + + async.done(function( data, s, x ){ + expect(data).toEqual(['The "X-XSS-Protection" HTTP header is not configured to equal to "1; mode=block". This is a potential security risk and we recommend adjusting this setting.', 'The "X-Content-Type-Options" HTTP header is not configured to equal to "nosniff". This is a potential security risk and we recommend adjusting this setting.']); + done(); + }); + }); + + it('should return none errors if all headers are there', function(done) { + protocolStub.returns('https'); + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond( + 200, + { + 'X-XSS-Protection': '1; mode=block', + 'X-Content-Type-Options': 'nosniff', + 'X-Robots-Tag': 'none', + 'X-Frame-Options': 'SAMEORIGIN', + 'Strict-Transport-Security': '2678400' + } + ); + + async.done(function( data, s, x ){ + expect(data).toEqual([]); + done(); + }); + }); + }); + + it('should return a SSL warning if HTTPS is not used', function(done) { + protocolStub.returns('http'); + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond(200, + { + 'X-XSS-Protection': '1; mode=block', + 'X-Content-Type-Options': 'nosniff', + 'X-Robots-Tag': 'none', + 'X-Frame-Options': 'SAMEORIGIN' + } + ); + + async.done(function( data, s, x ){ + expect(data).toEqual(['You are accessing this site via HTTP. We strongly suggest you configure your server to require using HTTPS instead.']); + done(); + }); + }); + + it('should return an error if the response has no statuscode 200', function(done) { + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond( + 500, + { + 'Content-Type': 'application/json' + }, + JSON.stringify({data: {serverHasInternetConnection: false, dataDirectoryProtected: false}}) + ); + async.done(function( data, s, x ){ + expect(data).toEqual(['Error occurred while checking server setup', 'Error occurred while checking server setup']); + done(); + }); + }); + + it('should return a SSL warning if SSL used without Strict-Transport-Security-Header', function(done) { + protocolStub.returns('https'); + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond(200, + { + 'X-XSS-Protection': '1; mode=block', + 'X-Content-Type-Options': 'nosniff', + 'X-Robots-Tag': 'none', + 'X-Frame-Options': 'SAMEORIGIN' + } + ); + + async.done(function( data, s, x ){ + expect(data).toEqual(['The "Strict-Transport-Security" HTTP header is not configured to least "2,678,400" seconds. This is a potential security risk and we recommend adjusting this setting.']); + done(); + }); + }); + + it('should return a SSL warning if SSL used with to small Strict-Transport-Security-Header', function(done) { + protocolStub.returns('https'); + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond(200, + { + 'Strict-Transport-Security': '2678399', + 'X-XSS-Protection': '1; mode=block', + 'X-Content-Type-Options': 'nosniff', + 'X-Robots-Tag': 'none', + 'X-Frame-Options': 'SAMEORIGIN' + } + ); + + async.done(function( data, s, x ){ + expect(data).toEqual(['The "Strict-Transport-Security" HTTP header is not configured to least "2,678,400" seconds. This is a potential security risk and we recommend adjusting this setting.']); + done(); + }); + }); + + it('should return a SSL warning if SSL used with to a bogus Strict-Transport-Security-Header', function(done) { + protocolStub.returns('https'); + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond(200, + { + 'Strict-Transport-Security': 'iAmABogusHeader342', + 'X-XSS-Protection': '1; mode=block', + 'X-Content-Type-Options': 'nosniff', + 'X-Robots-Tag': 'none', + 'X-Frame-Options': 'SAMEORIGIN' + } + ); + + async.done(function( data, s, x ){ + expect(data).toEqual(['The "Strict-Transport-Security" HTTP header is not configured to least "2,678,400" seconds. This is a potential security risk and we recommend adjusting this setting.']); + done(); + }); + }); + + it('should return no SSL warning if SSL used with to exact the minimum Strict-Transport-Security-Header', function(done) { + protocolStub.returns('https'); + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond(200, { + 'Strict-Transport-Security': '2678400', + 'X-XSS-Protection': '1; mode=block', + 'X-Content-Type-Options': 'nosniff', + 'X-Robots-Tag': 'none', + 'X-Frame-Options': 'SAMEORIGIN' + }); + + async.done(function( data, s, x ){ + expect(data).toEqual([]); + done(); + }); + }); + + it('should return no SSL warning if SSL used with to more than the minimum Strict-Transport-Security-Header', function(done) { + protocolStub.returns('https'); + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond(200, { + 'Strict-Transport-Security': '12678400', + 'X-XSS-Protection': '1; mode=block', + 'X-Content-Type-Options': 'nosniff', + 'X-Robots-Tag': 'none', + 'X-Frame-Options': 'SAMEORIGIN' + }); + + async.done(function( data, s, x ){ + expect(data).toEqual([]); + done(); + }); + }); + + it('should return no SSL warning if SSL used with to more than the minimum Strict-Transport-Security-Header and includeSubDomains parameter', function(done) { + protocolStub.returns('https'); + var async = OC.SetupChecks.checkGeneric(); + + suite.server.requests[0].respond(200, { + 'Strict-Transport-Security': '12678400; includeSubDomains', + 'X-XSS-Protection': '1; mode=block', + 'X-Content-Type-Options': 'nosniff', + 'X-Robots-Tag': 'none', + 'X-Frame-Options': 'SAMEORIGIN' + }); + + async.done(function( data, s, x ){ + expect(data).toEqual([]); + done(); + }); + }); +}); diff --git a/lib/base.php b/lib/base.php index 1f2e90deef..84616090ec 100644 --- a/lib/base.php +++ b/lib/base.php @@ -247,34 +247,6 @@ class OC { } } - public static function checkSSL() { - $request = \OC::$server->getRequest(); - - // redirect to https site if configured - if (\OC::$server->getSystemConfig()->getValue('forcessl', false)) { - // Default HSTS policy - $header = 'Strict-Transport-Security: max-age=31536000'; - - // If SSL for subdomains is enabled add "; includeSubDomains" to the header - if(\OC::$server->getSystemConfig()->getValue('forceSSLforSubdomains', false)) { - $header .= '; includeSubDomains'; - } - header($header); - ini_set('session.cookie_secure', true); - - if ($request->getServerProtocol() <> 'https' && !OC::$CLI) { - $url = 'https://' . $request->getServerHost() . $request->getRequestUri(); - header("Location: $url"); - exit(); - } - } else { - // Invalidate HSTS headers - if ($request->getServerProtocol() === 'https') { - header('Strict-Transport-Security: max-age=0'); - } - } - } - public static function checkMaintenanceMode() { // Allow ajax update script to execute without being stopped if (\OC::$server->getSystemConfig()->getValue('maintenance', false) && OC::$SUBURI != '/core/ajax/update.php') { @@ -569,8 +541,11 @@ class OC { self::initTemplateEngine(); self::checkConfig(); self::checkInstalled(); - self::checkSSL(); + OC_Response::addSecurityHeaders(); + if(self::$server->getRequest()->getServerProtocol() === 'https') { + ini_set('session.cookie_secure', true); + } $errors = OC_Util::checkServer(\OC::$server->getConfig()); if (count($errors) > 0) { diff --git a/lib/private/appframework/app.php b/lib/private/appframework/app.php index 6d54b931d5..1e1915c85d 100644 --- a/lib/private/appframework/app.php +++ b/lib/private/appframework/app.php @@ -123,7 +123,7 @@ class App { $expireDate, $container->getServer()->getWebRoot(), null, - $container->getServer()->getConfig()->getSystemValue('forcessl', false), + $container->getServer()->getRequest()->getServerProtocol() === 'https', true ); } diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index f6a89b358d..b1b4b71328 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -475,7 +475,7 @@ class Request implements \ArrayAccess, \Countable, IRequest { private function isOverwriteCondition($type = '') { $regex = '/' . $this->config->getSystemValue('overwritecondaddr', '') . '/'; return $regex === '//' || preg_match($regex, $this->server['REMOTE_ADDR']) === 1 - || ($type !== 'protocol' && $this->config->getSystemValue('forcessl', false)); + || $type !== 'protocol'; } /** diff --git a/lib/private/response.php b/lib/private/response.php index 600b702810..2bec5e3dec 100644 --- a/lib/private/response.php +++ b/lib/private/response.php @@ -195,15 +195,6 @@ class OC_Response { * components (e.g. SabreDAV) also benefit from this headers. */ public static function addSecurityHeaders() { - header('X-XSS-Protection: 1; mode=block'); // Enforce browser based XSS filters - header('X-Content-Type-Options: nosniff'); // Disable sniffing the content type for IE - - // iFrame Restriction Policy - $xFramePolicy = OC_Config::getValue('xframe_restriction', true); - if ($xFramePolicy) { - header('X-Frame-Options: Sameorigin'); // Disallow iFraming from other domains - } - /** * FIXME: Content Security Policy for legacy ownCloud components. This * can be removed once \OCP\AppFramework\Http\Response from the AppFramework @@ -219,9 +210,6 @@ class OC_Response { . 'media-src *; ' . 'connect-src *'; header('Content-Security-Policy:' . $policy); - - // https://developers.google.com/webmasters/control-crawl-index/docs/robots_meta_tag - header('X-Robots-Tag: none'); } } diff --git a/lib/private/user/session.php b/lib/private/user/session.php index 67a4c7a436..a756795205 100644 --- a/lib/private/user/session.php +++ b/lib/private/user/session.php @@ -265,7 +265,7 @@ class Session implements IUserSession, Emitter { * @param string $token */ public function setMagicInCookie($username, $token) { - $secureCookie = \OC_Config::getValue("forcessl", false); //TODO: DI for cookies and OC_Config + $secureCookie = \OC::$server->getRequest()->getServerProtocol() === 'https'; $expires = time() + \OC_Config::getValue('remember_login_cookie_lifetime', 60 * 60 * 24 * 15); setcookie("oc_username", $username, $expires, \OC::$WEBROOT, '', $secureCookie, true); setcookie("oc_token", $token, $expires, \OC::$WEBROOT, '', $secureCookie, true); diff --git a/settings/admin.php b/settings/admin.php index 95940db728..da25ab55a9 100644 --- a/settings/admin.php +++ b/settings/admin.php @@ -58,11 +58,6 @@ $excludedGroupsList = $appConfig->getValue('core', 'shareapi_exclude_groups_list $excludedGroupsList = explode(',', $excludedGroupsList); // FIXME: this should be JSON! $template->assign('shareExcludedGroupsList', implode('|', $excludedGroupsList)); -// Check if connected using HTTPS -$template->assign('isConnectedViaHTTPS', $request->getServerProtocol() === 'https'); -$template->assign('enforceHTTPSEnabled', $config->getSystemValue('forcessl', false)); -$template->assign('forceSSLforSubdomainsEnabled', $config->getSystemValue('forceSSLforSubdomains', false)); - // If the current web root is non-empty but the web root from the config is, // and system cron is used, the URL generator fails to build valid URLs. $shouldSuggestOverwriteCliUrl = $config->getAppValue('core', 'backgroundjobs_mode', 'ajax') === 'cron' && diff --git a/settings/controller/securitysettingscontroller.php b/settings/controller/securitysettingscontroller.php index af60df8dc3..50e70ebb70 100644 --- a/settings/controller/securitysettingscontroller.php +++ b/settings/controller/securitysettingscontroller.php @@ -42,43 +42,6 @@ class SecuritySettingsController extends Controller { ); } - /** - * @return array - */ - protected function returnError() { - return array( - 'status' => 'error' - ); - } - - /** - * Enforce or disable the enforcement of SSL - * @param boolean $enforceHTTPS Whether SSL should be enforced - * @return array - */ - public function enforceSSL($enforceHTTPS = false) { - if(!is_bool($enforceHTTPS)) { - return $this->returnError(); - } - $this->config->setSystemValue('forcessl', $enforceHTTPS); - - return $this->returnSuccess(); - } - - /** - * Enforce or disable the enforcement for SSL on subdomains - * @param bool $forceSSLforSubdomains Whether SSL on subdomains should be enforced - * @return array - */ - public function enforceSSLForSubdomains($forceSSLforSubdomains = false) { - if(!is_bool($forceSSLforSubdomains)) { - return $this->returnError(); - } - $this->config->setSystemValue('forceSSLforSubdomains', $forceSSLforSubdomains); - - return $this->returnSuccess(); - } - /** * Add a new trusted domain * @param string $newTrustedDomain The newly to add trusted domain diff --git a/settings/js/admin.js b/settings/js/admin.js index 34bc246604..9fe4226827 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -75,32 +75,6 @@ $(document).ready(function(){ $('#setDefaultExpireDate').toggleClass('hidden', !(this.checked && $('#shareapiDefaultExpireDate')[0].checked)); }); - $('#forcessl').change(function(){ - $(this).val(($(this).val() !== 'true')); - var forceSSLForSubdomain = $('#forceSSLforSubdomainsSpan'); - - $.post(OC.generateUrl('settings/admin/security/ssl'), { - enforceHTTPS: $(this).val() - },function(){} ); - - if($(this).val() === 'true') { - forceSSLForSubdomain.prop('disabled', false); - forceSSLForSubdomain.removeClass('hidden'); - } else { - forceSSLForSubdomain.prop('disabled', true); - forceSSLForSubdomain.addClass('hidden'); - } - }); - - $('#forceSSLforSubdomains').change(function(){ - $(this).val(($(this).val() !== 'true')); - - $.post(OC.generateUrl('settings/admin/security/ssl/subdomains'), { - forceSSLforSubdomains: $(this).val() - },function(){} ); - }); - - $('#mail_smtpauth').change(function() { if (!this.checked) { $('#mail_credentials').addClass('hidden'); @@ -158,9 +132,10 @@ $(document).ready(function(){ // run setup checks then gather error messages $.when( OC.SetupChecks.checkWebDAV(), - OC.SetupChecks.checkSetup() - ).then(function(check1, check2) { - var errors = [].concat(check1, check2); + OC.SetupChecks.checkSetup(), + OC.SetupChecks.checkGeneric() + ).then(function(check1, check2, check3) { + var errors = [].concat(check1, check2, check3); var $el = $('#postsetupchecks'); var $errorsEl; $el.find('.loading').addClass('hidden'); diff --git a/settings/routes.php b/settings/routes.php index 942d9b0fb2..ea49cc24eb 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -20,8 +20,6 @@ $application->registerRoutes($this, array( array('name' => 'MailSettings#sendTestMail', 'url' => '/settings/admin/mailtest', 'verb' => 'POST'), array('name' => 'AppSettings#listCategories', 'url' => '/settings/apps/categories', 'verb' => 'GET'), array('name' => 'AppSettings#listApps', 'url' => '/settings/apps/list', 'verb' => 'GET'), - array('name' => 'SecuritySettings#enforceSSL', 'url' => '/settings/admin/security/ssl', 'verb' => 'POST'), - array('name' => 'SecuritySettings#enforceSSLForSubdomains', 'url' => '/settings/admin/security/ssl/subdomains', 'verb' => 'POST'), array('name' => 'SecuritySettings#trustedDomains', 'url' => '/settings/admin/security/trustedDomains', 'verb' => 'POST'), array('name' => 'Users#setMailAddress', 'url' => '/settings/users/{id}/mailAddress', 'verb' => 'PUT'), array('name' => 'LogSettings#setLogLevel', 'url' => '/settings/admin/log/level', 'verb' => 'POST'), diff --git a/settings/templates/admin.php b/settings/templates/admin.php index 1608aa8123..b6326108bf 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -66,20 +66,6 @@ if ($_['mail_smtpmode'] == 'qmail') {
-
-

t('Security Warning'));?>

- - - t('You are accessing %s via HTTP. We strongly suggest you configure your server to require using HTTPS instead.', $theme->getTitle())); ?> - - -
- @@ -370,51 +356,6 @@ if ($_['cronErrors']) {

-
-

t('Security'));?>

-

- - /> -
- t( - 'Forces the clients to connect to %s via an encrypted connection.', - $theme->getName() - )); ?>
- > - - /> -
- t( - 'Forces the clients to connect to %s and subdomains via an encrypted connection.', - $theme->getName() - )); ?> -
- "); - p($l->t( - 'Please connect to your %s via HTTPS to enable or disable the SSL enforcement.', - $theme->getName() - )); - print_unescaped(""); - } - ?> -

-
-

t('Email Server'));?>

diff --git a/tests/settings/controller/securitysettingscontrollertest.php b/tests/settings/controller/securitysettingscontrollertest.php index d89e493236..56848d8df3 100644 --- a/tests/settings/controller/securitysettingscontrollertest.php +++ b/tests/settings/controller/securitysettingscontrollertest.php @@ -31,77 +31,6 @@ class SecuritySettingsControllerTest extends \PHPUnit_Framework_TestCase { $this->securitySettingsController = $this->container['SecuritySettingsController']; } - - public function testEnforceSSLEmpty() { - $this->container['Config'] - ->expects($this->once()) - ->method('setSystemValue') - ->with('forcessl', false); - - $response = $this->securitySettingsController->enforceSSL(); - $expectedResponse = array('status' => 'success'); - - $this->assertSame($expectedResponse, $response); - } - - public function testEnforceSSL() { - $this->container['Config'] - ->expects($this->once()) - ->method('setSystemValue') - ->with('forcessl', true); - - $response = $this->securitySettingsController->enforceSSL(true); - $expectedResponse = array('status' => 'success'); - - $this->assertSame($expectedResponse, $response); - } - - public function testEnforceSSLInvalid() { - $this->container['Config'] - ->expects($this->exactly(0)) - ->method('setSystemValue'); - - $response = $this->securitySettingsController->enforceSSL('blah'); - $expectedResponse = array('status' => 'error'); - - $this->assertSame($expectedResponse, $response); - } - - public function testEnforceSSLForSubdomainsEmpty() { - $this->container['Config'] - ->expects($this->once()) - ->method('setSystemValue') - ->with('forceSSLforSubdomains', false); - - $response = $this->securitySettingsController->enforceSSLForSubdomains(); - $expectedResponse = array('status' => 'success'); - - $this->assertSame($expectedResponse, $response); - } - - public function testEnforceSSLForSubdomains() { - $this->container['Config'] - ->expects($this->once()) - ->method('setSystemValue') - ->with('forceSSLforSubdomains', true); - - $response = $this->securitySettingsController->enforceSSLForSubdomains(true); - $expectedResponse = array('status' => 'success'); - - $this->assertSame($expectedResponse, $response); - } - - public function testEnforceSSLForSubdomainsInvalid() { - $this->container['Config'] - ->expects($this->exactly(0)) - ->method('setSystemValue'); - - $response = $this->securitySettingsController->enforceSSLForSubdomains('blah'); - $expectedResponse = array('status' => 'error'); - - $this->assertSame($expectedResponse, $response); - } - public function testTrustedDomainsWithExistingValues() { $this->container['Config'] ->expects($this->once())