add prefix_url to config options to allow polaris to run behind a reverse proxy

This commit is contained in:
João Oliveira 2017-10-01 00:47:06 +01:00
parent 69feab3bcc
commit a82af0f0b8
5 changed files with 92 additions and 59 deletions

View file

@ -22,6 +22,7 @@ pub struct MiscSettings {
pub auth_secret: String, pub auth_secret: String,
pub index_sleep_duration_seconds: i32, pub index_sleep_duration_seconds: i32,
pub index_album_art_pattern: String, pub index_album_art_pattern: String,
pub prefix_url: String,
} }
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -36,6 +37,7 @@ pub struct Config {
pub album_art_pattern: Option<String>, pub album_art_pattern: Option<String>,
pub reindex_every_n_seconds: Option<i32>, pub reindex_every_n_seconds: Option<i32>,
pub mount_dirs: Option<Vec<MountPoint>>, pub mount_dirs: Option<Vec<MountPoint>>,
pub prefix_url: Option<String>,
pub users: Option<Vec<ConfigUser>>, pub users: Option<Vec<ConfigUser>>,
pub ydns: Option<DDNSConfig>, pub ydns: Option<DDNSConfig>,
} }
@ -83,15 +85,17 @@ pub fn read<T>(db: &T) -> Result<Config>
album_art_pattern: None, album_art_pattern: None,
reindex_every_n_seconds: None, reindex_every_n_seconds: None,
mount_dirs: None, mount_dirs: None,
prefix_url: None,
users: None, users: None,
ydns: None, ydns: None,
}; };
let (art_pattern, sleep_duration) = misc_settings let (art_pattern, sleep_duration, url) = misc_settings
.select((index_album_art_pattern, index_sleep_duration_seconds)) .select((index_album_art_pattern, index_sleep_duration_seconds, prefix_url))
.get_result(connection.deref())?; .get_result(connection.deref())?;
config.album_art_pattern = Some(art_pattern); config.album_art_pattern = Some(art_pattern);
config.reindex_every_n_seconds = Some(sleep_duration); config.reindex_every_n_seconds = Some(sleep_duration);
config.prefix_url = if url != "" { Some(url) } else { None };
let mount_dirs = mount_points let mount_dirs = mount_points
.select((source, name)) .select((source, name))
@ -102,15 +106,15 @@ pub fn read<T>(db: &T) -> Result<Config>
.select((users::columns::name, users::columns::admin)) .select((users::columns::name, users::columns::admin))
.get_results(connection.deref())?; .get_results(connection.deref())?;
config.users = Some(found_users config.users = Some(found_users
.into_iter() .into_iter()
.map(|(n, a)| { .map(|(n, a)| {
ConfigUser { ConfigUser {
name: n, name: n,
password: "".to_owned(), password: "".to_owned(),
admin: a != 0, admin: a != 0,
} }
}) })
.collect::<_>()); .collect::<_>());
let ydns = ddns_config let ydns = ddns_config
.select((host, username, password)) .select((host, username, password))
@ -166,9 +170,9 @@ pub fn amend<T>(db: &T, new_config: &Config) -> Result<()>
let delete_usernames: Vec<String> = old_usernames let delete_usernames: Vec<String> = old_usernames
.into_iter() .into_iter()
.filter(|old_name| match config_users.iter().find(|u| &u.name == old_name) { .filter(|old_name| match config_users.iter().find(|u| &u.name == old_name) {
None => true, None => true,
Some(new_user) => !new_user.password.is_empty(), Some(new_user) => !new_user.password.is_empty(),
}) })
.collect::<_>(); .collect::<_>();
diesel::delete(users::table.filter(users::name.eq_any(&delete_usernames))) diesel::delete(users::table.filter(users::name.eq_any(&delete_usernames)))
.execute(connection.deref())?; .execute(connection.deref())?;
@ -209,8 +213,14 @@ pub fn amend<T>(db: &T, new_config: &Config) -> Result<()>
use self::ddns_config::dsl::*; use self::ddns_config::dsl::*;
diesel::update(ddns_config) diesel::update(ddns_config)
.set((host.eq(ydns.host.clone()), .set((host.eq(ydns.host.clone()),
username.eq(ydns.username.clone()), username.eq(ydns.username.clone()),
password.eq(ydns.password.clone()))) password.eq(ydns.password.clone())))
.execute(connection.deref())?;
}
if let Some(ref prefix_url) = new_config.prefix_url {
diesel::update(misc_settings::table)
.set(misc_settings::prefix_url.eq(prefix_url))
.execute(connection.deref())?; .execute(connection.deref())?;
} }
@ -244,35 +254,37 @@ fn test_amend() {
let initial_config = Config { let initial_config = Config {
album_art_pattern: Some("file\\.png".into()), album_art_pattern: Some("file\\.png".into()),
reindex_every_n_seconds: Some(123), reindex_every_n_seconds: Some(123),
prefix_url: None,
mount_dirs: Some(vec![MountPoint { mount_dirs: Some(vec![MountPoint {
source: "C:\\Music".into(), source: "C:\\Music".into(),
name: "root".into(), name: "root".into(),
}]), }]),
users: Some(vec![ConfigUser { users: Some(vec![ConfigUser {
name: "Teddy🐻".into(), name: "Teddy🐻".into(),
password: "Tasty🍖".into(), password: "Tasty🍖".into(),
admin: false, admin: false,
}]), }]),
ydns: None, ydns: None,
}; };
let new_config = Config { let new_config = Config {
album_art_pattern: Some("🖼️\\.jpg".into()), album_art_pattern: Some("🖼️\\.jpg".into()),
reindex_every_n_seconds: None, reindex_every_n_seconds: None,
prefix_url: Some("polaris".into()),
mount_dirs: Some(vec![MountPoint { mount_dirs: Some(vec![MountPoint {
source: "/home/music".into(), source: "/home/music".into(),
name: "🎵📁".into(), name: "🎵📁".into(),
}]), }]),
users: Some(vec![ConfigUser { users: Some(vec![ConfigUser {
name: "Kermit🐸".into(), name: "Kermit🐸".into(),
password: "🐞🐞".into(), password: "🐞🐞".into(),
admin: false, admin: false,
}]), }]),
ydns: Some(DDNSConfig { ydns: Some(DDNSConfig {
host: "🐸🐸🐸.ydns.eu".into(), host: "🐸🐸🐸.ydns.eu".into(),
username: "kfr🐸g".into(), username: "kfr🐸g".into(),
password: "tasty🐞".into(), password: "tasty🐞".into(),
}), }),
}; };
let mut expected_config = new_config.clone(); let mut expected_config = new_config.clone();
@ -298,12 +310,13 @@ fn test_amend_preserve_password_hashes() {
let initial_config = Config { let initial_config = Config {
album_art_pattern: None, album_art_pattern: None,
reindex_every_n_seconds: None, reindex_every_n_seconds: None,
prefix_url: None,
mount_dirs: None, mount_dirs: None,
users: Some(vec![ConfigUser { users: Some(vec![ConfigUser {
name: "Teddy🐻".into(), name: "Teddy🐻".into(),
password: "Tasty🍖".into(), password: "Tasty🍖".into(),
admin: false, admin: false,
}]), }]),
ydns: None, ydns: None,
}; };
amend(&db, &initial_config).unwrap(); amend(&db, &initial_config).unwrap();
@ -320,17 +333,18 @@ fn test_amend_preserve_password_hashes() {
let new_config = Config { let new_config = Config {
album_art_pattern: None, album_art_pattern: None,
reindex_every_n_seconds: None, reindex_every_n_seconds: None,
prefix_url: None,
mount_dirs: None, mount_dirs: None,
users: Some(vec![ConfigUser { users: Some(vec![ConfigUser {
name: "Kermit🐸".into(), name: "Kermit🐸".into(),
password: "tasty🐞".into(), password: "tasty🐞".into(),
admin: false, admin: false,
}, },
ConfigUser { ConfigUser {
name: "Teddy🐻".into(), name: "Teddy🐻".into(),
password: "".into(), password: "".into(),
admin: false, admin: false,
}]), }]),
ydns: None, ydns: None,
}; };
amend(&db, &new_config).unwrap(); amend(&db, &new_config).unwrap();
@ -357,12 +371,13 @@ fn test_toggle_admin() {
let initial_config = Config { let initial_config = Config {
album_art_pattern: None, album_art_pattern: None,
reindex_every_n_seconds: None, reindex_every_n_seconds: None,
prefix_url: None,
mount_dirs: None, mount_dirs: None,
users: Some(vec![ConfigUser { users: Some(vec![ConfigUser {
name: "Teddy🐻".into(), name: "Teddy🐻".into(),
password: "Tasty🍖".into(), password: "Tasty🍖".into(),
admin: true, admin: true,
}]), }]),
ydns: None, ydns: None,
}; };
amend(&db, &initial_config).unwrap(); amend(&db, &initial_config).unwrap();
@ -379,12 +394,13 @@ fn test_toggle_admin() {
let new_config = Config { let new_config = Config {
album_art_pattern: None, album_art_pattern: None,
reindex_every_n_seconds: None, reindex_every_n_seconds: None,
prefix_url: None,
mount_dirs: None, mount_dirs: None,
users: Some(vec![ConfigUser { users: Some(vec![ConfigUser {
name: "Teddy🐻".into(), name: "Teddy🐻".into(),
password: "".into(), password: "".into(),
admin: false, admin: false,
}]), }]),
ydns: None, ydns: None,
}; };
amend(&db, &new_config).unwrap(); amend(&db, &new_config).unwrap();

View file

@ -0,0 +1,11 @@
CREATE TEMPORARY TABLE misc_settings_backup(id, auth_secret, index_sleep_duration_seconds, index_album_art_pattern);
INSERT INTO misc_settings_backup SELECT id, auth_secret, index_sleep_duration_seconds, index_album_art_pattern FROM misc_settings;
DROP TABLE misc_settings;
CREATE TABLE misc_settings (
id INTEGER PRIMARY KEY NOT NULL CHECK(id = 0),
auth_secret TEXT NOT NULL,
index_sleep_duration_seconds INTEGER NOT NULL,
index_album_art_pattern TEXT NOT NULL
);
INSERT INTO misc_settings SELECT * FROM misc_settings_backup;
DROP TABLE misc_settings_backup;

View file

@ -0,0 +1 @@
ALTER TABLE misc_settings ADD COLUMN prefix_url TEXT NOT NULL DEFAULT "";

Binary file not shown.

View file

@ -145,6 +145,7 @@ fn run() -> Result<()> {
let config = config::parse_toml_file(&path)?; let config = config::parse_toml_file(&path)?;
config::overwrite(db.deref(), &config)?; config::overwrite(db.deref(), &config)?;
} }
let config = config::read(db.deref())?;
// Init index // Init index
let (index_sender, index_receiver) = channel(); let (index_sender, index_receiver) = channel();
@ -161,13 +162,17 @@ fn run() -> Result<()> {
std::thread::spawn(move || { index::self_trigger(db_ref.deref(), sender_ref); }); std::thread::spawn(move || { index::self_trigger(db_ref.deref(), sender_ref); });
// Mount API // Mount API
println!("Mounting API"); let prefix_url = config.prefix_url.unwrap_or("".to_string());
let api_url = format!("{}/api", &prefix_url);
println!("Mounting API on {}", api_url);
let mut mount = Mount::new(); let mut mount = Mount::new();
let handler = api::get_handler(db.clone(), index_sender)?; let handler = api::get_handler(db.clone(), index_sender)?;
mount.mount("/api/", handler); mount.mount(&api_url, handler);
// Mount static files // Mount static files
println!("Mounting static files"); let static_url = format!("/{}", &prefix_url);
println!("Mounting static files on {}", static_url);
let web_dir_name = matches.opt_str("w"); let web_dir_name = matches.opt_str("w");
let mut default_web_dir = utils::get_data_root()?; let mut default_web_dir = utils::get_data_root()?;
default_web_dir.push("web"); default_web_dir.push("web");
@ -175,7 +180,7 @@ fn run() -> Result<()> {
.map(|n| Path::new(n.as_str()).to_path_buf()) .map(|n| Path::new(n.as_str()).to_path_buf())
.unwrap_or(default_web_dir); .unwrap_or(default_web_dir);
mount.mount("/", Static::new(web_dir_path)); mount.mount(&static_url, Static::new(web_dir_path));
println!("Starting up server"); println!("Starting up server");
let port: u16 = matches.opt_str("p").unwrap_or("5050".to_owned()).parse().or(Err("invalid port number"))?; let port: u16 = matches.opt_str("p").unwrap_or("5050".to_owned()).parse().or(Err("invalid port number"))?;