diff --git a/Duplicati/Server/Database/ServerSettings.cs b/Duplicati/Server/Database/ServerSettings.cs index 4e221f6d0..8104bb175 100644 --- a/Duplicati/Server/Database/ServerSettings.cs +++ b/Duplicati/Server/Database/ServerSettings.cs @@ -50,8 +50,9 @@ namespace Duplicati.Server.Database public const string SERVER_SSL_CERTIFICATE = "server-ssl-certificate"; public const string HAS_FIXED_INVALID_BACKUPID = "has-fixed-invalid-backup-id"; public const string UPDATE_CHANNEL = "update-channel"; - public const string USAGE_REPORTER_LEVEL = "usage-reporter-level"; - } + public const string USAGE_REPORTER_LEVEL = "usage-reporter-level"; + public const string HAS_ASKED_FOR_PASSWORD_PROTECTION = "has-asked-for-password-protection"; + } private Dictionary m_values; private Database.Connection m_connection; @@ -199,9 +200,27 @@ namespace Duplicati.Server.Database m_values[CONST.IS_FIRST_RUN] = value.ToString(); SaveSettings(); } - } - - public bool UnackedError + } + + public bool HasAskedForPasswordProtection + { + get + { + var tp = m_values[CONST.HAS_ASKED_FOR_PASSWORD_PROTECTION]; + if (string.IsNullOrEmpty(tp)) + return true; + + return Duplicati.Library.Utility.Utility.ParseBoolOption(m_values, CONST.HAS_ASKED_FOR_PASSWORD_PROTECTION); + } + set + { + lock (m_connection.m_lock) + m_values[CONST.HAS_ASKED_FOR_PASSWORD_PROTECTION] = value.ToString(); + SaveSettings(); + } + } + + public bool UnackedError { get { diff --git a/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js b/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js index d99756f3c..9d93e9aad 100644 --- a/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js +++ b/Duplicati/Server/webroot/ngax/scripts/controllers/AppController.js @@ -163,5 +163,21 @@ backupApp.controller('AppController', function($scope, $cookies, $location, AppS var dt = data.data['max-download-speed']; $scope.throttle_active = (ut != null && ut.trim().length != 0) || (dt != null && dt.trim().length != 0); + var firstpw = data.data['has-asked-for-password-protection']; + var haspw = data.data['server-passphrase']; + if (!firstpw && haspw == '') { + DialogService.dialog( + gettextCatalog.getString('First run setup'), + gettextCatalog.getString('If your machine is in a multi-user environment (i.e. the machine has more than one account), you need to set a password to prevent other users from accessing data on your account.\nDo you want to set a password now?'), + [gettextCatalog.getString('No, my machine has only a single account'), gettextCatalog.getString('Yes')], + function(btn) { + AppService.patch('/serversettings', { 'has-asked-for-password-protection': 'true'}, {'headers': {'Content-Type': 'application/json'}}); + if (btn == 1) { + $location.path('/settings'); + } + } + ); + } + }, AppUtils.connectionError); }); diff --git a/guiTests/guiTest.py b/guiTests/guiTest.py index 4900ea93f..9a6695791 100644 --- a/guiTests/guiTest.py +++ b/guiTests/guiTest.py @@ -97,6 +97,9 @@ write_random_file(1024 * 1024, SOURCE_FOLDER + os.sep + "1MB.test") write_random_file(100 * 1024, SOURCE_FOLDER + os.sep + "subfolder" + os.sep + "100KB.test") sha1_source = sha1_folder(SOURCE_FOLDER) +# Dismiss the password request +driver.find_element_by_link_text("No, my machine has only a single account").click() + # Add new backup driver.find_element_by_link_text("Add backup").click()