diff options
| -rw-r--r-- | src/leap/bitmask/gui/mainwindow.py | 3 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/preferenceswindow.py | 153 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/ui/preferences.ui | 75 | 
3 files changed, 217 insertions, 14 deletions
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 7b9d492e..25747785 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -419,7 +419,8 @@ class MainWindow(QtGui.QMainWindow):          Displays the preferences window.          """ -        PreferencesWindow(self, self._srp_auth, self._soledad).show() +        PreferencesWindow( +            self, self._srp_auth, self._soledad, self._settings).show()      def _uncheck_logger_button(self):          """ diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index a8220e86..2b48b54c 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -18,15 +18,18 @@  """  Preferences window  """ +import os  import logging  from functools import partial -from PySide import QtGui +from PySide import QtCore, QtGui  from leap.bitmask.gui.ui_preferences import Ui_Preferences  from leap.soledad.client import NoStorageSecret  from leap.bitmask.crypto.srpauth import SRPAuthBadPassword  from leap.bitmask.util.password import basic_password_checks +from leap.bitmask.services import get_supported +from leap.bitmask.config.providerconfig import ProviderConfig  logger = logging.getLogger(__name__) @@ -38,7 +41,7 @@ class PreferencesWindow(QtGui.QDialog):      WEAK_PASSWORDS = ("123456", "qweasd", "qwerty", "password") -    def __init__(self, parent, srp_auth, soledad): +    def __init__(self, parent, srp_auth, soledad, leap_settings):          """          :param parent: parent object of the PreferencesWindow.          :parent type: QWidget @@ -51,14 +54,39 @@ class PreferencesWindow(QtGui.QDialog):          self._srp_auth = srp_auth          self._soledad = soledad +        self._settings = leap_settings          # Load UI          self.ui = Ui_Preferences()          self.ui.setupUi(self)          self.ui.lblPasswordChangeStatus.setVisible(False) +        self.ui.lblProvidersServicesStatus.setVisible(False) + +        # Correspondence for services and their name to display +        EIP_LABEL = self.tr("Encrypted Internet") +        MX_LABEL = self.tr("Encrypted Mail") + +        self.SERVICE_DISPLAY = [ +            EIP_LABEL, +            MX_LABEL +        ] +        self.SERVICE_CONFIG = [ +            "openvpn", +            "mx" +        ] + +        self._selected_services = set() +        self._provider_config = ProviderConfig()          # Connections          self.ui.pbChangePassword.clicked.connect(self._change_password) +        self.ui.cbProvidersServices.currentIndexChanged[unicode].connect( +            self._populate_services) + +        if not self._settings.get_configured_providers(): +            self.ui.gbEnabledServices.setEnabled(False) +        else: +            self._add_configured_providers()      def _set_password_change_status(self, status, error=False, success=False):          """ @@ -134,7 +162,7 @@ class PreferencesWindow(QtGui.QDialog):          self._set_password_change_status(              self.tr("Password changed successfully."), success=True) -        self._clear_inputs() +        self._clear_password_inputs()          self._set_changing_password(False)      def _change_password_problem(self, failure): @@ -156,10 +184,127 @@ class PreferencesWindow(QtGui.QDialog):          self._set_changing_password(False)          failure.trap(Exception) -    def _clear_inputs(self): +    def _clear_password_inputs(self):          """          Clear the contents of the inputs.          """          self.ui.leCurrentPassword.setText("")          self.ui.leNewPassword.setText("")          self.ui.leNewPassword2.setText("") + +    def _set_providers_services_status(self, status, success=False): +        """ +        Sets the status label for the password change. + +        :param status: status message to display, can be HTML +        :type status: str +        """ +        if success: +            status = "<font color='green'><b>%s</b></font>" % (status,) + +        self.ui.lblProvidersServicesStatus.setVisible(True) +        self.ui.lblProvidersServicesStatus.setText(status) + +    def _add_configured_providers(self): +        """ +        Add the client's configured providers to the providers combo boxes. +        """ +        self.ui.cbProvidersServices.clear() +        self.ui.cbProvidersGateway.clear() +        for provider in self._settings.get_configured_providers(): +            self.ui.cbProvidersServices.addItem(provider) +            self.ui.cbProvidersGateway.addItem(provider) + +    def _service_selection_changed(self, service, state): +        """ +        SLOT +        TRIGGER: service_checkbox.stateChanged +        Adds the service to the state if the state is checked, removes +        it otherwise + +        :param service: service to handle +        :type service: str +        :param state: state of the checkbox +        :type state: int +        """ +        if state == QtCore.Qt.Checked: +            self._selected_services = \ +                self._selected_services.union(set([service])) +        else: +            self._selected_services = \ +                self._selected_services.difference(set([service])) + +        # We hide the maybe-visible status label after a change +        self.ui.lblProvidersServicesStatus.setVisible(False) + +    def _populate_services(self, domain): +        """ +        SLOT +        TRIGGERS: +            self.ui.cbProvidersServices.clicked + +        Loads the services that the provider provides into the UI for +        the user to enable or disable. + +        :param domain: the domain of the provider to load services from. +        :type domain: str +        """ +        # We hide the maybe-visible status label after a change +        self.ui.lblProvidersServicesStatus.setVisible(False) + +        provider_config_path = os.path.join( +            "leap", "providers", domain, "provider.json") + +        if not domain or not self._provider_config.load(provider_config_path): +            return + +        # set the proper connection for the 'save' button +        try: +            self.ui.pbSaveServices.clicked.disconnect() +        except RuntimeError: +            pass  # Signal was not connected + +        save_services = partial(self._save_enabled_services, domain) +        self.ui.pbSaveServices.clicked.connect(save_services) + +        services = get_supported(self._provider_config.get_services()) +        services_conf = self._settings.get_enabled_services(domain) + +        # discard changes if other provider is selected +        self._selected_services = set() + +        # from: http://stackoverflow.com/a/13103617/687989 +        # remove existing checkboxes +        layout = self.ui.vlServices +        for i in reversed(range(layout.count())): +            layout.itemAt(i).widget().setParent(None) + +        # add one checkbox per service and set the current configured value +        for service in services: +            try: +                checkbox = QtGui.QCheckBox(self) +                service_index = self.SERVICE_CONFIG.index(service) +                checkbox.setText(self.SERVICE_DISPLAY[service_index]) +                self.ui.vlServices.addWidget(checkbox) +                checkbox.stateChanged.connect( +                    partial(self._service_selection_changed, service)) + +                checkbox.setChecked(service in services_conf) +            except ValueError: +                logger.error("Something went wrong while trying to " +                             "load service %s" % (service,)) + +    def _save_enabled_services(self, provider): +        """ +        Saves the new settings to the configuration file. + +        :param provider: the provider config that we need to save. +        :type provider: str +        """ +        services = list(self._selected_services) +        self._settings.set_enabled_services(provider, services) + +        msg = self.tr( +            "Services settings for provider '{0}' saved.".format(provider)) +        logger.debug(msg) +        self._set_providers_services_status(msg, success=True) diff --git a/src/leap/bitmask/gui/ui/preferences.ui b/src/leap/bitmask/gui/ui/preferences.ui index 8c63ccad..1f9ef4c4 100644 --- a/src/leap/bitmask/gui/ui/preferences.ui +++ b/src/leap/bitmask/gui/ui/preferences.ui @@ -6,8 +6,8 @@     <rect>      <x>0</x>      <y>0</y> -    <width>451</width> -    <height>267</height> +    <width>453</width> +    <height>463</height>     </rect>    </property>    <property name="windowTitle"> @@ -17,8 +17,8 @@     <iconset resource="../../../../../data/resources/mainwindow.qrc">      <normaloff>:/images/mask-icon.png</normaloff>:/images/mask-icon.png</iconset>    </property> -  <layout class="QVBoxLayout" name="verticalLayout"> -   <item> +  <layout class="QGridLayout" name="gridLayout_3"> +   <item row="0" column="0">      <widget class="QGroupBox" name="gbPasswordChange">       <property name="title">        <string>Password Change</string> @@ -98,7 +98,64 @@       </layout>      </widget>     </item> -   <item> +   <item row="2" column="0"> +    <widget class="QGroupBox" name="gbEnabledServices"> +     <property name="title"> +      <string>Enabled services</string> +     </property> +     <layout class="QGridLayout" name="gridLayout_2"> +      <item row="3" column="1"> +       <widget class="QPushButton" name="pbSaveServices"> +        <property name="text"> +         <string>Save this provider settings</string> +        </property> +       </widget> +      </item> +      <item row="2" column="0" colspan="2"> +       <widget class="QGroupBox" name="gbServices"> +        <property name="title"> +         <string>Services</string> +        </property> +        <property name="flat"> +         <bool>false</bool> +        </property> +        <layout class="QGridLayout" name="gridLayout_4"> +         <item row="0" column="0"> +          <layout class="QVBoxLayout" name="vlServices"/> +         </item> +        </layout> +       </widget> +      </item> +      <item row="0" column="1"> +       <widget class="QComboBox" name="cbProvidersServices"> +        <item> +         <property name="text"> +          <string><Select provider></string> +         </property> +        </item> +       </widget> +      </item> +      <item row="0" column="0"> +       <widget class="QLabel" name="label_2"> +        <property name="text"> +         <string>Select provider:</string> +        </property> +       </widget> +      </item> +      <item row="1" column="0" colspan="2"> +       <widget class="QLabel" name="lblProvidersServicesStatus"> +        <property name="text"> +         <string>< Providers Services Status ></string> +        </property> +        <property name="alignment"> +         <set>Qt::AlignCenter</set> +        </property> +       </widget> +      </item> +     </layout> +    </widget> +   </item> +   <item row="1" column="0">      <widget class="QGroupBox" name="gbGatewaySelector">       <property name="enabled">        <bool>false</bool> @@ -116,12 +173,12 @@           <string>&Select provider:</string>          </property>          <property name="buddy"> -         <cstring>cbProviders</cstring> +         <cstring>cbProvidersGateway</cstring>          </property>         </widget>        </item>        <item row="0" column="1"> -       <widget class="QComboBox" name="cbProviders"> +       <widget class="QComboBox" name="cbProvidersGateway">          <item>           <property name="text">            <string><Select provider></string> @@ -137,7 +194,7 @@         </widget>        </item>        <item row="1" column="1"> -       <widget class="QComboBox" name="comboBox"> +       <widget class="QComboBox" name="cbGateways">          <item>           <property name="text">            <string>Automatic</string> @@ -148,7 +205,7 @@       </layout>      </widget>     </item> -   <item> +   <item row="3" column="0">      <spacer name="verticalSpacer">       <property name="orientation">        <enum>Qt::Vertical</enum>  | 
