Page MenuHomePhabricator

Update login and account creation for API changes
Closed, ResolvedPublic3 Story Points

Description

Description

The Android login and account creation API usage requires updating for changes in AuthManager. ETA for "thing will break" is end of February. Some questions to think about:

  • Will the old way really break? How will we gracefully transition?
  • Do we need to remove account creation from the Gingerbread app?
  • Do we need a security review?
  • Can we use device accounts with this (for example, "login with Google")?

We should start thinking about this now and talk with @Anomie to understand when we can start testing with a local instance.

References

Details

Related Gerrit Patches:

Related Objects

Event Timeline

Niedzielski raised the priority of this task from to High.
Niedzielski updated the task description. (Show Details)
Niedzielski added subscribers: Niedzielski, Anomie.
Restricted Application added a subscriber: Aklapper. · View Herald TranscriptJan 20 2016, 8:56 PM
Niedzielski updated the task description. (Show Details)Jan 20 2016, 8:58 PM
Niedzielski set Security to None.
  • Will the old way really break?

Account creation will. Login might continue working for some unspecified period of time for some unspecified group of users.

  • Can we use device accounts with this (for example, "login with Google")?

If the GoogleLogin extension is updated for AuthManager and deployed to WMF wikis, it should be possible. After AuthManager itself is deployed and working, I wouldn't be opposed to consulting on that update.

Dbrant added a subscriber: Dbrant.Jan 20 2016, 10:37 PM

@Anomie, for account creation, will there be no overlap for the new and old API?

Only to the extent that we have different wikis on different versions (wmf.X and wmf.X+1) from Tuesday to Thursday each week.

It would be possible to do a might-work-might-not BC version of account creation like we're doing for login, but I'm less confident in the "might-work" side of that for WMF wikis since our login is pretty vanilla while account creation is currently hooked by AntiSpoof, TitleBlacklist, and ConfirmEdit (the captcha extension). Combine that with the fact that lots of people log in via the API while account creation is done far less often, and it seems like a lot of complexity for much less benefit.

Hm, we're in a tricky spot because we need some time to actually distribute app updates to all users. I think we looked a few months ago and we had something like 50% of all users on the latest version of the app after it had been out a couple weeks. If overlapping APIs can't be supported on the backend, maybe we can put a temporary "timebomb" or remote config in now for disabling account creation after a certain date. Or better yet, switch out the implementations after a certain date.

You could also disable or switch implementations based on whether /w/api.php?action=paraminfo&modules=query+authmanagerinfo or /w/api.php?action=paraminfo&modules=clientlogin indicates that the modules exist, or on the specific parameters returned as being accepted by /w/api.php?action=paraminfo&modules=createaccount.

jeremyb-phone edited subscribers, added: jeremyb; removed: jeremyb-phone.Jan 22 2016, 1:40 AM
jeremyb-phone added a subscriber: jeremyb-phone.

Hi @Anomie! Any update on when the API changes are expected to deploy? Are they ready for testing?

https://gerrit.wikimedia.org/r/#/c/265201/ is basically done except for the "send a password reset email" module, although I can't say with 100% certainty that nothing will need changing. I don't know about progress on T124832: Setup testing server for AuthManager in Labs.

For deployment, who knows, especially since people are likely to be shy about it after SessionManager and wmf.11.

I got as far as creating a new Labs project to host it and then wandered away. I'll see if I can get that moving again today/tomorrow.

Change 278035 had a related patch set uploaded (by Mholloway):
Update login and account creation API tasks to work with new AuthManager

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

Might as well pull this (back) into the sprint since I'm doing the work.

Adding T110302: Update ConfirmEdit to use AuthManager as a blocker since it's unclear the how API will behave around CAPTCHAs but I assume AuthManager won't be deployed to the Wikipedias without them.

@Mhurd For efficiency's sake I added you to the existing task, but if you want to start a separate, iOS specific Phab task for this, go for it.

As I mentioned at standup this is something I'd be willing and interested in taking on for iOS, too.

Adding T110302: Update ConfirmEdit to use AuthManager as a blocker since it's unclear the how API will behave around CAPTCHAs but I assume AuthManager won't be deployed to the Wikipedias without them.

Generically, ConfirmEdit will have some sort of AuthenticationRequest required for the initial submission. You'd fetch the information about that AuthenticationRequest from action=query&meta=authmanagerinfo to be able to display the captcha (the exact format of the result there is yet to be determined), and supply the relevant fields when you send the action=createaccount request.

Also, BTW, looking at that made me realize a bug in AuthPluginPrimaryAuthenticationProvider, there should be a "retype" field in there for creation. I'll fix that on the test server momentarily.

TODO: detect whether AuthManager is enabled and vary login process accordingly. Then we can get these patches in anytime.

I'll see about getting this in this afternoon.

As promised at some point, for the benefit of the iOS folks, here's a high-level overview of the changes you'll need to make to log in or create and account with AuthManager (AM); hopefully it'll save you a bit of work. Overall it's relatively painless.

1. Check for AuthManager

As @Anomie suggested above, we're set up to handle both AM and legacy login/account creation as needed. We start the sequence by posting an authmanagerinfo request to see if AM is enabled on the target wiki. If the response object has a "query" property, it is.

{
  action: query,
  format: json,
  meta: authmanagerinfo,
  amirequestsfor: login
}
2. Get a token

In the current/soon-to-be-deprecated flow, you make a request to the API with a username/password and get a token back to resubmit the same info with. With AM, to get a token, you'll post a request with these params:

{
  action: query,
  format: json,
  meta: tokens,
  type: ['login' or 'createaccount' as appropriate]  
}
3. Request your action
3a. Log in

Largely the same as before but note that with AuthManager (1) the param names are slightly different, and (2) you're required to provide a loginreturnurl value; we just use www.wikipedia.org.

3b. Create an account

As with login, fairly similar to before, but with slightly different param names and the following additional required values: (1) a retype value to compare against the password, and (2) a createreturnurl value (again, we use www.wikipedia.org).

4. Handle the response

Responses with AuthManager are substantially different, especially in the failure case. If you succeed, you'll receive PASS in the response status field. If you fail, rather than receiving an error code, you'll receive FAIL along with a localized error message string in the message field. If, like us, you currently bundle a large number of translated login/account creation error strings, I think this will render them obsolete.

In some cases (e.g., account creation or n consecutive failed login attempts) you'll probably receive a CAPTCHA challenge but I believe this feature is still under development.

Notes

As before, usernames are case-sensitive and the first character is automatically upper-cased on creation. Unlike before, however, if a username is submitted for login with the first character lower-cased, it will fail. It's probably best to capitalize the first character for the user before sending.

I highly recommend the Postman tool for poking around with API calls; I found it made this work a lot easier.

1. Check for AuthManager

Besides just checking for AuthManager, the response contains details about the different fields that are on Special:UserLogin or Special:CreateAccount and that you might submit to action=clientlogin or action=createaccount to begin a login or account creation.

2. Get a token

In the current/soon-to-be-deprecated flow, you make a request to the API with a username/password and get a token back to resubmit the same info with. With AM, to get a token, you'll post a request with these params:

{
  action: query,
  format: json,
  meta: tokens,
  type: ['login' or 'createaccount' as appropriate]  
}

You can do this with the current flow too, since 1.27.0-wmf.12.

3a. Log in

Largely the same as before but note that with AuthManager (1) the param names are slightly different

Also of note is that you need to specify the rememberMe parameter (with any value, it works like an HTML checkbox) if you want to get back cookies to be logged in for longer than the current session.

and (2) you're required to provide a loginreturnurl value; we just use www.wikipedia.org.

FYI, the significance of the loginreturnurl is that in the future it could give you a response that instructs you to redirect the user to some other website (i.e. you'd open it in a webview of some sort). When whatever you're redirecting to is done, it will send the webview back to the loginreturnurl along with the parameters that you'll need to submit back to the API. When you see that URL in your webview, you would grab the parameters and close the webview.

Responses with AuthManager are substantially different, especially in the failure case. If you succeed, you'll receive PASS in the response status field. If you fail, rather than receiving an error code, you'll receive FAIL along with a localized error message string in the message field.

Note you can select HTML, wikitext, or raw "message key and parameters" format for the localized error message using the loginmessageformat (or createmessageformat) parameter, and the language with uselang.

Besides PASS or FAIL, you might also see UI which indicates that something wanted to ask for more data. "Somethings" that exist now or are likely to exist soon include a password reset (e.g. someone just got promoted to sysop and they need to set a stronger password) or entry of the second factor for two-factor authentication. A UI response will have a message field with a localized message for the user and a requests field that has details on what, specifically, is being requested (in the same format as you get in step 1).

There's also the possibility for REDIRECT (as described above; I don't think we have plans for anything that would need this at the moment, but something like "log in with your Google account" would do it to send the user to Google's authentication page) or RESTART (I don't think we have plans for anything that would need this at the moment either, this would happen if the user picked "log in with your Google account" and it succeeded but we don't have a link from that Google account to any local username; the semantics are that you either treat it like UI, or like FAIL, or you could switch to action=createaccount and include createpreservestate in the initial request).

If you're testing against http://authmanager.wmflabs.org, you can test these different response types by setting secondaryStatus in your request.

In some cases (e.g., account creation or n consecutive failed login attempts) you'll probably receive a CAPTCHA challenge but I believe this feature is still under development.

If you're testing against http://authmanager.wmflabs.org, this should be live now. In the response from step 1 (if you use amirequestsfor=create), you'll see an entry for "CaptchaAuthenticationRequest" that has the information about the captcha. As currently configured, you'd submit the captchaId field with the value given and the captchaWord field with the solution to the captcha; the image URL is the value given for the captchaInfo field.

Unlike before, however, if a username is submitted for login with the first character lower-cased, it will fail.

This was a bug and has already been fixed.

Thanks for the detailed info, @Anomie!

If you're testing against http://authmanager.wmflabs.org, this should be live now. In the response from step 1 (if you use amirequestsfor=create), you'll see an entry for "CaptchaAuthenticationRequest" that has the information about the captcha. As currently configured, you'd submit the captchaId field with the value given and the captchaWord field with the solution to the captcha; the image URL is the value given for the captchaInfo field.

My patch is now working with the account creation flow as currently configured on the labs instance. Digging a little deeper on this, will the captcha info always appear in the initial amirequestsfor response if it's required, or do we also need to handle a possible captcha challenge in a subsequent step as in the current flow?

Also of note is that you need to specify the rememberMe parameter (with any value, it works like an HTML checkbox) if you want to get back cookies to be logged in for longer than the current session.

FYI @Dbrant, this is new functionality for us and seems like a discrete task that can be done after the core compatibility work is complete, so I'm going to create a follow-up ticket for it.

My patch is now working with the account creation flow as currently configured on the labs instance. Digging a little deeper on this, will the captcha info always appear in the initial amirequestsfor response if it's required, or do we also need to handle a possible captcha challenge in a subsequent step as in the current flow?

With the way ConfirmEdit is currently written, it cannot ask for a captcha challenge in a subsequent step.

It wouldn't be impossible for someone to change ConfirmEdit's code so that it could say "oh, by the way, here's another captcha for you to solve before you can finish", but that would require changing the code. If such a thing did happen, you'd get a UI response where the 'requests' response field contained a CaptchaAuthenticationRequest.

BTW, you'll never see it on WMF wikis and I only mention it in case someone else finds this in a search, but there's also the possibility for ReCaptchaAuthenticationRequest or ReCaptchaNoCaptchaAuthenticationRequest, if a wiki is using ConfirmEdit with ReCaptcha or ReCaptchaNoCaptcha.

Mholloway set the point value for this task to 3.May 18 2016, 7:56 PM

Change 278035 merged by jenkins-bot:
Update login and account creation to work with AuthManager

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

Mholloway added a comment.EditedMay 19 2016, 8:50 PM

QA Instructions:

  1. Create a new account with the app. Log out, and log back in with the new account. Log out again.
  2. Enter the developer settings*, set 'mediaWikiBaseUri' to 'https://authmanager.wmflabs.org', and move the 'mediaWikiBaseUriSupportsLangCode' slider to the 'off' position. Exit the app and swipe away.
  3. Reopen the app and repeat step 1.
  4. Return the developer settings that you changed in Step 2 to their original settings ('mediaWikiBaseUriSupportsLangCode' in 'on' position and empty 'mediaWikiBaseUri' setting).

*The developer settings are reached through an icon on the right side of the toolbar in the settings activity. If this icon is not present, enable developer mode by selecting 'Settings' from the left nav drawer, clicking 'About the Wikipedia app,' and clicking the 'W' icon on the following screen seven times (until a 'You are now a developer' message appears. Then restart the app and the icon should be present.)

Testing on Android 4.4.2/Toshiba AT7-C tablet and Wikipedia 2.1.144-alpha-2016-05-20. This is fixed as I followed Mholloway's QA Instructions with no errors occurring.

Dbrant closed this task as Resolved.May 23 2016, 5:54 PM

@Fjalapeno, I'm not sure if it helps but a while back I was debugging the new login API and took some notes. I'm pretty slow so I spent longer than I should have but it might be worth sharing.

Current (deprecated)

curl -c cookies -d 'action=login&format=json&lgname=USERNAME&lgpassword=PASSWORD&formatversion=2' https://en.wikipedia.org/w/api.php|jq .login.token
curl -b cookies -d 'action=login&format=json&lgname=USERNAME&lgpassword=PASSWORD&formatversion=2&lgtoken=TOKEN%2B%5C' https://en.wikipedia.org/w/api.php|jq

New

curl -c cookies 'https://en.wikipedia.org/w/api.php?action=query&format=json&meta=tokens&formatversion=2&type=login'|jq .query.tokens.logintoken
curl -b cookies -d 'action=login&format=json&lgname=USERNAME&lgpassword=PASSWORD&formatversion=2&lgtoken=TOKEN%2B%5C' https://en.wikipedia.org/w/api.php|jq

As an aside, we had some trouble with HTTP2 the other day. The stock cURL on Ubuntu 16.04 seems to only support HTTP1.1. You can compile in support and run the above commands with --http2, I think.

New

curl -c cookies 'https://en.wikipedia.org/w/api.php?action=query&format=json&meta=tokens&formatversion=2&type=login'|jq .query.tokens.logintoken
curl -b cookies -d 'action=login&format=json&lgname=USERNAME&lgpassword=PASSWORD&formatversion=2&lgtoken=TOKEN%2B%5C' https://en.wikipedia.org/w/api.php|jq

Note that, unless you're using bot passwords (which you shouldn't be in the Android or iOS apps), that's now deprecated too in favor of action=clientlogin.