Philipp Hörist pushed to branch master at gajim / gajim
Commits: 560a122a by Philipp Hörist at 2018-07-31T22:35:42Z Add error message to change password dialog
- Move register methods to own module
- - - - -
8 changed files:
- gajim/common/connection.py - + gajim/common/modules/register.py - gajim/data/gui/change_password_dialog.ui - gajim/data/style/gajim.css - gajim/dialogs.py - gajim/gtk/__init__.py - gajim/gtk/dialogs.py - gajim/options_dialog.py
Changes:
===================================== gajim/common/connection.py ===================================== --- 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':
===================================== gajim/common/modules/register.py ===================================== --- /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 http://www.gnu.org/licenses/. + +# 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'
===================================== gajim/data/gui/change_password_dialog.ui ===================================== --- a/gajim/data/gui/change_password_dialog.ui +++ b/gajim/data/gui/change_password_dialog.ui @@ -1,157 +1,56 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.18.3 --> +<!-- Generated with glade 3.22.1 --> <interface> <requires lib="gtk+" version="3.12"/> - <object class="GtkDialog" id="change_password_dialog"> + <object class="GtkBox" id="change_password_box"> + <property name="width_request">220</property> + <property name="visible">True</property> <property name="can_focus">False</property> - <property name="border_width">6</property> - <property name="title" translatable="yes">Change Password</property> - <property name="type_hint">dialog</property> - <child internal-child="vbox"> - <object class="GtkBox" id="dialog-vbox7"> + <property name="margin_bottom">12</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkEntry" id="password1_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="visibility">False</property> + <property name="placeholder_text" translatable="yes">New Password</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="password2_entry"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="visibility">False</property> + <property name="activates_default">True</property> + <property name="placeholder_text" translatable="yes">Confirm New Password</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="error_label"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child internal-child="action_area"> - <object class="GtkButtonBox" id="dialog-action_area6"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="layout_style">end</property> - <child> - <object class="GtkButton" id="cancelbutton2"> - <property name="label">gtk-cancel</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkButton" id="okbutton2"> - <property name="label">gtk-ok</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="can_default">True</property> - <property name="receives_default">False</property> - <property name="use_stock">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="pack_type">end</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkBox" id="hbox2928"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="border_width">6</property> - <property name="spacing">12</property> - <child> - <object class="GtkImage" id="image416"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="stock">gtk-dialog-question</property> - <property name="icon_size">6</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkBox" id="vbox54"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="orientation">vertical</property> - <property name="spacing">6</property> - <child> - <object class="GtkLabel" id="label208"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Enter new password:</property> - <property name="wrap">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">0</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="password1_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="visibility">False</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> - <child> - <object class="GtkLabel" id="label209"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="xalign">0</property> - <property name="label" translatable="yes">Enter it again for confirmation:</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">2</property> - </packing> - </child> - <child> - <object class="GtkEntry" id="password2_entry"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="visibility">False</property> - <property name="activates_default">True</property> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">3</property> - </packing> - </child> - </object> - <packing> - <property name="expand">True</property> - <property name="fill">True</property> - <property name="position">1</property> - </packing> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">2</property> - </packing> - </child> + <property name="wrap">True</property> + <property name="xalign">0</property> + <style> + <class name="error-color"/> + </style> </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> </child> - <action-widgets> - <action-widget response="-6">cancelbutton2</action-widget> - <action-widget response="-5">okbutton2</action-widget> - </action-widgets> </object> </interface>
===================================== gajim/data/style/gajim.css ===================================== --- 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;}
===================================== gajim/dialogs.py ===================================== --- 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'),
===================================== gajim/gtk/__init__.py ===================================== --- 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
===================================== gajim/gtk/dialogs.py ===================================== --- a/gajim/gtk/dialogs.py +++ b/gajim/gtk/dialogs.py @@ -13,6 +13,7 @@ # along with Gajim. If not, see http://www.gnu.org/licenses/.
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)
===================================== gajim/options_dialog.py ===================================== --- 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
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/560a122ab59d5918fc7039c15bcd8987c9e...