Refactor Privacy and Blocking into own modules

This commit is contained in:
Philipp Hörist 2018-07-08 10:29:24 +02:00
parent 3cfd82b0c2
commit bd79fe629f
10 changed files with 705 additions and 528 deletions

View File

@ -103,11 +103,6 @@ class CommonConnection:
self.priority = app.get_priority(name, 'offline')
self.time_to_reconnect = None
self.blocked_list = []
self.blocked_contacts = []
self.blocked_groups = []
self.blocked_all = False
self.seclabel_supported = False
self.seclabel_catalogues = {}
@ -631,8 +626,6 @@ class Connection(CommonConnection, ConnectionHandlers):
# Register all modules
modules.register(self)
app.ged.register_event_handler('privacy-list-received', ged.CORE,
self._nec_privacy_list_received)
app.ged.register_event_handler('agent-info-error-received', ged.CORE,
self._nec_agent_info_error_received)
app.ged.register_event_handler('agent-info-received', ged.CORE,
@ -651,8 +644,6 @@ class Connection(CommonConnection, ConnectionHandlers):
ConnectionHandlers.cleanup(self)
modules.unregister(self)
app.ged.remove_event_handler('privacy-list-received', ged.CORE,
self._nec_privacy_list_received)
app.ged.remove_event_handler('agent-info-error-received', ged.CORE,
self._nec_agent_info_error_received)
app.ged.remove_event_handler('agent-info-received', ged.CORE,
@ -702,7 +693,7 @@ class Connection(CommonConnection, ConnectionHandlers):
# Do not try to reco while we are already trying
self.time_to_reconnect = None
if self.connected < 2: # connection failed
log.debug('reconnect')
log.info('Reconnect')
self.connected = 1
app.nec.push_incoming_event(OurShowEvent(None, conn=self,
show='connecting'))
@ -710,12 +701,14 @@ class Connection(CommonConnection, ConnectionHandlers):
self.on_connect_auth = self._discover_server_at_connection
self.connect_and_init(self.old_show, self.status, self.USE_GPG)
else:
log.info('Reconnect successfull')
# reconnect succeeded
self.time_to_reconnect = None
self.retrycount = 0
# We are doing disconnect at so many places, better use one function in all
def disconnect(self, on_purpose=False):
log.info('Disconnect: on_purpose: %s', on_purpose)
app.interface.music_track_changed(None, None, self.name)
self.get_module('PEP').reset_stored_publish()
self.on_purpose = on_purpose
@ -798,7 +791,7 @@ class Connection(CommonConnection, ConnectionHandlers):
# END disconnectedReconnCB
def _connection_lost(self):
log.debug('_connection_lost')
log.info('_connection_lost')
self.disconnect(on_purpose = False)
if self.removing_account:
return
@ -882,38 +875,6 @@ class Connection(CommonConnection, ConnectionHandlers):
app.nec.push_incoming_event(RegisterAgentInfoReceivedEvent(
None, conn=self, agent=data[0], config=conf,
is_form=is_form))
elif realm == nbxmpp.NS_PRIVACY:
if event == nbxmpp.features_nb.PRIVACY_LISTS_RECEIVED:
# data is (list)
app.nec.push_incoming_event(PrivacyListsReceivedEvent(None,
conn=self, lists_list=data))
elif event == nbxmpp.features_nb.PRIVACY_LIST_RECEIVED:
# data is (resp)
if not data:
return
rules = []
name = data.getTag('query').getTag('list').getAttr('name')
for child in data.getTag('query').getTag('list').getChildren():
dict_item = child.getAttrs()
childs = []
if 'type' in dict_item:
for scnd_child in child.getChildren():
childs += [scnd_child.getName()]
rules.append({'action':dict_item['action'],
'type':dict_item['type'], 'order':dict_item['order'],
'value':dict_item['value'], 'child':childs})
else:
for scnd_child in child.getChildren():
childs.append(scnd_child.getName())
rules.append({'action':dict_item['action'],
'order':dict_item['order'], 'child':childs})
app.nec.push_incoming_event(PrivacyListReceivedEvent(None,
conn=self, list_name=name, rules=rules))
elif event == nbxmpp.features_nb.PRIVACY_LISTS_ACTIVE_DEFAULT:
# data is (dict)
app.nec.push_incoming_event(PrivacyListActiveDefaultEvent(
None, conn=self, active_list=data['active'],
default_list=data['default']))
def _select_next_host(self, hosts):
"""
@ -952,6 +913,7 @@ class Connection(CommonConnection, ConnectionHandlers):
if self.connection:
return self.connection, ''
log.info('Connect')
if self.sm.resuming and self.sm.location:
# If resuming and server gave a location, connect from there
hostname = self.sm.location
@ -1086,7 +1048,6 @@ class Connection(CommonConnection, ConnectionHandlers):
app.config.set_per('proxies', p, 'type', 'bosh')
app.config.set_per('proxies', p, 'bosh_uri', url)
def _connect_to_next_host(self, retry=False):
log.debug('Connection to next host')
if not self._hosts:
@ -1233,6 +1194,7 @@ class Connection(CommonConnection, ConnectionHandlers):
if not self.connected: # We went offline during connecting process
# FIXME - not possible, maybe it was when we used threads
return
log.info('Connect successfull')
_con_type = con_type
if _con_type != self._current_type:
log.info('Connecting to next host beacuse desired type is %s and returned is %s'
@ -1269,6 +1231,7 @@ class Connection(CommonConnection, ConnectionHandlers):
msg=_('Connection with account %s has been lost. Retry '
'connecting.') % self.name))
return
log.info('Connection accepted')
self._hosts = []
self.connection_auto_accepted = False
self.connected_hostname = self._current_host['host']
@ -1389,6 +1352,7 @@ class Connection(CommonConnection, ConnectionHandlers):
'Retry connecting.') % self.name))
return
log.info('SSL Cert accepted')
name = None
if not app.config.get_per('accounts', self.name, 'anonymous_auth'):
name = app.config.get_per('accounts', self.name, 'name')
@ -1420,6 +1384,7 @@ class Connection(CommonConnection, ConnectionHandlers):
ConnectionHandlers._register_handlers(self, con, con_type)
def __on_auth(self, con, auth):
log.info('auth')
if not con:
self.disconnect(on_purpose=True)
app.nec.push_incoming_event(ConnectionLostEvent(None, conn=self,
@ -1472,207 +1437,11 @@ class Connection(CommonConnection, ConnectionHandlers):
def add_lang(self, stanza):
stanza.setAttr('xml:lang', i18n.LANG)
def get_privacy_lists(self):
if not app.account_is_connected(self.name):
return
nbxmpp.features_nb.getPrivacyLists(self.connection)
def send_keepalive(self):
# nothing received for the last foo seconds
if self.connection:
self.connection.send(' ')
def get_active_default_lists(self):
if not app.account_is_connected(self.name):
return
nbxmpp.features_nb.getActiveAndDefaultPrivacyLists(self.connection)
def del_privacy_list(self, privacy_list):
if not app.account_is_connected(self.name):
return
def _on_del_privacy_list_result(result):
if result:
app.nec.push_incoming_event(PrivacyListRemovedEvent(None,
conn=self, list_name=privacy_list))
else:
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='privacy-list-error', args=privacy_list))
nbxmpp.features_nb.delPrivacyList(self.connection, privacy_list,
_on_del_privacy_list_result)
def get_privacy_list(self, title):
if not app.account_is_connected(self.name):
return
nbxmpp.features_nb.getPrivacyList(self.connection, title)
def set_privacy_list(self, listname, tags):
if not app.account_is_connected(self.name):
return
nbxmpp.features_nb.setPrivacyList(self.connection, listname, tags)
def set_active_list(self, listname):
if not app.account_is_connected(self.name):
return
nbxmpp.features_nb.setActivePrivacyList(self.connection, listname,
'active')
def set_default_list(self, listname):
if not app.account_is_connected(self.name):
return
nbxmpp.features_nb.setDefaultPrivacyList(self.connection, listname)
def build_privacy_rule(self, name, action, order=1):
"""
Build a Privacy rule stanza for invisibility
"""
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVACY, xmlns='')
l = iq.setQuery().setTag('list', {'name': name})
i = l.setTag('item', {'action': action, 'order': str(order)})
i.setTag('presence-out')
return iq
def build_invisible_rule(self):
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVACY, xmlns='')
l = iq.setQuery().setTag('list', {'name': 'invisible'})
if self.name in app.interface.status_sent_to_groups and \
len(app.interface.status_sent_to_groups[self.name]) > 0:
for group in app.interface.status_sent_to_groups[self.name]:
i = l.setTag('item', {'type': 'group', 'value': group,
'action': 'allow', 'order': '1'})
i.setTag('presence-out')
if self.name in app.interface.status_sent_to_users and \
len(app.interface.status_sent_to_users[self.name]) > 0:
for jid in app.interface.status_sent_to_users[self.name]:
i = l.setTag('item', {'type': 'jid', 'value': jid,
'action': 'allow', 'order': '2'})
i.setTag('presence-out')
i = l.setTag('item', {'action': 'deny', 'order': '3'})
i.setTag('presence-out')
return iq
def set_invisible_rule(self):
if not app.account_is_connected(self.name):
return
iq = self.build_invisible_rule()
self.connection.send(iq)
def get_max_blocked_list_order(self):
max_order = 0
for rule in self.blocked_list:
order = int(rule['order'])
if order > max_order:
max_order = order
return max_order
def block_contacts(self, contact_list, message):
if self.privacy_default_list is None:
self.privacy_default_list = 'block'
if not self.privacy_rules_supported:
if self.blocking_supported: #XEP-0191
iq = nbxmpp.Iq('set', xmlns='')
query = iq.setQuery(name='block')
query.setNamespace(nbxmpp.NS_BLOCKING)
for contact in contact_list:
query.addChild(name='item', attrs={'jid': contact.jid})
self.connection.send(iq)
return
for contact in contact_list:
contact.show = 'offline'
self.send_custom_status('offline', message, contact.jid)
max_order = self.get_max_blocked_list_order()
new_rule = {'order': str(max_order + 1),
'type': 'jid',
'action': 'deny',
'value': contact.jid}
self.blocked_list.append(new_rule)
self.blocked_contacts.append(contact.jid)
self.set_privacy_list(self.privacy_default_list, self.blocked_list)
if len(self.blocked_list) == 1:
self.set_default_list(self.privacy_default_list)
def unblock_contacts(self, contact_list):
if not self.privacy_rules_supported:
if self.blocking_supported: #XEP-0191
iq = nbxmpp.Iq('set', xmlns='')
query = iq.setQuery(name='unblock')
query.setNamespace(nbxmpp.NS_BLOCKING)
for contact in contact_list:
query.addChild(name='item', attrs={'jid': contact.jid})
self.connection.send(iq)
return
self.new_blocked_list = []
self.to_unblock = []
for contact in contact_list:
self.to_unblock.append(contact.jid)
if contact.jid in self.blocked_contacts:
self.blocked_contacts.remove(contact.jid)
for rule in self.blocked_list:
if rule['action'] != 'deny' or rule['type'] != 'jid' \
or rule['value'] not in self.to_unblock:
self.new_blocked_list.append(rule)
if len(self.new_blocked_list) == 0:
self.blocked_list = []
self.blocked_contacts = []
self.blocked_groups = []
self.set_default_list('')
self.del_privacy_list(self.privacy_default_list)
else:
self.set_privacy_list(self.privacy_default_list, self.new_blocked_list)
if not app.interface.roster.regroup:
show = app.SHOW_LIST[self.connected]
else: # accounts merged
show = helpers.get_global_show()
if show == 'invisible':
return
for contact in contact_list:
self.send_custom_status(show, self.status, contact.jid)
# Send a presence Probe to get the current Status
probe = nbxmpp.Presence(contact.jid, 'probe', frm=self.get_own_jid())
self.connection.send(probe)
def block_group(self, group, contact_list, message):
if not self.privacy_rules_supported:
return
self.blocked_groups.append(group)
for contact in contact_list:
self.send_custom_status('offline', message, contact.jid)
max_order = self.get_max_blocked_list_order()
new_rule = {'order': str(max_order + 1),
'type': 'group',
'action': 'deny',
'value': group}
self.blocked_list.append(new_rule)
self.set_privacy_list(self.privacy_default_list, self.blocked_list)
if len(self.blocked_list) == 1:
self.set_default_list(self.privacy_default_list)
def unblock_group(self, group, contact_list):
if not self.privacy_rules_supported:
return
if group in self.blocked_groups:
self.blocked_groups.remove(group)
self.new_blocked_list = []
for rule in self.blocked_list:
if rule['action'] != 'deny' or rule['type'] != 'group' or \
rule['value'] != group:
self.new_blocked_list.append(rule)
if len(self.new_blocked_list) == 0:
self.blocked_list = []
self.blocked_contacts = []
self.blocked_groups = []
self.set_default_list('')
self.del_privacy_list(self.privacy_default_list)
else:
self.set_privacy_list(self.privacy_default_list, self.new_blocked_list)
if not app.interface.roster.regroup:
show = app.SHOW_LIST[self.connected]
else: # accounts merged
show = helpers.get_global_show()
if show == 'invisible':
return
for contact in contact_list:
self.send_custom_status(show, self.status, contact.jid)
def send_invisible_presence(self, msg, signed, initial = False):
if not app.account_is_connected(self.name):
return
@ -1694,15 +1463,17 @@ class Connection(CommonConnection, ConnectionHandlers):
self.connection.send(p)
# try to set the privacy rule
iq = self.build_invisible_rule()
self.connection.SendAndCallForResponse(iq, self._continue_invisible,
{'msg': msg, 'signed': signed, 'initial': initial})
iq = self.get_module('PrivacyLists').set_invisible_rule(
callback=self._continue_invisible,
msg=msg,
signed=signed,
initial=initial)
def _continue_invisible(self, con, iq_obj, msg, signed, initial):
if iq_obj.getType() == 'error': # server doesn't support privacy lists
return
# active the privacy rule
self.set_active_list('invisible')
self.get_module('PrivacyLists').set_active_list('invisible')
self.connected = app.SHOW_LIST.index('invisible')
self.status = msg
priority = app.get_priority(self.name, 'invisible')
@ -1777,42 +1548,35 @@ class Connection(CommonConnection, ConnectionHandlers):
if len(result_array) != 0:
self._stun_servers = self._hosts = [i for i in result_array]
def _request_privacy(self):
if not app.account_is_connected(self.name) or not self.connection:
return
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVACY, xmlns='')
id_ = self.connection.getAnID()
iq.setID(id_)
self.awaiting_answers[id_] = (PRIVACY_ARRIVED, )
self.connection.send(iq)
def _request_blocking(self):
if not app.account_is_connected(self.name) or not self.connection:
return
iq = nbxmpp.Iq('get', xmlns=None)
iq.setQuery('blocklist').setNamespace(nbxmpp.NS_BLOCKING)
self.connection.send(iq)
def _continue_connection_request_privacy(self):
if self.privacy_rules_supported:
if not self.privacy_rules_requested:
self.privacy_rules_requested = True
self._request_privacy()
self.get_module('PrivacyLists').get_privacy_lists(
self._received_privacy)
else:
if self.continue_connect_info and self.continue_connect_info[0]\
== 'invisible':
# Privacy lists not supported
log.info('Privacy Lists not supported')
self._received_privacy(False)
def _received_privacy(self, result):
if not result:
if (self.continue_connect_info and
self.continue_connect_info[0] == 'invisible'):
# Trying to login as invisible but privacy list not
# supported
self.disconnect(on_purpose=True)
app.nec.push_incoming_event(OurShowEvent(None, conn=self,
show='offline'))
app.nec.push_incoming_event(OurShowEvent(
None, conn=self, show='offline'))
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='invisibility-not-supported', args=self.name))
None, dialog_name='invisibility-not-supported',
args=self.name))
return
if self.blocking_supported:
self._request_blocking()
# Ask metacontacts before roster
self.get_metacontacts()
self.get_module('Blocking').get_blocking_list()
# Ask metacontacts before roster
self.get_metacontacts()
def _nec_agent_info_error_received(self, obj):
if obj.conn.name != self.name:
@ -1937,7 +1701,7 @@ class Connection(CommonConnection, ConnectionHandlers):
def _change_from_invisible(self):
if self.privacy_rules_supported:
self.set_active_list('')
self.get_module('PrivacyLists').set_active_list(None)
def _update_status(self, show, msg, idle_time=None):
xmpp_show = helpers.get_xmpp_show(show)
@ -2156,43 +1920,6 @@ class Connection(CommonConnection, ConnectionHandlers):
iq2.setAttr('to', to)
self.connection.send(iq)
def _nec_privacy_list_received(self, obj):
roster = app.interface.roster
if obj.conn.name != self.name:
return
if obj.list_name != self.privacy_default_list:
return
self.blocked_contacts = []
self.blocked_groups = []
self.blocked_list = []
self.blocked_all = False
for rule in obj.rules:
if rule['action'] == 'allow':
if not 'type' in rule:
self.blocked_all = False
elif rule['type'] == 'jid' and rule['value'] in \
self.blocked_contacts:
self.blocked_contacts.remove(rule['value'])
elif rule['type'] == 'group' and rule['value'] in \
self.blocked_groups:
self.blocked_groups.remove(rule['value'])
elif rule['action'] == 'deny':
if not 'type' in rule:
self.blocked_all = True
elif rule['type'] == 'jid' and rule['value'] not in \
self.blocked_contacts:
self.blocked_contacts.append(rule['value'])
elif rule['type'] == 'group' and rule['value'] not in \
self.blocked_groups:
self.blocked_groups.append(rule['value'])
self.blocked_list.append(rule)
if 'type' in rule:
if rule['type'] == 'jid':
roster.draw_contact(rule['value'], self.name)
if rule['type'] == 'group':
roster.draw_group(rule['value'], self.name)
def bookmarks_available(self):
if self.private_storage_supported:
return True

View File

@ -771,8 +771,6 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
self.continue_connect_info = None
self.privacy_default_list = None
app.nec.register_incoming_event(StreamConflictReceivedEvent)
app.nec.register_incoming_event(MessageReceivedEvent)
app.nec.register_incoming_event(ArchivingErrorReceivedEvent)
@ -798,8 +796,6 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
ged.POSTGUI, self._nec_unsubscribed_presence_received_end)
app.ged.register_event_handler('agent-removed', ged.CORE,
self._nec_agent_removed)
app.ged.register_event_handler('blocking', ged.CORE,
self._nec_blocking)
def cleanup(self):
ConnectionHandlersBase.cleanup(self)
@ -823,7 +819,6 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
ged.POSTGUI, self._nec_unsubscribed_presence_received_end)
app.ged.remove_event_handler('agent-removed', ged.CORE,
self._nec_agent_removed)
app.ged.remove_event_handler('blocking', ged.CORE, self._nec_blocking)
def add_sha(self, p, send_caps=True):
p = self.get_module('VCardAvatars').add_update_node(p)
@ -912,21 +907,6 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
conn=self))
GLib.timeout_add_seconds(10, self.discover_servers)
del self.awaiting_answers[id_]
elif self.awaiting_answers[id_][0] == PRIVACY_ARRIVED:
del self.awaiting_answers[id_]
if iq_obj.getType() != 'error':
for list_ in iq_obj.getQueryPayload():
if list_.getName() == 'default':
self.privacy_default_list = list_.getAttr('name')
self.get_privacy_list(self.privacy_default_list)
break
# Ask metacontacts before roster
self.get_metacontacts()
else:
# That should never happen, but as it's blocking in the
# connection process, we don't take the risk
self.privacy_rules_supported = False
self._continue_connection_request_privacy()
def _nec_iq_error_received(self, obj):
if obj.conn.name != self.name:
@ -1181,27 +1161,6 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
app.nec.push_incoming_event(MucAdminReceivedEvent(None, conn=self,
stanza=iq_obj))
def _PrivacySetCB(self, con, iq_obj):
"""
Privacy lists (XEP 016)
A list has been set.
"""
log.debug('PrivacySetCB')
if not self.connection or self.connected < 2:
return
result = iq_obj.buildReply('result')
q = result.getTag('query')
if q:
result.delChild(q)
self.connection.send(result)
for list_ in iq_obj.getQueryPayload():
if list_.getName() == 'list':
self.get_privacy_list(list_.getAttr('name'))
raise nbxmpp.NodeProcessed
def _getRoster(self):
log.debug('getRosterCB')
if not self.connection:
@ -1342,42 +1301,6 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
jid_from = helpers.get_full_jid_from_iq(iq_obj)
jingle_xtls.handle_new_cert(con, iq_obj, jid_from)
def _BlockingSetCB(self, con, iq_obj):
log.debug('_BlockingSetCB')
app.nec.push_incoming_event(
BlockingEvent(None, conn=self, stanza=iq_obj))
reply = nbxmpp.Iq(typ='result', attrs={'id': iq_obj.getID()},
to=iq_obj.getFrom(), frm=iq_obj.getTo(), xmlns=None)
self.connection.send(reply)
raise nbxmpp.NodeProcessed
def _BlockingResultCB(self, con, iq_obj):
log.debug('_BlockingResultCB')
app.nec.push_incoming_event(
BlockingEvent(None, conn=self, stanza=iq_obj))
raise nbxmpp.NodeProcessed
def _nec_blocking(self, obj):
if obj.conn.name != self.name:
return
if obj.unblock_all:
self.blocked_contacts = []
elif obj.blocklist:
self.blocked_contacts = obj.blocklist
else:
for jid in obj.blocked_jids:
if jid not in self.blocked_contacts:
self.blocked_contacts.append(jid)
contact_list = app.contacts.get_contacts(self.name, jid)
for contact in contact_list:
contact.show = 'offline'
for jid in obj.unblocked_jids:
if jid in self.blocked_contacts:
self.blocked_contacts.remove(jid)
# Send a presence Probe to get the current Status
probe = nbxmpp.Presence(jid, 'probe', frm=self.get_own_jid())
self.connection.send(probe)
def _StreamCB(self, con, obj):
log.debug('StreamCB')
app.nec.push_incoming_event(StreamReceivedEvent(None,
@ -1422,7 +1345,7 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
nbxmpp.NS_DISCO_INFO)
con.RegisterHandler('iq', self._DiscoverItemsGetCB, 'get',
nbxmpp.NS_DISCO_ITEMS)
con.RegisterHandler('iq', self._PrivacySetCB, 'set', nbxmpp.NS_PRIVACY)
con.RegisterHandler('iq', self._ArchiveCB, ns=nbxmpp.NS_MAM_1)
con.RegisterHandler('iq', self._ArchiveCB, ns=nbxmpp.NS_MAM_2)
con.RegisterHandler('iq', self._JingleCB, 'result')
@ -1437,10 +1360,6 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
nbxmpp.NS_PUBKEY_PUBKEY)
con.RegisterHandler('iq', self._PubkeyResultCB, 'result',
nbxmpp.NS_PUBKEY_PUBKEY)
con.RegisterHandler('iq', self._BlockingSetCB, 'set',
nbxmpp.NS_BLOCKING)
con.RegisterHandler('iq', self._BlockingResultCB, 'result',
nbxmpp.NS_BLOCKING)
for handler in modules.get_handlers(self):
con.RegisterHandler(*handler)

View File

@ -1759,22 +1759,6 @@ class UniqueRoomIdNotSupportedEvent(nec.NetworkIncomingEvent):
name = 'unique-room-id-not-supported'
base_network_events = []
class PrivacyListsReceivedEvent(nec.NetworkIncomingEvent):
name = 'privacy-lists-received'
base_network_events = []
class PrivacyListReceivedEvent(nec.NetworkIncomingEvent):
name = 'privacy-list-received'
base_network_events = []
class PrivacyListRemovedEvent(nec.NetworkIncomingEvent):
name = 'privacy-list-removed'
base_network_events = []
class PrivacyListActiveDefaultEvent(nec.NetworkIncomingEvent):
name = 'privacy-list-active-default'
base_network_events = []
class NonAnonymousServerErrorEvent(nec.NetworkIncomingEvent):
name = 'non-anonymous-server-error'
base_network_events = []
@ -2479,43 +2463,3 @@ class InformationEvent(nec.NetworkIncomingEvent):
else:
self.args = (self.args,)
return True
class BlockingEvent(nec.NetworkIncomingEvent):
name = 'blocking'
base_network_events = []
def init(self):
self.blocklist = []
self.blocked_jids = []
self.unblocked_jids = []
self.unblock_all = False
def generate(self):
block_list = self.stanza.getTag(
'blocklist', namespace=nbxmpp.NS_BLOCKING)
if block_list is not None:
for item in block_list.getTags('item'):
self.blocklist.append(item.getAttr('jid'))
app.log('blocking').info(
'Blocklist Received: %s', self.blocklist)
return True
block_tag = self.stanza.getTag('block', namespace=nbxmpp.NS_BLOCKING)
if block_tag is not None:
for item in block_tag.getTags('item'):
self.blocked_jids.append(item.getAttr('jid'))
app.log('blocking').info(
'Blocking Push - blocked JIDs: %s', self.blocked_jids)
unblock_tag = self.stanza.getTag(
'unblock', namespace=nbxmpp.NS_BLOCKING)
if unblock_tag is not None:
if not unblock_tag.getTags('item'):
self.unblock_all = True
app.log('blocking').info('Blocking Push - unblocked all')
return True
for item in unblock_tag.getTags('item'):
self.unblocked_jids.append(item.getAttr('jid'))
app.log('blocking').info(
'Blocking Push - unblocked JIDs: %s', self.unblocked_jids)
return True

View File

@ -1385,12 +1385,15 @@ def update_optional_features(account = None):
app.connections[a].status)
def jid_is_blocked(account, jid):
return ((jid in app.connections[account].blocked_contacts) or \
app.connections[account].blocked_all)
con = app.connections[account]
return (jid in con.get_module('Blocking').blocked or
jid in con.get_module('PrivacyLists').blocked_contacts or
con.get_module('PrivacyLists').blocked_all)
def group_is_blocked(account, group):
return ((group in app.connections[account].blocked_groups) or \
app.connections[account].blocked_all)
con = app.connections[account]
return (group in con.get_module('PrivacyLists').blocked_groups or
con.get_module('PrivacyLists').blocked_all)
def get_subscription_request_msg(account=None):
s = app.config.get_per('accounts', account, 'subscription_request_msg')

View File

@ -0,0 +1,156 @@
# 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-0191: Blocking Command
import logging
import nbxmpp
from gajim.common import app
from gajim.common.nec import NetworkIncomingEvent
log = logging.getLogger('gajim.c.m.blocking')
class Blocking:
def __init__(self, con):
self._con = con
self._account = con.name
self.blocked = []
self.handlers = [
('iq', self._blocking_push_received, 'set', nbxmpp.NS_BLOCKING)
]
def get_blocking_list(self):
iq = nbxmpp.Iq('get', nbxmpp.NS_BLOCKING)
iq.setQuery('blocklist')
log.info('Request list')
self._con.connection.SendAndCallForResponse(
iq, self._blocking_list_received)
def _blocking_list_received(self, stanza):
if not nbxmpp.isResultNode(stanza):
log.info('Error: %s', stanza.getError())
return
self.blocked = []
blocklist = stanza.getTag('blocklist', namespace=nbxmpp.NS_BLOCKING)
if blocklist is None:
log.error('No blocklist node')
return
for item in blocklist.getTags('item'):
self.blocked.append(item.getAttr('jid'))
log.info('Received list: %s', self.blocked)
app.nec.push_incoming_event(
BlockingEvent(None, conn=self._con, changed=self.blocked))
def _blocking_push_received(self, conn, stanza):
reply = stanza.buildReply('result')
childs = reply.getChildren()
for child in childs:
reply.delChild(child)
self._con.connection.send(reply)
changed_list = []
unblock = stanza.getTag('unblock', namespace=nbxmpp.NS_BLOCKING)
if unblock is not None:
items = unblock.getTags('item')
if not items:
# Unblock all
changed_list = list(self.blocked)
self.blocked = []
for jid in self.blocked:
self._presence_probe(jid)
log.info('Unblock all Push')
return
for item in items:
# Unblock some contacts
jid = item.getAttr('jid')
changed_list.append(jid)
if jid not in self.blocked:
continue
self.blocked.remove(jid)
self._presence_probe(jid)
log.info('Unblock Push: %s', jid)
block = stanza.getTag('block', namespace=nbxmpp.NS_BLOCKING)
if block is not None:
for item in block.getTags('item'):
jid = item.getAttr('jid')
if jid in self.blocked:
continue
changed_list.append(jid)
self.blocked.append(jid)
self._set_contact_offline(jid)
log.info('Block Push: %s', jid)
app.nec.push_incoming_event(
BlockingEvent(None, conn=self._con, changed=changed_list))
raise nbxmpp.NodeProcessed
def _set_contact_offline(self, jid):
contact_list = app.contacts.get_contacts(self._account, jid)
for contact in contact_list:
contact.show = 'offline'
def _presence_probe(self, jid):
log.info('Presence probe: %s', jid)
# Send a presence Probe to get the current Status
probe = nbxmpp.Presence(jid, 'probe', frm=self._con.get_own_jid())
self._con.connection.send(probe)
def block(self, contact_list):
if not self._con.blocking_supported:
return
iq = nbxmpp.Iq('set', nbxmpp.NS_BLOCKING)
query = iq.setQuery(name='block')
for contact in contact_list:
query.addChild(name='item', attrs={'jid': contact.jid})
log.info('Block: %s', contact.jid)
self._con.connection.SendAndCallForResponse(
iq, self._default_result_handler, {})
def unblock(self, contact_list):
if not self._con.blocking_supported:
return
iq = nbxmpp.Iq('set', nbxmpp.NS_BLOCKING)
query = iq.setQuery(name='unblock')
for contact in contact_list:
query.addChild(name='item', attrs={'jid': contact.jid})
log.info('Unblock: %s', contact.jid)
self._con.connection.SendAndCallForResponse(
iq, self._default_result_handler, {})
def _default_result_handler(self, conn, stanza):
if not nbxmpp.isResultNode(stanza):
log.warning('Operation failed: %s', stanza.getError())
class BlockingEvent(NetworkIncomingEvent):
name = 'blocking'
base_network_events = []
def get_instance(*args, **kwargs):
return Blocking(*args, **kwargs), 'Blocking'

View File

@ -0,0 +1,450 @@
# 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-0016: Privacy Lists
import logging
import nbxmpp
from gajim.common import app
from gajim.common import helpers
from gajim.common.nec import NetworkIncomingEvent
from gajim.common.connection_handlers_events import InformationEvent
log = logging.getLogger('gajim.c.m.privacylists')
class PrivacyLists:
def __init__(self, con):
self._con = con
self._account = con.name
self.default_list = None
self.active_list = None
self.blocked_contacts = []
self.blocked_groups = []
self.blocked_list = []
self.blocked_all = False
self.handlers = [
('iq', self._list_push_received, 'set', nbxmpp.NS_PRIVACY)
]
def _list_push_received(self, con, stanza):
result = stanza.buildReply('result')
result.delChild(result.getTag('query'))
self._con.connection.send(result)
for list_ in stanza.getQueryPayload():
if list_.getName() == 'list':
name = list_.getAttr('name')
log.info('Received Push: %s', name)
self.get_privacy_list(name)
raise nbxmpp.NodeProcessed
def get_privacy_lists(self, callback=None):
log.info('Request lists')
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVACY)
self._con.connection.SendAndCallForResponse(
iq, self._privacy_lists_received, {'callback': callback})
def _privacy_lists_received(self, conn, stanza, callback):
lists = []
new_default = None
result = nbxmpp.isResultNode(stanza)
if not result:
log.warning('List not available: %s', stanza.getError())
else:
for list_ in stanza.getQueryPayload():
name = list_.getAttr('name')
if list_.getName() == 'active':
self.active_list = name
elif list_.getName() == 'default':
new_default = name
else:
lists.append(name)
log.info('Received lists: %s', lists)
# Download default list if we dont have it
if self.default_list != new_default:
self.default_list = new_default
if new_default is not None:
log.info('Found new default list: %s', new_default)
self.get_privacy_list(new_default)
if callback:
callback(result)
else:
app.nec.push_incoming_event(
PrivacyListsReceivedEvent(None,
conn=self._con,
active_list=self.active_list,
default_list=self.default_list,
lists=lists))
def get_privacy_list(self, name):
log.info('Request list: %s', name)
list_ = nbxmpp.Node('list', {'name': name})
iq = nbxmpp.Iq('get', nbxmpp.NS_PRIVACY, payload=[list_])
self._con.connection.SendAndCallForResponse(
iq, self._privacy_list_received)
def _privacy_list_received(self, stanza):
if not nbxmpp.isResultNode(stanza):
log.warning('List not available: %s', stanza.getError())
return
rules = []
list_ = stanza.getQueryPayload()[0]
name = list_.getAttr('name')
for child in list_.getChildren():
item = child.getAttrs()
childs = []
for scnd_child in child.getChildren():
childs.append(scnd_child.getName())
item['child'] = childs
if len(item) not in (3, 5):
log.warning('Wrong count of attrs: %s', stanza)
continue
rules.append(item)
log.info('Received list: %s', name)
if name == self.default_list:
self._default_list_received(rules)
app.nec.push_incoming_event(PrivacyListReceivedEvent(
None, conn=self._con, list_name=name, rules=rules))
def del_privacy_list(self, name):
log.info('Remove list: %s', name)
def _del_privacy_list_result(stanza):
if not nbxmpp.isResultNode(stanza):
log.warning('List deletion failed: %s', stanza.getError())
app.nec.push_incoming_event(InformationEvent(
None, dialog_name='privacy-list-error', args=name))
else:
app.nec.push_incoming_event(PrivacyListRemovedEvent(
None, conn=self._con, list_name=name))
node = nbxmpp.Node('list', {'name': name})
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVACY, payload=[node])
self._con.connection.SendAndCallForResponse(
iq, _del_privacy_list_result)
def set_privacy_list(self, name, rules):
node = nbxmpp.Node('list', {'name': name})
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVACY, payload=[node])
for item in rules:
childs = item.get('child', [])
for child in childs:
node.setTag(child)
item.pop('child', None)
node.setTag('item', item)
log.info('Update list: %s %s', name, rules)
self._con.connection.SendAndCallForResponse(
iq, self._default_result_handler, {})
def _default_list_received(self, rules):
roster = app.interface.roster
for rule in rules:
if rule['action'] == 'allow':
if 'type' not in rule:
self.blocked_all = False
elif rule['type'] == 'jid':
if rule['value'] in self.blocked_contacts:
self.blocked_contacts.remove(rule['value'])
elif rule['type'] == 'group':
if rule['value'] in self.blocked_groups:
self.blocked_groups.remove(rule['value'])
elif rule['action'] == 'deny':
if 'type' not in rule:
self.blocked_all = True
elif rule['type'] == 'jid':
if rule['value'] not in self.blocked_contacts:
self.blocked_contacts.append(rule['value'])
elif rule['type'] == 'group':
if rule['value'] not in self.blocked_groups:
self.blocked_groups.append(rule['value'])
self.blocked_list.append(rule)
if 'type' in rule:
if rule['type'] == 'jid':
roster.draw_contact(rule['value'], self._account)
if rule['type'] == 'group':
roster.draw_group(rule['value'], self._account)
def set_active_list(self, name=None):
log.info('Set active list: %s', name)
attr = {}
if name:
attr['name'] = name
node = nbxmpp.Node('active', attr)
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVACY, payload=[node])
self._con.connection.SendAndCallForResponse(
iq, self._default_result_handler, {})
def set_default_list(self, name=None):
log.info('Set default list: %s', name)
attr = {}
if name:
attr['name'] = name
node = nbxmpp.Node('default', attr)
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVACY, payload=[node])
self._con.connection.SendAndCallForResponse(
iq, self._default_result_handler, {})
def _default_result_handler(self, conn, stanza):
if not nbxmpp.isResultNode(stanza):
log.warning('Operation failed: %s', stanza.getError())
def _build_invisible_rule(self):
node = nbxmpp.Node('list', {'name': 'invisible'})
iq = nbxmpp.Iq('set', nbxmpp.NS_PRIVACY, payload=[node])
if self._account in app.interface.status_sent_to_groups and \
len(app.interface.status_sent_to_groups[self._account]) > 0:
for group in app.interface.status_sent_to_groups[self._account]:
item = node.setTag('item', {'type': 'group',
'value': group,
'action': 'allow',
'order': '1'})
item.setTag('presence-out')
if self._account in app.interface.status_sent_to_users and \
len(app.interface.status_sent_to_users[self._account]) > 0:
for jid in app.interface.status_sent_to_users[self._account]:
item = node.setTag('item', {'type': 'jid',
'value': jid,
'action': 'allow',
'order': '2'})
item.setTag('presence-out')
item = node.setTag('item', {'action': 'deny', 'order': '3'})
item.setTag('presence-out')
return iq
def set_invisible_rule(self, callback=None, **kwargs):
log.info('Update invisible list')
iq = self._build_invisible_rule()
if callback is None:
callback = self._default_result_handler
self._con.connection.SendAndCallForResponse(
iq, callback, kwargs)
def _get_max_blocked_list_order(self):
max_order = 0
for rule in self.blocked_list:
order = int(rule['order'])
if order > max_order:
max_order = order
return max_order
def block_gc_contact(self, jid):
if jid in self.blocked_contacts:
return
log.info('Block GC contact: %s', jid)
if self.default_list is None:
self.default_list = 'block'
max_order = self._get_max_blocked_list_order()
new_rule = {'order': str(max_order + 1),
'type': 'jid',
'action': 'deny',
'value': jid,
'child': ['message', 'iq', 'presence-out']}
self.blocked_list.append(new_rule)
self.blocked_contacts.append(jid)
self.set_privacy_list(self.default_list, self.blocked_list)
if len(self.blocked_list) == 1:
self.set_default_list(self.default_list)
def block_contacts(self, contact_list, message):
if not self._con.privacy_rules_supported:
self._con.get_module('Blocking').block(contact_list)
return
if self.default_list is None:
self.default_list = 'block'
for contact in contact_list:
log.info('Block contacts: %s', contact.jid)
contact.show = 'offline'
self._con.send_custom_status('offline', message, contact.jid)
max_order = self._get_max_blocked_list_order()
new_rule = {'order': str(max_order + 1),
'type': 'jid',
'action': 'deny',
'value': contact.jid}
self.blocked_list.append(new_rule)
self.blocked_contacts.append(contact.jid)
self.set_privacy_list(self.default_list, self.blocked_list)
if len(self.blocked_list) == 1:
self.set_default_list(self.default_list)
def unblock_gc_contact(self, jid):
new_blocked_list = []
# needed for draw_contact:
if jid not in self.blocked_contacts:
return
self.blocked_contacts.remove(jid)
log.info('Unblock GC contact: %s', jid)
for rule in self.blocked_list:
if rule['action'] != 'deny' or rule['type'] != 'jid' \
or rule['value'] != jid:
new_blocked_list.append(rule)
if len(new_blocked_list) == 0:
self.blocked_list = []
self.blocked_contacts = []
self.blocked_groups = []
self.set_default_list(None)
self.del_privacy_list(self.default_list)
else:
self.set_privacy_list(self.default_list, new_blocked_list)
def unblock_contacts(self, contact_list):
if not self._con.privacy_rules_supported:
self._con.get_module('Blocking').unblock(contact_list)
return
new_blocked_list = []
to_unblock = []
for contact in contact_list:
log.info('Unblock contacts: %s', contact.jid)
to_unblock.append(contact.jid)
if contact.jid in self.blocked_contacts:
self.blocked_contacts.remove(contact.jid)
for rule in self.blocked_list:
if rule['action'] != 'deny' or rule['type'] != 'jid' \
or rule['value'] not in to_unblock:
new_blocked_list.append(rule)
if len(new_blocked_list) == 0:
self.blocked_list = []
self.blocked_contacts = []
self.blocked_groups = []
self.set_default_list(None)
self.del_privacy_list(self.default_list)
else:
self.set_privacy_list(self.default_list, new_blocked_list)
if not app.interface.roster.regroup:
show = app.SHOW_LIST[self._con.connected]
else: # accounts merged
show = helpers.get_global_show()
if show == 'invisible':
return
for contact in contact_list:
self._con.send_custom_status(show, self._con.status, contact.jid)
self._presence_probe(contact.jid)
def block_group(self, group, contact_list, message):
if not self._con.privacy_rules_supported:
return
if group in self.blocked_groups:
return
self.blocked_groups.append(group)
log.info('Block group: %s', group)
if self.default_list is None:
self.default_list = 'block'
for contact in contact_list:
self._con.send_custom_status('offline', message, contact.jid)
max_order = self._get_max_blocked_list_order()
new_rule = {'order': str(max_order + 1),
'type': 'group',
'action': 'deny',
'value': group}
self.blocked_list.append(new_rule)
self.set_privacy_list(self.default_list, self.blocked_list)
if len(self.blocked_list) == 1:
self.set_default_list(self.default_list)
def unblock_group(self, group, contact_list):
if not self._con.privacy_rules_supported:
return
if group not in self.blocked_groups:
return
self.blocked_groups.remove(group)
log.info('Unblock group: %s', group)
new_blocked_list = []
for rule in self.blocked_list:
if rule['action'] != 'deny' or rule['type'] != 'group' or \
rule['value'] != group:
new_blocked_list.append(rule)
if len(new_blocked_list) == 0:
self.blocked_list = []
self.blocked_contacts = []
self.blocked_groups = []
self.set_default_list('')
self.del_privacy_list(self.default_list)
else:
self.set_privacy_list(self.default_list, new_blocked_list)
if not app.interface.roster.regroup:
show = app.SHOW_LIST[self._con.connected]
else: # accounts merged
show = helpers.get_global_show()
if show == 'invisible':
return
for contact in contact_list:
self._con.send_custom_status(show, self._con.status, contact.jid)
def _presence_probe(self, jid):
log.info('Presence probe: %s', jid)
# Send a presence Probe to get the current Status
probe = nbxmpp.Presence(jid, 'probe', frm=self._con.get_own_jid())
self._con.connection.send(probe)
class PrivacyListsReceivedEvent(NetworkIncomingEvent):
name = 'privacy-lists-received'
base_network_events = []
class PrivacyListReceivedEvent(NetworkIncomingEvent):
name = 'privacy-list-received'
base_network_events = []
class PrivacyListRemovedEvent(NetworkIncomingEvent):
name = 'privacy-list-removed'
base_network_events = []
def get_instance(*args, **kwargs):
return PrivacyLists(*args, **kwargs), 'PrivacyLists'

View File

@ -4100,8 +4100,8 @@ class PrivacyListWindow:
app.ged.register_event_handler('privacy-list-received', ged.GUI1,
self._nec_privacy_list_received)
app.ged.register_event_handler('privacy-list-active-default',
ged.GUI1, self._nec_privacy_list_active_default)
app.ged.register_event_handler('privacy-lists-received', ged.GUI1,
self._nec_privacy_lists_received)
self.window.show_all()
self.add_edit_vbox.hide()
@ -4118,10 +4118,10 @@ class PrivacyListWindow:
del app.interface.instances[self.account][key_name]
app.ged.remove_event_handler('privacy-list-received', ged.GUI1,
self._nec_privacy_list_received)
app.ged.remove_event_handler('privacy-list-active-default',
ged.GUI1, self._nec_privacy_list_active_default)
app.ged.remove_event_handler('privacy-lists-received', ged.GUI1,
self._nec_privacy_lists_received)
def _nec_privacy_list_active_default(self, obj):
def _nec_privacy_lists_received(self, obj):
if obj.conn.name != self.account:
return
if obj.active_list == self.privacy_list_name:
@ -4166,7 +4166,8 @@ class PrivacyListWindow:
self.privacy_list_active_checkbutton.set_sensitive(True)
self.privacy_list_default_checkbutton.set_sensitive(True)
self.reset_fields()
app.connections[self.account].get_active_default_lists()
con = app.connections[self.account]
con.get_module('PrivacyLists').get_privacy_lists()
def _nec_privacy_list_received(self, obj):
if obj.conn.name != self.account:
@ -4176,7 +4177,8 @@ class PrivacyListWindow:
self.privacy_list_received(obj.rules)
def refresh_rules(self):
app.connections[self.account].get_privacy_list(self.privacy_list_name)
con = app.connections[self.account]
con.get_module('PrivacyLists').get_privacy_list(self.privacy_list_name)
def on_delete_rule_button_clicked(self, widget):
model = self.list_of_rules_combobox.get_model()
@ -4186,8 +4188,9 @@ class PrivacyListWindow:
for rule in self.global_rules:
if rule != _rule:
tags.append(self.global_rules[rule])
app.connections[self.account].set_privacy_list(
self.privacy_list_name, tags)
con = app.connections[self.account]
con.get_module('PrivacyLists').set_privacy_list(
self.privacy_list_name, tags)
self.privacy_list_received(tags)
self.add_edit_vbox.hide()
if not tags: # we removed latest rule
@ -4279,18 +4282,20 @@ class PrivacyListWindow:
self.edit_send_status_checkbutton.set_sensitive(True)
def on_privacy_list_active_checkbutton_toggled(self, widget):
name = None
if widget.get_active():
app.connections[self.account].set_active_list(
self.privacy_list_name)
else:
app.connections[self.account].set_active_list(None)
name = self.privacy_list_name
con = app.connections[self.account]
con.get_module('PrivacyLists').set_active_list(name)
def on_privacy_list_default_checkbutton_toggled(self, widget):
name = None
if widget.get_active():
app.connections[self.account].set_default_list(
self.privacy_list_name)
else:
app.connections[self.account].set_default_list(None)
name = self.privacy_list_name
con = app.connections[self.account]
con.get_module('PrivacyLists').set_default_list(name)
def on_new_rule_button_clicked(self, widget):
self.reset_fields()
@ -4362,8 +4367,9 @@ class PrivacyListWindow:
else:
tags.append(current_tags)
app.connections[self.account].set_privacy_list(
self.privacy_list_name, tags)
con = app.connections[self.account]
con.get_module('PrivacyLists').set_privacy_list(
self.privacy_list_name, tags)
self.refresh_rules()
self.add_edit_vbox.hide()
if 'privacy_lists' in app.interface.instances[self.account]:
@ -4419,7 +4425,7 @@ class PrivacyListsWindow:
app.ged.register_event_handler('privacy-lists-received', ged.GUI1,
self._nec_privacy_lists_received)
app.ged.register_event_handler('privacy-lists-removed', ged.GUI1,
app.ged.register_event_handler('privacy-list-removed', ged.GUI1,
self._nec_privacy_lists_removed)
self.window.show_all()
@ -4435,14 +4441,18 @@ class PrivacyListsWindow:
del app.interface.instances[self.account]['privacy_lists']
app.ged.remove_event_handler('privacy-lists-received', ged.GUI1,
self._nec_privacy_lists_received)
app.ged.remove_event_handler('privacy-lists-removed', ged.GUI1,
app.ged.remove_event_handler('privacy-list-removed', ged.GUI1,
self._nec_privacy_lists_removed)
def remove_privacy_list_from_combobox(self, privacy_list):
if privacy_list not in self.privacy_lists_save:
return
privacy_list_index = self.privacy_lists_save.index(privacy_list)
self.list_of_privacy_lists_combobox.remove_text(privacy_list_index)
model = self.list_of_privacy_lists_combobox.get_model()
for entry in model:
if entry[0] == privacy_list:
model.remove(entry.iter)
self.privacy_lists_save.remove(privacy_list)
def add_privacy_list_to_combobox(self, privacy_list):
@ -4477,32 +4487,32 @@ class PrivacyListsWindow:
def on_delete_privacy_list_button_clicked(self, widget):
active_list = self.privacy_lists_save[
self.list_of_privacy_lists_combobox.get_active()]
app.connections[self.account].del_privacy_list(active_list)
con = app.connections[self.account]
con.get_module('PrivacyLists').del_privacy_list(active_list)
def privacy_list_removed(self, active_list):
self.privacy_lists_save.remove(active_list)
self.privacy_lists_received({'lists': self.privacy_lists_save})
self.privacy_lists_received(self.privacy_lists_save)
def _nec_privacy_lists_removed(self, obj):
if obj.conn.name != self.account:
return
self.privacy_list_removed(obj.lists_list)
self.privacy_list_removed(obj.list_name)
def privacy_lists_received(self, lists):
if not lists:
return
privacy_lists = []
for privacy_list in lists['lists']:
for privacy_list in lists:
privacy_lists.append(privacy_list)
self.draw_privacy_lists_in_combobox(privacy_lists)
def _nec_privacy_lists_received(self, obj):
if obj.conn.name != self.account:
return
self.privacy_lists_received(obj.lists_list)
self.privacy_lists_received(obj.lists)
def privacy_lists_refresh(self):
app.connections[self.account].get_privacy_lists()
con = app.connections[self.account]
con.get_module('PrivacyLists').get_privacy_lists()
def on_new_privacy_list_button_clicked(self, widget):
name = self.new_privacy_list_entry.get_text()

View File

@ -2919,46 +2919,15 @@ class GroupchatControl(ChatControlBase):
def on_block(self, widget, nick):
fjid = self.room_jid + '/' + nick
connection = app.connections[self.account]
default = connection.privacy_default_list
if fjid in connection.blocked_contacts:
return
max_order = connection.get_max_blocked_list_order()
new_rule = {'order': str(max_order + 1), 'type': 'jid',
'action': 'deny', 'value' : fjid, 'child': ['message', 'iq',
'presence-out']}
connection.blocked_list.append(new_rule)
connection.blocked_contacts.append(fjid)
con = app.connections[self.account]
con.get_module('PrivacyLists').block_gc_contact(fjid)
self.draw_contact(nick)
connection.set_privacy_list(default, connection.blocked_list)
if len(connection.blocked_list) == 1:
connection.set_default_list(default)
def on_unblock(self, widget, nick):
fjid = self.room_jid + '/' + nick
connection = app.connections[self.account]
default = connection.privacy_default_list
connection.new_blocked_list = []
# needed for draw_contact:
if fjid in connection.blocked_contacts:
connection.blocked_contacts.remove(fjid)
con = app.connections[self.account]
con.get_module('PrivacyLists').unblock_gc_contact(fjid)
self.draw_contact(nick)
for rule in connection.blocked_list:
if rule['action'] != 'deny' or rule['type'] != 'jid' \
or rule['value'] != fjid:
connection.new_blocked_list.append(rule)
if len(connection.new_blocked_list) == 0:
connection.blocked_list = []
connection.blocked_contacts = []
connection.blocked_groups = []
connection.set_default_list('')
connection.del_privacy_list(default)
if 'privay_list_block' in app.interface.instances[self.account]:
del app.interface.instances[self.account]\
['privay_list_block']
else:
connection.set_privacy_list(default, connection.new_blocked_list)
def on_voice_checkmenuitem_activate(self, widget, nick):
if widget.get_active():

View File

@ -2812,12 +2812,8 @@ class RosterWindow:
on_response_ok = (remove, list_), transient_for=self.window)
def _nec_blocking(self, obj):
if obj.unblock_all or obj.blocklist:
jids = app.contacts.get_jid_list(obj.conn.name)
self._idle_draw_jids_of_account(jids, obj.conn.name)
else:
for jid in obj.blocked_jids + obj.unblocked_jids:
self.draw_contact(jid, obj.conn.name)
for jid in obj.changed:
self.draw_contact(jid, obj.conn.name)
def on_block(self, widget, list_, group=None):
"""
@ -2834,13 +2830,15 @@ class RosterWindow:
if group is None:
for acct in accounts:
l_ = [i[0] for i in list_ if i[1] == acct]
app.connections[acct].block_contacts(l_, msg)
con = app.connections[acct]
con.get_module('PrivacyLists').block_contacts(l_, msg)
for contact in l_:
self.draw_contact(contact.jid, acct)
else:
for acct in accounts:
l_ = [i[0] for i in list_ if i[1] == acct]
app.connections[acct].block_group(group, l_, msg)
con = app.connections[acct]
con.get_module('PrivacyLists').block_group(group, l_, msg)
self.draw_group(group, acct)
for contact in l_:
self.draw_contact(contact.jid, acct)
@ -2874,13 +2872,15 @@ class RosterWindow:
if group is None:
for acct in accounts:
l_ = [i[0] for i in list_ if i[1] == acct]
app.connections[acct].unblock_contacts(l_)
con = app.connections[acct]
con.get_module('PrivacyLists').unblock_contacts(l_)
for contact in l_:
self.draw_contact(contact.jid, acct)
else:
for acct in accounts:
l_ = [i[0] for i in list_ if i[1] == acct]
app.connections[acct].unblock_group(group, l_)
con = app.connections[acct]
con.get_module('PrivacyLists').unblock_group(group, l_)
self.draw_group(group, acct)
for contact in l_:
self.draw_contact(contact.jid, acct)
@ -3462,7 +3462,8 @@ class RosterWindow:
for account in account_list:
if app.SHOW_LIST[app.connections[account].connected] == \
'invisible':
app.connections[account].set_invisible_rule()
con = app.connections[account]
con.get_module('PrivacyLists').set_invisible_rule()
# 3. send directed presence
for (contact, account) in contact_list:

View File

@ -20,8 +20,6 @@ class MockConnection(Mock, ConnectionHandlers):
self.connected = 2
self.pep = {}
self.blocked_contacts = {}
self.blocked_groups = {}
self.sessions = {}
self.nested_group_delimiter = '::'
self.server_resource = 'Gajim'