Updated the user management example to be more accessible

This commit is contained in:
Emi Tatsuo 2020-11-22 01:29:24 -05:00
parent 916ac1009c
commit 502e68f1aa
Signed by: Emi
GPG key ID: 68FAB2E2E6DFC98B

View file

@ -2,32 +2,118 @@ use anyhow::*;
use log::LevelFilter; use log::LevelFilter;
use northstar::{ use northstar::{
GEMINI_PORT, GEMINI_PORT,
Document,
Request, Request,
Response, Response,
Server, Server,
user_management::UserManagementRoutes, user_management::{
User,
UserManagementRoutes,
},
}; };
#[tokio::main] #[tokio::main]
/// An ultra-simple demonstration of authentication.
///
/// The user should be able to set a secret string that only they can see. They should be
/// able to change this at any time to any thing. Both the string and the user account
/// will persist across restarts.
///
/// This method sets up and starts the server
async fn main() -> Result<()> { async fn main() -> Result<()> {
// Turn on logging
env_logger::builder() env_logger::builder()
.filter_module("northstar", LevelFilter::Debug) .filter_module("northstar", LevelFilter::Debug)
.init(); .init();
Server::bind(("0.0.0.0", GEMINI_PORT)) Server::bind(("0.0.0.0", GEMINI_PORT))
.add_route("/", handle_request)
// Add our main routes
.add_route("/", handle_main)
.add_route("/update", handle_update)
// Add routes for handling user authentication
.add_um_routes::<String>("/") .add_um_routes::<String>("/")
// Start the server
.serve() .serve()
.await .await
} }
/// An ultra-simple demonstration of simple authentication. /// The landing page
/// ///
/// If the user attempts to connect, they will be prompted to create a client certificate. /// Displays the user's current secret string, or prompts the user to sign in if they
/// Once they've made one, they'll be given the opportunity to create an account by /// haven't. Includes links to update your string (`/update`) or your account
/// selecting a username. They'll then get a message confirming their account creation. /// (`/account`). Even though we haven't added an explicit handler for `/account`, this
/// Any time this user visits the site in the future, they'll get a personalized welcome /// route is managed by northstar.
/// message. async fn handle_main(request: Request) -> Result<Response> {
async fn handle_request(_request: Request) -> Result<Response> {
Ok(Response::success_plain("Base handler")) // Check to see if the user is signed in. If they are, we get a copy of their data
// (just a simple [`String`] for this demo, but this can be any serializable struct.
if let User::SignedIn(user) = request.user::<String>()? {
// If the user is signed in, render and return their page
let response = Document::new()
.add_text("Your personal secret string:")
.add_text(user.as_ref())
.add_blank_line()
.add_link("/update", "Change your string")
.add_link("/account", "Update your account")
.into();
Ok(response)
} else {
// If the user is not logged in, prompt them to go to /account
let response = Document::new()
.add_text("Please login to use this app.")
.add_blank_line()
.add_link("/account", "Login or create account")
.into();
Ok(response)
}
}
/// The update endpoint
///
/// Users can update their secret string here. Users who haven't logged in will be
/// promped to do so.
async fn handle_update(request: Request) -> Result<Response> {
// Check if the user is signed in again
if let User::SignedIn(mut user) = request.user::<String>()? {
// If the user is logged in, check to see if they provided any input. If they
// have, we can set that input as their new string, otherwise we ask them for it
if let Some(string) = request.input() {
// Update the users data
*user.as_mut() = string.to_owned();
// Render a response
let response = Document::new()
.add_text("String updated!")
.add_blank_line()
.add_link("/", "Back")
.into();
Ok(response)
} else {
// Ask the user for some input
Ok(Response::input_lossy("Enter your new string"))
}
} else {
// The user isn't logged in, so we should ask them too
let response = Document::new()
.add_text("Please login to use this app.")
.add_blank_line()
.add_link("/account", "Login or create account")
.into();
Ok(response)
}
} }