diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-05-05 16:23:09 +0200 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2023-05-05 16:23:09 +0200 |
commit | ddfb939e57f71570c2d93ba25b4d11db3f47cbfb (patch) | |
tree | 642847b724121ea44c78ceb648075646125119d5 | |
parent | f56fc06ddb134b8b1424c81bba55a4254971aeaf (diff) |
simple reboot server
-rw-r--r-- | Cargo.lock | 57 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/main.rs | 68 |
3 files changed, 114 insertions, 13 deletions
@@ -31,7 +31,7 @@ dependencies = [ "actix-tls", "actix-utils", "ahash 0.8.3", - "base64", + "base64 0.21.0", "bitflags", "brotli", "bytes", @@ -204,6 +204,21 @@ dependencies = [ ] [[package]] +name = "actix-web-httpauth" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dda62cf04bc3a9ad2ea8f314f721951cfdb4cdacec4e984d20e77c7bb170991" +dependencies = [ + "actix-utils", + "actix-web", + "base64 0.13.1", + "futures-core", + "futures-util", + "log", + "pin-project-lite", +] + +[[package]] name = "adler" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -264,6 +279,12 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" @@ -470,6 +491,7 @@ dependencies = [ "futures-task", "pin-project-lite", "pin-utils", + "slab", ] [[package]] @@ -650,6 +672,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -677,6 +708,20 @@ dependencies = [ ] [[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset", + "pin-utils", + "static_assertions", +] + +[[package]] name = "num_cpus" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -854,6 +899,8 @@ name = "rustkrazy_admind" version = "0.1.0" dependencies = [ "actix-web", + "actix-web-httpauth", + "nix", "rustls", "rustls-pemfile", "thiserror", @@ -877,7 +924,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64", + "base64 0.21.0", ] [[package]] @@ -989,6 +1036,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] name = "syn" version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7,6 +7,8 @@ edition = "2021" [dependencies] actix-web = { version = "4.3.1", features = ["rustls"] } +actix-web-httpauth = "0.8.0" +nix = "0.26.2" rustls = "0.20.0" rustls-pemfile = "1.0.2" thiserror = "1.0" diff --git a/src/main.rs b/src/main.rs index 1f2c99f..6b058ab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,14 +3,57 @@ use rustkrazy_admind::{Error, Result}; use std::fs::File; use std::io::{self, BufReader}; -use actix_web::{http::header::ContentType, web, App, HttpRequest, HttpResponse, HttpServer}; +use actix_web::{ + dev::ServiceRequest, http::header::ContentType, web, App, HttpResponse, HttpServer, +}; +use actix_web_httpauth::extractors::basic::{BasicAuth, Config}; +use actix_web_httpauth::extractors::AuthenticationError; +use actix_web_httpauth::middleware::HttpAuthentication; +use nix::sys::reboot::{reboot, RebootMode}; use rustls::{Certificate, PrivateKey, ServerConfig}; use rustls_pemfile::{certs, pkcs8_private_keys}; -async fn index(req: HttpRequest) -> HttpResponse { - HttpResponse::Ok() - .content_type(ContentType::plaintext()) - .body("it works") +async fn handle_reboot() -> HttpResponse { + match reboot(RebootMode::RB_AUTOBOOT) { + Ok(_) => HttpResponse::Ok() + .content_type(ContentType::plaintext()) + .body("rebooting..."), + Err(e) => HttpResponse::InternalServerError() + .content_type(ContentType::plaintext()) + .body(format!("can't reboot: {}", e)), + } +} + +async fn basic_auth_validator( + req: ServiceRequest, + credentials: BasicAuth, +) -> std::result::Result<ServiceRequest, (actix_web::Error, ServiceRequest)> { + let config = req.app_data::<Config>().cloned().unwrap_or_default(); + + match validate_credentials( + credentials.user_id(), + credentials.password().unwrap_or_default().trim(), + ) { + Ok(res) => { + if res { + Ok(req) + } else { + Err((AuthenticationError::from(config).into(), req)) + } + } + Err(_) => Err((AuthenticationError::from(config).into(), req)), + } +} + +fn validate_credentials(user_id: &str, user_password: &str) -> io::Result<bool> { + if user_id == "rustkrazy" && user_password == "rustkrazy" { + return Ok(true); + } + + Err(io::Error::new( + io::ErrorKind::PermissionDenied, + "Invalid credentials", + )) } #[actix_web::main] @@ -31,12 +74,15 @@ async fn start() -> Result<()> { println!("[admind] start https://[::]:8443"); - Ok( - HttpServer::new(|| App::new().service(web::resource("/").to(index))) - .bind_rustls("[::]:8443", config)? - .run() - .await?, - ) + Ok(HttpServer::new(|| { + let auth = HttpAuthentication::basic(basic_auth_validator); + App::new() + .wrap(auth) + .service(web::resource("/rustkrazy/reboot").to(handle_reboot)) + }) + .bind_rustls("[::]:8443", config)? + .run() + .await?) } fn load_rustls_config() -> Result<ServerConfig> { |