Updated the user management example to be more accessible
This commit is contained in:
parent
916ac1009c
commit
502e68f1aa
|
@ -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)
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue