Run erc-services-regain-mode callback on a timer

* lisp/erc/erc-services.el (erc-services-regain-timeout-seconds): New
variable.
(erc-services-regain-mode): Mention CertFP in doc string.
(erc--nickname-in-use-make-request): Ensure the 900 RPL_LOGGEDIN
callback always runs after `erc-services-regain-timeout-seconds', even
when SASL isn't being used.
* test/lisp/erc/erc-scenarios-services-misc.el
(erc-scenarios-services-misc--regain-command/oftc): New test.
* test/lisp/erc/resources/services/regain/taken-regain-oftc.eld: New
file.
This commit is contained in:
F. Jason Park 2025-01-30 19:07:00 -08:00
parent fb53de0c06
commit a62a262397
3 changed files with 86 additions and 6 deletions

View file

@ -548,6 +548,9 @@ for details and use cases."
(function-item erc-services-issue-ghost-and-retry-nick)
function)))
(defvar erc-services-regain-timeout-seconds 5
"Seconds after which to run callbacks if necessary.")
(defun erc-services-retry-nick-on-connect (want)
"Try at most once to grab nickname WANT after reconnecting.
Expect to be used when automatically reconnecting to servers
@ -608,8 +611,8 @@ consider its main option, `erc-services-regain-alist':
In practical terms, this means that this module, which is still
somewhat experimental, is likely only useful in conjunction with
SASL authentication rather than the traditional approach provided
by the `services' module it shares a library with (see Info
SASL authentication or CertFP rather than the traditional approach
provided by the `services' module it shares a library with (see Info
node `(erc) SASL' for more)."
nil nil localp)
@ -632,11 +635,21 @@ one."
(funcall found want))))
(on-900
(lambda (_ parsed)
(cancel-timer timer)
(remove-hook 'erc-server-900-functions on-900 t)
(unless erc-server-connected
(when (equal (car (erc-response.command-args parsed)) temp)
(add-hook 'erc-after-connect after-connect nil t)))
nil)))
(unless (equal want (erc-current-nick))
(if erc-server-connected
(funcall after-connect nil temp)
(when (or (eq parsed 'forcep)
(equal (car (erc-response.command-args parsed)) temp))
(add-hook 'erc-after-connect after-connect nil t))))
nil))
(timer (run-at-time erc-services-regain-timeout-seconds
nil (lambda (buffer)
(when (buffer-live-p buffer)
(with-current-buffer buffer
(funcall on-900 nil 'forcep))))
(current-buffer))))
(add-hook 'erc-server-900-functions on-900 nil t))
(cl-call-next-method))

View file

@ -223,6 +223,31 @@
;; Works with "given" `:id'.
(should (and (erc-network) (not (eq (erc-network) 'ExampleNet)))))))
(ert-deftest erc-scenarios-services-misc--regain-command/oftc ()
:tags '(:expensive-test)
(erc-scenarios-common-with-cleanup
((erc-server-flood-penalty 0.1)
(erc-scenarios-common-dialog "services/regain")
(dumb-server (erc-d-run "localhost" t 'taken-regain-oftc))
(port (process-contact dumb-server :service))
(erc-modules `(services-regain ,@erc-modules))
(erc-services-regain-timeout-seconds 1)
(use-id-p (cl-evenp (truncate (float-time))))
(erc-services-regain-alist (list (cons (if use-id-p 'oftc 'OFTC)
#'erc-services-issue-regain)))
(expect (erc-d-t-make-expecter)))
(with-current-buffer (erc :server "127.0.0.1"
:port port
:nick "dummy"
:user "tester"
:full-name "tester"
:id (and use-id-p 'oftc))
(funcall expect 10 "Nickname dummy is already in use, trying dummy`")
(funcall expect 10 "-NickServ- REGAIN succeed on nickname")
(funcall expect 10 "*** Your new nickname is dummy")
(funcall expect 10 "*** dummy has changed mode for dummy to +R"))))
(ert-deftest erc-scenarios-services-misc--ghost-and-retry-nick ()
:tags '(:expensive-test)
(erc-scenarios-common-with-cleanup

View file

@ -0,0 +1,42 @@
;; -*- mode: lisp-data; -*-
((nick 10 "NICK dummy"))
((user 10 "USER tester 0 * :tester")
(0.09 ":reflection.oftc.net NOTICE AUTH :*** Looking up your hostname...")
(0.03 ":reflection.oftc.net NOTICE AUTH :*** Checking Ident")
(0.02 ":reflection.oftc.net NOTICE AUTH :*** Found your hostname")
(0.01 ":reflection.oftc.net NOTICE AUTH :*** No Ident response")
(0.01 ":reflection.oftc.net 433 * dummy :Nickname is already in use."))
((nick 10 "NICK dummy`")
(0.09 ":reflection.oftc.net NOTICE dummy` :*** Connected securely via TLSv1.3 TLS_AES_256_GCM_SHA384-256")
(0.03 ":reflection.oftc.net NOTICE dummy` :*** Your client certificate fingerprint is 4F6DDB61A5CFFA42719D39E3819B45DC58E4E307")
(0.01 ":reflection.oftc.net 001 dummy` :Welcome to the OFTC Internet Relay Chat Network dummy`")
(0.01 ":reflection.oftc.net 002 dummy` :Your host is reflection.oftc.net[64.86.243.183/6697], running version hybrid-7.2.2+oftc1.7.3")
(0.01 ":reflection.oftc.net 003 dummy` :This server was created Nov 1 2023 at 10:10:46")
(0.00 ":reflection.oftc.net 004 dummy` reflection.oftc.net hybrid-7.2.2+oftc1.7.3 CDGPRSabcdfgijklnorsuwxyz bciklmnopstvzeIMRS bkloveI")
(0.01 ":reflection.oftc.net 005 dummy` CALLERID CASEMAPPING=rfc1459 DEAF=D KICKLEN=160 MODES=4 NICKLEN=30 PREFIX=(ov)@+ STATUSMSG=@+ TOPICLEN=391 NETWORK=OFTC MAXLIST=beI:100 MAXTARGETS=1 CHANTYPES=# :are supported by this server")
(0.03 ":reflection.oftc.net 005 dummy` CHANLIMIT=#:250 CHANNELLEN=50 CHANMODES=eIqb,k,l,cimnpstzMRS AWAYLEN=160 KNOCK ELIST=CMNTU SAFELIST EXCEPTS=e INVEX=I :are supported by this server")
(0.01 ":reflection.oftc.net 042 dummy` 8L3AAEM45 :your unique ID")
(0.00 ":reflection.oftc.net 251 dummy` :There are 31 users and 16297 invisible on 19 servers")
(0.00 ":reflection.oftc.net 252 dummy` 20 :IRC Operators online")
(0.00 ":reflection.oftc.net 253 dummy` 25 :unknown connection(s)")
(0.00 ":reflection.oftc.net 254 dummy` 4118 :channels formed")
(0.00 ":reflection.oftc.net 255 dummy` :I have 1245 clients and 1 servers")
(0.00 ":reflection.oftc.net 265 dummy` :Current local users: 1245 Max: 1782")
(0.00 ":reflection.oftc.net 266 dummy` :Current global users: 16328 Max: 19479")
(0.00 ":reflection.oftc.net 250 dummy` :Highest connection count: 1783 (1782 clients) (203288 connections received)")
(0.03 ":reflection.oftc.net 375 dummy` :- reflection.oftc.net Message of the Day - ")
(0.00 ":reflection.oftc.net 372 dummy` :- O")
(0.00 ":reflection.oftc.net 372 dummy` :- Thanks and enjoy your stay! The OFTC team.")
(0.00 ":reflection.oftc.net 376 dummy` :End of /MOTD command.")
(0.03 ":dummy`!~tester@static-198-54-134-141.cust.tzulo.com MODE dummy` :+i"))
((mode 10 "MODE dummy` +i")
(0.00 ":CTCPServ!services@services.oftc.net PRIVMSG dummy` :\1VERSION\1"))
((~notice 10 "NOTICE CTCPServ :\1VERSION \2ERC\2"))
((privmsg 10 "PRIVMSG NickServ :REGAIN dummy")
(0.01 ":NickServ!services@services.oftc.net NOTICE dummy` :REGAIN succeed on nickname \2dummy\2. You have been changed to your nickname.")
(0.05 ":dummy`!~tester@static-198-54-134-141.cust.tzulo.com NICK :dummy")
(0.01 ":dummy MODE dummy :+R")
(0.04 ":dummy MODE dummy :-R")
(0.01 ":dummy MODE dummy :+R"))
((quit 10 "QUIT :\2ERC\2 5")
(0.08 "ERROR :Closing Link: static-198-54-134-141.cust.tzulo.com ()"))