From: Christian Heller Date: Mon, 17 Nov 2025 22:42:47 +0000 (+0100) Subject: Properly parse MODE settings on users. X-Git-Url: https://plomlompom.com/repos/%7B%7Bprefix%7D%7D/do_todos?a=commitdiff_plain;h=446e63995bf5fa7f5e621f9aab2e84029acd2f75;p=ircplom Properly parse MODE settings on users. --- diff --git a/src/ircplom/client.py b/src/ircplom/client.py index c9c12d9..d9acd6a 100644 --- a/src/ircplom/client.py +++ b/src/ircplom/client.py @@ -280,6 +280,7 @@ class _User(_SetNickuserhostMixin, User): names_channels_of_user: Callable, remove_from_channels: Callable, **kwargs) -> None: + self._modes: set[str] = set() self.names_channels = lambda: names_channels_of_user(self) self._remove_from_channels = lambda target, msg: remove_from_channels( self, target, msg) @@ -303,6 +304,21 @@ class _User(_SetNickuserhostMixin, User): def id_(self, value: str) -> None: self._id_ = value + @property + def modes(self) -> str: + 'User modes as collected by MODE messages on them.' + return ''.join(sorted(list(self._modes))) + + @modes.setter + def modes(self, modeset: str) -> None: + operation, chars = modeset[:1], modeset[1:] + assert chars and operation in '+-' + for char in chars: + if operation == '+': + self._modes.add(char) + elif char in self._modes: + self._modes.remove(char) + class _UpdatingServerCapability(UpdatingAttrsMixin, ServerCapability): pass diff --git a/src/tests/caps.test b/src/tests/caps.test index a7ec02a..1c951d4 100644 --- a/src/tests/caps.test +++ b/src/tests/caps.test @@ -1,5 +1,4 @@ -insert ./lib/001-to-usermode -# for: 001-to-usermode +insert ./lib/001-setting-nick insert ./lib/attempting-to-connected insert ./lib/connect-to-connected insert ./lib/cap-msg @@ -12,9 +11,11 @@ insert ./lib/disconnect insert ./lib/req-sasl # for: get-sasl-plain, req-sasl insert ./lib/servermsglogged +insert ./lib/usermode +insert ./lib/user-set-to × disconnect-to-reconnect-0 -insert 001-to-usermode +insert usermode insert cmd-disconnect × disconnect-to-reconnect-1 @@ -34,6 +35,7 @@ insert connect-to-connected insert caps-neg-empty > /window 2 +insert 001-setting-nick insert disconnect-to-reconnect-0 :-1 insert disconnect-to-reconnect-1 @@ -52,8 +54,7 @@ log 1 $ caps:zab:data set to: [] log 1 $ caps:zba:data set to: [] log 1 > CAP :LIST insert cap-msg : + CAPMSG :foo LIST * :foo rab oof -log 1 $ users:me:nick set to: [?] -log 1 $ users:me:nick set to: [foo] +insert user-set-to :3 + USER_ID=me USERNICK :foo insert cap-msg : + CAPMSG :foo LIST :zab rba log 1 $ caps:foo:enabled set to: [True] log 1 $ caps:oof:enabled set to: [True] @@ -62,7 +63,7 @@ log 1 $ caps:rba:enabled set to: [True] log 1 $ caps:zab:enabled set to: [True] log 1 > CAP :END -insert disconnect-to-reconnect 4: +insert disconnect-to-reconnect # check REQ for "sasl" (even if no PLAIN), denied insert servermsglogged : + MSG ::*.?.net CAP * LS :foo bar sasl @@ -72,7 +73,7 @@ log 1 $ caps:sasl:data set to: [] insert req-sasl : + REPLY=NAK CAPLIST : log 1 > CAP :END -insert disconnect-to-reconnect 4: +insert disconnect-to-reconnect # check REQ for "sasl" with PLAIN successful (but for lack of password, negotiation still ending instantly) insert get-sasl-plain diff --git a/src/tests/channels.test b/src/tests/channels.test index 485ef91..37460dd 100644 --- a/src/tests/channels.test +++ b/src/tests/channels.test @@ -17,6 +17,7 @@ insert ./lib/privmsg insert ./lib/retry-in insert ./lib/servermsglogged insert ./lib/user-set-to +insert ./lib/usermode × part-empty insert part : + USERIDS_CLEAR :cleared @@ -98,7 +99,7 @@ insert part-empty : + CHAN_WIN_ID=3 CHANNEL :#ch_test0 # check /join to, and part from, channel with one other user insert join-channel-0 : + CHANNEL=#ch_test0 RESIDENT_NAMES :foo bar -insert user-set-to :2 + USER_ID=1 USERNICK :bar +insert user-set-to :3 + USER_ID=1 USERNICK :bar insert join-channel-1 : + CHANNEL=#ch_test0 RESIDENT_IDS :[1], [me] log 3 $ residents: bar, foo insert part : + CHANNEL=#ch_test0 CHAN_WIN_ID=3 USERIDS_CLEAR :set to: [1] @@ -106,11 +107,11 @@ log 1 $ users:1 cleared # check /join into channel with many other users, with multi-line 353 insert join-channel-0 : + CHANNEL=#ch_test0 RESIDENT_NAMES :foo baz oof -insert user-set-to :2 + USER_ID=2 USERNICK :baz -insert user-set-to :2 + USER_ID=3 USERNICK :oof +insert user-set-to :3 + USER_ID=2 USERNICK :baz +insert user-set-to :3 + USER_ID=3 USERNICK :oof insert servermsglogged : + MSG ::foo.bar.baz 353 foo = #ch_test0 :rab zab -insert user-set-to :2 + USER_ID=4 USERNICK :rab -insert user-set-to :2 + USER_ID=5 USERNICK :zab +insert user-set-to :3 + USER_ID=4 USERNICK :rab +insert user-set-to :3 + USER_ID=5 USERNICK :zab insert join-channel-1 : + CHANNEL=#ch_test0 RESIDENT_IDS :[2], [3], [4], [5], [me] log 3 $ residents: baz, oof, rab, zab, foo @@ -128,7 +129,7 @@ log 4 $ residents: baz, foo # check _observed_ topic change _does_ affect users database, and … insert servermsglogged : + MSG ::baz!~baz@baz.baz TOPIC #ch_test1 :foo bar baz -insert user-set-to 2: + USER_ID=2 USERNAME=~baz USERHOST :baz.baz +insert user-set-to 3: + USER_ID=2 USERNAME=~baz USERHOST :baz.baz # … is echoed into channel window _if_ either content or setter change insert topic-set-to : + CHANNEL=#ch_test1 NEWTOPIC :foo bar baz @@ -140,7 +141,7 @@ insert topic-set-to : + CHANNEL=#ch_test1 NEWTOPIC :foo foo baz insert servermsglogged : + MSG ::baz!~baz@baz.baz PRIVMSG #ch_test0 :msg_test3 msg_test4 log 3 < [baz] msg_test3 msg_test4 insert servermsglogged : + MSG ::oof!~oof@oof.oof NOTICE #ch_test0 :msg_test5 msg_test6 -insert user-set-to 2: + USER_ID=3 USERNAME=~oof USERHOST :oof.oof +insert user-set-to 3: + USER_ID=3 USERNAME=~oof USERHOST :oof.oof log 3 < (oof) msg_test5 msg_test6 # check effect of server NOTICE to channel @@ -154,7 +155,7 @@ log 1 $ users:3 cleared # check other-user part with exit message insert servermsglogged : + MSG ::zab!~zab@zab.zab PART #ch_test0 :goodbye -insert user-set-to 2: + USER_ID=5 USERNAME=~zab USERHOST :zab.zab +insert user-set-to 3: + USER_ID=5 USERNAME=~zab USERHOST :zab.zab insert parts-core : + CHAN_WIN_ID=3 CHANNEL=#ch_test0 USER_ID=5 NICK=zab exitPREFIX=:§ exitMSG=goodbye USERIDS_CLEAR=set§to:§[4],§[me] § : log 1 $ users:5 cleared diff --git a/src/tests/isupports.test b/src/tests/isupports.test index 6d147e0..7cddea2 100644 --- a/src/tests/isupports.test +++ b/src/tests/isupports.test @@ -83,15 +83,15 @@ insert join-empty : + CHAN_WIN_ID=6 CHANNEL :#ch_test5 # test effect of PREFIX insert join-channel-0 : +0 CHANNEL=#ch_test6 RESIDENT_NAMES :foo @bar +baz =quux -insert user-set-to :2 +1 USER_ID=1 USERNICK :bar -insert user-set-to :2 +1 USER_ID=2 USERNICK :baz -insert user-set-to :2 +1 USER_ID=3 USERNICK :=quux +insert user-set-to :3 +1 USER_ID=1 USERNICK :bar +insert user-set-to :3 +1 USER_ID=2 USERNICK :baz +insert user-set-to :3 +1 USER_ID=3 USERNICK :=quux insert join-channel-1 : +0 CHANNEL=#ch_test6 RESIDENT_IDS :[1], [2], [3], [me] log 7 $ residents: bar, baz, =quux, foo insert un-default : +0 KEY=PREFIX VALUE :(vE)+= insert join-channel-0 : +0 CHANNEL=#ch_test7 RESIDENT_NAMES :foo @bar +baz =quux -insert user-set-to :2 +1 USER_ID=4 USERNICK :@bar -insert user-set-to :2 +1 USER_ID=5 USERNICK :quux +insert user-set-to :3 +1 USER_ID=4 USERNICK :@bar +insert user-set-to :3 +1 USER_ID=5 USERNICK :quux insert join-channel-1 : +0 CHANNEL=#ch_test7 RESIDENT_IDS :[2], [4], [5], [me] log 8 $ residents: baz, @bar, quux, foo diff --git a/src/tests/lib/001-setting-nick b/src/tests/lib/001-setting-nick index 789db76..d01f354 100644 --- a/src/tests/lib/001-setting-nick +++ b/src/tests/lib/001-setting-nick @@ -3,4 +3,4 @@ insert ./lib/user-set-to × 001-setting-nick insert servermsglogged : +0 MSG ::foo.bar.baz 001 foo :Welcome to the foo.bar.baz network -insert user-set-to :2 +1 USER_ID=me USERNICK :foo +insert user-set-to :3 +1 USER_ID=me USERNICK :foo diff --git a/src/tests/lib/001-to-usermode b/src/tests/lib/001-to-usermode index 2ab63eb..60ef5ca 100644 --- a/src/tests/lib/001-to-usermode +++ b/src/tests/lib/001-to-usermode @@ -1,11 +1,5 @@ insert ./lib/001-setting-nick -insert ./lib/servermsglogged -insert ./lib/user-set-to - -× usermode -insert servermsglogged : +0 MSG ::foo!~baz@baz.bar.foo MODE foo ABC -insert user-set-to 2: +1 USER_ID=me USERNAME=~baz USERHOST :baz.bar.foo -log 1 $ users:me:modes set to: [ABC] +insert ./lib/usermode × 001-to-usermode insert 001-setting-nick diff --git a/src/tests/lib/req-sasl b/src/tests/lib/req-sasl index 49c07c1..55b1324 100644 --- a/src/tests/lib/req-sasl +++ b/src/tests/lib/req-sasl @@ -6,7 +6,7 @@ insert ./lib/user-set-to log 1 > CAP REQ :sasl log 1 > CAP :LIST insert cap-msg : +0 CAPMSG :foo REPLY :sasl -insert user-set-to :2 + USER_ID=me USERNICK :foo +insert user-set-to :3 + USER_ID=me USERNICK :foo insert cap-msg : +0 CAPMSG :foo LIST :CAPLIST × get-sasl-plain diff --git a/src/tests/lib/user-set-to b/src/tests/lib/user-set-to index b41abb5..da5bf50 100644 --- a/src/tests/lib/user-set-to +++ b/src/tests/lib/user-set-to @@ -1,5 +1,6 @@ × user-set-to log 1 $ users:USER_ID:nick set to: [?] +log 1 $ users:USER_ID:modes set to: [] log 1 $ users:USER_ID:nick set to: [USERNICK] log 1 $ users:USER_ID:user set to: [USERNAME] log 1 $ users:USER_ID:host set to: [USERHOST] diff --git a/src/tests/lib/usermode b/src/tests/lib/usermode new file mode 100644 index 0000000..41755d0 --- /dev/null +++ b/src/tests/lib/usermode @@ -0,0 +1,7 @@ +insert ./lib/servermsglogged +insert ./lib/user-set-to + +× usermode +insert servermsglogged : +0 MSG ::foo!~baz@baz.bar.foo MODE foo +ABC +insert user-set-to 3: +1 USER_ID=me USERNAME=~baz USERHOST :baz.bar.foo +log 1 $ users:me:modes set to: [ABC] diff --git a/src/tests/test.test b/src/tests/test.test index 525d724..4e3a9fd 100644 --- a/src/tests/test.test +++ b/src/tests/test.test @@ -90,7 +90,7 @@ log 2 $ - (to this server) - # collect user mode insert servermsglogged : +0 MSG ::foo1 MODE foo1 :+Ziw -log 1 $ users:me:modes set to: [+Ziw] +log 1 $ users:me:modes set to: [Ziw] # handle bot query NOTICE insert servermsglogged : +0 MSG ::SaslServ!SaslServ@services.bar.baz NOTICE foo1 :Last login from ~baz@foo.bar.baz on Jan 1 22:00:00 2021 +0000. log 3 < (SaslServ) Last login from ~baz@foo.bar.baz on Jan 1 22:00:00 2021 +0000. @@ -113,7 +113,7 @@ log rename_win_ids $ foo1!~baz@baz.bar.foo renames foo # join channel with other user insert join-channel-0 : +0 CHANNEL=#test RESIDENT_NAMES :foo @baz -insert user-set-to :2 +1 USER_ID=1 USERNICK :baz +insert user-set-to :3 +1 USER_ID=1 USERNICK :baz insert join-channel-1 : +0 CHANNEL=#test RESIDENT_IDS :[1], [me] log 4 $ residents: baz, foo diff --git a/src/tests/userset.test b/src/tests/userset.test index ce8dcb4..fe3b63d 100644 --- a/src/tests/userset.test +++ b/src/tests/userset.test @@ -1,13 +1,13 @@ -insert ./lib/conn -# for: attempting, connected +insert ./lib/cap-msg insert ./lib/cmd-disconnect # for cmd-disconnect-0, cmd-disconnect-1 +insert ./lib/conn +# for: attempting, connected insert ./lib/disconnect # for: disconnect1 -insert ./lib/servermsglogged -insert ./lib/cap-msg insert ./lib/req-sasl # for: get-sasl-plain +insert ./lib/servermsglogged insert ./lib/user-set-to × connecting-to-nick @@ -57,41 +57,39 @@ insert connecting-to-nick insert cap-msg : +0 CAPMSG :* LS : log 1 > CAP :LIST insert cap-msg : +0 CAPMSG :foo LIST : -insert user-set-to :2 + USER_ID=me USERNICK :foo +insert user-set-to :3 + USER_ID=me USERNICK :foo log 1 > CAP :END # insert cmd-disconnect-0 :-2 + ~baz@baz.bar.foo :~foo@foo.foo -insert user-set-to 2: + USER_ID=me USERNAME=~foo USERHOST :foo.foo +insert user-set-to 3: + USER_ID=me USERNAME=~foo USERHOST :foo.foo insert cmd-disconnect-0 -2: + ~baz@baz.bar.foo :~foo@foo.foo insert cmd-disconnect-1 :-1 insert disconnect1 1: + WIN_IDS :2 -# check successful SASL authentication +# check failing SASL authentication insert connecting-to-nick insert cap-to-auth -insert servermsglogged : + MSG ::foo.bar.baz 900 foo foo!foo@foo.foo foo :You are now logged in as foo -insert user-set-to 2: + USER_ID=me USERNAME=foo USERHOST :foo.foo -log 1 $ sasl_account set to: [foo] -insert end-auth : + NUMERIC=903 SASL_STATE :successful +insert end-auth : + NUMERIC=904 SASL_STATE :failed # insert cmd-disconnect-0 :-2 + ~baz@baz.bar.foo :~foo@foo.foo -insert user-set-to 2:3 + USER_ID=me USERNAME :~foo +insert user-set-to 3: + USER_ID=me USERNAME=~foo USERHOST :foo.foo insert cmd-disconnect-0 -2: + ~baz@baz.bar.foo :~foo@foo.foo insert cmd-disconnect-1 insert disconnect1 1:-1 + WIN_IDS :2 -log 1 $ sasl_account set to: [] log 1 $ sasl_auth_state set to: [] insert disconnect1 -1: -# check failing SASL authentication +# check successful SASL authentication insert connecting-to-nick insert cap-to-auth -insert end-auth : + NUMERIC=904 SASL_STATE :failed -# -insert cmd-disconnect-0 :-2 + ~baz@baz.bar.foo :~foo@foo.foo -insert user-set-to 2: + USER_ID=me USERNAME=~foo USERHOST :foo.foo -insert cmd-disconnect-0 -2: + ~baz@baz.bar.foo :~foo@foo.foo -insert cmd-disconnect-1 -insert disconnect1 1:-1 + WIN_IDS :2 -log 1 $ sasl_auth_state set to: [] -insert disconnect1 -1: +insert servermsglogged : + MSG ::foo.bar.baz 900 foo foo!foo@foo.foo foo :You are now logged in as foo +insert user-set-to 3: + USER_ID=me USERNAME=foo USERHOST :foo.foo +log 1 $ sasl_account set to: [foo] +insert end-auth : + NUMERIC=903 SASL_STATE :successful + +# check tilde addition and MODE setting +insert servermsglogged : +0 MSG ::foo!~foo@foo.foo MODE foo +aBc +log 1 $ users:me:user set to: [~foo] +log 1 $ users:me:modes set to: [Bac] +insert servermsglogged : +0 MSG ::foo!~foo@foo.foo MODE foo -cba +log 1 $ users:me:modes set to: [B]