handle (un)subscription requests with NEC
This commit is contained in:
parent
a3a61a3c22
commit
e2c270a67c
|
@ -1116,6 +1116,16 @@ ConnectionJingle, ConnectionIBBytestream):
|
|||
self._nec_ping_received)
|
||||
gajim.ged.register_event_handler('presence-received', ged.CORE,
|
||||
self._nec_presence_received)
|
||||
gajim.ged.register_event_handler('subscribe-presence-received',
|
||||
ged.CORE, self._nec_subscribe_presence_received)
|
||||
gajim.ged.register_event_handler('subscribed-presence-received',
|
||||
ged.CORE, self._nec_subscribed_presence_received)
|
||||
gajim.ged.register_event_handler('subscribed-presence-received',
|
||||
ged.POSTGUI, self._nec_subscribed_presence_received_end)
|
||||
gajim.ged.register_event_handler('unsubscribed-presence-received',
|
||||
ged.CORE, self._nec_unsubscribed_presence_received)
|
||||
gajim.ged.register_event_handler('unsubscribed-presence-received',
|
||||
ged.POSTGUI, self._nec_unsubscribed_presence_received_end)
|
||||
|
||||
def build_http_auth_answer(self, iq_obj, answer):
|
||||
if not self.connection or self.connected < 2:
|
||||
|
@ -1869,6 +1879,94 @@ ConnectionJingle, ConnectionIBBytestream):
|
|||
sess.terminate_e2e()
|
||||
self.delete_session(jid, sess.thread_id)
|
||||
|
||||
def _nec_subscribe_presence_received(self, obj):
|
||||
account = obj.conn.name
|
||||
if account != self.name:
|
||||
return
|
||||
if gajim.jid_is_transport(obj.fjid) and obj.fjid in \
|
||||
self.agent_registrations:
|
||||
self.agent_registrations[obj.fjid]['sub_received'] = True
|
||||
if not self.agent_registrations[obj.fjid]['roster_push']:
|
||||
# We'll reply after roster push result
|
||||
return True
|
||||
if gajim.config.get_per('accounts', self.name, 'autoauth') or \
|
||||
gajim.jid_is_transport(obj.fjid) or obj.jid in self.jids_for_auto_auth \
|
||||
or obj.transport_auto_auth:
|
||||
if self.connection:
|
||||
p = xmpp.Presence(obj.fjid, 'subscribed')
|
||||
p = self.add_sha(p)
|
||||
self.connection.send(p)
|
||||
if gajim.jid_is_transport(obj.fjid) or obj.transport_auto_auth:
|
||||
#TODO!?!?
|
||||
#self.show = 'offline'
|
||||
#self.status = 'offline'
|
||||
#emit NOTIFY
|
||||
pass
|
||||
if obj.transport_auto_auth:
|
||||
self.automatically_added.append(obj.jid)
|
||||
self.request_subscription(obj.jid, name=obj.user_nick)
|
||||
return True
|
||||
if not obj.status:
|
||||
obj.status = _('I would like to add you to my roster.')
|
||||
|
||||
def _nec_subscribed_presence_received(self, obj):
|
||||
account = obj.conn.name
|
||||
if account != self.name:
|
||||
return
|
||||
# BE CAREFUL: no con.updateRosterItem() in a callback
|
||||
if obj.jid in self.automatically_added:
|
||||
self.automatically_added.remove(obj.jid)
|
||||
return True
|
||||
# detect a subscription loop
|
||||
if obj.jid not in self.subscribed_events:
|
||||
self.subscribed_events[obj.jid] = []
|
||||
self.subscribed_events[obj.jid].append(time_time())
|
||||
block = False
|
||||
if len(self.subscribed_events[obj.jid]) > 5:
|
||||
if time_time() - self.subscribed_events[obj.jid][0] < 5:
|
||||
block = True
|
||||
self.subscribed_events[obj.jid] = \
|
||||
self.subscribed_events[obj.jid][1:]
|
||||
if block:
|
||||
gajim.config.set_per('account', self.name, 'dont_ack_subscription',
|
||||
True)
|
||||
return True
|
||||
|
||||
def _nec_subscribed_presence_received_end(self, obj):
|
||||
account = obj.conn.name
|
||||
if account != self.name:
|
||||
return
|
||||
if not gajim.config.get_per('accounts', account,
|
||||
'dont_ack_subscription'):
|
||||
self.ack_subscribed(obj.jid)
|
||||
|
||||
def _nec_unsubscribed_presence_received(self, obj):
|
||||
account = obj.conn.name
|
||||
if account != self.name:
|
||||
return
|
||||
# detect a unsubscription loop
|
||||
if obj.jid not in self.subscribed_events:
|
||||
self.subscribed_events[obj.jid] = []
|
||||
self.subscribed_events[obj.jid].append(time_time())
|
||||
block = False
|
||||
if len(self.subscribed_events[obj.jid]) > 5:
|
||||
if time_time() - self.subscribed_events[obj.jid][0] < 5:
|
||||
block = True
|
||||
self.subscribed_events[obj.jid] = \
|
||||
self.subscribed_events[obj.jid][1:]
|
||||
if block:
|
||||
gajim.config.set_per('account', self.name, 'dont_ack_subscription',
|
||||
True)
|
||||
return True
|
||||
|
||||
def _nec_unsubscribed_presence_received_end(self, obj):
|
||||
account = obj.conn.name
|
||||
if account != self.name:
|
||||
return
|
||||
if not gajim.config.get_per('accounts', account,
|
||||
'dont_ack_subscription'):
|
||||
self.ack_unsubscribed(obj.jid)
|
||||
|
||||
def _StanzaArrivedCB(self, con, obj):
|
||||
self.last_io = gajim.idlequeue.current_time()
|
||||
|
||||
|
|
|
@ -624,8 +624,8 @@ class PresenceReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
except Exception:
|
||||
if self.iq_obj.getTag('error') and self.iq_obj.getTag('error').\
|
||||
getTag('jid-malformed'):
|
||||
# wrong jid, we probably tried to change our nick in a room to a non
|
||||
# valid one
|
||||
# wrong jid, we probably tried to change our nick in a room to a
|
||||
# non valid one
|
||||
who = str(self.iq_obj.getFrom())
|
||||
jid_stripped, resource = gajim.get_room_and_nick_from_fjid(who)
|
||||
self.conn.dispatch('GC_MSG', (jid_stripped,
|
||||
|
@ -641,7 +641,7 @@ class PresenceReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
# XEP-0172 User Nickname
|
||||
self.user_nick = self.iq_obj.getTagData('nick') or ''
|
||||
self.contact_nickname = None
|
||||
transport_auto_auth = False
|
||||
self.transport_auto_auth = False
|
||||
# XEP-0203
|
||||
delay_tag = self.iq_obj.getTag('delay', namespace=xmpp.NS_DELAY2)
|
||||
if delay_tag:
|
||||
|
@ -668,12 +668,12 @@ class PresenceReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
agent = gajim.get_server_from_jid(self.jid)
|
||||
if self.conn.connection.getRoster().getItem(agent):
|
||||
# to be sure it's a transport contact
|
||||
transport_auto_auth = True
|
||||
self.transport_auto_auth = True
|
||||
|
||||
if not self.is_gc and self.id_ and self.id_.startswith('gajim_muc_') \
|
||||
and self.ptype == 'error':
|
||||
# Error presences may not include sent stanza, so we don't detect it's
|
||||
# a muc preence. So detect it by ID
|
||||
# Error presences may not include sent stanza, so we don't detect
|
||||
# it's a muc presence. So detect it by ID
|
||||
h = hmac.new(self.conn.secret_hmac, self.jid).hexdigest()[:6]
|
||||
if self.id_.split('_')[-1] == h:
|
||||
self.is_gc = True
|
||||
|
@ -706,74 +706,17 @@ class PresenceReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
|||
return
|
||||
|
||||
if self.ptype == 'subscribe':
|
||||
log.debug('subscribe request from %s' % self.fjid)
|
||||
if self.fjid.find('@') <= 0 and self.fjid in \
|
||||
self.conn.agent_registrations:
|
||||
self.conn.agent_registrations[self.fjid]['sub_received'] = True
|
||||
if not self.conn.agent_registrations[self.fjid]['roster_push']:
|
||||
# We'll reply after roster push result
|
||||
return
|
||||
if gajim.config.get_per('accounts', self.conn.name, 'autoauth') or \
|
||||
self.fjid.find('@') <= 0 or self.jid in \
|
||||
self.conn.jids_for_auto_auth or transport_auto_auth:
|
||||
if self.conn.connection:
|
||||
p = xmpp.Presence(self.fjid, 'subscribed')
|
||||
p = self.conn.add_sha(p)
|
||||
self.conn.connection.send(p)
|
||||
if self.fjid.find('@') <= 0 or transport_auto_auth:
|
||||
self.show = 'offline'
|
||||
self.status = 'offline'
|
||||
return True
|
||||
|
||||
if transport_auto_auth:
|
||||
self.conn.automatically_added.append(self.jid)
|
||||
self.conn.request_subscription(self.jid,
|
||||
name=self.user_nick)
|
||||
else:
|
||||
if not self.status:
|
||||
self.status = _('I would like to add you to my roster.')
|
||||
self.conn.dispatch('SUBSCRIBE', (self.jid, self.status,
|
||||
self.user_nick))
|
||||
gajim.nec.push_incoming_event(SubscribePresenceReceivedEvent(None,
|
||||
conn=self.conn, iq_obj=self.iq_obj, presence_obj=self))
|
||||
elif self.ptype == 'subscribed':
|
||||
if self.jid in self.conn.automatically_added:
|
||||
self.conn.automatically_added.remove(self.jid)
|
||||
else:
|
||||
# detect a subscription loop
|
||||
if self.jid not in self.conn.subscribed_events:
|
||||
self.conn.subscribed_events[self.jid] = []
|
||||
self.conn.subscribed_events[self.jid].append(time_time())
|
||||
block = False
|
||||
if len(self.conn.subscribed_events[self.jid]) > 5:
|
||||
if time_time() - self.subscribed_events[self.jid][0] < 5:
|
||||
block = True
|
||||
self.conn.subscribed_events[self.jid] = \
|
||||
self.conn.subscribed_events[self.jid][1:]
|
||||
if block:
|
||||
gajim.config.set_per('account', self.conn.name,
|
||||
'dont_ack_subscription', True)
|
||||
else:
|
||||
self.conn.dispatch('SUBSCRIBED', (self.jid, self.resource))
|
||||
# BE CAREFUL: no con.updateRosterItem() in a callback
|
||||
log.debug(_('we are now subscribed to %s') % self.jid)
|
||||
gajim.nec.push_incoming_event(SubscribedPresenceReceivedEvent(None,
|
||||
conn=self.conn, iq_obj=self.iq_obj, presence_obj=self))
|
||||
elif self.ptype == 'unsubscribe':
|
||||
log.debug(_('unsubscribe request from %s') % self.jid)
|
||||
elif self.ptype == 'unsubscribed':
|
||||
log.debug(_('we are now unsubscribed from %s') % self.jid)
|
||||
# detect a unsubscription loop
|
||||
if self.jid not in self.conn.subscribed_events:
|
||||
self.conn.subscribed_events[self.jid] = []
|
||||
self.conn.subscribed_events[self.jid].append(time_time())
|
||||
block = False
|
||||
if len(self.conn.subscribed_events[self.jid]) > 5:
|
||||
if time_time() - self.conn.subscribed_events[self.jid][0] < 5:
|
||||
block = True
|
||||
self.conn.subscribed_events[self.jid] = \
|
||||
self.conn.subscribed_events[self.jid][1:]
|
||||
if block:
|
||||
gajim.config.set_per('account', self.conn.name,
|
||||
'dont_ack_subscription', True)
|
||||
else:
|
||||
self.conn.dispatch('UNSUBSCRIBED', self.jid)
|
||||
gajim.nec.push_incoming_event(UnsubscribedPresenceReceivedEvent(
|
||||
None, conn=self.conn, iq_obj=self.iq_obj, presence_obj=self))
|
||||
elif self.ptype == 'error':
|
||||
errmsg = self.iq_obj.getError()
|
||||
errcode = self.iq_obj.getErrorCode()
|
||||
|
@ -934,3 +877,32 @@ class GcPresenceReceivedEvent(nec.NetworkIncomingEvent):
|
|||
self.actor = self.iq_obj.getActor()
|
||||
self.new_nick = self.iq_obj.getNewNick()
|
||||
return True
|
||||
|
||||
class SubscribePresenceReceivedEvent(nec.NetworkIncomingEvent):
|
||||
name = 'subscribe-presence-received'
|
||||
base_network_events = []
|
||||
|
||||
def generate(self):
|
||||
self.jid = self.presence_obj.jid
|
||||
self.fjid = self.presence_obj.fjid
|
||||
self.status = self.presence_obj.status
|
||||
self.transport_auto_auth = self.presence_obj.transport_auto_auth
|
||||
self.user_nick = self.presence_obj.user_nick
|
||||
return True
|
||||
|
||||
class SubscribedPresenceReceivedEvent(nec.NetworkIncomingEvent):
|
||||
name = 'subscribed-presence-received'
|
||||
base_network_events = []
|
||||
|
||||
def generate(self):
|
||||
self.jid = self.presence_obj.jid
|
||||
self.resource = self.presence_obj.resource
|
||||
return True
|
||||
|
||||
class UnsubscribedPresenceReceivedEvent(nec.NetworkIncomingEvent):
|
||||
name = 'unsubscribed-presence-received'
|
||||
base_network_events = []
|
||||
|
||||
def generate(self):
|
||||
self.jid = self.presence_obj.jid
|
||||
return True
|
||||
|
|
|
@ -520,56 +520,48 @@ class Interface:
|
|||
array[4].roster_message(array[0], msg, array[3], account,
|
||||
msg_type='error')
|
||||
|
||||
def handle_event_subscribe(self, account, array):
|
||||
def handle_event_subscribe_presence(self, obj):
|
||||
#('SUBSCRIBE', account, (jid, text, user_nick)) user_nick is JEP-0172
|
||||
if self.remote_ctrl:
|
||||
self.remote_ctrl.raise_signal('Subscribe', (account, array))
|
||||
|
||||
jid = array[0]
|
||||
text = array[1]
|
||||
nick = array[2]
|
||||
account = obj.conn.name
|
||||
if helpers.allow_popup_window(account) or not self.systray_enabled:
|
||||
dialogs.SubscriptionRequestWindow(jid, text, account, nick)
|
||||
dialogs.SubscriptionRequestWindow(obj.jid, obj.status, account,
|
||||
obj.user_nick)
|
||||
return
|
||||
|
||||
self.add_event(account, jid, 'subscription_request', (text, nick))
|
||||
self.add_event(account, obj.jid, 'subscription_request', (obj.status,
|
||||
obj.user_nick))
|
||||
|
||||
if helpers.allow_showing_notification(account):
|
||||
path = gtkgui_helpers.get_icon_path('gajim-subscription_request',
|
||||
48)
|
||||
event_type = _('Subscription request')
|
||||
notify.popup(event_type, jid, account, 'subscription_request', path,
|
||||
event_type, jid)
|
||||
notify.popup(event_type, obj.jid, account, 'subscription_request',
|
||||
path, event_type, obj.jid)
|
||||
|
||||
def handle_event_subscribed(self, account, array):
|
||||
def handle_event_subscribed_presence(self, obj):
|
||||
#('SUBSCRIBED', account, (jid, resource))
|
||||
jid = array[0]
|
||||
if jid in gajim.contacts.get_jid_list(account):
|
||||
c = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||
c.resource = array[1]
|
||||
account = obj.conn.name
|
||||
if obj.jid in gajim.contacts.get_jid_list(account):
|
||||
c = gajim.contacts.get_first_contact_from_jid(account, obj.jid)
|
||||
c.resource = obj.resource
|
||||
self.roster.remove_contact_from_groups(c.jid, account,
|
||||
[_('Not in Roster'), _('Observers')], update=False)
|
||||
else:
|
||||
keyID = ''
|
||||
attached_keys = gajim.config.get_per('accounts', account,
|
||||
'attached_gpg_keys').split()
|
||||
if jid in attached_keys:
|
||||
keyID = attached_keys[attached_keys.index(jid) + 1]
|
||||
name = jid.split('@', 1)[0]
|
||||
if obj.jid in attached_keys:
|
||||
keyID = attached_keys[attached_keys.index(obj.jid) + 1]
|
||||
name = obj.jid.split('@', 1)[0]
|
||||
name = name.split('%', 1)[0]
|
||||
contact1 = gajim.contacts.create_contact(jid=jid, account=account,
|
||||
name=name, groups=[], show='online', status='online', ask='to',
|
||||
resource=array[1], keyID=keyID)
|
||||
contact1 = gajim.contacts.create_contact(jid=obj.jid,
|
||||
account=account, name=name, groups=[], show='online',
|
||||
status='online', ask='to', resource=obj.resource, keyID=keyID)
|
||||
gajim.contacts.add_contact(account, contact1)
|
||||
self.roster.add_contact(jid, account)
|
||||
self.roster.add_contact(obj.jid, account)
|
||||
dialogs.InformationDialog(_('Authorization accepted'),
|
||||
_('The contact "%s" has authorized you to see his or her status.')
|
||||
% jid)
|
||||
if not gajim.config.get_per('accounts', account,
|
||||
'dont_ack_subscription'):
|
||||
gajim.connections[account].ack_subscribed(jid)
|
||||
if self.remote_ctrl:
|
||||
self.remote_ctrl.raise_signal('Subscribed', (account, array))
|
||||
% obj.jid)
|
||||
|
||||
def show_unsubscribed_dialog(self, account, contact):
|
||||
def on_yes(is_checked, list_):
|
||||
|
@ -583,13 +575,10 @@ class Interface:
|
|||
# FIXME: Per RFC 3921, we can "deny" ack as well, but the GUI does
|
||||
# not show deny
|
||||
|
||||
def handle_event_unsubscribed(self, account, jid):
|
||||
def handle_event_unsubscribed_presence(self, obj):
|
||||
#('UNSUBSCRIBED', account, jid)
|
||||
gajim.connections[account].ack_unsubscribed(jid)
|
||||
if self.remote_ctrl:
|
||||
self.remote_ctrl.raise_signal('Unsubscribed', (account, jid))
|
||||
|
||||
contact = gajim.contacts.get_first_contact_from_jid(account, jid)
|
||||
account = obj.conn.name
|
||||
contact = gajim.contacts.get_first_contact_from_jid(account, obj.jid)
|
||||
if not contact:
|
||||
return
|
||||
|
||||
|
@ -597,13 +586,13 @@ class Interface:
|
|||
self.show_unsubscribed_dialog(account, contact)
|
||||
return
|
||||
|
||||
self.add_event(account, jid, 'unsubscribed', contact)
|
||||
self.add_event(account, obj.jid, 'unsubscribed', contact)
|
||||
|
||||
if helpers.allow_showing_notification(account):
|
||||
path = gtkgui_helpers.get_icon_path('gajim-unsubscribed', 48)
|
||||
event_type = _('Unsubscribed')
|
||||
notify.popup(event_type, jid, account, 'unsubscribed', path,
|
||||
event_type, jid)
|
||||
notify.popup(event_type, obj.jid, account, 'unsubscribed', path,
|
||||
event_type, obj.jid)
|
||||
|
||||
def handle_event_agent_removed(self, account, agent):
|
||||
# remove transport's contacts from treeview
|
||||
|
@ -1911,9 +1900,6 @@ class Interface:
|
|||
'MSGERROR': [self.handle_event_msgerror],
|
||||
'MSGSENT': [self.handle_event_msgsent],
|
||||
'MSGNOTSENT': [self.handle_event_msgnotsent],
|
||||
'SUBSCRIBED': [self.handle_event_subscribed],
|
||||
'UNSUBSCRIBED': [self.handle_event_unsubscribed],
|
||||
'SUBSCRIBE': [self.handle_event_subscribe],
|
||||
'AGENT_REMOVED': [self.handle_event_agent_removed],
|
||||
'REGISTER_AGENT_INFO': [self.handle_event_register_agent_info],
|
||||
'AGENT_INFO_ITEMS': [self.handle_event_agent_info_items],
|
||||
|
@ -1985,6 +1971,12 @@ class Interface:
|
|||
'roster-item-exchange-received': \
|
||||
[self.handle_event_roster_item_exchange],
|
||||
'stream-conflict-received': [self.handle_event_resource_conflict],
|
||||
'subscribe-presence-received': [
|
||||
self.handle_event_subscribe_presence],
|
||||
'subscribed-presence-received': [
|
||||
self.handle_event_subscribed_presence],
|
||||
'unsubscribed-presence-received': [
|
||||
self.handle_event_unsubscribed_presence],
|
||||
}
|
||||
|
||||
def register_core_handlers(self):
|
||||
|
|
|
@ -117,6 +117,12 @@ class Remote:
|
|||
self.on_roster_info)
|
||||
gajim.ged.register_event_handler('presence-received', ged.POSTGUI,
|
||||
self.on_presence_received)
|
||||
gajim.ged.register_event_handler('subscribe-presence-received',
|
||||
ged.POSTGUI, self.on_subscribe_presence_received)
|
||||
gajim.ged.register_event_handler('subscribed-presence-received',
|
||||
ged.POSTGUI, self.on_subscribed_presence_received)
|
||||
gajim.ged.register_event_handler('unsubscribed-presence-received',
|
||||
ged.POSTGUI, self.on_unsubscribed_presence_received)
|
||||
|
||||
def on_last_status_time(self, obj):
|
||||
self.raise_signal('LastStatusTime', (obj.conn.name, [
|
||||
|
@ -151,6 +157,17 @@ class Remote:
|
|||
obj.status, obj.resource, obj.prio, obj.keyID, obj.timestamp,
|
||||
obj.contact_nickname]))
|
||||
|
||||
def on_subscribe_presence_received(self, obj):
|
||||
self.raise_signal('Subscribe', (obj.conn.name, [obj.jid, obj.status,
|
||||
obj.user_nick]))
|
||||
|
||||
def on_subscribed_presence_received(self, obj):
|
||||
self.raise_signal('Subscribed', (obj.conn.name, [obj.jid,
|
||||
obj.resource]))
|
||||
|
||||
def on_unsubscribed_presence_received(self, obj):
|
||||
self.raise_signal('Unsubscribed', (obj.conn.name, obj.jid))
|
||||
|
||||
def raise_signal(self, signal, arg):
|
||||
if self.signal_object:
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue