mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2026-06-01 20:25:36 -06:00
Merge ac5d1f653e into f21a3adae2
This commit is contained in:
commit
00132aefaa
@ -50,10 +50,11 @@
|
|||||||
#########################
|
#########################
|
||||||
|
|
||||||
## Database URL
|
## Database URL
|
||||||
## When using SQLite, this is the path to the DB file, and it defaults to
|
## When using SQLite, this should use the sqlite:// scheme followed by the path
|
||||||
## %DATA_FOLDER%/db.sqlite3. If DATA_FOLDER is set to an external location, this
|
## to the DB file. It defaults to sqlite://%DATA_FOLDER%/db.sqlite3.
|
||||||
## must be set to a local sqlite3 file path.
|
## Bare paths without the sqlite:// scheme are supported for backwards compatibility,
|
||||||
# DATABASE_URL=data/db.sqlite3
|
## but only if the database file already exists.
|
||||||
|
# DATABASE_URL=sqlite://data/db.sqlite3
|
||||||
## When using MySQL, specify an appropriate connection URI.
|
## When using MySQL, specify an appropriate connection URI.
|
||||||
## Details: https://docs.diesel.rs/2.1.x/diesel/mysql/struct.MysqlConnection.html
|
## Details: https://docs.diesel.rs/2.1.x/diesel/mysql/struct.MysqlConnection.html
|
||||||
# DATABASE_URL=mysql://user:password@host[:port]/database_name
|
# DATABASE_URL=mysql://user:password@host[:port]/database_name
|
||||||
|
|||||||
@ -507,7 +507,7 @@ make_config! {
|
|||||||
/// Data folder |> Main data folder
|
/// Data folder |> Main data folder
|
||||||
data_folder: String, false, def, "data".to_string();
|
data_folder: String, false, def, "data".to_string();
|
||||||
/// Database URL
|
/// Database URL
|
||||||
database_url: String, false, auto, |c| format!("{}/db.sqlite3", c.data_folder);
|
database_url: String, false, auto, |c| format!("sqlite://{}/db.sqlite3", c.data_folder);
|
||||||
/// Icon cache folder
|
/// Icon cache folder
|
||||||
icon_cache_folder: String, false, auto, |c| format!("{}/icon_cache", c.data_folder);
|
icon_cache_folder: String, false, auto, |c| format!("{}/icon_cache", c.data_folder);
|
||||||
/// Attachments folder
|
/// Attachments folder
|
||||||
@ -929,14 +929,17 @@ fn validate_config(cfg: &ConfigItems, on_update: bool) -> Result<(), Error> {
|
|||||||
{
|
{
|
||||||
use crate::db::DbConnType;
|
use crate::db::DbConnType;
|
||||||
let url = &cfg.database_url;
|
let url = &cfg.database_url;
|
||||||
if DbConnType::from_url(url)? == DbConnType::Sqlite && url.contains('/') {
|
if DbConnType::from_url(url)? == DbConnType::Sqlite {
|
||||||
let path = std::path::Path::new(&url);
|
let file_path = url.strip_prefix("sqlite://").unwrap_or(url);
|
||||||
if let Some(parent) = path.parent() {
|
if file_path.contains('/') {
|
||||||
if !parent.is_dir() {
|
let path = std::path::Path::new(file_path);
|
||||||
err!(format!(
|
if let Some(parent) = path.parent() {
|
||||||
"SQLite database directory `{}` does not exist or is not a directory",
|
if !parent.is_dir() {
|
||||||
parent.display()
|
err!(format!(
|
||||||
));
|
"SQLite database directory `{}` does not exist or is not a directory",
|
||||||
|
parent.display()
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -272,13 +272,32 @@ impl DbConnType {
|
|||||||
#[cfg(not(postgresql))]
|
#[cfg(not(postgresql))]
|
||||||
err!("`DATABASE_URL` is a PostgreSQL URL, but the 'postgresql' feature is not enabled")
|
err!("`DATABASE_URL` is a PostgreSQL URL, but the 'postgresql' feature is not enabled")
|
||||||
|
|
||||||
//Sqlite
|
// Sqlite (explicit)
|
||||||
} else {
|
} else if url.len() > 7 && &url[..7] == "sqlite:" {
|
||||||
#[cfg(sqlite)]
|
#[cfg(sqlite)]
|
||||||
return Ok(DbConnType::Sqlite);
|
return Ok(DbConnType::Sqlite);
|
||||||
|
|
||||||
#[cfg(not(sqlite))]
|
#[cfg(not(sqlite))]
|
||||||
err!("`DATABASE_URL` looks like a SQLite URL, but 'sqlite' feature is not enabled")
|
err!("`DATABASE_URL` is a SQLite URL, but the 'sqlite' feature is not enabled")
|
||||||
|
|
||||||
|
// No recognized scheme — assume legacy bare-path SQLite, but the database file must already exist.
|
||||||
|
// This prevents misconfigured URLs (typos, quoted strings) from silently creating a new empty SQLite database.
|
||||||
|
} else {
|
||||||
|
#[cfg(sqlite)]
|
||||||
|
{
|
||||||
|
if std::path::Path::new(url).exists() {
|
||||||
|
return Ok(DbConnType::Sqlite);
|
||||||
|
}
|
||||||
|
err!(format!(
|
||||||
|
"`DATABASE_URL` does not match any known database scheme (mysql://, postgresql://, sqlite://) \
|
||||||
|
and no existing SQLite database was found at '{url}'. \
|
||||||
|
If you intend to use SQLite, use an explicit `sqlite://` scheme in your `DATABASE_URL`. \
|
||||||
|
Otherwise, check your DATABASE_URL for typos or quoting issues."
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(sqlite))]
|
||||||
|
err!("`DATABASE_URL` does not match any known database scheme (mysql://, postgresql://, sqlite://)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,11 +409,12 @@ pub fn backup_sqlite() -> Result<String, Error> {
|
|||||||
|
|
||||||
let db_url = CONFIG.database_url();
|
let db_url = CONFIG.database_url();
|
||||||
if DbConnType::from_url(&CONFIG.database_url()).map(|t| t == DbConnType::Sqlite).unwrap_or(false) {
|
if DbConnType::from_url(&CONFIG.database_url()).map(|t| t == DbConnType::Sqlite).unwrap_or(false) {
|
||||||
// Since we do not allow any schema for sqlite database_url's like `file:` or `sqlite:` to be set, we can assume here it isn't
|
// Strip the sqlite:// prefix if present to get the raw file path
|
||||||
// This way we can set a readonly flag on the opening mode without issues.
|
let file_path = db_url.strip_prefix("sqlite://").unwrap_or(&db_url);
|
||||||
let mut conn = diesel::sqlite::SqliteConnection::establish(&format!("sqlite://{db_url}?mode=ro"))?;
|
// Open a read-only connection for the backup
|
||||||
|
let mut conn = diesel::sqlite::SqliteConnection::establish(&format!("sqlite://{file_path}?mode=ro"))?;
|
||||||
|
|
||||||
let db_path = std::path::Path::new(&db_url).parent().unwrap();
|
let db_path = std::path::Path::new(file_path).parent().unwrap();
|
||||||
let backup_file = db_path
|
let backup_file = db_path
|
||||||
.join(format!("db_{}.sqlite3", chrono::Utc::now().format("%Y%m%d_%H%M%S")))
|
.join(format!("db_{}.sqlite3", chrono::Utc::now().format("%Y%m%d_%H%M%S")))
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user