Add error message to change password dialog

- Move register methods to own module
This commit is contained in:
Philipp Hörist 2018-08-01 00:35:15 +02:00
parent 4096ab5db5
commit 560a122ab5
8 changed files with 171 additions and 198 deletions

View File

@ -1835,17 +1835,6 @@ class Connection(CommonConnection, ConnectionHandlers):
# disconnect from jabber server # disconnect from jabber server
self.connection.send(p) 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_): def get_password(self, callback, type_):
if app.config.get_per('accounts', self.name, 'anonymous_auth') and \ if app.config.get_per('accounts', self.name, 'anonymous_auth') and \
type_ != 'ANONYMOUS': type_ != 'ANONYMOUS':

View File

@ -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'

View File

@ -1,123 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 --> <!-- Generated with glade 3.22.1 -->
<interface> <interface>
<requires lib="gtk+" version="3.12"/> <requires lib="gtk+" version="3.12"/>
<object class="GtkDialog" id="change_password_dialog"> <object class="GtkBox" id="change_password_box">
<property name="can_focus">False</property> <property name="width_request">220</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="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="margin_bottom">12</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<property name="spacing">6</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> <child>
<object class="GtkEntry" id="password1_entry"> <object class="GtkEntry" id="password1_entry">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="visibility">False</property> <property name="visibility">False</property>
<property name="placeholder_text" translatable="yes">New Password</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
<property name="fill">False</property> <property name="fill">True</property>
<property name="position">1</property> <property name="position">0</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> </packing>
</child> </child>
<child> <child>
@ -126,20 +28,23 @@
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="visibility">False</property> <property name="visibility">False</property>
<property name="activates_default">True</property> <property name="activates_default">True</property>
<property name="placeholder_text" translatable="yes">Confirm New Password</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <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="fill">True</property>
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkLabel" id="error_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="wrap">True</property>
<property name="xalign">0</property>
<style>
<class name="error-color"/>
</style>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -148,10 +53,4 @@
</packing> </packing>
</child> </child>
</object> </object>
</child>
<action-widgets>
<action-widget response="-6">cancelbutton2</action-widget>
<action-widget response="-5">okbutton2</action-widget>
</action-widgets>
</object>
</interface> </interface>

View File

@ -21,6 +21,8 @@
background-image: none; background-image: none;
} }
.dialog-margin > box { margin: 18px;}
#MessageWindow, #RosterWindow paned { background-color: @theme_base_color; } #MessageWindow, #RosterWindow paned { background-color: @theme_base_color; }
.chatcontrol-separator-top {margin-top: 5px;} .chatcontrol-separator-top {margin-top: 5px;}

View File

@ -1058,41 +1058,6 @@ class SynchroniseSelectContactsDialog:
iter_ = model.iter_next(iter_) iter_ = model.iter_next(iter_)
self.dialog.destroy() 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 #Action that can be done with an incoming list of contacts
TRANSLATED_ACTION = {'add': _('add'), 'modify': _('modify'), TRANSLATED_ACTION = {'add': _('add'), 'modify': _('modify'),

View File

@ -51,6 +51,7 @@ from gajim.gtk.dialogs import ConfirmationDialog
from gajim.gtk.dialogs import AspellDictError from gajim.gtk.dialogs import AspellDictError
from gajim.gtk.dialogs import HigDialog from gajim.gtk.dialogs import HigDialog
from gajim.gtk.dialogs import SSLErrorDialog from gajim.gtk.dialogs import SSLErrorDialog
from gajim.gtk.dialogs import ChangePasswordDialog
from gajim.gtk.about import AboutDialog from gajim.gtk.about import AboutDialog
from gajim.gtk.join_groupchat import JoinGroupchatWindow from gajim.gtk.join_groupchat import JoinGroupchatWindow

View File

@ -13,6 +13,7 @@
# along with Gajim. If not, see <http://www.gnu.org/licenses/>. # along with Gajim. If not, see <http://www.gnu.org/licenses/>.
from gi.repository import Gtk from gi.repository import Gtk
from gi.repository import Gdk
from gajim.common import app from gajim.common import app
from gajim.common import helpers from gajim.common import helpers
@ -931,3 +932,57 @@ class SSLErrorDialog(ConfirmationDialogDoubleCheck):
def on_cert_clicked(self, button): def on_cert_clicked(self, button):
CertificatDialog(self, self.account, self.cert) 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)

View File

@ -6,6 +6,8 @@ from gajim.common.const import OptionKind, OptionType
from gajim.common.exceptions import GajimGeneralException from gajim.common.exceptions import GajimGeneralException
from gajim import dialogs from gajim import dialogs
from gajim.gtk import ErrorDialog from gajim.gtk import ErrorDialog
from gajim.gtk import ChangePasswordDialog
class OptionsDialog(Gtk.ApplicationWindow): class OptionsDialog(Gtk.ApplicationWindow):
def __init__(self, parent, title, flags, options, account, def __init__(self, parent, title, flags, options, account,
@ -530,15 +532,13 @@ class ChangePasswordOption(DialogOption):
def show_dialog(self, parent): def show_dialog(self, parent):
try: try:
self.change_dialog = dialogs.ChangePasswordDialog( self.change_dialog = ChangePasswordDialog(
self.account, self.on_changed, parent) self.account, self.on_changed, parent)
except GajimGeneralException: except GajimGeneralException:
return return
self.change_dialog.dialog.set_modal(True) self.change_dialog.set_modal(True)
def on_changed(self, new_password): 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): def set_activatable(self, name, value):