Skip to content

Commit

Permalink
Merge branch 'next'
Browse files Browse the repository at this point in the history
Update to 0.3.2
  • Loading branch information
Byron committed Apr 7, 2015
2 parents 0b196b7 + 2489b81 commit fec6113
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 15 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]

name = "yup-oauth2"
version = "0.3.0"
version = "0.3.2"
authors = ["Sebastian Thiel <byronimo@gmail.com>"]
repository = "https://github.com/Byron/yup-oauth2"
description = "A partial oauth2 implementation, providing the 'device' authorization flow"
Expand All @@ -20,5 +20,5 @@ rustc-serialize = "*"

[dev-dependencies]
getopts = "*"
yup-hyper-mock = ">= 0.1.3"
yup-hyper-mock = ">= 0.1.4"
open = "*"
80 changes: 79 additions & 1 deletion src/common.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,73 @@
use chrono::{DateTime, UTC, TimeZone};
use std::marker::MarkerTrait;
use std::fmt;
use std::str::FromStr;
use hyper;

/// A marker trait for all Flows
pub trait Flow : MarkerTrait {
fn type_id() -> FlowType;
}

/// Represents all implemented token types
#[derive(Clone, PartialEq, Debug)]
pub enum TokenType {
/// Means that whoever bears the access token will be granted access
Bearer,
}

impl Str for TokenType {
fn as_slice(&self) -> &'static str {
match *self {
TokenType::Bearer => "Bearer"
}
}
}

impl FromStr for TokenType {
type Err = ();
fn from_str(s: &str) -> Result<TokenType, ()> {
match s {
"Bearer" => Ok(TokenType::Bearer),
_ => Err(())
}
}
}


/// A scheme for use in `hyper::header::Authorization`
#[derive(Clone, PartialEq, Debug)]
pub struct Scheme {
/// The type of our access token
pub token_type: TokenType,
/// The token returned by one of the Authorization Flows
pub access_token: String
}

impl hyper::header::Scheme for Scheme {
fn scheme() -> Option<&'static str> {
None
}

fn fmt_scheme(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.token_type.as_slice(), self.access_token)
}
}

impl FromStr for Scheme {
type Err = &'static str;
fn from_str(s: &str) -> Result<Scheme, &'static str> {
let parts: Vec<&str> = s.split(' ').collect();
if parts.len() != 2 {
return Err("Expected two parts: <token_type> <token>")
}
match <TokenType as FromStr>::from_str(parts[0]) {
Ok(t) => Ok(Scheme { token_type: t, access_token: parts[1].to_string() }),
Err(_) => Err("Couldn't parse token type")
}
}
}

/// Represents a token as returned by OAuth2 servers.
///
/// It is produced by all authentication flows.
Expand Down Expand Up @@ -66,7 +128,7 @@ impl Token {
}

/// All known authentication types, for suitable constants
#[derive(Copy)]
#[derive(Clone, Copy)]
pub enum FlowType {
/// [device authentication](https://developers.google.com/youtube/v3/guides/authentication#devices)
Device,
Expand Down Expand Up @@ -116,6 +178,7 @@ pub struct ConsoleApplicationSecret {
#[cfg(test)]
pub mod tests {
use super::*;
use hyper;

pub 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\"}}";

Expand All @@ -127,4 +190,19 @@ pub mod tests {
Err(err) => panic!(err),
}
}

#[test]
fn schema() {
let s = Scheme {token_type: TokenType::Bearer, access_token: "foo".to_string() };
let mut headers = hyper::header::Headers::new();
headers.set(hyper::header::Authorization(s));
assert_eq!(headers.to_string(), "Authorization: Bearer foo\r\n".to_string());
}

#[test]
fn parse_schema() {
let auth: hyper::header::Authorization<Scheme> = hyper::header::Header::parse_header(&[b"Bearer foo".to_vec()]).unwrap();
assert_eq!(auth.0.token_type, TokenType::Bearer);
assert_eq!(auth.0.access_token, "foo".to_string());
}
}
11 changes: 6 additions & 5 deletions src/device.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::iter::IntoIterator;
use std::time::Duration;
use std::default::Default;
use std::rc::Rc;

use hyper;
use hyper::header::ContentType;
Expand Down Expand Up @@ -61,7 +62,7 @@ pub struct PollInformation {
#[derive(Clone)]
pub enum RequestResult {
/// Indicates connection failure
Error(hyper::HttpError),
Error(Rc<hyper::HttpError>),
/// The OAuth client was not found
InvalidClient,
/// Some requested scopes were invalid. String contains the scopes as part of
Expand All @@ -85,7 +86,7 @@ impl RequestResult {
#[derive(Clone)]
pub enum PollResult {
/// Connection failure - retry if you think it's worth it
Error(hyper::HttpError),
Error(Rc<hyper::HttpError>),
/// See `PollInformation`
AuthorizationPending(PollInformation),
/// indicates we are expired, including the expiration date
Expand All @@ -98,7 +99,7 @@ pub enum PollResult {

impl Default for PollResult {
fn default() -> PollResult {
PollResult::Error(hyper::HttpError::HttpStatusError)
PollResult::Error(Rc::new(hyper::HttpError::HttpStatusError))
}
}

Expand Down Expand Up @@ -166,7 +167,7 @@ impl<C, NC> DeviceFlow<C, NC>
.body(req.as_slice())
.send() {
Err(err) => {
return RequestResult::Error(err);
return RequestResult::Error(Rc::new(err));
}
Ok(mut res) => {

Expand Down Expand Up @@ -266,7 +267,7 @@ impl<C, NC> DeviceFlow<C, NC>
.body(req.as_slice())
.send() {
Err(err) => {
return PollResult::Error(err);
return PollResult::Error(Rc::new(err));
}
Ok(mut res) => {
let mut json_str = String::new();
Expand Down
6 changes: 3 additions & 3 deletions src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl<D, S, C, NC> Authenticator<D, S, C, NC>
&self.secret.client_secret, scopes.iter());
match res {
RequestResult::Error(err) => {
match self.delegate.connection_error(err) {
match self.delegate.connection_error(&*err) {
Retry::Abort => return None,
Retry::After(d) => sleep(d),
}
Expand All @@ -154,7 +154,7 @@ impl<D, S, C, NC> Authenticator<D, S, C, NC>
loop {
match flow.poll_token() {
PollResult::Error(err) => {
match self.delegate.connection_error(err) {
match self.delegate.connection_error(&*err) {
Retry::Abort => return None,
Retry::After(d) => sleep(d),
}
Expand Down Expand Up @@ -269,7 +269,7 @@ pub trait AuthenticatorDelegate {
/// Called whenever there is an HttpError, usually if there are network problems.
///
/// Return retry information.
fn connection_error(&mut self, hyper::HttpError) -> Retry {
fn connection_error(&mut self, &hyper::HttpError) -> Retry {
Retry::Abort
}

Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(old_io, std_misc, core, hash)]
#![feature(old_io, std_misc, core)]
#![allow(deprecated)]
//! This library can be used to acquire oauth2.0 authentication for services.
//! At the time of writing, only one way of doing so is implemented, the [device flow](https://developers.google.com/youtube/v3/guides/authentication#devices), along with a flow
Expand Down Expand Up @@ -68,11 +68,11 @@ extern crate hyper;
#[macro_use]
extern crate log;
#[cfg(test)] #[macro_use]
extern crate "yup-hyper-mock" as hyper_mock;
extern crate yup_hyper_mock as hyper_mock;
extern crate mime;
extern crate url;
extern crate itertools;
extern crate "rustc-serialize" as rustc_serialize;
extern crate rustc_serialize as rustc_serialize;


mod device;
Expand All @@ -82,6 +82,6 @@ mod helper;

pub use device::{DeviceFlow, PollInformation, PollResult};
pub use refresh::{RefreshFlow, RefreshResult};
pub use common::{Token, FlowType, ApplicationSecret, ConsoleApplicationSecret};
pub use common::{Token, FlowType, ApplicationSecret, ConsoleApplicationSecret, Scheme, TokenType};
pub use helper::{TokenStorage, NullStorage, MemoryStorage, Authenticator,
AuthenticatorDelegate, Retry, DefaultAuthenticatorDelegate, GetToken};

0 comments on commit fec6113

Please sign in to comment.