Adapt to nbxmpp API changes
- Remove support for OAUTH2 - Remove insecure password dialog, its impossible now that a user can connect plain by mistake - Refactor requesting the password - Add possibility to delete passwords
This commit is contained in:
parent
b8863e82be
commit
6e30d3af64
6 changed files with 66 additions and 169 deletions
|
@ -391,9 +391,6 @@ class Config:
|
||||||
'subscription_request_msg': [opt_str, '', _('Message that is sent to contacts you want to add')],
|
'subscription_request_msg': [opt_str, '', _('Message that is sent to contacts you want to add')],
|
||||||
'enable_message_carbons': [opt_bool, True, _('If enabled and if server supports this feature, Gajim will receive messages sent and received by other resources.')],
|
'enable_message_carbons': [opt_bool, True, _('If enabled and if server supports this feature, Gajim will receive messages sent and received by other resources.')],
|
||||||
'ft_send_local_ips': [opt_bool, True, _('If enabled, Gajim will send your local IPs so your contact can connect to your machine to transfer files.')],
|
'ft_send_local_ips': [opt_bool, True, _('If enabled, Gajim will send your local IPs so your contact can connect to your machine to transfer files.')],
|
||||||
'oauth2_refresh_token': [opt_str, '', _('Latest token for OAuth 2.0 authentication.')],
|
|
||||||
'oauth2_client_id': [opt_str, '0000000044077801', _('client_id for OAuth 2.0 authentication.')],
|
|
||||||
'oauth2_redirect_url': [opt_str, 'https%3A%2F%2Fgajim.org%2Fmsnauth%2Findex.cgi', _('redirect_url for OAuth 2.0 authentication.')],
|
|
||||||
'opened_chat_controls': [opt_str, '', _('Space separated list of JIDs for which chat window will be re-opened on next startup.')],
|
'opened_chat_controls': [opt_str, '', _('Space separated list of JIDs for which chat window will be re-opened on next startup.')],
|
||||||
'recent_groupchats': [opt_str, ''],
|
'recent_groupchats': [opt_str, ''],
|
||||||
'httpupload_verify': [opt_bool, True, _('HTTP Upload: Enable HTTPS Verification')],
|
'httpupload_verify': [opt_bool, True, _('HTTP Upload: Enable HTTPS Verification')],
|
||||||
|
|
|
@ -87,7 +87,7 @@ class CommonConnection:
|
||||||
self.connected = 0
|
self.connected = 0
|
||||||
self.connection = None # xmpppy ClientCommon instance
|
self.connection = None # xmpppy ClientCommon instance
|
||||||
self.is_zeroconf = False
|
self.is_zeroconf = False
|
||||||
self.password = ''
|
self.password = None
|
||||||
self.server_resource = self._compute_resource()
|
self.server_resource = self._compute_resource()
|
||||||
self.gpg = None
|
self.gpg = None
|
||||||
self.USE_GPG = False
|
self.USE_GPG = False
|
||||||
|
@ -500,7 +500,6 @@ class Connection(CommonConnection, ConnectionHandlers):
|
||||||
self.new_account_info = None
|
self.new_account_info = None
|
||||||
self.new_account_form = None
|
self.new_account_form = None
|
||||||
self.last_sent = []
|
self.last_sent = []
|
||||||
self.password = passwords.get_password(name)
|
|
||||||
|
|
||||||
self._unregister_account = False
|
self._unregister_account = False
|
||||||
self._unregister_account_cb = None
|
self._unregister_account_cb = None
|
||||||
|
@ -510,7 +509,6 @@ class Connection(CommonConnection, ConnectionHandlers):
|
||||||
self.register_supported = False
|
self.register_supported = False
|
||||||
# Do we auto accept insecure connection
|
# Do we auto accept insecure connection
|
||||||
self.connection_auto_accepted = False
|
self.connection_auto_accepted = False
|
||||||
self.pasword_callback = None
|
|
||||||
|
|
||||||
self.on_connect_success = None
|
self.on_connect_success = None
|
||||||
self.on_connect_failure = None
|
self.on_connect_failure = None
|
||||||
|
@ -1273,25 +1271,45 @@ class Connection(CommonConnection, ConnectionHandlers):
|
||||||
return
|
return
|
||||||
|
|
||||||
log.info('SSL Cert accepted')
|
log.info('SSL Cert accepted')
|
||||||
name = None
|
self._auth()
|
||||||
if not app.config.get_per('accounts', self.name, 'anonymous_auth'):
|
|
||||||
name = app.config.get_per('accounts', self.name, 'name')
|
|
||||||
|
|
||||||
|
def _get_password(self, mechanism, on_password):
|
||||||
|
if not mechanism.startswith('SCRAM') and not mechanism == 'PLAIN':
|
||||||
|
log.error('No password method for %s known', mechanism)
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.password is not None:
|
||||||
|
# Passord already known
|
||||||
|
on_password(self.password)
|
||||||
|
return
|
||||||
|
|
||||||
|
pass_saved = app.config.get_per('accounts', self.name, 'savepass')
|
||||||
|
if pass_saved:
|
||||||
|
# Request password from keyring only if the user chose to save
|
||||||
|
# his password
|
||||||
|
self.password = passwords.get_password(self.name)
|
||||||
|
|
||||||
|
if self.password is not None:
|
||||||
|
on_password(self.password)
|
||||||
|
else:
|
||||||
|
app.nec.push_incoming_event(PasswordRequiredEvent(
|
||||||
|
None, conn=self, on_password=on_password))
|
||||||
|
|
||||||
|
def _auth(self):
|
||||||
self._register_handlers(self.connection, self._current_type)
|
self._register_handlers(self.connection, self._current_type)
|
||||||
|
|
||||||
auth_mechs = app.config.get_per(
|
if app.config.get_per('accounts', self.name, 'anonymous_auth'):
|
||||||
'accounts', self.name, 'authentication_mechanisms').split()
|
name = None
|
||||||
for mech in auth_mechs:
|
auth_mechs = {'ANONYMOUS'}
|
||||||
if mech not in nbxmpp.auth_nb.SASL_AUTHENTICATION_MECHANISMS:
|
|
||||||
log.warning('Unknown authentication mechanisms %s', mech)
|
|
||||||
if not auth_mechs:
|
|
||||||
auth_mechs = None
|
|
||||||
else:
|
else:
|
||||||
auth_mechs = set(auth_mechs)
|
name = app.config.get_per('accounts', self.name, 'name')
|
||||||
self.connection.auth(user=name,
|
auth_mechs = app.config.get_per(
|
||||||
password=self.password,
|
'accounts', self.name, 'authentication_mechanisms').split()
|
||||||
|
auth_mechs = set(auth_mechs) if auth_mechs else None
|
||||||
|
|
||||||
|
self.connection.auth(name,
|
||||||
|
get_password=self._get_password,
|
||||||
resource=self.server_resource,
|
resource=self.server_resource,
|
||||||
sasl=True,
|
|
||||||
auth_mechs=auth_mechs)
|
auth_mechs=auth_mechs)
|
||||||
|
|
||||||
def _register_handlers(self, con, con_type):
|
def _register_handlers(self, con, con_type):
|
||||||
|
@ -1795,66 +1813,6 @@ class Connection(CommonConnection, ConnectionHandlers):
|
||||||
caps=ptype != 'unavailable',
|
caps=ptype != 'unavailable',
|
||||||
idle_time=idle_time)
|
idle_time=idle_time)
|
||||||
|
|
||||||
def get_password(self, callback, type_):
|
|
||||||
if app.config.get_per('accounts', self.name, 'anonymous_auth') and \
|
|
||||||
type_ != 'ANONYMOUS':
|
|
||||||
app.nec.push_incoming_event(
|
|
||||||
NonAnonymousServerErrorEvent(None, conn=self))
|
|
||||||
self.disconnect(reconnect=False)
|
|
||||||
return
|
|
||||||
self.pasword_callback = (callback, type_)
|
|
||||||
if type_ == 'X-MESSENGER-OAUTH2':
|
|
||||||
client_id = app.config.get_per('accounts', self.name,
|
|
||||||
'oauth2_client_id')
|
|
||||||
refresh_token = app.config.get_per('accounts', self.name,
|
|
||||||
'oauth2_refresh_token')
|
|
||||||
if refresh_token:
|
|
||||||
renew_url = (
|
|
||||||
'https://oauth.live.com/token?client_id='
|
|
||||||
'%s&redirect_uri=https%%3A%%2F%%2Foauth.live.'
|
|
||||||
'com%%2Fdesktop&grant_type=refresh_token&'
|
|
||||||
'refresh_token=%s') % (client_id, refresh_token)
|
|
||||||
result = helpers.download_image(self.name, {'src': renew_url})[0]
|
|
||||||
if result:
|
|
||||||
dict_ = json.loads(result)
|
|
||||||
if 'access_token' in dict_:
|
|
||||||
self.set_password(dict_['access_token'])
|
|
||||||
return
|
|
||||||
script_url = app.config.get_per('accounts', self.name,
|
|
||||||
'oauth2_redirect_url')
|
|
||||||
token_url = (
|
|
||||||
'https://oauth.live.com/authorize?client_id='
|
|
||||||
'%s&scope=wl.messenger%%20wl.offline_access&'
|
|
||||||
'response_type=code&redirect_uri=%s') % (client_id, script_url)
|
|
||||||
helpers.launch_browser_mailer('url', token_url)
|
|
||||||
self.disconnect(reconnect=False)
|
|
||||||
app.nec.push_incoming_event(
|
|
||||||
Oauth2CredentialsRequiredEvent(None, conn=self))
|
|
||||||
return
|
|
||||||
if self.password:
|
|
||||||
self.set_password(self.password)
|
|
||||||
return
|
|
||||||
app.nec.push_incoming_event(PasswordRequiredEvent(None, conn=self))
|
|
||||||
|
|
||||||
def set_password(self, password):
|
|
||||||
self.password = password
|
|
||||||
if self.pasword_callback:
|
|
||||||
callback, type_ = self.pasword_callback
|
|
||||||
if self._current_type == 'plain' and type_ == 'PLAIN' and \
|
|
||||||
app.config.get_per('accounts', self.name,
|
|
||||||
'warn_when_insecure_password'):
|
|
||||||
app.nec.push_incoming_event(InsecurePasswordEvent(None,
|
|
||||||
conn=self))
|
|
||||||
return
|
|
||||||
callback(password)
|
|
||||||
self.pasword_callback = None
|
|
||||||
|
|
||||||
def accept_insecure_password(self):
|
|
||||||
if self.pasword_callback:
|
|
||||||
callback = self.pasword_callback[0]
|
|
||||||
callback(self.password)
|
|
||||||
self.pasword_callback = None
|
|
||||||
|
|
||||||
def unregister_account(self, on_remove_success):
|
def unregister_account(self, on_remove_success):
|
||||||
self._unregister_account = True
|
self._unregister_account = True
|
||||||
self._unregister_account_cb = on_remove_success
|
self._unregister_account_cb = on_remove_success
|
||||||
|
|
|
@ -681,9 +681,6 @@ class PEPReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
||||||
class PlainConnectionEvent(nec.NetworkIncomingEvent):
|
class PlainConnectionEvent(nec.NetworkIncomingEvent):
|
||||||
name = 'plain-connection'
|
name = 'plain-connection'
|
||||||
|
|
||||||
class InsecurePasswordEvent(nec.NetworkIncomingEvent):
|
|
||||||
name = 'insecure-password'
|
|
||||||
|
|
||||||
class InsecureSSLConnectionEvent(nec.NetworkIncomingEvent):
|
class InsecureSSLConnectionEvent(nec.NetworkIncomingEvent):
|
||||||
name = 'insecure-ssl-connection'
|
name = 'insecure-ssl-connection'
|
||||||
|
|
||||||
|
@ -723,9 +720,6 @@ class ZeroconfNameConflictEvent(nec.NetworkIncomingEvent):
|
||||||
class PasswordRequiredEvent(nec.NetworkIncomingEvent):
|
class PasswordRequiredEvent(nec.NetworkIncomingEvent):
|
||||||
name = 'password-required'
|
name = 'password-required'
|
||||||
|
|
||||||
class Oauth2CredentialsRequiredEvent(nec.NetworkIncomingEvent):
|
|
||||||
name = 'oauth2-credentials-required'
|
|
||||||
|
|
||||||
class SignedInEvent(nec.NetworkIncomingEvent):
|
class SignedInEvent(nec.NetworkIncomingEvent):
|
||||||
name = 'signed-in'
|
name = 'signed-in'
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,14 @@ class PasswordStorage:
|
||||||
def get_password(self, account_name):
|
def get_password(self, account_name):
|
||||||
"""Return the password for account_name, or None if not found."""
|
"""Return the password for account_name, or None if not found."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def save_password(self, account_name, password):
|
def save_password(self, account_name, password):
|
||||||
"""Save password for account_name. Return a bool indicating success."""
|
"""Save password for account_name. Return a bool indicating success."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def delete_password(self, account_name):
|
||||||
|
"""Delete password for account_name. Return a bool indicating success."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
class SecretPasswordStorage(PasswordStorage):
|
class SecretPasswordStorage(PasswordStorage):
|
||||||
""" Store password using Keyring """
|
""" Store password using Keyring """
|
||||||
|
@ -69,6 +73,10 @@ class SecretPasswordStorage(PasswordStorage):
|
||||||
log.debug('getting password')
|
log.debug('getting password')
|
||||||
return self.keyring.get_password('gajim', account_name)
|
return self.keyring.get_password('gajim', account_name)
|
||||||
|
|
||||||
|
def delete_password(self, account_name):
|
||||||
|
return self.keyring.delete_password('gajim', account_name)
|
||||||
|
|
||||||
|
|
||||||
class PasswordStorageManager(PasswordStorage):
|
class PasswordStorageManager(PasswordStorage):
|
||||||
"""Access all the implemented password storage backends, knowing which ones
|
"""Access all the implemented password storage backends, knowing which ones
|
||||||
are available and which we prefer to use.
|
are available and which we prefer to use.
|
||||||
|
@ -118,17 +126,27 @@ class PasswordStorageManager(PasswordStorage):
|
||||||
return pw
|
return pw
|
||||||
|
|
||||||
def save_password(self, account_name, password):
|
def save_password(self, account_name, password):
|
||||||
|
if account_name in app.connections:
|
||||||
|
app.connections[account_name].password = password
|
||||||
|
if not app.config.get_per('accounts', account_name, 'savepass'):
|
||||||
|
return True
|
||||||
|
|
||||||
if self.preferred_backend:
|
if self.preferred_backend:
|
||||||
if self.preferred_backend.save_password(account_name, password):
|
if self.preferred_backend.save_password(account_name, password):
|
||||||
app.config.set_per('accounts', account_name, 'password',
|
app.config.set_per('accounts', account_name, 'password',
|
||||||
self.preferred_backend.identifier)
|
self.preferred_backend.identifier)
|
||||||
if account_name in app.connections:
|
else:
|
||||||
app.connections[account_name].password = password
|
app.config.set_per('accounts', account_name, 'password', password)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
app.config.set_per('accounts', account_name, 'password', password)
|
def delete_password(self, account_name):
|
||||||
if account_name in app.connections:
|
if account_name in app.connections:
|
||||||
app.connections[account_name].password = password
|
app.connections[account_name].password = None
|
||||||
|
|
||||||
|
if not self.preferred_backend:
|
||||||
|
self.preferred_backend.delete_password(account_name)
|
||||||
|
else:
|
||||||
|
app.config.set_per('accounts', account_name, 'password', None)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def set_preferred_backend(self):
|
def set_preferred_backend(self):
|
||||||
|
@ -148,7 +166,8 @@ def get_storage():
|
||||||
def get_password(account_name):
|
def get_password(account_name):
|
||||||
return get_storage().get_password(account_name)
|
return get_storage().get_password(account_name)
|
||||||
|
|
||||||
|
def delete_password(account_name):
|
||||||
|
return get_storage().delete_password(account_name)
|
||||||
|
|
||||||
def save_password(account_name, password):
|
def save_password(account_name, password):
|
||||||
if account_name in app.connections:
|
|
||||||
app.connections[account_name].set_password(password)
|
|
||||||
return get_storage().save_password(account_name, password)
|
return get_storage().save_password(account_name, password)
|
||||||
|
|
|
@ -810,4 +810,4 @@ class LoginDialog(OptionsDialog):
|
||||||
def on_destroy(self, *args):
|
def on_destroy(self, *args):
|
||||||
savepass = app.config.get_per('accounts', self.account, 'savepass')
|
savepass = app.config.get_per('accounts', self.account, 'savepass')
|
||||||
if not savepass:
|
if not savepass:
|
||||||
passwords.save_password(self.account, '')
|
passwords.delete_password(self.account)
|
||||||
|
|
|
@ -107,7 +107,6 @@ from gajim.gtk.dialogs import WarningDialog
|
||||||
from gajim.gtk.dialogs import InformationDialog
|
from gajim.gtk.dialogs import InformationDialog
|
||||||
from gajim.gtk.dialogs import InputDialog
|
from gajim.gtk.dialogs import InputDialog
|
||||||
from gajim.gtk.dialogs import YesNoDialog
|
from gajim.gtk.dialogs import YesNoDialog
|
||||||
from gajim.gtk.dialogs import InputTextDialog
|
|
||||||
from gajim.gtk.dialogs import PlainConnectionDialog
|
from gajim.gtk.dialogs import PlainConnectionDialog
|
||||||
from gajim.gtk.dialogs import SSLErrorDialog
|
from gajim.gtk.dialogs import SSLErrorDialog
|
||||||
from gajim.gtk.dialogs import ConfirmationDialogDoubleCheck
|
from gajim.gtk.dialogs import ConfirmationDialogDoubleCheck
|
||||||
|
@ -713,45 +712,19 @@ class Interface:
|
||||||
text = _('Enter your password for account %s') % account
|
text = _('Enter your password for account %s') % account
|
||||||
|
|
||||||
def on_ok(passphrase, save):
|
def on_ok(passphrase, save):
|
||||||
if save:
|
app.config.set_per('accounts', account, 'savepass', save)
|
||||||
app.config.set_per('accounts', account, 'savepass', True)
|
passwords.save_password(account, passphrase)
|
||||||
passwords.save_password(account, passphrase)
|
obj.on_password(passphrase)
|
||||||
obj.conn.set_password(passphrase)
|
|
||||||
del self.pass_dialog[account]
|
del self.pass_dialog[account]
|
||||||
|
|
||||||
def on_cancel():
|
def on_cancel():
|
||||||
self.roster.set_state(account, 'offline')
|
obj.conn.disconnect(reconnect=False, immediately=True)
|
||||||
self.roster.update_status_combobox()
|
|
||||||
del self.pass_dialog[account]
|
del self.pass_dialog[account]
|
||||||
|
|
||||||
self.pass_dialog[account] = dialogs.PassphraseDialog(
|
self.pass_dialog[account] = dialogs.PassphraseDialog(
|
||||||
_('Password Required'), text, _('Save password'), ok_handler=on_ok,
|
_('Password Required'), text, _('Save password'), ok_handler=on_ok,
|
||||||
cancel_handler=on_cancel)
|
cancel_handler=on_cancel)
|
||||||
|
|
||||||
def handle_oauth2_credentials(self, obj):
|
|
||||||
account = obj.conn.name
|
|
||||||
def on_ok(refresh):
|
|
||||||
app.config.set_per('accounts', account, 'oauth2_refresh_token',
|
|
||||||
refresh)
|
|
||||||
st = app.config.get_per('accounts', account, 'last_status')
|
|
||||||
msg = helpers.from_one_line(app.config.get_per('accounts',
|
|
||||||
account, 'last_status_msg'))
|
|
||||||
app.interface.roster.send_status(account, st, msg)
|
|
||||||
del self.pass_dialog[account]
|
|
||||||
|
|
||||||
def on_cancel():
|
|
||||||
app.config.set_per('accounts', account, 'oauth2_refresh_token',
|
|
||||||
'')
|
|
||||||
self.roster.set_state(account, 'offline')
|
|
||||||
self.roster.update_status_combobox()
|
|
||||||
del self.pass_dialog[account]
|
|
||||||
|
|
||||||
instruction = _('Please copy / paste the refresh token from the website'
|
|
||||||
' that has just been opened.')
|
|
||||||
self.pass_dialog[account] = InputTextDialog(
|
|
||||||
_('Oauth2 Credentials'), instruction, is_modal=False,
|
|
||||||
ok_handler=on_ok, cancel_handler=on_cancel)
|
|
||||||
|
|
||||||
def handle_event_roster_info(self, obj):
|
def handle_event_roster_info(self, obj):
|
||||||
#('ROSTER_INFO', account, (jid, name, sub, ask, groups))
|
#('ROSTER_INFO', account, (jid, name, sub, ask, groups))
|
||||||
account = obj.conn.name
|
account = obj.conn.name
|
||||||
|
@ -1454,48 +1427,6 @@ class Interface:
|
||||||
checktext2, on_response_ok=on_ok, on_response_cancel=on_cancel,
|
checktext2, on_response_ok=on_ok, on_response_cancel=on_cancel,
|
||||||
is_modal=False)
|
is_modal=False)
|
||||||
|
|
||||||
def handle_event_insecure_password(self, obj):
|
|
||||||
# ('INSECURE_PASSWORD', account, ())
|
|
||||||
def on_ok(is_checked):
|
|
||||||
if not is_checked[0]:
|
|
||||||
on_cancel()
|
|
||||||
return
|
|
||||||
del self.instances[obj.conn.name]['online_dialog']\
|
|
||||||
['insecure_password']
|
|
||||||
if is_checked[1]:
|
|
||||||
app.config.set_per('accounts', obj.conn.name,
|
|
||||||
'warn_when_insecure_password', False)
|
|
||||||
if obj.conn.connected == 0:
|
|
||||||
# We have been disconnecting (too long time since window is
|
|
||||||
# opened)
|
|
||||||
# re-connect with auto-accept
|
|
||||||
obj.conn.connection_auto_accepted = True
|
|
||||||
show, msg = obj.conn.continue_connect_info[:2]
|
|
||||||
self.roster.send_status(obj.conn.name, show, msg)
|
|
||||||
return
|
|
||||||
obj.conn.accept_insecure_password()
|
|
||||||
|
|
||||||
def on_cancel():
|
|
||||||
del self.instances[obj.conn.name]['online_dialog']\
|
|
||||||
['insecure_password']
|
|
||||||
obj.conn.disconnect(reconnect=False)
|
|
||||||
app.nec.push_incoming_event(OurShowEvent(None, conn=obj.conn,
|
|
||||||
show='offline'))
|
|
||||||
|
|
||||||
pritext = _('Insecure connection')
|
|
||||||
sectext = _('You are about to send your password unencrypted on an '
|
|
||||||
'insecure connection. Are you sure you want to do that?')
|
|
||||||
checktext1 = _('Yes, I really want to connect insecurely')
|
|
||||||
checktext2 = _('_Do not ask me again')
|
|
||||||
if 'insecure_password' in self.instances[obj.conn.name]\
|
|
||||||
['online_dialog']:
|
|
||||||
self.instances[obj.conn.name]['online_dialog']\
|
|
||||||
['insecure_password'].destroy()
|
|
||||||
self.instances[obj.conn.name]['online_dialog']['insecure_password'] = \
|
|
||||||
ConfirmationDialogDoubleCheck(pritext, sectext, checktext1,
|
|
||||||
checktext2, on_response_ok=on_ok, on_response_cancel=on_cancel,
|
|
||||||
is_modal=False)
|
|
||||||
|
|
||||||
def create_core_handlers_list(self):
|
def create_core_handlers_list(self):
|
||||||
self.handlers = {
|
self.handlers = {
|
||||||
'DB_ERROR': [self.handle_event_db_error],
|
'DB_ERROR': [self.handle_event_db_error],
|
||||||
|
@ -1515,7 +1446,6 @@ class Interface:
|
||||||
'gpg-trust-key': [self.handle_event_gpg_trust_key],
|
'gpg-trust-key': [self.handle_event_gpg_trust_key],
|
||||||
'http-auth-received': [self.handle_event_http_auth],
|
'http-auth-received': [self.handle_event_http_auth],
|
||||||
'information': [self.handle_event_information],
|
'information': [self.handle_event_information],
|
||||||
'insecure-password': [self.handle_event_insecure_password],
|
|
||||||
'insecure-ssl-connection': \
|
'insecure-ssl-connection': \
|
||||||
[self.handle_event_insecure_ssl_connection],
|
[self.handle_event_insecure_ssl_connection],
|
||||||
'iq-error-received': [self.handle_event_iq_error],
|
'iq-error-received': [self.handle_event_iq_error],
|
||||||
|
@ -1530,7 +1460,6 @@ class Interface:
|
||||||
'message-sent': [self.handle_event_msgsent],
|
'message-sent': [self.handle_event_msgsent],
|
||||||
'metacontacts-received': [self.handle_event_metacontacts],
|
'metacontacts-received': [self.handle_event_metacontacts],
|
||||||
'muc-owner-received': [self.handle_event_gc_config],
|
'muc-owner-received': [self.handle_event_gc_config],
|
||||||
'oauth2-credentials-required': [self.handle_oauth2_credentials],
|
|
||||||
'our-show': [self.handle_event_status],
|
'our-show': [self.handle_event_status],
|
||||||
'password-required': [self.handle_event_password_required],
|
'password-required': [self.handle_event_password_required],
|
||||||
'plain-connection': [self.handle_event_plain_connection],
|
'plain-connection': [self.handle_event_plain_connection],
|
||||||
|
|
Loading…
Add table
Reference in a new issue