From 3a42c8e835f004db7da1477671c22fdda91cc8e5 Mon Sep 17 00:00:00 2001 From: James Lu Date: Fri, 7 Jul 2017 20:02:37 -0700 Subject: [PATCH] protocols: add _check_oper_status_change abstraction This condenses a large chunk of the code checking for oper ups, and adds support for the servprotect/admin umodes in an IRCd-independent manner. Closes #451. --- protocols/hybrid.py | 3 +-- protocols/inspircd.py | 5 +---- protocols/ircs2s_common.py | 19 ++++++++++++++----- protocols/p10.py | 3 +-- protocols/ts6.py | 4 +--- protocols/unreal.py | 9 ++------- 6 files changed, 20 insertions(+), 23 deletions(-) diff --git a/protocols/hybrid.py b/protocols/hybrid.py index 04c35fa..22eef87 100644 --- a/protocols/hybrid.py +++ b/protocols/hybrid.py @@ -185,8 +185,7 @@ class HybridProtocol(TS6Protocol): self.servers[numeric].users.add(uid) # Call the OPERED UP hook if +o is being added to the mode list. - if ('+o', None) in parsedmodes: - self.call_hooks([uid, 'CLIENT_OPERED', {'text': 'IRC_Operator'}]) + self._check_oper_status_change(uid, parsedmodes) # Set the account name if present if account: diff --git a/protocols/inspircd.py b/protocols/inspircd.py index 1ecd258..d0663ef 100644 --- a/protocols/inspircd.py +++ b/protocols/inspircd.py @@ -562,10 +562,7 @@ class InspIRCdProtocol(TS6BaseProtocol): parsedmodes = self.parse_modes(uid, [args[8], args[9]]) self.apply_modes(uid, parsedmodes) - if (self.umodes.get('servprotect'), None) in userobj.modes: - # Services are usually given a "Network Service" WHOIS, so - # set that as the opertype. - self.call_hooks([uid, 'CLIENT_OPERED', {'text': 'Network Service'}]) + self._check_oper_status_change(uid, parsedmodes) self.servers[numeric].users.add(uid) return {'uid': uid, 'ts': ts, 'nick': nick, 'realhost': realhost, 'host': host, 'ident': ident, 'ip': ip} diff --git a/protocols/ircs2s_common.py b/protocols/ircs2s_common.py index fef789d..e59aca8 100644 --- a/protocols/ircs2s_common.py +++ b/protocols/ircs2s_common.py @@ -571,6 +571,19 @@ class IRCS2SProtocol(IRCCommonProtocol): # This sets a dummy away reason of "Away" because no actual text is provided. self.call_hooks([uid, 'AWAY', {'text': 'Away' if away_status else ''}]) + def _check_oper_status_change(self, uid, modes): + if uid in self.users: + u = self.users[uid] + if 'admin' in self.umodes and (self.umodes['admin'], None) in u.modes: + opertype = 'Server Administrator' + elif 'servprotect' in self.umodes and (self.umodes['servprotect'], None) in u.modes: + opertype = 'Network Service' + else: + opertype = 'IRC Operator' + + if ('+o', None) in modes: + self.call_hooks([uid, 'CLIENT_OPERED', {'text': opertype}]) + def handle_mode(self, source, command, args): """Handles mode changes.""" # InspIRCd: @@ -591,15 +604,11 @@ class IRCS2SProtocol(IRCCommonProtocol): changedmodes = self.parse_modes(target, modestrings) self.apply_modes(target, changedmodes) - # Call the CLIENT_OPERED hook if +o is being set. - # TODO: handle umodes for admin, servprotect, etc. and set the oper type accordingly. - if ('+o', None) in changedmodes and target in self.users: - self.call_hooks([target, 'CLIENT_OPERED', {'text': 'IRC Operator'}]) - if target in self.users: # Target was a user. Check for any cloak and away status changes. self._check_cloak_change(target) self._check_umode_away_change(target) + self._check_oper_status_change(target, changedmodes) return {'target': target, 'modes': changedmodes, 'channeldata': channeldata} diff --git a/protocols/p10.py b/protocols/p10.py index 3688a5a..b182b42 100644 --- a/protocols/p10.py +++ b/protocols/p10.py @@ -858,8 +858,7 @@ class P10Protocol(IRCS2SProtocol): self.call_hooks([uid, 'CLIENT_SERVICES_LOGIN', {'text': accountname}]) # Call the OPERED UP hook if +o is being added to the mode list. - if ('+o', None) in parsedmodes: - self.call_hooks([uid, 'CLIENT_OPERED', {'text': 'IRC Operator'}]) + self._check_oper_status_change(uid, parsedmodes) self._check_cloak_change(uid) diff --git a/protocols/ts6.py b/protocols/ts6.py index b549fd8..5fea708 100644 --- a/protocols/ts6.py +++ b/protocols/ts6.py @@ -509,9 +509,7 @@ class TS6Protocol(TS6BaseProtocol): self.servers[numeric].users.add(uid) # Call the OPERED UP hook if +o is being added to the mode list. - if ('+o', None) in parsedmodes: - otype = 'Server Administrator' if ('+a', None) in parsedmodes else 'IRC Operator' - self.call_hooks([uid, 'CLIENT_OPERED', {'text': otype}]) + self._check_oper_status_change(uid, parsedmodes) # Set the accountname if present if accountname != "*": diff --git a/protocols/unreal.py b/protocols/unreal.py index dcc3cf9..bb12850 100644 --- a/protocols/unreal.py +++ b/protocols/unreal.py @@ -404,9 +404,7 @@ class UnrealProtocol(TS6BaseProtocol): # enabled) but NOT +t (vHost set). self.users[uid].cloaked_host = args[9] - if ('+o', None) in parsedmodes: - # If +o being set, call the CLIENT_OPERED internal hook. - self.call_hooks([uid, 'CLIENT_OPERED', {'text': 'IRC Operator'}]) + self._check_oper_status_change(uid, parsedmodes) if ('+x', None) not in parsedmodes: # If +x is not set, update to use the person's real host. @@ -826,10 +824,7 @@ class UnrealProtocol(TS6BaseProtocol): parsedmodes = self.parse_modes(numeric, args) self.apply_modes(numeric, parsedmodes) - if ('+o', None) in parsedmodes: - # If +o being set, call the CLIENT_OPERED internal hook. - self.call_hooks([numeric, 'CLIENT_OPERED', {'text': 'IRC Operator'}]) - + self._check_oper_status_change(numeric, parsedmodes) self._check_cloak_change(numeric, parsedmodes) return {'target': numeric, 'modes': parsedmodes}