aboutsummaryrefslogtreecommitdiffstats
path: root/teleterm/src/oauth.rs
diff options
context:
space:
mode:
Diffstat (limited to 'teleterm/src/oauth.rs')
-rw-r--r--teleterm/src/oauth.rs118
1 files changed, 81 insertions, 37 deletions
diff --git a/teleterm/src/oauth.rs b/teleterm/src/oauth.rs
index d76a1b7..c4ec4bb 100644
--- a/teleterm/src/oauth.rs
+++ b/teleterm/src/oauth.rs
@@ -1,40 +1,39 @@
use crate::prelude::*;
use oauth2::TokenResponse as _;
-mod recurse_center;
-pub use recurse_center::RecurseCenter;
-
// this needs to be fixed because we listen for it in a hardcoded place
pub const CLI_REDIRECT_URL: &str = "http://localhost:44141/oauth";
-pub trait Oauth {
- fn client(&self) -> &oauth2::basic::BasicClient;
- fn user_id(&self) -> &str;
- fn name(&self) -> &str;
+pub struct Oauth {
+ client: oauth2::basic::BasicClient,
+ user_id: String,
+}
- fn server_token_file(
- &self,
- must_exist: bool,
- ) -> Option<std::path::PathBuf> {
- let name = format!("server-oauth-{}-{}", self.name(), self.user_id());
- crate::dirs::Dirs::new().data_file(&name, must_exist)
+impl Oauth {
+ pub fn new(config: Config, user_id: String) -> Self {
+ let client = config.into_basic_client();
+ Self { client, user_id }
}
- fn generate_authorize_url(&self) -> String {
+ pub fn generate_authorize_url(&self) -> String {
let (auth_url, _) = self
- .client()
+ .client
.authorize_url(oauth2::CsrfToken::new_random)
.url();
auth_url.to_string()
}
- fn get_access_token_from_auth_code(
+ pub fn user_id(&self) -> &str {
+ &self.user_id
+ }
+
+ pub fn get_access_token_from_auth_code(
&self,
code: &str,
) -> Box<dyn futures::Future<Item = String, Error = Error> + Send> {
let token_cache_file = self.server_token_file(false).unwrap();
let fut = self
- .client()
+ .client
.exchange_code(oauth2::AuthorizationCode::new(code.to_string()))
.request_future(oauth2::reqwest::future_http_client)
.map_err(|e| {
@@ -48,32 +47,61 @@ pub trait Oauth {
Box::new(fut)
}
- fn get_access_token_from_refresh_token(
- &self,
- token: &str,
+ pub fn get_access_token_from_refresh_token(
+ self,
) -> Box<dyn futures::Future<Item = String, Error = Error> + Send> {
let token_cache_file = self.server_token_file(false).unwrap();
- let fut = self
- .client()
- .exchange_refresh_token(&oauth2::RefreshToken::new(
- token.to_string(),
- ))
- .request_future(oauth2::reqwest::future_http_client)
- .map_err(|e| {
- let msg = stringify_oauth2_http_error(&e);
- Error::ExchangeRefreshToken { msg }
- })
- .and_then(|token| {
- cache_refresh_token(token_cache_file, &token)
- .map(move |_| token.access_token().secret().to_string())
- });
+ let fut = load_refresh_token(&token_cache_file).and_then(
+ move |refresh_token| {
+ // XXX
+ let refresh_token = refresh_token.unwrap();
+ self.client
+ .exchange_refresh_token(&oauth2::RefreshToken::new(
+ refresh_token,
+ ))
+ .request_future(oauth2::reqwest::future_http_client)
+ .map_err(|e| {
+ let msg = stringify_oauth2_http_error(&e);
+ Error::ExchangeRefreshToken { msg }
+ })
+ .and_then(move |token| {
+ cache_refresh_token(token_cache_file, &token).map(
+ move |_| {
+ token.access_token().secret().to_string()
+ },
+ )
+ })
+ },
+ );
Box::new(fut)
}
- fn get_username_from_access_token(
+ pub fn server_token_file(
&self,
- token: &str,
- ) -> Box<dyn futures::Future<Item = String, Error = Error> + Send>;
+ must_exist: bool,
+ ) -> Option<std::path::PathBuf> {
+ let name = format!("server-oauth-{}", self.user_id);
+ crate::dirs::Dirs::new().data_file(&name, must_exist)
+ }
+}
+
+fn load_refresh_token(
+ token_cache_file: &std::path::Path,
+) -> Box<dyn futures::Future<Item = Option<String>, Error = Error> + Send> {
+ let token_cache_file = token_cache_file.to_path_buf();
+ Box::new(
+ tokio::fs::File::open(token_cache_file.clone())
+ .with_context(move || crate::error::OpenFile {
+ filename: token_cache_file.to_string_lossy().to_string(),
+ })
+ .and_then(|file| {
+ tokio::io::lines(std::io::BufReader::new(file))
+ .into_future()
+ .map_err(|(e, _)| e)
+ .context(crate::error::ReadFile)
+ })
+ .map(|(refresh_token, _)| refresh_token),
+ )
}
fn cache_refresh_token(
@@ -107,6 +135,22 @@ pub struct Config {
}
impl Config {
+ pub fn new(
+ client_id: String,
+ client_secret: String,
+ auth_url: url::Url,
+ token_url: url::Url,
+ redirect_url: url::Url,
+ ) -> Self {
+ Self {
+ client_id,
+ client_secret,
+ auth_url,
+ token_url,
+ redirect_url,
+ }
+ }
+
pub fn set_redirect_url(&mut self, url: url::Url) {
self.redirect_url = url;
}