user list, user create w/ endpoints, misc

This commit is contained in:
2026-03-04 22:46:46 +01:00
parent de6ea0d913
commit 2ebbc88c0a
4 changed files with 45 additions and 2 deletions

View File

@@ -18,15 +18,21 @@ mod users;
pub fn api_router() -> Router { pub fn api_router() -> Router {
Router::new() Router::new()
.route("/api/live", get(async || "Mnemosyne lives")) .route("/api/live", get(async || "Mnemosyne lives"))
//
.route("/api/auth/login", post(auth::login)) .route("/api/auth/login", post(auth::login))
.route("/api/auth/logout", post(auth::logout)) .route("/api/auth/logout", post(auth::logout))
//
.route("/api/users", get(users::get_all))
.route("/api/users", post(users::create))
.route("/api/users/me", get(users::get_me)) .route("/api/users/me", get(users::get_me))
.route("/api/users/{id}", get(users::get_by_id)) .route("/api/users/{id}", get(users::get_by_id))
.route("/api/users/@{handle}", get(users::get_by_handle)) .route("/api/users/@{handle}", get(users::get_by_handle))
.route("/api/users/{id}/setpassw", post(users::change_password)) .route("/api/users/{id}/setpassw", post(users::change_password))
.route("/api/users/{id}/sethandle", post(users::change_handle)) .route("/api/users/{id}/sethandle", post(users::change_handle))
//
.route("/api/sessions/{id}", get(sessions::get_by_id)) .route("/api/sessions/{id}", get(sessions::get_by_id))
.route("/api/sessions/{id}/revoke", post(sessions::revoke_by_id)) .route("/api/sessions/{id}/revoke", post(sessions::revoke_by_id))
//
.route("/api/tags/{id}", get(tags::get_by_id)) .route("/api/tags/{id}", get(tags::get_by_id))
.route("/api/tags/#{name}", get(tags::get_by_name)) .route("/api/tags/#{name}", get(tags::get_by_name))
} }

View File

@@ -19,6 +19,7 @@ use crate::{
const CANT_CHANGE_OTHERS_HANDLE: &str = "You don't have permission to change this user's handle."; const CANT_CHANGE_OTHERS_HANDLE: &str = "You don't have permission to change this user's handle.";
const CANT_CHANGE_OTHERS_PASSW: &str = "You don't have permission to change this user's password."; const CANT_CHANGE_OTHERS_PASSW: &str = "You don't have permission to change this user's password.";
const CANT_MANUALLY_MAKE_USERS: &str = "You don't have permission to manually create new users.";
const HANDLE_CHANGED_SUCCESS: &str = "Handle changed successfully."; const HANDLE_CHANGED_SUCCESS: &str = "Handle changed successfully.";
const PASSW_CHANGED_SUCCESS: &str = "Password changed successfully."; const PASSW_CHANGED_SUCCESS: &str = "Password changed successfully.";
@@ -42,14 +43,29 @@ pub async fn get_by_handle(
Ok(Json(User::get_by_handle(handle)?).into_response()) Ok(Json(User::get_by_handle(handle)?).into_response())
} }
pub async fn get_all(headers: HeaderMap) -> Result<Response, CompositeError> {
User::authenticate(&headers)?.required()?;
Ok(Json(User::get_all()?).into_response())
}
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct ChangeHandleForm { pub struct HandleForm {
handle: UserHandle, handle: UserHandle,
} }
pub async fn create(
headers: HeaderMap,
Json(form): Json<HandleForm>,
) -> Result<Response, CompositeError> {
let u = User::authenticate(&headers)?.required()?;
if !u.has_permission(Permission::ManuallyCreateUsers)? {
return Ok((StatusCode::FORBIDDEN, CANT_MANUALLY_MAKE_USERS).into_response());
}
Ok(Json(User::create(form.handle)?).into_response())
}
pub async fn change_handle( pub async fn change_handle(
Path(id): Path<Uuid>, Path(id): Path<Uuid>,
headers: HeaderMap, headers: HeaderMap,
Json(form): Json<ChangeHandleForm>, Json(form): Json<HandleForm>,
) -> Result<Response, CompositeError> { ) -> Result<Response, CompositeError> {
let u = User::authenticate(&headers)?.required()?; let u = User::authenticate(&headers)?.required()?;
let mut target = if u.id == id { let mut target = if u.id == id {

View File

@@ -74,6 +74,26 @@ impl User {
None => Err(UserError::NoUserWithHandle(handle)), None => Err(UserError::NoUserWithHandle(handle)),
} }
} }
pub fn get_all() -> Result<Vec<User>, UserError> {
Ok(database::conn()?
.prepare("SELECT id, handle FROM users")?
.query_map((), |r| {
Ok(User {
id: r.get(0)?,
handle: r.get(1)?,
})
})?
.collect::<Result<Vec<User>, _>>()?)
}
pub fn create(handle: UserHandle) -> Result<User, UserError> {
let conn = database::conn()?;
let id = Uuid::now_v7();
conn.prepare("INSERT INTO users(id, handle) VALUES (?1, ?2)")?
.execute((&id, &handle))?;
Ok(User { id, handle })
}
pub fn set_handle(&mut self, new_handle: UserHandle) -> Result<(), UserError> { pub fn set_handle(&mut self, new_handle: UserHandle) -> Result<(), UserError> {
let conn = database::conn()?; let conn = database::conn()?;
conn.prepare("UPDATE users SET handle = ?1 WHERE id = ?2")? conn.prepare("UPDATE users SET handle = ?1 WHERE id = ?2")?

View File

@@ -10,6 +10,7 @@ pub enum Permission {
ChangeOthersPasswords, ChangeOthersPasswords,
// All Users have the right to change their own handle // All Users have the right to change their own handle
ChangeOthersHandles, ChangeOthersHandles,
ManuallyCreateUsers,
} }
impl User { impl User {