Skip to content

Commit 67e51f8

Browse files
committed
new database_password configuration option
1 parent dd919d3 commit 67e51f8

File tree

4 files changed

+29
-2
lines changed

4 files changed

+29
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- **Fix**: the search feature in the shell component was not working when no menu item was defined.
66
- Add support for encrypted Microsoft SQL Server connections. This finally allows connecting to databases that refuse clear-text connections, such as those hosted on Azure.
77
- Easier json handling in databases without a native json type. SQLPage now detects when you use a json function in SQLite or MariaDB to generate a column, and automatically converts the resulting string to a json object. This allows easily using components that take json parameters (like the new columns component) in MariaDB and SQLite.
8+
- Add a new optional `database_password` configuration option to set the password for the database connection separately from the connection string. This allows to keep the password separate from the connection string, which can be useful for security purposes, logging, and avoids having to percent-encode the password in the connection string.
89

910
## 0.29.0 (2024-09-25)
1011
- New columns component: `columns`. Useful to display a comparison between items, or large key figures to an user.

configuration.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Here are the available configuration options and their default values:
1010
| --------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
1111
| `listen_on` | 0.0.0.0:8080 | Interface and port on which the web server should listen |
1212
| `database_url` | sqlite://sqlpage.db?mode=rwc | Database connection URL, in the form `dbengine://user:password@host:port/dbname`. Special characters in user and password should be [percent-encoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding). |
13+
| `database_password` | | Database password. If set, this will override any password specified in the `database_url`. This allows you to keep the password separate from the connection string for better security. |
1314
| `port` | 8080 | Like listen_on, but specifies only the port. |
1415
| `unix_socket` | | Path to a UNIX socket to listen on instead of the TCP port. If specified, SQLPage will accept HTTP connections only on this socket and not on any TCP port. This option is mutually exclusive with `listen_on` and `port`.
1516
| `max_database_pool_connections` | PostgreSQL: 50<BR> MySql: 75<BR> SQLite: 16<BR> MSSQL: 100 | How many simultaneous database connections to open at most |
@@ -75,10 +76,15 @@ A full connection string for a PostgreSQL database might look like this:
7576
postgres://my_user:p%40ss@localhost:5432/my_database?sslmode=verify-ca&sslrootcert=/path/to/ca.pem&sslcert=/path/to/cert.pem&sslkey=/path/to/key.pem&application_name=my_application
7677
```
7778

79+
If the `database_password` configuration parameter is set, it will override any password specified in the `database_url`.
80+
It does not need to be percent-encoded.
81+
This allows you to keep the password separate from the connection string, which can be useful for security purposes, especially when storing configurations in version control systems.
82+
7883
### Example `.env` file
7984

8085
```bash
81-
DATABASE_URL="sqlite:///path/to/my_database.db?mode=rwc"
86+
DATABASE_URL="postgres://my_user@localhost:5432/my_database?sslmode=verify-ca&sslrootcert=/path/to/ca.pem"
87+
DATABASE_PASSWORD="my_secure_password"
8288
SQLITE_EXTENSIONS="mod_spatialite crypto define regexp"
8389
```
8490

src/app_config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ pub fn load_from_env() -> anyhow::Result<AppConfig> {
148148
pub struct AppConfig {
149149
#[serde(default = "default_database_url")]
150150
pub database_url: String,
151+
/// A separate field for the database password. If set, this will override any password specified in the `database_url`.
152+
#[serde(default)]
153+
pub database_password: Option<String>,
151154
pub max_database_pool_connections: Option<u32>,
152155
pub database_connection_idle_timeout_seconds: Option<f64>,
153156
pub database_connection_max_lifetime_seconds: Option<f64>,

src/webserver/database/connect.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::time::Duration;
1+
use std::{mem::take, time::Duration};
22

33
use super::Database;
44
use crate::{app_config::AppConfig, ON_CONNECT_FILE};
@@ -16,6 +16,9 @@ impl Database {
1616
let mut connect_options: AnyConnectOptions = database_url
1717
.parse()
1818
.with_context(|| format!("\"{database_url}\" is not a valid database URL. Please change the \"database_url\" option in the configuration file."))?;
19+
if let Some(password) = &config.database_password {
20+
set_database_password(&mut connect_options, password);
21+
}
1922
connect_options.log_statements(log::LevelFilter::Trace);
2023
connect_options.log_slow_statements(
2124
log::LevelFilter::Warn,
@@ -148,3 +151,17 @@ fn make_sqlite_fun(name: &str, f: fn(&str) -> String) -> Function {
148151
}
149152
})
150153
}
154+
155+
fn set_database_password(options: &mut AnyConnectOptions, password: &str) {
156+
if let Some(opts) = options.as_postgres_mut() {
157+
*opts = take(opts).password(password);
158+
} else if let Some(opts) = options.as_mysql_mut() {
159+
*opts = take(opts).password(password);
160+
} else if let Some(opts) = options.as_mssql_mut() {
161+
*opts = take(opts).password(password);
162+
} else if let Some(_opts) = options.as_sqlite_mut() {
163+
log::warn!("Setting a password for a SQLite database is not supported");
164+
} else {
165+
unreachable!("Unsupported database type");
166+
}
167+
}

0 commit comments

Comments
 (0)