add: schema, add user but no middleware

This commit is contained in:
2025-05-11 20:16:42 -07:00
parent a68ffc4bb7
commit 66d8144a03
8 changed files with 198 additions and 10 deletions

87
src/app/user.rs Normal file
View File

@@ -0,0 +1,87 @@
use leptos::prelude::*;
#[server]
pub async fn set_user(display_name: String, secret: String) -> Result<(), ServerFnError> {
use crate::common::Context;
use axum::http::{HeaderName, HeaderValue};
use leptos_axum::ResponseOptions;
use log::info;
use rand::{distr::Alphanumeric, Rng};
let mut secret = secret;
if display_name.len() == 0 && secret.len() == 0 {
return Err(ServerFnError::MissingArg(
"need either secret or display_name".into(),
));
}
info!("set_user called");
let data = use_context::<Context>().unwrap();
let mut client = data.client.lock().await;
let txn = client.transaction().await?;
// If the secret exists, update the database
if secret.len() > 0 {
// Validate the secret exists
txn.query_one("SELECT user_id FROM Users WHERE priv = $1", &[&secret])
.await?;
// Update display name if needed
if display_name.len() > 0 {
info!("Updating user with name {}", &display_name);
txn.execute(
"UPDATE Users SET display_name = $1 WHERE secret = $2;",
&[&display_name, &secret],
)
.await?;
}
} else if secret.len() == 0 {
// Create a new secret
info!("Creating user with name {}", &display_name);
secret = rand::rng()
.sample_iter(&Alphanumeric)
.take(4096)
.map(char::from)
.collect();
let public: String = rand::rng()
.sample_iter(&Alphanumeric)
.take(16)
.map(char::from)
.collect();
txn.execute(
"INSERT INTO Users (display_name, priv, pub) VALUES ($1, $2, $3);",
&[&display_name, &secret, &public],
)
.await?;
}
txn.commit().await?;
info!("Setting headers");
// Set user auth token
let response = expect_context::<ResponseOptions>();
info!("Appending header");
response.insert_header(
HeaderName::from_static("authorization"),
HeaderValue::from_str(&format! {"Basic {}", secret})?,
);
info!("Returning");
Ok(())
}
/// Renders the home page of your application.
#[component]
pub fn User() -> impl IntoView {
let set_user = ServerMultiAction::<SetUser>::new();
let create_user_view = view! {
<MultiActionForm action=set_user>
<div>
<p>"Display name to use; this will change your display name if you set a secret"</p>
<label>"Display name" <input type="text" name="display_name"/></label>
</div>
<div>
<p>"Leave blank to create a new user; enter the secret key to login to an existing user"</p>
<label>"Secret" <input type="text" name="secret"/></label>
</div>
<div>
<input type="submit" value="Login"/>
</div>
</MultiActionForm>
};
create_user_view
}