Added add_authenticated_input_route
This commit is contained in:
parent
edbfd3ed78
commit
9916770bd2
|
@ -30,7 +30,7 @@ async fn main() -> Result<()> {
|
|||
|
||||
// Add our main routes
|
||||
.add_authenticated_route("/", handle_main)
|
||||
.add_authenticated_route("/update", handle_update)
|
||||
.add_authenticated_input_route("/update", "Enter your new string:", handle_update)
|
||||
|
||||
// Add routes for handling user authentication
|
||||
.add_um_routes::<String>("/")
|
||||
|
@ -64,28 +64,20 @@ async fn handle_main(_req: Request, user: RegisteredUser<String>) -> Result<Resp
|
|||
/// The update endpoint
|
||||
///
|
||||
/// Users can update their secret string here.
|
||||
async fn handle_update(request: Request, mut user: RegisteredUser<String>) -> Result<Response> {
|
||||
async fn handle_update(_request: Request, mut user: RegisteredUser<String>, input: String) -> Result<Response> {
|
||||
|
||||
// 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() {
|
||||
// The user has already been prompted to log in if they weren't and asked to give an
|
||||
// input string, so all we need to do is...
|
||||
|
||||
// Update the users data
|
||||
*user.as_mut() = string.to_owned();
|
||||
// Update the users data
|
||||
*user.as_mut() = input;
|
||||
|
||||
// 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"))
|
||||
|
||||
}
|
||||
// Render a response
|
||||
let response = Document::new()
|
||||
.add_text("String updated!")
|
||||
.add_blank_line()
|
||||
.add_link("/", "Back")
|
||||
.into();
|
||||
Ok(response)
|
||||
|
||||
}
|
||||
|
|
|
@ -47,6 +47,38 @@ pub trait UserManagementRoutes: private::Sealed {
|
|||
UserData: Serialize + DeserializeOwned + 'static + Send + Sync,
|
||||
Handler: Clone + Send + Sync + 'static + Fn(Request, RegisteredUser<UserData>) -> F,
|
||||
F: Send + Sync + 'static + Future<Output = Result<Response>>;
|
||||
|
||||
/// Add a special route that requires users to be logged in AND takes input
|
||||
///
|
||||
/// Like with [`add_authenticated_route()`](Self::add_authenticated_route()), this
|
||||
/// prompts the user to log in if they haven't already, but additionally prompts the
|
||||
/// user for input before running the handler with both the user object and the input
|
||||
/// they provided.
|
||||
///
|
||||
/// To a user, this might look something like this:
|
||||
/// * Click a link to `/your/route`
|
||||
/// * See a screen asking you to sign in or create an account
|
||||
/// * Create a new account, and return to the app.
|
||||
/// * Now, clicking the link shows the prompt provided.
|
||||
/// * After entering some value, the user receives the response from the handler.
|
||||
///
|
||||
/// For a user whose already logged in, this will just look like a normal input route,
|
||||
/// where they enter some query and see a page. This method just takes the burden of
|
||||
/// having to check if the user sent a query string and respond with an INPUT response
|
||||
/// if not.
|
||||
///
|
||||
/// To use this method, ensure that [`add_um_routes()`](Self::add_um_routes()) has
|
||||
/// also been called.
|
||||
fn add_authenticated_input_route<UserData, Handler, F>(
|
||||
self,
|
||||
path: &'static str,
|
||||
prompt: &'static str,
|
||||
handler: Handler,
|
||||
) -> Self
|
||||
where
|
||||
UserData: Serialize + DeserializeOwned + 'static + Send + Sync,
|
||||
Handler: Clone + Send + Sync + 'static + Fn(Request, RegisteredUser<UserData>, String) -> F,
|
||||
F: Send + Sync + 'static + Future<Output = Result<Response>>;
|
||||
}
|
||||
|
||||
impl<A: ToSocketAddrs> UserManagementRoutes for crate::Builder<A> {
|
||||
|
@ -91,6 +123,32 @@ impl<A: ToSocketAddrs> UserManagementRoutes for crate::Builder<A> {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Add a special route that requires users to be logged in AND takes input
|
||||
///
|
||||
/// See [`UserManagementRoutes::add_authenticated_input_route()`]
|
||||
fn add_authenticated_input_route<UserData, Handler, F>(
|
||||
self,
|
||||
path: &'static str,
|
||||
prompt: &'static str,
|
||||
handler: Handler,
|
||||
) -> Self
|
||||
where
|
||||
UserData: Serialize + DeserializeOwned + 'static + Send + Sync,
|
||||
Handler: Clone + Send + Sync + 'static + Fn(Request, RegisteredUser<UserData>, String) -> F,
|
||||
F: Send + Sync + 'static + Future<Output = Result<Response>>
|
||||
{
|
||||
self.add_authenticated_route(path, move|request, user| {
|
||||
let handler = handler.clone();
|
||||
async move {
|
||||
if let Some(input) = request.input().map(str::to_owned) {
|
||||
(handler.clone())(request, user, input).await
|
||||
} else {
|
||||
Response::input(prompt)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_base<UserData: Serialize + DeserializeOwned>(request: Request, redirect: &'static str) -> Result<Response> {
|
||||
|
|
Loading…
Reference in a new issue