remove sqlite extensions to fix docker issue

UUIDs are now generated in the backend before insertion
This commit is contained in:
2025-09-07 17:19:16 +02:00
parent a1c9832515
commit 6fa26b3ddb
33 changed files with 754 additions and 308 deletions

View File

@@ -1,6 +1,6 @@
use crate::domain::{
oidc::ports::OidcMetrics,
warren::ports::{AuthMetrics, FileSystemMetrics, WarrenMetrics},
warren::ports::{AuthMetrics, FileSystemMetrics, OptionMetrics, WarrenMetrics},
};
#[derive(Debug, Clone, Copy)]
@@ -452,3 +452,26 @@ impl OidcMetrics for MetricsDebugLogger {
tracing::debug!("[Metrics] OIDC get user info failed");
}
}
impl OptionMetrics for MetricsDebugLogger {
async fn record_option_get_success(&self) {
tracing::debug!("[Metrics] Get option succeeded");
}
async fn record_option_get_failure(&self) {
tracing::debug!("[Metrics] Get option failed");
}
async fn record_option_set_success(&self) {
tracing::debug!("[Metrics] Set option succeeded");
}
async fn record_option_set_failure(&self) {
tracing::debug!("[Metrics] Set option failed");
}
async fn record_option_delete_success(&self) {
tracing::debug!("[Metrics] Delete option succeeded");
}
async fn record_option_delete_failure(&self) {
tracing::debug!("[Metrics] Delete option failed");
}
}

View File

@@ -9,6 +9,7 @@ use crate::domain::{
models::{
auth_session::requests::FetchAuthSessionResponse,
file::{AbsoluteFilePath, AbsoluteFilePathList, LsResponse},
option::{DeleteOptionResponse, GetOptionResponse, OptionType, SetOptionResponse},
share::{
CreateShareResponse, DeleteShareResponse, GetShareResponse, ListSharesResponse,
ShareCatResponse, ShareLsResponse, VerifySharePasswordResponse,
@@ -22,7 +23,7 @@ use crate::domain::{
WarrenRmResponse, WarrenSaveResponse, WarrenTouchResponse,
},
},
ports::{AuthNotifier, FileSystemNotifier, WarrenNotifier},
ports::{AuthNotifier, FileSystemNotifier, OptionNotifier, WarrenNotifier},
},
};
@@ -515,3 +516,25 @@ impl OidcNotifier for NotifierDebugLogger {
);
}
}
impl OptionNotifier for NotifierDebugLogger {
async fn got_option<T: OptionType>(&self, response: &GetOptionResponse<T>) {
tracing::debug!(
"[Notifier] Got option {}: {}",
response.key().to_string(),
response.value().to_string(),
);
}
async fn set_option<T: OptionType>(&self, response: &SetOptionResponse<T>) {
tracing::debug!(
"[Notifier] Set option {} to {}",
response.key().to_string(),
response.value().to_string(),
);
}
async fn deleted_option(&self, response: &DeleteOptionResponse) {
tracing::debug!("[Notifier] Deleted option {}", response.key().to_string());
}
}

View File

@@ -48,7 +48,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let user = self
.create_user(
@@ -72,7 +72,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let user = self
.create_or_update_user(
@@ -93,7 +93,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let user = self
.edit_user(
@@ -115,7 +115,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
self.delete_user_from_database(&mut connection, request.user_id())
.await
@@ -136,7 +136,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let user = self
.get_user_from_email(&mut connection, request.email())
@@ -166,7 +166,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let session = self
.create_session(&mut connection, request.user(), request.expiration())
@@ -184,7 +184,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let session = self
.get_auth_session(&mut connection, request.session_id())
@@ -212,7 +212,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let user_warren = self
.add_user_to_warren(&mut connection, request.user_warren())
@@ -230,7 +230,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let user_warren = self
.update_user_warren(&mut connection, request.user_warren())
@@ -248,7 +248,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let user_warren = self
.remove_user_from_warren(&mut connection, request.user_id(), request.warren_id())
@@ -272,7 +272,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let user_warrens = self
.get_user_warrens(&mut connection, request.user_id())
@@ -290,7 +290,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let user_warrens = self
.get_all_user_warrens(&mut connection)
@@ -308,7 +308,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
self.get_user_warren(&mut connection, request.user_id(), request.warren_id())
.await
@@ -326,7 +326,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let users = self
.fetch_users(&mut connection)
@@ -345,7 +345,7 @@ impl AuthRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let users = self
.fetch_users(&mut connection)
@@ -402,6 +402,7 @@ impl Sqlite {
let user: User = sqlx::query_as(
"INSERT INTO users (
id,
name,
email,
hash,
@@ -411,12 +412,14 @@ impl Sqlite {
$1,
$2,
$3,
$4
$4,
$5
)
RETURNING
*
",
)
.bind(Uuid::new_v4())
.bind(name)
.bind(email)
.bind(password_hash)

View File

@@ -6,6 +6,7 @@ use sqlx::{
};
use tokio::task::JoinHandle;
pub mod auth;
pub mod options;
pub mod share;
pub mod warrens;
@@ -29,10 +30,6 @@ impl Sqlite {
pub async fn new(config: SqliteConfig) -> anyhow::Result<Self> {
let opts = SqliteConnectOptions::from_str(&config.database_url)?
.create_if_missing(true)
.extension_with_entrypoint(
"/var/lib/warren/sqlite_extensions/uuid",
"sqlite3_uuid_init",
)
.disable_statement_logging();
let pool = SqlitePoolOptions::new().connect_with(opts).await?;

View File

@@ -0,0 +1,134 @@
use anyhow::Context;
use sqlx::FromRow;
use crate::domain::warren::{
models::option::{
DeleteOptionError, DeleteOptionRequest, DeleteOptionResponse, GetOptionError,
GetOptionRequest, GetOptionResponse, OptionKey, OptionType, SetOptionError,
SetOptionRequest, SetOptionResponse,
},
ports::OptionRepository,
};
use super::{Sqlite, is_not_found_error};
#[derive(Debug, FromRow)]
struct OptionRow {
key: String,
value: String,
}
impl OptionRepository for Sqlite {
async fn get_option<T: OptionType>(
&self,
request: GetOptionRequest,
) -> Result<GetOptionResponse<T>, GetOptionError> {
let mut connection = self
.pool
.acquire()
.await
.context("Failed to get a Sqlite connection")?;
let key: OptionKey = request.into();
let row: OptionRow = sqlx::query_as(
"
SELECT
key,
value
FROM
application_options
WHERE
key = $1",
)
.bind(key.as_str())
.fetch_one(&mut *connection)
.await
.map_err(|e| {
if is_not_found_error(&e) {
GetOptionError::NotFound(key)
} else {
GetOptionError::Unknown(e.into())
}
})?;
let parsed = T::parse(&row.value).map_err(|_| GetOptionError::Parse)?;
Ok(GetOptionResponse::new(
OptionKey::new(&row.key).unwrap(),
parsed,
))
}
async fn set_option<T: OptionType>(
&self,
request: SetOptionRequest<T>,
) -> Result<SetOptionResponse<T>, SetOptionError> {
let mut connection = self
.pool
.acquire()
.await
.context("Failed to get a Sqlite connection")?;
let (key, value) = request.unpack();
sqlx::query_as::<_, OptionRow>(
"
INSERT INTO application_options (
key,
value
) VALUES (
$1,
$2
)
RETURNING
key,
value
",
)
.bind(key.as_str())
.bind(value.inner().to_string())
.fetch_one(&mut *connection)
.await
.map_err(|e| SetOptionError::Unknown(e.into()))?;
Ok(SetOptionResponse::new(key, value.get_inner()))
}
async fn delete_option(
&self,
request: DeleteOptionRequest,
) -> Result<DeleteOptionResponse, DeleteOptionError> {
let mut connection = self
.pool
.acquire()
.await
.context("Failed to get a Sqlite connection")?;
let key: OptionKey = request.into();
sqlx::query_as::<_, OptionRow>(
"
DELETE FROM
application_options
WHERE
key = $1
RETURNING
key,
value
",
)
.bind(key.as_str())
.fetch_one(&mut *connection)
.await
.map_err(|e| {
if is_not_found_error(&e) {
DeleteOptionError::NotFound(key.clone())
} else {
DeleteOptionError::Unknown(e.into())
}
})?;
Ok(DeleteOptionResponse::new(key))
}
}

View File

@@ -154,6 +154,7 @@ pub(super) async fn create_share(
let share: ShareRow = sqlx::query_as(
"
INSERT INTO shares (
id,
creator_id,
warren_id,
path,
@@ -164,12 +165,14 @@ pub(super) async fn create_share(
$2,
$3,
$4,
datetime($5, 'unixepoch')
$5,
datetime($6, 'unixepoch')
)
RETURNING
*
",
)
.bind(Uuid::new_v4())
.bind(request.creator_id())
.bind(request.warren_id())
.bind(request.base().path())

View File

@@ -32,7 +32,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let warren = self
.create_warren(&mut connection, request.name(), request.path())
@@ -47,7 +47,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let warren = self
.edit_warren(
@@ -70,7 +70,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let warren = self
.delete_warren(&mut connection, request.id())
@@ -88,7 +88,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let warrens = self
.fetch_warrens(&mut connection, request.ids())
@@ -106,7 +106,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let warrens = self
.fetch_all_warrens(&mut connection)
@@ -121,7 +121,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let warren = self
.get_warren(&mut connection, request.id())
@@ -144,7 +144,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
super::share::get_share(&mut connection, request)
.await
@@ -159,7 +159,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
super::share::create_share(&mut connection, request)
.await
@@ -177,7 +177,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
let path = request.path().clone();
@@ -195,7 +195,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
super::share::delete_share(&mut connection, request)
.await
@@ -211,7 +211,7 @@ impl WarrenRepository for Sqlite {
.pool
.acquire()
.await
.context("Failed to get a PostgreSQL connection")?;
.context("Failed to get a Sqlite connection")?;
super::share::verify_password(&mut connection, request)
.await
@@ -232,16 +232,19 @@ impl Sqlite {
let warren: Warren = sqlx::query_as(
"
INSERT INTO warrens (
id,
name,
path
) VALUES (
$1,
$2
$2,
$3
)
RETURNING
*
",
)
.bind(Uuid::new_v4())
.bind(name)
.bind(path)
.fetch_one(&mut *tx)