mirror of
https://github.com/OMGeeky/yup-oauth2.git
synced 2026-01-04 18:30:26 +01:00
Merge branch 'syntex' into next
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
language: rust
|
||||
sudo: required
|
||||
rust:
|
||||
- stable
|
||||
- nightly
|
||||
before_script:
|
||||
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
|
||||
|
||||
12
Cargo.toml
12
Cargo.toml
@@ -8,6 +8,7 @@ description = "A partial oauth2 implementation, providing the 'device' authoriza
|
||||
documentation = "http://byron.github.io/yup-oauth2"
|
||||
keywords = ["google", "oauth", "v2"]
|
||||
license = "MIT"
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
chrono = "*"
|
||||
@@ -18,7 +19,16 @@ url = "*"
|
||||
hyper = ">= 0.5.0"
|
||||
itertools = "*"
|
||||
serde = "*"
|
||||
serde_macros = "*"
|
||||
serde_macros = { version = "*", optional = true }
|
||||
|
||||
[features]
|
||||
default = ["with_syntex"]
|
||||
nightly = ["serde_macros"]
|
||||
with_syntex = ["serde_codegen", "syntex"]
|
||||
|
||||
[build-dependencies]
|
||||
syntex = { version = "*", optional = true }
|
||||
serde_codegen = { version = "*", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
getopts = "*"
|
||||
|
||||
11
Makefile
Normal file
11
Makefile
Normal file
@@ -0,0 +1,11 @@
|
||||
.PHONY = nightly
|
||||
|
||||
help:
|
||||
$(info -- Targets -- )
|
||||
$(info )
|
||||
$(info nightly - run cargo with nightly configuration, set ARGS to something like 'build'. rustc must be set to nightly)
|
||||
$(info _____________Note that for using stable, you can use cargo directly)
|
||||
$(info )
|
||||
|
||||
nightly:
|
||||
cargo $(ARGS) --no-default-features --features=nightly
|
||||
28
build.rs
Normal file
28
build.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
#[cfg(feature = "with_syntex")]
|
||||
mod inner {
|
||||
extern crate syntex;
|
||||
extern crate serde_codegen;
|
||||
|
||||
use std::env;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn main() {
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
|
||||
let src = Path::new("src/lib.rs.in");
|
||||
let dst = Path::new(&out_dir).join("lib.rs");
|
||||
|
||||
let mut registry = syntex::Registry::new();
|
||||
serde_codegen::register(&mut registry);
|
||||
registry.expand("yup-oauth2", &src, &dst).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "with_syntex"))]
|
||||
mod inner {
|
||||
pub fn main() {}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
inner::main()
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
#![feature(collections, exit_status)]
|
||||
#![allow(deprecated)]
|
||||
extern crate yup_oauth2 as oauth2;
|
||||
extern crate yup_hyper_mock as mock;
|
||||
extern crate hyper;
|
||||
@@ -17,15 +15,17 @@ use time::Duration;
|
||||
use std::thread::sleep_ms;
|
||||
|
||||
|
||||
fn usage(program: &str, opts: &Options, err: Option<Fail>) {
|
||||
fn usage(program: &str, opts: &Options, err: Option<Fail>) -> ! {
|
||||
if err.is_some() {
|
||||
println!("{}", err.unwrap());
|
||||
env::set_exit_status(1);
|
||||
std::process::exit(1);
|
||||
}
|
||||
println!("{}", opts.short_usage(program) + " SCOPE [SCOPE ...]");
|
||||
println!("{}", opts.usage("A program to authenticate against oauthv2 services.\n\
|
||||
See https://developers.google.com/youtube/registering_an_application\n\
|
||||
and https://developers.google.com/youtube/v3/guides/authentication#devices"));
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
@@ -36,18 +36,16 @@ fn main() {
|
||||
opts.opt("c", "id", "oauthv2 ID of your application", "CLIENT_ID", HasArg::Yes, Occur::Req)
|
||||
.opt("s", "secret", "oauthv2 secret of your application", "CLIENT_SECRET", HasArg::Yes, Occur::Req);
|
||||
|
||||
let m = match opts.parse(args.tail()) {
|
||||
let m = match opts.parse(&args[1..]) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
usage(&prog, &opts, Some(e));
|
||||
return
|
||||
}
|
||||
};
|
||||
|
||||
if m.free.len() == 0 {
|
||||
let msg = Fail::ArgumentMissing("you must provide one or more authorization scopes as free options".to_string());
|
||||
usage(&prog, &opts, Some(msg));
|
||||
return
|
||||
}
|
||||
|
||||
let secret = oauth2::ApplicationSecret {
|
||||
@@ -93,7 +91,7 @@ fn main() {
|
||||
},
|
||||
Err(err) => {
|
||||
println!("Access token wasn't obtained: {}", err);
|
||||
env::set_exit_status(10);
|
||||
std::process::exit(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,9 +339,14 @@ pub mod tests {
|
||||
use std::default::Default;
|
||||
use time::Duration;
|
||||
use hyper;
|
||||
use yup_hyper_mock::{SequentialConnector, MockStream};
|
||||
|
||||
mock_connector_in_order!(MockGoogleAuth {
|
||||
"HTTP/1.1 200 OK\r\n\
|
||||
pub struct MockGoogleAuth(SequentialConnector);
|
||||
|
||||
impl Default for MockGoogleAuth {
|
||||
fn default() -> MockGoogleAuth {
|
||||
let mut c = MockGoogleAuth(Default::default());
|
||||
c.0.content.push("HTTP/1.1 200 OK\r\n\
|
||||
Server: BOGUS\r\n\
|
||||
\r\n\
|
||||
{\r\n\
|
||||
@@ -350,23 +355,38 @@ pub mod tests {
|
||||
\"verification_url\" : \"http://www.google.com/device\",\r\n\
|
||||
\"expires_in\" : 1800,\r\n\
|
||||
\"interval\" : 0\r\n\
|
||||
}"
|
||||
"HTTP/1.1 200 OK\r\n\
|
||||
Server: BOGUS\r\n\
|
||||
\r\n\
|
||||
{\r\n\
|
||||
\"error\" : \"authorization_pending\"\r\n\
|
||||
}"
|
||||
"HTTP/1.1 200 OK\r\n\
|
||||
Server: BOGUS\r\n\
|
||||
\r\n\
|
||||
{\r\n\
|
||||
\"access_token\":\"1/fFAGRNJru1FTz70BzhT3Zg\",\r\n\
|
||||
\"expires_in\":3920,\r\n\
|
||||
\"token_type\":\"Bearer\",\r\n\
|
||||
\"refresh_token\":\"1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ\"\r\n\
|
||||
}"
|
||||
});
|
||||
}".to_string());
|
||||
|
||||
c.0.content.push("HTTP/1.1 200 OK\r\n\
|
||||
Server: BOGUS\r\n\
|
||||
\r\n\
|
||||
{\r\n\
|
||||
\"error\" : \"authorization_pending\"\r\n\
|
||||
}".to_string());
|
||||
|
||||
c.0.content.push("HTTP/1.1 200 OK\r\n\
|
||||
Server: BOGUS\r\n\
|
||||
\r\n\
|
||||
{\r\n\
|
||||
\"access_token\":\"1/fFAGRNJru1FTz70BzhT3Zg\",\r\n\
|
||||
\"expires_in\":3920,\r\n\
|
||||
\"token_type\":\"Bearer\",\r\n\
|
||||
\"refresh_token\":\"1/6BMfW9j53gdGImsixUH6kU5RsR4zwI9lUVX-tqf8JXQ\"\r\n\
|
||||
}".to_string());
|
||||
c
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
impl hyper::net::NetworkConnector for MockGoogleAuth {
|
||||
type Stream = MockStream;
|
||||
|
||||
fn connect(&self, host: &str, port: u16, scheme: &str) -> ::hyper::Result<MockStream> {
|
||||
self.0.connect(host, port, scheme)
|
||||
}
|
||||
|
||||
fn set_ssl_verifier(&mut self, _: hyper::net::ContextVerifier) {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn working_flow() {
|
||||
|
||||
@@ -446,8 +446,8 @@ pub trait AuthenticatorDelegate {
|
||||
/// * Will be called exactly once, provided we didn't abort during `request_code` phase.
|
||||
/// * Will only be called if the Authenticator's flow_type is `FlowType::Device`.
|
||||
fn present_user_code(&mut self, pi: &PollInformation) {
|
||||
println!{"Please enter {} at {} and grant access to this application",
|
||||
pi.user_code, pi.verification_url}
|
||||
println!("Please enter {} at {} and grant access to this application",
|
||||
pi.user_code, pi.verification_url);
|
||||
println!("Do not close this application until you either denied or granted access.");
|
||||
println!("You have time until {}.", pi.expires_at.with_timezone(&Local));
|
||||
}
|
||||
|
||||
35
src/lib.rs
35
src/lib.rs
@@ -13,8 +13,8 @@
|
||||
//! The returned `Token` should be stored permanently to authorize future API requests.
|
||||
//!
|
||||
//! ```test_harness,no_run
|
||||
//! #![feature(custom_derive, plugin)]
|
||||
//! #![plugin(serde_macros)]
|
||||
//! #![cfg_attr(feature = "nightly", feature(custom_derive, custom_attribute, plugin))]
|
||||
//! #![cfg_attr(feature = "nightly", plugin(serde_macros))]
|
||||
//! extern crate hyper;
|
||||
//! extern crate yup_oauth2 as oauth2;
|
||||
//! extern crate serde;
|
||||
@@ -60,30 +60,11 @@
|
||||
//! };
|
||||
//! # }
|
||||
//! ```
|
||||
#![feature(custom_derive, plugin)]
|
||||
#![plugin(serde_macros)]
|
||||
extern crate chrono;
|
||||
#![cfg_attr(feature = "nightly", feature(custom_derive, custom_attribute, plugin))]
|
||||
#![cfg_attr(feature = "nightly", plugin(serde_macros))]
|
||||
|
||||
#[macro_use]
|
||||
extern crate hyper;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[cfg(test)] #[macro_use]
|
||||
extern crate yup_hyper_mock as hyper_mock;
|
||||
extern crate mime;
|
||||
extern crate url;
|
||||
extern crate time;
|
||||
extern crate itertools;
|
||||
extern crate serde;
|
||||
#[cfg(feature = "nightly")]
|
||||
include!("lib.rs.in");
|
||||
|
||||
|
||||
mod device;
|
||||
mod refresh;
|
||||
mod common;
|
||||
mod helper;
|
||||
|
||||
pub use device::{DeviceFlow, PollInformation, PollError};
|
||||
pub use refresh::{RefreshFlow, RefreshResult};
|
||||
pub use common::{Token, FlowType, ApplicationSecret, ConsoleApplicationSecret, Scheme, TokenType};
|
||||
pub use helper::{TokenStorage, NullStorage, MemoryStorage, Authenticator,
|
||||
AuthenticatorDelegate, Retry, DefaultAuthenticatorDelegate, GetToken};
|
||||
#[cfg(feature = "with_syntex")]
|
||||
include!(concat!(env!("OUT_DIR"), "/lib.rs"));
|
||||
24
src/lib.rs.in
Normal file
24
src/lib.rs.in
Normal file
@@ -0,0 +1,24 @@
|
||||
extern crate serde;
|
||||
|
||||
extern crate chrono;
|
||||
|
||||
extern crate hyper;
|
||||
#[macro_use] #[cfg(test)]
|
||||
extern crate log;
|
||||
#[macro_use] #[cfg(test)]
|
||||
extern crate yup_hyper_mock;
|
||||
extern crate mime;
|
||||
extern crate url;
|
||||
extern crate time;
|
||||
extern crate itertools;
|
||||
|
||||
mod device;
|
||||
mod refresh;
|
||||
mod common;
|
||||
mod helper;
|
||||
|
||||
pub use device::{DeviceFlow, PollInformation, PollError};
|
||||
pub use refresh::{RefreshFlow, RefreshResult};
|
||||
pub use common::{Token, FlowType, ApplicationSecret, ConsoleApplicationSecret, Scheme, TokenType};
|
||||
pub use helper::{TokenStorage, NullStorage, MemoryStorage, Authenticator,
|
||||
AuthenticatorDelegate, Retry, DefaultAuthenticatorDelegate, GetToken};
|
||||
@@ -123,17 +123,35 @@ mod tests {
|
||||
use std::default::Default;
|
||||
use super::*;
|
||||
use super::super::FlowType;
|
||||
use yup_hyper_mock::{MockStream, SequentialConnector};
|
||||
|
||||
mock_connector_in_order!(MockGoogleRefresh {
|
||||
"HTTP/1.1 200 OK\r\n\
|
||||
Server: BOGUS\r\n\
|
||||
\r\n\
|
||||
{\r\n\
|
||||
\"access_token\":\"1/fFAGRNJru1FTz70BzhT3Zg\",\r\n\
|
||||
\"expires_in\":3920,\r\n\
|
||||
\"token_type\":\"Bearer\"\r\n\
|
||||
}"
|
||||
});
|
||||
struct MockGoogleRefresh(SequentialConnector);
|
||||
|
||||
impl Default for MockGoogleRefresh {
|
||||
fn default() -> MockGoogleRefresh {
|
||||
let mut c = MockGoogleRefresh(Default::default());
|
||||
c.0.content.push("HTTP/1.1 200 OK\r\n\
|
||||
Server: BOGUS\r\n\
|
||||
\r\n\
|
||||
{\r\n\
|
||||
\"access_token\":\"1/fFAGRNJru1FTz70BzhT3Zg\",\r\n\
|
||||
\"expires_in\":3920,\r\n\
|
||||
\"token_type\":\"Bearer\"\r\n\
|
||||
}".to_string());
|
||||
|
||||
c
|
||||
}
|
||||
}
|
||||
|
||||
impl hyper::net::NetworkConnector for MockGoogleRefresh {
|
||||
type Stream = MockStream;
|
||||
|
||||
fn connect(&self, host: &str, port: u16, scheme: &str) -> ::hyper::Result<MockStream> {
|
||||
self.0.connect(host, port, scheme)
|
||||
}
|
||||
|
||||
fn set_ssl_verifier(&mut self, _: hyper::net::ContextVerifier) {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn refresh_flow() {
|
||||
|
||||
Reference in New Issue
Block a user