Add the ability for a user to set their password
This commit is contained in:
parent
d9f1efb8d3
commit
792437af44
@ -141,7 +141,7 @@ pub async fn get_user(
|
|||||||
ResultExt::Ok(None) => (StatusCode::NOT_FOUND, Json(None)),
|
ResultExt::Ok(None) => (StatusCode::NOT_FOUND, Json(None)),
|
||||||
ResultExt::Err(_err) => (StatusCode::BAD_REQUEST, Json(None)),
|
ResultExt::Err(_err) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||||
ResultExt::Fatal(err) => panic!("{}", err),
|
ResultExt::Fatal(err) => panic!("{}", err),
|
||||||
}
|
},
|
||||||
None => (
|
None => (
|
||||||
StatusCode::OK,
|
StatusCode::OK,
|
||||||
Json(Some(UserProfile {
|
Json(Some(UserProfile {
|
||||||
@ -169,13 +169,39 @@ pub async fn create_user(
|
|||||||
admin_required(core.clone(), headers, |_admin| async {
|
admin_required(core.clone(), headers, |_admin| async {
|
||||||
match core.create_user(&req.username).await {
|
match core.create_user(&req.username).await {
|
||||||
ResultExt::Ok(_) => (StatusCode::OK, Json(None)),
|
ResultExt::Ok(_) => (StatusCode::OK, Json(None)),
|
||||||
ResultExt::Err(err) => (StatusCode::BAD_REQUEST, Json(None)),
|
ResultExt::Err(_err) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||||
ResultExt::Fatal(fatal) => panic!("{}", fatal),
|
ResultExt::Fatal(fatal) => panic!("{}", fatal),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
#[typeshare]
|
||||||
|
pub struct SetPasswordRequest {
|
||||||
|
pub password_1: String,
|
||||||
|
pub password_2: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn set_password(
|
||||||
|
core: Core,
|
||||||
|
headers: HeaderMap,
|
||||||
|
req: SetPasswordRequest,
|
||||||
|
) -> (StatusCode, Json<Option<()>>) {
|
||||||
|
auth_required(core.clone(), headers, |user| async {
|
||||||
|
if req.password_1 == req.password_2 {
|
||||||
|
match core.set_password(user.id, req.password_1).await {
|
||||||
|
ResultExt::Ok(_) => (StatusCode::OK, Json(None)),
|
||||||
|
ResultExt::Err(_err) => (StatusCode::BAD_REQUEST, Json(None)),
|
||||||
|
ResultExt::Fatal(fatal) => panic!("{}", fatal),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(StatusCode::BAD_REQUEST, Json(None))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub async fn handle_auth(
|
pub async fn handle_auth(
|
||||||
auth_ctx: &AuthDB,
|
auth_ctx: &AuthDB,
|
||||||
|
@ -3,7 +3,7 @@ use std::fmt;
|
|||||||
use axum::{
|
use axum::{
|
||||||
extract::Path,
|
extract::Path,
|
||||||
http::{HeaderMap, StatusCode},
|
http::{HeaderMap, StatusCode},
|
||||||
routing::{get, post},
|
routing::{get, post, put},
|
||||||
Json, Router,
|
Json, Router,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -11,7 +11,8 @@ use crate::{
|
|||||||
core::Core,
|
core::Core,
|
||||||
database::UserId,
|
database::UserId,
|
||||||
handlers::{
|
handlers::{
|
||||||
check_password, create_user, get_user, healthcheck, AuthRequest, CreateUserRequest,
|
check_password, create_user, get_user, healthcheck, set_password, AuthRequest,
|
||||||
|
CreateUserRequest, SetPasswordRequest,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,6 +47,16 @@ pub fn routes(core: Core) -> Router {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/api/v1/user/password",
|
||||||
|
put({
|
||||||
|
let core = core.clone();
|
||||||
|
move |headers: HeaderMap, req: Json<SetPasswordRequest>| {
|
||||||
|
let Json(req) = req;
|
||||||
|
set_password(core, headers, req)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
.route(
|
.route(
|
||||||
"/api/v1/user/:user_id",
|
"/api/v1/user/:user_id",
|
||||||
get({
|
get({
|
||||||
@ -253,9 +264,60 @@ mod test {
|
|||||||
assert_eq!(profile.username, "admin");
|
assert_eq!(profile.username, "admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn a_user_can_change_their_password() {
|
||||||
|
let (_core, server) = setup_with_user().await;
|
||||||
|
|
||||||
|
let response = server
|
||||||
|
.post("/api/v1/auth")
|
||||||
|
.json(&AuthRequest {
|
||||||
|
username: "savanni".to_owned(),
|
||||||
|
password: "".to_owned(),
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
let session_id: Option<SessionId> = response.json();
|
||||||
|
let session_id = session_id.unwrap();
|
||||||
|
|
||||||
|
let response = server
|
||||||
|
.get("/api/v1/user")
|
||||||
|
.add_header("Authorization", format!("Bearer {}", session_id))
|
||||||
|
.await;
|
||||||
|
let profile = response.json::<Option<UserProfile>>().unwrap();
|
||||||
|
assert_eq!(profile.username, "savanni");
|
||||||
|
|
||||||
|
let response = server
|
||||||
|
.put("/api/v1/user/password")
|
||||||
|
.json(&SetPasswordRequest {
|
||||||
|
password_1: "abcdefg".to_owned(),
|
||||||
|
password_2: "abcd".to_owned(),
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
response.assert_status(StatusCode::UNAUTHORIZED);
|
||||||
|
|
||||||
|
let response = server
|
||||||
|
.put("/api/v1/user/password")
|
||||||
|
.add_header("Authorization", format!("Bearer {}", session_id))
|
||||||
|
.json(&SetPasswordRequest {
|
||||||
|
password_1: "abcdefg".to_owned(),
|
||||||
|
password_2: "abcd".to_owned(),
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
response.assert_status(StatusCode::BAD_REQUEST);
|
||||||
|
|
||||||
|
let response = server
|
||||||
|
.put(&format!("/api/v1/user/password"))
|
||||||
|
.add_header("Authorization", format!("Bearer {}", session_id))
|
||||||
|
.json(&SetPasswordRequest {
|
||||||
|
password_1: "abcdefg".to_owned(),
|
||||||
|
password_2: "abcdefg".to_owned(),
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
response.assert_status(StatusCode::OK);
|
||||||
|
}
|
||||||
|
|
||||||
#[ignore]
|
#[ignore]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn a_user_can_get_change_their_password() {
|
async fn a_user_cannot_change_another_users_password() {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user