Page MenuHomePhabricator

Return code with "FAIL" and "UI" responses from "clientlogin" and "createaccount" so they can be easily distinguished programmatically.
Closed, ResolvedPublic

Description

Things which are trickier than necessary to handle at the moment without these codes:

  • Differentiating between certain "UI" responses. For example - distinguishing between a clientlogin UI response indicating a temporary password needs to be changed vs a clientlogin UI response indicating the user should update their pwd of fewer than 8 characters when logging in for the first time after being granted admin rights. Presently the only differentiator in the response is the error message itself, which is problematic for apps because these messages sometimes refer to UI elements which may or may not be present in app interfaces ("Skip" buttons etc - sometimes for size constraint and localization reasons icon are used instead).
  • Differentiating between certain "FAIL" responses. For example - distinguishing when a login has failed because the user's repeated failed login attempts have triggered a captcha requirement. Less state would have to be managed if you could just check the clientlogin UI response for a "NeedsCaptcha" code and only *then* make a secondary "authmanagerinfo amirequestsfor login" query to fetch captchaID/URL.
  • Determining what field should receive focus during login or account creation. For example, during account creation if the user chooses a user name which already exists it would be nice to move focus to the username field when showing them that message. Similar issues exist around setting focus on the captcha field.
  • Determining when login or account creation have reached the state where the user has fulfilled all non-captcha requirements. For example: during account creation we may want to hide all the captcha interface bits until the user has chosen a valid user name, etc.

Event Timeline

Presently the only differentiator in the [UI] response is the error message itself,

The UI response contains a list of the needed AuthenticationRequests, which is the correct way to determine what is needed from the user. If you need more differentiation, your best bet is to specify XXmessageformat=raw and use the message key, there's nothing that an additional "code" would tell you.

Differentiating between certain "FAIL" responses.

Same thing: If you need a code rather than the message, specify XXmessageformat=raw and use the message key. Some other code would give you no additional information.

Less state would have to be managed if you could just check the clientlogin UI response for a "NeedsCaptcha" code and only *then* make a secondary "authmanagerinfo amirequestsfor login" query to fetch captchaID/URL.

The UI response already indicates the need for a captcha by returning an appropriate AuthenticationRequest (on WMF wikis, that's probably CaptchaAuthenticationRequest). And unless I'm greatly mistaken it already includes all the information that a request to meta=authmanagerinfo would return.

Determining what field should receive focus during login or account creation.

That has nothing to do with the request in this task. If you can't determine this for yourself for some reason, you'd want something in the AuthenticationRequests' field data rather than a "code" telling you why you got a UI response.

Determining when login or account creation have reached the state where the user has fulfilled all non-captcha requirements.

AuthManager itself doesn't actually know this. Or, for that matter, that any particular request includes a captcha at all. There's nothing stopping someone from crazily registering multiple SecondaryAuthenticationProviders that each request a captcha, and do so well after any other part of the authentication process.

For example: during account creation we may want to hide all the captcha interface bits until the user has chosen a valid user name, etc.

Then you should be pre-validating the username using [[https://en.wikipedia.org/w/api.php?modules=query+users|action=query&list=users&usprop=cancreate]] before making the first request to action=createaccount.

In general the goal of the interface was to be predictible enough that one can write a client which will work on an arbitrary MediaWiki site, no matter what auth extensions are installed. That also makes it inflexible.

Determining what field should receive focus during login or account creation.

Field-level errors would be nice (although might not be very reliable for focus as multiple things could fail at the same time) but would require a change to the extension interface and they aren't worth that.

Determining when login or account creation have reached the state where the user has fulfilled all non-captcha requirements.

From the APIs POV there isn't really any state involved - you send the captcha and the other fields in the same request. (AuthManager supports multi-step forms but nothing on the WMF cluster uses them for registration.) If you fail the captcha, you must restart and everything will be checked again. (In theory, someone might have taken the username right between you submitting the wrong captcha, and resubmitting.)

The UI response already indicates the need for a captcha by returning an appropriate AuthenticationRequest (on WMF wikis, that's probably CaptchaAuthenticationRequest).

The captcha would be preceded by a FAIL response so that's no help here. Then again, the respnse has no relationship with the captcha whatsoever (the component that issues it for e.g. an invalid password does not know whether there is a captcha, much less whether it will be triggered by the next request) so there is no easy way to add it.

Hey guys good comments! (Edit: I'm still digesting them but thought I'd flesh out one of my examples in the mean time)

Here's a more specific account creation "focus" example. I picked this one because it's the quickest/easiest to explain, but the fix I'm asking for works for the others too :)

If the user submits the account creation form on the app and it receives a "FAIL" response with a message saying "You have not specified a valid username" we show that message directly to the user. This is nice because we don't have to maintain a separate localized string or otherwise import one for this failure case. Here's the response:

"createaccount": {
    "status": "FAIL",
    "message": "You have not specified a valid username."
}

Now imagine we want to maintain the functionality mentioned above, but we'd *also* like to simply move input focus to the username field in this case (the password field may have had focus when the form was submitted - the app keyboard "Done" button can trigger a submission without focus leaving the field it was on). As @Anomie mentioned, we can use "createmessageformat=raw" to get a "key" (perhaps I should have said "key" instead of "code" in my ticket title), but we lose the message:

"createaccount": {
    "status": "FAIL",
    "message": {
        "key": "noname",
        "params": []
    }
}

All I'm asking for is both message and the key:

"createaccount": {
    "status": "FAIL",
    "message": "You have not specified a valid username.",
    "key": "noname"  // <-- THIS IS ALL I WANT FOR CHRISTMAS!!! :)
}

As reformulated, it seems reasonable to give you that much rope. I hope you don't hang yourself.

Change 338997 had a related patch set uploaded (by Anomie):
API: Add "messagecode" to AuthManager responses

https://gerrit.wikimedia.org/r/338997

Change 338997 merged by jenkins-bot:
API: Add "messagecode" to AuthManager responses

https://gerrit.wikimedia.org/r/338997

Tgr assigned this task to Anomie.

I am having troubles using the Mediawiki API for createaccount. I am trying to create sample codes using this api. I need help on this, thanks
@Tgr and @Mhurd @Anomie

@Didicodes: Hi, please see https://www.mediawiki.org/wiki/How_to_become_a_MediaWiki_hacker#Feedback,_questions_and_support and provide clear steps to reproduce and an actual question there. Tasks like this are not a place for general support questions. Thanks for your understanding.