aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2019-10-20 13:31:31 -0400
committerJesse Luehrs <doy@tozt.net>2019-10-20 13:31:31 -0400
commit4d8684f14658e404e25bac8235340129920e5017 (patch)
treedf4a5a5b1ee8267798a5a65f6ab3ec46a4794b5b
parent1fd0154711eadcd77c36bf6fc55917be54949f6a (diff)
downloadteleterm-4d8684f14658e404e25bac8235340129920e5017.tar.gz
teleterm-4d8684f14658e404e25bac8235340129920e5017.zip
fall back to /etc and /var if ~/.config files don't exist
-rw-r--r--src/config.rs25
-rw-r--r--src/dirs.rs76
-rw-r--r--src/oauth.rs33
-rw-r--r--src/server.rs6
4 files changed, 95 insertions, 45 deletions
diff --git a/src/config.rs b/src/config.rs
index dcc44d7..10b358b 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -41,17 +41,20 @@ pub fn config() -> config::Config {
crate::dirs::Dirs::new().config_file(CONFIG_FILENAME);
let mut config = config::Config::default();
- if let Err(e) = config.merge(config::File::from(config_filename.clone()))
- {
- log::warn!(
- "failed to read config file {}: {}",
- config_filename.to_string_lossy(),
- e
- );
- // if merge returns an error, the config source will still have been
- // added to the config object, so the config object will likely never
- // work, so we should recreate it from scratch.
- config = config::Config::default();
+ if let Some(config_filename) = config_filename {
+ if let Err(e) =
+ config.merge(config::File::from(config_filename.clone()))
+ {
+ log::warn!(
+ "failed to read config file {}: {}",
+ config_filename.to_string_lossy(),
+ e
+ );
+ // if merge returns an error, the config source will still have been
+ // added to the config object, so the config object will likely never
+ // work, so we should recreate it from scratch.
+ config = config::Config::default();
+ }
}
config
diff --git a/src/dirs.rs b/src/dirs.rs
index 44f828b..feea8e4 100644
--- a/src/dirs.rs
+++ b/src/dirs.rs
@@ -1,42 +1,80 @@
use crate::prelude::*;
pub struct Dirs {
- project_dirs: directories::ProjectDirs,
+ project_dirs: Option<directories::ProjectDirs>,
}
impl Dirs {
pub fn new() -> Self {
- // TODO: fall back to /var, /etc, etc if we're running without $HOME
- // set
Self {
- project_dirs: directories::ProjectDirs::from("", "", "teleterm")
- .expect("failed to find valid home directory"),
+ project_dirs: directories::ProjectDirs::from("", "", "teleterm"),
}
}
pub fn create_all(&self) -> Result<()> {
- let filename = self.data_dir();
- std::fs::create_dir_all(filename).with_context(|| {
- crate::error::CreateDir {
- filename: filename.to_string_lossy(),
- }
- })?;
+ if let Some(filename) = self.data_dir() {
+ std::fs::create_dir_all(filename).with_context(|| {
+ crate::error::CreateDir {
+ filename: filename.to_string_lossy(),
+ }
+ })?;
+ }
Ok(())
}
- fn config_dir(&self) -> &std::path::Path {
- self.project_dirs.config_dir()
+ fn global_config_dir(&self) -> &std::path::Path {
+ std::path::Path::new("/etc/teleterm")
+ }
+
+ fn config_dir(&self) -> Option<&std::path::Path> {
+ self.project_dirs
+ .as_ref()
+ .map(directories::ProjectDirs::config_dir)
+ }
+
+ pub fn config_file(&self, name: &str) -> Option<std::path::PathBuf> {
+ if let Some(config_dir) = self.config_dir() {
+ let file = config_dir.join(name);
+ if file.exists() {
+ return Some(file);
+ }
+ }
+
+ let file = self.global_config_dir().join(name);
+ if file.exists() {
+ return Some(file);
+ }
+
+ None
}
- pub fn config_file(&self, name: &str) -> std::path::PathBuf {
- self.config_dir().join(name)
+ fn global_data_dir(&self) -> &std::path::Path {
+ std::path::Path::new("/var/lib/teleterm")
}
- fn data_dir(&self) -> &std::path::Path {
- self.project_dirs.data_dir()
+ fn data_dir(&self) -> Option<&std::path::Path> {
+ self.project_dirs
+ .as_ref()
+ .map(directories::ProjectDirs::data_dir)
}
- pub fn data_file(&self, name: &str) -> std::path::PathBuf {
- self.data_dir().join(name)
+ pub fn data_file(
+ &self,
+ name: &str,
+ must_exist: bool,
+ ) -> Option<std::path::PathBuf> {
+ if let Some(data_dir) = self.data_dir() {
+ let file = data_dir.join(name);
+ if !must_exist || file.exists() {
+ return Some(file);
+ }
+ }
+
+ let file = self.global_data_dir().join(name);
+ if !must_exist || file.exists() {
+ return Some(file);
+ }
+
+ None
}
}
diff --git a/src/oauth.rs b/src/oauth.rs
index 0840585..26aecbc 100644
--- a/src/oauth.rs
+++ b/src/oauth.rs
@@ -13,9 +13,12 @@ pub trait Oauth {
fn user_id(&self) -> &str;
fn name(&self) -> &str;
- fn server_token_file(&self) -> std::path::PathBuf {
+ 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)
+ crate::dirs::Dirs::new().data_file(&name, must_exist)
}
fn generate_authorize_url(&self) -> String {
@@ -31,7 +34,7 @@ pub trait Oauth {
code: &str,
) -> Box<dyn futures::future::Future<Item = String, Error = Error> + Send>
{
- let token_cache_file = self.server_token_file();
+ let token_cache_file = self.server_token_file(false).unwrap();
let fut = self
.client()
.exchange_code(oauth2::AuthorizationCode::new(code.to_string()))
@@ -52,7 +55,7 @@ pub trait Oauth {
token: &str,
) -> Box<dyn futures::future::Future<Item = String, Error = Error> + Send>
{
- let token_cache_file = self.server_token_file();
+ let token_cache_file = self.server_token_file(false).unwrap();
let fut = self
.client()
.exchange_refresh_token(&oauth2::RefreshToken::new(
@@ -80,7 +83,7 @@ pub fn save_client_auth_id(
auth: crate::protocol::AuthType,
id: &str,
) -> impl futures::future::Future<Item = (), Error = Error> {
- let id_file = client_id_file(auth);
+ let id_file = client_id_file(auth, false).unwrap();
let id = id.to_string();
tokio::fs::File::create(id_file.clone())
.with_context(move || crate::error::CreateFile {
@@ -95,18 +98,22 @@ pub fn save_client_auth_id(
pub fn load_client_auth_id(
auth: crate::protocol::AuthType,
) -> Option<String> {
- let id_file = client_id_file(auth);
- std::fs::File::open(id_file).ok().and_then(|mut file| {
- let mut id = vec![];
- file.read_to_end(&mut id)
- .ok()
- .map(|_| std::string::String::from_utf8_lossy(&id).to_string())
+ client_id_file(auth, true).and_then(|id_file| {
+ std::fs::File::open(id_file).ok().and_then(|mut file| {
+ let mut id = vec![];
+ file.read_to_end(&mut id).ok().map(|_| {
+ std::string::String::from_utf8_lossy(&id).to_string()
+ })
+ })
})
}
-fn client_id_file(auth: crate::protocol::AuthType) -> std::path::PathBuf {
+fn client_id_file(
+ auth: crate::protocol::AuthType,
+ must_exist: bool,
+) -> Option<std::path::PathBuf> {
let filename = format!("client-oauth-{}", auth.name());
- crate::dirs::Dirs::new().data_file(&filename)
+ crate::dirs::Dirs::new().data_file(&filename, must_exist)
}
fn cache_refresh_token(
diff --git a/src/server.rs b/src/server.rs
index 8c965a9..cbc410f 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -433,11 +433,13 @@ impl<S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Send + 'static>
client.user_id()
);
- if refresh {
+ let token_filename = client.server_token_file(true);
+ if let (Some(token_filename), true) =
+ (token_filename, refresh)
+ {
let term_type = term_type.to_string();
let client = conn.oauth_client.take().unwrap();
let mut new_state = conn.state.clone();
- let token_filename = client.server_token_file();
let fut = tokio::fs::File::open(token_filename.clone())
.with_context(move || crate::error::OpenFile {
filename: token_filename