kochab/examples/user_management.rs

68 lines
2.5 KiB
Rust

use anyhow::*;
use futures_core::future::BoxFuture;
use futures_util::FutureExt;
use log::LevelFilter;
use northstar::{
GEMINI_MIME,
GEMINI_PORT,
Request,
Response,
Server,
user_management::{User, UserManagerError},
};
#[tokio::main]
async fn main() -> Result<()> {
env_logger::builder()
.filter_module("northstar", LevelFilter::Debug)
.init();
Server::bind(("0.0.0.0", GEMINI_PORT))
.add_route("/", handle_request)
.serve()
.await
}
/// An ultra-simple demonstration of simple authentication.
///
/// If the user attempts to connect, they will be prompted to create a client certificate.
/// Once they've made one, they'll be given the opportunity to create an account by
/// selecting a username. They'll then get a message confirming their account creation.
/// Any time this user visits the site in the future, they'll get a personalized welcome
/// message.
fn handle_request(request: Request) -> BoxFuture<'static, Result<Response>> {
async move {
Ok(match request.user::<String>()? {
User::Unauthenticated => {
Response::client_certificate_required()
},
User::NotSignedIn(user) => {
if let Some(username) = request.input() {
match user.register::<String>(username.to_owned()) {
Ok(_user) => Response::success(&GEMINI_MIME)
.with_body("Your account has been created!\n=>/ Begin"),
Err(UserManagerError::UsernameNotUnique) =>
Response::input_lossy("That username is taken. Try again"),
Err(e) => panic!("Unexpected error: {}", e),
}
} else {
Response::input_lossy("Please pick a username")
}
},
User::SignedIn(mut user) => {
if request.path_segments()[0].eq("push") { // User connecting to /push
if let Some(push) = request.input() {
user.as_mut().push_str(push);
user.save()?;
} else {
return Ok(Response::input_lossy("Enter a string to push"));
}
}
Response::success(&GEMINI_MIME)
.with_body(format!("Your current string: {}\n=> /push Push", user.as_ref()))
}
})
}.boxed()
}