From 89eedff7af5424c69984a696ffb1cd2a8992f606 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 21 Oct 2013 14:14:32 -0200 Subject: add readme and changelog to long-description reformat changelog in .rst --- CHANGELOG | 369 ------------------------------------------------------ CHANGELOG.rst | 394 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ MANIFEST.in | 2 +- README.rst | 4 +- setup.py | 21 +--- 5 files changed, 400 insertions(+), 390 deletions(-) delete mode 100644 CHANGELOG create mode 100644 CHANGELOG.rst diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index 25e90051..00000000 --- a/CHANGELOG +++ /dev/null @@ -1,369 +0,0 @@ -0.3.5 Oct 18 -- the "I can stand on one foot" release: - o In case of Soledad failure, display to the user that there was a - problem. Closes #4025. - o Widget squashing problem in wizard checking a new provider. Closes - #4058. - o Remember last domain used to login. Closes #4116. - o Display first run wizard, regardless of pinned providers. Closes - #4143. - o Show EIP status 'ON' in the systray tooltip when is - connected. Related to #3998. - o Catch u1db errors during soledad initialization. - o Disable --danger flag on release versions. Closes #4124. - o Display mail status in the tray icon as an enabled item. Fixes - #4036. - o Only show N unread Emails when N > 0. Fixes #4098. - o Hide login error message when the user interacts with the widgets - to fix the potential problem. Fixes #4022. - o Add call to `make` to the bootstrap script. - o Improve GUI based on QA rounds. Fixes #4041 and #4042. - o Increase the amount of retries for the authentication request - session. Fixes #4037. - o Rename EIP to Encrypted Internet in its preference panel. Fixes - #4057. - o Disable stdout redirection on Windows for the time being since it - breaks the bundle. - o Default UP_SCRIPT and DOWN_SCRIPT to None and only add that - parameter to the vpn command if not None. - o Look for gpg on windows with the .exe extension. - o Change the Util menu to be named File in OSX. Fixes #4039. - o Show more context information in the logs. Closes #3923. - o Automate internationalization process, create project file - dynamically on make. Closes #3925. - o Add support for running lxde polkit agent. Closes #4028. - o Added Vietnamese and English (United Kingdom) translations. - o Implements openvpn observer. Closes: #3901 - o Reconnect EIP if network down. Closes #3790 - o Reconnect if tls-restart. Closes: #3262 - -0.3.4 Oct 4 -- the "look at my new makeup" release: - o Fixes a bug where you cannot login to a different provider once - you logged in to another one. Fixes #3695. - o Resets the session for every login attempt. Related to #3695. - o Avoid error message if --version flag is used. Closes #3914. - o Fix a bug in which failing to authenticate properly left - connection in an unconsistent state. Closes: #3926 - o Avoids errors due to the EIP switch button and action being - enabled when we do not have a configured provider. Closes: #3927 - o Add more verbose error handling during key generation and syncing. - Helps diagnose: #3985; Addresses in part: #3965 - o Choose one gnupg binary path that is also not a symlink. Closes - #3999. - o Refactor vpn launchers, reuse code, improve implementations, - update documentation. Closes #2858. - o Add preferences option to enable/disable the automatic start of - EIP and selection of the EIP provider to auto start. Closes #3631. - o Force cleanlooks style for kde only if the app is running from - bundle. Closes #3981. - o Add a dropdown for known providers in the wizard. Closes #3995. - o Separate pinned providers from user configures ones. Closes #3996. - o Improve error handling during soledad bootstrap. Closes: #3965. - Affects: #3619, #3867, #3966 - o Implement new UI design. Closes #3973. - o Make the initial provider cert verifications against our modified - CA-bundle (includes ca-cert certificates, for now). Closes: #3850 - o Use token header for authenticated requests. Closes #3910. - o Do not distinguish between different possible authentication - errors. Fixes #3859. - o Do not start Soledad if Mail is not enabled. Fixes #3989. - o Allow window minization on OSX. Fixes #3932. - o Properly stop the smtp daemon. Fixes #3873. - -0.3.3 Sep 20 -- "the calm after the tempest" release: - o Remove execution bits in text files in bundle. Closes #3617. - o Use generic bad username/password message instead of specific ones when - the user uses incorrect data during login. Closes #3656. - o Fix LoggerWindow saving more than one line return per line in the logs - file. Closes #3714. - o Fix keyring imports so we do not get import errors. Closes: #3759 - o Catch logout problem, display a user message and allow log back in after a - successful logout if there was a logout error before. Closes #3774. - o Fix path prefix helper for the bundle and add regresion tests. Closes #3778. - o Prevent dialogs closing the app when it has been minimized to the tray. Closes #3791. - o Do not try to install resolv-update globally. Closes: #3803 - o Inconsistent hide/show main window from tray action. Closes #3821. - o Allow SMTP to start even when provider does not offer EIP. Closes: #3847 - o Fix username case problem at register/login. Closes #3857. - o Catch IndexError on `first` utility. - o Update git repo name in docs. Closes: #3417 - o Move STANDALONE flag to a module and unify get_path_prefix queries. - Closes #3636. - o Display the Encrypted Internet and Encrypted Email status in the systray - tooltip. Closes #3758. - o Tasktray menu changes, closes #3792. - - Remove the provider domain item (e.g. bitmask.net). - - Rename the EIP status menu items to be more descriptive. - - Change the EIP status menu items from disabled menu items - to submenus with children. - - Move the EIP action menu items under the EIP status submenu tree. - o Adds --version flag. Closes: #3816 - o Refactors EIPConnection to use LEAPConnection state machine. Closes: #3900 - o Include resource files and ui in the distrubution tarball. Closes: #3825 - -0.3.2 Sep 6 -- the "no crashes or anything" release: - o Fix up script in non-bundle linuces. Closes: #3450 - o Logout stops imap and smtp services. Closes: #3553 - o Properly daemonize polkit-gnome-authentication-agent. Closes: #3554 - o Set appropiate error on login cancel. Closes #3582. - o Fix gateway selection problem. Closes 3595. - o Fix typo in wizard: stablish -> establish. Closes #3615. - o Display Encrypted Mail instead of mx in wizard. Closes #3657. - o Fix save logs to file dialog freezing. Closes #3675. - o Complain if setup.py is run with python3. Closes: #3711 - o Enable preferences option in systray. Closes #3717. - o Make soledad emit failed signal for all kinds of socket error. - o Allow to selectively silence logs from different leap components. Closes: #3504 - o Add option to select gateway manually in the preferences panel. Closes #3505. - o Add preferences option to select the enabled services of a provider. Closes #3534. - o Refactor basic password checks. Closes #3552. - o Use dirspec instead of plain xdg. Closes #3574. - o Remove last page from wizard. Closes #3616. - o Display encrypted mail status in the tray. Closes #3659. - -0.3.1 Aug 23: - o Replace wizard images with the rainbow mask. Closes #3425. - o Update leap.common minimum version needed. - o Set the standalone flag before it's being used. Fixes #3426. - o Stop the twisted reactor adding the stop call to the call chain - instead of stopping it directly. Fixes #3406. - o Allow soledad initialization to retry if it times out. Closes: - #3413 - o Activate window when setting it visible. Also display Hide/Show - message in the tray icon taking into account the window - activation. Fixes #3433. - o Do not start IMAP daemon if mail was not selected among the - services. Fixes #3435. - o Reword RECONNECTING state of openvpn. Fixes #3429. - o Improve OpenVPN detection by searching for a specific leap-only - string in the command line. This makes it possible to run other - VPN instances while also using EIP. Fixes #3268 and #3364. - o OSX: Check for the tun.kext existence in /Library/Extensions - instead of /System/Library/Extensions. Fixes #3271. - o Use DELETE /1/logout to properly logout. Fixes #3510. - o Make the poll interval bigger to improve openvpn's internal - behavior. If it gets queried too many times per second, it's - behavior won't be good. Fixes #3430. - o Transforms usernames to lower case before they are used in the - registration and authentication. Closes #3541. - o Add filter option to the logger window. Closes #3407. - o Add a preference panel that lets you change your password. Closes - #3500 #2798 #3533. - o Move all client code into its own namespace - (leap.bitmask). Closes: #2959 - o Make mail fetch interval in imap service configurable via - environment variable. Closes: #3409 - o Update to new soledad package scheme (common, client and - server). Closes #3487. - o Fetch incoming mail when mail client logs in. Closes: #3525 - o Add first draft of the UI for Encrypted Mail. Closes #3499. - -0.3.0 Aug 9: - o Add missing scripts does not stop if a command fails, also warns - the user if there was an error. Closes #3294. - o Replace 'Sign Out' with 'Log Out' and 'User' with - 'Username'. Closes #3319. - o Verify cacert existence before using it. Closes bug #3362. - o Properly handle login failures. Closes bug #3401. - o Bugfix, avoid getting negative rates. Closes #3274. - o Raise window when setting it as visible. Fixes #3374 - o Fail gracefully when the events port 8090 is in use by something - else. Fixes #3276. - o Validate the username in the login form against the same regexp as - the wizard registration form. Fixes #3214. - o Update text from the tray menu based on the visibility of the - window. Fixes #3400. - o Add check for outdated polkit file. Closes #3209. - o Add support for multiple schemas so we can support multiples api - versions. Closes #3310. - o Rebrand the client to be named Bitmask. Feature #3313. - o Add cancel button to login. Closes #3318. - o Add multiple schema support for SMTP. Closes #3403. - o Add multiple schema support for Soledad. Closes #3404. - o Update Transifex project name and translators' - documentation. Closes #3418. - o Add check for tuntap kext before launching openvpn. Closes: #2906 - o Accept flag for changing openvpn verbosity in logs. Closes: #3305 - o Add imap service to the client. Closes: #2579 - o Add pyside-uic support inside the virtualenv. This way it won't - fail to 'make' if the virtualenv is activated. Closes #3411. - o Reintegrate SMTP relay module. Closes #3375 - o Reintegrate Soledad into the client. Closes #3307. - o Support bundled gpg. Related to #3397. - o Set the default port for SMTP to be 2013. - o Display a more generic error message in the main window, and leave - the detailed one for the log. Closes #3373. - -0.2.4 Jul 26: - o Use the provider CA cert for every request once we have it - bootstrapped (TOFU). Closes #3227. - o Make calls to leap.common.events asynchronous. Closes #2937. - o Always logout when closing the app if the user previously signed - in. Fixes #3245. - o Make sure the domain field in provider.json is escaped to avoid - potential problems. Fixes #3244. - o Fix incorrect handling of locks in Windows so that stalled locks - do not avoid raising the first instance of the app. Closes: #2910 - o Use traffic rates instead of totals. Closes #2913 - o Allow to alternate between rates and total throughput for the - virtual interface. Closes: #3232 - o Reset rates/totals when terminating connection. Closes #3249 - o Fix a bug in the displayed magnitude for the up/down traffic rates - and totals. - o Force Cleanlooks style if we are running in a KDE environment, so - that it doesn't load potentially incompatible Qt libs. Fixes - #3194. - o Wrap long login status messages to 40 characters. Fixes #3124 - o Workaround a segmentation fault when emitting a signal with its - last parameter being None. Fixes #3083. - o Added IS_RELEASE_VERSION flag that allows us to use code only in - develop versions. Closes #3224. - o Try to terminate already running openvpn instances. Closes #2916 - o Linux: Dynamically generate policy file for polkit. Closes #3208 - o Workaround some OpenVPN problems with priviledge dropping and - routing. Fixes #3178 #3135 #3207 #3203 - -0.2.3 Jul 12: - o Adapt code to Soledad 0.2.1 api. - o Fix Main Window briefly display before the wizard on first - start. Closes Bug #2954. - o Bugfix: Remember should not be automatically set to - checked. Closes #2955. - o Bugfix: reload config if switching to a different provider. Closes - #3067. - o Bugfix: logger window's toggle button reflects window - state. Closes #3152. - o Set timeout for requests to 10 seconds globally, configurable from - leap.util.constants. Fixes #2878. - o Bugfix: display error message on registration problem. Closes - #3039. - o Make wizard use the main event loop, ensuring clean termination. - o Use cocoasudo for installing missing updown scripts. - o Bugfix: Systray Turn ON action fails because is not correctly - enabled/disabled. Closes #3125. - o Bugfix: wrong systray icon on startup. Closes #3147. - o Bugfix: parse line return in the logger window. Closes #3151. - o Do not log user data on registration. Fixes #3168. - o Add --log-append eip.log to windows EIP launcher options to save - the logs in case of any problems. Fixes #2054. - o OSX: Make the install_path relative to the launcher path instead - of absolute. - o OSX: Fix icon display in cocoasudo. - o OSX: Raise window when showing if running on OSX. - o Bugfix: EIP status button moved to status panel. - o Check if there is no gateway to use and display correct - message. Close #2921. - o Reorder tray icons according new design. Closes #2919. - o Redirect stdout/stderr and twisted log to the logger. Closes - #3134. - o Improve LoggerWindow colors for easier debugging. - o Move the key manager to its own repository/package. - -0.2.2 Jun 28: - o Add support for the kde polkit daemon - o Handle 'Incorrect Password' exception (keyring) - o Select the configured domain in the providers combo box. Closes - #2693. - o Remember provider along with the username and password. Closes - #2755. - o Close the app on rejected wizard. Closes bug #2905. - o Only use the Keyring when it's using a known good backend. Closes - #2960 - o Update implementation and semantics of the supported and available - services by a provider. Closes bug #3032. - o Only show the question mark for a check being done if the previous - one passed. Fixes #2569. - o Fix main client window not restoring after minimized into - systray. Closes #2574 - o Set EIP different status icons depending on OS. Closes #2643. - o Reimplement openvpn invocation to use twisted ProcessProtocol - o Add runtime requirements checker, verifies that the requirements - are installed and in its correct versions. Closes #2563 - o Add centraliced logging facility, log history in a window. Closes - #2566 - o Improve wizard, hide registration widgets (labels, inputs, button) - and only display a message. Closes #2694 - o Clarify labels through the app (use of EIP) - o Check if the provider api version is supported. Closes feature - #2774. - o Autoselect VPN gateway based on timezone. Closes #2790. - o Disable vpn disconnect on logout. Closes #2795. - o Improve gateway selector based on timezone. It allows to use - multiple gateways in openvpn for redundancy. Closes #2894. - o Use cocoasudo in place of osascript for osx privilege escalation - during openvpn launch. - o Clicking in the tray icon will always show the context menu - instead of activating the window under certain - circumstances. Closes #2788 - o Autostart EIP whenever possible. Closes #2815 - o Update test suite, run_scripts and requirements to run smoothly - with buildbot. - o Add a copy of the processed requirements to util/ - o Display the default provider configured in the systray menu. Close - #2813 - o Make the login steps be a chain of defers in order to be able to - have more cancel points for the whole procedure. Closes #2571 - o Linux: check for up/down scripts and policy files and ask user for - permission to install them in a root-writeable location. Used from - within bundle or for broken installations. - o Integrate SMTP-Relay into the client. - o Integrate Soledad and KeyManager. - o Move the KeyManager from leap.common to leap-client. - o Only use one systray icon, repesenting the status for EIP. Closes - #2762 - o Properly set the binary manifest to the windows openvpn - binary. Closes #203 - o OSX: Add dialog with suggestion to install up/down scripts if - these not found. Closes: #1264, #2759, #2249 - o Workaround for PySide breaking with multiple inheritance. Closes - #2827 - o Refactor login to its own widget and remove Utils menu. Closes - #2789 - o Refactor the status bits out of the MainWindow to its own - StatusPanelWidget. Closes #2792 - o Save the default provider to be used for autostart EIP as - DefaultProvider in leap.conf. Closes #2793 - o Cleanly terminate openvpn process, sending SIGTERM and SIGKILL - after a while. Closes #2753 - o Use twisted's deferToThread and Deferreds to handle parallel tasks - o Use a qt4 reactor for twisted, for launching leap twisted - services. - -0.2.1 May 15: - o Rewrite most of the client based on the insight gained so far. - o Deselecting the remember checkbox makes the app not populate - user/password values on the login widget. Closes #2059 - o Rewording of setup steps in wizard, to make them more meaningful - to the non-technical user. Closes #2061 - o Fix typo in wizard. - o Fix multiple drawing of services if going back. - o Make registration errors show in red. - o Add a warning if EIP service needs admin password. Addresses part - of #2062 - o Make traffic indicators display fixed precision. Closes #2114 - o Do not hide the application if the user right clicked the system - tray icon. - o Sanitize network-fetched content that is used to build openvpn - command. - o Avoids multiple instances of leap-client. Each new one just raises - the existing instance and quits. - o Use dark eip icons os osx. Closes #2130 - o Moves BaseConfig to leap.common.config. Closes #2164 - o Add handling for ASSIGN_IP state from OpenVPN in the mainwindow. - o Emit events notifying of the session_id and uid after - authentication so other services can make use of it. Closes #1957 - o Working packaging workflow with rewritten client, using - pyinstaller and platypus. - o Remove network checks temporarily until we find a good way of - doing it, and a good way to deal with them. - o Saves the token to allow token authenticated queries. - o Turn "leap" into namespace package, move common files to - leap_common package that can be shared by other LEAP projects. - o Support standalone configurations for distribution in thumbdrives - and the like. - o Add support for requests < 1.0.0 - o Tests infrastructure, and tests for crypto/srpauth and crypto/srpregister. - o Documentation updated for 0.2.1 release. - o Docstrings style changed to fit sphinx autodoc format. - o Add a simple UI to notify of pending updates. - o Add Windows support. - o Try to install TAP driver on Windows if no tap device is preset. diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 00000000..e9740e4a --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,394 @@ +.. :changelog:: + +History +------- + +0.3.5 Oct 18 -- the "I can stand on one foot" release: +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +- In case of Soledad failure, display to the user that there was a + problem. Closes #4025. +- Widget squashing problem in wizard checking a new provider. Closes + #4058. +- Remember last domain used to login. Closes #4116. +- Display first run wizard, regardless of pinned providers. Closes + #4143. +- Show EIP status 'ON' in the systray tooltip when is + connected. Related to #3998. +- Catch u1db errors during soledad initialization. +- Disable --danger flag on release versions. Closes #4124. +- Display mail status in the tray icon as an enabled item. Fixes + #4036. +- Only show N unread Emails when N > 0. Fixes #4098. +- Hide login error message when the user interacts with the widgets + to fix the potential problem. Fixes #4022. +- Add call to `make` to the bootstrap script. +- Improve GUI based on QA rounds. Fixes #4041 and #4042. +- Increase the amount of retries for the authentication request + session. Fixes #4037. +- Rename EIP to Encrypted Internet in its preference panel. Fixes + #4057. +- Disable stdout redirection on Windows for the time being since it + breaks the bundle. +- Default UP_SCRIPT and DOWN_SCRIPT to None and only add that + parameter to the vpn command if not None. +- Look for gpg on windows with the .exe extension. +- Change the Util menu to be named File in OSX. Fixes #4039. +- Show more context information in the logs. Closes #3923. +- Automate internationalization process, create project file + dynamically on make. Closes #3925. +- Add support for running lxde polkit agent. Closes #4028. +- Added Vietnamese and English (United Kingdom) translations. +- Implements openvpn observer. Closes: #3901 +- Reconnect EIP if network down. Closes #3790 +- Reconnect if tls-restart. Closes: #3262 + +0.3.4 Oct 4 -- the "look at my new makeup" release: ++++++++++++++++++++++++++++++++++++++++++++++++++++ + +- Fixes a bug where you cannot login to a different provider once + you logged in to another one. Fixes #3695. +- Resets the session for every login attempt. Related to #3695. +- Avoid error message if --version flag is used. Closes #3914. +- Fix a bug in which failing to authenticate properly left + connection in an unconsistent state. Closes: #3926 +- Avoids errors due to the EIP switch button and action being + enabled when we do not have a configured provider. Closes: #3927 +- Add more verbose error handling during key generation and syncing. + Helps diagnose: #3985; Addresses in part: #3965 +- Choose one gnupg binary path that is also not a symlink. Closes + #3999. +- Refactor vpn launchers, reuse code, improve implementations, + update documentation. Closes #2858. +- Add preferences option to enable/disable the automatic start of + EIP and selection of the EIP provider to auto start. Closes #3631. +- Force cleanlooks style for kde only if the app is running from + bundle. Closes #3981. +- Add a dropdown for known providers in the wizard. Closes #3995. +- Separate pinned providers from user configures ones. Closes #3996. +- Improve error handling during soledad bootstrap. Closes: #3965. + Affects: #3619, #3867, #3966 +- Implement new UI design. Closes #3973. +- Make the initial provider cert verifications against our modified + CA-bundle (includes ca-cert certificates, for now). Closes: #3850 +- Use token header for authenticated requests. Closes #3910. +- Do not distinguish between different possible authentication + errors. Fixes #3859. +- Do not start Soledad if Mail is not enabled. Fixes #3989. +- Allow window minization on OSX. Fixes #3932. +- Properly stop the smtp daemon. Fixes #3873. + +0.3.3 Sep 20 -- "the calm after the tempest" release: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +- Remove execution bits in text files in bundle. Closes #3617. +- Use generic bad username/password message instead of specific ones when + the user uses incorrect data during login. Closes #3656. +- Fix LoggerWindow saving more than one line return per line in the logs + file. Closes #3714. +- Fix keyring imports so we do not get import errors. Closes: #3759 +- Catch logout problem, display a user message and allow log back in after a + successful logout if there was a logout error before. Closes #3774. +- Fix path prefix helper for the bundle and add regresion tests. Closes #3778. +- Prevent dialogs closing the app when it has been minimized to the tray. Closes #3791. +- Do not try to install resolv-update globally. Closes: #3803 +- Inconsistent hide/show main window from tray action. Closes #3821. +- Allow SMTP to start even when provider does not offer EIP. Closes: #3847 +- Fix username case problem at register/login. Closes #3857. +- Catch IndexError on `first` utility. +- Update git repo name in docs. Closes: #3417 +- Move STANDALONE flag to a module and unify get_path_prefix queries. + Closes #3636. +- Display the Encrypted Internet and Encrypted Email status in the systray + tooltip. Closes #3758. +- Tasktray menu changes, closes #3792. +- Remove the provider domain item (e.g. bitmask.net). +- Rename the EIP status menu items to be more descriptive. +- Change the EIP status menu items from disabled menu items + to submenus with children. +- Move the EIP action menu items under the EIP status submenu tree. +- Adds ``--version`` flag. Closes: #3816 +- Refactors EIPConnection to use LEAPConnection state machine. Closes: #3900 +- Include resource files and ui in the distrubution tarball. Closes: #3825 + +0.3.2 Sep 6 -- the "no crashes or anything" release: +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +- Fix up script in non-bundle linuces. Closes: #3450 +- Logout stops imap and smtp services. Closes: #3553 +- Properly daemonize polkit-gnome-authentication-agent. Closes: #3554 +- Set appropiate error on login cancel. Closes #3582. +- Fix gateway selection problem. Closes 3595. +- Fix typo in wizard: stablish -> establish. Closes #3615. +- Display Encrypted Mail instead of mx in wizard. Closes #3657. +- Fix save logs to file dialog freezing. Closes #3675. +- Complain if setup.py is run with python3. Closes: #3711 +- Enable preferences option in systray. Closes #3717. +- Make soledad emit failed signal for all kinds of socket error. +- Allow to selectively silence logs from different leap components. Closes: #3504 +- Add option to select gateway manually in the preferences panel. Closes #3505. +- Add preferences option to select the enabled services of a provider. Closes #3534. +- Refactor basic password checks. Closes #3552. +- Use dirspec instead of plain xdg. Closes #3574. +- Remove last page from wizard. Closes #3616. +- Display encrypted mail status in the tray. Closes #3659. + +0.3.1 Aug 23: ++++++++++++++ + +- Replace wizard images with the rainbow mask. Closes #3425. +- Update leap.common minimum version needed. +- Set the standalone flag before it's being used. Fixes #3426. +- Stop the twisted reactor adding the stop call to the call chain + instead of stopping it directly. Fixes #3406. +- Allow soledad initialization to retry if it times out. Closes: + #3413 +- Activate window when setting it visible. Also display Hide/Show + message in the tray icon taking into account the window + activation. Fixes #3433. +- Do not start IMAP daemon if mail was not selected among the + services. Fixes #3435. +- Reword RECONNECTING state of openvpn. Fixes #3429. +- Improve OpenVPN detection by searching for a specific leap-only + string in the command line. This makes it possible to run other + VPN instances while also using EIP. Fixes #3268 and #3364. +- OSX: Check for the tun.kext existence in /Library/Extensions + instead of /System/Library/Extensions. Fixes #3271. +- Use DELETE /1/logout to properly logout. Fixes #3510. +- Make the poll interval bigger to improve openvpn's internal + behavior. If it gets queried too many times per second, it's + behavior won't be good. Fixes #3430. +- Transforms usernames to lower case before they are used in the + registration and authentication. Closes #3541. +- Add filter option to the logger window. Closes #3407. +- Add a preference panel that lets you change your password. Closes + #3500 #2798 #3533. +- Move all client code into its own namespace + (leap.bitmask). Closes: #2959 +- Make mail fetch interval in imap service configurable via + environment variable. Closes: #3409 +- Update to new soledad package scheme (common, client and + server). Closes #3487. +- Fetch incoming mail when mail client logs in. Closes: #3525 +- Add first draft of the UI for Encrypted Mail. Closes #3499. + +0.3.0 Aug 9: +++++++++++++ + +- Add missing scripts does not stop if a command fails, also warns + the user if there was an error. Closes #3294. +- Replace 'Sign Out' with 'Log Out' and 'User' with + 'Username'. Closes #3319. +- Verify cacert existence before using it. Closes bug #3362. +- Properly handle login failures. Closes bug #3401. +- Bugfix, avoid getting negative rates. Closes #3274. +- Raise window when setting it as visible. Fixes #3374 +- Fail gracefully when the events port 8090 is in use by something + else. Fixes #3276. +- Validate the username in the login form against the same regexp as + the wizard registration form. Fixes #3214. +- Update text from the tray menu based on the visibility of the + window. Fixes #3400. +- Add check for outdated polkit file. Closes #3209. +- Add support for multiple schemas so we can support multiples api + versions. Closes #3310. +- Rebrand the client to be named Bitmask. Feature #3313. +- Add cancel button to login. Closes #3318. +- Add multiple schema support for SMTP. Closes #3403. +- Add multiple schema support for Soledad. Closes #3404. +- Update Transifex project name and translators' + documentation. Closes #3418. +- Add check for tuntap kext before launching openvpn. Closes: #2906 +- Accept flag for changing openvpn verbosity in logs. Closes: #3305 +- Add imap service to the client. Closes: #2579 +- Add pyside-uic support inside the virtualenv. This way it won't + fail to 'make' if the virtualenv is activated. Closes #3411. +- Reintegrate SMTP relay module. Closes #3375 +- Reintegrate Soledad into the client. Closes #3307. +- Support bundled gpg. Related to #3397. +- Set the default port for SMTP to be 2013. +- Display a more generic error message in the main window, and leave + the detailed one for the log. Closes #3373. + +0.2.4 Jul 26: ++++++++++++++ + +- Use the provider CA cert for every request once we have it + bootstrapped (TOFU). Closes #3227. +- Make calls to leap.common.events asynchronous. Closes #2937. +- Always logout when closing the app if the user previously signed + in. Fixes #3245. +- Make sure the domain field in provider.json is escaped to avoid + potential problems. Fixes #3244. +- Fix incorrect handling of locks in Windows so that stalled locks + do not avoid raising the first instance of the app. Closes: #2910 +- Use traffic rates instead of totals. Closes #2913 +- Allow to alternate between rates and total throughput for the + virtual interface. Closes: #3232 +- Reset rates/totals when terminating connection. Closes #3249 +- Fix a bug in the displayed magnitude for the up/down traffic rates + and totals. +- Force Cleanlooks style if we are running in a KDE environment, so + that it doesn't load potentially incompatible Qt libs. Fixes + #3194. +- Wrap long login status messages to 40 characters. Fixes #3124 +- Workaround a segmentation fault when emitting a signal with its + last parameter being None. Fixes #3083. +- Added IS_RELEASE_VERSION flag that allows us to use code only in + develop versions. Closes #3224. +- Try to terminate already running openvpn instances. Closes #2916 +- Linux: Dynamically generate policy file for polkit. Closes #3208 +- Workaround some OpenVPN problems with priviledge dropping and + routing. Fixes #3178 #3135 #3207 #3203 + +0.2.3 Jul 12: ++++++++++++++ + +- Adapt code to Soledad 0.2.1 api. +- Fix Main Window briefly display before the wizard on first + start. Closes Bug #2954. +- Bugfix: Remember should not be automatically set to + checked. Closes #2955. +- Bugfix: reload config if switching to a different provider. Closes + #3067. +- Bugfix: logger window's toggle button reflects window + state. Closes #3152. +- Set timeout for requests to 10 seconds globally, configurable from + leap.util.constants. Fixes #2878. +- Bugfix: display error message on registration problem. Closes + #3039. +- Make wizard use the main event loop, ensuring clean termination. +- Use cocoasudo for installing missing updown scripts. +- Bugfix: Systray Turn ON action fails because is not correctly + enabled/disabled. Closes #3125. +- Bugfix: wrong systray icon on startup. Closes #3147. +- Bugfix: parse line return in the logger window. Closes #3151. +- Do not log user data on registration. Fixes #3168. +- Add --log-append eip.log to windows EIP launcher options to save + the logs in case of any problems. Fixes #2054. +- OSX: Make the install_path relative to the launcher path instead + -f absolute. +- OSX: Fix icon display in cocoasudo. +- OSX: Raise window when showing if running on OSX. +- Bugfix: EIP status button moved to status panel. +- Check if there is no gateway to use and display correct + message. Close #2921. +- Reorder tray icons according new design. Closes #2919. +- Redirect stdout/stderr and twisted log to the logger. Closes + #3134. +- Improve LoggerWindow colors for easier debugging. +- Move the key manager to its own repository/package. + +0.2.2 Jun 28: ++++++++++++++ + +- Add support for the kde polkit daemon +- Handle 'Incorrect Password' exception (keyring) +- Select the configured domain in the providers combo box. Closes + #2693. +- Remember provider along with the username and password. Closes + #2755. +- Close the app on rejected wizard. Closes bug #2905. +- Only use the Keyring when it's using a known good backend. Closes + #2960 +- Update implementation and semantics of the supported and available + services by a provider. Closes bug #3032. +- Only show the question mark for a check being done if the previous + -ne passed. Fixes #2569. +- Fix main client window not restoring after minimized into + systray. Closes #2574 +- Set EIP different status icons depending on OS. Closes #2643. +- Reimplement openvpn invocation to use twisted ProcessProtocol +- Add runtime requirements checker, verifies that the requirements + are installed and in its correct versions. Closes #2563 +- Add centraliced logging facility, log history in a window. Closes + #2566 +- Improve wizard, hide registration widgets (labels, inputs, button) + and only display a message. Closes #2694 +- Clarify labels through the app (use of EIP) +- Check if the provider api version is supported. Closes feature + #2774. +- Autoselect VPN gateway based on timezone. Closes #2790. +- Disable vpn disconnect on logout. Closes #2795. +- Improve gateway selector based on timezone. It allows to use + multiple gateways in openvpn for redundancy. Closes #2894. +- Use cocoasudo in place of osascript for osx privilege escalation + during openvpn launch. +- Clicking in the tray icon will always show the context menu + instead of activating the window under certain + circumstances. Closes #2788 +- Autostart EIP whenever possible. Closes #2815 +- Update test suite, run_scripts and requirements to run smoothly + with buildbot. +- Add a copy of the processed requirements to util/ +- Display the default provider configured in the systray menu. Close + #2813 +- Make the login steps be a chain of defers in order to be able to + have more cancel points for the whole procedure. Closes #2571 +- Linux: check for up/down scripts and policy files and ask user for + permission to install them in a root-writeable location. Used from + within bundle or for broken installations. +- Integrate SMTP-Relay into the client. +- Integrate Soledad and KeyManager. +- Move the KeyManager from leap.common to leap-client. +- Only use one systray icon, repesenting the status for EIP. Closes + #2762 +- Properly set the binary manifest to the windows openvpn + binary. Closes #203 +- OSX: Add dialog with suggestion to install up/down scripts if + these not found. Closes: #1264, #2759, #2249 +- Workaround for PySide breaking with multiple inheritance. Closes + #2827 +- Refactor login to its own widget and remove Utils menu. Closes + #2789 +- Refactor the status bits out of the MainWindow to its own + StatusPanelWidget. Closes #2792 +- Save the default provider to be used for autostart EIP as + DefaultProvider in leap.conf. Closes #2793 +- Cleanly terminate openvpn process, sending SIGTERM and SIGKILL + after a while. Closes #2753 +- Use twisted's deferToThread and Deferreds to handle parallel tasks +- Use a qt4 reactor for twisted, for launching leap twisted + services. + +0.2.1 May 15: ++++++++++++++ + +- Rewrite most of the client based on the insight gained so far. +- Deselecting the remember checkbox makes the app not populate + user/password values on the login widget. Closes #2059 +- Rewording of setup steps in wizard, to make them more meaningful + to the non-technical user. Closes #2061 +- Fix typo in wizard. +- Fix multiple drawing of services if going back. +- Make registration errors show in red. +- Add a warning if EIP service needs admin password. Addresses part + -f #2062 +- Make traffic indicators display fixed precision. Closes #2114 +- Do not hide the application if the user right clicked the system + tray icon. +- Sanitize network-fetched content that is used to build openvpn + command. +- Avoids multiple instances of leap-client. Each new one just raises + the existing instance and quits. +- Use dark eip icons os osx. Closes #2130 +- Moves BaseConfig to leap.common.config. Closes #2164 +- Add handling for ASSIGN_IP state from OpenVPN in the mainwindow. +- Emit events notifying of the session_id and uid after + authentication so other services can make use of it. Closes #1957 +- Working packaging workflow with rewritten client, using + pyinstaller and platypus. +- Remove network checks temporarily until we find a good way of + doing it, and a good way to deal with them. +- Saves the token to allow token authenticated queries. +- Turn "leap" into namespace package, move common files to + leap_common package that can be shared by other LEAP projects. +- Support standalone configurations for distribution in thumbdrives + and the like. +- Add support for requests < 1.0.0 +- Tests infrastructure, and tests for crypto/srpauth and crypto/srpregister. +- Documentation updated for 0.2.1 release. +- Docstrings style changed to fit sphinx autodoc format. +- Add a simple UI to notify of pending updates. +- Add Windows support. +- Try to install TAP driver on Windows if no tap device is preset. diff --git a/MANIFEST.in b/MANIFEST.in index 876393da..73355b99 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -6,7 +6,7 @@ prune docs/covhtml include versioneer.py include LICENSE include README.rst -include CHANGELOG +include CHANGELOG.rst include src/leap/bitmask/util/reqs.txt include src/leap/bitmask/crypto/tests/wrongcert.pem diff --git a/README.rst b/README.rst index a4272c40..811cfdfa 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,6 @@ Bitmask ======= + *your internet encryption toolkit* .. image:: https://pypip.in/v/leap.bitmask/badge.png @@ -7,6 +8,7 @@ Bitmask **Bitmask** is the multiplatform desktop client for the services offered by `the LEAP Platform`_. + It is written in python using `PySide`_ and licensed under the GPL3. Currently we distribute pre-compiled bundles for Linux and OSX, with Windows bundles following soon. @@ -35,7 +37,7 @@ Bitmask depends on these libraries: Python packages are listed in ``pkg/requirements.pip`` and ``pkg/test-requirements.pip`` Getting dependencies under debian -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +++++++++++++++++++++++++++++++++++ With a Debian based system, to be able to run Bitmask you need to run the following command:: diff --git a/setup.py b/setup.py index 78c5b0fb..fd87e56c 100755 --- a/setup.py +++ b/setup.py @@ -168,25 +168,8 @@ setup( cmdclass=cmdclass, description=("The Internet Encryption Toolkit: " "Encrypted Internet Proxy and Encrypted Mail."), - # XXX unify the long_description on a file of its own, so we - # can reuse it easily. - long_description=( - "Bitmask is the multiplatform desktop client for the LEAP Platform." - "\n" - "The LEAP Encryption Access Project develops " - "a multi-year plan to secure everyday communication.\n " - "The Encrypted Internet Proxy (EIP) provides circumvention, location " - "anonymization, and traffic encryption in a hassle-free, " - "automatically self-configuring fashion.\n" - "Encrypted Mail offers automatic encryption and decryption for " - "both outgoing and incoming email, adding public key cryptography " - "to your mail without you ever having to worry about key distribution " - "or signature verification. \n" - "The Encrypted Mail services will run local SMTP and IMAP proxies " - "that, once you configure the mail client of your choice, will " - "automatically encrypt and decrypt your email using GPG encryption " - "under the hood." - ), + long_description=open('README.rst').read() + '\n\n\n' + + open('CHANGELOG.rst').read(), classifiers=trove_classifiers, install_requires=parsed_reqs, test_suite='nose.collector', -- cgit v1.2.3 From 56402b3820361e7a606b38a5aa76a30282c63c18 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 21 Oct 2013 15:22:44 -0200 Subject: add downloads link; mention windows support --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 811cfdfa..7a8329b9 100644 --- a/README.rst +++ b/README.rst @@ -10,11 +10,11 @@ Bitmask `the LEAP Platform`_. It is written in python using `PySide`_ and licensed under the GPL3. -Currently we distribute pre-compiled bundles for Linux and OSX, with Windows -bundles following soon. +Currently we distribute pre-compiled `bundles`_ for Linux, OSX and Windows. .. _`PySide`: http://qt-project.org/wiki/PySide .. _`the LEAP Platform`: https://github.com/leapcode/leap_platform +.. _`bundles`: https://downloads.leap.se/client/ Read the Docs! -- cgit v1.2.3 From 297694e06ffb1eb4b191cbc164bd1d7a8ba5f46b Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 16 Oct 2013 16:39:13 -0300 Subject: Update apt-get dependencies * Also, tweak different sections to be consistent with the new quickstart. * Squashed contributions by Jeremy (@bneg) * add note about authors.rst --- README.rst | 11 ++----- docs/dev/environment.rst | 15 +++++---- docs/dev/quickstart.rst | 81 ++++++++++++++++++++++++++++++++++++++++++++++++ docs/dev/workflow.rst | 5 +++ docs/index.rst | 1 + docs/testers/howto.rst | 12 +++---- 6 files changed, 103 insertions(+), 22 deletions(-) create mode 100644 docs/dev/quickstart.rst diff --git a/README.rst b/README.rst index 7a8329b9..a9af236e 100644 --- a/README.rst +++ b/README.rst @@ -41,7 +41,9 @@ Getting dependencies under debian With a Debian based system, to be able to run Bitmask you need to run the following command:: - $ sudo apt-get install openvpn python-pyside pyside-tools python-setuptools python-all-dev python-pip python-dev python-openssl + $ sudo apt-get install git python-dev python-setuptools + python-virtualenv python-pip python-openssl libsqlite3-dev g++ openvpn + pyside-tools python-pyside Installing ----------- @@ -102,13 +104,6 @@ Run Bitmask:: (bitmask)$ bitmask --debug - -If you are testing a new provider that doesn't have the proper certificates yet, you can use --danger flag, but **DO NOT use it on a regular basis**. - -**WARNING**: If you use the --danger flag you may be victim to a MITM_ attack without noticing. Use at your own risk. - -.. _MITM: http://en.wikipedia.org/wiki/Man-in-the-middle_attack - Testing ======= diff --git a/docs/dev/environment.rst b/docs/dev/environment.rst index e942b1cb..8e6fd89d 100644 --- a/docs/dev/environment.rst +++ b/docs/dev/environment.rst @@ -13,14 +13,14 @@ Cloning the repo :: - git clone git://leap.se/bitmask_client + git clone https://leap.se/git/?p=bitmask_client.git git checkout develop .. XXX change this when repo changes. Base Dependencies ------------------ -Bitmask depends on these libraries: +Bitmask depends on these base libraries: * `python 2.6 or 2.7` * `qt4` libraries (see also :ref:`Troubleshooting PySide install ` about how to install inside your virtualenv) @@ -29,13 +29,11 @@ Bitmask depends on these libraries: Debian ^^^^^^ -In debian-based systems:: +In debian-based systems, you can get everything you need: - $ apt-get install openvpn python-pyside python-openssl - -To install the software from sources:: - - $ apt-get install python-pip python-dev +.. include:: quickstart.rst + :start-after: begin-debian-deps + :end-before: end-debian-deps .. _virtualenv: @@ -122,6 +120,7 @@ If you *only* are running bitmask from inside a virtualenv, you will need to cop Missing Authentication agent ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. TODO I think we could be safely removing this section by now. If you are using linux and running a desktop other than unity or gnome, you might get an error saying that you are not running the authentication agent. For systems with gnome libraries installed you can launch it like this:: diff --git a/docs/dev/quickstart.rst b/docs/dev/quickstart.rst new file mode 100644 index 00000000..8f0e90dd --- /dev/null +++ b/docs/dev/quickstart.rst @@ -0,0 +1,81 @@ +Quickstart +========== + +**Assumptions:** These instructions were made on a clean Ubuntu 12.04.3 +system. + +**Goal:** With minimal effort or reading install the necessary packages +to build the latest development code for ``bitmask_client`` + +**Outcome:** At the end of these instructions, you should be able to run +the latest development branch for bitmask client, getting the GUI in debug +mode and connect to a LEAP provider (bitmask.net) + + +Prerequisites +------------- + +.. begin-debian-deps +:: + + $ sudo apt-get install git python-dev python-setuptools + python-virtualenv python-pip python-openssl libsqlite3-dev g++ openvpn + pyside-tools python-pyside + +.. python-qt4 ??? (for translations) +.. TODO I'm pretty sure python-qt4 shoudln't be there... + Nor libsqlite-dev, that's a bug in python-sqlcipher/soledad. + + +.. XXX any change HERE ^^^^ should be reflected also in README.rst. + From any other place in the documentation, it should be just included. + +.. end-debian-deps + +Clone the repo into your working directory, and checkout development branch:: + + $ git clone https://github.com/leapcode/bitmask_client + $ cd bitmask_client + $ git checkout develop + + +Create and activate the virtualenv, and symlink to your gloabal PySide install:: + + $ virtualenv . + $ source bin/activate + $ pkg/postmkvenv.sh + + +Python libraries +---------------- + +.. TODO Check! -- this step should not be needed. setup develop should do it for you. +Install python requirements:: + + $ pip install -r pkg/requirements.pip + +Install the bitmask package in development mode inside the virtualenv:: + + $ ./setup.py develop + +Compile the resource files:: + + $ make + +Copy necessary files into system folders, with root privileges:: + + $ sudo mkdir -p /etc/leap + $ sudo cp pkg/linux/resolv-update /etc/leap + $ sudo cp pkg/linux/polkit/net.openvpn.gui.leap.policy /usr/share/polkit-1/actions/ + + +Running +-------- + +Run ``bitmask_client`` in debug mode:: + + $ bitmask --debug + +You should see the ``bitmask_client`` window prompting to connect to an +existing node or add a new one. If not, something went wrong, maybe ask +on #leap-dev at irc.freenode.net diff --git a/docs/dev/workflow.rst b/docs/dev/workflow.rst index abd228c1..f217df24 100644 --- a/docs/dev/workflow.rst +++ b/docs/dev/workflow.rst @@ -90,3 +90,8 @@ Other methods ------------- Feel free to use any other methods like format-patch and mail or whatever method you prefer, although we recommend you follow the same workflow as we do. + +Contributors +------------ + +Please, add yourself to ``dev/authors.rst`` if you contribute code to Bitmask. diff --git a/docs/index.rst b/docs/index.rst index d0b0ff22..f210be8c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -44,6 +44,7 @@ If you want to contribute to the project, we wrote this for you. .. toctree:: :maxdepth: 1 + dev/quickstart dev/environment dev/tests dev/workflow diff --git a/docs/testers/howto.rst b/docs/testers/howto.rst index 1e276f7d..24a90de5 100644 --- a/docs/testers/howto.rst +++ b/docs/testers/howto.rst @@ -108,13 +108,13 @@ compact way suitable (ahem) also for non developers. Install dependencies ^^^^^^^^^^^^^^^^^^^^ -First, install all the base dependencies plus git, virtualenv and development -files needed to compile several extensions:: +First, install all the development files and dependencies needed to compile:: - apt-get install openvpn git-core python-dev python-pyside python-setuptools python-virtualenv + sudo apt-get install openvpn git-core python-dev python-pyside python-setuptools \ + python-virtualenv python-all-dev python-pip python-dev python-openssl git \ + libgnutls-dev python-qt4 g++ libsqlite3-dev -.. TODO Should review these dependencies. I think python-sqlite is missing, we - have an issue for that^^ +.. TODO Should review these dependencies. .. TODO we really should keep the dependencies in a single file that we are able to include, to avoid phasing out. @@ -132,7 +132,7 @@ Download and source the following script in the parent folder where you want you .. code-block:: bash - cd /tmp + cd /tmp wget https://raw.github.com/leapcode/bitmask_client/develop/pkg/scripts/bitmask_bootstrap.sh source bitmask_bootstrap.sh -- cgit v1.2.3 From 96e2bcb0a103130b20026c2f943e16205867ec80 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 16 Oct 2013 17:01:23 -0300 Subject: add include to testing howto too --- docs/testers/howto.rst | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/docs/testers/howto.rst b/docs/testers/howto.rst index 24a90de5..d9536632 100644 --- a/docs/testers/howto.rst +++ b/docs/testers/howto.rst @@ -108,16 +108,11 @@ compact way suitable (ahem) also for non developers. Install dependencies ^^^^^^^^^^^^^^^^^^^^ -First, install all the development files and dependencies needed to compile:: +First, install all the development files and dependencies needed to compile: - sudo apt-get install openvpn git-core python-dev python-pyside python-setuptools \ - python-virtualenv python-all-dev python-pip python-dev python-openssl git \ - libgnutls-dev python-qt4 g++ libsqlite3-dev - -.. TODO Should review these dependencies. - -.. TODO we really should keep the dependencies in a single file that we are able to - include, to avoid phasing out. +.. include:: ../dev/quickstart.rst + :start-after: begin-debian-deps + :end-before: end-debian-deps Bootstrap script -- cgit v1.2.3 From e1fee7f497c5b31e88600aa2d8702b9fef78951d Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 22 Oct 2013 10:49:40 -0200 Subject: Fixes to environment.rst. Closes: #4185 --- docs/dev/environment.rst | 57 ++++++++++++++++++++++++++++++++++++++---------- docs/dev/quickstart.rst | 6 +++-- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/docs/dev/environment.rst b/docs/dev/environment.rst index 8e6fd89d..596d833e 100644 --- a/docs/dev/environment.rst +++ b/docs/dev/environment.rst @@ -3,7 +3,7 @@ Setting up a development environment ==================================== -This document covers how to get an enviroment ready to contribute code to Bitmask. +This document covers how to get an enviroment ready to contribute code to Bitmask, with some explanations of what are we doing in each step along the way. For just the meat, check the :ref:`quickstart ` `section`. Cloning the repo ---------------- @@ -58,10 +58,14 @@ Read more about it in the `project documentation page - $ source /bin/activate +You first create a virtualenv in any directory that you like:: + + $ mkdir ~/Virtualenvs + $ virtualenv ~/Virtualenvs/bitmask + $ source ~/Virtualenvs/bitmask/bin/activate + +.. TODO use virtualenvwrapper + isis non-sudo recipe here .. _pysidevirtualenv: @@ -74,14 +78,10 @@ As a workaround, you can run the following script after creating your virtualenv $ pkg/postmkvenv.sh -A second option if that does not work for you would be to install PySide globally and pass the ``--site-packages`` option when you are creating your virtualenv:: - - $ apt-get install python-pyside - $ virtualenv --site-packages . +A second option if that does not work for you would be to install PySide globally and pass the ``--system-site-packages`` option when you are creating your virtualenv:: -After that, you must export ``LEAP_VENV_SKIP_PYSIDE`` to skip the isntallation:: - - $ export LEAP_VENV_SKIP_PYSIDE=1 + $ sudo apt-get install python-pyside + $ virtualenv --system-site-packages . And now you are ready to proceed with the next section. @@ -92,8 +92,32 @@ Install python dependencies You can install python dependencies with ``pip``. If you do it inside your working environment, they will be installed avoiding the need for administrative permissions:: - $ pip install -r pkg/requirements.pip + $ (bitmask) pip install -r pkg/requirements.pip + +.. _makeresources: + +Install Bitmask +--------------- + +We will be using setuptools **development mode** inside the virtualenv. It will +creaate a link from the local site-packages to your working directory. In this +way, your changes will always be in the installation path without need to +install the package you are working on.:: + $ (bitmask) python2 setup.py develop + +After this step, your Bitmask launcher will be located at +``~/Virtualenvs/bitmask/bin/bitmask``, and it will be in the path as long as you +have sourced your virtualenv. + +Make resources +-------------- + +We also need to compile the resource files:: + + $ (bitmask) make resources + +.. TODO need to make translations too? .. _copyscriptfiles: @@ -129,3 +153,12 @@ If you are using linux and running a desktop other than unity or gnome, you migh or if you are a kde user:: /usr/lib/kde4/libexec/polkit-kde-authentication-agent-1 & + +Running! +-------- + +If everything went well, you should be able to run your client by invoking +``bitmask``. If it does not get launched, or you just want to see more verbose +output, try the debug mode:: + + $ (bitmask) bitmask --debug diff --git a/docs/dev/quickstart.rst b/docs/dev/quickstart.rst index 8f0e90dd..978dc9e5 100644 --- a/docs/dev/quickstart.rst +++ b/docs/dev/quickstart.rst @@ -1,3 +1,5 @@ +.. _quickstart: + Quickstart ========== @@ -56,11 +58,11 @@ Install python requirements:: Install the bitmask package in development mode inside the virtualenv:: - $ ./setup.py develop + $ python2 setup.py develop Compile the resource files:: - $ make + $ make resources Copy necessary files into system folders, with root privileges:: -- cgit v1.2.3 From 1e1e65134474d65c00a0b5ed89c70fe46c56a1e5 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 22 Oct 2013 11:09:12 -0200 Subject: add prompt indication for the virtualenv --- docs/dev/environment.rst | 50 +++++++++++++++++++++++++++++++++++------------- docs/dev/quickstart.rst | 29 ++++++++++++++-------------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/docs/dev/environment.rst b/docs/dev/environment.rst index 596d833e..0f6366ef 100644 --- a/docs/dev/environment.rst +++ b/docs/dev/environment.rst @@ -3,7 +3,11 @@ Setting up a development environment ==================================== -This document covers how to get an enviroment ready to contribute code to Bitmask, with some explanations of what are we doing in each step along the way. For just the meat, check the :ref:`quickstart ` `section`. +This document covers how to get an enviroment ready to contribute code to +Bitmask, with some explanations of what are we doing in each step along the way. +For just the meat, check the :ref:`quickstart ` section. If you only +want to do a a quick fetch of the latest code for casual testing, you can use +the :ref:`bootstrap script ` instead. Cloning the repo ---------------- @@ -13,7 +17,8 @@ Cloning the repo :: - git clone https://leap.se/git/?p=bitmask_client.git + git clone https://leap.se/git/?p=bitmask_client.git bitmask + cd bitmask git checkout develop .. XXX change this when repo changes. @@ -64,6 +69,9 @@ You first create a virtualenv in any directory that you like:: $ mkdir ~/Virtualenvs $ virtualenv ~/Virtualenvs/bitmask $ source ~/Virtualenvs/bitmask/bin/activate + (bitmask)$ + +Note the change in the prompt. .. TODO use virtualenvwrapper + isis non-sudo recipe here @@ -76,7 +84,7 @@ If you attempt to install PySide inside a virtualenv as part of the rest of the As a workaround, you can run the following script after creating your virtualenv. It will symlink to your global PySide installation (*this is the recommended way if you are running a debian-based system*):: - $ pkg/postmkvenv.sh + (bitmask)$ pkg/postmkvenv.sh A second option if that does not work for you would be to install PySide globally and pass the ``--system-site-packages`` option when you are creating your virtualenv:: @@ -90,32 +98,48 @@ And now you are ready to proceed with the next section. Install python dependencies ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You can install python dependencies with ``pip``. If you do it inside your working environment, they will be installed avoiding the need for administrative permissions:: +You can install python dependencies with ``pip``. If you do it inside your +working environment, they will be installed avoiding the need for administrative +permissions:: - $ (bitmask) pip install -r pkg/requirements.pip + (bitmask)$ pip install -r pkg/requirements.pip -.. _makeresources: +This step is not strictly needed, since the ``setup.py develop`` in the next +paragraph with also fetch the needed dependencies. But you need to know abou it: +when you or any person in the development team will be adding a new dependency, +you will have to repeat this command so that the new dependencies are installed +inside your virtualenv. + +.. _installbitmaskdevelop: Install Bitmask --------------- -We will be using setuptools **development mode** inside the virtualenv. It will -creaate a link from the local site-packages to your working directory. In this -way, your changes will always be in the installation path without need to -install the package you are working on.:: +Normally we would install the ``leap.bitmask`` package as any other package +inside the virtualenv. +But, instead, we will be using setuptools **development mode**. The difference +is that, instead of installing the package in a permanent location in your +regular installed packages path, it will create a link from the local +site-packages to your working directory. In this way, your changes will always +be in the installation path without need to install the package you are working +on.:: - $ (bitmask) python2 setup.py develop + (bitmask)$ python2 setup.py develop After this step, your Bitmask launcher will be located at ``~/Virtualenvs/bitmask/bin/bitmask``, and it will be in the path as long as you have sourced your virtualenv. +.. _makeresources: + Make resources -------------- We also need to compile the resource files:: - $ (bitmask) make resources + (bitmask)$ make resources + +You need to repeat this step each time you change a ``.ui`` file. .. TODO need to make translations too? @@ -161,4 +185,4 @@ If everything went well, you should be able to run your client by invoking ``bitmask``. If it does not get launched, or you just want to see more verbose output, try the debug mode:: - $ (bitmask) bitmask --debug + (bitmask)$ bitmask --debug diff --git a/docs/dev/quickstart.rst b/docs/dev/quickstart.rst index 978dc9e5..8ef7dfb8 100644 --- a/docs/dev/quickstart.rst +++ b/docs/dev/quickstart.rst @@ -13,6 +13,9 @@ to build the latest development code for ``bitmask_client`` the latest development branch for bitmask client, getting the GUI in debug mode and connect to a LEAP provider (bitmask.net) +If you want to know what each step is for, check +:ref:`this other section `. + Prerequisites ------------- @@ -36,8 +39,8 @@ Prerequisites Clone the repo into your working directory, and checkout development branch:: - $ git clone https://github.com/leapcode/bitmask_client - $ cd bitmask_client + $ git clone https://github.com/leapcode/bitmask_client bitmask + $ cd bitmask $ git checkout develop @@ -45,30 +48,26 @@ Create and activate the virtualenv, and symlink to your gloabal PySide install:: $ virtualenv . $ source bin/activate - $ pkg/postmkvenv.sh + (bitmask)$ pkg/postmkvenv.sh Python libraries ---------------- -.. TODO Check! -- this step should not be needed. setup develop should do it for you. -Install python requirements:: - - $ pip install -r pkg/requirements.pip - -Install the bitmask package in development mode inside the virtualenv:: +Install the bitmask package in development mode inside the virtualenv. This will +also install the needed dependencies:: - $ python2 setup.py develop + (bitmask)$ python2 setup.py develop Compile the resource files:: - $ make resources + (bitmask)$ make resources Copy necessary files into system folders, with root privileges:: - $ sudo mkdir -p /etc/leap - $ sudo cp pkg/linux/resolv-update /etc/leap - $ sudo cp pkg/linux/polkit/net.openvpn.gui.leap.policy /usr/share/polkit-1/actions/ + (bitmask)$ sudo mkdir -p /etc/leap + (bitmask)$ sudo cp pkg/linux/resolv-update /etc/leap + (bitmask)$ sudo cp pkg/linux/polkit/net.openvpn.gui.leap.policy /usr/share/polkit-1/actions/ Running @@ -76,7 +75,7 @@ Running Run ``bitmask_client`` in debug mode:: - $ bitmask --debug + (bitmask)$ bitmask --debug You should see the ``bitmask_client`` window prompting to connect to an existing node or add a new one. If not, something went wrong, maybe ask -- cgit v1.2.3 From e4ede90a3e20bd9b023fed12d6d72db3fcc380ab Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 22 Oct 2013 11:20:20 -0200 Subject: add pip install --- README.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index a9af236e..4bebc180 100644 --- a/README.rst +++ b/README.rst @@ -48,10 +48,15 @@ With a Debian based system, to be able to run Bitmask you need to run the follow Installing ----------- -After getting the source and installing all the dependencies, proceed to install ``bitmask`` package:: +Quick install, from the cheese shop:: + + $ sudo pip install leap.bitmask + +If you prefer to install from sources:: + + $ make + $ sudo python2 setup.py install - $ make - $ sudo python2 setup.py install Running ------- -- cgit v1.2.3 From 3a98bfed008fa1e02a7f5a63d5b9bc5e94ee630d Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 23 Oct 2013 15:59:48 -0200 Subject: use coloredlogs optionally --- src/leap/bitmask/app.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/leap/bitmask/app.py b/src/leap/bitmask/app.py index 40a77075..3bb9c8c3 100644 --- a/src/leap/bitmask/app.py +++ b/src/leap/bitmask/app.py @@ -39,7 +39,6 @@ # M:::::::::::~NMMM7???7MMMM:::::::::::::::::::::::NMMMI??I7MMMM:::::::::::::M # M::::::::::::::7MMMMMMM+:::::::::::::::::::::::::::?MMMMMMMZ:::::::::::::::M # (thanks to: http://www.glassgiant.com/ascii/) - import logging import signal import sys @@ -105,9 +104,16 @@ def add_logger_handlers(debug=False, logfile=None): formatter = logging.Formatter(log_format) # Console handler - console = logging.StreamHandler() - console.setLevel(level) - console.setFormatter(formatter) + try: + import coloredlogs + console = coloredlogs.ColoredStreamHandler(level=level) + except ImportError: + console = logging.StreamHandler() + console.setLevel(level) + console.setFormatter(formatter) + using_coloredlog = False + else: + using_coloredlog = True silencer = log_silencer.SelectiveSilencerFilter() console.addFilter(silencer) @@ -131,6 +137,9 @@ def add_logger_handlers(debug=False, logfile=None): logger.addHandler(fileh) logger.debug('File handler plugged!') + if not using_coloredlog: + replace_stdout_stderr_with_logging(logger) + return logger @@ -185,7 +194,6 @@ def main(): BaseConfig.standalone = standalone logger = add_logger_handlers(debug, logfile) - replace_stdout_stderr_with_logging(logger) # And then we import all the other stuff from leap.bitmask.gui import locale_rc -- cgit v1.2.3 From d4398c52acc54fb27a4b8bba2735a41f55b8f402 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 17 Oct 2013 12:04:12 -0300 Subject: Mail State Machine refactor. Closes: #4059 --- pkg/requirements.pip | 1 + src/leap/bitmask/gui/mail_status.py | 105 +++--- src/leap/bitmask/gui/mainwindow.py | 195 +++------- src/leap/bitmask/gui/statemachines.py | 414 ++++++++++++++++++++- src/leap/bitmask/services/connections.py | 10 +- src/leap/bitmask/services/eip/connection.py | 2 +- src/leap/bitmask/services/mail/conductor.py | 383 +++++++++++++++++++ src/leap/bitmask/services/mail/connection.py | 103 +++++ .../services/soledad/soledadbootstrapper.py | 4 +- 9 files changed, 1007 insertions(+), 210 deletions(-) create mode 100644 src/leap/bitmask/services/mail/conductor.py create mode 100644 src/leap/bitmask/services/mail/connection.py diff --git a/pkg/requirements.pip b/pkg/requirements.pip index 458db39c..98610fbb 100644 --- a/pkg/requirements.pip +++ b/pkg/requirements.pip @@ -16,6 +16,7 @@ twisted qt4reactor python-daemon # this should not be needed for Windows. keyring +zope.proxy leap.common>=0.3.4 leap.soledad.client>=0.4.0 diff --git a/src/leap/bitmask/gui/mail_status.py b/src/leap/bitmask/gui/mail_status.py index 83533666..c2c06dbb 100644 --- a/src/leap/bitmask/gui/mail_status.py +++ b/src/leap/bitmask/gui/mail_status.py @@ -50,6 +50,8 @@ class MailStatusWidget(QtGui.QWidget): QtGui.QWidget.__init__(self, parent) self._systray = None + self._disabled = True + self._started = False self.ui = Ui_MailStatusWidget() self.ui.setupUi(self) @@ -98,29 +100,16 @@ class MailStatusWidget(QtGui.QWidget): callback=self._mail_handle_soledad_events, reqcbk=lambda req, resp: None) - register(signal=proto.SMTP_SERVICE_STARTED, - callback=self._mail_handle_smtp_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.SMTP_SERVICE_FAILED_TO_START, - callback=self._mail_handle_smtp_events, - reqcbk=lambda req, resp: None) - - register(signal=proto.IMAP_SERVICE_STARTED, + register(signal=proto.IMAP_UNREAD_MAIL, callback=self._mail_handle_imap_events, reqcbk=lambda req, resp: None) - - register(signal=proto.IMAP_SERVICE_FAILED_TO_START, + register(signal=proto.IMAP_SERVICE_STARTED, callback=self._mail_handle_imap_events, reqcbk=lambda req, resp: None) - - register(signal=proto.IMAP_UNREAD_MAIL, + register(signal=proto.SMTP_SERVICE_STARTED, callback=self._mail_handle_imap_events, reqcbk=lambda req, resp: None) - self._smtp_started = False - self._imap_started = False - self._soledad_event.connect( self._mail_handle_soledad_events_slot) self._imap_event.connect( @@ -176,6 +165,9 @@ class MailStatusWidget(QtGui.QWidget): """ # TODO: Figure out how to handle this with the two status in different # classes + # XXX right now we could connect the state transition signals of the + # two connection machines (EIP/Mail) to a class that keeps track of the + # state -- kali # status = self.tr("Encrypted Internet: {0}").format(self._eip_status) # status += '\n' # status += self.tr("Mail is {0}").format(self._mx_status) @@ -292,11 +284,9 @@ class MailStatusWidget(QtGui.QWidget): """ # We want to ignore this kind of events once everything has # started - if self._smtp_started and self._imap_started: + if self._started: return - self._set_mail_status(self.tr("Starting..."), ready=1) - ext_status = "" if req.event == proto.KEYMANAGER_LOOKING_FOR_KEY: @@ -340,14 +330,9 @@ class MailStatusWidget(QtGui.QWidget): ext_status = "" if req.event == proto.SMTP_SERVICE_STARTED: - ext_status = self.tr("SMTP has started...") self._smtp_started = True - if self._smtp_started and self._imap_started: - self._set_mail_status(self.tr("ON"), ready=2) - ext_status = "" elif req.event == proto.SMTP_SERVICE_FAILED_TO_START: ext_status = self.tr("SMTP failed to start, check the logs.") - self._set_mail_status(self.tr("Failed")) else: leap_assert(False, "Don't know how to handle this state: %s" @@ -355,6 +340,8 @@ class MailStatusWidget(QtGui.QWidget): self._set_mail_status(ext_status, ready=2) + # ----- XXX deprecate (move to mail conductor) + def _mail_handle_imap_events(self, req): """ Callback for the IMAP events @@ -376,27 +363,17 @@ class MailStatusWidget(QtGui.QWidget): """ ext_status = None - if req.event == proto.IMAP_SERVICE_STARTED: - ext_status = self.tr("IMAP has started...") - self._imap_started = True - if self._smtp_started and self._imap_started: - self._set_mail_status(self.tr("ON"), ready=2) - ext_status = "" - elif req.event == proto.IMAP_SERVICE_FAILED_TO_START: - ext_status = self.tr("IMAP failed to start, check the logs.") - self._set_mail_status(self.tr("Failed")) - elif req.event == proto.IMAP_UNREAD_MAIL: - if self._smtp_started and self._imap_started: + if req.event == proto.IMAP_UNREAD_MAIL: + + if self._started: + print "printing foo" if req.content != "0": self._set_mail_status(self.tr("%s Unread Emails") % (req.content,), ready=2) else: self._set_mail_status("", ready=2) - else: - leap_assert(False, # XXX ??? - "Don't know how to handle this state: %s" - % (req.event)) - + elif req.event == proto.IMAP_SERVICE_STARTED: + self._imap_started = True if ext_status is not None: self._set_mail_status(ext_status, ready=1) @@ -414,8 +391,50 @@ class MailStatusWidget(QtGui.QWidget): """ self._set_mail_status(self.tr("Disabled"), -1) - def stopped_mail(self): + # statuses + + # XXX make the signal emit the label and state. + + @QtCore.Slot() + def mail_state_disconnected(self): + """ + Displays the correct UI for the disconnected state. + """ + # XXX this should handle the disabled state better. + self._started = False + if self._disabled: + self.mail_state_disabled() + else: + self._set_mail_status(self.tr("OFF"), -1) + + @QtCore.Slot() + def mail_state_connecting(self): + """ + Displays the correct UI for the connecting state. + """ + self._disabled = False + self._started = True + self._set_mail_status(self.tr("Starting..."), 1) + + @QtCore.Slot() + def mail_state_disconnecting(self): + """ + Displays the correct UI for the connecting state. + """ + self._set_mail_status(self.tr("Disconnecting..."), 1) + + @QtCore.Slot() + def mail_state_connected(self): + """ + Displays the correct UI for the connected state. + """ + self._set_mail_status(self.tr("ON"), 2) + + @QtCore.Slot() + def mail_state_disabled(self): """ - Displayes the correct UI for the stopped state. + Displays the correct UI for the disabled state. """ - self._set_mail_status(self.tr("OFF")) + self._disabled = True + self._set_mail_status( + self.tr("You must be logged in to use encrypted email."), -1) diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index f5631c69..dddd53da 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -24,6 +24,7 @@ import keyring from PySide import QtCore, QtGui from twisted.internet import threads +from zope.proxy import ProxyBase, setProxiedObject, sameProxiedObjects from leap.bitmask import __version__ as VERSION from leap.bitmask.config.leapsettings import LeapSettings @@ -39,18 +40,15 @@ from leap.bitmask.gui.mail_status import MailStatusWidget from leap.bitmask.gui.wizard import Wizard from leap.bitmask import provider -from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper -from leap.bitmask.services.eip.eipbootstrapper import EIPBootstrapper -from leap.bitmask.services.eip import eipconfig -# XXX: Soledad might not work out of the box in Windows, issue #2932 -from leap.bitmask.services.soledad.soledadbootstrapper import \ - SoledadBootstrapper -from leap.bitmask.services.mail.smtpbootstrapper import SMTPBootstrapper -from leap.bitmask.services.mail import imap from leap.bitmask.platform_init import IS_WIN, IS_MAC from leap.bitmask.platform_init.initializers import init_platform +from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper +from leap.bitmask.services.mail import conductor as mail_conductor + +from leap.bitmask.services.eip import eipconfig from leap.bitmask.services.eip import get_openvpn_management +from leap.bitmask.services.eip.eipbootstrapper import EIPBootstrapper from leap.bitmask.services.eip.connection import EIPConnection from leap.bitmask.services.eip.vpnprocess import VPN from leap.bitmask.services.eip.vpnprocess import OpenVPNAlreadyRunning @@ -62,12 +60,12 @@ from leap.bitmask.services.eip.linuxvpnlauncher import EIPNoPkexecAvailable from leap.bitmask.services.eip.linuxvpnlauncher import \ EIPNoPolkitAuthAgentAvailable from leap.bitmask.services.eip.darwinvpnlauncher import EIPNoTunKextLoaded +from leap.bitmask.services.soledad.soledadbootstrapper import \ + SoledadBootstrapper from leap.bitmask.util.keyring_helpers import has_keyring from leap.bitmask.util.leap_log_handler import LeapLogHandler -from leap.bitmask.services.mail.smtpconfig import SMTPConfig - if IS_WIN: from leap.bitmask.platform_init.locks import WindowsLock from leap.bitmask.platform_init.locks import raise_window_ack @@ -93,10 +91,6 @@ class MainWindow(QtGui.QMainWindow): # Keyring KEYRING_KEY = "bitmask" - # SMTP - PORT_KEY = "port" - IP_KEY = "ip_address" - OPENVPN_SERVICE = "openvpn" MX_SERVICE = "mx" @@ -257,10 +251,6 @@ class MainWindow(QtGui.QMainWindow): self._soledad_bootstrapper.soledad_failed.connect( self._mail_status.set_soledad_failed) - self._smtp_bootstrapper = SMTPBootstrapper() - self._smtp_bootstrapper.download_config.connect( - self._smtp_bootstrapped_stage) - self.ui.action_about_leap.triggered.connect(self._about) self.ui.action_quit.triggered.connect(self.quit) self.ui.action_wizard.triggered.connect(self._launch_wizard) @@ -307,12 +297,13 @@ class MainWindow(QtGui.QMainWindow): # Services signals/slots connection self.new_updates.connect(self._react_to_new_updates) + + # XXX should connect to mail_conductor.start_mail_service instead + self.soledad_ready.connect(self._start_smtp_bootstrapping) self.soledad_ready.connect(self._start_imap_service) - self.soledad_ready.connect(self._set_soledad_ready) self.mail_client_logged_in.connect(self._fetch_incoming_mail) self.logout.connect(self._stop_imap_service) self.logout.connect(self._stop_smtp_service) - self.logout.connect(self._mail_status.stopped_mail) ################################# end Qt Signals connection ######## @@ -325,17 +316,18 @@ class MainWindow(QtGui.QMainWindow): self._bypass_checks = bypass_checks - self._soledad = None - self._soledad_ready = False - self._keymanager = None - self._smtp_service = None - self._smtp_port = None - self._imap_service = None + # We initialize Soledad and Keymanager instances as + # transparent proxies, so we can pass the reference freely + # around. + self._soledad = ProxyBase(None) + self._keymanager = ProxyBase(None) self._login_defer = None self._download_provider_defer = None - self._smtp_config = SMTPConfig() + self._mail_conductor = mail_conductor.MailConductor( + self._soledad, self._keymanager) + self._mail_conductor.connect_mail_signals(self._mail_status) # Eip machine is a public attribute where the state machine for # the eip connection will be available to the different components. @@ -347,6 +339,7 @@ class MainWindow(QtGui.QMainWindow): self.eip_machine = None # start event machines self.start_eip_machine() + self._mail_conductor.start_mail_machine(parent=self) if self._first_run(): self._wizard_firstrun = True @@ -460,7 +453,7 @@ class MainWindow(QtGui.QMainWindow): """ preferences_window = PreferencesWindow(self, self._srp_auth) - if self._soledad_ready: + if sameProxiedObjects(self._soledad, None): preferences_window.set_soledad_ready(self._soledad) else: self.soledad_ready.connect( @@ -478,16 +471,6 @@ class MainWindow(QtGui.QMainWindow): """ EIPPreferencesWindow(self).show() - def _set_soledad_ready(self): - """ - SLOT - TRIGGERS: - self.soledad_ready - - It sets the soledad object as ready to use. - """ - self._soledad_ready = True - # # updates # @@ -803,6 +786,7 @@ class MainWindow(QtGui.QMainWindow): provider configuration if it's not present, otherwise will emit the corresponding signals inmediately """ + # XXX should rename this provider, name clash. provider = self._login_widget.get_selected_provider() pb = self._provider_bootstrapper @@ -823,6 +807,7 @@ class MainWindow(QtGui.QMainWindow): :type data: dict """ if data[self._provider_bootstrapper.PASSED_KEY]: + # XXX should rename this provider, name clash. provider = self._login_widget.get_selected_provider() # If there's no loaded provider or @@ -1023,114 +1008,58 @@ class MainWindow(QtGui.QMainWindow): logger.debug("ERROR on soledad bootstrapping:") logger.error("%r" % data[self._soledad_bootstrapper.ERROR_KEY]) return - else: - logger.debug("Done bootstrapping Soledad") - self._soledad = self._soledad_bootstrapper.soledad - self._keymanager = self._soledad_bootstrapper.keymanager + logger.debug("Done bootstrapping Soledad") + + # Update the proxy objects to point to + # the initialized instances. + setProxiedObject(self._soledad, + self._soledad_bootstrapper.soledad) + setProxiedObject(self._keymanager, + self._soledad_bootstrapper.keymanager) # Ok, now soledad is ready, so we can allow other things that # depend on soledad to start. # this will trigger start_imap_service + # and start_smtp_boostrapping self.soledad_ready.emit() - # TODO connect all these activations to the soledad_ready - # signal so the logic is clearer to follow. - - if self._provider_config.provides_mx() and \ - self._enabled_services.count(self.MX_SERVICE) > 0: - self._smtp_bootstrapper.run_smtp_setup_checks( - self._provider_config, - self._smtp_config, - True) - ################################################################### # Service control methods: smtp - def _smtp_bootstrapped_stage(self, data): + @QtCore.Slot() + def _start_smtp_bootstrapping(self): """ SLOT TRIGGERS: - self._smtp_bootstrapper.download_config - - If there was a problem, displays it, otherwise it does nothing. - This is used for intermediate bootstrapping stages, in case - they fail. - - :param data: result from the bootstrapping stage for Soledad - :type data: dict - """ - passed = data[self._smtp_bootstrapper.PASSED_KEY] - if not passed: - logger.error(data[self._smtp_bootstrapper.ERROR_KEY]) - return - logger.debug("Done bootstrapping SMTP") - self._check_smtp_config() - - def _check_smtp_config(self): - """ - Checks smtp config and tries to download smtp client cert if needed. + self.soledad_ready """ - hosts = self._smtp_config.get_hosts() - # TODO handle more than one host and define how to choose - if len(hosts) > 0: - hostname = hosts.keys()[0] - logger.debug("Using hostname %s for SMTP" % (hostname,)) - host = hosts[hostname][self.IP_KEY].encode("utf-8") - port = hosts[hostname][self.PORT_KEY] - - client_cert = self._smtp_config.get_client_cert_path( + # TODO for simmetry, this should be called start_smtp_service + # (and delegate all the checks to the conductor) + if self._provider_config.provides_mx() and \ + self._enabled_services.count(self.MX_SERVICE) > 0: + self._mail_conductor.smtp_bootstrapper.run_smtp_setup_checks( self._provider_config, - about_to_download=True) - - if not os.path.isfile(client_cert): - self._smtp_bootstrapper._download_client_certificates() - if os.path.isfile(client_cert): - self._start_smtp_service(host, port, client_cert) - else: - logger.warning("Tried to download email client " - "certificate, but could not find any") - - else: - logger.warning("No smtp hosts configured") - - def _start_smtp_service(self, host, port, cert): - """ - Starts the smtp service. - """ - # TODO Make the encrypted_only configurable - # TODO pick local smtp port in a better way - # TODO remove hard-coded port and let leap.mail set - # the specific default. - - from leap.mail.smtp import setup_smtp_relay - self._smtp_service, self._smtp_port = setup_smtp_relay( - port=2013, - keymanager=self._keymanager, - smtp_host=host, - smtp_port=port, - smtp_cert=cert, - smtp_key=cert, - encrypted_only=False) + self._mail_conductor.smtp_config, + download_if_needed=True) + # XXX --- should remove from here, and connecte directly to the state + # machine. + @QtCore.Slot() def _stop_smtp_service(self): """ SLOT TRIGGERS: self.logout """ - # There is a subtle difference here: - # we are stopping the factory for the smtp service here, - # but in the imap case we are just stopping the fetcher. - if self._smtp_service is not None: - logger.debug('Stopping smtp service.') - self._smtp_port.stopListening() - self._smtp_service.doStop() + # TODO call stop_mail_service + self._mail_conductor.stop_smtp_service() ################################################################### # Service control methods: imap + @QtCore.Slot() def _start_imap_service(self): """ SLOT @@ -1139,11 +1068,7 @@ class MainWindow(QtGui.QMainWindow): """ if self._provider_config.provides_mx() and \ self._enabled_services.count(self.MX_SERVICE) > 0: - logger.debug('Starting imap service') - - self._imap_service = imap.start_imap_service( - self._soledad, - self._keymanager) + self._mail_conductor.start_imap_service() def _on_mail_client_logged_in(self, req): """ @@ -1151,30 +1076,25 @@ class MainWindow(QtGui.QMainWindow): """ self.mail_client_logged_in.emit() + @QtCore.Slot() def _fetch_incoming_mail(self): """ SLOT TRIGGERS: self.mail_client_logged_in """ - # TODO have a mutex over fetch operation. - if self._imap_service: - logger.debug('Client connected, fetching mail...') - self._imap_service.fetch() + # TODO connect signal directly!!! + self._mail_conductor.fetch_incoming_mail() + @QtCore.Slot() def _stop_imap_service(self): """ SLOT TRIGGERS: self.logout """ - # There is a subtle difference here: - # we are just stopping the fetcher here, - # but in the smtp case we are stopping the factory. - # We should homogenize both services. - if self._imap_service is not None: - logger.debug('Stopping imap service.') - self._imap_service.stop() + # TODO call stop_mail_service + self._mail_conductor.stop_imap_service() # end service control methods (imap) @@ -1623,8 +1543,8 @@ class MainWindow(QtGui.QMainWindow): if ok: self._logged_user = None - self._login_widget.logged_out() + self._mail_status.mail_state_disabled() else: self._login_widget.set_login_status( @@ -1700,8 +1620,7 @@ class MainWindow(QtGui.QMainWindow): """ logger.debug('About to quit, doing cleanup...') - if self._imap_service is not None: - self._imap_service.stop() + self._mail_conductor.stop_imap_service() if self._srp_auth is not None: if self._srp_auth.get_session_id() is not None or \ diff --git a/src/leap/bitmask/gui/statemachines.py b/src/leap/bitmask/gui/statemachines.py index 94726720..ee16a4c6 100644 --- a/src/leap/bitmask/gui/statemachines.py +++ b/src/leap/bitmask/gui/statemachines.py @@ -19,7 +19,8 @@ State machines for the Bitmask app. """ import logging -from PySide.QtCore import QStateMachine, QState +from PySide import QtCore +from PySide.QtCore import QStateMachine, QState, Signal from PySide.QtCore import QObject from leap.bitmask.services import connections @@ -36,28 +37,255 @@ _CON = "connecting" _DIS = "disconnecting" -class IntermediateState(QState): +class SignallingState(QState): """ - Intermediate state that emits a custom signal on entry + A state that emits a custom signal on entry. """ - def __init__(self, signal): + def __init__(self, signal, parent=None, name=None): """ Initializer. :param signal: the signal to be emitted on entry on this state. :type signal: QtCore.QSignal """ - super(IntermediateState, self).__init__() + super(SignallingState, self).__init__(parent) self._signal = signal + self._name = name def onEntry(self, *args): """ Emits the signal on entry. """ - logger.debug('IntermediateState entered. Emitting signal ...') + logger.debug('State %s entered. Emitting signal ...' + % (self._name + self.__class__.__name__)) if self._signal is not None: self._signal.emit() +class States(object): + """ + States for composite objects + """ + + class Off(SignallingState): + pass + + class Connecting(SignallingState): + pass + + class On(SignallingState): + pass + + class Disconnecting(SignallingState): + pass + + class StepsTrack(QObject): + state_change = Signal() + + def __init__(self, target): + super(States.StepsTrack, self).__init__() + self.received = set([]) + self.target = set(target) + + def is_all_done(self): + return all([ev in self.target for ev in self.received]) + + def is_any_done(self): + return any([ev in self.target for ev in self.received]) + + def seen(self, _type): + if _type in self.target: + self.received.add(_type) + + def reset_seen(self): + self.received = set([]) + + class TransitionOR(QtCore.QSignalTransition): + + def __init__(self, state): + super(States.TransitionOR, self).__init__( + state, QtCore.SIGNAL('state_change()')) + self.state = state + + def eventTest(self, e): + self.state.seen(e.type()) + done = self.state.is_any_done() + if done: + self.state.reset_seen() + return done + + def onTransition(self, e): + pass + + class TransitionAND(QtCore.QSignalTransition): + + def __init__(self, state): + super(States.TransitionAND, self).__init__( + state, QtCore.SIGNAL('state_change()')) + self.state = state + + def eventTest(self, e): + self.state.seen(e.type()) + done = self.state.is_all_done() + if done: + self.state.reset_seen() + return done + + def onTransition(self, e): + pass + + +class CompositeEvent(QtCore.QEvent): + def __init__(self): + super(CompositeEvent, self).__init__( + QtCore.QEvent.Type(self.ID)) + + +class Composite(object): + # TODO we should generate the connectingEvents dinamycally, + # depending on how much composite states do we get. + # This only supports up to 2 composite states. + + class ConnectingEvent1(CompositeEvent): + ID = QtCore.QEvent.User + 1 + + class ConnectingEvent2(CompositeEvent): + ID = QtCore.QEvent.User + 2 + + class ConnectedEvent1(CompositeEvent): + ID = QtCore.QEvent.User + 3 + + class ConnectedEvent2(CompositeEvent): + ID = QtCore.QEvent.User + 4 + + class DisconnectingEvent1(CompositeEvent): + ID = QtCore.QEvent.User + 5 + + class DisconnectingEvent2(CompositeEvent): + ID = QtCore.QEvent.User + 6 + + class DisconnectedEvent1(CompositeEvent): + ID = QtCore.QEvent.User + 7 + + class DisconnectedEvent2(CompositeEvent): + ID = QtCore.QEvent.User + 8 + + +class Events(QtCore.QObject): + """ + A Wrapper object for containing the events that will be + posted to a composite state machine. + """ + def __init__(self, parent=None): + """ + Initializes the QObject with the given parent. + """ + QtCore.QObject.__init__(self, parent) + + +class CompositeMachine(QStateMachine): + + def __init__(self, parent=None): + QStateMachine.__init__(self, parent) + + # events + self.events = Events(parent) + self.create_events() + + def create_events(self): + """ + Creates a bunch of events to be posted to the state machine when + the transitions say so. + """ + # XXX refactor into a dictionary? + self.events.con_ev1 = Composite.ConnectingEvent1() + self.events.con_ev2 = Composite.ConnectingEvent2() + self.events.on_ev1 = Composite.ConnectedEvent1() + self.events.on_ev2 = Composite.ConnectedEvent2() + self.events.dis_ev1 = Composite.DisconnectingEvent1() + self.events.dis_ev2 = Composite.DisconnectingEvent2() + self.events.off_ev1 = Composite.DisconnectedEvent1() + self.events.off_ev2 = Composite.DisconnectedEvent2() + + def beginSelectTransitions(self, e): + """ + Weird. Having this method makes underlying backtraces + to appear magically on the transitions. + :param e: the received event + :type e: QEvent + """ + pass + + def _connect_children(self, child1, child2): + """ + Connects the state transition signals for children machines. + + :param child1: the first child machine + :type child1: QStateMachine + :param child2: the second child machine + :type child2: QStateMachine + """ + # TODO refactor and generalize for composites + # of more than 2 connections. + + c1 = child1.conn + c1.qtsigs.connecting_signal.connect(self.con_ev1_slot) + c1.qtsigs.connected_signal.connect(self.on_ev1_slot) + c1.qtsigs.disconnecting_signal.connect(self.dis_ev1_slot) + c1.qtsigs.disconnected_signal.connect(self.off_ev1_slot) + + c2 = child2.conn + c2.qtsigs.connecting_signal.connect(self.con_ev2_slot) + c2.qtsigs.connected_signal.connect(self.on_ev2_slot) + c2.qtsigs.disconnecting_signal.connect(self.dis_ev2_slot) + c2.qtsigs.disconnected_signal.connect(self.off_ev2_slot) + + # XXX why is this getting deletec in c++? + #Traceback (most recent call last): + #self.postEvent(self.events.on_ev2) + #RuntimeError: Internal C++ object (ConnectedEvent2) already deleted. + # XXX trying the following workaround, since + # I cannot find why in the world this is getting deleted :( + # XXX refactor! + + # slots connection1 + + def con_ev1_slot(self): + # XXX if we just postEvent, we get the Internal C++ object deleted... + # so the workaround is to re-create it each time. + self.events.con_ev1 = Composite.ConnectingEvent1() + self.postEvent(self.events.con_ev1) + + def on_ev1_slot(self): + self.events.on_ev1 = Composite.ConnectedEvent1() + self.postEvent(self.events.on_ev1) + + def dis_ev1_slot(self): + self.events.dis_ev1 = Composite.DisconnectingEvent1() + self.postEvent(self.events.dis_ev1) + + def off_ev1_slot(self): + self.events.off_ev1 = Composite.DisconnectedEvent1() + self.postEvent(self.events.off_ev1) + + # slots connection2 + + def con_ev2_slot(self): + self.events.con_ev2 = Composite.ConnectingEvent2() + self.postEvent(self.events.con_ev2) + + def on_ev2_slot(self): + self.events.on_ev2 = Composite.ConnectedEvent2() + self.postEvent(self.events.on_ev2) + + def dis_ev2_slot(self): + self.events.dis_ev2 = Composite.DisconnectingEvent2() + self.postEvent(self.events.dis_ev2) + + def off_ev2_slot(self): + self.events.off_ev2 = Composite.DisconnectedEvent2() + self.postEvent(self.events.off_ev2) + + class ConnectionMachineBuilder(object): """ Builder class for state machines made from LEAPConnections. @@ -65,16 +293,161 @@ class ConnectionMachineBuilder(object): def __init__(self, connection): """ :param connection: an instance of a concrete LEAPConnection - we will be building a state machine for. + we will be building a state machine for. :type connection: AbstractLEAPConnection """ self._conn = connection leap_assert_type(self._conn, connections.AbstractLEAPConnection) - def make_machine(self, button=None, action=None, label=None): + def make_machine(self, **kwargs): """ Creates a statemachine associated with the passed controls. + It returns the state machine if the connection used for initializing + the ConnectionMachineBuilder inherits exactly from + LEAPAbstractConnection, and a tuple with the Composite Machine and its + individual parts in case that it is a composite machine which + connection definition inherits from more than one class that, on their + time, inherit from LEAPAbstractConnection. + + :params: see parameters for ``_make_simple_machine`` + :returns: a QStateMachine, or a tuple with the form: + (CompositeStateMachine, (StateMachine1, StateMachine2)) + :rtype: QStateMachine or tuple + """ + components = self._conn.components + + if components is None: + # simple case: connection definition inherits directly from + # the abstract connection. + + leap_assert_type(self._conn, connections.AbstractLEAPConnection) + return self._make_simple_machine(self._conn, **kwargs) + + if components: + # composite case: connection definition inherits from several + # classes, each one of which inherit from the abstract connection. + child_machines = tuple( + [ConnectionMachineBuilder(connection()).make_machine() + for connection in components]) + composite_machine = self._make_composite_machine( + self._conn, child_machines, **kwargs) + + composite_machine._connect_children( + *child_machines) + + # XXX should also connect its own states with the signals + # for the composite machine itself + + return (composite_machine, child_machines) + + def _make_composite_machine(self, conn, children, + **kwargs): + """ + Creates a composite machine. + + :param conn: an instance of a connection definition. + :type conn: LEAPAbstractConnection + :param children: children machines + :type children: tuple of state machines + :returns: A composite state machine + :rtype: QStateMachine + """ + # TODO split this method in smaller utility functions. + parent = kwargs.get('parent', None) + + # 1. create machine + machine = CompositeMachine(parent=parent) + + # 2. create states + off = States.Off(conn.qtsigs.disconnected_signal, + parent=machine, + name=conn.name) + off.setObjectName("off") + + on = States.On(conn.qtsigs.connected_signal, + parent=machine, + name=conn.name) + on.setObjectName("on") + + connecting_state = States.Connecting( + conn.qtsigs.connecting_signal, + parent=machine, + name=conn.name) + connecting_state.setObjectName("connecting") + + disconnecting_state = States.Disconnecting( + conn.qtsigs.disconnecting_signal, + parent=machine, + name=conn.name) + disconnecting_state.setObjectName("disconnecting") + + # 3. TODO create as many connectingEvents as needed (dynamically create + # classses for that) + # (we have manually created classes for events under CompositeEvent for + # now, to begin with the simple 2 states case for mail. + + # 4. state tracking objects for each transition stage + + connecting_track0 = States.StepsTrack( + (Composite.ConnectingEvent1.ID, + Composite.ConnectingEvent2.ID)) + connecting_track0.setObjectName("connecting_step_0") + + connecting_track1 = States.StepsTrack( + (Composite.ConnectedEvent1.ID, + Composite.ConnectedEvent2.ID)) + connecting_track1.setObjectName("connecting_step_1") + + disconnecting_track0 = States.StepsTrack( + (Composite.DisconnectingEvent1.ID, + Composite.DisconnectingEvent2.ID)) + disconnecting_track0.setObjectName("disconnecting_step_0") + + disconnecting_track1 = States.StepsTrack( + (Composite.DisconnectedEvent1.ID, + Composite.DisconnectedEvent2.ID)) + disconnecting_track1.setObjectName("disconnecting_step_1") + + # 5. definte the transitions with the matching state-tracking + # objects. + + # off -> connecting + connecting_transition = States.TransitionOR( + connecting_track0) + connecting_transition.setTargetState(connecting_state) + off.addTransition(connecting_transition) + + # connecting -> on + connected_transition = States.TransitionAND( + connecting_track1) + connected_transition.setTargetState(on) + connecting_state.addTransition(connected_transition) + + # on -> disconnecting + disconnecting_transition = States.TransitionOR( + disconnecting_track0) + disconnecting_transition.setTargetState(disconnecting_state) + on.addTransition(disconnecting_transition) + + # disconnecting -> off + disconnected_transition = States.TransitionAND( + disconnecting_track1) + disconnected_transition.setTargetState(off) + disconnecting_state.addTransition(disconnected_transition) + + machine.setInitialState(off) + machine.conn = conn + return machine + + def _make_simple_machine(self, conn, + button=None, action=None, label=None): + """ + Creates a statemachine associated with the passed controls. + + :param conn: the connection instance that defines this machine. + :type conn: AbstractLEAPConnection + :param button: the switch button. :type button: QPushButton @@ -88,9 +461,7 @@ class ConnectionMachineBuilder(object): :rtype: QStateMachine """ machine = QStateMachine() - conn = self._conn - - states = self._make_states(button, action, label) + states = self._make_states(conn, button, action, label) # transitions: @@ -151,11 +522,17 @@ class ConnectionMachineBuilder(object): for state in states.itervalues(): machine.addState(state) machine.setInitialState(states[_OFF]) + + machine.conn = conn return machine - def _make_states(self, button, action, label): + def _make_states(self, conn, button, action, label): """ - Creates the four states for the state machine + Creates the four states for the simple state machine. + Adds the needed properties for the passed controls. + + :param conn: the connection instance that defines this machine. + :type conn: AbstractLEAPConnection :param button: the switch button. :type button: QPushButton @@ -169,7 +546,6 @@ class ConnectionMachineBuilder(object): :returns: a dict of states :rtype: dict """ - conn = self._conn states = {} # TODO add tooltip @@ -190,8 +566,9 @@ class ConnectionMachineBuilder(object): states[_OFF] = off # CONNECTING State ---------------- - connecting = IntermediateState( - conn.qtsigs.connecting_signal) + connecting = SignallingState( + conn.qtsigs.connecting_signal, + name=conn.name) on_label = _tr("Turn {0}").format( conn.Disconnected.short_label) if button: @@ -224,8 +601,9 @@ class ConnectionMachineBuilder(object): states[_ON] = on # DISCONNECTING State ------------- - disconnecting = IntermediateState( - conn.qtsigs.disconnecting_signal) + disconnecting = SignallingState( + conn.qtsigs.disconnecting_signal, + name=conn.name) if button: disconnecting.assignProperty( button, 'enabled', False) diff --git a/src/leap/bitmask/services/connections.py b/src/leap/bitmask/services/connections.py index 8aeb4e0c..ecfd35ff 100644 --- a/src/leap/bitmask/services/connections.py +++ b/src/leap/bitmask/services/connections.py @@ -41,9 +41,6 @@ The different services should declare a ServiceConnection class that inherits from AbstractLEAPConnection, so an instance of such class can be used to inform the StateMachineBuilder of the particularities of the state transitions for each particular connection. - -In the future, we will extend this class to allow composites in connections, -so we can apply conditional logic to the transitions. """ @@ -79,12 +76,7 @@ class AbstractLEAPConnection(object): """ return self._qtsigs - # XXX for conditional transitions with composites, - # we might want to add - # a field with dependencies: what this connection - # needs for (ON) state. - # XXX Look also at child states in the state machine. - #depends = () + components = None # Signals that derived classes # have to implement. diff --git a/src/leap/bitmask/services/eip/connection.py b/src/leap/bitmask/services/eip/connection.py index 962d9cf2..8a35d550 100644 --- a/src/leap/bitmask/services/eip/connection.py +++ b/src/leap/bitmask/services/eip/connection.py @@ -46,5 +46,5 @@ class EIPConnectionSignals(QtCore.QObject): class EIPConnection(AbstractLEAPConnection): def __init__(self): - # XXX this should be public instead self._qtsigs = EIPConnectionSignals() + self._connection_name = "Encrypted Internet" diff --git a/src/leap/bitmask/services/mail/conductor.py b/src/leap/bitmask/services/mail/conductor.py new file mode 100644 index 00000000..3a3e16a3 --- /dev/null +++ b/src/leap/bitmask/services/mail/conductor.py @@ -0,0 +1,383 @@ +# -*- coding: utf-8 -*- +# conductor.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +Mail Services Conductor +""" +import logging +import os + +from PySide import QtCore +from zope.proxy import sameProxiedObjects + +from leap.bitmask.gui import statemachines +from leap.bitmask.services.mail import imap +from leap.bitmask.services.mail import connection as mail_connection +from leap.bitmask.services.mail.smtpbootstrapper import SMTPBootstrapper +from leap.bitmask.services.mail.smtpconfig import SMTPConfig +from leap.bitmask.util import is_file + +from leap.common.check import leap_assert + +from leap.common.events import register as leap_register +from leap.common.events import events_pb2 as leap_events + +logger = logging.getLogger(__name__) + + +class IMAPControl(object): + """ + Methods related to IMAP control. + """ + def __init__(self): + """ + Initializes smtp variables. + """ + self.imap_machine = None + self.imap_service = None + self.imap_connection = None + + leap_register(signal=leap_events.IMAP_SERVICE_STARTED, + callback=self._handle_imap_events, + reqcbk=lambda req, resp: None) + leap_register(signal=leap_events.IMAP_SERVICE_FAILED_TO_START, + callback=self._handle_imap_events, + reqcbk=lambda req, resp: None) + + def set_imap_connection(self, imap_connection): + """ + Sets the imap connection to an initialized connection. + + :param imap_connection: an initialized imap connection + :type imap_connection: IMAPConnection instance. + """ + self.imap_connection = imap_connection + + def start_imap_service(self): + """ + Starts imap service. + """ + logger.debug('Starting imap service') + leap_assert(sameProxiedObjects(self._soledad, None) + is not True, + "We need a non-null soledad for initializing imap service") + leap_assert(sameProxiedObjects(self._keymanager, None) + is not True, + "We need a non-null keymanager for initializing imap " + "service") + + if self.imap_service is None: + # first time. + self.imap_service = imap.start_imap_service( + self._soledad, + self._keymanager) + else: + # we have the fetcher. just start it. + self.imap_service.start_loop() + + def stop_imap_service(self): + """ + Stops imap service. + + There is a subtle difference here: + we are just stopping the fetcher here, + but in the smtp case we are stopping the factory. + """ + self.imap_connection.qtsigs.disconnecting_signal.emit() + # TODO We should homogenize both services. + if self.imap_service is not None: + logger.debug('Stopping imap service.') + self.imap_service.stop() + + def fetch_incoming_mail(self): + """ + Fetches incoming mail. + """ + # TODO have a mutex over fetch operation. + if self.imap_service: + logger.debug('Client connected, fetching mail...') + self.imap_service.fetch() + + # handle events + + def _handle_imap_events(self, req): + """ + Callback handler for the IMAP events + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest + """ + if req.event == leap_events.IMAP_SERVICE_STARTED: + self.on_imap_connected() + elif req.event == leap_events.IMAP_SERVICE_FAILED_TO_START: + self.on_imap_failed() + + # emit connection signals + + def on_imap_connecting(self): + """ + Callback for IMAP connecting state. + """ + self.imap_connection.qtsigs.connecting_signal.emit() + + def on_imap_connected(self): + """ + Callback for IMAP connected state. + """ + self.imap_connection.qtsigs.connected_signal.emit() + + def on_imap_failed(self): + """ + Callback for IMAP failed state. + """ + self.imap_connection.qtsigs.connetion_aborted_signal.emit() + + +class SMTPControl(object): + + PORT_KEY = "port" + IP_KEY = "ip_address" + + def __init__(self): + """ + Initializes smtp variables. + """ + self.smtp_config = SMTPConfig() + self.smtp_connection = None + self.smtp_machine = None + self._smtp_service = None + self._smtp_port = None + + self.smtp_bootstrapper = SMTPBootstrapper() + self.smtp_bootstrapper.download_config.connect( + self.smtp_bootstrapped_stage) + + leap_register(signal=leap_events.SMTP_SERVICE_STARTED, + callback=self._handle_smtp_events, + reqcbk=lambda req, resp: None) + leap_register(signal=leap_events.SMTP_SERVICE_FAILED_TO_START, + callback=self._handle_smtp_events, + reqcbk=lambda req, resp: None) + + def set_smtp_connection(self, smtp_connection): + """ + Sets the smtp connection to an initialized connection. + :param smtp_connection: an initialized smtp connection + :type smtp_connection: SMTPConnection instance. + """ + self.smtp_connection = smtp_connection + + def start_smtp_service(self, host, port, cert): + """ + Starts the smtp service. + + :param host: the hostname of the remove SMTP server. + :type host: str + :param port: the port of the remote SMTP server + :type port: str + :param cert: the client certificate for authentication + :type cert: str + """ + # TODO Make the encrypted_only configurable + # TODO pick local smtp port in a better way + # TODO remove hard-coded port and let leap.mail set + # the specific default. + self.smtp_connection.qtsigs.connecting_signal.emit() + from leap.mail.smtp import setup_smtp_relay + self._smtp_service, self._smtp_port = setup_smtp_relay( + port=2013, + keymanager=self._keymanager, + smtp_host=host, + smtp_port=port, + smtp_cert=cert, + smtp_key=cert, + encrypted_only=False) + + def stop_smtp_service(self): + """ + Stops the smtp service. + + There is a subtle difference here: + we are stopping the factory for the smtp service here, + but in the imap case we are just stopping the fetcher. + """ + self.smtp_connection.qtsigs.disconnecting_signal.emit() + # TODO We should homogenize both services. + if self._smtp_service is not None: + logger.debug('Stopping smtp service.') + self._smtp_port.stopListening() + self._smtp_service.doStop() + + @QtCore.Slot() + def smtp_bootstrapped_stage(self, data): + """ + SLOT + TRIGGERS: + self.smtp_bootstrapper.download_config + + If there was a problem, displays it, otherwise it does nothing. + This is used for intermediate bootstrapping stages, in case + they fail. + + :param data: result from the bootstrapping stage for Soledad + :type data: dict + """ + passed = data[self.smtp_bootstrapper.PASSED_KEY] + if not passed: + logger.error(data[self.smtp_bootstrapper.ERROR_KEY]) + return + logger.debug("Done bootstrapping SMTP") + self.check_smtp_config() + + def check_smtp_config(self): + """ + Checks smtp config and tries to download smtp client cert if needed. + Currently called when smtp_bootstrapped_stage has successfuly finished. + """ + logger.debug("Checking SMTP config...") + leap_assert(self.smtp_bootstrapper._provider_config, + "smtp bootstrapper does not have a provider_config") + + provider_config = self.smtp_bootstrapper._provider_config + smtp_config = self.smtp_config + hosts = smtp_config.get_hosts() + # TODO handle more than one host and define how to choose + if len(hosts) > 0: + hostname = hosts.keys()[0] + logger.debug("Using hostname %s for SMTP" % (hostname,)) + host = hosts[hostname][self.IP_KEY].encode("utf-8") + port = hosts[hostname][self.PORT_KEY] + + client_cert = smtp_config.get_client_cert_path( + provider_config, + about_to_download=True) + + # XXX change this logic! + # check_config should be called from within start_service, + # and not the other way around. + if not is_file(client_cert): + self.smtp_bootstrapper._download_client_certificates() + if os.path.isfile(client_cert): + self.start_smtp_service(host, port, client_cert) + else: + logger.warning("Tried to download email client " + "certificate, but could not find any") + + else: + logger.warning("No smtp hosts configured") + + # handle smtp events + + def _handle_smtp_events(self, req): + """ + Callback handler for the SMTP events. + + :param req: Request type + :type req: leap.common.events.events_pb2.SignalRequest + """ + if req.event == leap_events.SMTP_SERVICE_STARTED: + self.on_smtp_connected() + elif req.event == leap_events.SMTP_SERVICE_FAILED_TO_START: + self.on_smtp_failed() + + # emit connection signals + + def on_smtp_connecting(self): + """ + Callback for SMTP connecting state. + """ + self.smtp_connection.qtsigs.connecting_signal.emit() + + def on_smtp_connected(self): + """ + Callback for SMTP connected state. + """ + self.smtp_connection.qtsigs.connected_signal.emit() + + def on_smtp_failed(self): + """ + Callback for SMTP failed state. + """ + self.smtp_connection.qtsigs.connection_aborted_signal.emit() + + +class MailConductor(IMAPControl, SMTPControl): + """ + This class encapsulates everything related to the initialization and + process control for the mail services. + Currently, it initializes IMAPConnection and SMPTConnection. + """ + # XXX We could consider to use composition instead of inheritance here. + + def __init__(self, soledad, keymanager): + """ + Initializes the mail conductor. + + :param soledad: a transparent proxy that eventually will point to a + Soledad Instance. + :type soledad: zope.proxy.ProxyBase + + :param keymanager: a transparent proxy that eventually will point to a + Keymanager Instance. + :type soledad: zope.proxy.ProxyBase + """ + IMAPControl.__init__(self) + SMTPControl.__init__(self) + self._soledad = soledad + self._keymanager = keymanager + + self._mail_machine = None + + self._mail_connection = mail_connection.MailConnection() + + def start_mail_machine(self, **kwargs): + """ + Starts mail machine. + """ + logger.debug("Starting mail state machine...") + builder = statemachines.ConnectionMachineBuilder(self._mail_connection) + (mail, (imap, smtp)) = builder.make_machine(**kwargs) + + # we have instantiated the connections while building the composite + # machines, and we have to use the qtsigs instantiated there. + # XXX we could probably use a proxy here too to make the thing + # transparent. + self.set_imap_connection(imap.conn) + self.set_smtp_connection(smtp.conn) + + self._mail_machine = mail + # XXX ------------------- + # need to keep a reference? + #self._mail_events = mail.events + self._mail_machine.start() + + self._imap_machine = imap + self._imap_machine.start() + self._smtp_machine = smtp + self._smtp_machine.start() + + def connect_mail_signals(self, widget): + """ + Connects the mail signals to the mail_status widget slots. + + :param widget: the widget containing the slots. + :type widget: QtCore.QWidget + """ + qtsigs = self._mail_connection.qtsigs + qtsigs.connected_signal.connect(widget.mail_state_connected) + qtsigs.connecting_signal.connect(widget.mail_state_connecting) + qtsigs.disconnecting_signal.connect(widget.mail_state_disconnecting) + qtsigs.disconnected_signal.connect(widget.mail_state_disconnected) diff --git a/src/leap/bitmask/services/mail/connection.py b/src/leap/bitmask/services/mail/connection.py new file mode 100644 index 00000000..29378f62 --- /dev/null +++ b/src/leap/bitmask/services/mail/connection.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# connection.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +Email Connections +""" +from PySide import QtCore + +from leap.bitmask.services.connections import AbstractLEAPConnection + + +class IMAPConnectionSignals(QtCore.QObject): + """ + Qt Signals used by IMAPConnection + """ + # commands + do_connect_signal = QtCore.Signal() + do_disconnect_signal = QtCore.Signal() + + # intermediate stages + connecting_signal = QtCore.Signal() + disconnecting_signal = QtCore.Signal() + + connected_signal = QtCore.Signal() + disconnected_signal = QtCore.Signal() + + connection_died_signal = QtCore.Signal() + connection_aborted_signal = QtCore.Signal() + + +class IMAPConnection(AbstractLEAPConnection): + + _connection_name = "IMAP" + + def __init__(self): + self._qtsigs = IMAPConnectionSignals() + + +class SMTPConnectionSignals(QtCore.QObject): + """ + Qt Signals used by SMTPConnection + """ + # commands + do_connect_signal = QtCore.Signal() + do_disconnect_signal = QtCore.Signal() + + # intermediate stages + connecting_signal = QtCore.Signal() + disconnecting_signal = QtCore.Signal() + + connected_signal = QtCore.Signal() + disconnected_signal = QtCore.Signal() + + connection_died_signal = QtCore.Signal() + connection_aborted_signal = QtCore.Signal() + + +class SMTPConnection(AbstractLEAPConnection): + + _connection_name = "IMAP" + + def __init__(self): + self._qtsigs = SMTPConnectionSignals() + + +class MailConnectionSignals(QtCore.QObject): + """ + Qt Signals used by MailConnection + """ + # commands + do_connect_signal = QtCore.Signal() + do_disconnect_signal = QtCore.Signal() + + connecting_signal = QtCore.Signal() + disconnecting_signal = QtCore.Signal() + + connected_signal = QtCore.Signal() + disconnected_signal = QtCore.Signal() + + connection_died_signal = QtCore.Signal() + connection_aborted_signal = QtCore.Signal() + + +class MailConnection(AbstractLEAPConnection): + + components = IMAPConnection, SMTPConnection + _connection_name = "Mail" + + def __init__(self): + self._qtsigs = MailConnectionSignals() diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 4619ba80..1940fc68 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -25,6 +25,7 @@ from ssl import SSLError from PySide import QtCore from u1db import errors as u1db_errors +from zope.proxy import sameProxiedObjects from leap.bitmask.config import flags from leap.bitmask.config.providerconfig import ProviderConfig @@ -190,7 +191,8 @@ class SoledadBootstrapper(AbstractBootstrapper): # soledad-launcher in the gui. raise - leap_check(self._soledad is not None, + leap_assert(sameProxiedObjects(self._soledad, None) + is not True, "Null soledad, error while initializing") # and now, let's sync -- cgit v1.2.3 From 4c3329d67ec6730da0b26cc3b57a1ee689560cd0 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 24 Oct 2013 10:42:03 -0200 Subject: changes file --- changes/feature_4059-mail-state-refactor | 1 + changes/feature_colored-logs | 1 + 2 files changed, 2 insertions(+) create mode 100644 changes/feature_4059-mail-state-refactor create mode 100644 changes/feature_colored-logs diff --git a/changes/feature_4059-mail-state-refactor b/changes/feature_4059-mail-state-refactor new file mode 100644 index 00000000..2e3f5056 --- /dev/null +++ b/changes/feature_4059-mail-state-refactor @@ -0,0 +1 @@ +- Refactor mail connections to use state machine. Closes: #4059 diff --git a/changes/feature_colored-logs b/changes/feature_colored-logs new file mode 100644 index 00000000..b28a38bd --- /dev/null +++ b/changes/feature_colored-logs @@ -0,0 +1 @@ +- Use coloredlogs handler if present (for development, not a requirement). -- cgit v1.2.3 From 6c924e87562f5eb986f6e6bf592e2a9d41fa90f1 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 28 Oct 2013 18:26:53 -0200 Subject: dependency pinning on requests --- changes/feature-4308-pin-requests-dep | 1 + pkg/requirements.pip | 2 +- src/leap/bitmask/crypto/srpauth.py | 7 ++++++- src/leap/bitmask/util/compat.py | 31 +++++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 changes/feature-4308-pin-requests-dep create mode 100644 src/leap/bitmask/util/compat.py diff --git a/changes/feature-4308-pin-requests-dep b/changes/feature-4308-pin-requests-dep new file mode 100644 index 00000000..1f7af6ca --- /dev/null +++ b/changes/feature-4308-pin-requests-dep @@ -0,0 +1 @@ +- Add support for requests 1.1.0 (raring). Closes: #4308 diff --git a/pkg/requirements.pip b/pkg/requirements.pip index 98610fbb..29a313ea 100644 --- a/pkg/requirements.pip +++ b/pkg/requirements.pip @@ -6,7 +6,7 @@ # Use LEAP_VENV_SKIP_PYSIDE to avoid installing it! argparse -requests +requests>=1.1.0 srp>=1.0.2 pyopenssl python-dateutil diff --git a/src/leap/bitmask/crypto/srpauth.py b/src/leap/bitmask/crypto/srpauth.py index 47ed21b0..e7998e62 100644 --- a/src/leap/bitmask/crypto/srpauth.py +++ b/src/leap/bitmask/crypto/srpauth.py @@ -31,6 +31,7 @@ from PySide import QtCore from twisted.internet import threads from leap.bitmask.util import request_helpers as reqhelper +from leap.bitmask.util.compat import requests_has_max_retries from leap.bitmask.util.constants import REQUEST_TIMEOUT from leap.common.check import leap_assert from leap.common.events import signal as events_signal @@ -184,7 +185,11 @@ class SRPAuth(QtCore.QObject): # NOTE: This is a workaround for the moment, the server # side seems to return correctly every time, but it fails # on the client end. - self._session.mount('https://', HTTPAdapter(max_retries=30)) + if requests_has_max_retries: + adapter = HTTPAdapter(max_retries=30) + else: + adapter = HTTPAdapter() + self._session.mount('https://', adapter) def _safe_unhexlify(self, val): """ diff --git a/src/leap/bitmask/util/compat.py b/src/leap/bitmask/util/compat.py new file mode 100644 index 00000000..e34b9ead --- /dev/null +++ b/src/leap/bitmask/util/compat.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# compat.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +""" +Utilities for dealing with compat versions. +""" +from distutils.version import LooseVersion as V + +from requests import __version__ as _requests_version + + +def _requests_has_max_retries(): + """ + Returns True if we can use the max_retries parameter + """ + return V(_requests_version) > V('1.1.0') + +requests_has_max_retries = _requests_has_max_retries() -- cgit v1.2.3 From 30c922e03f61d9c588d4d4eca5edcdf2a5c4056c Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 23 Oct 2013 16:20:58 -0300 Subject: Use unicode values and encode them out. --- changes/bug-4189_non-ascii-path-problem | 1 + src/leap/bitmask/provider/providerbootstrapper.py | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 changes/bug-4189_non-ascii-path-problem diff --git a/changes/bug-4189_non-ascii-path-problem b/changes/bug-4189_non-ascii-path-problem new file mode 100644 index 00000000..a6bead2d --- /dev/null +++ b/changes/bug-4189_non-ascii-path-problem @@ -0,0 +1 @@ + o Fix problem with non-ascii paths. Closes #4189. diff --git a/src/leap/bitmask/provider/providerbootstrapper.py b/src/leap/bitmask/provider/providerbootstrapper.py index 1b5947e1..2adf8aa8 100644 --- a/src/leap/bitmask/provider/providerbootstrapper.py +++ b/src/leap/bitmask/provider/providerbootstrapper.py @@ -20,6 +20,7 @@ Provider bootstrapping import logging import socket import os +import sys import requests @@ -125,9 +126,13 @@ class ProviderBootstrapper(AbstractBootstrapper): # err --- but we can do it after a failure, to diagnose what went # wrong. Right now we're just adding connection overhead. -- kali + verify = self.verify + if verify: + verify = self.verify.encode(sys.getfilesystemencoding()) + try: res = self._session.get("https://%s" % (self._domain,), - verify=self.verify, + verify=verify, timeout=REQUEST_TIMEOUT) res.raise_for_status() except requests.exceptions.SSLError as exc: @@ -180,6 +185,8 @@ class ProviderBootstrapper(AbstractBootstrapper): # no ca? then download from main domain again. pass + if verify: + verify = verify.encode(sys.getfilesystemencoding()) logger.debug("Requesting for provider.json... " "uri: {0}, verify: {1}, headers: {2}".format( uri, verify, headers)) @@ -336,9 +343,9 @@ class ProviderBootstrapper(AbstractBootstrapper): test_uri = "%s/%s/cert" % (self._provider_config.get_api_uri(), self._provider_config.get_api_version()) - res = self._session.get(test_uri, - verify=self._provider_config - .get_ca_cert_path(), + ca_cert_path = self._provider_config.get_ca_cert_path() + ca_cert_path = ca_cert_path.encode(sys.getfilesystemencoding()) + res = self._session.get(test_uri, verify=ca_cert_path, timeout=REQUEST_TIMEOUT) res.raise_for_status() -- cgit v1.2.3 From d3ca8c456c7220a65ef0f88042fe49fb438eddc9 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 23 Oct 2013 17:34:11 -0300 Subject: Encode cert path before send it. --- src/leap/bitmask/crypto/srpauth.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/leap/bitmask/crypto/srpauth.py b/src/leap/bitmask/crypto/srpauth.py index 47ed21b0..31316f17 100644 --- a/src/leap/bitmask/crypto/srpauth.py +++ b/src/leap/bitmask/crypto/srpauth.py @@ -17,6 +17,7 @@ import binascii import logging +import sys import requests import srp @@ -249,10 +250,13 @@ class SRPAuth(QtCore.QObject): (self._provider_config.get_api_uri(), self._provider_config.get_api_version(), "sessions") + + ca_cert_path = self._provider_config.get_ca_cert_path() + ca_cert_path = ca_cert_path.encode(sys.getfilesystemencoding()) + init_session = self._session.post(sessions_url, data=auth_data, - verify=self._provider_config. - get_ca_cert_path(), + verify=ca_cert_path, timeout=REQUEST_TIMEOUT) # Clean up A value, we don't need it anymore self._srp_a = None -- cgit v1.2.3 From 2b063c0d5b0da8f76c5de64d7bdeb2ee1edf1b93 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 29 Oct 2013 12:36:12 -0200 Subject: Adds a command to freeze debian versions. --- changes/feature_4315-freeze-debianver-command | 1 + setup.py | 72 ++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 changes/feature_4315-freeze-debianver-command diff --git a/changes/feature_4315-freeze-debianver-command b/changes/feature_4315-freeze-debianver-command new file mode 100644 index 00000000..0ae8ad97 --- /dev/null +++ b/changes/feature_4315-freeze-debianver-command @@ -0,0 +1 @@ +- Add a command to setup.py to freeze the versions reported under debian branches. Closes: #4315 diff --git a/setup.py b/setup.py index fd87e56c..dca8f44a 100755 --- a/setup.py +++ b/setup.py @@ -44,7 +44,6 @@ versioneer.versionfile_build = 'leap/bitmask/_version.py' versioneer.tag_prefix = '' # tags are like 1.2.0 versioneer.parentdir_prefix = 'leap.bitmask-' -#from setuptools import Command # The following import avoids the premature unloading of the `util` submodule # when running tests, which would cause an error when nose finishes tests and @@ -74,10 +73,69 @@ trove_classifiers = [ "Topic :: Utilities", ] +DOWNLOAD_BASE = ('https://github.com/leapcode/bitmask_client/' + 'archive/%s.tar.gz') +_versions = versioneer.get_versions() +VERSION = _versions['version'] +VERSION_FULL = _versions['full'] +DOWNLOAD_URL = "" -parsed_reqs = utils.parse_requirements() +# get the short version for the download url +_version_short = re.findall('\d+\.\d+\.\d+', VERSION) +if len(_version_short) > 0: + VERSION_SHORT = _version_short[0] + DOWNLOAD_URL = DOWNLOAD_BASE % VERSION_SHORT cmdclass = versioneer.get_cmdclass() + + +from setuptools import Command + + +class freeze_debianver(Command): + """ + Freezes the version in a debian branch. + To be used after merging the development branch onto the debian one. + """ + user_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + proceed = str(raw_input( + "This will overwrite the file _version.py. Continue? [y/N] ")) + if proceed != "y": + print("He. You scared. Aborting.") + return + template = r""" +# This file was generated by the `freeze_debianver` command in setup.py +# Using 'versioneer.py' (0.7+) from +# revision-control system data, or from the parent directory name of an +# unpacked source archive. Distribution tarballs contain a pre-generated copy +# of this file. + +version_version = '{version}' +version_full = '{version_full}' +""" + templatefun = r""" + +def get_versions(default={}, verbose=False): + return {'version': version_version, 'full': version_full} +""" + subst_template = template.format( + version=VERSION_SHORT, + version_full=VERSION_FULL) + templatefun + with open(versioneer.versionfile_source, 'w') as f: + f.write(subst_template) + + +cmdclass["freeze_debianver"] = freeze_debianver +parsed_reqs = utils.parse_requirements() + leap_launcher = 'bitmask=leap.bitmask.app:main' from setuptools.command.develop import develop as _develop @@ -150,16 +208,6 @@ if IS_LINUX: ["pkg/linux/resolv-update"]), ] -DOWNLOAD_BASE = ('https://github.com/leapcode/bitmask_client/' - 'archive/%s.tar.gz') -VERSION = versioneer.get_version() -DOWNLOAD_URL = "" - -# get the short version for the download url -short_ver = re.findall('\d+\.\d+\.\d+', VERSION) -if len(short_ver) > 0: - DOWNLOAD_URL = DOWNLOAD_BASE % short_ver[0] - setup( name="leap.bitmask", -- cgit v1.2.3 From aa9b0460a9320a0ec12e45e75011fce6b102ac58 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 24 Oct 2013 17:19:30 -0300 Subject: Encode paths before use them. --- src/leap/bitmask/services/__init__.py | 7 ++++++- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 10 ++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/leap/bitmask/services/__init__.py b/src/leap/bitmask/services/__init__.py index f9456159..e62277b6 100644 --- a/src/leap/bitmask/services/__init__.py +++ b/src/leap/bitmask/services/__init__.py @@ -19,6 +19,7 @@ Services module. """ import logging import os +import sys from PySide import QtCore @@ -135,8 +136,12 @@ def download_service_config(provider_config, service_config, if token is not None: headers["Authorization"] = 'Token token="{0}"'.format(token) + verify = provider_config.get_ca_cert_path() + if verify: + verify = verify.encode(sys.getfilesystemencoding()) + res = session.get(config_uri, - verify=provider_config.get_ca_cert_path(), + verify=verify, headers=headers, timeout=REQUEST_TIMEOUT, cookies=cookies) diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 4619ba80..3bb5fd84 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -20,6 +20,7 @@ Soledad bootstrapping import logging import os import socket +import sys from ssl import SSLError @@ -239,14 +240,15 @@ class SoledadBootstrapper(AbstractBootstrapper): """ # TODO: If selected server fails, retry with another host # (issue #3309) + encoding = sys.getfilesystemencoding() try: self._soledad = Soledad( uuid, - self._password.encode("utf-8"), - secrets_path=secrets_path, - local_db_path=local_db_path, + self._password.encode('utf-8'), + secrets_path=secrets_path.encode(encoding), + local_db_path=local_db_path.encode(encoding), server_url=server_url, - cert_file=cert_file, + cert_file=cert_file.encode(encoding), auth_token=auth_token) # XXX All these errors should be handled by soledad itself, -- cgit v1.2.3 From d6a40020d89a1dfab6c49aa710b6e84bc91140b6 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 25 Oct 2013 17:32:31 -0300 Subject: Handle encoding problems in the vpn connection. --- src/leap/bitmask/services/eip/darwinvpnlauncher.py | 5 ++++- src/leap/bitmask/services/eip/linuxvpnlauncher.py | 5 ++++- src/leap/bitmask/services/eip/vpnlauncher.py | 3 --- src/leap/bitmask/services/eip/vpnprocess.py | 18 +++++++++++++++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/leap/bitmask/services/eip/darwinvpnlauncher.py b/src/leap/bitmask/services/eip/darwinvpnlauncher.py index f3b6bfc8..fe3fe4c1 100644 --- a/src/leap/bitmask/services/eip/darwinvpnlauncher.py +++ b/src/leap/bitmask/services/eip/darwinvpnlauncher.py @@ -21,6 +21,7 @@ import commands import getpass import logging import os +import sys from leap.bitmask.services.eip.vpnlauncher import VPNLauncher from leap.bitmask.services.eip.vpnlauncher import VPNLauncherException @@ -185,6 +186,8 @@ class DarwinVPNLauncher(VPNLauncher): :rtype: dict """ + ld_library_path = os.path.join(get_path_prefix(), "..", "lib") + ld_library_path.encode(sys.getfilesystemencoding()) return { - "DYLD_LIBRARY_PATH": os.path.join(get_path_prefix(), "..", "lib") + "DYLD_LIBRARY_PATH": ld_library_path } diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py index efb23285..d02f6f96 100644 --- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py +++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py @@ -21,6 +21,7 @@ import commands import logging import os import subprocess +import sys import time from leap.bitmask.config import flags @@ -231,6 +232,8 @@ class LinuxVPNLauncher(VPNLauncher): :rtype: dict """ + ld_library_path = os.path.join(get_path_prefix(), "..", "lib") + ld_library_path.encode(sys.getfilesystemencoding()) return { - "LD_LIBRARY_PATH": os.path.join(get_path_prefix(), "..", "lib") + "LD_LIBRARY_PATH": ld_library_path } diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index bce3599b..07497814 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -250,9 +250,6 @@ class VPNLauncher(object): '--ping-restart', '30'] command_and_args = [openvpn] + args - logger.debug("Running VPN with command:") - logger.debug(" ".join(command_and_args)) - return command_and_args @classmethod diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index 19e1aa7b..51f0f738 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -23,6 +23,7 @@ import psutil import psutil.error import shutil import socket +import sys from itertools import chain, repeat @@ -864,15 +865,26 @@ class VPNProcess(protocol.ProcessProtocol, VPNManager): """ Gets the vpn command from the aproppriate launcher. - Might throw: VPNLauncherException, OpenVPNNotFoundException. + Might throw: + VPNLauncherException, + OpenVPNNotFoundException. + + :rtype: list of str """ - cmd = self._launcher.get_vpn_command( + command = self._launcher.get_vpn_command( eipconfig=self._eipconfig, providerconfig=self._providerconfig, socket_host=self._socket_host, socket_port=self._socket_port, openvpn_verb=self._openvpn_verb) - return map(str, cmd) + + encoding = sys.getfilesystemencoding() + for i, c in enumerate(command): + if not isinstance(c, str): + command[i] = c.encode(encoding) + + logger.debug("Running VPN with command: {0}".format(command)) + return command # shutdown -- cgit v1.2.3 From c90be9157d5423d055984b354c5712f6873336b8 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 29 Oct 2013 12:24:45 -0300 Subject: Update docstrings to unicode types. --- src/leap/bitmask/config/providerconfig.py | 5 +++-- src/leap/bitmask/gui/login.py | 4 ++-- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/leap/bitmask/config/providerconfig.py b/src/leap/bitmask/config/providerconfig.py index 44698d83..e80b2337 100644 --- a/src/leap/bitmask/config/providerconfig.py +++ b/src/leap/bitmask/config/providerconfig.py @@ -169,11 +169,12 @@ class ProviderConfig(BaseConfig): checking if the cert exists because we are about to write it. :type about_to_download: bool + + :rtype: unicode """ cert_path = os.path.join(get_path_prefix(), "leap", "providers", - self.get_domain(), - "keys", "ca", "cacert.pem") + self.get_domain(), "keys", "ca", "cacert.pem") if not about_to_download: cert_exists = os.path.exists(cert_path) diff --git a/src/leap/bitmask/gui/login.py b/src/leap/bitmask/gui/login.py index ac34fe23..255a06d3 100644 --- a/src/leap/bitmask/gui/login.py +++ b/src/leap/bitmask/gui/login.py @@ -168,7 +168,7 @@ class LoginWidget(QtGui.QWidget): """ Returns the user that appears in the widget. - :rtype: str + :rtype: unicode """ return self.ui.lnUser.text() @@ -185,7 +185,7 @@ class LoginWidget(QtGui.QWidget): """ Returns the password that appears in the widget - :rtype: str + :rtype: unicode """ return self.ui.lnPassword.text() diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 3bb5fd84..c673ea61 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -414,9 +414,9 @@ class SoledadBootstrapper(AbstractBootstrapper): :param provider_config: Provider configuration :type provider_config: ProviderConfig :param user: User's login - :type user: str + :type user: unicode :param password: User's password - :type password: str + :type password: unicode :param download_if_needed: If True, it will only download files if the have changed since the time it was previously downloaded. -- cgit v1.2.3 From 0f5d0e2b3f2c2403f2c518b984bf11d01d799bb0 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 29 Oct 2013 14:58:20 -0300 Subject: Create Soledad object with an unicode passphrase. [Related to bug #4330] --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index fec60338..d06cc910 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -246,7 +246,7 @@ class SoledadBootstrapper(AbstractBootstrapper): try: self._soledad = Soledad( uuid, - self._password.encode('utf-8'), + self._password, secrets_path=secrets_path.encode(encoding), local_db_path=local_db_path.encode(encoding), server_url=server_url, -- cgit v1.2.3 From f60a971f37b9a9e0ee1115faaaae6aadbd91f3cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 30 Oct 2013 11:06:36 -0300 Subject: Properly log EIP status changes --- changes/log_eip_status | 1 + src/leap/bitmask/gui/eip_status.py | 4 ++++ src/leap/bitmask/gui/statemachines.py | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 changes/log_eip_status diff --git a/changes/log_eip_status b/changes/log_eip_status new file mode 100644 index 00000000..97153fd7 --- /dev/null +++ b/changes/log_eip_status @@ -0,0 +1 @@ + - Properly log EIP status changes. diff --git a/src/leap/bitmask/gui/eip_status.py b/src/leap/bitmask/gui/eip_status.py index 77685cd3..324586c0 100644 --- a/src/leap/bitmask/gui/eip_status.py +++ b/src/leap/bitmask/gui/eip_status.py @@ -269,6 +269,10 @@ class EIPStatusWidget(QtGui.QWidget): :type error: bool """ leap_assert_type(error, bool) + if error: + logger.error(status) + else: + logger.debug(status) self._eip_status = status if error: status = "%s" % (status,) diff --git a/src/leap/bitmask/gui/statemachines.py b/src/leap/bitmask/gui/statemachines.py index ee16a4c6..386cb75f 100644 --- a/src/leap/bitmask/gui/statemachines.py +++ b/src/leap/bitmask/gui/statemachines.py @@ -55,8 +55,8 @@ class SignallingState(QState): """ Emits the signal on entry. """ - logger.debug('State %s entered. Emitting signal ...' - % (self._name + self.__class__.__name__)) + logger.debug('State %s::%s entered. Emitting signal ...' + % (self._name, self.objectName())) if self._signal is not None: self._signal.emit() -- cgit v1.2.3 From d28cb4d97c15952070f1bd2b737264686b025836 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 30 Oct 2013 12:20:18 -0200 Subject: format fixes --- changes/bug-4189_non-ascii-path-problem | 2 +- changes/log_eip_status | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/changes/bug-4189_non-ascii-path-problem b/changes/bug-4189_non-ascii-path-problem index a6bead2d..e8b43e40 100644 --- a/changes/bug-4189_non-ascii-path-problem +++ b/changes/bug-4189_non-ascii-path-problem @@ -1 +1 @@ - o Fix problem with non-ascii paths. Closes #4189. +- Fix problem with non-ascii paths. Closes #4189. diff --git a/changes/log_eip_status b/changes/log_eip_status index 97153fd7..32ac2b42 100644 --- a/changes/log_eip_status +++ b/changes/log_eip_status @@ -1 +1 @@ - - Properly log EIP status changes. +- Properly log EIP status changes. -- cgit v1.2.3 From 1f101bb60192ae8ad6c88e76d942dd4a88d976a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 30 Oct 2013 11:59:57 -0300 Subject: Align left the speed and transferred display for EIP --- changes/bug_tighter_clustering_eip_meter | 2 ++ src/leap/bitmask/gui/ui/eip_status.ui | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 changes/bug_tighter_clustering_eip_meter diff --git a/changes/bug_tighter_clustering_eip_meter b/changes/bug_tighter_clustering_eip_meter new file mode 100644 index 00000000..32101c9e --- /dev/null +++ b/changes/bug_tighter_clustering_eip_meter @@ -0,0 +1,2 @@ + - Align left the speed and transferred displays for EIP. Fixes + #4204. \ No newline at end of file diff --git a/src/leap/bitmask/gui/ui/eip_status.ui b/src/leap/bitmask/gui/ui/eip_status.ui index 25831118..d078ca0c 100644 --- a/src/leap/bitmask/gui/ui/eip_status.ui +++ b/src/leap/bitmask/gui/ui/eip_status.ui @@ -185,6 +185,9 @@ PointingHandCursor + + text-align: left; + 0.0 KB/s @@ -249,6 +252,9 @@ PointingHandCursor + + text-align: left; + 0.0 KB/s -- cgit v1.2.3 From 01447ca9d4867bbcafc6b4616b5ed62480883deb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 30 Oct 2013 12:48:35 -0300 Subject: Hide unsupported services by the configured providers --- changes/feature_hide_unused_services | 2 + src/leap/bitmask/gui/mainwindow.py | 28 ++++++ src/leap/bitmask/gui/ui/mainwindow.ui | 172 +++++++++++++++++++--------------- 3 files changed, 128 insertions(+), 74 deletions(-) create mode 100644 changes/feature_hide_unused_services diff --git a/changes/feature_hide_unused_services b/changes/feature_hide_unused_services new file mode 100644 index 00000000..abcdeb6f --- /dev/null +++ b/changes/feature_hide_unused_services @@ -0,0 +1,2 @@ + - Hide the GUI for services that are not supported on the set of + configured providers. Closes #4170. \ No newline at end of file diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index dddd53da..72dcf278 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -545,6 +545,8 @@ class MainWindow(QtGui.QMainWindow): if IS_MAC: self.raise_() + self._hide_unsupported_services() + if self._wizard: possible_username = self._wizard.get_username() possible_password = self._wizard.get_password() @@ -603,6 +605,30 @@ class MainWindow(QtGui.QMainWindow): saved_password.decode("utf8")) self._login() + def _hide_unsupported_services(self): + """ + Given a set of configured providers, it creates a set of + available services among all of them and displays the service + widgets of only those. + + This means, for example, that with just one provider with EIP + only, the mail widget won't be displayed. + """ + providers = self._settings.get_configured_providers() + + services = set() + + for prov in providers: + provider_config = ProviderConfig() + loaded = provider_config.load( + provider.get_provider_path(prov)) + if loaded: + for service in provider_config.get_services(): + services.add(service) + + self.ui.eipWidget.setVisible(self.OPENVPN_SERVICE in services) + self.ui.mailWidget.setVisible(self.MX_SERVICE in services) + # # systray # @@ -883,6 +909,8 @@ class MainWindow(QtGui.QMainWindow): username = self._login_widget.get_user().encode("utf8") password = self._login_widget.get_password().encode("utf8") + self._hide_unsupported_services() + if self._srp_auth is None: self._srp_auth = SRPAuth(self._provider_config) self._srp_auth.authentication_finished.connect( diff --git a/src/leap/bitmask/gui/ui/mainwindow.ui b/src/leap/bitmask/gui/ui/mainwindow.ui index 10c77057..badd291d 100644 --- a/src/leap/bitmask/gui/ui/mainwindow.ui +++ b/src/leap/bitmask/gui/ui/mainwindow.ui @@ -75,7 +75,7 @@ 0 0 524 - 635 + 636 @@ -86,88 +86,100 @@ 0 - - - - 0 - 0 - - - - QFrame{background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(160, 160, 160, 128), stop:1 rgba(255, 255, 255, 0));} - - - - 24 + + + + 0 - - 24 + + 0 - - - - 16 - 75 - true - + + + + 0 + 0 + - background-color: rgba(255, 255, 255, 0); - - - Encrypted Internet + QFrame{background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgba(160, 160, 160, 128), stop:1 rgba(255, 255, 255, 0));} + + + 24 + + + 24 + + + + + + 16 + 75 + true + + + + background-color: rgba(255, 255, 255, 0); + + + Encrypted Internet + + + + + + + + 48 + 20 + + + + + + + + + + + :/images/black/32/gear.png:/images/black/32/gear.png + + + false + + + false + + + false + + + + - - - - 48 - 20 - + + + 12 - - + + 0 - - + + 12 - - - :/images/black/32/gear.png:/images/black/32/gear.png - - - false + + 0 - - false - - - false - - + - - - - 12 - - - 0 - - - 12 - - - 0 - - - @@ -253,14 +265,26 @@ background-color: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 rgb - - - -1 - - - 12 - - + + + + 0 + + + 0 + + + + + -1 + + + 12 + + + + + -- cgit v1.2.3 From 85aae3723d754dcc7a3d60edab666591ecbddd5b Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 30 Oct 2013 12:26:00 -0300 Subject: Fix non-ascii password change problem. [Closes #4003] --- changes/bug-4003_fix-non-ascii-password-change | 1 + src/leap/bitmask/crypto/srpauth.py | 14 +++++++------- src/leap/bitmask/gui/mainwindow.py | 4 ++-- src/leap/bitmask/gui/preferenceswindow.py | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) create mode 100644 changes/bug-4003_fix-non-ascii-password-change diff --git a/changes/bug-4003_fix-non-ascii-password-change b/changes/bug-4003_fix-non-ascii-password-change new file mode 100644 index 00000000..2d6a0ed8 --- /dev/null +++ b/changes/bug-4003_fix-non-ascii-password-change @@ -0,0 +1 @@ + - Fix problem changing a non-ascii password. Closes #4003. diff --git a/src/leap/bitmask/crypto/srpauth.py b/src/leap/bitmask/crypto/srpauth.py index 93fb740f..ab98850d 100644 --- a/src/leap/bitmask/crypto/srpauth.py +++ b/src/leap/bitmask/crypto/srpauth.py @@ -217,10 +217,9 @@ class SRPAuth(QtCore.QObject): """ logger.debug("Authentication preprocessing...") - self._srp_user = self._srp.User(username, - password, - self._hashfun, - self._ng) + self._srp_user = self._srp.User(username.encode('utf-8'), + password.encode('utf-8'), + self._hashfun, self._ng) _, A = self._srp_user.start_authentication() self._srp_a = A @@ -487,7 +486,8 @@ class SRPAuth(QtCore.QObject): self.get_uid()) salt, verifier = self._srp.create_salted_verification_key( - self._username, new_password, self._hashfun, self._ng) + self._username.encode('utf-8'), new_password.encode('utf-8'), + self._hashfun, self._ng) cookies = {self.SESSION_ID_KEY: self.get_session_id()} headers = { @@ -518,9 +518,9 @@ class SRPAuth(QtCore.QObject): Might raise SRPAuthenticationError :param username: username for this session - :type username: str + :type username: unicode :param password: password for this user - :type password: str + :type password: unicode :returns: A defer on a different thread :rtype: twisted.internet.defer.Deferred diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index dddd53da..fa1a82f8 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -880,8 +880,8 @@ class MainWindow(QtGui.QMainWindow): leap_assert(self._provider_config, "We need a provider config!") if data[self._provider_bootstrapper.PASSED_KEY]: - username = self._login_widget.get_user().encode("utf8") - password = self._login_widget.get_password().encode("utf8") + username = self._login_widget.get_user() + password = self._login_widget.get_password() if self._srp_auth is None: self._srp_auth = SRPAuth(self._provider_config) diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index 58cb05ba..b043afe6 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -156,7 +156,7 @@ class PreferencesWindow(QtGui.QDialog): """ logger.debug("SRP password changed successfully.") try: - self._soledad.change_passphrase(str(new_password)) + self._soledad.change_passphrase(new_password) logger.debug("Soledad password changed successfully.") except NoStorageSecret: logger.debug( -- cgit v1.2.3 From 1198f8484f0a6c89a610cd9aabcf30d2f43c832e Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 30 Oct 2013 12:31:14 -0300 Subject: Fix pep8 indent issue. And better operator usage. - E128: continuation line under-indented for visual indent. - Don't use identity operator to compare boolean. --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index d06cc910..79bec1eb 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -192,9 +192,8 @@ class SoledadBootstrapper(AbstractBootstrapper): # soledad-launcher in the gui. raise - leap_assert(sameProxiedObjects(self._soledad, None) - is not True, - "Null soledad, error while initializing") + leap_assert(not sameProxiedObjects(self._soledad, None), + "Null soledad, error while initializing") # and now, let's sync sync_tries = self.MAX_SYNC_RETRIES -- cgit v1.2.3 From 0917f8fb1bdb7b77971c5770dc6ea7f1e89a9aaa Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 30 Oct 2013 15:03:14 -0300 Subject: Remove autostart eip option from settings panel. [Closes #4132] --- changes/feature-4132_remove-autostart-eip-setting | 2 + src/leap/bitmask/gui/eip_preferenceswindow.py | 36 --------- src/leap/bitmask/gui/ui/eippreferences.ui | 99 +++-------------------- 3 files changed, 11 insertions(+), 126 deletions(-) create mode 100644 changes/feature-4132_remove-autostart-eip-setting diff --git a/changes/feature-4132_remove-autostart-eip-setting b/changes/feature-4132_remove-autostart-eip-setting new file mode 100644 index 00000000..5f3e6b7d --- /dev/null +++ b/changes/feature-4132_remove-autostart-eip-setting @@ -0,0 +1,2 @@ + - Remove autostart eip option from settings panel, rely on last used + setting. Closes #4132. diff --git a/src/leap/bitmask/gui/eip_preferenceswindow.py b/src/leap/bitmask/gui/eip_preferenceswindow.py index 9f8c4ff4..e0c5d51f 100644 --- a/src/leap/bitmask/gui/eip_preferenceswindow.py +++ b/src/leap/bitmask/gui/eip_preferenceswindow.py @@ -50,7 +50,6 @@ class EIPPreferencesWindow(QtGui.QDialog): self.ui = Ui_EIPPreferences() self.ui.setupUi(self) self.ui.lblProvidersGatewayStatus.setVisible(False) - self.ui.lblAutoStartEIPStatus.setVisible(False) # Connections self.ui.cbProvidersGateway.currentIndexChanged[unicode].connect( @@ -59,40 +58,8 @@ class EIPPreferencesWindow(QtGui.QDialog): self.ui.cbGateways.currentIndexChanged[unicode].connect( lambda x: self.ui.lblProvidersGatewayStatus.setVisible(False)) - self.ui.cbProvidersEIP.currentIndexChanged[unicode].connect( - lambda x: self.ui.lblAutoStartEIPStatus.setVisible(False)) - - self.ui.cbAutoStartEIP.toggled.connect( - lambda x: self.ui.lblAutoStartEIPStatus.setVisible(False)) - - self.ui.pbSaveAutoStartEIP.clicked.connect(self._save_auto_start_eip) - self._add_configured_providers() - # Load auto start EIP settings - self.ui.cbAutoStartEIP.setChecked(self._settings.get_autostart_eip()) - default_provider = self._settings.get_defaultprovider() - idx = self.ui.cbProvidersEIP.findText(default_provider) - self.ui.cbProvidersEIP.setCurrentIndex(idx) - - def _save_auto_start_eip(self): - """ - SLOT - TRIGGER: - self.ui.cbAutoStartEIP.toggled - - Saves the automatic start of EIP user preference. - """ - default_provider = self.ui.cbProvidersEIP.currentText() - enabled = self.ui.cbAutoStartEIP.isChecked() - - self._settings.set_autostart_eip(enabled) - self._settings.set_defaultprovider(default_provider) - - self.ui.lblAutoStartEIPStatus.show() - logger.debug('Auto start EIP saved: {0} {1}.'.format( - default_provider, enabled)) - def _set_providers_gateway_status(self, status, success=False, error=False): """ @@ -120,16 +87,13 @@ class EIPPreferencesWindow(QtGui.QDialog): Add the client's configured providers to the providers combo boxes. """ self.ui.cbProvidersGateway.clear() - self.ui.cbProvidersEIP.clear() providers = self._settings.get_configured_providers() if not providers: - self.ui.gbAutomaticEIP.setEnabled(False) self.ui.gbGatewaySelector.setEnabled(False) return for provider in providers: self.ui.cbProvidersGateway.addItem(provider) - self.ui.cbProvidersEIP.addItem(provider) def _save_selected_gateway(self, provider): """ diff --git a/src/leap/bitmask/gui/ui/eippreferences.ui b/src/leap/bitmask/gui/ui/eippreferences.ui index cc77c82e..a3050683 100644 --- a/src/leap/bitmask/gui/ui/eippreferences.ui +++ b/src/leap/bitmask/gui/ui/eippreferences.ui @@ -7,7 +7,7 @@ 0 0 435 - 273 + 144 @@ -18,7 +18,7 @@ :/images/mask-icon.png:/images/mask-icon.png - + true @@ -33,7 +33,7 @@ - &Select provider: + Select &provider: cbProvidersGateway @@ -52,7 +52,7 @@ - Save this provider settings + &Save this provider settings @@ -69,7 +69,10 @@ - Select gateway: + Select &gateway: + + + cbGateways @@ -85,76 +88,9 @@ - - - - Automatic Encrypted Internet start - - - - - - Qt::LeftToRight - - - - - - QFrame::NoFrame - - - QFrame::Plain - - - <font color='green'><b>Automatic EIP start saved!</b></font> - - - Qt::AlignCenter - - - - - - - Save auto start setting - - - - - - - Qt::LeftToRight - - - Enable Automatic start: - - - true - - - - - - - - <Select provider> - - - - - - cbAutoStartEIP - lblAutoStartEIPStatus - pbSaveAutoStartEIP - cbProvidersEIP - - - cbAutoStartEIP - cbProvidersEIP - pbSaveAutoStartEIP cbProvidersGateway cbGateways pbSaveGateway @@ -162,22 +98,5 @@ - - - cbAutoStartEIP - toggled(bool) - cbProvidersEIP - setEnabled(bool) - - - 180 - 53 - - - 238 - 53 - - - - + -- cgit v1.2.3 From 318b25373a271c12b3497125db620ab36c0db490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 30 Oct 2013 15:06:04 -0300 Subject: Properly stop imap at logout --- changes/VERSION_COMPAT | 3 +++ changes/bug_properly_stop_imap | 1 + src/leap/bitmask/services/mail/conductor.py | 23 ++++++++++++----------- 3 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 changes/bug_properly_stop_imap diff --git a/changes/VERSION_COMPAT b/changes/VERSION_COMPAT index cc00ecf7..b5e72ed5 100644 --- a/changes/VERSION_COMPAT +++ b/changes/VERSION_COMPAT @@ -8,3 +8,6 @@ # # BEGIN DEPENDENCY LIST ------------------------- # leap.foo.bar>=x.y.z + +leap.mail>=0.3.6 +leap.soledad>=0.4.2 \ No newline at end of file diff --git a/changes/bug_properly_stop_imap b/changes/bug_properly_stop_imap new file mode 100644 index 00000000..f2942bad --- /dev/null +++ b/changes/bug_properly_stop_imap @@ -0,0 +1 @@ +- Properly stop the imap daemon at logout. Fixes #4199. \ No newline at end of file diff --git a/src/leap/bitmask/services/mail/conductor.py b/src/leap/bitmask/services/mail/conductor.py index 3a3e16a3..c294381b 100644 --- a/src/leap/bitmask/services/mail/conductor.py +++ b/src/leap/bitmask/services/mail/conductor.py @@ -48,6 +48,8 @@ class IMAPControl(object): """ self.imap_machine = None self.imap_service = None + self.imap_port = None + self.imap_factory = None self.imap_connection = None leap_register(signal=leap_events.IMAP_SERVICE_STARTED, @@ -81,7 +83,9 @@ class IMAPControl(object): if self.imap_service is None: # first time. - self.imap_service = imap.start_imap_service( + self.imap_service, \ + self.imap_port, \ + self.imap_factory = imap.start_imap_service( self._soledad, self._keymanager) else: @@ -90,17 +94,18 @@ class IMAPControl(object): def stop_imap_service(self): """ - Stops imap service. - - There is a subtle difference here: - we are just stopping the fetcher here, - but in the smtp case we are stopping the factory. + Stops imap service (fetcher, factory and port). """ self.imap_connection.qtsigs.disconnecting_signal.emit() # TODO We should homogenize both services. if self.imap_service is not None: logger.debug('Stopping imap service.') + # Stop the loop call in the fetcher self.imap_service.stop() + # Stop listening on the IMAP port + self.imap_port.stopListening() + # Stop the protocol + self.imap_factory.doStop() def fetch_incoming_mail(self): """ @@ -208,11 +213,7 @@ class SMTPControl(object): def stop_smtp_service(self): """ - Stops the smtp service. - - There is a subtle difference here: - we are stopping the factory for the smtp service here, - but in the imap case we are just stopping the fetcher. + Stops the smtp service (port and factory). """ self.smtp_connection.qtsigs.disconnecting_signal.emit() # TODO We should homogenize both services. -- cgit v1.2.3 From b1b8397d9b320d13ee1bc4cd3878c081b760a380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 30 Oct 2013 15:29:17 -0300 Subject: Refactor keyring usage and fix saving problem --- changes/bug_fix_keyring_save | 2 ++ src/leap/bitmask/gui/login.py | 43 +++++++++++++++++++++++++++++++++++++- src/leap/bitmask/gui/mainwindow.py | 29 +------------------------ 3 files changed, 45 insertions(+), 29 deletions(-) create mode 100644 changes/bug_fix_keyring_save diff --git a/changes/bug_fix_keyring_save b/changes/bug_fix_keyring_save new file mode 100644 index 00000000..3be0e05b --- /dev/null +++ b/changes/bug_fix_keyring_save @@ -0,0 +1,2 @@ + - Refactor keyring handling and make it properly save user and + password. Fixes #4190. \ No newline at end of file diff --git a/src/leap/bitmask/gui/login.py b/src/leap/bitmask/gui/login.py index 255a06d3..b21057f0 100644 --- a/src/leap/bitmask/gui/login.py +++ b/src/leap/bitmask/gui/login.py @@ -49,6 +49,9 @@ class LoginWidget(QtGui.QWidget): BARE_USERNAME_REGEX = r"^[A-Za-z\d_]+$" + # Keyring + KEYRING_KEY = "bitmask" + def __init__(self, settings, parent=None): """ Constructs the LoginWidget. @@ -177,7 +180,7 @@ class LoginWidget(QtGui.QWidget): Sets the password for the widget :param password: password to set - :type password: str + :type password: unicode """ self.ui.lnPassword.setText(password) @@ -366,3 +369,41 @@ class LoginWidget(QtGui.QWidget): self.ui.btnLogout.setText(self.tr("Logout")) self.ui.btnLogout.setEnabled(True) self.ui.clblErrorMsg.hide() + + def load_user_from_keyring(self, saved_user): + """ + Tries to load a user from the keyring, returns True if it was + loaded successfully, False otherwise. + + :param saved_user: String containing the saved username as + user@domain + :type saved_user: unicode + + :rtype: bool + """ + leap_assert_type(saved_user, unicode) + + try: + username, domain = saved_user.split('@') + except ValueError as e: + # if the saved_user does not contain an '@' + logger.error('Username@provider malformed. %r' % (e, )) + return False + + self.set_user(username) + + self.set_remember(True) + + saved_password = None + try: + saved_password = keyring.get_password(self.KEYRING_KEY, + saved_user + .encode("utf8")) + except ValueError as e: + logger.debug("Incorrect Password. %r." % (e,)) + + if saved_password is not None: + self.set_password(saved_password) + return True + + return False diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 6af71e24..ce3f113b 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -20,8 +20,6 @@ Main window for Bitmask. import logging import os -import keyring - from PySide import QtCore, QtGui from twisted.internet import threads from zope.proxy import ProxyBase, setProxiedObject, sameProxiedObjects @@ -88,9 +86,6 @@ class MainWindow(QtGui.QMainWindow): LOGIN_INDEX = 0 EIP_STATUS_INDEX = 1 - # Keyring - KEYRING_KEY = "bitmask" - OPENVPN_SERVICE = "openvpn" MX_SERVICE = "mx" @@ -579,30 +574,8 @@ class MainWindow(QtGui.QMainWindow): saved_user = self._settings.get_user() - try: - username, domain = saved_user.split('@') - except (ValueError, AttributeError) as e: - # if the saved_user does not contain an '@' or its None - logger.error('Username@provider malformed. %r' % (e, )) - saved_user = None - if saved_user is not None and has_keyring(): - # fill the username - self._login_widget.set_user(username) - - self._login_widget.set_remember(True) - - saved_password = None - try: - saved_password = keyring.get_password(self.KEYRING_KEY, - saved_user - .encode("utf8")) - except ValueError, e: - logger.debug("Incorrect Password. %r." % (e,)) - - if saved_password is not None: - self._login_widget.set_password( - saved_password.decode("utf8")) + if self._login_widget.load_user_from_keyring(saved_user): self._login() def _hide_unsupported_services(self): -- cgit v1.2.3 From 0e724a63c682cfd2d8251fec528a2b8a40b493cb Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 30 Oct 2013 17:29:32 -0200 Subject: format fixes --- changes/bug-4003_fix-non-ascii-password-change | 2 +- changes/bug_fix_keyring_save | 4 ++-- changes/bug_tighter_clustering_eip_meter | 4 ++-- changes/feature-4132_remove-autostart-eip-setting | 4 ++-- changes/feature_hide_unused_services | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/changes/bug-4003_fix-non-ascii-password-change b/changes/bug-4003_fix-non-ascii-password-change index 2d6a0ed8..58de5078 100644 --- a/changes/bug-4003_fix-non-ascii-password-change +++ b/changes/bug-4003_fix-non-ascii-password-change @@ -1 +1 @@ - - Fix problem changing a non-ascii password. Closes #4003. +- Fix problem changing a non-ascii password. Closes #4003. diff --git a/changes/bug_fix_keyring_save b/changes/bug_fix_keyring_save index 3be0e05b..64bb82a9 100644 --- a/changes/bug_fix_keyring_save +++ b/changes/bug_fix_keyring_save @@ -1,2 +1,2 @@ - - Refactor keyring handling and make it properly save user and - password. Fixes #4190. \ No newline at end of file +- Refactor keyring handling and make it properly save user and + password. Fixes #4190. diff --git a/changes/bug_tighter_clustering_eip_meter b/changes/bug_tighter_clustering_eip_meter index 32101c9e..dca8f2cd 100644 --- a/changes/bug_tighter_clustering_eip_meter +++ b/changes/bug_tighter_clustering_eip_meter @@ -1,2 +1,2 @@ - - Align left the speed and transferred displays for EIP. Fixes - #4204. \ No newline at end of file +- Align left the speed and transferred displays for EIP. Fixes + #4204. diff --git a/changes/feature-4132_remove-autostart-eip-setting b/changes/feature-4132_remove-autostart-eip-setting index 5f3e6b7d..f95e4125 100644 --- a/changes/feature-4132_remove-autostart-eip-setting +++ b/changes/feature-4132_remove-autostart-eip-setting @@ -1,2 +1,2 @@ - - Remove autostart eip option from settings panel, rely on last used - setting. Closes #4132. +- Remove autostart eip option from settings panel, rely on last used + setting. Closes #4132. diff --git a/changes/feature_hide_unused_services b/changes/feature_hide_unused_services index abcdeb6f..dc942da2 100644 --- a/changes/feature_hide_unused_services +++ b/changes/feature_hide_unused_services @@ -1,2 +1,2 @@ - - Hide the GUI for services that are not supported on the set of - configured providers. Closes #4170. \ No newline at end of file +- Hide the GUI for services that are not supported on the set of + configured providers. Closes #4170. -- cgit v1.2.3 From 8fe8b705e71d5e5148073826e4030b496defc6b0 Mon Sep 17 00:00:00 2001 From: drebs Date: Thu, 31 Oct 2013 10:14:08 -0200 Subject: Fix soledad bootstrapper syncing log message type. --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 79bec1eb..d5aaf5f4 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -283,7 +283,7 @@ class SoledadBootstrapper(AbstractBootstrapper): Raises SoledadSyncError if not successful. """ try: - logger.error("trying to sync soledad....") + logger.msg("trying to sync soledad....") self._soledad.sync() except SSLError as exc: logger.error("%r" % (exc,)) -- cgit v1.2.3 From b213c870b9d924acb61a7362964856a764d60699 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 30 Oct 2013 17:50:16 -0300 Subject: Add script to bootstrap a develop environment. --- pkg/scripts/bootstrap_develop.sh | 191 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100755 pkg/scripts/bootstrap_develop.sh diff --git a/pkg/scripts/bootstrap_develop.sh b/pkg/scripts/bootstrap_develop.sh new file mode 100755 index 00000000..4660c499 --- /dev/null +++ b/pkg/scripts/bootstrap_develop.sh @@ -0,0 +1,191 @@ +#!/bin/bash +###################################################################### +# boostrap_develop.sh +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +###################################################################### +set -e # Exit immediately if a command exits with a non-zero status. +REPOSITORIES="bitmask_client leap_pycommon soledad keymanager leap_mail" +PACKAGES="leap_pycommon keymanager soledad/common soledad/client soledad/server leap_mail bitmask_client" +REPOS_ROOT=`pwd` # Root path for all the needed repositories + +PS4=">> " # for debugging + +# Escape code +esc=`echo -en "\033"` + +# Set colors +cc_green="${esc}[0;32m" +cc_yellow="${esc}[0;33m" +cc_blue="${esc}[0;34m" +cc_red="${esc}[0;31m" +cc_normal=`echo -en "${esc}[m\017"` + +clone_repos() { + status="cloning repositories" + echo "${cc_green}Status: $status...${cc_normal}" + set -x # show commands + + # clone the leap.se repos + git clone ssh://gitolite@leap.se/bitmask_client + git clone ssh://gitolite@leap.se/leap_pycommon + git clone ssh://gitolite@leap.se/soledad + git clone ssh://gitolite@leap.se/keymanager + git clone ssh://gitolite@leap.se/leap_mail + + set +x + echo "${cc_green}Status: $status done!${cc_normal}" +} + +checkout_develop(){ + status="checkout develop" + echo "${cc_green}Status: $status...${cc_normal}" + set -x # show commands + + # get the latest develop in every repo + for repo in $REPOSITORIES; do + cd $REPOS_ROOT/$repo + git checkout -f develop + done + + set +x + echo "${cc_green}Status: $status done!${cc_normal}" +} + +update_repos() { + status="updating repositories" + echo "${cc_green}Status: $status...${cc_normal}" + set -x # show commands + + # get the latest develop in every repo + for repo in $REPOSITORIES; do + cd $REPOS_ROOT/$repo + git checkout -f develop + git fetch origin; git fetch --tags origin + git reset --hard origin/develop + done + + set +x + echo "${cc_green}Status: $status done!${cc_normal}" +} + +create_venv() { + status="creating virtualenv" + echo "${cc_green}Status: $status...${cc_normal}" + set -x # show commands + + # create and activate the virtualenv + cd $REPOS_ROOT + virtualenv bitmask.venv && source ./bitmask.venv/bin/activate + + # symlink PySide to the venv + cd $REPOS_ROOT/bitmask_client + ./pkg/postmkvenv.sh + + set +x + echo "${cc_green}Status: $status done.${cc_normal}" +} + +setup_develop() { + status="installing packages" + echo "${cc_green}Status: $status...${cc_normal}" + set -x # show commands + + # do a setup develop in every package + for package in $PACKAGES; do + cd $REPOS_ROOT/$package + python setup.py develop + done + + # hack to solve gnupg version problem + pip uninstall -y gnupg && pip install gnupg + + set +x + echo "${cc_green}Status: $status done.${cc_normal}" +} + +finish(){ + echo "${cc_green}Status: process completed.${cc_normal}" + echo "You can run the client with the following command:" + echo -n "${cc_yellow}" + echo " shell> source bitmask.venv/bin/activate" + echo " shell> python bitmask_client/src/leap/bitmask/app.py -d" + echo "${cc_normal}" + echo "or with this script using:" + echo "${cc_yellow} shell> $0 run${cc_normal}" + echo +} + +initialize() { + clone_repos + checkout_develop + create_venv + setup_develop + + # make: compile ui and resources in client + make + + finish +} + +update() { + update_repos + + source $REPOS_ROOT/bitmask.venv/bin/activate + + setup_develop + + # make: compile ui and resources in client + make + + finish +} + +run() { + echo "${cc_green}Status: running client...${cc_normal}" + source bitmask.venv/bin/activate + set -x + python bitmask_client/src/leap/bitmask/app.py -d $* + set +x +} + +help() { + echo ">> LEAP developer helper" + echo "Bootstraps the environment to start developing the bitmask client" + echo "with all the needed repositories and dependencies." + echo + echo "Usage: $0 {init | update | help}" + echo + echo " init : Initialize repositories, create virtualenv and \`python setup.py develop\` all." + echo " update : Update the repositories and install new deps (if needed)." + echo " run : Runs the client (any extra parameters will be sent to the app)." + echo " help : Show this help" + echo +} + +case "$1" in + init) + initialize + ;; + update) + update + ;; + run) + run + ;; + *) + help + ;; +esac -- cgit v1.2.3 From 8d649285cdf9ff2068821bd7ee04fe6351ef49c4 Mon Sep 17 00:00:00 2001 From: drebs Date: Thu, 31 Oct 2013 14:21:35 -0200 Subject: Fix soledad bootstrapper syncing log message type (2). --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index d5aaf5f4..63596398 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -283,7 +283,7 @@ class SoledadBootstrapper(AbstractBootstrapper): Raises SoledadSyncError if not successful. """ try: - logger.msg("trying to sync soledad....") + logger.debug("trying to sync soledad....") self._soledad.sync() except SSLError as exc: logger.error("%r" % (exc,)) -- cgit v1.2.3 From 5ce85ca915bc63a08e82857a445c1866ca3abf85 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 31 Oct 2013 16:48:04 -0200 Subject: improve error handling --- changes/bug-improvie-error-handling | 1 + src/leap/bitmask/services/mail/imap.py | 7 ++++--- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 7 +++++-- 3 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 changes/bug-improvie-error-handling diff --git a/changes/bug-improvie-error-handling b/changes/bug-improvie-error-handling new file mode 100644 index 00000000..405dd771 --- /dev/null +++ b/changes/bug-improvie-error-handling @@ -0,0 +1 @@ +- Capture soledad boostrap errors after latest soledad changes. diff --git a/src/leap/bitmask/services/mail/imap.py b/src/leap/bitmask/services/mail/imap.py index 4828180e..2667f156 100644 --- a/src/leap/bitmask/services/mail/imap.py +++ b/src/leap/bitmask/services/mail/imap.py @@ -41,9 +41,10 @@ def get_mail_check_period(): try: period = int(period_str) except (ValueError, TypeError): - logger.warning("BAD value found for %s: %s" % ( - INCOMING_CHECK_PERIOD_ENV, - period_str)) + if period is not None: + logger.warning("BAD value found for %s: %s" % ( + INCOMING_CHECK_PERIOD_ENV, + period_str)) except Exception as exc: logger.warning("Unhandled error while getting %s: %r" % ( INCOMING_CHECK_PERIOD_ENV, diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 63596398..54ef67eb 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -41,7 +41,7 @@ from leap.common.check import leap_assert, leap_assert_type, leap_check from leap.common.files import which from leap.keymanager import KeyManager, openpgp from leap.keymanager.errors import KeyNotFound -from leap.soledad.client import Soledad +from leap.soledad.client import Soledad, BootstrapSequenceError logger = logging.getLogger(__name__) @@ -260,7 +260,10 @@ class SoledadBootstrapper(AbstractBootstrapper): logger.debug("SOLEDAD initialization TIMED OUT...") self.soledad_timeout.emit() except socket.error as exc: - logger.error("Socket error while initializing soledad") + logger.warning("Socket error while initializing soledad") + self.soledad_timeout.emit() + except BootstrapSequenceError as exc: + logger.warning("Error while initializing soledad") self.soledad_timeout.emit() # unrecoverable -- cgit v1.2.3 From 51cfd78c39d8eeab0c3004b7acb3ce0411742556 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 31 Oct 2013 16:30:21 -0300 Subject: Password change policy improvement. Only allow the user to change its password if is logged in and: - provider supports email and its started. - provider does not support email. In case that the conditions needed are not fullfiled, show the user the actions needed to be able to change its password. [Closes #4093] --- changes/bug-4093_change-password-policy | 2 ++ src/leap/bitmask/gui/mainwindow.py | 10 ++++----- src/leap/bitmask/gui/preferenceswindow.py | 37 ++++++++++++++++++++++++++++++- 3 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 changes/bug-4093_change-password-policy diff --git a/changes/bug-4093_change-password-policy b/changes/bug-4093_change-password-policy new file mode 100644 index 00000000..87f6fd15 --- /dev/null +++ b/changes/bug-4093_change-password-policy @@ -0,0 +1,2 @@ + - Enable password change in the client only if it has started the correct + services. Closes #4093. diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index ce3f113b..5eb9e6dc 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -446,13 +446,11 @@ class MainWindow(QtGui.QMainWindow): Displays the preferences window. """ - preferences_window = PreferencesWindow(self, self._srp_auth) + preferences_window = PreferencesWindow(self, self._srp_auth, + self._provider_config) - if sameProxiedObjects(self._soledad, None): - preferences_window.set_soledad_ready(self._soledad) - else: - self.soledad_ready.connect( - lambda: preferences_window.set_soledad_ready(self._soledad)) + self.soledad_ready.connect( + lambda: preferences_window.set_soledad_ready(self._soledad)) preferences_window.show() diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index b043afe6..86fe9433 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -40,12 +40,14 @@ class PreferencesWindow(QtGui.QDialog): """ Window that displays the preferences. """ - def __init__(self, parent, srp_auth): + def __init__(self, parent, srp_auth, provider_config): """ :param parent: parent object of the PreferencesWindow. :parent type: QWidget :param srp_auth: SRPAuth object configured in the main app. :type srp_auth: SRPAuth + :param provider_config: ProviderConfig object. + :type provider_config: ProviderConfig """ QtGui.QDialog.__init__(self, parent) self.AUTOMATIC_GATEWAY_LABEL = self.tr("Automatic") @@ -72,6 +74,35 @@ class PreferencesWindow(QtGui.QDialog): else: self._add_configured_providers() + pw_enabled = False + + # check if the user is logged in + if srp_auth is not None and srp_auth.get_session_id() is not None: + # check if provider has 'mx' ... + if provider_config.provides_mx(): + domain = provider_config.get_domain() + enabled_services = self._settings.get_enabled_services(domain) + mx_name = get_service_display_name('mx') + + # ... and if the user have it enabled + if 'mx' not in enabled_services: + msg = self.tr("You need to enable {0} in order to change " + "the password.".format(mx_name)) + self._set_password_change_status(msg, error=True) + else: + msg = self.tr( + "You need to wait until {0} is ready in " + "order to change the password.".format(mx_name)) + self._set_password_change_status(msg) + else: + pw_enabled = True + else: + msg = self.tr( + "In order to change your password you need to be logged in.") + self._set_password_change_status(msg) + + self.ui.gbPasswordChange.setEnabled(pw_enabled) + def set_soledad_ready(self, soledad): """ SLOT @@ -84,6 +115,7 @@ class PreferencesWindow(QtGui.QDialog): :type soledad: Soledad """ self._soledad = soledad + self.ui.lblPasswordChangeStatus.setVisible(False) self.ui.gbPasswordChange.setEnabled(True) def _set_password_change_status(self, status, error=False, success=False): @@ -98,6 +130,9 @@ class PreferencesWindow(QtGui.QDialog): elif success: status = "%s" % (status,) + if not self.ui.gbPasswordChange.isEnabled(): + status = "%s" % (status,) + self.ui.lblPasswordChangeStatus.setVisible(True) self.ui.lblPasswordChangeStatus.setText(status) -- cgit v1.2.3 From b2a62d05985ab3bc50fc36e5b9e89765e39da58e Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 31 Oct 2013 16:53:14 -0300 Subject: Select the logged in provider in the pref. window. [Closes #4117] --- ...elect-current-logged-in-provider-in-preferences-window | 2 ++ src/leap/bitmask/gui/preferenceswindow.py | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 changes/bug-4117_select-current-logged-in-provider-in-preferences-window diff --git a/changes/bug-4117_select-current-logged-in-provider-in-preferences-window b/changes/bug-4117_select-current-logged-in-provider-in-preferences-window new file mode 100644 index 00000000..46a031e0 --- /dev/null +++ b/changes/bug-4117_select-current-logged-in-provider-in-preferences-window @@ -0,0 +1,2 @@ + - Select the current logged in provider in the preferences window. Closes + #4117. diff --git a/src/leap/bitmask/gui/preferenceswindow.py b/src/leap/bitmask/gui/preferenceswindow.py index 86fe9433..acb39b07 100644 --- a/src/leap/bitmask/gui/preferenceswindow.py +++ b/src/leap/bitmask/gui/preferenceswindow.py @@ -77,10 +77,11 @@ class PreferencesWindow(QtGui.QDialog): pw_enabled = False # check if the user is logged in - if srp_auth is not None and srp_auth.get_session_id() is not None: + if srp_auth is not None and srp_auth.get_token() is not None: # check if provider has 'mx' ... + domain = provider_config.get_domain() + self._select_provider_by_name(domain) if provider_config.provides_mx(): - domain = provider_config.get_domain() enabled_services = self._settings.get_enabled_services(domain) mx_name = get_service_display_name('mx') @@ -253,6 +254,16 @@ class PreferencesWindow(QtGui.QDialog): for provider in self._settings.get_configured_providers(): self.ui.cbProvidersServices.addItem(provider) + def _select_provider_by_name(self, name): + """ + Given a provider name/domain, selects it in the combobox. + + :param name: name or domain for the provider + :type name: str + """ + provider_index = self.ui.cbProvidersServices.findText(name) + self.ui.cbProvidersServices.setCurrentIndex(provider_index) + def _service_selection_changed(self, service, state): """ SLOT -- cgit v1.2.3 From 71f53e07adfa77e1f9f2832334e90b1ffadda73a Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Fri, 1 Nov 2013 00:04:17 -0200 Subject: remove print --- src/leap/bitmask/gui/mail_status.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/leap/bitmask/gui/mail_status.py b/src/leap/bitmask/gui/mail_status.py index c2c06dbb..c1e82d4d 100644 --- a/src/leap/bitmask/gui/mail_status.py +++ b/src/leap/bitmask/gui/mail_status.py @@ -364,9 +364,7 @@ class MailStatusWidget(QtGui.QWidget): ext_status = None if req.event == proto.IMAP_UNREAD_MAIL: - if self._started: - print "printing foo" if req.content != "0": self._set_mail_status(self.tr("%s Unread Emails") % (req.content,), ready=2) -- cgit v1.2.3 From 2367dc448d3b1846801b8a93018f74727fcd7592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 1 Nov 2013 10:46:30 -0300 Subject: Update requirements --- changes/VERSION_COMPAT | 3 --- pkg/requirements.pip | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/changes/VERSION_COMPAT b/changes/VERSION_COMPAT index b5e72ed5..cc00ecf7 100644 --- a/changes/VERSION_COMPAT +++ b/changes/VERSION_COMPAT @@ -8,6 +8,3 @@ # # BEGIN DEPENDENCY LIST ------------------------- # leap.foo.bar>=x.y.z - -leap.mail>=0.3.6 -leap.soledad>=0.4.2 \ No newline at end of file diff --git a/pkg/requirements.pip b/pkg/requirements.pip index 29a313ea..885b19f8 100644 --- a/pkg/requirements.pip +++ b/pkg/requirements.pip @@ -19,9 +19,9 @@ keyring zope.proxy leap.common>=0.3.4 -leap.soledad.client>=0.4.0 +leap.soledad.client>=0.4.2 leap.keymanager>=0.3.4 -leap.mail>=0.3.5 +leap.mail>=0.3.6 # Remove this when u1db fixes its dependency on oauth oauth -- cgit v1.2.3 From 80fde752f0bf7946869361f6a77d1952f9339636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 1 Nov 2013 10:49:59 -0300 Subject: Fold in changes --- CHANGELOG.rst | 23 ++++++++++++++++++++++ changes/bug-4003_fix-non-ascii-password-change | 1 - changes/bug-4093_change-password-policy | 2 -- ...urrent-logged-in-provider-in-preferences-window | 2 -- changes/bug-4189_non-ascii-path-problem | 1 - changes/bug-improvie-error-handling | 1 - changes/bug_fix_keyring_save | 2 -- changes/bug_properly_stop_imap | 1 - changes/bug_tighter_clustering_eip_meter | 2 -- changes/feature-4132_remove-autostart-eip-setting | 2 -- changes/feature-4308-pin-requests-dep | 1 - changes/feature_4059-mail-state-refactor | 1 - changes/feature_4315-freeze-debianver-command | 1 - changes/feature_colored-logs | 1 - changes/feature_hide_unused_services | 2 -- 15 files changed, 23 insertions(+), 20 deletions(-) delete mode 100644 changes/bug-4003_fix-non-ascii-password-change delete mode 100644 changes/bug-4093_change-password-policy delete mode 100644 changes/bug-4117_select-current-logged-in-provider-in-preferences-window delete mode 100644 changes/bug-4189_non-ascii-path-problem delete mode 100644 changes/bug-improvie-error-handling delete mode 100644 changes/bug_fix_keyring_save delete mode 100644 changes/bug_properly_stop_imap delete mode 100644 changes/bug_tighter_clustering_eip_meter delete mode 100644 changes/feature-4132_remove-autostart-eip-setting delete mode 100644 changes/feature-4308-pin-requests-dep delete mode 100644 changes/feature_4059-mail-state-refactor delete mode 100644 changes/feature_4315-freeze-debianver-command delete mode 100644 changes/feature_colored-logs delete mode 100644 changes/feature_hide_unused_services diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e9740e4a..09ea992e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -3,6 +3,29 @@ History ------- +0.3.6 Nov 1 -- the "bạn có thể đọc này?" release: +- Fix problem changing a non-ascii password. Closes #4003. +- Enable password change in the client only if it has started the + correct services. Closes #4093. +- Select the current logged in provider in the preferences + window. Closes #4117. +- Fix problem with non-ascii paths. Closes #4189. +- Capture soledad boostrap errors after latest soledad changes. +- Refactor keyring handling and make it properly save user and + password. Fixes #4190. +- Properly stop the imap daemon at logout. Fixes #4199. +- Align left the speed and transferred displays for EIP. Fixes #4204. +- Remove autostart eip option from settings panel, rely on last used + setting. Closes #4132. +- Add support for requests 1.1.0 (raring). Closes: #4308 +- Refactor mail connections to use state machine. Closes: #4059 +- Add a command to setup.py to freeze the versions reported under + debian branches. Closes: #4315 +- Use coloredlogs handler if present (for development, not a + requirement). +- Hide the GUI for services that are not supported on the set of + configured providers. Closes #4170. + 0.3.5 Oct 18 -- the "I can stand on one foot" release: ++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/changes/bug-4003_fix-non-ascii-password-change b/changes/bug-4003_fix-non-ascii-password-change deleted file mode 100644 index 58de5078..00000000 --- a/changes/bug-4003_fix-non-ascii-password-change +++ /dev/null @@ -1 +0,0 @@ -- Fix problem changing a non-ascii password. Closes #4003. diff --git a/changes/bug-4093_change-password-policy b/changes/bug-4093_change-password-policy deleted file mode 100644 index 87f6fd15..00000000 --- a/changes/bug-4093_change-password-policy +++ /dev/null @@ -1,2 +0,0 @@ - - Enable password change in the client only if it has started the correct - services. Closes #4093. diff --git a/changes/bug-4117_select-current-logged-in-provider-in-preferences-window b/changes/bug-4117_select-current-logged-in-provider-in-preferences-window deleted file mode 100644 index 46a031e0..00000000 --- a/changes/bug-4117_select-current-logged-in-provider-in-preferences-window +++ /dev/null @@ -1,2 +0,0 @@ - - Select the current logged in provider in the preferences window. Closes - #4117. diff --git a/changes/bug-4189_non-ascii-path-problem b/changes/bug-4189_non-ascii-path-problem deleted file mode 100644 index e8b43e40..00000000 --- a/changes/bug-4189_non-ascii-path-problem +++ /dev/null @@ -1 +0,0 @@ -- Fix problem with non-ascii paths. Closes #4189. diff --git a/changes/bug-improvie-error-handling b/changes/bug-improvie-error-handling deleted file mode 100644 index 405dd771..00000000 --- a/changes/bug-improvie-error-handling +++ /dev/null @@ -1 +0,0 @@ -- Capture soledad boostrap errors after latest soledad changes. diff --git a/changes/bug_fix_keyring_save b/changes/bug_fix_keyring_save deleted file mode 100644 index 64bb82a9..00000000 --- a/changes/bug_fix_keyring_save +++ /dev/null @@ -1,2 +0,0 @@ -- Refactor keyring handling and make it properly save user and - password. Fixes #4190. diff --git a/changes/bug_properly_stop_imap b/changes/bug_properly_stop_imap deleted file mode 100644 index f2942bad..00000000 --- a/changes/bug_properly_stop_imap +++ /dev/null @@ -1 +0,0 @@ -- Properly stop the imap daemon at logout. Fixes #4199. \ No newline at end of file diff --git a/changes/bug_tighter_clustering_eip_meter b/changes/bug_tighter_clustering_eip_meter deleted file mode 100644 index dca8f2cd..00000000 --- a/changes/bug_tighter_clustering_eip_meter +++ /dev/null @@ -1,2 +0,0 @@ -- Align left the speed and transferred displays for EIP. Fixes - #4204. diff --git a/changes/feature-4132_remove-autostart-eip-setting b/changes/feature-4132_remove-autostart-eip-setting deleted file mode 100644 index f95e4125..00000000 --- a/changes/feature-4132_remove-autostart-eip-setting +++ /dev/null @@ -1,2 +0,0 @@ -- Remove autostart eip option from settings panel, rely on last used - setting. Closes #4132. diff --git a/changes/feature-4308-pin-requests-dep b/changes/feature-4308-pin-requests-dep deleted file mode 100644 index 1f7af6ca..00000000 --- a/changes/feature-4308-pin-requests-dep +++ /dev/null @@ -1 +0,0 @@ -- Add support for requests 1.1.0 (raring). Closes: #4308 diff --git a/changes/feature_4059-mail-state-refactor b/changes/feature_4059-mail-state-refactor deleted file mode 100644 index 2e3f5056..00000000 --- a/changes/feature_4059-mail-state-refactor +++ /dev/null @@ -1 +0,0 @@ -- Refactor mail connections to use state machine. Closes: #4059 diff --git a/changes/feature_4315-freeze-debianver-command b/changes/feature_4315-freeze-debianver-command deleted file mode 100644 index 0ae8ad97..00000000 --- a/changes/feature_4315-freeze-debianver-command +++ /dev/null @@ -1 +0,0 @@ -- Add a command to setup.py to freeze the versions reported under debian branches. Closes: #4315 diff --git a/changes/feature_colored-logs b/changes/feature_colored-logs deleted file mode 100644 index b28a38bd..00000000 --- a/changes/feature_colored-logs +++ /dev/null @@ -1 +0,0 @@ -- Use coloredlogs handler if present (for development, not a requirement). diff --git a/changes/feature_hide_unused_services b/changes/feature_hide_unused_services deleted file mode 100644 index dc942da2..00000000 --- a/changes/feature_hide_unused_services +++ /dev/null @@ -1,2 +0,0 @@ -- Hide the GUI for services that are not supported on the set of - configured providers. Closes #4170. -- cgit v1.2.3