Ok, I've redone the whole shebang, hoping this'll pass muster. If not, I can do a larger refactor of the whole ConfirmEdit extension, maybe make a fresh one and introduce better machine-readable hook points into the API and form.
But I hope this'll do for now. :)
MediaWiki core: https://gerrit.wikimedia.org/r/53793 ConfirmEdit ext: https://gerrit.wikimedia.org/r/53794
Major changes from previous approach: * instead of falling through if in API mode (dangerous if using the new extension on old core), we check the captcha in the same consistent place in a hook from LoginForm. * We add a fairly generic hook that allows extensions to add return data via the createaccount API if they threw an abort instead of sending a generic error. This is used to append the captcha data. * We return result='needcaptcha' explicitly if we need to pass a captcha * Captcha data is not available until after you have a token, so this requires making two requests if you want to show a captcha before prompting for username/password.
If y'all would prefer totally fresh interfaces with a consistent machine-readable API... I can do that too, but it'd be spiffy if we could do the less invasive change first. :)
-- brion
On Mon, Mar 25, 2013 at 1:38 AM, S Page spage@wikimedia.org wrote:
On Thu, Mar 14, 2013 at 3:55 PM, Brion Vibber bvibber@wikimedia.org wrote:
MediaWiki core: https://gerrit.wikimedia.org/r/53793 ConfirmEdit ext: https://gerrit.wikimedia.org/r/53794
So far I've tested it with the default 'math captcha' mode, with this
test
This is great to see.
Using your test rig or Special:APISandbox, the API return warns about "Unrecognized parameters: 'wpCaptchaId', 'wpCaptchaWord" when I get the captcha wrong.
It seems if the user gets the captcha wrong, there's no explicit indication like captcha-createaccount-fail ('Incorrect or missing confirmation code.'). Instead the API reports a generic Failure result, and the UI presents a new captcha.
ConfirmEdit has a getMessage() to provide action-specific text like fancycaptcha-createaccount. Perhaps the API should pass that back as well. Otherwise the UI has to know the details of the captcha in use so it can get a message for it.
The current CreateAccount form submission to Special:UserLogin reports many form errors like username exists, password wrong, etc. before it runs the AbortNewAccount hook where ConfirmEdit checks the captcha. But APICreateAccount runs the APICreateAccountBeforeCreate hook early, before it dummies up a login form and calls the same validation. So users will go through the frustration of getting the captcha right before being told their username isn't available or their password isn't long enough.
There's also the weirdness that ApiCreateAccount winds up checking the CAPTCHA twice. AIUI, here's the program flow:
ApiCreateAccount() Runs APICreateAccountBeforeCreate hook (captcha may abort) Creates a login forms and call $loginForm->addNewaccountInternal(); addNewaccountInternal(): Does a bunch of form validation Runs AbortNewAccount hook (captcha may abort, also TitleBlacklist, AntiSpoof, etc. may abort)
If ApiCreateAccount() could tell there was a captcha failure within addNewaccountInternal and could ask the captcha to addCaptchaAPI() to the result, then we wouldn't need the new APICreateAccountBeforeCreate hook.
It would be nice if captcha was always checked on its own hook instead of sharing a hook with other extensions. That would let a future validation API run the username past TitleBlacklist and AntiSpoof without getting shot down by the captcha.
Cheers,
=S Page software engineer on E3