Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example using the Github OAuth2 flow #15

Merged
merged 1 commit into from
Jul 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ branches:
script:
- cargo test -- --test-threads=1
- cargo test --example google
- cargo test --example github
notifications:
email:
on_success: never
101 changes: 101 additions & 0 deletions examples/github.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//!
//! This example showcases the Github OAuth2 process for requesting access to the user's public repos.
//!
//! Before running it, you'll need to generate your own Github OAuth2 credentials.
//!
//! In order to run the example call:
//!
//! ```sh
//! GITHUB_CLIENT_ID=xxx GITHUB_CLIENT_SECRET=yyy cargo run --example github
//! ```
//!
//! ...and follow the instructions.
//!

extern crate url;
extern crate oauth2;

use std::env;
use std::net::TcpListener;
use std::io::{BufRead, BufReader, Write};
use url::Url;
use oauth2::Config;

fn main() {
let github_client_id = env::var("GITHUB_CLIENT_ID").expect("Missing the GITHUB_CLIENT_ID environment variable.");
let github_client_secret = env::var("GITHUB_CLIENT_SECRET").expect("Missing the GITHUB_CLIENT_SECRET environment variable.");
let auth_url = "https://github.com/login/oauth/authorize";
let token_url = "https://github.com/login/oauth/access_token";

// Set up the config for the Github OAuth2 process.
let mut config = Config::new(github_client_id, github_client_secret, auth_url, token_url);

// This example is requesting access to the "public_repo" features.
config = config.add_scope("public_repo");

// This example will be running its own server at localhost:8080.
// See below for the server implementation.
config = config.set_redirect_url("http://localhost:8080");

// Set the state parameter (optional)
config = config.set_state("1234");

// Generate the authorization URL to which we'll redirect the user.
let authorize_url = config.authorize_url();

println!("Open this URL in your browser:\n{}\n", authorize_url.to_string());

// These variables will store the code & state retrieved during the authorization process.
let mut code = String::new();
let mut state = String::new();

// A very naive implementation of the redirect server.
let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
for stream in listener.incoming() {
match stream {
Ok(mut stream) => {
{
let mut reader = BufReader::new(&stream);

let mut request_line = String::new();
reader.read_line(&mut request_line).unwrap();

let redirect_url = request_line.split_whitespace().nth(1).unwrap();
let url = Url::parse(&("http://localhost".to_string() + redirect_url)).unwrap();

let code_pair = url.query_pairs().find(|pair| {
let &(ref key, _) = pair;
key == "code"
}).unwrap();

let (_, value) = code_pair;
code = value.into_owned();

let state_pair = url.query_pairs().find(|pair| {
let &(ref key, _) = pair;
key == "state"
}).unwrap();

let (_, value) = state_pair;
state = value.into_owned();
}

let message = "Go back to your terminal :)";
let response = format!("HTTP/1.1 200 OK\r\ncontent-length: {}\r\n\r\n{}", message.len(), message);
stream.write_all(response.as_bytes()).unwrap();

// The server will terminate itself after collecting the first code.
break;
}
Err(_) => {},
}
};

println!("Github returned the following code:\n{}\n", code);
println!("Github returned the following state:\n{}\n", state);

// Exchange the code with a token.
let token = config.exchange_code(code);

println!("Github returned the following token:\n{:?}\n", token);
}
15 changes: 15 additions & 0 deletions examples/google.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ fn main() {
// See below for the server implementation.
config = config.set_redirect_url("http://localhost:8080");

// Set the state parameter (optional)
config = config.set_state("1234");

// Generate the authorization URL to which we'll redirect the user.
let authorize_url = config.authorize_url();

println!("Open this URL in your browser:\n{}\n", authorize_url.to_string());

// These variables will store the code & state retrieved during the authorization process.
let mut code = String::new();
let mut state = String::new();

// A very naive implementation of the redirect server.
let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
Expand All @@ -64,6 +70,14 @@ fn main() {

let (_, value) = code_pair;
code = value.into_owned();

let state_pair = url.query_pairs().find(|pair| {
let &(ref key, _) = pair;
key == "state"
}).unwrap();

let (_, value) = state_pair;
state = value.into_owned();
}

let message = "Go back to your terminal :)";
Expand All @@ -78,6 +92,7 @@ fn main() {
};

println!("Google returned the following code:\n{}\n", code);
println!("Google returned the following state:\n{}\n", state);

// Exchange the code with a token.
let token = config.exchange_code(code);
Expand Down