make transactions higher level (pass them everywhere)
This commit is contained in:
@@ -5,13 +5,16 @@ use axum::{
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::users::{
|
||||
User,
|
||||
auth::{
|
||||
AuthError, COOKIE_NAME, SessionAuthRequired, SessionAuthenticate, UserAuthRequired,
|
||||
implementation::authenticate_via_credentials,
|
||||
use crate::{
|
||||
database,
|
||||
users::{
|
||||
User,
|
||||
auth::{
|
||||
AuthError, COOKIE_NAME, SessionAuthRequired, SessionAuthenticate, UserAuthRequired,
|
||||
implementation::authenticate_via_credentials,
|
||||
},
|
||||
sessions::Session,
|
||||
},
|
||||
sessions::Session,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -22,7 +25,8 @@ pub struct LoginForm {
|
||||
|
||||
fn login_common(creds: LoginForm) -> Result<(String, String), AuthError> {
|
||||
let u = authenticate_via_credentials(&creds.handle, &creds.password)?.required()?;
|
||||
let (_, token) = Session::new_for_user(&u)?;
|
||||
let conn = database::conn()?;
|
||||
let (_, token) = Session::new_for_user(&conn, &u)?;
|
||||
let secure = match cfg!(debug_assertions) {
|
||||
false => "; Secure",
|
||||
true => "",
|
||||
@@ -49,13 +53,15 @@ pub async fn login_form(Form(creds): Form<LoginForm>) -> Result<Response, AuthEr
|
||||
|
||||
pub async fn logout(headers: HeaderMap) -> Result<Response, AuthError> {
|
||||
let mut s = Session::authenticate(&headers)?.required()?;
|
||||
s.revoke(Some(&User::get_by_id(s.user_id)?))?;
|
||||
let conn = database::conn()?;
|
||||
s.revoke(&conn, Some(&User::get_by_id(&conn, s.user_id)?))?;
|
||||
let cookie = format!("{COOKIE_NAME}=revoking; Path=/; HttpOnly; Max-Age=0");
|
||||
Ok(([(header::SET_COOKIE, cookie)], "Logged out!").into_response())
|
||||
}
|
||||
pub async fn logout_form(headers: HeaderMap) -> Result<Response, AuthError> {
|
||||
let mut s = Session::authenticate(&headers)?.required()?;
|
||||
s.revoke(Some(&User::get_by_id(s.user_id)?))?;
|
||||
let conn = database::conn()?;
|
||||
s.revoke(&conn, Some(&User::get_by_id(&conn, s.user_id)?))?;
|
||||
let cookie = format!("{COOKIE_NAME}=revoking; Path=/; HttpOnly; Max-Age=0");
|
||||
Ok(([(header::SET_COOKIE, cookie)], Redirect::to("/")).into_response())
|
||||
}
|
||||
|
||||
@@ -85,5 +85,5 @@ composite_from!(
|
||||
PersonError,
|
||||
QuoteError,
|
||||
DatabaseError,
|
||||
RedirectViaError
|
||||
RedirectViaError,
|
||||
);
|
||||
|
||||
@@ -9,6 +9,7 @@ use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
api::CompositeError,
|
||||
database,
|
||||
persons::{Name, Person},
|
||||
users::{
|
||||
User,
|
||||
@@ -21,21 +22,24 @@ pub const CANT_SET_PRIMARYNAME: &str = "You don't have permission to swap primar
|
||||
|
||||
pub async fn get_all(headers: HeaderMap) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(Person::get_all()?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(Person::get_all(&conn)?).into_response())
|
||||
}
|
||||
pub async fn get_by_id(
|
||||
Path(id): Path<Uuid>,
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(Person::get_by_id(id)?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(Person::get_by_id(&conn, id)?).into_response())
|
||||
}
|
||||
pub async fn pid_names(
|
||||
Path(id): Path<Uuid>,
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(Person::get_by_id(id)?.get_all_names()?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(Person::get_by_id(&conn, id)?.get_all_names(&conn)?).into_response())
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -48,7 +52,8 @@ pub async fn create(
|
||||
Json(form): Json<PersonNameForm>,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
let p = Person::create(form.name, u.id)?;
|
||||
let conn = database::conn()?;
|
||||
let p = Person::create(&conn, form.name, u.id)?;
|
||||
Ok((StatusCode::CREATED, Json(p)).into_response())
|
||||
}
|
||||
pub async fn add_name(
|
||||
@@ -57,27 +62,30 @@ pub async fn add_name(
|
||||
Json(form): Json<PersonNameForm>,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
let p = Person::get_by_id(id)?;
|
||||
let n = p.add_name(form.name, u.id)?;
|
||||
let conn = database::conn()?;
|
||||
let p = Person::get_by_id(&conn, id)?;
|
||||
let n = p.add_name(&conn, form.name, u.id)?;
|
||||
|
||||
Ok((StatusCode::CREATED, Json(n)).into_response())
|
||||
}
|
||||
|
||||
pub async fn n_by_id(Path(id): Path<Uuid>, headers: HeaderMap) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(Name::get_by_id(id)?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(Name::get_by_id(&conn, id)?).into_response())
|
||||
}
|
||||
pub async fn n_setprimary(
|
||||
Path(id): Path<Uuid>,
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
if !u.has_permission(Permission::ChangePersonPrimaryName)? {
|
||||
let conn = database::conn()?;
|
||||
if !u.has_permission(&conn, Permission::ChangePersonPrimaryName)? {
|
||||
return Ok((StatusCode::FORBIDDEN, CANT_SET_PRIMARYNAME).into_response());
|
||||
}
|
||||
|
||||
let mut n = Name::get_by_id(id)?;
|
||||
n.set_primary()?;
|
||||
let mut n = Name::get_by_id(&conn, id)?;
|
||||
n.set_primary(&conn)?;
|
||||
n.is_primary = true;
|
||||
Ok(Json(n).into_response())
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
api::CompositeError,
|
||||
database,
|
||||
persons::Name,
|
||||
quotes::Quote,
|
||||
users::{
|
||||
@@ -23,7 +24,8 @@ pub async fn get_by_id(
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(Quote::get_by_id(id)?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(Quote::get_by_id(&conn, id)?).into_response())
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -46,14 +48,16 @@ pub async fn create(
|
||||
Json(form): Json<QuoteCreateForm>,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
let conn = database::conn()?;
|
||||
|
||||
let lines = form
|
||||
.lines
|
||||
.into_iter()
|
||||
.map(|l| Ok((l.content, Name::get_by_id(l.name_id)?)))
|
||||
.map(|l| Ok((l.content, Name::get_by_id(&conn, l.name_id)?)))
|
||||
.collect::<Result<Vec<(String, Name)>, CompositeError>>()?;
|
||||
|
||||
let q = Quote::create(
|
||||
&conn,
|
||||
lines,
|
||||
form.timestamp,
|
||||
form.context,
|
||||
|
||||
@@ -8,6 +8,7 @@ use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
api::CompositeError,
|
||||
database,
|
||||
users::{
|
||||
User,
|
||||
auth::{UserAuthRequired, UserAuthenticate},
|
||||
@@ -23,10 +24,11 @@ pub async fn get_by_id(
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
let s = Session::get_by_id(id)?;
|
||||
let conn = database::conn()?;
|
||||
let s = Session::get_by_id(&conn, id)?;
|
||||
|
||||
match s.user_id == u.id
|
||||
|| u.has_permission(Permission::ListOthersSessions)
|
||||
|| u.has_permission(&conn, Permission::ListOthersSessions)
|
||||
.is_ok_and(|v| v)
|
||||
{
|
||||
true => Ok(Json(s).into_response()),
|
||||
@@ -39,17 +41,18 @@ pub async fn revoke_by_id(
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
let mut s = Session::get_by_id(id)?;
|
||||
let conn = database::conn()?;
|
||||
let mut s = Session::get_by_id(&conn, id)?;
|
||||
|
||||
match s.user_id == u.id
|
||||
|| u.has_permission(Permission::RevokeOthersSessions)
|
||||
|| u.has_permission(&conn, Permission::RevokeOthersSessions)
|
||||
.is_ok_and(|v| v)
|
||||
{
|
||||
true => {
|
||||
s.revoke(Some(&u))?;
|
||||
s.revoke(&conn, Some(&u))?;
|
||||
Ok(Json(s).into_response())
|
||||
}
|
||||
false => match u.has_permission(Permission::ListOthersSessions)? {
|
||||
false => match u.has_permission(&conn, Permission::ListOthersSessions)? {
|
||||
true => Ok((StatusCode::FORBIDDEN, CANT_REVOKE).into_response()),
|
||||
false => Err(SessionError::NoSessionWithId(id))?,
|
||||
},
|
||||
|
||||
@@ -9,6 +9,7 @@ use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
api::CompositeError,
|
||||
database,
|
||||
tags::{Tag, TagName},
|
||||
users::{
|
||||
User,
|
||||
@@ -24,7 +25,8 @@ const TAG_DELETED: &str = "Tag deleted successfully.";
|
||||
|
||||
pub async fn get_all(headers: HeaderMap) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(Tag::get_all()?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(Tag::get_all(&conn)?).into_response())
|
||||
}
|
||||
|
||||
pub async fn get_by_id(
|
||||
@@ -32,7 +34,8 @@ pub async fn get_by_id(
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(Tag::get_by_id(id)?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(Tag::get_by_id(&conn, id)?).into_response())
|
||||
}
|
||||
|
||||
pub async fn get_by_name(
|
||||
@@ -40,7 +43,8 @@ pub async fn get_by_name(
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(Tag::get_by_name(name)?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(Tag::get_by_name(&conn, name)?).into_response())
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -52,10 +56,11 @@ pub async fn create(
|
||||
Json(form): Json<TagNameForm>,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
if !u.has_permission(Permission::CreateTags)? {
|
||||
let conn = database::conn()?;
|
||||
if !u.has_permission(&conn, Permission::CreateTags)? {
|
||||
return Ok((StatusCode::FORBIDDEN, CANT_MAKE_TAGS).into_response());
|
||||
}
|
||||
Ok(Json(Tag::create(form.name)?).into_response())
|
||||
Ok(Json(Tag::create(&conn, form.name)?).into_response())
|
||||
}
|
||||
|
||||
pub async fn rename(
|
||||
@@ -64,19 +69,21 @@ pub async fn rename(
|
||||
Json(form): Json<TagNameForm>,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
if !u.has_permission(Permission::RenameTags)? {
|
||||
let conn = database::conn()?;
|
||||
if !u.has_permission(&conn, Permission::RenameTags)? {
|
||||
return Ok((StatusCode::FORBIDDEN, CANT_RENAME_TAGS).into_response());
|
||||
}
|
||||
let mut tag = Tag::get_by_id(id)?;
|
||||
tag.rename(form.name)?;
|
||||
let mut tag = Tag::get_by_id(&conn, id)?;
|
||||
tag.rename(&conn, form.name)?;
|
||||
Ok(Json(tag).into_response())
|
||||
}
|
||||
|
||||
pub async fn delete(Path(id): Path<Uuid>, headers: HeaderMap) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
if !u.has_permission(Permission::DeleteTags)? {
|
||||
let conn = database::conn()?;
|
||||
if !u.has_permission(&conn, Permission::DeleteTags)? {
|
||||
return Ok((StatusCode::FORBIDDEN, CANT_DEL_TAGS).into_response());
|
||||
}
|
||||
Tag::get_by_id(id)?.delete()?;
|
||||
Tag::get_by_id(&conn, id)?.delete(&conn)?;
|
||||
Ok((StatusCode::OK, TAG_DELETED).into_response())
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
api::CompositeError,
|
||||
database,
|
||||
users::{
|
||||
User,
|
||||
auth::{UserAuthRequired, UserAuthenticate},
|
||||
@@ -32,7 +33,8 @@ pub async fn get_by_id(
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(User::get_by_id(id)?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(User::get_by_id(&conn, id)?).into_response())
|
||||
}
|
||||
|
||||
pub async fn get_by_handle(
|
||||
@@ -40,12 +42,14 @@ pub async fn get_by_handle(
|
||||
headers: HeaderMap,
|
||||
) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(User::get_by_handle(handle)?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(User::get_by_handle(&conn, handle)?).into_response())
|
||||
}
|
||||
|
||||
pub async fn get_all(headers: HeaderMap) -> Result<Response, CompositeError> {
|
||||
User::authenticate(&headers)?.required()?;
|
||||
Ok(Json(User::get_all()?).into_response())
|
||||
let conn = database::conn()?;
|
||||
Ok(Json(User::get_all(&conn)?).into_response())
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -57,10 +61,11 @@ pub async fn create(
|
||||
Json(form): Json<HandleForm>,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
if !u.has_permission(Permission::ManuallyCreateUsers)? {
|
||||
let conn = database::conn()?;
|
||||
if !u.has_permission(&conn, Permission::ManuallyCreateUsers)? {
|
||||
return Ok((StatusCode::FORBIDDEN, CANT_MANUALLY_MAKE_USERS).into_response());
|
||||
}
|
||||
Ok(Json(User::create(form.handle)?).into_response())
|
||||
Ok(Json(User::create(&conn, form.handle)?).into_response())
|
||||
}
|
||||
pub async fn change_handle(
|
||||
Path(id): Path<Uuid>,
|
||||
@@ -68,15 +73,17 @@ pub async fn change_handle(
|
||||
Json(form): Json<HandleForm>,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
let conn = database::conn()?;
|
||||
|
||||
let mut target = if u.id == id {
|
||||
u
|
||||
} else {
|
||||
if !u.has_permission(Permission::ChangeOthersHandles)? {
|
||||
if !u.has_permission(&conn, Permission::ChangeOthersHandles)? {
|
||||
return Ok((StatusCode::FORBIDDEN, CANT_CHANGE_OTHERS_HANDLE).into_response());
|
||||
}
|
||||
User::get_by_id(id)?
|
||||
User::get_by_id(&conn, id)?
|
||||
};
|
||||
target.set_handle(form.handle)?;
|
||||
target.set_handle(&conn, form.handle)?;
|
||||
Ok(HANDLE_CHANGED_SUCCESS.into_response())
|
||||
}
|
||||
|
||||
@@ -90,14 +97,15 @@ pub async fn change_password(
|
||||
Json(form): Json<ChangePasswordForm>,
|
||||
) -> Result<Response, CompositeError> {
|
||||
let u = User::authenticate(&headers)?.required()?;
|
||||
let conn = database::conn()?;
|
||||
let mut target = if u.id == id {
|
||||
u
|
||||
} else {
|
||||
if !u.has_permission(Permission::ChangeOthersPasswords)? {
|
||||
if !u.has_permission(&conn, Permission::ChangeOthersPasswords)? {
|
||||
return Ok((StatusCode::FORBIDDEN, CANT_CHANGE_OTHERS_PASSW).into_response());
|
||||
}
|
||||
User::get_by_id(id)?
|
||||
User::get_by_id(&conn, id)?
|
||||
};
|
||||
target.set_password(Some(&form.password))?;
|
||||
target.set_password(&conn, Some(&form.password))?;
|
||||
Ok(PASSW_CHANGED_SUCCESS.into_response())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user