diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | changes/bug-4984_update-menu-name-in-wizard | 1 | ||||
| -rw-r--r-- | changes/bug-4995_error-on-every-logout | 1 | ||||
| -rw-r--r-- | changes/bug_5083_sync_soledad_only_on_account_create | 3 | ||||
| -rw-r--r-- | changes/feature_5095_ensure-imap-flushes-data-before-quitting | 1 | ||||
| -rw-r--r-- | src/leap/bitmask/app.py | 7 | ||||
| -rw-r--r-- | src/leap/bitmask/config/leapsettings.py | 14 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/mainwindow.py | 16 | ||||
| -rw-r--r-- | src/leap/bitmask/gui/ui/wizard.ui | 2 | ||||
| -rw-r--r-- | src/leap/bitmask/services/mail/conductor.py | 14 | ||||
| -rw-r--r-- | src/leap/bitmask/services/soledad/soledadbootstrapper.py | 15 | ||||
| -rw-r--r-- | src/leap/bitmask/util/__init__.py | 5 | ||||
| -rw-r--r-- | src/leap/bitmask/util/leap_log_handler.py | 7 | 
13 files changed, 64 insertions, 23 deletions
@@ -2,6 +2,7 @@  *.swo  *.pyc  *.log +*.lprof  *.*~  .*  *_rc.py diff --git a/changes/bug-4984_update-menu-name-in-wizard b/changes/bug-4984_update-menu-name-in-wizard new file mode 100644 index 00000000..9048951a --- /dev/null +++ b/changes/bug-4984_update-menu-name-in-wizard @@ -0,0 +1 @@ +- Update menu name in Wizard. Closes #4984. diff --git a/changes/bug-4995_error-on-every-logout b/changes/bug-4995_error-on-every-logout new file mode 100644 index 00000000..beb4e4c2 --- /dev/null +++ b/changes/bug-4995_error-on-every-logout @@ -0,0 +1 @@ +- Fix "Something went wrong with the logout" misleading error in every logout. Closes #4995 and #5071. diff --git a/changes/bug_5083_sync_soledad_only_on_account_create b/changes/bug_5083_sync_soledad_only_on_account_create new file mode 100644 index 00000000..6deaa41f --- /dev/null +++ b/changes/bug_5083_sync_soledad_only_on_account_create @@ -0,0 +1,3 @@ +- Sync Soledad before bootstrapping mail only if the key for the user +  is not found locally. Otherwise, defer to thread and +  continue. Closes #5083
\ No newline at end of file diff --git a/changes/feature_5095_ensure-imap-flushes-data-before-quitting b/changes/feature_5095_ensure-imap-flushes-data-before-quitting new file mode 100644 index 00000000..ef1f2888 --- /dev/null +++ b/changes/feature_5095_ensure-imap-flushes-data-before-quitting @@ -0,0 +1 @@ +- Ensure IMAP flushes data to disk before quitting. Closes #5095. diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py index 941ba4f8..1146d1d0 100644 --- a/src/leap/bitmask/app.py +++ b/src/leap/bitmask/app.py @@ -50,7 +50,7 @@ from PySide import QtCore, QtGui  from leap.bitmask import __version__ as VERSION  from leap.bitmask.util import leap_argparse -from leap.bitmask.util import log_silencer +from leap.bitmask.util import log_silencer, LOG_FORMAT  from leap.bitmask.util.leap_log_handler import LeapLogHandler  from leap.bitmask.util.streamtologger import StreamToLogger  from leap.bitmask.platform_init import IS_WIN @@ -100,10 +100,7 @@ def add_logger_handlers(debug=False, logfile=None, replace_stdout=True):      # Create logger and formatter      logger = logging.getLogger(name='leap')      logger.setLevel(level) - -    log_format = ('%(asctime)s - %(name)s:%(funcName)s:L#%(lineno)s ' -                  '- %(levelname)s - %(message)s') -    formatter = logging.Formatter(log_format) +    formatter = logging.Formatter(LOG_FORMAT)      # Console handler      try: diff --git a/src/leap/bitmask/config/leapsettings.py b/src/leap/bitmask/config/leapsettings.py index 91ff83a8..13a1e99e 100644 --- a/src/leap/bitmask/config/leapsettings.py +++ b/src/leap/bitmask/config/leapsettings.py @@ -372,12 +372,16 @@ class LeapSettings(object):          Sets the uuid for a given username.          :param username: the full user identifier in the form user@provider -        :type username: basestring -        :param value: the uuid to save -        :type value: basestring +        :type username: str or unicode +        :param value: the uuid to save or None to remove it +        :type value: str or unicode or None          """          leap_assert("@" in username,                      "Expected username in the form user@provider")          user, provider = username.split('@') -        leap_assert(len(value) > 0, "We cannot save an empty uuid") -        self._settings.setValue(self.UUIDFORUSER_KEY % (provider, user), value) +        key = self.UUIDFORUSER_KEY % (provider, user) +        if value is None: +            self._settings.remove(key) +        else: +            leap_assert(len(value) > 0, "We cannot save an empty uuid") +            self._settings.setValue(key, value) diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index ffedfa1c..db24a1c8 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -19,6 +19,7 @@ Main window for Bitmask.  """  import logging +from threading import Condition  from PySide import QtCore, QtGui  from datetime import datetime  from twisted.internet import threads @@ -112,6 +113,9 @@ class MainWindow(QtGui.QMainWindow):      # We give EIP some time to come up before starting soledad anyway      EIP_TIMEOUT = 60000  # in milliseconds +    # We give each service some time to come to a halt before forcing quit +    SERVICE_STOP_TIMEOUT = 20 +      def __init__(self, quit_callback,                   openvpn_verb=1,                   bypass_checks=False): @@ -893,7 +897,7 @@ class MainWindow(QtGui.QMainWindow):              "If you use Thunderbird you can use the Bitmask extension helper. "              "Search for 'Bitmask' in the add-on manager or download it "              "from: {0}.<br><br>" -            "You can configure bitmask manually with this options:<br>" +            "You can configure Bitmask manually with these options:<br>"              "<em>"              "   Incoming -> IMAP, port: {1}<br>"              "   Outgoing -> SMTP, port: {2}<br>" @@ -1330,8 +1334,13 @@ class MainWindow(QtGui.QMainWindow):          TRIGGERS:              self.logout          """ +        cv = Condition() +        cv.acquire()          # TODO call stop_mail_service -        self._mail_conductor.stop_imap_service() +        threads.deferToThread(self._mail_conductor.stop_imap_service, cv) +        # and wait for it to be stopped +        logger.debug('Waiting for imap service to stop.') +        cv.wait(self.SERVICE_STOP_TIMEOUT)      # end service control methods (imap) @@ -1857,7 +1866,7 @@ class MainWindow(QtGui.QMainWindow):          """          logger.debug('About to quit, doing cleanup...') -        self._mail_conductor.stop_imap_service() +        self._stop_imap_service()          if self._srp_auth is not None:              if self._srp_auth.get_session_id() is not None or \ @@ -1899,7 +1908,6 @@ class MainWindow(QtGui.QMainWindow):          self._backend.stop()          self._cleanup_and_quit() -          self._really_quit = True          if self._wizard: diff --git a/src/leap/bitmask/gui/ui/wizard.ui b/src/leap/bitmask/gui/ui/wizard.ui index 1ddd854f..d9b8499e 100644 --- a/src/leap/bitmask/gui/ui/wizard.ui +++ b/src/leap/bitmask/gui/ui/wizard.ui @@ -59,7 +59,7 @@      <item row="0" column="0">       <widget class="QLabel" name="label_3">        <property name="text"> -       <string><html><head/><body><p>Now we will guide you through some configuration that is needed before you can connect for the first time.</p><p>If you ever need to modify these options again, you can find the wizard in the <span style=" font-style:italic;">'Settings'</span> menu from the main window.</p><p>Do you want to <span style=" font-weight:600;">sign up</span> for a new account, or <span style=" font-weight:600;">log in</span> with an already existing username?</p></body></html></string> +       <string><html><head/><body><p>Now we will guide you through some configuration that is needed before you can connect for the first time.</p><p>If you ever need to modify these options again, you can find the wizard in the <span style=" font-style:italic;">'Bitmask -&gt; Create new account...'</span> menu from the main window.</p><p>Do you want to <span style=" font-weight:600;">sign up</span> for a new account, or <span style=" font-weight:600;">log in</span> with an already existing username?</p></body></html></string>        </property>        <property name="textFormat">         <enum>Qt::RichText</enum> diff --git a/src/leap/bitmask/services/mail/conductor.py b/src/leap/bitmask/services/mail/conductor.py index fc53923c..f5892468 100644 --- a/src/leap/bitmask/services/mail/conductor.py +++ b/src/leap/bitmask/services/mail/conductor.py @@ -95,9 +95,13 @@ class IMAPControl(object):              logger.debug("Starting loop")              self.imap_service.start_loop() -    def stop_imap_service(self): +    def stop_imap_service(self, cv):          """          Stops imap service (fetcher, factory and port). + +        :param cv: A condition variable to which we can signal when imap +                   indeed stops. +        :type cv: threading.Condition          """          self.imap_connection.qtsigs.disconnecting_signal.emit()          # TODO We should homogenize both services. @@ -110,7 +114,13 @@ class IMAPControl(object):              self.imap_port.stopListening()              # Stop the protocol              self.imap_factory.theAccount.closed = True -            self.imap_factory.doStop() +            self.imap_factory.doStop(cv) +        else: +            # main window does not have to wait because there's no service to +            # be stopped, so we release the condition variable +            cv.acquire() +            cv.notify() +            cv.release()      def fetch_incoming_mail(self):          """ diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 5351bcd2..f7217af6 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -26,6 +26,7 @@ from ssl import SSLError  from PySide import QtCore  from u1db import errors as u1db_errors +from twisted.internet import threads  from zope.proxy import sameProxiedObjects  from leap.bitmask.config import flags @@ -288,7 +289,18 @@ class SoledadBootstrapper(AbstractBootstrapper):              self._init_keymanager(self._address)              self.local_only_ready.emit({self.PASSED_KEY: True})          else: -            self._do_soledad_sync() +            try: +                address = make_address( +                    self._user, self._provider_config.get_domain()) +                self._init_keymanager(address) +                self._keymanager.get_key( +                    address, openpgp.OpenPGPKey, +                    private=True, fetch_remote=False) +                threads.deferToThread(self._do_soledad_sync) +            except KeyNotFound: +                logger.debug("Key not found. Generating key for %s" % +                             (address,)) +                self._do_soledad_sync()      def _pick_server(self, uuid):          """ @@ -546,7 +558,6 @@ class SoledadBootstrapper(AbstractBootstrapper):          address = make_address(              self._user, self._provider_config.get_domain()) -        self._init_keymanager(address)          logger.debug("Retrieving key for %s" % (address,))          try: diff --git a/src/leap/bitmask/util/__init__.py b/src/leap/bitmask/util/__init__.py index c35be99e..2b2cd874 100644 --- a/src/leap/bitmask/util/__init__.py +++ b/src/leap/bitmask/util/__init__.py @@ -28,6 +28,11 @@ from leap.common.config import get_path_prefix as common_get_path_prefix  # We'll give your money back if it does not alleviate the eye strain, at least. +# levelname length == 8, since 'CRITICAL' is the longest +LOG_FORMAT = ('%(asctime)s - %(levelname)-8s - ' +              'L#%(lineno)-4s : %(name)s:%(funcName)s() - %(message)s') + +  def first(things):      """      Return the head of a collection. diff --git a/src/leap/bitmask/util/leap_log_handler.py b/src/leap/bitmask/util/leap_log_handler.py index 1ab62331..807e53d4 100644 --- a/src/leap/bitmask/util/leap_log_handler.py +++ b/src/leap/bitmask/util/leap_log_handler.py @@ -21,6 +21,8 @@ import logging  from PySide import QtCore +from leap.bitmask.util import LOG_FORMAT +  class LogHandler(logging.Handler):      """ @@ -52,10 +54,7 @@ class LogHandler(logging.Handler):          :param logging_level: the debug level to define the color.          :type logging_level: str.          """ -        log_format = ('%(asctime)s - %(name)s:%(funcName)s:L#%(lineno)s ' -                      '- %(levelname)s - %(message)s') -        formatter = logging.Formatter(log_format) - +        formatter = logging.Formatter(LOG_FORMAT)          return formatter      def emit(self, logRecord):  | 
