diff --git a/onionshare/settings.py b/onionshare/settings.py index 7699d91f..c3b49ae8 100644 --- a/onionshare/settings.py +++ b/onionshare/settings.py @@ -33,15 +33,28 @@ class Settings(object): self.filename = self.build_filename() # These are the default settings. They will get overwritten when loading from disk - self._settings = { + self.default_settings = { 'version': helpers.get_version(), 'connection_type': 'automatic', 'control_port_address': '127.0.0.1', 'control_port_port': 9051, 'socket_file_path': '/var/run/tor/control', 'auth_type': 'no_auth', - 'auth_password': '' + 'auth_password': '', + 'close_after_first_download': True, + 'use_stealth': False } + self._settings = {} + self.fill_in_defaults() + + def fill_in_defaults(self): + """ + If there are any missing settings from self._settings, replace them with + their default values. + """ + for key in self.default_settings: + if key not in self._settings: + self._settings[key] = self.default_settings[key] def build_filename(self): """ @@ -64,6 +77,7 @@ class Settings(object): if os.path.exists(self.filename): try: self._settings = json.loads(open(self.filename, 'r').read()) + self.fill_in_defaults() except: pass diff --git a/onionshare_gui/settings_dialog.py b/onionshare_gui/settings_dialog.py index 521abbcc..7c3c3a5d 100644 --- a/onionshare_gui/settings_dialog.py +++ b/onionshare_gui/settings_dialog.py @@ -35,6 +35,37 @@ class SettingsDialog(QtWidgets.QDialog): self.setModal(True) self.setWindowTitle(strings._('gui_settings_window_title', True)) + # Sharing options + + # Close after first download + self.close_after_first_download_checkbox = QtWidgets.QCheckBox() + self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked) + self.close_after_first_download_checkbox.setText(strings._("gui_settings_close_after_first_download_option", True)) + + # Sharing options layout + sharing_group_layout = QtWidgets.QVBoxLayout() + sharing_group_layout.addWidget(self.close_after_first_download_checkbox) + sharing_group = QtWidgets.QGroupBox(strings._("gui_settings_sharing_label", True)) + sharing_group.setLayout(sharing_group_layout) + + + # Stealth options + + # Stealth + stealth_details = QtWidgets.QLabel(strings._("gui_settings_stealth_option_details", True)) + stealth_details.setWordWrap(True) + self.stealth_checkbox = QtWidgets.QCheckBox() + self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) + self.stealth_checkbox.setText(strings._("gui_settings_stealth_option", True)) + + # Stealth options layout + stealth_group_layout = QtWidgets.QVBoxLayout() + stealth_group_layout.addWidget(stealth_details) + stealth_group_layout.addWidget(self.stealth_checkbox) + stealth_group = QtWidgets.QGroupBox(strings._("gui_settings_stealth_label", True)) + stealth_group.setLayout(stealth_group_layout) + + # Connection type: either automatic, control port, or socket file # Automatic @@ -125,6 +156,8 @@ class SettingsDialog(QtWidgets.QDialog): # Layout layout = QtWidgets.QVBoxLayout() + layout.addWidget(sharing_group) + layout.addWidget(stealth_group) layout.addWidget(connection_type_group) layout.addWidget(self.authenticate_group) layout.addStretch() @@ -136,6 +169,18 @@ class SettingsDialog(QtWidgets.QDialog): settings = Settings() settings.load() + close_after_first_download = settings.get('close_after_first_download') + if close_after_first_download: + self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked) + else: + self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Unchecked) + + use_stealth = settings.get('use_stealth') + if use_stealth: + self.stealth_checkbox.setCheckState(QtCore.Qt.Checked) + else: + self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) + connection_type = settings.get('connection_type') if connection_type == 'automatic': self.connection_type_automatic_radio.setChecked(True) @@ -162,9 +207,9 @@ class SettingsDialog(QtWidgets.QDialog): fields. If unchecked, enable all other fields. """ if checked: - self.authenticate_group.setEnabled(False) + self.authenticate_group.hide() else: - self.authenticate_group.setEnabled(True) + self.authenticate_group.show() def connection_type_control_port_toggled(self, checked): """ @@ -239,6 +284,9 @@ class SettingsDialog(QtWidgets.QDialog): """ settings = Settings() + settings.set('close_after_first_download', self.close_after_first_download_checkbox.isChecked()) + settings.set('use_stealth', self.stealth_checkbox.isChecked()) + if self.connection_type_automatic_radio.isChecked(): settings.set('connection_type', 'automatic') if self.connection_type_control_port_radio.isChecked(): diff --git a/share/locale/en.json b/share/locale/en.json index 34e0f254..62f45d78 100644 --- a/share/locale/en.json +++ b/share/locale/en.json @@ -59,6 +59,11 @@ "gui_menu_settings_action": "&Settings", "gui_menu_quit_action": "&Quit", "gui_settings_window_title": "Settings", + "gui_settings_stealth_label": "Stealth (advanced)", + "gui_settings_stealth_option": "Create stealth onion services", + "gui_settings_stealth_option_details": "This makes OnionShare more secure, but also more difficult for the recipient to connect to it.
More information.", + "gui_settings_sharing_label": "Sharing options", + "gui_settings_close_after_first_download_option": "Stop sharing after first download", "gui_settings_connection_type_label": "How should OnionShare connect to Tor?", "gui_settings_connection_type_automatic_option": "Attempt automatic configuration with Tor Browser", "gui_settings_connection_type_control_port_option": "Connect using control port",