dermesser/yup-oauth2

DeviceFlow failing

Opened this issue · 1 comments

I am unsure if this is an issue with Google's backend or this library, but the DeviceFlow stopped working for me:

let secret =
    yup_oauth2::parse_application_secret(include_bytes!("../../youtube_client_secret.json"))
        .expect("youtube application secret");
let hyper_client =
    hyper::Client::builder().build(hyper_rustls::HttpsConnector::with_native_roots());
let auth = yup_oauth2::DeviceFlowAuthenticator::builder(secret)
    .hyper_client(hyper_client.clone())
    .persist_tokens_to_disk("youtube_token_cache.json")
    .build()
    .await
    .expect("youtube authenticator");

let scopes = &["https://www.googleapis.com/auth/youtube.readonly"];
auth.token(scopes).await.expect("authenticator token"); //<-- this fails

It fails with the following error:

thread 'main' panicked at 'authenticator token: JSONError(Error("data did not match any variant of untagged enum AuthErrorOr", line: 0, column: 0))', src/util/mod.rs:28:30
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

When enabling the debug logger, I get the following (redacted):

[2021-06-25T14:16:22Z DEBUG yup_oauth2::device] received response; head: Parts { status: 200, version: HTTP/2.0, headers: {"cache-control": "no-cache, no-store, max-age=0, must-revalidate", "date": "Fri, 25 Jun 2021 14:16:22 GMT", "pragma": "no-cache", "expires": "Mon, 01 Jan 1990 00:00:00 GMT", "content-type": "application/json; charset=utf-8", "vary": "X-Origin", "vary": "Referer", "vary": "Origin,Accept-Encoding", "server": "ESF", "x-xss-protection": "0", "x-frame-options": "SAMEORIGIN", "x-content-type-options": "nosniff", "alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-T051=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"", "accept-ranges": "none"} }, body: b"{\n  \"device_code\": \"******************\",\n  \"user_code\": \"****-****\",\n  \"expires_in\": 1800,\n  \"interval\": 5,\n  \"verification_url\": \"https://www.google.com/device\"\n}"

This body is then parsed into a DeviceAuthResponse which causes the error, because DeviceAuthResponse contains expires_at instead of expires_in: https://developers.google.com/identity/protocols/oauth2/limited-input-device#step-2:-handle-the-authorization-server-response

EDIT: The issue I've encountered below was actually #161

I'm running into a suspiciously similar problem but with the ServiceAccount flow.

My token looks like:

{"timestamp":"Aug 12 19:08:11.303","level":"DEBUG","fields":{"message":"received response; head: Parts { status: 200, version: HTTP/2.0, headers: {\"content-type\": \"application/json; charset=UTF-8\", \"vary\": \"X-Origin\", \"vary\": \"Referer\", \"vary\": \"Origin,Accept-Encoding\", \"date\": \"Thu, 12 Aug 2021 18:08:11 GMT\", \"server\": \"scaffolding on HTTPServer2\", \"cache-control\": \"private\", \"x-xss-protection\": \"0\", \"x-frame-options\": \"SAMEORIGIN\", \"x-content-type-options\": \"nosniff\", \"alt-svc\": \"h3=\\\":443\\\"; ma=2592000,h3-29=\\\":443\\\"; ma=2592000,h3-T051=\\\":443\\\"; ma=2592000,h3-Q050=\\\":443\\\"; ma=2592000,h3-Q046=\\\":443\\\"; ma=2592000,h3-Q043=\\\":443\\\"; ma=2592000,quic=\\\":443\\\"; ma=2592000; v=\\\"46,43\\\"\", \"accept-ranges\": \"none\"} }, body: b\"{\\\"access_token\\\":\\\"************\\\",\\\"expires_in\\\":3599,\\\"token_type\\\":\\\"Bearer\\\"}\"","log.target":"yup_oauth2::service_account","log.module_path":"yup_oauth2::service_account","target":"yup_oauth2::service_account"}

(i.e. it has an access_token, an expires_in and a token_type)

However, this fails with

JSON Error; this might be a bug with unexpected server responses! data did not match any variant of untagged enum AuthErrorOr

This doesn't make sense to me given my reading of the code so I'm very confused. Weirdly enough if I replace

        } = serde_json::from_slice::<AuthErrorOr<RawToken>>(json_data)?.into_result()?;

with

        } = serde_json::from_slice::<RawToken>(json_data)?;

then the error goes away. Could this be some kind of serde bug?

@dermesser Would appreciate if you have any ideas for this issue? Let me know if you need any more information.