add: create user api

This commit is contained in:
trisua 2025-03-21 22:18:36 -04:00
parent 6dff656583
commit cda879f6df
11 changed files with 187 additions and 25 deletions

1
src/routes/api/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod v1;

41
src/routes/api/v1/auth.rs Normal file
View file

@ -0,0 +1,41 @@
use super::{ApiReturn, AuthProps};
use crate::{
State,
data::model::{Error, User},
get_user_from_token,
};
use axum::{Extension, Json, response::IntoResponse};
use axum_extra::extract::CookieJar;
pub async fn register_request(
jar: CookieJar,
Extension(data): Extension<State>,
Json(props): Json<AuthProps>,
) -> impl IntoResponse {
let data = data.read().await;
let user = get_user_from_token!((jar, data) <optional>);
if user.is_some() {
return Json(ApiReturn {
ok: false,
message: Error::AlreadyAuthenticated.to_string(),
payload: (),
});
}
match data
.create_user(User::new(props.username, props.password))
.await
{
Ok(_) => Json(ApiReturn {
ok: true,
message: "User created".to_string(),
payload: (),
}),
Err(_) => Json(ApiReturn {
ok: false,
message: Error::Unknown.to_string(),
payload: (),
}),
}
}

32
src/routes/api/v1/mod.rs Normal file
View file

@ -0,0 +1,32 @@
pub mod auth;
use axum::{Router, routing::post};
use serde::{Deserialize, Serialize};
pub fn routes() -> Router {
Router::new().route("/auth/register", post(auth::register_request))
}
#[derive(Serialize, Deserialize)]
pub struct ApiReturn<T>
where
T: Serialize,
{
pub ok: bool,
pub message: String,
pub payload: T,
}
impl<T> ApiReturn<T>
where
T: Serialize,
{
pub fn to_json(&self) -> String {
serde_json::to_string(&self).unwrap()
}
}
#[derive(Deserialize)]
pub struct AuthProps {
pub username: String,
pub password: String,
}

View file

@ -1,39 +1,58 @@
pub mod api;
pub mod assets;
use crate::State;
use crate::{State, get_user_from_token};
use axum::{
Extension, Router,
response::{Html, IntoResponse},
response::{Html, IntoResponse, Redirect},
routing::get,
};
use axum_extra::extract::CookieJar;
/// `/`
pub async fn index_request(Extension(data): Extension<State>) -> impl IntoResponse {
pub async fn index_request(jar: CookieJar, Extension(data): Extension<State>) -> impl IntoResponse {
let data = data.read().await;
let user = get_user_from_token!((jar, data) <optional>);
let mut context = data.initial_context();
Html(data.1.render("index.html", &mut context).unwrap())
}
/// `/_atto/login`
pub async fn login_request(Extension(data): Extension<State>) -> impl IntoResponse {
pub async fn login_request(jar: CookieJar, Extension(data): Extension<State>) -> impl IntoResponse {
let data = data.read().await;
let user = get_user_from_token!((jar, data) <optional>);
if user.is_some() {
return Err(Redirect::to("/"));
}
let mut context = data.initial_context();
Html(
Ok(Html(
data.1
.render("_atto/auth/login.html", &mut context)
.unwrap(),
)
))
}
/// `/_atto/register`
pub async fn register_request(Extension(data): Extension<State>) -> impl IntoResponse {
pub async fn register_request(
jar: CookieJar,
Extension(data): Extension<State>,
) -> impl IntoResponse {
let data = data.read().await;
let user = get_user_from_token!((jar, data) <optional>);
if user.is_some() {
return Err(Redirect::to("/"));
}
let mut context = data.initial_context();
Html(
Ok(Html(
data.1
.render("_atto/auth/register.html", &mut context)
.unwrap(),
)
))
}
pub fn routes() -> Router {
@ -41,6 +60,8 @@ pub fn routes() -> Router {
// assets
.route("/css/style.css", get(assets::style_css_request))
.route("/js/atto.js", get(assets::atto_js_request))
// api
.nest("/api/v1", api::v1::routes())
// pages
.route("/", get(index_request))
.route("/_atto/login", get(login_request))