From 560a122ab59d5918fc7039c15bcd8987c9e15ab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20H=C3=B6rist?= Date: Wed, 1 Aug 2018 00:35:15 +0200 Subject: [PATCH] Add error message to change password dialog - Move register methods to own module --- gajim/common/connection.py | 11 -- gajim/common/modules/register.py | 62 ++++++++ gajim/data/gui/change_password_dialog.ui | 193 ++++++----------------- gajim/data/style/gajim.css | 2 + gajim/dialogs.py | 35 ---- gajim/gtk/__init__.py | 1 + gajim/gtk/dialogs.py | 55 +++++++ gajim/options_dialog.py | 10 +- 8 files changed, 171 insertions(+), 198 deletions(-) create mode 100644 gajim/common/modules/register.py diff --git a/gajim/common/connection.py b/gajim/common/connection.py index 85703eb67..42528cabb 100644 --- a/gajim/common/connection.py +++ b/gajim/common/connection.py @@ -1835,17 +1835,6 @@ class Connection(CommonConnection, ConnectionHandlers): # disconnect from jabber server self.connection.send(p) - def change_password(self, password): - if not app.account_is_connected(self.name): - return - hostname = app.config.get_per('accounts', self.name, 'hostname') - username = app.config.get_per('accounts', self.name, 'name') - iq = nbxmpp.Iq(typ='set', to=hostname) - q = iq.setTag(nbxmpp.NS_REGISTER + ' query') - q.setTagData('username', username) - q.setTagData('password', password) - self.connection.send(iq) - def get_password(self, callback, type_): if app.config.get_per('accounts', self.name, 'anonymous_auth') and \ type_ != 'ANONYMOUS': diff --git a/gajim/common/modules/register.py b/gajim/common/modules/register.py new file mode 100644 index 000000000..6f52b57c5 --- /dev/null +++ b/gajim/common/modules/register.py @@ -0,0 +1,62 @@ +# This file is part of Gajim. +# +# Gajim 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; version 3 only. +# +# Gajim 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 Gajim. If not, see . + +# XEP-0077: In-Band Registration + +import logging +import weakref + +import nbxmpp + +from gajim.common import app + +log = logging.getLogger('gajim.c.m.register') + + +class Register: + def __init__(self, con): + self._con = con + self._account = con.name + + self.handlers = [] + + def change_password(self, password, success_cb, error_cb): + if not app.account_is_connected(self._account): + return + hostname = app.config.get_per('accounts', self._account, 'hostname') + username = app.config.get_per('accounts', self._account, 'name') + iq = nbxmpp.Iq(typ='set', to=hostname) + q = iq.setTag(nbxmpp.NS_REGISTER + ' query') + q.setTagData('username', username) + q.setTagData('password', password) + + weak_success_cb = weakref.WeakMethod(success_cb) + weak_error_cb = weakref.WeakMethod(error_cb) + log.info('Send password change') + self._con.connection.SendAndCallForResponse( + iq, self._change_password_response, {'success_cb': weak_success_cb, + 'error_cb': weak_error_cb}) + + def _change_password_response(self, con, stanza, success_cb, error_cb): + if not nbxmpp.isResultNode(stanza): + error = stanza.getErrorMsg() + log.info('Error: %s', error) + error_cb()(error) + else: + log.info('Password changed') + success_cb()() + + +def get_instance(*args, **kwargs): + return Register(*args, **kwargs), 'Register' diff --git a/gajim/data/gui/change_password_dialog.ui b/gajim/data/gui/change_password_dialog.ui index 13ffe02a7..292334a4f 100644 --- a/gajim/data/gui/change_password_dialog.ui +++ b/gajim/data/gui/change_password_dialog.ui @@ -1,157 +1,56 @@ - + - + + 220 + True False - 6 - Change Password - dialog - - + 12 + vertical + 6 + + + True + True + False + New Password + + + False + True + 0 + + + + + True + True + False + True + Confirm New Password + + + False + True + 1 + + + + True False - vertical - 6 - - - True - False - end - - - gtk-cancel - True - True - True - False - True - - - False - False - 0 - - - - - gtk-ok - True - True - True - False - True - - - False - False - 1 - - - - - False - False - end - 0 - - - - - True - False - 6 - 12 - - - True - False - gtk-dialog-question - 6 - - - False - True - 0 - - - - - True - False - vertical - 6 - - - True - False - 0 - Enter new password: - True - - - False - False - 0 - - - - - True - True - False - - - False - False - 1 - - - - - True - False - 0 - Enter it again for confirmation: - - - False - False - 2 - - - - - True - True - False - True - - - False - False - 3 - - - - - True - True - 1 - - - - - False - True - 2 - - + True + 0 + + + False + True + 2 + - - cancelbutton2 - okbutton2 - diff --git a/gajim/data/style/gajim.css b/gajim/data/style/gajim.css index fc0baf96d..b42354ebe 100644 --- a/gajim/data/style/gajim.css +++ b/gajim/data/style/gajim.css @@ -21,6 +21,8 @@ background-image: none; } +.dialog-margin > box { margin: 18px;} + #MessageWindow, #RosterWindow paned { background-color: @theme_base_color; } .chatcontrol-separator-top {margin-top: 5px;} diff --git a/gajim/dialogs.py b/gajim/dialogs.py index 205e99cb4..ead6e7d07 100644 --- a/gajim/dialogs.py +++ b/gajim/dialogs.py @@ -1058,41 +1058,6 @@ class SynchroniseSelectContactsDialog: iter_ = model.iter_next(iter_) self.dialog.destroy() -class ChangePasswordDialog: - def __init__(self, account, on_response, transient_for=None): - # 'account' can be None if we are about to create our first one - if not account or app.connections[account].connected < 2: - ErrorDialog(_('You are not connected to the server'), - _('Without a connection, you can not change your password.')) - raise GajimGeneralException('You are not connected to the server') - self.account = account - self.on_response = on_response - self.xml = gtkgui_helpers.get_gtk_builder('change_password_dialog.ui') - self.dialog = self.xml.get_object('change_password_dialog') - self.dialog.set_transient_for(transient_for) - self.password1_entry = self.xml.get_object('password1_entry') - self.password2_entry = self.xml.get_object('password2_entry') - self.dialog.connect('response', self.on_dialog_response) - - self.dialog.show_all() - - def on_dialog_response(self, dialog, response): - if response != Gtk.ResponseType.OK: - dialog.destroy() - self.on_response(None) - return - password1 = self.password1_entry.get_text() - if not password1: - ErrorDialog(_('Invalid password'), _('You must enter a password.')) - return - password2 = self.password2_entry.get_text() - if password1 != password2: - ErrorDialog(_('Passwords do not match'), - _('The passwords typed in both fields must be identical.')) - return - dialog.destroy() - self.on_response(password1) - #Action that can be done with an incoming list of contacts TRANSLATED_ACTION = {'add': _('add'), 'modify': _('modify'), diff --git a/gajim/gtk/__init__.py b/gajim/gtk/__init__.py index c901ac2e5..e21fc3645 100644 --- a/gajim/gtk/__init__.py +++ b/gajim/gtk/__init__.py @@ -51,6 +51,7 @@ from gajim.gtk.dialogs import ConfirmationDialog from gajim.gtk.dialogs import AspellDictError from gajim.gtk.dialogs import HigDialog from gajim.gtk.dialogs import SSLErrorDialog +from gajim.gtk.dialogs import ChangePasswordDialog from gajim.gtk.about import AboutDialog from gajim.gtk.join_groupchat import JoinGroupchatWindow diff --git a/gajim/gtk/dialogs.py b/gajim/gtk/dialogs.py index 731fb7b4c..ea3feb5bc 100644 --- a/gajim/gtk/dialogs.py +++ b/gajim/gtk/dialogs.py @@ -13,6 +13,7 @@ # along with Gajim. If not, see . from gi.repository import Gtk +from gi.repository import Gdk from gajim.common import app from gajim.common import helpers @@ -931,3 +932,57 @@ class SSLErrorDialog(ConfirmationDialogDoubleCheck): def on_cert_clicked(self, button): CertificatDialog(self, self.account, self.cert) + + +class ChangePasswordDialog(Gtk.Dialog): + def __init__(self, account, success_cb, transient_for): + flags = Gtk.DialogFlags.DESTROY_WITH_PARENT + super().__init__(_('Change Password'), None, flags) + + self._account = account + self._success_cb = success_cb + + self._builder = get_builder('change_password_dialog.ui') + self.get_content_area().add( + self._builder.get_object('change_password_box')) + self._password1_entry = self._builder.get_object('password1_entry') + self._password2_entry = self._builder.get_object('password2_entry') + self._error_label = self._builder.get_object('error_label') + + self.set_transient_for(transient_for) + + self.add_button(_('_OK'), Gtk.ResponseType.OK) + self.set_default_response(Gtk.ResponseType.OK) + self.get_style_context().add_class('dialog-margin') + self.connect('response', self._on_dialog_response) + self.show_all() + + def _on_dialog_response(self, dialog, response): + if response != Gtk.ResponseType.OK: + self.destroy() + return + + password1 = self._password1_entry.get_text() + if not password1: + self._error_label.set_text(_('You must enter a password')) + return + password2 = self._password2_entry.get_text() + if password1 != password2: + self._error_label.set_text(_('Passwords do not match')) + return + + self._password1_entry.set_sensitive(False) + self._password2_entry.set_sensitive(False) + + con = app.connections[self._account] + con.get_module('Register').change_password( + password1, self._on_success, self._on_error) + + def _on_success(self): + self._success_cb(self._password1_entry.get_text()) + self.destroy() + + def _on_error(self, error_text): + self._error_label.set_text(error_text) + self._password1_entry.set_sensitive(True) + self._password2_entry.set_sensitive(True) diff --git a/gajim/options_dialog.py b/gajim/options_dialog.py index a5e66ab5b..5f06a17f8 100644 --- a/gajim/options_dialog.py +++ b/gajim/options_dialog.py @@ -6,6 +6,8 @@ from gajim.common.const import OptionKind, OptionType from gajim.common.exceptions import GajimGeneralException from gajim import dialogs from gajim.gtk import ErrorDialog +from gajim.gtk import ChangePasswordDialog + class OptionsDialog(Gtk.ApplicationWindow): def __init__(self, parent, title, flags, options, account, @@ -530,16 +532,14 @@ class ChangePasswordOption(DialogOption): def show_dialog(self, parent): try: - self.change_dialog = dialogs.ChangePasswordDialog( + self.change_dialog = ChangePasswordDialog( self.account, self.on_changed, parent) except GajimGeneralException: return - self.change_dialog.dialog.set_modal(True) + self.change_dialog.set_modal(True) def on_changed(self, new_password): - if new_password is not None: - app.connections[self.account].change_password(new_password) - self.set_value(new_password) + self.set_value(new_password) def set_activatable(self, name, value): activatable = False