Add server config route
This commit is contained in:
12
matrixgw_backend/Cargo.lock
generated
12
matrixgw_backend/Cargo.lock
generated
@@ -68,6 +68,17 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "actix-remote-ip"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7629b357d4705cf3f1e31f989f48ecd56027112f7d52dcf06dd96ee197065f8e"
|
||||
dependencies = [
|
||||
"actix-web",
|
||||
"futures-util",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "actix-router"
|
||||
version = "0.5.3"
|
||||
@@ -1405,6 +1416,7 @@ checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
|
||||
name = "matrixgw_backend"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix-remote-ip",
|
||||
"actix-session",
|
||||
"actix-web",
|
||||
"anyhow",
|
||||
|
||||
@@ -14,3 +14,4 @@ rust-s3 = { version = "0.37.0", features = ["tokio"] }
|
||||
tokio = { version = "1.48.0", features = ["full"] }
|
||||
actix-web = "4.11.0"
|
||||
actix-session = { version = "0.11.0", features = ["redis-session"] }
|
||||
actix-remote-ip = "0.1.0"
|
||||
@@ -18,6 +18,11 @@ pub struct AppConfig {
|
||||
#[clap(short, long, env)]
|
||||
pub proxy_ip: Option<String>,
|
||||
|
||||
/// Unsecure : for development, bypass authentication, using the account with the given
|
||||
/// email address by default
|
||||
#[clap(long, env)]
|
||||
unsecure_auto_login_email: Option<String>,
|
||||
|
||||
/// Secret key, used to secure some resources. Must be randomly generated
|
||||
#[clap(short = 'S', long, env, default_value = "")]
|
||||
secret: String,
|
||||
@@ -54,6 +59,10 @@ pub struct AppConfig {
|
||||
)]
|
||||
pub oidc_configuration_url: String,
|
||||
|
||||
/// OpenID provider name
|
||||
#[arg(long, env, default_value = "3rd party provider")]
|
||||
pub oidc_provider_name: String,
|
||||
|
||||
/// OpenID client ID
|
||||
#[arg(long, env, default_value = "foo")]
|
||||
pub oidc_client_id: String,
|
||||
@@ -103,6 +112,14 @@ impl AppConfig {
|
||||
&ARGS
|
||||
}
|
||||
|
||||
/// Get auto login email (if not empty)
|
||||
pub fn unsecure_auto_login_email(&self) -> Option<&str> {
|
||||
match self.unsecure_auto_login_email.as_deref() {
|
||||
None | Some("") => None,
|
||||
s => s,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get app secret
|
||||
pub fn secret(&self) -> &str {
|
||||
let mut secret = self.secret.as_str();
|
||||
@@ -118,6 +135,11 @@ impl AppConfig {
|
||||
secret
|
||||
}
|
||||
|
||||
/// Check if auth is disabled
|
||||
pub fn is_auth_disabled(&self) -> bool {
|
||||
self.unsecure_auto_login_email().is_some()
|
||||
}
|
||||
|
||||
/// Get Redis connection configuration
|
||||
pub fn redis_connection_string(&self) -> String {
|
||||
format!(
|
||||
@@ -136,6 +158,7 @@ impl AppConfig {
|
||||
client_id: self.oidc_client_id.as_str(),
|
||||
client_secret: self.oidc_client_secret.as_str(),
|
||||
configuration_url: self.oidc_configuration_url.as_str(),
|
||||
name: self.oidc_provider_name.as_str(),
|
||||
redirect_url: self
|
||||
.oidc_redirect_url
|
||||
.replace("APP_ORIGIN", &self.website_origin),
|
||||
@@ -169,6 +192,7 @@ impl AppConfig {
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize)]
|
||||
pub struct OIDCProvider<'a> {
|
||||
pub name: &'a str,
|
||||
pub client_id: &'a str,
|
||||
pub client_secret: &'a str,
|
||||
pub configuration_url: &'a str,
|
||||
|
||||
1
matrixgw_backend/src/controllers/mod.rs
Normal file
1
matrixgw_backend/src/controllers/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod server_controller;
|
||||
74
matrixgw_backend/src/controllers/server_controller.rs
Normal file
74
matrixgw_backend/src/controllers/server_controller.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
use crate::app_config::AppConfig;
|
||||
use actix_web::HttpResponse;
|
||||
|
||||
/// Serve robots.txt (disallow ranking)
|
||||
pub async fn robots_txt() -> HttpResponse {
|
||||
HttpResponse::Ok()
|
||||
.content_type("text/plain")
|
||||
.body("User-agent: *\nDisallow: /\n")
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct LenConstraints {
|
||||
min: usize,
|
||||
max: usize,
|
||||
}
|
||||
|
||||
impl LenConstraints {
|
||||
pub fn new(min: usize, max: usize) -> Self {
|
||||
Self { min, max }
|
||||
}
|
||||
pub fn not_empty(max: usize) -> Self {
|
||||
Self { min: 1, max }
|
||||
}
|
||||
pub fn max_only(max: usize) -> Self {
|
||||
Self { min: 0, max }
|
||||
}
|
||||
|
||||
pub fn check_str(&self, s: &str) -> bool {
|
||||
s.len() >= self.min && s.len() <= self.max
|
||||
}
|
||||
|
||||
pub fn check_u32(&self, v: u32) -> bool {
|
||||
v >= self.min as u32 && v <= self.max as u32
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct ServerConstraints {
|
||||
pub token_name: LenConstraints,
|
||||
pub token_ip_net: LenConstraints,
|
||||
pub token_max_inactivity: LenConstraints,
|
||||
}
|
||||
|
||||
impl Default for ServerConstraints {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
token_name: LenConstraints::new(5, 255),
|
||||
token_ip_net: LenConstraints::max_only(44),
|
||||
token_max_inactivity: LenConstraints::new(3600, 3600 * 24 * 365),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
struct ServerConfig {
|
||||
auth_disabled: bool,
|
||||
oidc_provider_name: &'static str,
|
||||
constraints: ServerConstraints,
|
||||
}
|
||||
|
||||
impl Default for ServerConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
auth_disabled: AppConfig::get().is_auth_disabled(),
|
||||
oidc_provider_name: AppConfig::get().openid_provider().name,
|
||||
constraints: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Get server static configuration
|
||||
pub async fn config() -> HttpResponse {
|
||||
HttpResponse::Ok().json(ServerConfig::default())
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
pub mod app_config;
|
||||
pub mod controllers;
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
use actix_remote_ip::RemoteIPConfig;
|
||||
use actix_session::SessionMiddleware;
|
||||
use actix_session::config::SessionLifecycle;
|
||||
use actix_session::storage::RedisSessionStore;
|
||||
use actix_web::cookie::Key;
|
||||
use actix_web::{App, HttpServer};
|
||||
use actix_web::{App, HttpServer, web};
|
||||
use matrixgw_backend::app_config::AppConfig;
|
||||
use matrixgw_backend::controllers::server_controller;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
@@ -19,9 +23,26 @@ async fn main() -> std::io::Result<()> {
|
||||
AppConfig::get().website_origin
|
||||
);
|
||||
|
||||
HttpServer::new(move || App::new())
|
||||
.workers(4)
|
||||
.bind(&AppConfig::get().listen_address)?
|
||||
.run()
|
||||
.await
|
||||
HttpServer::new(move || {
|
||||
App::new()
|
||||
.wrap(
|
||||
SessionMiddleware::builder(redis_store.clone(), secret_key.clone())
|
||||
.cookie_name("matrixgw-session".to_string())
|
||||
.session_lifecycle(SessionLifecycle::BrowserSession(Default::default()))
|
||||
.build(),
|
||||
)
|
||||
.app_data(web::Data::new(RemoteIPConfig {
|
||||
proxy: AppConfig::get().proxy_ip.clone(),
|
||||
}))
|
||||
// Server controller
|
||||
.route("/robots.txt", web::get().to(server_controller::robots_txt))
|
||||
.route(
|
||||
"/api/server/config",
|
||||
web::get().to(server_controller::config),
|
||||
)
|
||||
})
|
||||
.workers(4)
|
||||
.bind(&AppConfig::get().listen_address)?
|
||||
.run()
|
||||
.await
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user