diff options
author | Dessalines <tyhou13@gmx.com> | 2020-04-14 16:07:20 -0400 |
---|---|---|
committer | Dessalines <tyhou13@gmx.com> | 2020-04-14 16:07:20 -0400 |
commit | 1336b4ed6023e7fcf0fd40be63569966ee4b1b45 (patch) | |
tree | e62e4422e0ba0430ea6d060f01d20dee22d6e564 /server | |
parent | f040dac647d50c97e3f9ab8058563a7fe0f29261 (diff) | |
parent | 641e4c5d96d9d152bc75318b3ea08f789d920b2b (diff) |
Merge branch 'dev' into federation
Diffstat (limited to 'server')
-rw-r--r-- | server/src/api/site.rs | 70 | ||||
-rw-r--r-- | server/src/lib.rs | 4 | ||||
-rw-r--r-- | server/src/main.rs | 1 | ||||
-rw-r--r-- | server/src/routes/api.rs | 2 | ||||
-rw-r--r-- | server/src/routes/index.rs | 3 | ||||
-rw-r--r-- | server/src/settings.rs | 45 | ||||
-rw-r--r-- | server/src/version.rs | 2 | ||||
-rw-r--r-- | server/src/websocket/mod.rs | 2 | ||||
-rw-r--r-- | server/src/websocket/server.rs | 10 |
9 files changed, 122 insertions, 17 deletions
diff --git a/server/src/api/site.rs b/server/src/api/site.rs index ad45e8d1..4202fea0 100644 --- a/server/src/api/site.rs +++ b/server/src/api/site.rs @@ -97,6 +97,22 @@ pub struct TransferSite { auth: String, } +#[derive(Serialize, Deserialize)] +pub struct GetSiteConfig { + auth: String, +} + +#[derive(Serialize, Deserialize)] +pub struct GetSiteConfigResponse { + config_hjson: String, +} + +#[derive(Serialize, Deserialize)] +pub struct SaveSiteConfig { + config_hjson: String, + auth: String, +} + impl Perform<ListCategoriesResponse> for Oper<ListCategories> { fn perform(&self, conn: &PgConnection) -> Result<ListCategoriesResponse, Error> { let _data: &ListCategories = &self.data; @@ -514,3 +530,57 @@ impl Perform<GetSiteResponse> for Oper<TransferSite> { }) } } + +impl Perform<GetSiteConfigResponse> for Oper<GetSiteConfig> { + fn perform(&self, conn: &PgConnection) -> Result<GetSiteConfigResponse, Error> { + let data: &GetSiteConfig = &self.data; + + let claims = match Claims::decode(&data.auth) { + Ok(claims) => claims.claims, + Err(_e) => return Err(APIError::err("not_logged_in").into()), + }; + + let user_id = claims.id; + + // Only let admins read this + let admins = UserView::admins(&conn)?; + let admin_ids: Vec<i32> = admins.into_iter().map(|m| m.id).collect(); + + if !admin_ids.contains(&user_id) { + return Err(APIError::err("not_an_admin").into()); + } + + let config_hjson = Settings::read_config_file()?; + + Ok(GetSiteConfigResponse { config_hjson }) + } +} + +impl Perform<GetSiteConfigResponse> for Oper<SaveSiteConfig> { + fn perform(&self, conn: &PgConnection) -> Result<GetSiteConfigResponse, Error> { + let data: &SaveSiteConfig = &self.data; + + let claims = match Claims::decode(&data.auth) { + Ok(claims) => claims.claims, + Err(_e) => return Err(APIError::err("not_logged_in").into()), + }; + + let user_id = claims.id; + + // Only let admins read this + let admins = UserView::admins(&conn)?; + let admin_ids: Vec<i32> = admins.into_iter().map(|m| m.id).collect(); + + if !admin_ids.contains(&user_id) { + return Err(APIError::err("not_an_admin").into()); + } + + // Make sure docker doesn't have :ro at the end of the volume, so its not a read-only filesystem + let config_hjson = match Settings::save_config_file(&data.config_hjson) { + Ok(config_hjson) => config_hjson, + Err(_e) => return Err(APIError::err("couldnt_update_site").into()), + }; + + Ok(GetSiteConfigResponse { config_hjson }) + } +} diff --git a/server/src/lib.rs b/server/src/lib.rs index e45311ee..2c78cfc2 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -115,7 +115,7 @@ pub fn send_email( to_username: &str, html: &str, ) -> Result<(), String> { - let email_config = Settings::get().email.as_ref().ok_or("no_email_setup")?; + let email_config = Settings::get().email.ok_or("no_email_setup")?; let email = Email::builder() .to((to_email, to_username)) @@ -130,7 +130,7 @@ pub fn send_email( } else { SmtpClient::new(&email_config.smtp_server, ClientSecurity::None).unwrap() } - .hello_name(ClientId::Domain(Settings::get().hostname.to_owned())) + .hello_name(ClientId::Domain(Settings::get().hostname)) .smtp_utf8(true) .authentication_mechanism(Mechanism::Plain) .connection_reuse(ConnectionReuseParameters::ReuseUnlimited); diff --git a/server/src/main.rs b/server/src/main.rs index 59dc2cb7..88d62eb9 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -57,6 +57,7 @@ async fn main() -> Result<(), Error> { // Create Http server with websocket support Ok( HttpServer::new(move || { + let settings = Settings::get(); App::new() .wrap(middleware::Logger::default()) .data(pool.clone()) diff --git a/server/src/routes/api.rs b/server/src/routes/api.rs index 29a360e4..36a55f96 100644 --- a/server/src/routes/api.rs +++ b/server/src/routes/api.rs @@ -52,6 +52,8 @@ pub fn config(cfg: &mut web::ServiceConfig) { .route("/api/v1/site", web::post().to(route_post::<CreateSite, SiteResponse>)) .route("/api/v1/site", web::put().to(route_post::<EditSite, SiteResponse>)) .route("/api/v1/site/transfer", web::post().to(route_post::<TransferSite, GetSiteResponse>)) + .route("/api/v1/site/config", web::get().to(route_get::<GetSiteConfig, GetSiteConfigResponse>)) + .route("/api/v1/site/config", web::put().to(route_post::<SaveSiteConfig, GetSiteConfigResponse>)) .route("/api/v1/admin/add", web::post().to(route_post::<AddAdmin, AddAdminResponse>)) .route("/api/v1/user/ban", web::post().to(route_post::<BanUser, BanUserResponse>)) // User account actions diff --git a/server/src/routes/index.rs b/server/src/routes/index.rs index c1c363c9..2e192df4 100644 --- a/server/src/routes/index.rs +++ b/server/src/routes/index.rs @@ -33,6 +33,7 @@ pub fn config(cfg: &mut web::ServiceConfig) { .route("/modlog/community/{community_id}", web::get().to(index)) .route("/modlog", web::get().to(index)) .route("/setup", web::get().to(index)) + .route("/admin", web::get().to(index)) .route( "/search/q/{q}/type/{type}/sort/{sort}/page/{page}", web::get().to(index), @@ -44,6 +45,6 @@ pub fn config(cfg: &mut web::ServiceConfig) { async fn index() -> Result<NamedFile, actix_web::error::Error> { Ok(NamedFile::open( - Settings::get().front_end_dir.to_owned() + "/index.html", + Settings::get().front_end_dir + "/index.html", )?) } diff --git a/server/src/settings.rs b/server/src/settings.rs index 29d5966b..8c3cd6a1 100644 --- a/server/src/settings.rs +++ b/server/src/settings.rs @@ -1,12 +1,15 @@ use config::{Config, ConfigError, Environment, File}; +use failure::Error; use serde::Deserialize; use std::env; +use std::fs; use std::net::IpAddr; +use std::sync::RwLock; static CONFIG_FILE_DEFAULTS: &str = "config/defaults.hjson"; static CONFIG_FILE: &str = "config/config.hjson"; -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Clone)] pub struct Settings { pub setup: Option<Setup>, pub database: Database, @@ -20,7 +23,7 @@ pub struct Settings { pub federation: Federation, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Clone)] pub struct Setup { pub admin_username: String, pub admin_password: String, @@ -28,7 +31,7 @@ pub struct Setup { pub site_name: String, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Clone)] pub struct RateLimitConfig { pub message: i32, pub message_per_second: i32, @@ -38,7 +41,7 @@ pub struct RateLimitConfig { pub register_per_second: i32, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Clone)] pub struct EmailConfig { pub smtp_server: String, pub smtp_login: Option<String>, @@ -47,7 +50,7 @@ pub struct EmailConfig { pub use_tls: bool, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Clone)] pub struct Database { pub user: String, pub password: String, @@ -65,12 +68,10 @@ pub struct Federation { } lazy_static! { - static ref SETTINGS: Settings = { - match Settings::init() { - Ok(c) => c, - Err(e) => panic!("{}", e), - } - }; + static ref SETTINGS: RwLock<Settings> = RwLock::new(match Settings::init() { + Ok(c) => c, + Err(e) => panic!("{}", e), + }); } impl Settings { @@ -96,8 +97,8 @@ impl Settings { } /// Returns the config as a struct. - pub fn get() -> &'static Self { - &SETTINGS + pub fn get() -> Self { + SETTINGS.read().unwrap().to_owned() } /// Returns the postgres connection url. If LEMMY_DATABASE_URL is set, that is used, @@ -119,4 +120,22 @@ impl Settings { pub fn api_endpoint(&self) -> String { format!("{}/api/v1", self.hostname) } + + pub fn read_config_file() -> Result<String, Error> { + Ok(fs::read_to_string(CONFIG_FILE)?) + } + + pub fn save_config_file(data: &str) -> Result<String, Error> { + fs::write(CONFIG_FILE, data)?; + + // Reload the new settings + // From https://stackoverflow.com/questions/29654927/how-do-i-assign-a-string-to-a-mutable-static-variable/47181804#47181804 + let mut new_settings = SETTINGS.write().unwrap(); + *new_settings = match Settings::init() { + Ok(c) => c, + Err(e) => panic!("{}", e), + }; + + Self::read_config_file() + } } diff --git a/server/src/version.rs b/server/src/version.rs index 1491a0a2..f02e9ae5 100644 --- a/server/src/version.rs +++ b/server/src/version.rs @@ -1 +1 @@ -pub const VERSION: &str = "v0.6.44"; +pub const VERSION: &str = "v0.6.49"; diff --git a/server/src/websocket/mod.rs b/server/src/websocket/mod.rs index a1feede2..c7136423 100644 --- a/server/src/websocket/mod.rs +++ b/server/src/websocket/mod.rs @@ -46,4 +46,6 @@ pub enum UserOperation { GetPrivateMessages, UserJoin, GetComments, + GetSiteConfig, + SaveSiteConfig, } diff --git a/server/src/websocket/server.rs b/server/src/websocket/server.rs index f205c91e..faa8041c 100644 --- a/server/src/websocket/server.rs +++ b/server/src/websocket/server.rs @@ -708,6 +708,16 @@ fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result<Str res.online = chat.sessions.len(); to_json_string(&user_operation, &res) } + UserOperation::GetSiteConfig => { + let get_site_config: GetSiteConfig = serde_json::from_str(data)?; + let res = Oper::new(get_site_config).perform(&conn)?; + to_json_string(&user_operation, &res) + } + UserOperation::SaveSiteConfig => { + let save_site_config: SaveSiteConfig = serde_json::from_str(data)?; + let res = Oper::new(save_site_config).perform(&conn)?; + to_json_string(&user_operation, &res) + } UserOperation::Search => { do_user_operation::<Search, SearchResponse>(user_operation, data, &conn) } |