From 926575bc811e8382100695a3396da7191fb43eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 8 Mar 2013 13:15:38 -0300 Subject: Add translation support Also: - Make OpenVPN use a random port every time - Logout in parallel so the UI doesn't block - Add the WAIT status from OpenVPN to the mainwindow displays - Support non-unix sockets in the LinuxVPNLauncher --- src/leap/app.py | 3 +- src/leap/config/baseconfig.py | 11 ++++-- src/leap/crypto/srpauth.py | 34 +++++++++-------- src/leap/gui/mainwindow.py | 72 +++++++++++++++++++---------------- src/leap/gui/ui/wizard.ui | 1 + src/leap/gui/wizard.py | 28 +++++++------- src/leap/services/eip/vpn.py | 5 ++- src/leap/services/eip/vpnlaunchers.py | 11 +++++- src/leap/util/leap_argparse.py | 2 +- 9 files changed, 95 insertions(+), 72 deletions(-) (limited to 'src') diff --git a/src/leap/app.py b/src/leap/app.py index fa50cd1e..743ea6ea 100644 --- a/src/leap/app.py +++ b/src/leap/app.py @@ -27,8 +27,7 @@ from PySide import QtCore, QtGui VERSION = "unknown" from leap.util import leap_argparse -# TODO: add translations -#from leap.gui import locale_rc +from leap.gui import locale_rc from leap.gui.mainwindow import MainWindow diff --git a/src/leap/config/baseconfig.py b/src/leap/config/baseconfig.py index b80fd419..b6890d09 100644 --- a/src/leap/config/baseconfig.py +++ b/src/leap/config/baseconfig.py @@ -159,10 +159,13 @@ class LocalizedKey(object): """ descriptions = self._func(instance) description_lang = "" - if lang in descriptions.keys(): - description_lang = descriptions[lang] - else: - logger.warning("Unknown language: %s" % (lang,)) + config_lang = "en" + for key in descriptions.keys(): + if lang.startswith(key): + config_lang = key + break + + description_lang = descriptions[config_lang] return description_lang def __get__(self, instance, instancetype): diff --git a/src/leap/crypto/srpauth.py b/src/leap/crypto/srpauth.py index 28e4f037..8530b7da 100644 --- a/src/leap/crypto/srpauth.py +++ b/src/leap/crypto/srpauth.py @@ -156,18 +156,18 @@ class SRPAuth(QtCore.QObject): "Status code = %r. Content: %r" % (init_session.status_code, init_session.content)) if init_session.status_code == 422: - raise SRPAuthenticationError("Unknown user") + raise SRPAuthenticationError(self.tr("Unknown user")) salt = init_session.json().get("salt", None) B = init_session.json().get("B", None) if salt is None: logger.error("No salt parameter sent") - raise SRPAuthenticationError("The server did not send the " + - "salt parameter") + raise SRPAuthenticationError(self.tr("The server did not send " + "the salt parameter")) if B is None: logger.error("No B parameter sent") - raise SRPAuthenticationError("The server did not send the " + - "B parameter") + raise SRPAuthenticationError(self.tr("The server did not send " + "the B parameter")) return salt, B @@ -194,8 +194,8 @@ class SRPAuth(QtCore.QObject): unhex_B = self._safe_unhexlify(B) except TypeError as e: logger.error("Bad data from server: %r" % (e,)) - raise SRPAuthenticationError("The data sent from the server " - "had errors") + raise SRPAuthenticationError(self.tr("The data sent from " + "the server had errors")) M = self._srp_user.process_challenge(unhex_salt, unhex_B) auth_url = "%s/%s/%s/%s" % (self._provider_config.get_api_uri(), @@ -215,20 +215,21 @@ class SRPAuth(QtCore.QObject): get_ca_cert_path()) except requests.exceptions.ConnectionError as e: logger.error("No connection made (HAMK): %r" % (e,)) - raise SRPAuthenticationError("Could not connect to the server") + raise SRPAuthenticationError(self.tr("Could not connect to " + "the server")) if auth_result.status_code == 422: logger.error("[%s] Wrong password (HAMK): [%s]" % (auth_result.status_code, auth_result.json(). get("errors", ""))) - raise SRPAuthenticationError("Wrong password") + raise SRPAuthenticationError(self.tr("Wrong password")) if auth_result.status_code not in (200,): logger.error("No valid response (HAMK): " "Status code = %s. Content = %r" % (auth_result.status_code, auth_result.content)) - raise SRPAuthenticationError("Unknown error (%s)" % + raise SRPAuthenticationError(self.tr("Unknown error (%s)") % (auth_result.status_code,)) M2 = auth_result.json().get("M2", None) @@ -237,8 +238,8 @@ class SRPAuth(QtCore.QObject): if M2 is None or self.get_uid() is None: logger.error("Something went wrong. Content = %r" % (auth_result.content,)) - raise SRPAuthenticationError("Problem getting data from" - " server") + raise SRPAuthenticationError(self.tr("Problem getting data " + "from server")) return M2 @@ -258,13 +259,14 @@ class SRPAuth(QtCore.QObject): unhex_M2 = self._safe_unhexlify(M2) except TypeError: logger.error("Bad data from server (HAWK)") - raise SRPAuthenticationError("Bad data from server") + raise SRPAuthenticationError(self.tr("Bad data from server")) self._srp_user.verify_session(unhex_M2) if not self._srp_user.authenticated(): logger.error("Auth verification failed") - raise SRPAuthenticationError("Auth verification failed") + raise SRPAuthenticationError(self.tr("Auth verification " + "failed")) logger.debug("Session verified.") self.set_session_id(self._session.cookies["_session_id"]) @@ -379,7 +381,7 @@ class SRPAuth(QtCore.QObject): self.__instance.authenticate(username, password) logger.debug("Successful login!") - self.authentication_finished.emit(True, "Succeeded") + self.authentication_finished.emit(True, self.tr("Succeeded")) return True except Exception as e: logger.error("Error logging in %s" % (e,)) @@ -393,7 +395,7 @@ class SRPAuth(QtCore.QObject): """ try: self.__instance.logout() - self.logout_finished.emit(True, "Succeeded") + self.logout_finished.emit(True, self.tr("Succeeded")) return True except Exception as e: self.logout_finished.emit(False, "%s" % (e,)) diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index df21a2bb..d66ddbb5 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -20,6 +20,7 @@ Main window for the leap client """ import os import logging +import random from PySide import QtCore, QtGui @@ -141,9 +142,10 @@ class MainWindow(QtGui.QMainWindow): self._systray = None self._vpn_systray = None - self._action_eip_status = QtGui.QAction("Encryption is OFF", self) + self._action_eip_status = QtGui.QAction(self.tr("Encryption is OFF"), + self) self._action_eip_status.setEnabled(False) - self._action_eip_stop = QtGui.QAction("Stop", self) + self._action_eip_stop = QtGui.QAction(self.tr("Stop"), self) self._action_eip_stop.triggered.connect( self._stop_eip) self._action_eip_write = QtGui.QAction( @@ -155,7 +157,7 @@ class MainWindow(QtGui.QMainWindow): "0.0 Kb", self) self._action_eip_read.setEnabled(False) - self._action_visible = QtGui.QAction("Hide", self) + self._action_visible = QtGui.QAction(self.tr("Hide"), self) self._action_visible.triggered.connect(self._toggle_visible) self._center_window() @@ -226,9 +228,9 @@ class MainWindow(QtGui.QMainWindow): Toggles the window visibility """ self.setVisible(not self.isVisible()) - action_visible_text = "Hide" + action_visible_text = self.tr("Hide") if not self.isVisible(): - action_visible_text = "Show" + action_visible_text = self.tr("Show") self._action_visible.setText(action_visible_text) def _center_window(self): @@ -257,14 +259,15 @@ class MainWindow(QtGui.QMainWindow): """ Display the About LEAP dialog """ - QtGui.QMessageBox.about(self, "About LEAP", - "LEAP is a non-profit dedicated to giving " - "all internet users access to secure " - "communication. Our focus is on adapting " - "encryption technology to make it easy to use " - "and widely available. " - "More about LEAP" - "") + QtGui.QMessageBox.about( + self, self.tr("About LEAP"), + self.tr("LEAP is a non-profit dedicated to giving " + "all internet users access to secure " + "communication. Our focus is on adapting " + "encryption technology to make it easy to use " + "and widely available. " + "More about LEAP" + "")) def quit(self): self._really_quit = True @@ -399,7 +402,8 @@ class MainWindow(QtGui.QMainWindow): self._provider_config, download_if_needed=True) else: - self._set_status("Could not load provider configuration") + self._set_status( + self.tr("Could not load provider configuration")) self._login_set_enabled(True) else: self._set_status(data[self._provider_bootstrapper.ERROR_KEY]) @@ -424,18 +428,18 @@ class MainWindow(QtGui.QMainWindow): provider = self.ui.cmbProviders.currentText() if len(provider) == 0: - self._set_status("Please select a valid provider") + self._set_status(self.tr("Please select a valid provider")) return if len(username) == 0: - self._set_status("Please provide a valid username") + self._set_status(self.tr("Please provide a valid username")) return if len(password) == 0: - self._set_status("Please provide a valid Password") + self._set_status(self.tr("Please provide a valid Password")) return - self._set_status("Logging in...") + self._set_status(self.tr("Logging in...")) self._login_set_enabled(False) self._download_provider_config() @@ -496,11 +500,11 @@ class MainWindow(QtGui.QMainWindow): def _start_eip(self): self._vpn.start(eipconfig=self._eip_config, providerconfig=self._provider_config, - socket_host="/home/chiiph/vpnsock", - socket_port="unix") + socket_host="localhost", + socket_port=str(random.randint(1000, 9999))) self._vpn_systray.setVisible(True) self.ui.btnEipStartStop.setEnabled(True) - self.ui.btnEipStartStop.setText("Stop EIP") + self.ui.btnEipStartStop.setText(self.tr("Stop EIP")) self.ui.btnEipStartStop.clicked.disconnect( self._start_eip) self.ui.btnEipStartStop.clicked.connect( @@ -509,9 +513,9 @@ class MainWindow(QtGui.QMainWindow): def _stop_eip(self): self._vpn.set_should_quit() self._vpn_systray.setVisible(False) - self._set_eip_status("EIP has stopped") + self._set_eip_status(self.tr("EIP has stopped")) self._set_eip_status_icon("error") - self.ui.btnEipStartStop.setText("Start EIP") + self.ui.btnEipStartStop.setText(self.tr("Start EIP")) self.ui.btnEipStartStop.clicked.disconnect( self._stop_eip) self.ui.btnEipStartStop.clicked.connect( @@ -524,7 +528,7 @@ class MainWindow(QtGui.QMainWindow): leap_assert(self._eip_bootstrapper, "We need an eip bootstrapper!") leap_assert(self._provider_config, "We need a provider config") - self._set_eip_status("Checking configuration, please wait...") + self._set_eip_status(self.tr("Checking configuration, please wait...")) if self._provider_config.provides_eip(): self._eip_bootstrapper.run_eip_setup_checks( @@ -532,7 +536,7 @@ class MainWindow(QtGui.QMainWindow): self._provider_config, download_if_needed=True) else: - self._set_eip_status("%s does not support EIP" % + self._set_eip_status(self.tr("%s does not support EIP") % (self._provider_config.get_domain(),)) def _set_eip_status_icon(self, status): @@ -543,11 +547,11 @@ class MainWindow(QtGui.QMainWindow): @type status: str """ selected_pixmap = self.ERROR_ICON - tray_message = "Encryption is OFF" - if status in ("AUTH", "GET_CONFIG"): + tray_message = self.tr("Encryption is OFF") + if status in ("WAIT", "AUTH", "GET_CONFIG"): selected_pixmap = self.CONNECTING_ICON elif status in ("CONNECTED"): - tray_message = "Encryption is ON" + tray_message = self.tr("Encryption is ON") selected_pixmap = self.CONNECTED_ICON self.ui.lblVPNStatusIcon.setPixmap(selected_pixmap) @@ -565,11 +569,13 @@ class MainWindow(QtGui.QMainWindow): status = data[self._vpn.STATUS_STEP_KEY] self._set_eip_status_icon(status) if status == "AUTH": - self._set_eip_status("VPN: Authenticating...") + self._set_eip_status(self.tr("VPN: Authenticating...")) elif status == "GET_CONFIG": - self._set_eip_status("VPN: Retrieving configuration...") + self._set_eip_status(self.tr("VPN: Retrieving configuration...")) elif status == "CONNECTED": - self._set_eip_status("VPN: Connected!") + self._set_eip_status(self.tr("VPN: Connected!")) + elif status == "WAIT": + self._set_eip_status(self.tr("VPN: Waiting to start...")) else: self._set_eip_status(status) @@ -621,8 +627,8 @@ class MainWindow(QtGui.QMainWindow): Starts the logout sequence """ self._set_eip_status_icon("error") - self._set_eip_status("Signing out...") - self._srp_auth.logout() + self._set_eip_status(self.tr("Signing out...")) + self._checker_thread.add_checks([self._srp_auth.logout]) def _done_logging_out(self, ok, message): """ diff --git a/src/leap/gui/ui/wizard.ui b/src/leap/gui/ui/wizard.ui index 2d9cb441..a7198c5f 100644 --- a/src/leap/gui/ui/wizard.ui +++ b/src/leap/gui/ui/wizard.ui @@ -798,6 +798,7 @@ + diff --git a/src/leap/gui/wizard.py b/src/leap/gui/wizard.py index bac74d1d..fa705645 100644 --- a/src/leap/gui/wizard.py +++ b/src/leap/gui/wizard.py @@ -21,7 +21,7 @@ First run wizard import os import logging -from PySide import QtGui +from PySide import QtCore, QtGui from functools import partial from ui_wizard import Ui_Wizard @@ -152,19 +152,20 @@ class Wizard(QtGui.QWizard): username.encode("ascii") password.encode("ascii") except: - message = u"Refrain from using non ASCII áñ characters" + message = self.tr(u"Refrain from using non " + u"ASCII characters like á, ñ, æ") if message is not None and password != password2: - message = "Passwords don't match" + message = self.tr("Passwords don't match") if message is None and len(password) < 6: - message = "Password too short" + message = self.tr("Password too short") if message is None and password in self.WEAK_PASSWORDS: - message = "Password too easy" + message = self.tr("Password too easy") if message is None and username == password: - message = "Password equal to username" + message = self.tr("Password equal to username") if message is not None: self._set_register_status(message) @@ -190,20 +191,20 @@ class Wizard(QtGui.QWizard): self._checker_thread.add_checks( [partial(register.register_user, username, password)]) self._username = username - self._set_register_status("Starting registration...") + self._set_register_status(self.tr("Starting registration...")) else: self.ui.btnRegister.setEnabled(True) def _registration_finished(self, ok, req): if ok: - self._set_register_status("" - "User registration OK") + self._set_register_status(self.tr("" + "User registration OK")) self.ui.lblPassword2.clearFocus() self.page(self.REGISTER_USER_PAGE).set_completed() self.button(QtGui.QWizard.BackButton).setEnabled(False) else: self._username = None - error_msg = "Unknown error" + error_msg = self.tr("Unknown error") try: error_msg = req.json().get("errors").get("login")[0] except: @@ -304,7 +305,7 @@ class Wizard(QtGui.QWizard): new_data = { self._provider_bootstrapper.PASSED_KEY: False, self._provider_bootstrapper.ERROR_KEY: - "Unable to load provider configuration" + self.tr("Unable to load provider configuration") } self._complete_task(new_data, self.ui.lblProviderInfo) @@ -387,13 +388,14 @@ class Wizard(QtGui.QWizard): if pageId == self.PRESENT_PROVIDER_PAGE: # TODO: get the right lang for these + lang = QtCore.QLocale.system().name() self.ui.lblProviderName.setText( "%s" % - (self._provider_config.get_name(),)) + (self._provider_config.get_name(lang=lang),)) self.ui.lblProviderURL.setText(self._provider_config.get_domain()) self.ui.lblProviderDesc.setText( "%s" % - (self._provider_config.get_description(),)) + (self._provider_config.get_description(lang=lang),)) self.ui.lblProviderPolicy.setText(self._provider_config .get_enrollment_policy()) diff --git a/src/leap/services/eip/vpn.py b/src/leap/services/eip/vpn.py index 71944f50..3ec32f6f 100644 --- a/src/leap/services/eip/vpn.py +++ b/src/leap/services/eip/vpn.py @@ -31,7 +31,6 @@ from leap.services.eip.udstelnet import UDSTelnet from leap.util.check import leap_assert, leap_assert_type logger = logging.getLogger(__name__) -ON_POSIX = 'posix' in sys.builtin_module_names # TODO: abstract the thread that can be asked to quit to another @@ -103,6 +102,7 @@ class VPN(QtCore.QThread): self._send_command("signal SIGTERM") self._tn.close() self._subp.terminate() + self._subp.waitForFinished() except Exception as e: logger.debug("Could not terminate process, trying command " + "signal SIGNINT: %r" % (e,)) @@ -309,6 +309,9 @@ class VPN(QtCore.QThread): self._parse_state_and_notify(self._send_command("state")) self._parse_status_and_notify(self._send_command("status")) output_sofar = self._subp.readAllStandardOutput() + if len(output_sofar) > 0: + logger.debug(output_sofar) + output_sofar = self._subp.readAllStandardError() if len(output_sofar) > 0: logger.debug(output_sofar) QtCore.QThread.msleep(self.POLL_TIME) diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 00e9c966..cf817321 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -215,8 +215,15 @@ class LinuxVPNLauncher(VPNLauncher): args += [ '--user', getpass.getuser(), - '--group', grp.getgrgid(os.getgroups()[-1]).gr_name, - '--management-client-user', getpass.getuser(), + '--group', grp.getgrgid(os.getgroups()[-1]).gr_name + ] + + if socket_port == "unix": + args += [ + '--management-client-user', getpass.getuser() + ] + + args += [ '--management-signal', '--management', socket_host, socket_port, '--script-security', '2' diff --git a/src/leap/util/leap_argparse.py b/src/leap/util/leap_argparse.py index 78597f63..83272a3d 100644 --- a/src/leap/util/leap_argparse.py +++ b/src/leap/util/leap_argparse.py @@ -20,7 +20,7 @@ import argparse def build_parser(): """ - all the options for the leap arg parser + All the options for the leap arg parser Some of these could be switched on only if debug flag is present! """ epilog = "Copyright 2012 The LEAP Encryption Access Project" -- cgit v1.2.3