Skip to content

Commit b834939

Browse files
committed
Auto merge of #1842 - jtgeibel:update/oauth2, r=sgrif
Bump to oauth2:2.0.0
2 parents 897e627 + 88f5eaf commit b834939

File tree

7 files changed

+68
-52
lines changed

7 files changed

+68
-52
lines changed

Cargo.lock

Lines changed: 23 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ tar = "0.4.16"
3838
base64 = "0.9"
3939

4040
openssl = "0.10.13"
41-
oauth2 = "0.3"
41+
oauth2 = "2.0.0"
4242
log = "0.4"
4343
env_logger = "0.5"
4444
hex = "0.3"

src/app.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{db, Config, Env};
44
use std::{path::PathBuf, sync::Arc, time::Duration};
55

66
use diesel::r2d2;
7+
use oauth2::basic::BasicClient;
78
use reqwest::Client;
89
use scheduled_thread_pool::ScheduledThreadPool;
910

@@ -16,7 +17,7 @@ pub struct App {
1617
pub diesel_database: db::DieselPool,
1718

1819
/// The GitHub OAuth2 configuration
19-
pub github: oauth2::Config,
20+
pub github: BasicClient,
2021

2122
/// A unique key used with conduit_cookie to generate cookies
2223
pub session_key: String,
@@ -43,15 +44,21 @@ impl App {
4344
///
4445
/// - GitHub OAuth
4546
/// - Database connection pools
46-
/// - Holds an HTTP `Client` and associated connection pool, if provided
47+
/// - A `git2::Repository` instance from the index repo checkout (that server.rs ensures exists)
4748
pub fn new(config: &Config, http_client: Option<Client>) -> App {
48-
let mut github = oauth2::Config::new(
49-
&config.gh_client_id,
50-
&config.gh_client_secret,
51-
"https://github.com/login/oauth/authorize",
52-
"https://github.com/login/oauth/access_token",
53-
);
54-
github.scopes.push(String::from("read:org"));
49+
use oauth2::prelude::*;
50+
use oauth2::{AuthUrl, ClientId, ClientSecret, Scope, TokenUrl};
51+
use url::Url;
52+
53+
let github = BasicClient::new(
54+
ClientId::new(config.gh_client_id.clone()),
55+
Some(ClientSecret::new(config.gh_client_secret.clone())),
56+
AuthUrl::new(Url::parse("https://github.com/login/oauth/authorize").unwrap()),
57+
Some(TokenUrl::new(
58+
Url::parse("https://github.com/login/oauth/access_token").unwrap(),
59+
)),
60+
)
61+
.add_scope(Scope::new("read:org".to_string()));
5562

5663
let db_pool_size = match (dotenv::var("DB_POOL_SIZE"), config.env) {
5764
(Ok(num), _) => num.parse().expect("couldn't parse DB_POOL_SIZE"),

src/controllers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ mod prelude {
3434

3535
fn query(&self) -> IndexMap<String, String> {
3636
url::form_urlencoded::parse(self.query_string().unwrap_or("").as_bytes())
37-
.map(|(a, b)| (a.into_owned(), b.into_owned()))
37+
.into_owned()
3838
.collect()
3939
}
4040

src/controllers/user/session.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use crate::controllers::prelude::*;
22

33
use crate::github;
44
use conduit_cookie::RequestSession;
5-
use rand::distributions::Alphanumeric;
6-
use rand::{thread_rng, Rng};
5+
use oauth2::{prelude::*, AuthorizationCode, TokenResponse};
76

87
use crate::models::{NewUser, User};
98
use crate::schema::users;
@@ -25,17 +24,14 @@ use crate::util::errors::{CargoError, ReadOnlyMode};
2524
/// }
2625
/// ```
2726
pub fn github_authorize(req: &mut dyn Request) -> CargoResult<Response> {
28-
// Generate a random 16 char ASCII string
29-
let mut rng = thread_rng();
30-
let state: String = std::iter::repeat(())
31-
.map(|()| rng.sample(Alphanumeric))
32-
.take(16)
33-
.collect();
27+
let (url, state) = req
28+
.app()
29+
.github
30+
.authorize_url(oauth2::CsrfToken::new_random);
31+
let state = state.secret().to_string();
3432
req.session()
3533
.insert("github_oauth_state".to_string(), state.clone());
3634

37-
let url = req.app().github.authorize_url(state.clone());
38-
3935
#[derive(Serialize)]
4036
struct R {
4137
url: String,
@@ -92,11 +88,16 @@ pub fn github_access_token(req: &mut dyn Request) -> CargoResult<Response> {
9288
}
9389

9490
// Fetch the access token from github using the code we just got
95-
let token = req.app().github.exchange(code).map_err(|s| human(&s))?;
96-
97-
let ghuser = github::github::<GithubUser>(req.app(), "/user", &token)?;
98-
let user = ghuser.save_to_database(&token.access_token, &*req.db_conn()?)?;
9991

92+
let code = AuthorizationCode::new(code);
93+
let token = req
94+
.app()
95+
.github
96+
.exchange_code(code)
97+
.map_err(|s| human(&s))?;
98+
let token = token.access_token();
99+
let ghuser = github::github_api::<GithubUser>(req.app(), "/user", token)?;
100+
let user = ghuser.save_to_database(&token.secret(), &*req.db_conn()?)?;
100101
req.session()
101102
.insert("user_id".to_string(), user.id.to_string());
102103
req.mut_extensions().insert(user);

src/github.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! This module implements functionality for interacting with GitHub.
22
3-
use oauth2::*;
3+
use oauth2::{prelude::*, AccessToken};
44
use reqwest::{self, header};
55

66
use serde::de::DeserializeOwned;
@@ -13,7 +13,7 @@ use crate::util::{errors::NotFound, human, internal, CargoError, CargoResult};
1313
/// Does all the nonsense for sending a GET to Github. Doesn't handle parsing
1414
/// because custom error-code handling may be desirable. Use
1515
/// `parse_github_response` to handle the "common" processing of responses.
16-
pub fn github<T>(app: &App, url: &str, auth: &Token) -> CargoResult<T>
16+
pub fn github_api<T>(app: &App, url: &str, auth: &AccessToken) -> CargoResult<T>
1717
where
1818
T: DeserializeOwned,
1919
{
@@ -23,10 +23,7 @@ where
2323
app.http_client()
2424
.get(&url)
2525
.header(header::ACCEPT, "application/vnd.github.v3+json")
26-
.header(
27-
header::AUTHORIZATION,
28-
format!("token {}", auth.access_token),
29-
)
26+
.header(header::AUTHORIZATION, format!("token {}", auth.secret()))
3027
.send()?
3128
.error_for_status()
3229
.map_err(|e| handle_error_response(&e))?
@@ -55,16 +52,6 @@ fn handle_error_response(error: &reqwest::Error) -> Box<dyn CargoError> {
5552
}
5653
}
5754

58-
/// Gets a token with the given string as the access token, but all
59-
/// other info null'd out. Generally, just to be fed to the `github` fn.
60-
pub fn token(token: String) -> Token {
61-
Token {
62-
access_token: token,
63-
scopes: Vec::new(),
64-
token_type: String::new(),
65-
}
66-
}
67-
6855
pub fn team_url(login: &str) -> String {
6956
let mut login_pieces = login.split(':');
7057
login_pieces.next();

src/models/team.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use diesel::prelude::*;
22

33
use crate::app::App;
4-
use crate::github;
4+
use crate::github::{github_api, team_url};
55
use crate::util::{errors::NotFound, human, CargoResult};
66

7+
use oauth2::{prelude::*, AccessToken};
8+
79
use crate::models::{Crate, CrateOwner, Owner, OwnerKind, User};
810
use crate::schema::{crate_owners, teams};
911
use crate::views::EncodableTeam;
@@ -141,8 +143,8 @@ impl Team {
141143
// FIXME: we just set per_page=100 and don't bother chasing pagination
142144
// links. A hundred teams should be enough for any org, right?
143145
let url = format!("/orgs/{}/teams?per_page=100", org_name);
144-
let token = github::token(req_user.gh_access_token.clone());
145-
let teams = github::github::<Vec<GithubTeam>>(app, &url, &token)?;
146+
let token = AccessToken::new(req_user.gh_access_token.clone());
147+
let teams = github_api::<Vec<GithubTeam>>(app, &url, &token)?;
146148

147149
let team = teams
148150
.into_iter()
@@ -164,7 +166,7 @@ impl Team {
164166
}
165167

166168
let url = format!("/orgs/{}", org_name);
167-
let org = github::github::<Org>(app, &url, &token)?;
169+
let org = github_api::<Org>(app, &url, &token)?;
168170

169171
NewTeam::new(&login.to_lowercase(), team.id, team.name, org.avatar_url)
170172
.create_or_update(conn)
@@ -200,7 +202,7 @@ impl Team {
200202
avatar,
201203
..
202204
} = self;
203-
let url = github::team_url(&login);
205+
let url = team_url(&login);
204206

205207
EncodableTeam {
206208
id,
@@ -222,8 +224,8 @@ fn team_with_gh_id_contains_user(app: &App, github_id: i32, user: &User) -> Carg
222224
}
223225

224226
let url = format!("/teams/{}/memberships/{}", &github_id, &user.gh_login);
225-
let token = github::token(user.gh_access_token.clone());
226-
let membership = match github::github::<Membership>(app, &url, &token) {
227+
let token = AccessToken::new(user.gh_access_token.clone());
228+
let membership = match github_api::<Membership>(app, &url, &token) {
227229
// Officially how `false` is returned
228230
Err(ref e) if e.is::<NotFound>() => return Ok(false),
229231
x => x?,

0 commit comments

Comments
 (0)