From b4271853a9a092ab1162fa6e0843d4b61c2563e3 Mon Sep 17 00:00:00 2001
From: Philippe Loctaux
Date: Wed, 15 Nov 2023 21:01:22 +0100
Subject: [PATCH] rocket v0.5-rc4 with some adjustements:
- all db access are done with transactions
- Forwards in Outcomes return a status
---
crates/ezidam/Cargo.toml | 6 +-
crates/ezidam/src/guards/access_token.rs | 10 +-
crates/ezidam/src/guards/basic_auth.rs | 6 +-
crates/ezidam/src/guards/completed_setup.rs | 6 +-
crates/ezidam/src/guards/jwt.rs | 98 +++++++++----------
.../src/guards/jwt/admin_not_current.rs | 7 +-
crates/ezidam/src/guards/need_setup.rs | 6 +-
crates/ezidam/src/guards/refresh_token.rs | 3 +-
crates/ezidam/src/guards/totp_request.rs | 5 +-
crates/ezidam/src/routes.rs | 1 +
crates/ezidam/src/routes/admin/apps.rs | 27 +++--
crates/ezidam/src/routes/admin/dashboard.rs | 8 +-
crates/ezidam/src/routes/admin/permissions.rs | 36 +++----
crates/ezidam/src/routes/admin/roles.rs | 20 ++--
crates/ezidam/src/routes/admin/settings.rs | 45 +++++----
crates/ezidam/src/routes/admin/users.rs | 60 +++++++-----
crates/ezidam/src/routes/oauth/authorize.rs | 14 +--
crates/ezidam/src/routes/oauth/redirect.rs | 27 ++---
crates/ezidam/src/routes/oauth/token.rs | 53 +++++-----
crates/ezidam/src/routes/oauth/totp.rs | 38 +++----
.../ezidam/src/routes/root/forgot_password.rs | 10 +-
crates/ezidam/src/routes/root/logo.rs | 4 +-
crates/ezidam/src/routes/root/logout.rs | 22 +++--
.../ezidam/src/routes/root/reset_password.rs | 7 +-
crates/ezidam/src/routes/settings/personal.rs | 15 +--
crates/ezidam/src/routes/settings/security.rs | 45 ++++-----
crates/ezidam/src/routes/setup.rs | 15 ++-
crates/ezidam/src/routes/well_known.rs | 8 +-
28 files changed, 332 insertions(+), 270 deletions(-)
diff --git a/crates/ezidam/Cargo.toml b/crates/ezidam/Cargo.toml
index 3450b7b..ae07f1e 100644
--- a/crates/ezidam/Cargo.toml
+++ b/crates/ezidam/Cargo.toml
@@ -4,9 +4,9 @@ version = "0.1.0"
edition = "2021"
[dependencies]
-rocket = { version = "=0.5.0-rc.3", features = ["json"] }
-rocket_db_pools = { version = "=0.1.0-rc.3", features = ["sqlx_sqlite"] }
-rocket_dyn_templates = { version = "=0.1.0-rc.3", features = ["tera"] }
+rocket = { version = "=0.5.0-rc.4", features = ["json"] }
+rocket_db_pools = { version = "=0.1.0-rc.4", features = ["sqlx_sqlite"] }
+rocket_dyn_templates = { version = "=0.1.0-rc.4", features = ["tera"] }
infer = { version = "0.13", default-features = false }
erased-serde = "0.3"
url = { workspace = true }
diff --git a/crates/ezidam/src/guards/access_token.rs b/crates/ezidam/src/guards/access_token.rs
index 476d2d2..0756af9 100644
--- a/crates/ezidam/src/guards/access_token.rs
+++ b/crates/ezidam/src/guards/access_token.rs
@@ -35,7 +35,7 @@ impl AccessToken {
},
Err(e) => match e {
Outcome::Success(s) => Ok(Some(Self(s))),
- Outcome::Failure(e) => Err(BearerAuthError::Jwt(e.1)),
+ Outcome::Error(e) => Err(BearerAuthError::Jwt(e.1)),
Outcome::Forward(_) => Ok(None),
},
}
@@ -50,15 +50,15 @@ impl<'r> FromRequest<'r> for AccessToken {
let keys: Vec<_> = request.headers().get("Authorization").collect();
match keys.len() {
- 0 => Outcome::Forward(()),
+ 0 => Outcome::Forward(Status::Unauthorized),
1 => match AccessToken::from_bearer(keys[0], request).await {
Ok(access_token) => match access_token {
Some(access_token) => Outcome::Success(access_token),
- None => Outcome::Forward(()),
+ None => Outcome::Forward(Status::Unauthorized),
},
- Err(e) => Outcome::Failure((Status::Unauthorized, e)),
+ Err(e) => Outcome::Error((Status::Unauthorized, e)),
},
- _ => Outcome::Failure((Status::BadRequest, BearerAuthError::BadCount)),
+ _ => Outcome::Error((Status::BadRequest, BearerAuthError::BadCount)),
}
}
}
diff --git a/crates/ezidam/src/guards/basic_auth.rs b/crates/ezidam/src/guards/basic_auth.rs
index a8a4d2b..cccb549 100644
--- a/crates/ezidam/src/guards/basic_auth.rs
+++ b/crates/ezidam/src/guards/basic_auth.rs
@@ -56,12 +56,12 @@ impl<'r> FromRequest<'r> for BasicAuth {
let keys: Vec<_> = request.headers().get("Authorization").collect();
match keys.len() {
- 0 => Outcome::Forward(()),
+ 0 => Outcome::Forward(Status::BadRequest),
1 => match BasicAuth::from_base64(keys[0]) {
Ok(auth_header) => Outcome::Success(auth_header),
- Err(e) => Outcome::Failure((Status::BadRequest, e)),
+ Err(e) => Outcome::Error((Status::BadRequest, e)),
},
- _ => Outcome::Failure((Status::BadRequest, BasicAuthError::BadCount)),
+ _ => Outcome::Error((Status::BadRequest, BasicAuthError::BadCount)),
}
}
}
diff --git a/crates/ezidam/src/guards/completed_setup.rs b/crates/ezidam/src/guards/completed_setup.rs
index 057eb35..2a38e15 100644
--- a/crates/ezidam/src/guards/completed_setup.rs
+++ b/crates/ezidam/src/guards/completed_setup.rs
@@ -19,16 +19,16 @@ impl<'r> FromRequest<'r> for CompletedSetup {
async fn from_request(request: &'r Request<'_>) -> Outcome {
let db = match request.guard::<&Database>().await {
Outcome::Success(database) => database,
- Outcome::Failure(e) => return Outcome::Failure((e.0, Error::GetDatabase)),
+ Outcome::Error(e) => return Outcome::Error((e.0, Error::GetDatabase)),
Outcome::Forward(f) => return Outcome::Forward(f),
};
match User::get_initial_admin(&**db).await {
Ok(initial_admin) => match initial_admin {
Some(_) => Outcome::Success(CompletedSetup),
- None => Outcome::Forward(()),
+ None => Outcome::Forward(Status::PermanentRedirect),
},
- Err(e) => Outcome::Failure((Status::InternalServerError, Error::Request(e))),
+ Err(e) => Outcome::Error((Status::InternalServerError, Error::Request(e))),
}
}
}
diff --git a/crates/ezidam/src/guards/jwt.rs b/crates/ezidam/src/guards/jwt.rs
index ddc5f57..83fdb97 100644
--- a/crates/ezidam/src/guards/jwt.rs
+++ b/crates/ezidam/src/guards/jwt.rs
@@ -16,6 +16,7 @@ use rocket::time::Duration;
use rocket::tokio::task;
use rocket::Request;
use settings::Settings;
+use std::ops::DerefMut;
use users::User;
mod admin;
@@ -78,14 +79,14 @@ pub async fn validate_jwt(
// Get database
let db = match request.guard::<&Database>().await {
Outcome::Success(database) => database,
- Outcome::Failure(e) => return Err(Outcome::Failure((e.0, Error::GetDatabase))),
+ Outcome::Error(e) => return Err(Outcome::Error((e.0, Error::GetDatabase))),
Outcome::Forward(f) => return Err(Outcome::Forward(f)),
};
let mut transaction = match db.begin().await {
Ok(transaction) => transaction,
Err(_e) => {
- return Err(Outcome::Failure((
+ return Err(Outcome::Error((
Status::InternalServerError,
Error::StartTransaction,
)));
@@ -93,10 +94,10 @@ pub async fn validate_jwt(
};
// Get keys
- let keys = match Key::get_all(&mut transaction, Some(false)).await {
+ let keys = match Key::get_all(transaction.deref_mut(), Some(false)).await {
Ok(keys) => keys,
Err(e) => {
- return Err(Outcome::Failure((
+ return Err(Outcome::Error((
Status::InternalServerError,
Error::Keys(e),
)))
@@ -105,10 +106,10 @@ pub async fn validate_jwt(
if let Some(specific_user) = specific_user {
// Get settings
- let settings = match Settings::get(&mut transaction).await {
+ let settings = match Settings::get(transaction.deref_mut()).await {
Ok(settings) => settings,
Err(e) => {
- return Err(Outcome::Failure((
+ return Err(Outcome::Error((
Status::InternalServerError,
Error::GetSettings(e),
)));
@@ -119,7 +120,7 @@ pub async fn validate_jwt(
let first_admin = match settings.first_admin() {
Some(home_page) => UserID(home_page.to_string()),
None => {
- return Err(Outcome::Failure((
+ return Err(Outcome::Error((
Status::InternalServerError,
Error::FirstAdminNotSet,
)));
@@ -133,7 +134,7 @@ pub async fn validate_jwt(
}
if let Err(_e) = transaction.commit().await {
- return Err(Outcome::Failure((
+ return Err(Outcome::Error((
Status::InternalServerError,
Error::CommitTransaction,
)));
@@ -191,11 +192,11 @@ pub async fn validate_jwt(
// Return jwt claims
Ok(claims)
}
- Err(_e) => Err(Outcome::Forward(())),
+ Err(_e) => Err(Outcome::Forward(Status::Unauthorized)),
},
Err(e) => {
// Failed to run blocking task
- Err(Outcome::Failure((
+ Err(Outcome::Error((
Status::InternalServerError,
Error::BlockingTask(e.to_string()),
)))
@@ -211,92 +212,92 @@ pub async fn use_refresh_token(
// Get database
let db = match request.guard::<&Database>().await {
Outcome::Success(database) => database,
- Outcome::Failure(e) => return Outcome::Failure((e.0, Error::GetDatabase)),
+ Outcome::Error(e) => return Outcome::Error((e.0, Error::GetDatabase)),
Outcome::Forward(f) => return Outcome::Forward(f),
};
// Get cookies
let cookie_jar = match request.guard::<&CookieJar>().await {
Outcome::Success(cookie_jar) => cookie_jar,
- Outcome::Failure(e) => return Outcome::Failure((e.0, Error::GetCookies)),
+ Outcome::Error(e) => return Outcome::Error((e.0, Error::GetCookies)),
Outcome::Forward(f) => return Outcome::Forward(f),
};
let mut transaction = match db.begin().await {
Ok(transaction) => transaction,
Err(_e) => {
- return Outcome::Failure((Status::InternalServerError, Error::StartTransaction));
+ return Outcome::Error((Status::InternalServerError, Error::StartTransaction));
}
};
- let refresh_token = match RefreshToken::get_one(&mut transaction, &refresh).await {
+ let refresh_token = match RefreshToken::get_one(transaction.deref_mut(), &refresh).await {
Ok(refresh_token) => match refresh_token {
Some(refresh_token) => refresh_token,
- None => return Outcome::Forward(()),
+ None => return Outcome::Forward(Status::Unauthorized),
},
Err(e) => {
- return Outcome::Failure((Status::InternalServerError, Error::GetRefreshToken(e)));
+ return Outcome::Error((Status::InternalServerError, Error::GetRefreshToken(e)));
}
};
- let user = match User::get_one_from_refresh_token(&mut transaction, &refresh).await {
+ let user = match User::get_one_from_refresh_token(transaction.deref_mut(), &refresh).await {
Ok(user) => match user {
Some(user) => user,
None => {
- return Outcome::Failure((Status::InternalServerError, Error::UserNotFound));
+ return Outcome::Error((Status::InternalServerError, Error::UserNotFound));
}
},
Err(e) => {
- return Outcome::Failure((Status::InternalServerError, Error::GetUser(e)));
+ return Outcome::Error((Status::InternalServerError, Error::GetUser(e)));
}
};
// make sure that `get_admin` is respected, dont generate token for unwanted users!
if let Some(get_admin) = get_admin {
if user.is_admin() != get_admin {
- return Outcome::Forward(());
+ return Outcome::Forward(Status::Forbidden);
}
}
if refresh_token.has_been_used() {
// Revoke all tokens for user
if let Err(e) =
- RefreshToken::revoke_all_for_user(&mut transaction, refresh_token.user()).await
+ RefreshToken::revoke_all_for_user(transaction.deref_mut(), refresh_token.user()).await
{
- return Outcome::Failure((Status::InternalServerError, Error::RevokeRefreshTokens(e)));
+ return Outcome::Error((Status::InternalServerError, Error::RevokeRefreshTokens(e)));
}
if let Err(_e) = transaction.commit().await {
- return Outcome::Failure((Status::InternalServerError, Error::CommitTransaction));
+ return Outcome::Error((Status::InternalServerError, Error::CommitTransaction));
}
- return Outcome::Forward(());
+ return Outcome::Forward(Status::Unauthorized);
}
if refresh_token.is_revoked() {
- return Outcome::Forward(());
+ return Outcome::Forward(Status::Unauthorized);
}
if refresh_token.has_expired() {
- return Outcome::Forward(());
+ return Outcome::Forward(Status::Unauthorized);
}
- if let Err(e) = refresh_token.use_token(&mut transaction).await {
- return Outcome::Failure((Status::InternalServerError, Error::MarkRefreshTokenUsed(e)));
+ if let Err(e) = refresh_token.use_token(transaction.deref_mut()).await {
+ return Outcome::Error((Status::InternalServerError, Error::MarkRefreshTokenUsed(e)));
}
// Get base url
- let settings = match Settings::get(&mut transaction).await {
+ let settings = match Settings::get(transaction.deref_mut()).await {
Ok(settings) => settings,
Err(e) => {
- return Outcome::Failure((Status::InternalServerError, Error::GetSettings(e)));
+ return Outcome::Error((Status::InternalServerError, Error::GetSettings(e)));
}
};
let home_page = match settings.url().map(String::from) {
Some(home_page) => home_page,
None => {
- return Outcome::Failure((Status::InternalServerError, Error::ServerUrlNotSet));
+ return Outcome::Error((Status::InternalServerError, Error::ServerUrlNotSet));
}
};
@@ -304,7 +305,7 @@ pub async fn use_refresh_token(
let new_refresh_token = match task::spawn_blocking(SecretString::default).await {
Ok(new_refresh_token) => new_refresh_token,
Err(e) => {
- return Outcome::Failure((
+ return Outcome::Error((
Status::InternalServerError,
Error::BlockingTask(e.to_string()),
));
@@ -315,13 +316,13 @@ pub async fn use_refresh_token(
let ip_address = match request.client_ip() {
Some(ip) => ip.to_string(),
None => {
- return Outcome::Failure((Status::BadRequest, Error::UnknownIp));
+ return Outcome::Error((Status::BadRequest, Error::UnknownIp));
}
};
// Insert refresh token in database
if let Err(e) = RefreshToken::insert(
- &mut transaction,
+ transaction.deref_mut(),
new_refresh_token.as_ref(),
ip_address,
user.id(),
@@ -330,7 +331,7 @@ pub async fn use_refresh_token(
)
.await
{
- return Outcome::Failure((Status::InternalServerError, Error::SaveRefreshToken(e)));
+ return Outcome::Error((Status::InternalServerError, Error::SaveRefreshToken(e)));
}
// Add refresh token as a cookie
@@ -345,24 +346,21 @@ pub async fn use_refresh_token(
cookie_jar.add(cookie);
// Get latest key from database
- let key = match Key::get_most_recent(&mut transaction).await {
+ let key = match Key::get_most_recent(transaction.deref_mut()).await {
Ok(key) => match key {
Some(key) => key,
None => {
- return Outcome::Failure((
- Status::InternalServerError,
- Error::MostRecentKeyNotFound,
- ));
+ return Outcome::Error((Status::InternalServerError, Error::MostRecentKeyNotFound));
}
},
Err(e) => {
- return Outcome::Failure((Status::InternalServerError, Error::GetKey(e)));
+ return Outcome::Error((Status::InternalServerError, Error::GetKey(e)));
}
};
// Make sure key has not been revoked
if key.is_revoked() {
- return Outcome::Failure((Status::InternalServerError, Error::MostRecentKeyRevoked));
+ return Outcome::Error((Status::InternalServerError, Error::MostRecentKeyRevoked));
}
// Import private key
@@ -373,11 +371,11 @@ pub async fn use_refresh_token(
Ok(private_key) => match private_key {
Ok(private_key) => private_key,
Err(e) => {
- return Outcome::Failure((Status::InternalServerError, Error::ImportKey(e)));
+ return Outcome::Error((Status::InternalServerError, Error::ImportKey(e)));
}
},
Err(e) => {
- return Outcome::Failure((
+ return Outcome::Error((
Status::InternalServerError,
Error::BlockingTask(e.to_string()),
));
@@ -385,13 +383,13 @@ pub async fn use_refresh_token(
};
// Get user roles
- let roles = match Permission::get_all(&mut transaction, Some(user.id()), None).await {
+ let roles = match Permission::get_all(transaction.deref_mut(), Some(user.id()), None).await {
Ok(roles) => roles
.into_iter()
.map(|role| role.role().to_string())
.collect(),
Err(e) => {
- return Outcome::Failure((Status::InternalServerError, Error::GetPermissions(e)));
+ return Outcome::Error((Status::InternalServerError, Error::GetPermissions(e)));
}
};
@@ -403,7 +401,7 @@ pub async fn use_refresh_token(
{
Ok(jwt) => jwt,
Err(e) => {
- return Outcome::Failure((Status::InternalServerError, Error::SignJwt(e)));
+ return Outcome::Error((Status::InternalServerError, Error::SignJwt(e)));
}
};
@@ -416,7 +414,7 @@ pub async fn use_refresh_token(
cookie_jar.add(cookie);
if let Err(_e) = transaction.commit().await {
- return Outcome::Failure((Status::InternalServerError, Error::CommitTransaction));
+ return Outcome::Error((Status::InternalServerError, Error::CommitTransaction));
}
Outcome::Success(jwt_claims)
@@ -436,7 +434,7 @@ pub async fn use_access_token_or_refresh_token(
match validate_jwt(access, request, get_admin, specific_user).await {
Ok(jwt_claims) => match jwt_claims {
Some(jwt_claims) => Outcome::Success(jwt_claims),
- None => Outcome::Forward(()),
+ None => Outcome::Forward(Status::Unauthorized),
},
Err(e) => e,
}
@@ -447,7 +445,7 @@ pub async fn use_access_token_or_refresh_token(
}
(None, None) => {
// Nothing to do
- Outcome::Forward(())
+ Outcome::Forward(Status::Unauthorized)
}
}
}
diff --git a/crates/ezidam/src/guards/jwt/admin_not_current.rs b/crates/ezidam/src/guards/jwt/admin_not_current.rs
index 6ce90c8..6145a11 100644
--- a/crates/ezidam/src/guards/jwt/admin_not_current.rs
+++ b/crates/ezidam/src/guards/jwt/admin_not_current.rs
@@ -2,6 +2,7 @@ use super::Error;
use crate::guards::{use_access_token_or_refresh_token, SpecificUser};
use crate::id::RocketUserID;
use jwt::JwtClaims;
+use rocket::http::Status;
use rocket::request::{FromRequest, Outcome};
use rocket::Request;
@@ -30,7 +31,7 @@ impl<'r> FromRequest<'r> for JwtAdminNotCurrent {
ret
} {
Some(user_id) => user_id,
- None => return Outcome::Forward(()),
+ None => return Outcome::Forward(Status::Forbidden),
};
// Don't allow first admin
@@ -49,10 +50,10 @@ impl<'r> FromRequest<'r> for JwtAdminNotCurrent {
if success.0.subject != user_id.0 .0 {
Outcome::Success(success)
} else {
- Outcome::Forward(())
+ Outcome::Forward(Status::Forbidden)
}
}
- Outcome::Failure(failure) => Outcome::Failure(failure),
+ Outcome::Error(failure) => Outcome::Error(failure),
Outcome::Forward(forward) => Outcome::Forward(forward),
}
}
diff --git a/crates/ezidam/src/guards/need_setup.rs b/crates/ezidam/src/guards/need_setup.rs
index 953c50b..5f39172 100644
--- a/crates/ezidam/src/guards/need_setup.rs
+++ b/crates/ezidam/src/guards/need_setup.rs
@@ -19,16 +19,16 @@ impl<'r> FromRequest<'r> for NeedSetup {
async fn from_request(request: &'r Request<'_>) -> Outcome {
let db = match request.guard::<&Database>().await {
Outcome::Success(database) => database,
- Outcome::Failure(e) => return Outcome::Failure((e.0, Error::GetDatabase)),
+ Outcome::Error(e) => return Outcome::Error((e.0, Error::GetDatabase)),
Outcome::Forward(f) => return Outcome::Forward(f),
};
match User::get_initial_admin(&**db).await {
Ok(initial_admin) => match initial_admin {
- Some(_) => Outcome::Forward(()),
+ Some(_) => Outcome::Forward(Status::PermanentRedirect),
None => Outcome::Success(NeedSetup),
},
- Err(e) => Outcome::Failure((Status::InternalServerError, Error::Request(e))),
+ Err(e) => Outcome::Error((Status::InternalServerError, Error::Request(e))),
}
}
}
diff --git a/crates/ezidam/src/guards/refresh_token.rs b/crates/ezidam/src/guards/refresh_token.rs
index c92eac4..8c95876 100644
--- a/crates/ezidam/src/guards/refresh_token.rs
+++ b/crates/ezidam/src/guards/refresh_token.rs
@@ -1,4 +1,5 @@
use crate::tokens::REFRESH_TOKEN_COOKIE_NAME;
+use rocket::http::Status;
use rocket::request::{FromRequest, Outcome};
use rocket::Request;
@@ -26,7 +27,7 @@ impl<'r> FromRequest<'r> for RefreshToken {
async fn from_request(request: &'r Request<'_>) -> Outcome {
match get_refresh_token_from_cookie(request) {
Some(refresh_token) => Outcome::Success(Self(refresh_token)),
- None => Outcome::Forward(()),
+ None => Outcome::Forward(Status::Unauthorized),
}
}
}
diff --git a/crates/ezidam/src/guards/totp_request.rs b/crates/ezidam/src/guards/totp_request.rs
index 16cd50f..31fc6cb 100644
--- a/crates/ezidam/src/guards/totp_request.rs
+++ b/crates/ezidam/src/guards/totp_request.rs
@@ -1,3 +1,4 @@
+use rocket::http::Status;
use rocket::request::{FromRequest, Outcome};
use rocket::Request;
use users::totp_login_request::{TOTP_REQUEST_COOKIE_NAME, TOTP_REQUEST_LEN};
@@ -16,10 +17,10 @@ impl<'r> FromRequest<'r> for TotpRequest {
if value.len() == TOTP_REQUEST_LEN {
Outcome::Success(Self(value.to_string()))
} else {
- Outcome::Forward(())
+ Outcome::Forward(Status::BadRequest)
}
}
- None => Outcome::Forward(()),
+ None => Outcome::Forward(Status::BadRequest),
}
}
}
diff --git a/crates/ezidam/src/routes.rs b/crates/ezidam/src/routes.rs
index 03c6050..c5372c8 100644
--- a/crates/ezidam/src/routes.rs
+++ b/crates/ezidam/src/routes.rs
@@ -27,6 +27,7 @@ pub(self) mod prelude {
pub use rocket_db_pools::sqlx::Acquire;
pub use rocket_db_pools::Connection;
pub use rocket_dyn_templates::Template;
+ pub use std::ops::DerefMut;
pub type Result = std::result::Result;
}
diff --git a/crates/ezidam/src/routes/admin/apps.rs b/crates/ezidam/src/routes/admin/apps.rs
index 89c8fd6..976377c 100644
--- a/crates/ezidam/src/routes/admin/apps.rs
+++ b/crates/ezidam/src/routes/admin/apps.rs
@@ -10,7 +10,9 @@ pub async fn admin_apps_list(
admin: JwtAdmin,
flash: Option>,
) -> Result {
- let apps = App::get_all(&mut *db, None).await?;
+ let mut transaction = db.begin().await?;
+ let apps = App::get_all(transaction.deref_mut(), None).await?;
+ transaction.commit().await?;
let page = Page::AdminAppsList(super::content::AdminAppsList {
user: admin.0,
@@ -54,8 +56,9 @@ pub async fn admin_apps_new_form(
let app_secret_hash = task::spawn_blocking(move || Secret::new(app_secret)).await??;
// Insert in database
+ let mut transaction = db.begin().await?;
App::insert(
- &mut *db,
+ transaction.deref_mut(),
&app_id,
form.label,
&redirect_uri,
@@ -63,6 +66,7 @@ pub async fn admin_apps_new_form(
form.is_confidential,
)
.await?;
+ transaction.commit().await?;
Ok(Flash::new(
Redirect::to(uri!(admin_apps_list)),
@@ -79,9 +83,11 @@ pub async fn admin_apps_view(
flash: Option>,
) -> Result {
let app_id = id.0;
- let app = App::get_one_by_id(&mut *db, app_id.as_ref())
+ let mut transaction = db.begin().await?;
+ let app = App::get_one_by_id(transaction.deref_mut(), app_id.as_ref())
.await?
.ok_or_else(|| Error::not_found(app_id.to_string()))?;
+ transaction.commit().await?;
if app.is_archived() {
return Err(Error::gone(format!(
@@ -108,14 +114,16 @@ pub async fn admin_apps_view_form(
let redirect_uri = Url::parse(form.redirect_uri)?;
// Update app
+ let mut transaction = db.begin().await?;
App::update(
- &mut *db,
+ transaction.deref_mut(),
&id.0,
form.label,
&redirect_uri,
form.is_confidential,
)
.await?;
+ transaction.commit().await?;
Ok(Flash::new(
Redirect::to(uri!(admin_apps_list)),
@@ -144,7 +152,7 @@ pub async fn admin_apps_new_secret(
// Get app
let app_id = &id.0;
- let app = App::get_one_by_id(&mut transaction, app_id.as_ref())
+ let app = App::get_one_by_id(transaction.deref_mut(), app_id.as_ref())
.await?
.ok_or_else(|| Error::not_found(app_id.to_string()))?;
@@ -163,7 +171,8 @@ pub async fn admin_apps_new_secret(
let app_secret_hash = task::spawn_blocking(move || Secret::new(app_secret)).await??;
// Save new secret
- app.new_secret(&mut transaction, &app_secret_hash).await?;
+ app.new_secret(transaction.deref_mut(), &app_secret_hash)
+ .await?;
transaction.commit().await?;
@@ -198,7 +207,7 @@ pub async fn admin_apps_archive(
// Get app
let app_id = &id.0;
- let app = App::get_one_by_id(&mut transaction, app_id.as_ref())
+ let app = App::get_one_by_id(transaction.deref_mut(), app_id.as_ref())
.await?
.ok_or_else(|| Error::not_found(app_id.to_string()))?;
@@ -210,10 +219,10 @@ pub async fn admin_apps_archive(
}
// Archive
- app.archive(&mut transaction).await?;
+ app.archive(transaction.deref_mut()).await?;
// Revoke refresh tokens
- refresh_tokens::RefreshToken::revoke_all_for_app(&mut transaction, app_id).await?;
+ refresh_tokens::RefreshToken::revoke_all_for_app(transaction.deref_mut(), app_id).await?;
transaction.commit().await?;
diff --git a/crates/ezidam/src/routes/admin/dashboard.rs b/crates/ezidam/src/routes/admin/dashboard.rs
index fdee596..b4b2622 100644
--- a/crates/ezidam/src/routes/admin/dashboard.rs
+++ b/crates/ezidam/src/routes/admin/dashboard.rs
@@ -10,17 +10,17 @@ pub async fn admin_dashboard(mut db: Connection, admin: JwtAdmin) -> R
let mut transaction = db.begin().await?;
// Get users
- let users = User::get_all(&mut transaction).await?;
+ let users = User::get_all(transaction.deref_mut()).await?;
// Get roles
- let roles = Role::get_all(&mut transaction).await?;
+ let roles = Role::get_all(transaction.deref_mut()).await?;
// Get apps
- let apps = App::get_all(&mut transaction, None).await?;
+ let apps = App::get_all(transaction.deref_mut(), None).await?;
// Get number of logins in the last 24 hours
let number_logins_last_24_hours =
- AuthorizationCode::used_in_last_24_hours(&mut transaction).await?;
+ AuthorizationCode::used_in_last_24_hours(transaction.deref_mut()).await?;
transaction.commit().await?;
diff --git a/crates/ezidam/src/routes/admin/permissions.rs b/crates/ezidam/src/routes/admin/permissions.rs
index 5d852f7..ff777da 100644
--- a/crates/ezidam/src/routes/admin/permissions.rs
+++ b/crates/ezidam/src/routes/admin/permissions.rs
@@ -25,7 +25,7 @@ pub async fn admin_permissions_users(
) -> Result {
let mut transaction = db.begin().await?;
- let users = User::get_all(&mut transaction)
+ let users = User::get_all(transaction.deref_mut())
.await?
.into_iter()
.filter(|user| !user.is_archived())
@@ -69,7 +69,7 @@ pub async fn admin_permissions_for_user(
let mut transaction = db.begin().await?;
// Get user
- let user = User::get_by_id(&mut transaction, &id.0)
+ let user = User::get_by_id(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Failed to find user"))?;
@@ -78,14 +78,14 @@ pub async fn admin_permissions_for_user(
}
// Get roles
- let roles = Role::get_all(&mut transaction)
+ let roles = Role::get_all(transaction.deref_mut())
.await?
.into_iter()
.filter(|role| !role.is_archived())
.collect::>();
// Get permissions for user
- let permissions = Permission::get_all(&mut transaction, Some(user.id()), None).await?;
+ let permissions = Permission::get_all(transaction.deref_mut(), Some(user.id()), None).await?;
transaction.commit().await?;
@@ -138,7 +138,7 @@ pub async fn admin_permissions_for_user_form(
let mut transaction = db.begin().await?;
// Get user
- let user = User::get_by_id(&mut transaction, &id.0)
+ let user = User::get_by_id(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Failed to find user"))?;
@@ -147,14 +147,14 @@ pub async fn admin_permissions_for_user_form(
}
// Get roles
- let roles = Role::get_all(&mut transaction)
+ let roles = Role::get_all(transaction.deref_mut())
.await?
.into_iter()
.filter(|role| !role.is_archived())
.collect::>();
// Get permissions for user
- let permissions = Permission::get_all(&mut transaction, Some(user.id()), None).await?;
+ let permissions = Permission::get_all(transaction.deref_mut(), Some(user.id()), None).await?;
transaction.commit().await?;
@@ -167,14 +167,14 @@ pub async fn admin_permissions_for_user_form(
if permissions.iter().all(|perm| perm.role() != role.name()) {
// If the permission does not exist, add it
- Permission::add(&mut transaction, user.id(), role.name()).await?;
+ Permission::add(transaction.deref_mut(), user.id(), role.name()).await?;
}
} else {
// Intent is to delete permission
if permissions.iter().any(|perm| perm.role() == role.name()) {
// If the permission exists, delete it
- Permission::delete(&mut transaction, user.id(), role.name()).await?;
+ Permission::delete(transaction.deref_mut(), user.id(), role.name()).await?;
}
}
}
@@ -200,7 +200,7 @@ pub async fn admin_permissions_roles(
) -> Result {
let mut transaction = db.begin().await?;
- let roles = Role::get_all(&mut transaction)
+ let roles = Role::get_all(transaction.deref_mut())
.await?
.into_iter()
.filter(|role| !role.is_archived())
@@ -236,7 +236,7 @@ pub async fn admin_permissions_for_role(
let mut transaction = db.begin().await?;
// Get role
- let role = Role::get_by_name(&mut transaction, &id.0)
+ let role = Role::get_by_name(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Failed to find role"))?;
@@ -245,14 +245,14 @@ pub async fn admin_permissions_for_role(
}
// Get users
- let users = User::get_all(&mut transaction)
+ let users = User::get_all(transaction.deref_mut())
.await?
.into_iter()
.filter(|user| !user.is_archived())
.collect::>();
// Get permissions for role
- let permissions = Permission::get_all(&mut transaction, None, Some(role.name())).await?;
+ let permissions = Permission::get_all(transaction.deref_mut(), None, Some(role.name())).await?;
transaction.commit().await?;
@@ -305,7 +305,7 @@ pub async fn admin_permissions_for_role_form(
let mut transaction = db.begin().await?;
// Get role
- let role = Role::get_by_name(&mut transaction, &id.0)
+ let role = Role::get_by_name(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Failed to find role"))?;
@@ -314,14 +314,14 @@ pub async fn admin_permissions_for_role_form(
}
// Get users
- let users = User::get_all(&mut transaction)
+ let users = User::get_all(transaction.deref_mut())
.await?
.into_iter()
.filter(|user| !user.is_archived())
.collect::>();
// Get permissions for role
- let permissions = Permission::get_all(&mut transaction, None, Some(role.name())).await?;
+ let permissions = Permission::get_all(transaction.deref_mut(), None, Some(role.name())).await?;
transaction.commit().await?;
@@ -334,14 +334,14 @@ pub async fn admin_permissions_for_role_form(
if permissions.iter().all(|perm| perm.user() != user.id()) {
// If the permission does not exist, add it
- Permission::add(&mut transaction, user.id(), role.name()).await?;
+ Permission::add(transaction.deref_mut(), user.id(), role.name()).await?;
}
} else {
// Intent is to delete permission
if permissions.iter().any(|perm| perm.user() == user.id()) {
// If the permission exists, delete it
- Permission::delete(&mut transaction, user.id(), role.name()).await?;
+ Permission::delete(transaction.deref_mut(), user.id(), role.name()).await?;
}
}
}
diff --git a/crates/ezidam/src/routes/admin/roles.rs b/crates/ezidam/src/routes/admin/roles.rs
index 2b78ccf..79242de 100644
--- a/crates/ezidam/src/routes/admin/roles.rs
+++ b/crates/ezidam/src/routes/admin/roles.rs
@@ -12,7 +12,7 @@ pub async fn admin_roles_list(
) -> Result {
let mut transaction = db.begin().await?;
- let roles = Role::get_all(&mut transaction).await?;
+ let roles = Role::get_all(transaction.deref_mut()).await?;
transaction.commit().await?;
@@ -62,7 +62,7 @@ pub async fn admin_roles_new_form(
let mut transaction = db.begin().await?;
// Insert role in database
- if let Err(e) = Role::insert(&mut transaction, &name, form.label).await {
+ if let Err(e) = Role::insert(transaction.deref_mut(), &name, form.label).await {
return Ok(Flash::new(
Redirect::to(uri!(admin_roles_new)),
FlashKind::Danger,
@@ -91,7 +91,7 @@ pub async fn admin_roles_view(
let mut transaction = db.begin().await?;
- let role = Role::get_by_name(&mut transaction, &role_id)
+ let role = Role::get_by_name(transaction.deref_mut(), &role_id)
.await?
.ok_or_else(|| Error::not_found(role_id.to_string()))?;
@@ -128,12 +128,13 @@ pub async fn admin_roles_archive(
let mut transaction = db.begin().await?;
// Get role
- let role = Role::get_by_name(&mut transaction, &id.0)
+ let role = Role::get_by_name(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Could not find role"))?;
// Set new status
- role.set_archive_status(&mut transaction, true).await?;
+ role.set_archive_status(transaction.deref_mut(), true)
+ .await?;
transaction.commit().await?;
@@ -149,12 +150,13 @@ pub async fn admin_roles_archive(
let mut transaction = db.begin().await?;
// Get role
- let role = Role::get_by_name(&mut transaction, &id.0)
+ let role = Role::get_by_name(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Could not find role"))?;
// Set new status
- role.set_archive_status(&mut transaction, false).await?;
+ role.set_archive_status(transaction.deref_mut(), false)
+ .await?;
transaction.commit().await?;
@@ -191,7 +193,7 @@ pub async fn admin_roles_info_update(
) -> Result> {
let mut transaction = db.begin().await?;
- let role = Role::get_by_name(&mut transaction, &id.0)
+ let role = Role::get_by_name(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Could not find role"))?;
@@ -201,7 +203,7 @@ pub async fn admin_roles_info_update(
// Update label
if role.label() != form.label {
- if let Err(e) = role.set_label(&mut transaction, form.label).await {
+ if let Err(e) = role.set_label(transaction.deref_mut(), form.label).await {
return Ok(Flash::new(
Redirect::to(uri!(admin_roles_view(id))),
FlashKind::Danger,
diff --git a/crates/ezidam/src/routes/admin/settings.rs b/crates/ezidam/src/routes/admin/settings.rs
index 3d6be7c..b6be5f4 100644
--- a/crates/ezidam/src/routes/admin/settings.rs
+++ b/crates/ezidam/src/routes/admin/settings.rs
@@ -15,7 +15,9 @@ use users::User;
#[get("/admin/settings/branding")]
pub async fn settings_branding(mut db: Connection, admin: JwtAdmin) -> Result {
- let settings = Settings::get(&mut *db).await?;
+ let mut transaction = db.begin().await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
+ transaction.commit().await?;
Ok(Page::AdminSettingsBranding(
super::content::AdminSettingsBranding {
@@ -44,12 +46,12 @@ pub async fn settings_update_branding(
match form.delete_logo {
Some(delete_logo) => {
if delete_logo {
- Settings::delete_business_logo(&mut transaction).await?;
+ Settings::delete_business_logo(transaction.deref_mut()).await?;
}
}
None => {
if let Some(business_name) = form.business_name {
- Settings::set_business_name(&mut transaction, business_name).await?;
+ Settings::set_business_name(transaction.deref_mut(), business_name).await?;
}
if form.file.len() != 0 {
@@ -61,7 +63,7 @@ pub async fn settings_update_branding(
let file_bytes = rocket::tokio::fs::read(file_path).await?;
// Save in database
- Settings::set_business_logo(&mut transaction, &file_bytes).await?;
+ Settings::set_business_logo(transaction.deref_mut(), &file_bytes).await?;
}
}
}
@@ -110,30 +112,39 @@ pub async fn settings_security_form(
task::spawn_blocking(move || jwt::generate(&key_id_for_generation)).await??;
// Insert keys in database
- jwt::database::save_new_keys(&mut transaction, &key_id, &private_key, &public_key)
- .await?;
+ jwt::database::save_new_keys(
+ transaction.deref_mut(),
+ &key_id,
+ &private_key,
+ &public_key,
+ )
+ .await?;
// Revoke all keys except new one
- jwt::database::revoke_all_except_one(&mut transaction, &key_id).await?;
+ jwt::database::revoke_all_except_one(transaction.deref_mut(), &key_id).await?;
// Get app
- let app = App::get_one_by_id(&mut transaction, "ezidam")
+ let app = App::get_one_by_id(transaction.deref_mut(), "ezidam")
.await?
.ok_or_else(|| Error::not_found("Could not find application"))?;
// Get user info
- let user = User::get_by_login(&mut transaction, &admin.0.subject)
+ let user = User::get_by_login(transaction.deref_mut(), &admin.0.subject)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
// Revoke all refresh tokens
- RefreshToken::revoke_all(&mut transaction).await?;
+ RefreshToken::revoke_all(transaction.deref_mut()).await?;
// Generate refresh token
- let refresh_token =
- generate_refresh_token(&mut transaction, ip_address, user.id(), app.id())
- .await
- .map_err(Error::internal_server_error)?;
+ let refresh_token = generate_refresh_token(
+ transaction.deref_mut(),
+ ip_address,
+ user.id(),
+ app.id(),
+ )
+ .await
+ .map_err(Error::internal_server_error)?;
// Add refresh token as a cookie
let mut cookie = Cookie::new(REFRESH_TOKEN_COOKIE_NAME, refresh_token);
@@ -144,7 +155,7 @@ pub async fn settings_security_form(
cookie_jar.add(cookie);
// Get base url
- let settings = Settings::get(&mut transaction).await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
let home_page = settings
.url()
.map(String::from)
@@ -152,7 +163,7 @@ pub async fn settings_security_form(
// Generate jwt
let jwt = generate_jwt(
- &mut transaction,
+ transaction.deref_mut(),
&private_key,
&home_page,
&app.id().0,
@@ -194,7 +205,7 @@ pub async fn settings_maintenance(
) -> Result {
let mut transaction = db.begin().await?;
- let database_size = Settings::database_size(&mut transaction)
+ let database_size = Settings::database_size(transaction.deref_mut())
.await?
.ok_or_else(|| Error::internal_server_error("Failed to get database size"))?;
diff --git a/crates/ezidam/src/routes/admin/users.rs b/crates/ezidam/src/routes/admin/users.rs
index 5cd77b5..6b40e2e 100644
--- a/crates/ezidam/src/routes/admin/users.rs
+++ b/crates/ezidam/src/routes/admin/users.rs
@@ -18,7 +18,9 @@ pub async fn admin_users_list(
admin: JwtAdmin,
flash: Option>,
) -> Result {
- let users = User::get_all(&mut *db).await?;
+ let mut transaction = db.begin().await?;
+ let users = User::get_all(transaction.deref_mut()).await?;
+ transaction.commit().await?;
let page = Page::AdminUsersList(super::content::AdminUsersList {
user: admin.0,
@@ -68,7 +70,7 @@ pub async fn admin_users_new_form(
let mut transaction = db.begin().await?;
// Insert user in database
- if let Err(e) = User::insert(&mut transaction, &user_id, false, &username, None).await {
+ if let Err(e) = User::insert(transaction.deref_mut(), &user_id, false, &username, None).await {
return Ok(Flash::new(
Redirect::to(uri!(admin_users_new)),
FlashKind::Danger,
@@ -94,9 +96,11 @@ pub async fn admin_users_view(
flash: Option>,
) -> Result {
let user_id = id.0;
- let user = User::get_by_id(&mut *db, &user_id)
+ let mut transaction = db.begin().await?;
+ let user = User::get_by_id(transaction.deref_mut(), &user_id)
.await?
.ok_or_else(|| Error::not_found(user_id.to_string()))?;
+ transaction.commit().await?;
// If user has password reset token
let password_recover_expiration = user
@@ -136,13 +140,13 @@ pub async fn admin_users_archive(
let mut transaction = db.begin().await?;
// Get ID of first admin
- let settings = Settings::get(&mut transaction).await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
let first_admin = settings
.first_admin()
.ok_or_else(|| Error::bad_request("First user is not set"))?;
// Get user
- let user = User::get_by_id(&mut transaction, &id.0)
+ let user = User::get_by_id(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
@@ -152,17 +156,19 @@ pub async fn admin_users_archive(
}
// Set new status
- user.set_archive_status(&mut transaction, true).await?;
+ user.set_archive_status(transaction.deref_mut(), true)
+ .await?;
// Revoke refresh tokens
- refresh_tokens::RefreshToken::revoke_all_for_user(&mut transaction, user.id()).await?;
+ refresh_tokens::RefreshToken::revoke_all_for_user(transaction.deref_mut(), user.id())
+ .await?;
// Use all authorization codes
- AuthorizationCode::use_all_for_user(&mut transaction, user.id()).await?;
+ AuthorizationCode::use_all_for_user(transaction.deref_mut(), user.id()).await?;
// Use all totp login requests
if user.totp_secret().is_some() {
- TotpLoginRequest::use_all_for_user(&mut transaction, user.id()).await?;
+ TotpLoginRequest::use_all_for_user(transaction.deref_mut(), user.id()).await?;
}
transaction.commit().await?;
@@ -178,12 +184,13 @@ pub async fn admin_users_archive(
let mut transaction = db.begin().await?;
- let user = User::get_by_id(&mut transaction, &id.0)
+ let user = User::get_by_id(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
// Set new status
- user.set_archive_status(&mut transaction, false).await?;
+ user.set_archive_status(transaction.deref_mut(), false)
+ .await?;
transaction.commit().await?;
@@ -234,10 +241,10 @@ pub async fn admin_users_password_reset(
let mut transaction = db.begin().await?;
// Get settings
- let settings = Settings::get(&mut transaction).await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
// Get user
- let user = User::get_by_id(&mut transaction, &id.0)
+ let user = User::get_by_id(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
@@ -245,7 +252,7 @@ pub async fn admin_users_password_reset(
let token = task::spawn_blocking(PasswordResetToken::generate).await?;
// Save in database
- user.set_password_reset_token(&mut transaction, Some(&token))
+ user.set_password_reset_token(transaction.deref_mut(), Some(&token))
.await?;
transaction.commit().await?;
@@ -414,12 +421,12 @@ pub async fn admin_users_paper_key_reset(
let mut transaction = db.begin().await?;
// Get user
- let user = User::get_by_id(&mut transaction, &id.0)
+ let user = User::get_by_id(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
// Delete paper key
- user.set_paper_key(&mut transaction, None).await?;
+ user.set_paper_key(transaction.deref_mut(), None).await?;
transaction.commit().await?;
@@ -452,15 +459,15 @@ pub async fn admin_users_totp_secret_disable(
let mut transaction = db.begin().await?;
// Get user
- let user = User::get_by_id(&mut transaction, &id.0)
+ let user = User::get_by_id(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
// Delete totp secret
- user.set_totp_secret(&mut transaction, None).await?;
+ user.set_totp_secret(transaction.deref_mut(), None).await?;
// Delete totp backup
- user.set_totp_backup(&mut transaction, None).await?;
+ user.set_totp_backup(transaction.deref_mut(), None).await?;
transaction.commit().await?;
@@ -493,12 +500,12 @@ pub async fn admin_users_totp_backup_delete(
let mut transaction = db.begin().await?;
// Get user
- let user = User::get_by_id(&mut transaction, &id.0)
+ let user = User::get_by_id(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
// Delete totp backup
- user.set_totp_backup(&mut transaction, None).await?;
+ user.set_totp_backup(transaction.deref_mut(), None).await?;
transaction.commit().await?;
@@ -531,7 +538,7 @@ pub async fn admin_users_info_update(
) -> Result> {
let mut transaction = db.begin().await?;
- let user = User::get_by_id(&mut transaction, &id.0)
+ let user = User::get_by_id(transaction.deref_mut(), &id.0)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
@@ -553,7 +560,7 @@ pub async fn admin_users_info_update(
}
};
- if let Err(e) = user.set_username(&mut transaction, &username).await {
+ if let Err(e) = user.set_username(transaction.deref_mut(), &username).await {
return Ok(Flash::new(
Redirect::to(uri!(admin_users_view(id))),
FlashKind::Danger,
@@ -571,7 +578,7 @@ pub async fn admin_users_info_update(
// If it does not exist, use provided value
.unwrap_or(true)
{
- user.set_name(&mut transaction, form.name).await?;
+ user.set_name(transaction.deref_mut(), form.name).await?;
}
// Update email
@@ -595,7 +602,7 @@ pub async fn admin_users_info_update(
}
};
- if let Err(e) = user.set_email(&mut transaction, email).await {
+ if let Err(e) = user.set_email(transaction.deref_mut(), email).await {
return Ok(Flash::new(
Redirect::to(uri!(admin_users_view(id))),
FlashKind::Danger,
@@ -607,7 +614,8 @@ pub async fn admin_users_info_update(
// Admin status
let new_status = matches!(form.is_admin, Some("on"));
if user.is_admin() != new_status {
- user.set_admin_status(&mut transaction, new_status).await?;
+ user.set_admin_status(transaction.deref_mut(), new_status)
+ .await?;
}
transaction.commit().await?;
diff --git a/crates/ezidam/src/routes/oauth/authorize.rs b/crates/ezidam/src/routes/oauth/authorize.rs
index c9df67c..4cfafe8 100644
--- a/crates/ezidam/src/routes/oauth/authorize.rs
+++ b/crates/ezidam/src/routes/oauth/authorize.rs
@@ -21,7 +21,7 @@ pub async fn authorize_page(
// Get app info
let app = App::get_valid_app(
- &mut transaction,
+ transaction.deref_mut(),
auth_request.response_type,
auth_request.scope,
auth_request.client_id,
@@ -29,7 +29,7 @@ pub async fn authorize_page(
)
.await?;
- let settings = Settings::get(&mut transaction).await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
transaction.commit().await?;
@@ -59,7 +59,7 @@ pub async fn authorize_ezidam(mut db: Connection) -> Result
// Get ezidam app info
let app_id = "ezidam";
- let app = App::get_one_by_id(&mut transaction, app_id)
+ let app = App::get_one_by_id(transaction.deref_mut(), app_id)
.await?
.ok_or_else(|| Error::not_found(app_id))?;
@@ -117,7 +117,7 @@ pub async fn authorize_form(
// Get app info
let app = App::get_valid_app(
- &mut transaction,
+ transaction.deref_mut(),
auth_request.response_type,
auth_request.scope,
auth_request.client_id,
@@ -145,7 +145,7 @@ pub async fn authorize_form(
};
// Get user
- let Some(user) = User::get_by_login(&mut transaction, form.login).await? else {
+ let Some(user) = User::get_by_login(transaction.deref_mut(), form.login).await? else {
return Ok(Either::Right(invalid_credentials(form.login, auth_request)));
};
@@ -183,7 +183,7 @@ pub async fn authorize_form(
// Save in database
let mut transaction = db.begin().await?;
users::totp_login_request::TotpLoginRequest::insert(
- &mut transaction,
+ transaction.deref_mut(),
totp_token.as_ref(),
&user_id,
totp_duration,
@@ -211,7 +211,7 @@ pub async fn authorize_form(
let mut transaction = db.begin().await?;
// Save authorization code
- AuthorizationCode::insert(&mut transaction, code.as_ref(), app.id(), &user_id).await?;
+ AuthorizationCode::insert(transaction.deref_mut(), code.as_ref(), app.id(), &user_id).await?;
transaction.commit().await?;
diff --git a/crates/ezidam/src/routes/oauth/redirect.rs b/crates/ezidam/src/routes/oauth/redirect.rs
index b793890..a0f0e6d 100644
--- a/crates/ezidam/src/routes/oauth/redirect.rs
+++ b/crates/ezidam/src/routes/oauth/redirect.rs
@@ -26,15 +26,15 @@ pub async fn redirect_page(
let mut transaction = db.begin().await?;
// Get authorization code
- let code = AuthorizationCode::get_one(&mut transaction, redirect_request.code)
+ let code = AuthorizationCode::get_one(transaction.deref_mut(), redirect_request.code)
.await?
.ok_or_else(|| Error::not_found("Could not find authorization code"))?;
// Make sure code has not been used
if code.has_been_used() {
// Revoke all codes and refresh tokens for user
- AuthorizationCode::use_all_for_user(&mut transaction, code.user()).await?;
- RefreshToken::revoke_all_for_user(&mut transaction, code.user()).await?;
+ AuthorizationCode::use_all_for_user(transaction.deref_mut(), code.user()).await?;
+ RefreshToken::revoke_all_for_user(transaction.deref_mut(), code.user()).await?;
transaction.commit().await?;
@@ -49,14 +49,15 @@ pub async fn redirect_page(
}
// Get app
- let app = App::get_one_from_authorization_code(&mut transaction, redirect_request.code)
+ let app = App::get_one_from_authorization_code(transaction.deref_mut(), redirect_request.code)
.await?
.ok_or_else(|| Error::not_found("Could not find application"))?;
// Get user info
- let user = User::get_one_from_authorization_code(&mut transaction, redirect_request.code)
- .await?
- .ok_or_else(|| Error::not_found("Could not find user"))?;
+ let user =
+ User::get_one_from_authorization_code(transaction.deref_mut(), redirect_request.code)
+ .await?
+ .ok_or_else(|| Error::not_found("Could not find user"))?;
// Check if user is archived
if user.is_archived() {
@@ -64,10 +65,10 @@ pub async fn redirect_page(
}
// Mark code as used
- code.use_code(&mut transaction).await?;
+ code.use_code(transaction.deref_mut()).await?;
// Get base url
- let settings = Settings::get(&mut transaction).await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
let home_page = settings
.url()
.map(String::from)
@@ -76,7 +77,7 @@ pub async fn redirect_page(
if jwt_user.is_none() {
// Generate refresh token
let refresh_token =
- generate_refresh_token(&mut transaction, ip_address, user.id(), app.id())
+ generate_refresh_token(transaction.deref_mut(), ip_address, user.id(), app.id())
.await
.map_err(Error::internal_server_error)?;
@@ -89,7 +90,7 @@ pub async fn redirect_page(
cookie_jar.add(cookie);
// Get latest key from database
- let key = Key::get_most_recent(&mut transaction)
+ let key = Key::get_most_recent(transaction.deref_mut())
.await?
.ok_or_else(|| Error::internal_server_error("Failed to get key to sign JWT"))?;
@@ -105,7 +106,7 @@ pub async fn redirect_page(
// Generate jwt
let jwt = generate_jwt(
- &mut transaction,
+ transaction.deref_mut(),
&private_key,
&home_page,
&app.id().0,
@@ -130,7 +131,7 @@ pub async fn redirect_page(
{
// If it has expired, delete it
if password_recover.has_expired() {
- user.set_password_reset_token(&mut transaction, None)
+ user.set_password_reset_token(transaction.deref_mut(), None)
.await?;
}
}
diff --git a/crates/ezidam/src/routes/oauth/token.rs b/crates/ezidam/src/routes/oauth/token.rs
index ffb8a5d..e9af75e 100644
--- a/crates/ezidam/src/routes/oauth/token.rs
+++ b/crates/ezidam/src/routes/oauth/token.rs
@@ -187,7 +187,7 @@ pub async fn request_token(
.ok_or(TokenError::AuthorizationCodeNotProvided)?;
// Get authorization code
- let code = AuthorizationCode::get_one(&mut transaction, authorization_code)
+ let code = AuthorizationCode::get_one(transaction.deref_mut(), authorization_code)
.await
.map_err(TokenError::AuthorizationError)?
.ok_or(TokenError::AuthorizationCodeNotFound(
@@ -197,10 +197,10 @@ pub async fn request_token(
// Make sure code has not been used
if code.has_been_used() {
// Revoke all codes and refresh tokens for user
- AuthorizationCode::use_all_for_user(&mut transaction, code.user())
+ AuthorizationCode::use_all_for_user(transaction.deref_mut(), code.user())
.await
.map_err(TokenError::AuthorizationError)?;
- RefreshToken::revoke_all_for_user(&mut transaction, code.user())
+ RefreshToken::revoke_all_for_user(transaction.deref_mut(), code.user())
.await
.map_err(TokenError::RefreshTokenError)?;
@@ -218,10 +218,11 @@ pub async fn request_token(
}
// Get user info
- let user = User::get_one_from_authorization_code(&mut transaction, authorization_code)
- .await
- .map_err(TokenError::UserError)?
- .ok_or(TokenError::UserNotFound)?;
+ let user =
+ User::get_one_from_authorization_code(transaction.deref_mut(), authorization_code)
+ .await
+ .map_err(TokenError::UserError)?
+ .ok_or(TokenError::UserNotFound)?;
// Check if user is archived
if user.is_archived() {
@@ -229,15 +230,16 @@ pub async fn request_token(
}
// Get app from code
- let app = App::get_one_from_authorization_code(&mut transaction, authorization_code)
- .await
- .map_err(TokenError::AppError)?
- .ok_or(TokenError::AppNotFoundFromAuthorizationCode(
- authorization_code.into(),
- ))?;
+ let app =
+ App::get_one_from_authorization_code(transaction.deref_mut(), authorization_code)
+ .await
+ .map_err(TokenError::AppError)?
+ .ok_or(TokenError::AppNotFoundFromAuthorizationCode(
+ authorization_code.into(),
+ ))?;
// Mark code as used
- code.use_code(&mut transaction)
+ code.use_code(transaction.deref_mut())
.await
.map_err(TokenError::AuthorizationError)?;
@@ -248,19 +250,19 @@ pub async fn request_token(
.refresh_token
.ok_or(TokenError::RefreshTokenNotProvided)?;
- let user = User::get_one_from_refresh_token(&mut transaction, refresh_token)
+ let user = User::get_one_from_refresh_token(transaction.deref_mut(), refresh_token)
.await
.map_err(TokenError::UserError)?
.ok_or(TokenError::UserNotFound)?;
- let refresh_token = RefreshToken::get_one(&mut transaction, refresh_token)
+ let refresh_token = RefreshToken::get_one(transaction.deref_mut(), refresh_token)
.await
.map_err(TokenError::RefreshTokenError)?
.ok_or(TokenError::RefreshTokenNotFound(refresh_token.into()))?;
if refresh_token.has_been_used() {
// Revoke all tokens for user
- RefreshToken::revoke_all_for_user(&mut transaction, refresh_token.user())
+ RefreshToken::revoke_all_for_user(transaction.deref_mut(), refresh_token.user())
.await
.map_err(TokenError::RefreshTokenError)?;
@@ -281,7 +283,7 @@ pub async fn request_token(
}
// Get app
- let app = App::get_one_by_id(&mut transaction, refresh_token.app().as_ref())
+ let app = App::get_one_by_id(transaction.deref_mut(), refresh_token.app().as_ref())
.await
.map_err(TokenError::AppError)?
.ok_or(TokenError::AppNotFoundFromRefreshToken(format!(
@@ -290,7 +292,7 @@ pub async fn request_token(
)))?;
refresh_token
- .use_token(&mut transaction)
+ .use_token(transaction.deref_mut())
.await
.map_err(TokenError::RefreshTokenError)?;
@@ -336,7 +338,7 @@ pub async fn request_token(
}
// Get base url
- let settings = Settings::get(&mut transaction)
+ let settings = Settings::get(transaction.deref_mut())
.await
.map_err(TokenError::SettingsError)?;
let home_page = settings
@@ -345,12 +347,13 @@ pub async fn request_token(
.ok_or(TokenError::ServerUrlNotSet)?;
// Generate refresh token
- let refresh_token = generate_refresh_token(&mut transaction, ip_address, user.id(), app.id())
- .await
- .map_err(TokenError::RefreshTokenGenerate)?;
+ let refresh_token =
+ generate_refresh_token(transaction.deref_mut(), ip_address, user.id(), app.id())
+ .await
+ .map_err(TokenError::RefreshTokenGenerate)?;
// Get latest key from database
- let key = Key::get_most_recent(&mut transaction)
+ let key = Key::get_most_recent(transaction.deref_mut())
.await
.map_err(TokenError::JwtError)?
.ok_or(TokenError::JwkNotFound)?;
@@ -369,7 +372,7 @@ pub async fn request_token(
// Generate jwt
let jwt = generate_jwt(
- &mut transaction,
+ transaction.deref_mut(),
&private_key,
&home_page,
&app.id().0,
diff --git a/crates/ezidam/src/routes/oauth/totp.rs b/crates/ezidam/src/routes/oauth/totp.rs
index d4afd7e..9097776 100644
--- a/crates/ezidam/src/routes/oauth/totp.rs
+++ b/crates/ezidam/src/routes/oauth/totp.rs
@@ -3,7 +3,7 @@ use crate::routes::prelude::*;
use apps::App;
use authorization_codes::AuthorizationCode;
use hash::{Secret, SecretString};
-use rocket::http::{Cookie, CookieJar};
+use rocket::http::CookieJar;
use rocket::{get, post};
use users::totp_login_request::TOTP_REQUEST_COOKIE_NAME;
use users::User;
@@ -19,7 +19,7 @@ pub async fn totp_page(
// Get app info
let _app = App::get_valid_app(
- &mut transaction,
+ transaction.deref_mut(),
auth_request.response_type,
auth_request.scope,
auth_request.client_id,
@@ -28,10 +28,12 @@ pub async fn totp_page(
.await?;
// Get totp request
- let totp_request =
- users::totp_login_request::TotpLoginRequest::get_one(&mut transaction, &totp_request.0)
- .await?
- .ok_or_else(|| Error::not_found("Failed to find totp request"))?;
+ let totp_request = users::totp_login_request::TotpLoginRequest::get_one(
+ transaction.deref_mut(),
+ &totp_request.0,
+ )
+ .await?
+ .ok_or_else(|| Error::not_found("Failed to find totp request"))?;
if totp_request.has_expired() {
return Err(Error::bad_request("Totp request has expired"));
@@ -42,7 +44,7 @@ pub async fn totp_page(
}
// Get user
- let user = User::get_by_id(&mut transaction, totp_request.user())
+ let user = User::get_by_id(transaction.deref_mut(), totp_request.user())
.await?
.ok_or_else(|| Error::not_found("Failed to find user"))?;
@@ -75,7 +77,7 @@ pub async fn totp_verify(
// Get app info
let app = App::get_valid_app(
- &mut transaction,
+ transaction.deref_mut(),
auth_request.response_type,
auth_request.scope,
auth_request.client_id,
@@ -84,10 +86,12 @@ pub async fn totp_verify(
.await?;
// Get totp request
- let totp_request =
- users::totp_login_request::TotpLoginRequest::get_one(&mut transaction, &totp_request.0)
- .await?
- .ok_or_else(|| Error::not_found("Failed to find totp request"))?;
+ let totp_request = users::totp_login_request::TotpLoginRequest::get_one(
+ transaction.deref_mut(),
+ &totp_request.0,
+ )
+ .await?
+ .ok_or_else(|| Error::not_found("Failed to find totp request"))?;
if totp_request.has_expired() {
return Err(Error::bad_request("Totp request has expired"));
@@ -98,7 +102,7 @@ pub async fn totp_verify(
}
// Get user
- let user = User::get_by_id(&mut transaction, totp_request.user())
+ let user = User::get_by_id(transaction.deref_mut(), totp_request.user())
.await?
.ok_or_else(|| Error::not_found("Failed to find user"))?;
@@ -146,20 +150,20 @@ pub async fn totp_verify(
let mut transaction = db.begin().await?;
// Save authorization code
- AuthorizationCode::insert(&mut transaction, code.as_ref(), app.id(), user.id()).await?;
+ AuthorizationCode::insert(transaction.deref_mut(), code.as_ref(), app.id(), user.id()).await?;
// Mark totp token as used
- totp_request.use_code(&mut transaction).await?;
+ totp_request.use_code(transaction.deref_mut()).await?;
// Delete totp backup if it got used
if delete_totp_backup {
- user.set_totp_backup(&mut transaction, None).await?;
+ user.set_totp_backup(transaction.deref_mut(), None).await?;
}
transaction.commit().await?;
// Delete cookie
- cookie_jar.remove(Cookie::named(TOTP_REQUEST_COOKIE_NAME));
+ cookie_jar.remove(TOTP_REQUEST_COOKIE_NAME);
// Construct uri to redirect to
let uri = redirect_uri(auth_request, &app, &code);
diff --git a/crates/ezidam/src/routes/root/forgot_password.rs b/crates/ezidam/src/routes/root/forgot_password.rs
index f4893bf..476aa7a 100644
--- a/crates/ezidam/src/routes/root/forgot_password.rs
+++ b/crates/ezidam/src/routes/root/forgot_password.rs
@@ -67,7 +67,7 @@ pub async fn forgot_password_email_form(
let mut transaction = db.begin().await?;
// Get settings
- let settings = Settings::get(&mut transaction).await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
// Get server url
let url = settings
@@ -85,7 +85,7 @@ pub async fn forgot_password_email_form(
};
// Get user
- let user = match User::get_by_email(&mut transaction, &email).await? {
+ let user = match User::get_by_email(transaction.deref_mut(), &email).await? {
Some(user) => user,
None => {
return Ok(Flash::new(
@@ -100,7 +100,7 @@ pub async fn forgot_password_email_form(
let token = task::spawn_blocking(PasswordResetToken::generate).await?;
// Save in database
- user.set_password_reset_token(&mut transaction, Some(&token))
+ user.set_password_reset_token(transaction.deref_mut(), Some(&token))
.await?;
transaction.commit().await?;
@@ -236,7 +236,7 @@ pub async fn forgot_password_paper_key_form(
let mut transaction = db.begin().await?;
// Get user
- let user = match User::get_by_login(&mut transaction, form.login).await? {
+ let user = match User::get_by_login(transaction.deref_mut(), form.login).await? {
Some(user) => user,
None => {
return Ok(Flash::new(
@@ -272,7 +272,7 @@ pub async fn forgot_password_paper_key_form(
let token = task::spawn_blocking(PasswordResetToken::generate).await?;
// Save in database
- user.set_password_reset_token(&mut transaction, Some(&token))
+ user.set_password_reset_token(transaction.deref_mut(), Some(&token))
.await?;
transaction.commit().await?;
diff --git a/crates/ezidam/src/routes/root/logo.rs b/crates/ezidam/src/routes/root/logo.rs
index 2265f87..c0482f7 100644
--- a/crates/ezidam/src/routes/root/logo.rs
+++ b/crates/ezidam/src/routes/root/logo.rs
@@ -5,7 +5,9 @@ use settings::Settings;
#[get("/logo")]
pub async fn get_logo(mut db: Connection) -> Result {
// Get settings
- let settings = Settings::get(&mut *db).await?;
+ let mut transaction = db.begin().await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
+ transaction.commit().await?;
// HTTP response
Ok(FileFromBytes::from(settings.business_logo()))
diff --git a/crates/ezidam/src/routes/root/logout.rs b/crates/ezidam/src/routes/root/logout.rs
index 3c004dc..0099863 100644
--- a/crates/ezidam/src/routes/root/logout.rs
+++ b/crates/ezidam/src/routes/root/logout.rs
@@ -1,6 +1,6 @@
use crate::routes::prelude::*;
use crate::tokens::{JWT_COOKIE_NAME, REFRESH_TOKEN_COOKIE_NAME};
-use rocket::http::{Cookie, CookieJar};
+use rocket::http::CookieJar;
use rocket::post;
#[post("/logout")]
@@ -11,19 +11,23 @@ pub async fn request_logout(
) -> Result {
let mut transaction = db.begin().await?;
- let refresh_token = refresh_tokens::RefreshToken::get_one(&mut transaction, &refresh_token.0)
- .await?
- .ok_or_else(|| Error::not_found("Unknown refresh token"))?;
+ let refresh_token =
+ refresh_tokens::RefreshToken::get_one(transaction.deref_mut(), &refresh_token.0)
+ .await?
+ .ok_or_else(|| Error::not_found("Unknown refresh token"))?;
// Delete cookies
- cookie_jar.remove(Cookie::named(JWT_COOKIE_NAME));
- cookie_jar.remove(Cookie::named(REFRESH_TOKEN_COOKIE_NAME));
+ cookie_jar.remove(JWT_COOKIE_NAME);
+ cookie_jar.remove(REFRESH_TOKEN_COOKIE_NAME);
// If refresh token has already been used
if refresh_token.has_been_used() {
// Revoke all refresh tokens for user
- refresh_tokens::RefreshToken::revoke_all_for_user(&mut transaction, refresh_token.user())
- .await?;
+ refresh_tokens::RefreshToken::revoke_all_for_user(
+ transaction.deref_mut(),
+ refresh_token.user(),
+ )
+ .await?;
transaction.commit().await?;
@@ -41,7 +45,7 @@ pub async fn request_logout(
}
// Revoke token
- refresh_token.revoke(&mut transaction).await?;
+ refresh_token.revoke(transaction.deref_mut()).await?;
transaction.commit().await?;
diff --git a/crates/ezidam/src/routes/root/reset_password.rs b/crates/ezidam/src/routes/root/reset_password.rs
index 6b15765..f6481b6 100644
--- a/crates/ezidam/src/routes/root/reset_password.rs
+++ b/crates/ezidam/src/routes/root/reset_password.rs
@@ -60,15 +60,16 @@ pub async fn reset_password_form(
let mut transaction = db.begin().await?;
// Get user info
- let user = User::get_one_from_password_reset_token(&mut transaction, &token.0)
+ let user = User::get_one_from_password_reset_token(transaction.deref_mut(), &token.0)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
// Set password
- user.set_password(&mut transaction, Some(&password)).await?;
+ user.set_password(transaction.deref_mut(), Some(&password))
+ .await?;
// Consume password reset token
- user.set_password_reset_token(&mut transaction, None)
+ user.set_password_reset_token(transaction.deref_mut(), None)
.await?;
transaction.commit().await?;
diff --git a/crates/ezidam/src/routes/settings/personal.rs b/crates/ezidam/src/routes/settings/personal.rs
index cecc22d..ca3dc55 100644
--- a/crates/ezidam/src/routes/settings/personal.rs
+++ b/crates/ezidam/src/routes/settings/personal.rs
@@ -11,9 +11,11 @@ pub async fn user_settings_personal(
jwt_user: JwtUser,
flash: Option>,
) -> Result {
- let user = User::get_by_login(&mut *db, &jwt_user.0.subject)
+ let mut transaction = db.begin().await?;
+ let user = User::get_by_login(transaction.deref_mut(), &jwt_user.0.subject)
.await?
.ok_or_else(|| Error::not_found(jwt_user.0.subject.to_string()))?;
+ transaction.commit().await?;
// List possible timezones
let timezones = chrono_tz::TZ_VARIANTS
@@ -54,7 +56,7 @@ pub async fn user_settings_personal_form(
) -> Result> {
let mut transaction = db.begin().await?;
- let user = User::get_by_login(&mut transaction, &jwt_user.0.subject)
+ let user = User::get_by_login(transaction.deref_mut(), &jwt_user.0.subject)
.await?
.ok_or_else(|| Error::not_found(jwt_user.0.subject.to_string()))?;
@@ -76,7 +78,7 @@ pub async fn user_settings_personal_form(
}
};
- if let Err(e) = user.set_username(&mut transaction, &username).await {
+ if let Err(e) = user.set_username(transaction.deref_mut(), &username).await {
return Ok(Flash::new(
Redirect::to(uri!(user_settings_personal)),
FlashKind::Danger,
@@ -94,7 +96,7 @@ pub async fn user_settings_personal_form(
// If it does not exist, use provided value
.unwrap_or(true)
{
- user.set_name(&mut transaction, form.name).await?;
+ user.set_name(transaction.deref_mut(), form.name).await?;
}
// Update email
@@ -118,7 +120,7 @@ pub async fn user_settings_personal_form(
}
};
- if let Err(e) = user.set_email(&mut transaction, email).await {
+ if let Err(e) = user.set_email(transaction.deref_mut(), email).await {
return Ok(Flash::new(
Redirect::to(uri!(user_settings_personal)),
FlashKind::Danger,
@@ -130,7 +132,8 @@ pub async fn user_settings_personal_form(
// Update timezone
let form_timezone = form.timezone.parse().unwrap_or(chrono_tz::UTC).name();
if user.timezone() != form_timezone {
- user.set_timezone(&mut transaction, form_timezone).await?;
+ user.set_timezone(transaction.deref_mut(), form_timezone)
+ .await?;
}
transaction.commit().await?;
diff --git a/crates/ezidam/src/routes/settings/security.rs b/crates/ezidam/src/routes/settings/security.rs
index 6b52990..314d0e5 100644
--- a/crates/ezidam/src/routes/settings/security.rs
+++ b/crates/ezidam/src/routes/settings/security.rs
@@ -25,7 +25,7 @@ pub async fn user_settings_security(
let mut transaction = db.begin().await?;
// Get user info
- let user = User::get_by_login(&mut transaction, &jwt_user.0.subject)
+ let user = User::get_by_login(transaction.deref_mut(), &jwt_user.0.subject)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
@@ -59,21 +59,21 @@ pub async fn user_settings_security_logout_everywhere(
let mut transaction = db.begin().await?;
// Get app
- let app = App::get_one_by_id(&mut transaction, "ezidam")
+ let app = App::get_one_by_id(transaction.deref_mut(), "ezidam")
.await?
.ok_or_else(|| Error::not_found("Could not find application"))?;
// Get user info
- let user = User::get_by_login(&mut transaction, &jwt_user.0.subject)
+ let user = User::get_by_login(transaction.deref_mut(), &jwt_user.0.subject)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
// Revoke all refresh tokens for user
- RefreshToken::revoke_all_for_user(&mut transaction, user.id()).await?;
+ RefreshToken::revoke_all_for_user(transaction.deref_mut(), user.id()).await?;
// Generate refresh token
let refresh_token =
- generate_refresh_token(&mut transaction, ip_address, user.id(), app.id())
+ generate_refresh_token(transaction.deref_mut(), ip_address, user.id(), app.id())
.await
.map_err(Error::internal_server_error)?;
@@ -86,14 +86,14 @@ pub async fn user_settings_security_logout_everywhere(
cookie_jar.add(cookie);
// Get base url
- let settings = Settings::get(&mut transaction).await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
let home_page = settings
.url()
.map(String::from)
.ok_or_else(|| Error::bad_request("Server url is not set"))?;
// Get latest key from database
- let key = Key::get_most_recent(&mut transaction)
+ let key = Key::get_most_recent(transaction.deref_mut())
.await?
.ok_or_else(|| Error::internal_server_error("Failed to get a signing key"))?;
@@ -109,7 +109,7 @@ pub async fn user_settings_security_logout_everywhere(
// Generate jwt
let jwt = generate_jwt(
- &mut transaction,
+ transaction.deref_mut(),
&private_key,
&home_page,
&app.id().0,
@@ -158,12 +158,12 @@ pub async fn user_settings_security_paper_key(
let mut transaction = db.begin().await?;
// Get user info
- let user = User::get_by_login(&mut transaction, &jwt_user.0.subject)
+ let user = User::get_by_login(transaction.deref_mut(), &jwt_user.0.subject)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
// Save paper key
- user.set_paper_key(&mut transaction, Some(&paper_key))
+ user.set_paper_key(transaction.deref_mut(), Some(&paper_key))
.await?;
transaction.commit().await?;
@@ -208,12 +208,13 @@ pub async fn user_settings_security_password(
let mut transaction = db.begin().await?;
// Get user info
- let user = User::get_by_login(&mut transaction, &jwt_user.0.subject)
+ let user = User::get_by_login(transaction.deref_mut(), &jwt_user.0.subject)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
// Set password
- user.set_password(&mut transaction, Some(&password)).await?;
+ user.set_password(transaction.deref_mut(), Some(&password))
+ .await?;
transaction.commit().await?;
@@ -241,7 +242,7 @@ pub async fn user_settings_security_totp(
let mut transaction = db.begin().await?;
// Get settings
- let settings = Settings::get(&mut transaction).await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
// Get issuer
let issuer = settings
@@ -298,12 +299,12 @@ pub async fn user_settings_security_totp_form(
let mut transaction = db.begin().await?;
// Get user info
- let user = User::get_by_login(&mut transaction, &jwt_user.0.subject)
+ let user = User::get_by_login(transaction.deref_mut(), &jwt_user.0.subject)
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
// Get settings
- let settings = Settings::get(&mut transaction).await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
// Get totp issuer
let issuer = settings
@@ -321,8 +322,8 @@ pub async fn user_settings_security_totp_form(
// Delete secret and backup
let mut transaction = db.begin().await?;
- user.set_totp_secret(&mut transaction, None).await?;
- user.set_totp_backup(&mut transaction, None).await?;
+ user.set_totp_secret(transaction.deref_mut(), None).await?;
+ user.set_totp_backup(transaction.deref_mut(), None).await?;
transaction.commit().await?;
@@ -365,14 +366,14 @@ pub async fn user_settings_security_totp_form(
return if totp.check_current(token)? {
let mut transaction = db.begin().await?;
- user.set_totp_secret(&mut transaction, Some(&totp_secret))
+ user.set_totp_secret(transaction.deref_mut(), Some(&totp_secret))
.await?;
- user.set_totp_backup(&mut transaction, None).await?;
+ user.set_totp_backup(transaction.deref_mut(), None).await?;
transaction.commit().await?;
// Remove cookie
- cookie_jar.remove(Cookie::named(TOTP_COOKIE_NAME));
+ cookie_jar.remove(TOTP_COOKIE_NAME);
Ok(Flash::new(
Redirect::to(uri!(user_settings_security)),
@@ -418,7 +419,7 @@ pub async fn user_settings_security_totp_backup(
let mut transaction = db.begin().await?;
// Get user info
- let user = User::get_by_id(&mut transaction, &UserID(jwt_user.0.subject))
+ let user = User::get_by_id(transaction.deref_mut(), &UserID(jwt_user.0.subject))
.await?
.ok_or_else(|| Error::not_found("Could not find user"))?;
@@ -434,7 +435,7 @@ pub async fn user_settings_security_totp_backup(
let mut transaction = db.begin().await?;
// Save backup code
- user.set_totp_backup(&mut transaction, Some(&secret))
+ user.set_totp_backup(transaction.deref_mut(), Some(&secret))
.await?;
transaction.commit().await?;
diff --git a/crates/ezidam/src/routes/setup.rs b/crates/ezidam/src/routes/setup.rs
index 383c87d..17ea94c 100644
--- a/crates/ezidam/src/routes/setup.rs
+++ b/crates/ezidam/src/routes/setup.rs
@@ -85,7 +85,7 @@ async fn create_first_account(
// Insert ezidam app in database
App::insert(
- &mut transaction,
+ transaction.deref_mut(),
&ezidam_app_id,
"Ezidam",
&ezidam_redirect_uri,
@@ -95,13 +95,20 @@ async fn create_first_account(
.await?;
// Insert user in database
- User::insert(&mut transaction, &user_id, true, &username, Some(&password)).await?;
+ User::insert(
+ transaction.deref_mut(),
+ &user_id,
+ true,
+ &username,
+ Some(&password),
+ )
+ .await?;
// Store UserID in settings
- Settings::set_first_admin(&mut transaction, &user_id).await?;
+ Settings::set_first_admin(transaction.deref_mut(), &user_id).await?;
// Store URL in settings
- Settings::set_url(&mut transaction, &url).await?;
+ Settings::set_url(transaction.deref_mut(), &url).await?;
transaction.commit().await?;
diff --git a/crates/ezidam/src/routes/well_known.rs b/crates/ezidam/src/routes/well_known.rs
index e15bf66..0a663c4 100644
--- a/crates/ezidam/src/routes/well_known.rs
+++ b/crates/ezidam/src/routes/well_known.rs
@@ -14,7 +14,9 @@ pub fn routes() -> Vec {
#[get("/.well-known/openid-configuration")]
async fn openid_configuration(mut db: Connection) -> Result> {
// Get settings
- let settings = Settings::get(&mut *db).await?;
+ let mut transaction = db.begin().await?;
+ let settings = Settings::get(transaction.deref_mut()).await?;
+ transaction.commit().await?;
// Get server url
let url = settings
@@ -31,7 +33,9 @@ async fn openid_configuration(mut db: Connection) -> Result) -> Result {
// Get keys
- let keys = Key::get_all(&mut *db, Some(false)).await?;
+ let mut transaction = db.begin().await?;
+ let keys = Key::get_all(transaction.deref_mut(), Some(false)).await?;
+ transaction.commit().await?;
// For each key, import as public key and extract the jwk
let json_web_keys = join_all(keys.into_iter().map(|key| {