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

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,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>

View File

@ -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;}

View File

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

View File

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

View File

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

View File

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