Implement heir endpoints
This commit is contained in:
parent
fae3d0ebaa
commit
c6e3fa3eee
5 changed files with 140 additions and 16 deletions
|
@ -1,7 +1,11 @@
|
|||
use diesel::{SqliteConnection, r2d2::{ConnectionManager, PooledConnection}, RunQueryDsl, QueryDsl, SelectableHelper, ExpressionMethods, OptionalExtension};
|
||||
use crate::database::models::User;
|
||||
|
||||
pub fn user(user_id: &str, conn: &mut PooledConnection<ConnectionManager<SqliteConnection>>) -> diesel::result::QueryResult<User> {
|
||||
use super::models::Heir;
|
||||
|
||||
type Connection<'a> = &'a mut PooledConnection<ConnectionManager<SqliteConnection>>;
|
||||
|
||||
pub fn user(user_id: &str, conn: Connection) -> diesel::result::QueryResult<User> {
|
||||
use crate::database::schema::users::dsl::users;
|
||||
users
|
||||
.find(user_id)
|
||||
|
@ -9,7 +13,7 @@ pub fn user(user_id: &str, conn: &mut PooledConnection<ConnectionManager<SqliteC
|
|||
.first(conn)
|
||||
}
|
||||
|
||||
pub fn user_by_email(email: &str, conn: &mut PooledConnection<ConnectionManager<SqliteConnection>>) -> diesel::result::QueryResult<Option<User>> {
|
||||
pub fn user_by_email(email: &str, conn: Connection) -> diesel::result::QueryResult<Option<User>> {
|
||||
use crate::database::schema::users::dsl as users;
|
||||
users::users
|
||||
.filter(users::email.eq(email))
|
||||
|
@ -17,4 +21,12 @@ pub fn user_by_email(email: &str, conn: &mut PooledConnection<ConnectionManager<
|
|||
.select(User::as_select())
|
||||
.first(conn)
|
||||
.optional()
|
||||
}
|
||||
|
||||
pub fn list_heirs(user_id: &str, conn: Connection) -> diesel::result::QueryResult<Vec<Heir>> {
|
||||
use crate::database::schema::heirs::dsl as heirs;
|
||||
heirs::heirs
|
||||
.filter(heirs::user_id.eq(user_id))
|
||||
.select(Heir::as_select())
|
||||
.load(conn)
|
||||
}
|
|
@ -62,11 +62,11 @@ pub struct Entry {
|
|||
#[diesel(table_name = schema::heirs)]
|
||||
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
|
||||
pub struct Heir {
|
||||
id: String,
|
||||
user_id: String,
|
||||
created_at: NaiveDateTime,
|
||||
name: String,
|
||||
email: Option<String>,
|
||||
pub id: String,
|
||||
pub user_id: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub name: String,
|
||||
pub email: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Selectable, Serialize, Deserialize)]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use argon2::{password_hash::{rand_core::OsRng, SaltString}, Argon2, PasswordHash, PasswordHasher, PasswordVerifier};
|
||||
use axum::{extract::State, http::StatusCode, routing::{get, post}, Json, Router};
|
||||
use axum::{extract::State, http::StatusCode, routing::{get, post, put, delete}, Json, Router};
|
||||
use chrono::{Utc, NaiveDateTime};
|
||||
use diesel::{RunQueryDsl, ExpressionMethods};
|
||||
use diesel::{QueryDsl, RunQueryDsl, ExpressionMethods};
|
||||
use tracing::{error, info};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use uuid::Uuid;
|
||||
|
@ -13,6 +13,9 @@ pub fn auth_router() -> Router<AppState> {
|
|||
.route("/auth/register", post(register))
|
||||
.route("/auth/login", post(login))
|
||||
.route("/auth/genkey", get(genkey))
|
||||
.route("/auth/heirs", get(list_heirs))
|
||||
.route("/auth/heirs", put(insert_heir))
|
||||
.route("/auth/heirs", delete(delete_heir))
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -46,7 +49,7 @@ async fn genkey(State(state): State<AppState>, ExtractJwtUser(user): ExtractJwtU
|
|||
let session_key = Uuid::new_v4().to_string();
|
||||
let result = diesel::insert_into(session_keys)
|
||||
.values((
|
||||
user_id.eq(user.uid),
|
||||
user_id.eq(&user.uid),
|
||||
key.eq(&session_key),
|
||||
))
|
||||
.execute(&mut conn);
|
||||
|
@ -56,7 +59,7 @@ async fn genkey(State(state): State<AppState>, ExtractJwtUser(user): ExtractJwtU
|
|||
session_key,
|
||||
}))
|
||||
} else {
|
||||
error!("failed to insert into session_keys");
|
||||
error!("failed to insert into session_keys {}, error: {:?}", user.uid, result.err());
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
} else {
|
||||
|
@ -198,4 +201,110 @@ async fn register(State(state): State<AppState>, Json(req): Json<RegisterRequest
|
|||
error!("failed to obtain pooled connection");
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct HttpHeir {
|
||||
id: String,
|
||||
contact_method: String,
|
||||
name: String,
|
||||
value: String,
|
||||
}
|
||||
|
||||
impl From<crate::database::models::Heir> for HttpHeir {
|
||||
fn from(value: crate::database::models::Heir) -> Self {
|
||||
Self {
|
||||
id: value.id,
|
||||
// Only e-mail is implemented right now
|
||||
contact_method: "email".into(),
|
||||
name: value.name,
|
||||
value: value.email.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn list_heirs(State(state): State<AppState>, ExtractJwtUser(user): ExtractJwtUser) -> Result<Json<Vec<HttpHeir>>, StatusCode> {
|
||||
if let Ok(mut conn) = state.pool.get() {
|
||||
let result = actions::list_heirs(&user.uid, &mut conn);
|
||||
if let Ok(heirs) = result {
|
||||
Ok(Json(heirs.into_iter().map(HttpHeir::from).collect()))
|
||||
} else {
|
||||
error!("failed to obtain heirs: {}, error: {:?}", user.uid, result.err());
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
} else {
|
||||
error!("failed to obtain pooled connection");
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct InsertHeirRequest {
|
||||
contact_method: String,
|
||||
name: String,
|
||||
value: String,
|
||||
}
|
||||
|
||||
async fn insert_heir(State(state): State<AppState>, ExtractJwtUser(user): ExtractJwtUser, Json(req): Json<InsertHeirRequest>) -> Result<Json<Vec<HttpHeir>>, StatusCode> {
|
||||
use crate::database::schema::heirs::dsl::*;
|
||||
if let Ok(mut conn) = state.pool.get() {
|
||||
let heir_id = Uuid::new_v4().to_string();
|
||||
let result = diesel::insert_into(heirs)
|
||||
.values((
|
||||
id.eq(heir_id),
|
||||
created_at.eq(Utc::now().naive_utc()),
|
||||
user_id.eq(&user.uid),
|
||||
name.eq(req.name),
|
||||
// Only e-mail is implemented right now
|
||||
email.eq(req.value),
|
||||
))
|
||||
.execute(&mut conn);
|
||||
|
||||
if result.is_err() {
|
||||
error!("failed to insert into heirs: {}, error: {:?}", user.uid, result.err());
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
let result = actions::list_heirs(&user.uid, &mut conn);
|
||||
if let Ok(heirs_list) = result {
|
||||
Ok(Json(heirs_list.into_iter().map(HttpHeir::from).collect()))
|
||||
} else {
|
||||
error!("failed to obtain heirs: {}, error: {:?}", user.uid, result.err());
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
} else {
|
||||
error!("failed to obtain pooled connection");
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct DeleteHeirRequest {
|
||||
id: String,
|
||||
}
|
||||
|
||||
async fn delete_heir(State(state): State<AppState>, ExtractJwtUser(user): ExtractJwtUser, Json(req): Json<DeleteHeirRequest>) -> Result<Json<Vec<HttpHeir>>, StatusCode> {
|
||||
use crate::database::schema::heirs::dsl::*;
|
||||
if let Ok(mut conn) = state.pool.get() {
|
||||
let result = diesel::delete(heirs.filter(id.eq(&req.id))).execute(&mut conn);
|
||||
if result.is_err() {
|
||||
error!("failed to delete from heirs: {}, heir_id: {}, error: {:?}", user.uid, req.id, result.err());
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
let result = actions::list_heirs(&user.uid, &mut conn);
|
||||
if let Ok(heirs_list) = result {
|
||||
Ok(Json(heirs_list.into_iter().map(HttpHeir::from).collect()))
|
||||
} else {
|
||||
error!("failed to obtain heirs: {}, error: {:?}", user.uid, result.err());
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
} else {
|
||||
error!("failed to obtain pooled connection");
|
||||
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
}
|
|
@ -102,7 +102,7 @@ export default function register(app: AppInterface, auth: AuthInterface, databas
|
|||
return;
|
||||
}
|
||||
|
||||
await database.removeHeir(request.body);
|
||||
await database.removeHeir(request.body.id);
|
||||
|
||||
return (await database.listHeirs(payload.uid))
|
||||
.map((v) => (v["contactMethod"] = "email"))
|
||||
|
@ -111,9 +111,9 @@ export default function register(app: AppInterface, auth: AuthInterface, databas
|
|||
},
|
||||
schema: {
|
||||
headers: { $ref: "schema://identity/authorization" },
|
||||
body: {
|
||||
type: "string",
|
||||
},
|
||||
body: Type.Object({
|
||||
id: Type.String(),
|
||||
}),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -145,7 +145,10 @@ export async function removeHeir(credentials: Credentials, heirID: string): Prom
|
|||
return await asJson(
|
||||
sendRequest('/auth/heirs', credentials, {
|
||||
method: 'DELETE',
|
||||
body: heirID
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ id: heirID })
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue