aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-01-20 14:47:39 +0100
committermetamuffin <metamuffin@disroot.org>2024-01-20 14:47:39 +0100
commit9499c195230a7d5adaebd46892b373c86c5248c2 (patch)
treeff652e9959dc2f0349a4e5aed75e8837b452e45f
parent730353601db9818d148c85bfe1ecb119abaab7cc (diff)
downloadjellything-9499c195230a7d5adaebd46892b373c86c5248c2.tar
jellything-9499c195230a7d5adaebd46892b373c86c5248c2.tar.bz2
jellything-9499c195230a7d5adaebd46892b373c86c5248c2.tar.zst
seperate secrets config file
-rw-r--r--base/src/federation.rs18
-rw-r--r--base/src/lib.rs13
-rw-r--r--common/src/config.rs49
-rw-r--r--import/src/lib.rs8
-rw-r--r--server/src/main.rs6
-rw-r--r--server/src/routes/mod.rs5
-rw-r--r--server/src/routes/stream.rs9
-rw-r--r--server/src/routes/ui/account/session/token.rs4
-rw-r--r--tool/src/main.rs122
9 files changed, 130 insertions, 104 deletions
diff --git a/base/src/federation.rs b/base/src/federation.rs
index 9cd04ae..0041e26 100644
--- a/base/src/federation.rs
+++ b/base/src/federation.rs
@@ -3,10 +3,10 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2023 metamuffin <metamuffin.org>
*/
-use crate::CONF;
+use crate::SECRETS;
use anyhow::anyhow;
use jellyclient::{Instance, Session};
-use jellycommon::user::CreateSessionParams;
+use jellycommon::{config::FederationAccount, user::CreateSessionParams};
use std::{collections::HashMap, sync::Arc};
use tokio::sync::RwLock;
@@ -17,10 +17,12 @@ pub struct Federation {
impl Federation {
pub fn initialize() -> Self {
- let instances = CONF
- .remote_credentials
+ let instances = SECRETS
+ .federation
.iter()
- .map(|(k, (_, _, tls))| (k.to_owned(), Instance::new(k.to_owned(), *tls)))
+ .map(|(k, FederationAccount { tls, .. })| {
+ (k.to_owned(), Instance::new(k.to_owned(), *tls))
+ })
.collect::<HashMap<_, _>>();
Self {
@@ -40,8 +42,10 @@ impl Federation {
if let Some(s) = w.get(host) {
Ok(s.to_owned())
} else {
- let (username, password, _) = CONF
- .remote_credentials
+ let FederationAccount {
+ username, password, ..
+ } = SECRETS
+ .federation
.get(host)
.ok_or(anyhow!("no credentials of the remote server"))?;
let s = Arc::new(
diff --git a/base/src/lib.rs b/base/src/lib.rs
index a7b15c5..0001caa 100644
--- a/base/src/lib.rs
+++ b/base/src/lib.rs
@@ -10,7 +10,10 @@ pub mod federation;
pub mod permission;
pub mod temp;
-use jellycommon::{config::GlobalConfig, AssetLocation};
+use jellycommon::{
+ config::{GlobalConfig, SecretsConfig},
+ AssetLocation,
+};
use std::{fs::File, path::PathBuf, sync::LazyLock};
pub static CONF: LazyLock<GlobalConfig> = LazyLock::new(|| {
@@ -20,9 +23,13 @@ pub static CONF: LazyLock<GlobalConfig> = LazyLock::new(|| {
"First argument or JELLYTHING_CONFIG must specify the configuration to use.",
)
}))
- .unwrap(),
+ .expect("config cannot be read"),
)
- .unwrap()
+ .expect("config invalid")
+});
+pub static SECRETS: LazyLock<SecretsConfig> = LazyLock::new(|| {
+ serde_yaml::from_reader(File::open(&CONF.secrets_path).expect("secrets file missing"))
+ .expect("secrets config invalid")
});
pub trait AssetLocationExt {
diff --git a/common/src/config.rs b/common/src/config.rs
index 7328d6e..1c1439e 100644
--- a/common/src/config.rs
+++ b/common/src/config.rs
@@ -5,6 +5,7 @@
*/
use crate::{jhls::EncodingProfile, user::PermissionSet};
+use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, path::PathBuf};
@@ -20,16 +21,47 @@ pub struct GlobalConfig {
#[serde(default = "default::temp_path")] pub temp_path: PathBuf,
#[serde(default = "default::cache_path")] pub cache_path: PathBuf,
#[serde(default = "default::media_path")] pub media_path: PathBuf,
+ #[serde(default = "default::secrets_path")] pub secrets_path: PathBuf,
#[serde(default = "default::transcoding_profiles")] pub transcoding_profiles: Vec<EncodingProfile>,
#[serde(default = "default::max_in_memory_cache_size")] pub max_in_memory_cache_size: usize,
#[serde(default)] pub admin_username: Option<String>,
- #[serde(default)] pub admin_password: Option<String>,
- #[serde(default)] pub cookie_key: Option<String>,
- #[serde(default)] pub session_key: Option<String>,
#[serde(default = "default::login_expire")] pub login_expire: i64,
- #[serde(default)] pub remote_credentials: HashMap<String, (String, String, bool)>,
#[serde(default)] pub default_permission_set: PermissionSet,
- #[serde(default)] pub tmdb_api_key: Option<String>,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+pub struct SecretsConfig {
+ pub federation: HashMap<String, FederationAccount>,
+ pub api: ApiSecrets,
+ #[serde(default)]
+ pub cookie_key: Option<String>,
+ #[serde(default)]
+ pub session_key: Option<String>,
+ #[serde(default)]
+ pub admin_password: Option<String>,
+}
+#[derive(Serialize, Deserialize, Debug)]
+pub struct FederationAccount {
+ pub username: String,
+ pub password: String,
+ #[serde(default = "return_true")]
+ pub tls: bool,
+}
+#[derive(Serialize, Deserialize, Debug)]
+pub struct ApiSecrets {
+ pub tmdb: Option<String>,
+ pub imdb: Option<String>,
+ pub omdb: Option<String>,
+ pub fanart_tv: Option<String>,
+ pub trakt: Option<TraktApiSecrets>,
+}
+#[derive(Serialize, Deserialize, Debug)]
+pub struct TraktApiSecrets {
+ pub client_id: String,
+ pub client_secret: String,
+ pub expire: DateTime<Utc>,
+ pub access_token: String,
+ pub refresh_token: String,
}
mod default {
@@ -54,6 +86,9 @@ mod default {
pub fn media_path() -> PathBuf {
"data/media".into()
}
+ pub fn secrets_path() -> PathBuf {
+ "data/secrets.yaml".into()
+ }
pub fn temp_path() -> PathBuf {
"/tmp".into()
}
@@ -98,3 +133,7 @@ mod default {
]
}
}
+
+fn return_true() -> bool {
+ true
+}
diff --git a/import/src/lib.rs b/import/src/lib.rs
index abaf7fd..1d8efd8 100644
--- a/import/src/lib.rs
+++ b/import/src/lib.rs
@@ -12,10 +12,7 @@ use anyhow::{anyhow, bail, Context, Ok};
use async_recursion::async_recursion;
use futures::{executor::block_on, stream::FuturesUnordered, StreamExt};
use jellybase::{
- cache::{async_cache_file, cache_memory},
- database::{DataAcid, ReadableTable, Ser, T_NODE, T_NODE_IMPORT},
- federation::Federation,
- AssetLocationExt, CONF,
+ cache::{async_cache_file, cache_memory}, database::{DataAcid, ReadableTable, Ser, T_NODE, T_NODE_IMPORT}, federation::Federation, AssetLocationExt, CONF, SECRETS
};
use jellyclient::Session;
use jellycommon::{
@@ -241,8 +238,7 @@ async fn process_source(
ImportSource::Override(n) => insert_node(&id, n)?,
ImportSource::Tmdb { id: tid } => {
info!("tmdb lookup {id}");
- let key = CONF
- .tmdb_api_key
+ let key = SECRETS.api.tmdb
.as_ref()
.ok_or(anyhow!("no tmdb api key"))?;
diff --git a/server/src/main.rs b/server/src/main.rs
index 6862a98..fbfbba6 100644
--- a/server/src/main.rs
+++ b/server/src/main.rs
@@ -10,9 +10,7 @@
use crate::routes::ui::{account::hash_password, admin::log::enable_logging};
use database::DataAcid;
use jellybase::{
- database::{ReadableTable, Ser, T_USER},
- federation::Federation,
- CONF,
+ database::{ReadableTable, Ser, T_USER}, federation::Federation, CONF, SECRETS
};
use jellycommon::user::{PermissionSet, Theme, User};
use log::{error, info, warn};
@@ -33,7 +31,7 @@ async fn main() {
let federation = Federation::initialize();
if let Some(username) = &CONF.admin_username
- && let Some(password) = &CONF.admin_password
+ && let Some(password) = &SECRETS.admin_password
{
let txn = database.begin_write().unwrap();
let mut users = txn.open_table(T_USER).unwrap();
diff --git a/server/src/routes/mod.rs b/server/src/routes/mod.rs
index 6bc5127..d6c1e9f 100644
--- a/server/src/routes/mod.rs
+++ b/server/src/routes/mod.rs
@@ -6,7 +6,7 @@
use crate::{database::DataAcid, routes::ui::error::MyResult};
use api::{r_api_account_login, r_api_node_raw, r_api_root, r_api_version};
use base64::Engine;
-use jellybase::{federation::Federation, CONF};
+use jellybase::{federation::Federation, CONF, SECRETS};
use log::warn;
use rand::random;
use rocket::{
@@ -59,7 +59,8 @@ pub fn build_rocket(database: DataAcid, federation: Federation) -> Rocket<Build>
.map(|e| e.parse().unwrap())
.unwrap_or(8000),
secret_key: SecretKey::derive_from(
- CONF.cookie_key
+ SECRETS
+ .cookie_key
.clone()
.unwrap_or_else(|| {
warn!("cookie_key not configured, generating a random one.");
diff --git a/server/src/routes/stream.rs b/server/src/routes/stream.rs
index c033bda..5c21a5a 100644
--- a/server/src/routes/stream.rs
+++ b/server/src/routes/stream.rs
@@ -10,9 +10,10 @@ use jellybase::{
database::{TableExt, T_NODE},
federation::Federation,
permission::{NodePermissionExt, PermissionSetExt},
- CONF,
+ SECRETS,
};
use jellycommon::{
+ config::FederationAccount,
stream::StreamSpec,
user::{CreateSessionParams, UserPermission},
TrackSource,
@@ -77,8 +78,10 @@ pub async fn r_stream(
.last()
.ok_or(anyhow!("federation inconsistent"))?;
- let (username, password, _) = CONF
- .remote_credentials
+ let FederationAccount {
+ password, username, ..
+ } = SECRETS
+ .federation
.get(host)
.ok_or(anyhow!("no credentials on the server-side"))?;
diff --git a/server/src/routes/ui/account/session/token.rs b/server/src/routes/ui/account/session/token.rs
index 969207d..9cc0c4f 100644
--- a/server/src/routes/ui/account/session/token.rs
+++ b/server/src/routes/ui/account/session/token.rs
@@ -11,13 +11,13 @@ use aes_gcm_siv::{
use anyhow::anyhow;
use base64::Engine;
use chrono::{Duration, Utc};
-use jellybase::CONF;
+use jellybase::SECRETS;
use jellycommon::user::PermissionSet;
use log::warn;
use std::sync::LazyLock;
static SESSION_KEY: LazyLock<[u8; 32]> = LazyLock::new(|| {
- if let Some(sk) = &CONF.session_key {
+ if let Some(sk) = &SECRETS.session_key {
let r = base64::engine::general_purpose::STANDARD
.decode(sk)
.expect("key invalid; should be valid base64");
diff --git a/tool/src/main.rs b/tool/src/main.rs
index c220a08..58559dc 100644
--- a/tool/src/main.rs
+++ b/tool/src/main.rs
@@ -6,16 +6,13 @@
pub mod migrate;
use anyhow::anyhow;
-use base64::Engine;
use clap::{Parser, Subcommand, ValueEnum};
+use jellybase::{CONF, SECRETS};
use jellyclient::Instance;
-use jellycommon::{
- config::GlobalConfig, user::CreateSessionParams, Node, NodeKind, NodePrivate, NodePublic,
-};
-use log::{info, warn};
+use jellycommon::user::CreateSessionParams;
+use log::{error, info};
use migrate::migrate;
-use rand::random;
-use std::{fmt::Debug, fs::File, io::Write, path::PathBuf};
+use std::{fmt::Debug, path::PathBuf};
#[derive(Parser)]
struct Args {
@@ -65,69 +62,49 @@ fn main() -> anyhow::Result<()> {
.init();
let args = Args::parse();
- let config = args
- .config
- .or(std::env::var_os("JELLYTHING_CONFIG").map(|p| PathBuf::from(p)))
- .map(|path| {
- Ok::<_, anyhow::Error>(serde_yaml::from_reader::<_, GlobalConfig>(File::open(
- path,
- )?)?)
- })
- .transpose()?;
-
match args.action {
- Action::Init {
- base_path: path,
- brand,
- hostname,
- } => {
- info!("creating new instance...");
- std::fs::create_dir_all(path.join("library"))?;
- std::fs::create_dir_all(path.join("cache"))?;
- std::fs::create_dir_all(path.join("assets"))?;
- std::fs::create_dir_all(path.join("media"))?;
- File::create_new(path.join("assets/front.htm"))?
- .write_fmt(format_args!("<h1>My very own jellything instance</h1>"))?;
+ Action::Init { .. } => {
+ // info!("creating new instance...");
+ // std::fs::create_dir_all(path.join("library"))?;
+ // std::fs::create_dir_all(path.join("cache"))?;
+ // std::fs::create_dir_all(path.join("assets"))?;
+ // std::fs::create_dir_all(path.join("media"))?;
+ // File::create_new(path.join("assets/front.htm"))?
+ // .write_fmt(format_args!("<h1>My very own jellything instance</h1>"))?;
+
+ // // TODO: dont fill that
+ // serde_yaml::to_writer(
+ // File::create_new(path.join("config.yaml"))?,
+ // &GlobalConfig {
+ // brand: brand.clone(),
+ // hostname,
+ // slogan: "Creative slogan here".to_string(),
+ // asset_path: path.join("assets"),
+ // cache_path: path.join("cache"),
+ // library_path: path.join("library"),
+ // database_path: path.join("database"),
+ // temp_path: "/tmp".into(),
- // TODO: dont fill that
- serde_yaml::to_writer(
- File::create_new(path.join("config.yaml"))?,
- &GlobalConfig {
- brand: brand.clone(),
- hostname,
- slogan: "Creative slogan here".to_string(),
- asset_path: path.join("assets"),
- cache_path: path.join("cache"),
- library_path: path.join("library"),
- database_path: path.join("database"),
- temp_path: "/tmp".into(),
- cookie_key: Some(
- base64::engine::general_purpose::STANDARD
- .encode([(); 32].map(|_| random())),
- ),
- session_key: Some(
- base64::engine::general_purpose::STANDARD
- .encode([(); 32].map(|_| random())),
- ),
- login_expire: 10,
- ..Default::default()
- },
- )?;
- serde_json::to_writer(
- File::create_new(path.join("library/directory.json"))?,
- &Node {
- public: NodePublic {
- kind: Some(NodeKind::Collection),
- title: Some("My Library".to_string()),
- ..Default::default()
- },
- private: NodePrivate {
- ..Default::default()
- },
- },
- )?;
- info!("{brand:?} is ready!");
- warn!("please add an admin password to login.");
+ // login_expire: 10,
+ // ..Default::default()
+ // },
+ // )?;
+ // serde_json::to_writer(
+ // File::create_new(path.join("library/directory.json"))?,
+ // &Node {
+ // public: NodePublic {
+ // kind: Some(NodeKind::Collection),
+ // title: Some("My Library".to_string()),
+ // ..Default::default()
+ // },
+ // private: NodePrivate {
+ // ..Default::default()
+ // },
+ // },
+ // )?;
+ // info!("{brand:?} is ready!");
+ // warn!("please add an admin password to login.");
+ error!("init is currently disabled");
Ok(())
}
a @ Action::Migrate { .. } => migrate(a),
@@ -136,18 +113,19 @@ fn main() -> anyhow::Result<()> {
.build()
.unwrap()
.block_on(async move {
- let config = config.ok_or(anyhow!("this action requires the config"))?;
- let inst = Instance::new(hostname.unwrap_or(config.hostname.clone()), !no_tls);
+ let inst = Instance::new(hostname.unwrap_or(CONF.hostname.clone()), !no_tls);
info!("login");
let session = inst
.login(CreateSessionParams {
drop_permissions: None,
expire: None,
- password: config
+ password: SECRETS
.admin_password
+ .clone()
.ok_or(anyhow!("admin account required"))?,
- username: config
+ username: CONF
.admin_username
+ .clone()
.ok_or(anyhow!("admin account required"))?,
})
.await?;