Refactor MUC captcha challenge code

This commit is contained in:
Philipp Hörist 2018-12-19 11:01:09 +01:00
parent 1fec6681cd
commit e9f4c5050e
6 changed files with 82 additions and 75 deletions

View File

@ -1684,14 +1684,6 @@ class Connection(CommonConnection, ConnectionHandlers):
show=show,
caps=ptype != 'unavailable')
def send_captcha(self, jid, form_node):
if not app.account_is_connected(self.name):
return
iq = nbxmpp.Iq(typ='set', to=jid)
captcha = iq.addChild(name='captcha', namespace=nbxmpp.NS_CAPTCHA)
captcha.addChild(node=form_node)
self.connection.send(iq)
def check_unique_room_id_support(self, server, instance):
if not app.account_is_connected(self.name):
return

View File

@ -416,30 +416,6 @@ class GcMessageReceivedEvent(nec.NetworkIncomingEvent):
from gajim.common.modules.security_labels import parse_securitylabel
self.displaymarking = parse_securitylabel(self.stanza)
self.captcha_form = None
captcha_tag = self.stanza.getTag('captcha', namespace=nbxmpp.NS_CAPTCHA)
if captcha_tag:
self.captcha_form = captcha_tag.getTag('x',
namespace=nbxmpp.NS_DATA)
for field in self.captcha_form.getTags('field'):
for media in field.getTags('media'):
for uri in media.getTags('uri'):
uri_data = uri.getData()
if uri_data.startswith('cid:'):
uri_data = uri_data[4:]
found = False
for data in self.stanza.getTags('data',
namespace=nbxmpp.NS_BOB):
if data.getAttr('cid') == uri_data:
uri.setData(data.getData())
found = True
if not found:
self.conn.get_module('BitsOfBinary').get_bob_data(
uri_data, self.fjid,
self.conn._dispatch_gc_msg_with_captcha,
[self.stanza, self.msg_obj], 0)
return
from gajim.common.modules.misc import parse_correction
self.correct_id = parse_correction(self.stanza)

View File

@ -28,7 +28,6 @@ from gajim.common.helpers import AdditionalDataDict
from gajim.common.modules.security_labels import parse_securitylabel
from gajim.common.modules.user_nickname import parse_nickname
from gajim.common.modules.carbons import parse_carbon
from gajim.common.modules.bits_of_binary import parse_bob_data
from gajim.common.modules.misc import parse_delay
from gajim.common.modules.misc import parse_eme
from gajim.common.modules.misc import parse_correction
@ -58,7 +57,8 @@ class Message:
nbxmpp.NS_MAM_1,
nbxmpp.NS_MAM_2,
nbxmpp.NS_CONFERENCE,
nbxmpp.NS_IBB])
nbxmpp.NS_IBB,
nbxmpp.NS_CAPTCHA,])
def _message_received(self, _con, stanza):
# https://tools.ietf.org/html/rfc6120#section-8.1.1.1
@ -259,8 +259,6 @@ class Message:
event.additional_data.set_value(
'gajim', 'user_timestamp', user_timestamp)
parse_bob_data(event.stanza)
event_attr = {
'popup': False,
'msg_log_id': None,

View File

@ -22,12 +22,13 @@ import weakref
import nbxmpp
from gajim.common import i18n
from gajim.common.modules import dataforms
from gajim.common import app
from gajim.common import helpers
from gajim.common.caps_cache import muc_caps_cache
from gajim.common.nec import NetworkEvent
from gajim.common.nec import NetworkIncomingEvent
from gajim.common.modules import dataforms
from gajim.common.modules.bits_of_binary import parse_bob_data
log = logging.getLogger('gajim.c.m.muc')
@ -41,6 +42,7 @@ class MUC:
('message', self._on_config_change, '', nbxmpp.NS_MUC_USER),
('message', self._mediated_invite, '', nbxmpp.NS_MUC_USER),
('message', self._direct_invite, '', nbxmpp.NS_CONFERENCE),
('message', self._on_captcha_challenge, '', nbxmpp.NS_CAPTCHA),
]
def pass_disco(self, from_, identities, features, _data, _node):
@ -112,6 +114,35 @@ class MUC:
log.info('Set subject for %s', room_jid)
self._con.connection.send(message)
def _on_captcha_challenge(self, _con, stanza):
captcha = stanza.getTag('captcha', namespace=nbxmpp.NS_CAPTCHA)
if captcha is None:
return
parse_bob_data(stanza)
room_jid = str(stanza.getFrom())
contact = app.contacts.get_groupchat_contact(self._account, room_jid)
if contact is None:
return
log.info('Captcha challenge received from %s', room_jid)
data_form = captcha.getTag('x', namespace=nbxmpp.NS_DATA)
data_form = dataforms.extend_form(node=data_form)
app.nec.push_incoming_event(
NetworkEvent('captcha-challenge',
account=self._account,
room_jid=room_jid,
form=data_form))
raise nbxmpp.NodeProcessed
def send_captcha(self, room_jid, form_node):
if not app.account_is_connected(self._account):
return
iq = nbxmpp.Iq(typ='set', to=room_jid)
captcha = iq.addChild(name='captcha', namespace=nbxmpp.NS_CAPTCHA)
captcha.addChild(node=form_node)
self._con.connection.send(iq)
def request_config(self, room_jid):
if not app.account_is_connected(self._account):
return

View File

@ -44,7 +44,6 @@ from gajim import gtkgui_helpers
from gajim import gui_menu_builder
from gajim import message_control
from gajim import vcard
from gajim import dataforms_widget
from gajim.common.const import AvatarSize
from gajim.common.caps_cache import muc_caps_cache
@ -53,7 +52,6 @@ from gajim.common import app
from gajim.common import helpers
from gajim.common.helpers import launch_browser_mailer
from gajim.common.helpers import AdditionalDataDict
from gajim.common.modules import dataforms
from gajim.common import ged
from gajim.common import i18n
from gajim.common.i18n import _
@ -77,6 +75,7 @@ from gajim.gtk.add_contact import AddNewContactWindow
from gajim.gtk.tooltips import GCTooltip
from gajim.gtk.groupchat_config import GroupchatConfig
from gajim.gtk.adhoc_commands import CommandWindow
from gajim.gtk.dataform import DataFormWidget
from gajim.gtk.util import NickCompletionGenerator
from gajim.gtk.util import get_icon_name
from gajim.gtk.util import get_affiliation_surface
@ -330,6 +329,8 @@ class GroupchatControl(ChatControlBase):
self._nec_decrypted_message_received)
app.ged.register_event_handler('gc-stanza-message-outgoing', ged.OUT_POSTCORE,
self._message_sent)
app.ged.register_event_handler('captcha-challenge', ged.GUI1,
self._on_captcha_challenge)
self.is_connected = False
# disable win, we are not connected yet
ChatControlBase.got_disconnected(self)
@ -1073,6 +1074,48 @@ class GroupchatControl(ChatControlBase):
return
self._update_banner_state_image()
def _on_captcha_challenge(self, event):
if event.account != self.account:
return
if event.room_jid != self.room_jid:
return
if self.form_widget:
self.form_widget.hide()
self.form_widget.destroy()
self.btn_box.destroy()
self.form_widget = DataFormWidget(event.form)
def on_send_dataform_clicked(widget):
if not self.form_widget:
return
form_node = self.form_widget.get_submit_form()
con = app.connections[self.account]
con.get_module('MUC').send_captcha(self.room_jid, form_node)
self.form_widget.hide()
self.form_widget.destroy()
self.btn_box.destroy()
self.form_widget = None
del self.btn_box
# self.form_widget.connect('validated', on_send_dataform_clicked)
self.form_widget.show_all()
vbox = self.xml.get_object('gc_textviews_vbox')
vbox.pack_start(self.form_widget, False, True, 0)
valid_button = Gtk.Button(stock=Gtk.STOCK_OK)
valid_button.connect('clicked', on_send_dataform_clicked)
self.btn_box = Gtk.HButtonBox()
self.btn_box.set_layout(Gtk.ButtonBoxStyle.END)
self.btn_box.pack_start(valid_button, True, True, 0)
self.btn_box.show_all()
vbox.pack_start(self.btn_box, False, False, 0)
if self.parent_win:
self.parent_win.redraw_tab(self, 'attention')
else:
self.attention_flag = True
def _nec_mam_decrypted_message_received(self, obj):
if obj.conn.name != self.account:
return
@ -1090,42 +1133,7 @@ class GroupchatControl(ChatControlBase):
def _nec_gc_message_received(self, obj):
if obj.room_jid != self.room_jid or obj.conn.name != self.account:
return
if obj.captcha_form:
if self.form_widget:
self.form_widget.hide()
self.form_widget.destroy()
self.btn_box.destroy()
dataform = dataforms.extend_form(node=obj.captcha_form)
self.form_widget = dataforms_widget.DataFormWidget(dataform)
def on_send_dataform_clicked(widget):
if not self.form_widget:
return
form_node = self.form_widget.data_form.get_purged()
form_node.type_ = 'submit'
obj.conn.send_captcha(self.room_jid, form_node)
self.form_widget.hide()
self.form_widget.destroy()
self.btn_box.destroy()
self.form_widget = None
del self.btn_box
self.form_widget.connect('validated', on_send_dataform_clicked)
self.form_widget.show_all()
vbox = self.xml.get_object('gc_textviews_vbox')
vbox.pack_start(self.form_widget, False, True, 0)
valid_button = Gtk.Button(stock=Gtk.STOCK_OK)
valid_button.connect('clicked', on_send_dataform_clicked)
self.btn_box = Gtk.HButtonBox()
self.btn_box.set_layout(Gtk.ButtonBoxStyle.END)
self.btn_box.pack_start(valid_button, True, True, 0)
self.btn_box.show_all()
vbox.pack_start(self.btn_box, False, False, 0)
if self.parent_win:
self.parent_win.redraw_tab(self, 'attention')
else:
self.attention_flag = True
if not obj.nick:
# message from server
self.print_conversation(
@ -2169,6 +2177,8 @@ class GroupchatControl(ChatControlBase):
ged.GUI1, self._nec_mam_decrypted_message_received)
app.ged.remove_event_handler('gc-stanza-message-outgoing', ged.OUT_POSTCORE,
self._message_sent)
app.ged.remove_event_handler('captcha-challenge', ged.GUI1,
self._on_captcha_challenge)
if self.is_connected:
app.connections[self.account].send_gc_status(self.nick,

View File

@ -386,7 +386,7 @@ class GajimRemote(Server):
return
self.raise_signal('GCMessage', (obj.conn.name, [obj.fjid, obj.msgtxt,
obj.timestamp, obj.delayed, obj.xhtml_msgtxt,
obj.displaymarking, obj.captcha_form, obj.needs_highlight]))
obj.displaymarking, obj.needs_highlight]))
def on_our_status(self, obj):
self.raise_signal('AccountPresence', (obj.show, obj.conn.name))