Coder Social home page Coder Social logo

dermesser / yup-oauth2 Goto Github PK

View Code? Open in Web Editor NEW
208.0 9.0 110.0 5.51 MB

An oauth2 client implementation providing the Device, Installed, Service Account, and several more flows.

Home Page: https://docs.rs/yup-oauth2/

License: Apache License 2.0

Rust 99.26% Shell 0.74%
oauth2 google authorization

yup-oauth2's Introduction

Build Status crates.io

yup-oauth2 is a utility library which implements several OAuth 2.0 flows. It's mainly used by google-apis-rs, to authenticate against Google services. (However, you're able to use it with raw HTTP requests as well; the flows are implemented as token sources yielding HTTP Bearer tokens). Note that the newer, asynchronous versions of this crate (version 4) are not compatible with google-apis-rs anymore/at the moment.

To use asynchronous APIs with the new yup-oauth2 (from version 4), use the async-google-apis code generator, which generates asynchronous API stubs for Google APIs and other providers who provide Discovery documents for their REST APIs. (WARNING: that project is still alpha-quality. Contributions are welcome)

The provider we have been testing the code against is also Google. However, the code itself is generic, and any OAuth provider behaving like Google will work as well. If you find one that doesn't, please let us know and/or contribute a fix!

Supported authorization types

  • Device flow (user enters code on authorization page)
  • Installed application flow (user visits URL, copies code to application, application uses code to obtain token). Used for services like GMail, Drive, ...
  • Service account flow: Non-interactive authorization of server-to-server communication based on public key cryptography. Used for services like Cloud Pubsub, Cloud Storage, ...

Versions

  • Version 1.x for Hyper versions below 12
  • Version 2.x for Hyper versions 12 and above
  • Version 3.x for historical interest
  • Version 4.x for tokio 0.2/0.3
  • Version 5.x for tokio 1.0

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

yup-oauth2's People

Contributors

andreycizov avatar braincow avatar byron avatar chrisderock avatar ctaggart avatar dermesser avatar djc avatar djrodgerspryor avatar e-oz avatar edelangh avatar georgehahn avatar ggriffiniii avatar hakuyume avatar ignatenkobrain avatar imfede avatar ingwinlu avatar islandusurper avatar jneem avatar kendase3 avatar luketpeterson avatar lyonbeckers avatar markcatley avatar martell avatar mashedcode avatar nagisa avatar omgeeky avatar sanath-2024 avatar serprex avatar shadow53 avatar thebiggerguy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

yup-oauth2's Issues

Hyper 0.10.0 support (BorrowMut not implemented on hyper::Client)

Looks like hyper changed something in 0.10:

error[E0277]: the trait bound `hyper::Client: std::borrow::BorrowMut<hyper::client::Client>` is not satisfied
  --> src/main.rs:58:18                                                      
   | 
58 |     let access = oauth2::ServiceAccountAccess::new(client_secret, hyper::Client::new()); 
   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::borrow::BorrowMut<hyper::client::Client>` is not implemented for `hyper::Client`  
   | 
   = note: required by `<oauth2::ServiceAccountAccess<C>>::new`              

Service account look not working anymore

I just running the example and i got this message.

thread 'main' panicked at 'called Result::unwrap() on an Err value: StringError { error: "Token response lacks fields: TokenResponse { access_token: None, token_type: None, expires_in: None }" }', src/libcore/result.rs:1009:5

I also tried with my own JSON key without success.

Any idea to fix this issue?
Thanks for your help.

Compatability with Salesforce OAuth2

Hi,

I've been trying to get the Device Flow working with the Salesforce OAuth2 api. I've got it working but I've had to make some changes.

Before doing too much work on it I wondered how you wanted to handle these variances.

The changes roughly fall into the following categories:

  • Google calls a return field or uses some text that differs from the standard.
  • Salesforce uses some text that differs from the standard.
  • yup-oauth requires a field that is not required by the standard. Presumably, Google always provides it, but Salesforce does not.

Are you interested in accepting enhancements to allow connecting to other OAuth providers? I am guessing the main hard requirement is that we need to keep compatability with the google api. Is there anything else I need to keep in mind?

1.0.5 in git, but 1.0.7 on crates.io

Hello! I'm trying out yup-oauth2 and it looks interesting.

I noticed that the latest released version on crates.io was 1.0.7, but the latest on GitHub is 1.0.5. Thank you for building a useful Rust crate!

Use of Trait `Flow`

Hey guys,

Currently working with a fork of yup-oauth2 modified for another service and I wanted to upstream the changes and use the vanilla version.

Here is the basic usage of device-auth.

let ssl = hyper_native_tls::NativeTlsClient::new().unwrap();
    let connector = hyper::net::HttpsConnector::new(ssl);
    let client = hyper::Client::with_connector(connector);

    match oauth2::Authenticator::new(&secret, StdoutHandler, client, 
                                    oauth2::NullStorage, 
                                    Some(oauth2::FlowType::Device(String::from("https://deviceurl")))).token(&scope) {
        Ok(t) => {
            println!("Authentication granted!");
            println!("You should store the following information for use, or revoke it.");
            println!("All dates are given in UTC.");
            println!("{:?}", t);
        },
        Err(err) => {
            println!("Access token wasn't obtained: {}", err);
            std::process::exit(10);
        }
    }

I see the trait Flow with the function type_id implemented for DeviceFlow

impl<C> Flow for DeviceFlow<C> {
    fn type_id() -> FlowType {
        FlowType::Device(String::new())
    }
}

I first noticed that I can't use DeviceFlow as though it was a FlowType::Device
So I exported Flow in lib.rs

diff --git a/src/lib.rs b/src/lib.rs
index 38500f7..a6aff23 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -96,7 +96,7 @@ mod types;
 
 pub use device::{GOOGLE_DEVICE_CODE_URL, DeviceFlow};
 pub use refresh::{RefreshFlow, RefreshResult};
-pub use types::{Token, FlowType, ApplicationSecret, ConsoleApplicationSecret, Scheme, TokenType};
+pub use types::{Token, Flow, FlowType, ApplicationSecret, ConsoleApplicationSecret, Scheme, TokenType};
 pub use installed::{InstalledFlow, InstalledFlowReturnMethod};
 pub use storage::{TokenStorage, NullStorage, MemoryStorage, DiskTokenStorage};
 pub use authenticator::{Authenticator, Retry, GetToken};

I want to use it in this way

use oauth2::Flow;

let ssl = hyper_native_tls::NativeTlsClient::new().unwrap();
let connector = hyper::net::HttpsConnector::new(ssl);
let client = hyper::Client::with_connector(connector);

let mut flow = oauth2::DeviceFlow::new_device(client, &secret,
String::from("https://login.devicecode/blah"), Some(String::from("device_code")));

match oauth2::Authenticator::new(&secret, StdoutHandler, client,·
oauth2::NullStorage, Some(flow.type_id())).token(&scope) {

the function new_device is a modification of new with an added Option<String> so that we can set the grant_type. If no String is passed we default to http://oauth.net/grant_type/device/1.0 to keep the original functionality and new just wraps around this without passing the 4th argument.

My current error is

error: no method named `type_id` found for type `oauth2::DeviceFlow<hyper::Client>` in the current scope
note: found the following associated functions; to be used as methods, functions must have a `self` parameter
note: candidate #1 is defined in the trait `oauth2::Flow`

I haven't being using rust more then a week or so so I could be wrong but I assume I am trying to use this Trait in the correct manner?

tokio::spawn failed when getting token using GetToken future inside future 0.3

Getting service token from future 0.1 works perfectly fine, but it fails when called inside future 0.3 with compat(), this is the error:

ClientError(Error(User(Execute), "tokio::spawn failed (is a tokio runtime running this future?)"))

Code to reproduce the error:

Cargo.toml

[package]
name = "yup-auth"
version = "0.1.0"
edition = "2018"

[dependencies]
tokio = "0.2.0-alpha.6"
yup-oauth2 = "3.1.1"
futures-preview = { version = "0.3.0-alpha.19", features = ["compat"] }

src/main.rs

use futures::compat::Future01CompatExt;
use tokio::runtime;
use yup_oauth2::{self, GetToken, ServiceAccountAccess};

fn main() {
    let runtime = runtime::Builder::new()
        .core_threads(1)
        .name_prefix("oauth2")
        .build()
        .unwrap();

    let future = async move {
        let secret = yup_oauth2::service_account_key_from_file("clientsecret.json")
            .expect("clientsecret.json");

        let mut auth = ServiceAccountAccess::new(secret).build();

        let scope = "https://www.googleapis.com/auth/cloud-platform".to_string();
        let scopes = vec![scope];
        let token = auth
            .token(scopes)
            .compat()
            .await
            .expect("Couldn't get token");
        println!("{:?}", token);
    };

    runtime.block_on(future);
}

Go v1.0.0

This crate seems to be feature-complete enough to justify the big step upwards to 1.0. Feature-wise, the most common flows are available now.

When looking at the dependencies, there are still many below 1.0, but in a way this only affects their package maintainers as they essentially lose the patch-level in their version number (for sub-1-major packages, the minor version effectively becomes the major one when computing compatibility).

@dermesser Do you think it's OK going to 1.0 soon ?

Consider requiring `Send` on `GetToken.token()`s error type to ease use with `Failure`

The (fantastic!) downstream google* crates are slightly difficult to use with the failure crate ecosystem because their google_*::Error types don't automatically implement failure::Fail because they are !Sync and !Send because their google_*::Error:: MissingToken variant returns the error from yup_oauth2::GetToken::token(): Box<dyn std::error::Error>.

If yup_oauth2::GetToken::token()s error was also Send then google_*:Error would implement failure::Fail (it still would need to be Sync, but that's easily accomplished with the failure::SyncFailure helper).

Thanks for this useful set of crates!

Open to using a builder pattern?

I was thinking there could be an opportunity to improve the way authenticators are created and I was curious to hear if you would be in favor of the concept. To be clear I would plan on implementing the changes, but would like to hear your thoughts before I got started.

To give a rough proposal I believe creating an authenticator with the installed flow could look something like:

    let mut auth = Authenticator::new(
        InstalledFlow::new()
            .secret(secret)
            .return_method(InstalledFlowReturnMethod::HTTPRedirect),
    )
    .cache_tokens_to_disk("tokenstorage.json")
    .build()
    .expect("authenticator creation failed");

In this form the Authenticator would create an owned hyper client and use it for both the authenticator and installed flow. An optional method with_hyper would allow the user to provide their own hyper client. DeviceFlow would work similarly. This pattern could also allow removing the ability to create and use InstalledFlow and DeviceFlow without an authenticator, which in my opinion would be a good change to encourage proper use.

Do you feel this would be a welcome change?

Feature Request: Implement authorization flow for Service Accounts

The flow is described here: https://developers.google.com/identity/protocols/OAuth2ServiceAccount. It is especially interesting/necessary for Google Cloud Platform services, such as Cloud Pub/Sub, Compute Engine, Cloud Storage, etc.

tl;dr:

  • Get a Service Account key from the developer console
  • Sign a claim set (containing scope, app ID, ...) with that key, resulting in a JWT (JSON web token)
  • Request a token from https://www.googleapis.com/oauth2/v4/token using the signed JWT
  • Use the token; refresh if needed using the JWT.

The difficult part is probably generating the JWT signature, but it seems that https://crates.io/crates/jwt will do that for us.

I'll probably start working on this in the next few weeks, depending on the weather :o) (I'm posting this here just in case you or someone else wants to work on it or is already on it)

Token does not implement serde::de::Deserialize

... except that it does appear to...
In common.rs, I can see Deserialize inside the #derive attribute. But, this extremely simple sample code does not compile:

extern crate yup_oauth2;
extern crate serde_json;
use yup_oauth2::Token;

fn main() {
    serde_json::from_str::<Token>("");
}
src/main.rs:6:5: 6:34 error: the trait `serde::de::Deserialize` is not implemented for the type `yup_oauth2::common::Token` [E0277]
src/main.rs:6     serde_json::from_str::<Token>("");
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:6:5: 6:34 help: run `rustc --explain E0277` to see a detailed explanation
src/main.rs:6:5: 6:34 note: required by `serde_json::de::from_str`

Am I missing something obvious here?

Migrate to Stable and Serde 0.4.0

Have a look at this blog post for all the information you should need.

Once that is tried and tested, one could schedule it for one of the next releases of the google-apis, or at least provide the documentation needed to do it (it's a library afterall, don't know the details).

About self-hosted documentation

Hi,

I just noticed that by now, doc.rs seems to have matured to the point where it is really nice.

As you are publishing to crates.io, it automatically picks up the crate documentation, and looks quite good doing it.

Adopting it could simplify the .travis.yml script for example, and most importantly provide more value to the users.

What are your thoughts on this ?
Thank you

generalize AUTH URLs

After all, oauth is an open protocol, which is implemented by amazon as well.

This should be done soon, before the API collection comes out, as a signature change is likely to be happening.

yup-oauth2 doesn't compile on Rust nightly

Failure to compile on Rust nightlies since 2019-05-10. 2019-05-09 works, but come 2019-05-10 we receive:

error: expected expression, found `&&`
   --> /Users/john.stoneham/.cargo/registry/src/github.com-1ecc6299db9ec823/yup-oauth2-1.0.11/src/authenticator.rs:157:25
    |
157 |                         &&PollError::Expired(ref t) => {
    |                         ^^ expected expression
help: parentheses are required to parse this as an expression
    |
149 |                         &&PollError::HttpError(ref err) => ({
150 |                             match self.delegate.connection_error(err) {
151 |                                 Retry::Abort | Retry::Skip => {
152 |                                     return Err(Box::new(StringError::from(err as &Error)))
153 |                                 }
154 |                                 Retry::After(d) => sleep(d),
  ...

error: expected expression, found keyword `ref`
   --> /Users/john.stoneham/.cargo/registry/src/github.com-1ecc6299db9ec823/yup-oauth2-1.0.11/src/authenticator.rs:157:46
    |
157 |                         &&PollError::Expired(ref t) => {
    |                                              ^^^ expected expression

error: expected one of `,`, `.`, `?`, `}`, or an operator, found `=>`
   --> /Users/john.stoneham/.cargo/registry/src/github.com-1ecc6299db9ec823/yup-oauth2-1.0.11/src/authenticator.rs:157:53
    |
149 |                         &&PollError::HttpError(ref err) => {
    |                                                         -- while parsing the `match` arm starting here
...
157 |                         &&PollError::Expired(ref t) => {
    |                                                     ^^ expected one of `,`, `.`, `?`, `}`, or an operator here

error: aborting due to 3 previous errors

Consider exposing api dependencies in a module

Some of the public apis depend on a specific version of Hyper. I know that work is happening to fix that. I'm building a binary and just set all dependency versions to * (I know it's not recommended, but it's worked great since Cargo.lock is committed and we update every few weeks). The only exceptions to that are for hyper and subsequently hyper-rustls (I definitely use rustls over openssl whenever possible) and they have to line up with the yup-oauth2 dependencies.

I'll try to get a pull request together, but I think that something like

pub mod deps {
    pub mod hyper {
        pub use hyper::*;
    }
    pub mod hyper-rustls {
        pub use hyper_rustls::*;
    }
}

would work and then consumers would just do something like

    use yup_oauth2::deps::*;
    let key = yup_oauth2::ServiceAccountKey { ... }
    let authenticator = yup_oauth2::ServiceAccountAccess::new(
      key,
      hyper::Client::with_connector(hyper::net::HttpsConnector::new(hyper_rustls::TlsClient::new())),
    );
    let storage = Storage::new(
      hyper::Client::with_connector(hyper::net::HttpsConnector::new(hyper_rustls::TlsClient::new())),
      authenticator,
    );

This wouldn't be a breaking change because the library already depends on these specific versions. It would reduce friction when using them.

Is there any particular reason TokenStorage uses token scope hashes instead of subset matching

I am building a small app that does many things in Google Cloud. You can imagine it uses multiple scopes at the same time.

Right now, in order to authenticate against a set of scopes - I can use your lib to get the necessary token.

Now, google-apis-rs targets scopes one-by-one, for every call it makes. Which means that TokenStorage in yup-auth2 can't find them as it uses hashing of token scopes.

I would like to inquire if there is any particular reason this method is used and whether a pull request fixing this would make sense.

Support Application Default Credentials

I originally opened this over in google-apis-rs/generator#20, so let me know if you think this is a better fit for that project.

What do you think about supporting Application Default Credentials? To start we could just check GOOGLE_APPLICATION_CREDENTIALS.

Down the road, we could also communicate with the metadata server to automatically obtain credentials if GOOGLE_APPLICATION_CREDENTIALS wasn’t provided. This would obviously be more involved but I think reverse engineering this process from one of the official client libraries wouldn’t be too bad.

I envision adding a new top level function like: yup_oath2:: service_account_key_from_application_default_credentials, although that is rather verbose...

So the flow would be:

Try to use an explicitly provided service account.
If None, check GOOGLE_APPLICATION_CREDENTIALS
(Future work) If None, communicate with metadata server to use default service account
If still not found, Err.

One of the things I love about GCP (as opposed to AWS etc) is their authentication mechanism. It is so seamless and uniform across all their APIs. This would be a big step towards that UX.

Once we decide on a direction, I would be happy to open a PR.

unresolved name `form_urlencoded::serialize` [E0425]

I'm trying to compile google-drive3, but the build stops building one of it's dependencies -- yup-oauth2 -- using rustc-1.8 on debian testing. Any idea what might be wrong?

[cut1]/out/lib.rs:189:17: 189:43 error: unresolved name `form_urlencoded::serialize` [E0425]
[cut1]/out/lib.rs:189                 form_urlencoded::serialize(&[("client_id", client_id),
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:189:17: 189:43 help: run `rustc --explain E0425` to see a detailed explanation
[cut1]/out/lib.rs:588:17: 588:43 error: unresolved name `form_urlencoded::serialize` [E0425]
[cut1]/out/lib.rs:588                 form_urlencoded::serialize(&[("client_id", &self.id[..]),
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:588:17: 588:43 help: run `rustc --explain E0425` to see a detailed explanation
[cut1]/out/lib.rs:865:17: 865:43 error: unresolved name `form_urlencoded::serialize` [E0425]
[cut1]/out/lib.rs:865                 form_urlencoded::serialize(&[("client_id", client_id),
                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:865:17: 865:43 help: run `rustc --explain E0425` to see a detailed explanation
[cut1]/out/lib.rs:194:160: 194:164 error: the type of this value must be known in this context
[cut1]/out/lib.rs:194                 match self.client.borrow_mut().post(FlowType::Device.as_ref()).header(ContentType("application/x-www-form-urlencoded".parse().unwrap())).body(&*req).send()
                                                                                                                                                                                    ^~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:524:25: 524:58 error: the type of this value must be known in this context
[cut1]/out/lib.rs:524                         res.read_to_string(&mut json_str).unwrap();
                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:594:151: 594:155 error: the type of this value must be known in this context
[cut1]/out/lib.rs:594                 match self.client.borrow_mut().post(GOOGLE_TOKEN_URL).header(ContentType("application/x-www-form-urlencoded".parse().unwrap())).body(&*req).send()
                                                                                                                                                                           ^~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:602:25: 602:58 error: the type of this value must be known in this context
[cut1]/out/lib.rs:602                         res.read_to_string(&mut json_str).unwrap();
                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:593:17: 593:25 error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277]
[cut1]/out/lib.rs:593             let json_str =
                                      ^~~~~~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:593:17: 593:25 help: run `rustc --explain E0277` to see a detailed explanation
[cut1]/out/lib.rs:593:17: 593:25 note: `str` does not have a constant size known at compile-time
[cut1]/out/lib.rs:593:17: 593:25 note: all local variables must have a statically known size
[cut1]/out/lib.rs:871:151: 871:155 error: the type of this value must be known in this context
[cut1]/out/lib.rs:871                 match self.client.borrow_mut().post(GOOGLE_TOKEN_URL).header(ContentType("application/x-www-form-urlencoded".parse().unwrap())).body(&*req).send()
                                                                                                                                                                           ^~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:879:25: 879:58 error: the type of this value must be known in this context
[cut1]/out/lib.rs:879                         res.read_to_string(&mut json_str).unwrap();
                                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:870:17: 870:25 error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277]
[cut1]/out/lib.rs:870             let json_str =
                                      ^~~~~~~~
[cut0]//src/lib.rs:71:1: 71:47 note: in this expansion of include!
[cut1]/out/lib.rs:870:17: 870:25 help: run `rustc --explain E0277` to see a detailed explanation
[cut1]/out/lib.rs:870:17: 870:25 note: `str` does not have a constant size known at compile-time
[cut1]/out/lib.rs:870:17: 870:25 note: all local variables must have a statically known size

Nightly changes to type parameter lifetime constraints breaks yup-oauth2

It appears that Rust nightly requires the type parameter to have a lifetime constraint, as opposed to beta, where it just prints a warning:

Nightly:

mk@maero /tmp/yup-oauth2 % multirust run nightly cargo test                                                                                                                                                                           (master)
   Compiling yup-oauth2 v0.5.2 (file:///tmp/yup-oauth2)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 error: the parameter type `T` may not live long enough [E0309]
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180         pub fn request_code<'b, T,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:181                             I>(&mut self, client_id: &str,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:182                                client_secret: &str, scopes: I)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:183          -> Result<PollInformation, RequestError> where T: AsRef<str>,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:184          I: IntoIterator<Item = &'b T> {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:185             if self.state.is_some() {
                                                                              ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 help: run `rustc --explain E0309` to see a detailed explanation
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 help: consider adding an explicit lifetime bound `T: 'b`...
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 note: ...so that the reference type `&'b T` does not outlive the data it points at
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180         pub fn request_code<'b, T,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:181                             I>(&mut self, client_id: &str,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:182                                client_secret: &str, scopes: I)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:183          -> Result<PollInformation, RequestError> where T: AsRef<str>,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:184          I: IntoIterator<Item = &'b T> {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:185             if self.state.is_some() {
                                                                              ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 error: the parameter type `T` may not live long enough [E0309]
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180         pub fn request_code<'b, T,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:181                             I>(&mut self, client_id: &str,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:182                                client_secret: &str, scopes: I)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:183          -> Result<PollInformation, RequestError> where T: AsRef<str>,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:184          I: IntoIterator<Item = &'b T> {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:185             if self.state.is_some() {
                                                                              ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 help: run `rustc --explain E0309` to see a detailed explanation
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 help: consider adding an explicit lifetime bound `T: 'b`...
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 note: ...so that the reference type `&'b T` does not outlive the data it points at
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180         pub fn request_code<'b, T,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:181                             I>(&mut self, client_id: &str,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:182                                client_secret: &str, scopes: I)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:183          -> Result<PollInformation, RequestError> where T: AsRef<str>,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:184          I: IntoIterator<Item = &'b T> {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:185             if self.state.is_some() {
                                                                              ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563:9: 2570:16 error: the parameter type `T` may not live long enough [E0309]
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563         fn token<'b, I, T>(&mut self, scopes: I)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2564         -> Result<Token, Box<Error>>
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2565         where
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2566         T: AsRef<str> +
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2567         Ord,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2568         I: IntoIterator<Item
                                                                               ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563:9: 2570:16 help: run `rustc --explain E0309` to see a detailed explanation
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563:9: 2570:16 help: consider adding an explicit lifetime bound `T: 'b`...
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563:9: 2570:16 note: ...so that the reference type `&'b T` does not outlive the data it points at
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563         fn token<'b, I, T>(&mut self, scopes: I)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2564         -> Result<Token, Box<Error>>
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2565         where
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2566         T: AsRef<str> +
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2567         Ord,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2568         I: IntoIterator<Item
                                                                               ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683:9: 2819:10 error: the parameter type `T` may not live long enough [E0309]
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683         fn token<'b, I, T>(&mut self, scopes: I) -> Result<Token, Box<Error>>
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2684          where T: AsRef<str> + Ord, I: IntoIterator<Item = &'b T> {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2685             let (scope_key, scopes) =
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2686                 {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2687                     let mut sv: Vec<&str> =
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2688                         scopes.into_iter().map(|s|
                                                                               ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683:9: 2819:10 help: run `rustc --explain E0309` to see a detailed explanation
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683:9: 2819:10 help: consider adding an explicit lifetime bound `T: 'b`...
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683:9: 2819:10 note: ...so that the reference type `&'b T` does not outlive the data it points at
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683         fn token<'b, I, T>(&mut self, scopes: I) -> Result<Token, Box<Error>>
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2684          where T: AsRef<str> + Ord, I: IntoIterator<Item = &'b T> {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2685             let (scope_key, scopes) =
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2686                 {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2687                     let mut sv: Vec<&str> =
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2688                         scopes.into_iter().map(|s|
                                                                               ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
error: aborting due to 3 previous errors
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563:9: 2570:16 error: the parameter type `T` may not live long enough [E0309]
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563         fn token<'b, I, T>(&mut self, scopes: I)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2564         -> Result<Token, Box<Error>>
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2565         where
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2566         T: AsRef<str> +
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2567         Ord,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2568         I: IntoIterator<Item
                                                                               ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563:9: 2570:16 help: run `rustc --explain E0309` to see a detailed explanation
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563:9: 2570:16 help: consider adding an explicit lifetime bound `T: 'b`...
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563:9: 2570:16 note: ...so that the reference type `&'b T` does not outlive the data it points at
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2563         fn token<'b, I, T>(&mut self, scopes: I)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2564         -> Result<Token, Box<Error>>
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2565         where
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2566         T: AsRef<str> +
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2567         Ord,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2568         I: IntoIterator<Item
                                                                               ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
Build failed, waiting for other jobs to finish...
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683:9: 2819:10 error: the parameter type `T` may not live long enough [E0309]
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683         fn token<'b, I, T>(&mut self, scopes: I) -> Result<Token, Box<Error>>
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2684          where T: AsRef<str> + Ord, I: IntoIterator<Item = &'b T> {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2685             let (scope_key, scopes) =
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2686                 {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2687                     let mut sv: Vec<&str> =
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2688                         scopes.into_iter().map(|s|
                                                                               ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683:9: 2819:10 help: run `rustc --explain E0309` to see a detailed explanation
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683:9: 2819:10 help: consider adding an explicit lifetime bound `T: 'b`...
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683:9: 2819:10 note: ...so that the reference type `&'b T` does not outlive the data it points at
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2683         fn token<'b, I, T>(&mut self, scopes: I) -> Result<Token, Box<Error>>
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2684          where T: AsRef<str> + Ord, I: IntoIterator<Item = &'b T> {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2685             let (scope_key, scopes) =
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2686                 {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2687                     let mut sv: Vec<&str> =
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:2688                         scopes.into_iter().map(|s|
                                                                               ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
error: aborting due to 3 previous errors
Could not compile `yup-oauth2`.

Beta:

mk@maero /tmp/yup-oauth2 % multirust run beta cargo test
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 warning: the parameter type `T` may not live long enough [E0309]
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180         pub fn request_code<'b, T,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:181                             I>(&mut self, client_id: &str,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:182                                client_secret: &str, scopes: I)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:183          -> Result<PollInformation, RequestError> where T: AsRef<str>,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:184          I: IntoIterator<Item = &'b T> {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:185             if self.state.is_some() {
                                                                              ...
src/lib.rs:71:1: 71:47 note: in this expansion of include!
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 help: run `rustc --explain E0309` to see a detailed explanation
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 help: consider adding an explicit lifetime bound `T: 'b`...
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180:9: 549:10 note: this warning results from recent bug fixes and clarifications; it will become a HARD ERROR in the next release. See RFC 1214 for details.
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:180         pub fn request_code<'b, T,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:181                             I>(&mut self, client_id: &str,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:182                                client_secret: &str, scopes: I)
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:183          -> Result<PollInformation, RequestError> where T: AsRef<str>,
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:184          I: IntoIterator<Item = &'b T> {
/tmp/yup-oauth2/target/debug/build/yup-oauth2-e7d5cdf4504b56ef/out/lib.rs:185             if self.state.is_some() {
                                                                              ...
etc…

Build fails on OS X < 10.11

yup-oauth2 fails to build on Travis CI OS X workers:

   Compiling yup-oauth2 v0.5.4
     Running `/Users/travis/build/programble/fresh/target/debug/build/yup-oauth2-6fcf5dac526993e1/build-script-build`
Build failed, waiting for other jobs to finish...
failed to run custom build command for `yup-oauth2 v0.5.4`
Process didn't exit successfully: `/Users/travis/build/programble/fresh/target/debug/build/yup-oauth2-6fcf5dac526993e1/build-script-build` (signal: 11)
--- stderr
thread '<main>' has overflowed its stack

https://travis-ci.org/programble/fresh/jobs/107171816

This seems to be the only place this happens. Building locally on OS X works fine.

Relicense under dual MIT/Apache-2.0

This issue was automatically generated. Feel free to close without ceremony if
you do not agree with re-licensing or if it is not possible for other reasons.
Respond to @cmr with any questions or concerns, or pop over to
#rust-offtopic on IRC to discuss.

You're receiving this because someone (perhaps the project maintainer)
published a crates.io package with the license as "MIT" xor "Apache-2.0" and
the repository field pointing here.

TL;DR the Rust ecosystem is largely Apache-2.0. Being available under that
license is good for interoperation. The MIT license as an add-on can be nice
for GPLv2 projects to use your code.

Why?

The MIT license requires reproducing countless copies of the same copyright
header with different names in the copyright field, for every MIT library in
use. The Apache license does not have this drawback. However, this is not the
primary motivation for me creating these issues. The Apache license also has
protections from patent trolls and an explicit contribution licensing clause.
However, the Apache license is incompatible with GPLv2. This is why Rust is
dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for
GPLv2 compat), and doing so would be wise for this project. This also makes
this crate suitable for inclusion and unrestricted sharing in the Rust
standard distribution and other projects using dual MIT/Apache, such as my
personal ulterior motive, the Robigalia project.

Some ask, "Does this really apply to binary redistributions? Does MIT really
require reproducing the whole thing?" I'm not a lawyer, and I can't give legal
advice, but some Google Android apps include open source attributions using
this interpretation. Others also agree with
it
.
But, again, the copyright notice redistribution is not the primary motivation
for the dual-licensing. It's stronger protections to licensees and better
interoperation with the wider Rust ecosystem.

How?

To do this, get explicit approval from each contributor of copyrightable work
(as not all contributions qualify for copyright, due to not being a "creative
work", e.g. a typo fix) and then add the following to your README:

## License

Licensed under either of

 * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
 * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)

at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.

and in your license headers, if you have them, use the following boilerplate
(based on that used in Rust):

// Copyright 2016 yup-oauth2 Developers
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

It's commonly asked whether license headers are required. I'm not comfortable
making an official recommendation either way, but the Apache license
recommends it in their appendix on how to use the license.

Be sure to add the relevant LICENSE-{MIT,APACHE} files. You can copy these
from the Rust repo for a plain-text
version.

And don't forget to update the license metadata in your Cargo.toml to:

license = "MIT OR Apache-2.0"

I'll be going through projects which agree to be relicensed and have approval
by the necessary contributors and doing this changes, so feel free to leave
the heavy lifting to me!

Contributor checkoff

To agree to relicensing, comment with :

I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option.

Or, if you're a contributor, you can check the box in this repo next to your
name. My scripts will pick this exact phrase up and check your checkbox, but
I'll come through and manually review this issue later as well.

Rename this crate to a more fitting identifier

The current name, yup-oauth2 stems from the original intention to a very specialised implementation of the oauth2 protocol needed to get a youtube uploader going.

By now, this crate has become so much more that the name seems inadequate.

@dermesser Do you agree to this premise, and if so, maybe you have some suggestions for a new name too ?

Compiling with serde 1.0.5/serde_json 1.0.2

I am using the standard example code for reading a file with the application secret.
Code:
let f = File::open("client_secret.json").expect("Did not find client_secret.json"); let secret = json::from_reader::<File, ConsoleApplicationSecret>(f).expect("Error in parsing").installed.expect("Error in parsing");

I tried to debug it myself but I am kind of stuck as the tests of this repository with the serde versions changed did not produce this error.

Error Message:
102 | let secret = json::from_reader::<File, ConsoleApplicationSecret>(f).expect("Error in parsing").installed.expect("Error in parsing"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait for<'de> serde::Deserialize<'de> is not implemented for oauth2::ConsoleApplicationSecret | = note: required because of the requirements on the impl of serde::de::DeserializeOwned for oauth2::ConsoleApplicationSecret = note: required by serde_json::from_reader

Changing it to and include_str! and using json::from_str gives the probably related error:
let secret = json::from_str::<ConsoleApplicationSecret>(include_str!("../client_secret.json")).expect("Error in parsing").installed.expect("Error in parsing"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait serde::Deserialize<'_> is not implemented for oauth2::ConsoleApplicationSecret | = note: required by serde_json::from_str

&String is the worst parameter type.

service_account_key_from_file() takes &String, but it should probably be &str to avoid unnecessary allocations.

Callers can pass a &String, and it will auto-ref to &str. But I don't think most users will have a String to take a reference in the first place. More likely, they'd follow the example and have a hard-coded file path in a static string slice.

Clarification on hyper version regarding google apis

Hi,

I have a question regarding the relation of versions of hyper and the google apis:

yup-oauth2 claims the following:

Version 1.x for Hyper versions bellow 12 Version 2.x for Hyper versions 12 and above

The google-apis-rs currently claim hyper 0.10

Am I right that I cannot use yup-oauth2 > 1.x in conjunction with one of the google apis crates in one crate since I would need different hyper versions?
The yup-oauth2 examples all refer to v1.x and I think it's currently not possible to update them until google-api-rs is upgraded too. Correct me if I'm wrong.

There is a open issues on updating google-api-rs.

Thanks!

@flxo

Merge branch `futures` into `master` and release v3.0

The new asynchronous version is almost ready with improved test coverage of the individual flows etc.

Things missing:

  • Investigate usefulness of tests for Authenticator
  • Update README.md explaining various versions, add readme = statement to Cargo.toml
  • Write Authenticator example in lib.rs (fulfill TODO)
  • Add documentation to InstalledFlow, FlowDelegate, etc.
  • Create branch v2.0 in order to be able to keep releasing improvements to that version
  • Merge and push branch futures

Server-side oauth flow

Hi there!

There is no Server-side oauth flow implemented in this library. While implementing a custom solution for myself I wanted to ask if there were any discussions about implementing server-side flow?

If not - I can help with that. But overall library implementation won't fit for this flow (as far as I could understand from spending some time with sources of this library). If somebody is open to collaborating on it - I will be glad to contribute

Please publish 1.0.8 which would be consistent with git

diff -uNr /home/brain/rpmbuild/BUILD/yup-oauth2-1.0.7/src/lib.rs src/lib.rs
--- /home/brain/rpmbuild/BUILD/yup-oauth2-1.0.7/src/lib.rs	2018-03-24 20:27:56.000000000 +0100
+++ src/lib.rs	2018-07-25 23:07:26.165505192 +0200
@@ -39,6 +39,7 @@
 //! extern crate serde_derive;
 //! 
 //! extern crate hyper;
+//! extern crate hyper_rustls;
 //! extern crate yup_oauth2 as oauth2;
 //! extern crate serde;
 //! extern crate serde_json;
@@ -46,12 +47,14 @@
 //! use oauth2::{Authenticator, DefaultAuthenticatorDelegate, PollInformation, ConsoleApplicationSecret, MemoryStorage, GetToken};
 //! use serde_json as json;
 //! use std::default::Default;
+//! use hyper::{Client, net::HttpsConnector};
+//! use hyper_rustls::TlsClient;
 //! # const SECRET: &'static str = "{\"installed\":{\"auth_uri\":\"https://accounts.google.com/o/oauth2/auth\",\"client_secret\":\"UqkDJd5RFwnHoiG5x5Rub8SI\",\"token_uri\":\"https://accounts.google.com/o/oauth2/token\",\"client_email\":\"\",\"redirect_uris\":[\"urn:ietf:wg:oauth:2.0:oob\",\"oob\"],\"client_x509_cert_url\":\"\",\"client_id\":\"14070749909-vgip2f1okm7bkvajhi9jugan6126io9v.apps.googleusercontent.com\",\"auth_provider_x509_cert_url\":\"https://www.googleapis.com/oauth2/v1/certs\"}}";
 //!
 //! # #[test] fn device() {
 //! let secret = json::from_str::<ConsoleApplicationSecret>(SECRET).unwrap().installed.unwrap();
 //! let res = Authenticator::new(&secret, DefaultAuthenticatorDelegate,
-//!                         hyper::Client::new(),
+//!                         Client::with_connector(HttpsConnector::new(TlsClient::new())),
 //!                         <MemoryStorage as Default>::default(), None)
 //!                         .token(&["https://www.googleapis.com/auth/youtube.upload"]);
 //! match res {

This is diff between archive from crates.io and the github. Would be nice if you would publish same version in there.

Use rust-serde for json serialization

This will make it easier to maintain, after all, rust-serde is used by google-rust-apis.

This will also allow pretty-printing of our common structures, like the ConsoleApplicationSecret (-> use in google-apis-rs when serializing Token/Secret).

Service account look not working anymore

I just running the example and i got this message.

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: StringError { error: "Token response lacks fields: TokenResponse { access_token: None, token_type: None, expires_in: None }" }', src/libcore/result.rs:860:4

I also tried with my own JSON key without success.

Any idea to fix this issue?
Thanks for your help.

Does not compile with serde 0.10

Currently, if you try to compile with serde 0.10 compilation fails with the following error:

error[E0277]: the trait boundoauth2::ApplicationSecret: serde::Deserializeis not satisfied --> src/main.rs:90:18 | 90 | let secret = json::from_reader::<File,ApplicationSecret>(f).unwrap().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the traitserde::Deserializeis not implemented foroauth2::ApplicationSecret

Treat about to expire tokens as expired

Authenticator::token either retrieves a new token or a cached one if it’s not expired. As it is responsible for refreshing tokens it is reasonable to assume any token it provides is fresh. However, if the cached token is going to imminently expire it is possible for it to provide a token that becomes useless before it can be used (either the client is too slow or the client and servers clocks are off).

If instead it treats any cached token with say < 1 minute left on the lifespan as being already expired It doesn't meaningfully increase the number of refreshes but make it far more likely the token provided is actually useful.

Switch to hyper-tls?

We want to package yup-oauth2 for Fedora, however it depends on rustls which depends on ring and we would like to avoid packaging yet another crypto library. It would be very nice if you could switch to hyper-tls. Or if you don't want to port to hyper 0.12, you could use hyper-native-tls.

Cannot use `DiskTokenStorage` default implementation

Hello,
I'm a rustacean newbie, and I'm trying to authenticate using DiskTokenStorage.

let auth = Authenticator::new(&secret, MyDelegate,
                                  hyper::Client::new(),
                                  DiskTokenStorage::default(), 
                                  Some(oauth2::FlowType::InstalledInteractive));

However, I get the error: "No such file or directory". I looked at the source code, and couldn't locate where the default location is being set. Let's say if I want to create a new DiskTokenStorage passing a custom location, I would have to implement the TokenStorage trait again, which it feels unnecessary.

I'm probably doing some trivial mistake, but I cannot find it where.

Many thanks!

Move to std::future::Future

I'm sure you're aware that a new release of rust is imminent with async/await support. Hyper, tokio, and other libraries used by this crate are migrating to std::future::Future to fully support the new syntax. Are there any plans to migrate this crate to std::future::Future? I expect the rest of the ecosystem to migrate to the new trait relatively quickly once async/await support lands on stable in a couple days. Would you be open to a PR that moves to the latest hyper, tokio, and Future?

Unable to use programmatic_auth not possible

Using programmatic_auth as auth_uri it failes to generate a correct URL.

redirect_uri and response_type aren't allowed but they get added using FlowType::InstalledInteractive.

Google says Parameter not allowed for this message type: redirect_uri and Parameter not allowed for this message type: response_type

also the scopes need to be devided by a + instead of spaces.

After that it would be nice to get the code which is in the cookie "oauth_token".

This is needed for generating the correct token for using the hangouts chat api (see hangups). Idea is to do automatic logins/auths. 100% from CLI

Did I miss something?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.