clippy pedantic fix + get rid of a few unwraps
All checks were successful
Build and test / docs (push) Successful in 7m1s
Build and test / check-license (push) Successful in 57s
Build and test / check (push) Successful in 2m46s
Build and test / build (push) Successful in 3m12s
Build and test / test (push) Successful in 3m25s

This commit is contained in:
2025-12-23 13:40:46 +09:00
parent c866400b4a
commit 4c3677d6d3
51 changed files with 596 additions and 545 deletions

View File

@@ -42,10 +42,8 @@ pub async fn check_authorization(
/// - `gid:1001`
/// - `group:admins`
pub fn read_and_parse_group_denylist(denylist_path: &Path) -> anyhow::Result<GroupDenylist> {
let content = std::fs::read_to_string(denylist_path).context(format!(
"Failed to read denylist file at {:?}",
denylist_path
))?;
let content = std::fs::read_to_string(denylist_path)
.context(format!("Failed to read denylist file at {denylist_path:?}"))?;
let mut groups = HashSet::with_capacity(content.lines().count());
@@ -128,7 +126,6 @@ pub fn read_and_parse_group_denylist(denylist_path: &Path) -> anyhow::Result<Gro
line_number + 1,
err
);
continue;
}
},
_ => {

View File

@@ -44,7 +44,7 @@ impl MysqlConfig {
if let Some(password_file) = &self.password_file {
let password = fs::read_to_string(password_file)
.with_context(|| {
format!("Failed to read MySQL password file at {:?}", password_file)
format!("Failed to read MySQL password file at {password_file:?}")
})?
.trim()
.to_owned();
@@ -96,8 +96,8 @@ impl ServerConfig {
tracing::debug!("Reading config file at {:?}", config_path);
fs::read_to_string(config_path)
.context(format!("Failed to read config file at {:?}", config_path))
.context(format!("Failed to read config file at {config_path:?}"))
.and_then(|c| toml::from_str(&c).context("Failed to parse config file"))
.context(format!("Failed to parse config file at {:?}", config_path))
.context(format!("Failed to parse config file at {config_path:?}"))
}
}

View File

@@ -78,7 +78,7 @@ pub async fn session_handler(
))
.await
.ok();
anyhow::bail!("Failed to get username from uid: {}", e);
anyhow::bail!("Failed to get username from uid: {e}");
}
};
@@ -181,10 +181,10 @@ async fn session_handler_with_db_connection(
request => request.to_owned(),
};
if request_to_display != Request::Exit {
tracing::info!("Received request: {:#?}", request_to_display);
} else {
if request_to_display == Request::Exit {
tracing::debug!("Received request: {:#?}", request_to_display);
} else {
tracing::info!("Received request: {:#?}", request_to_display);
}
let response = match request {
@@ -194,22 +194,20 @@ async fn session_handler_with_db_connection(
}
Request::ListValidNamePrefixes => {
let mut result = Vec::with_capacity(unix_user.groups.len() + 1);
result.push(unix_user.username.to_owned());
result.push(unix_user.username.clone());
for group in get_user_filtered_groups(unix_user, group_denylist) {
result.push(group.to_owned());
result.push(group.clone());
}
Response::ListValidNamePrefixes(result)
}
Request::CompleteDatabaseName(partial_database_name) => {
// TODO: more correct validation here
if !partial_database_name
if partial_database_name
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
{
Response::CompleteDatabaseName(vec![])
} else {
let result = complete_database_name(
partial_database_name,
unix_user,
@@ -219,16 +217,16 @@ async fn session_handler_with_db_connection(
)
.await;
Response::CompleteDatabaseName(result)
} else {
Response::CompleteDatabaseName(vec![])
}
}
Request::CompleteUserName(partial_user_name) => {
// TODO: more correct validation here
if !partial_user_name
if partial_user_name
.chars()
.all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
{
Response::CompleteUserName(vec![])
} else {
let result = complete_user_name(
partial_user_name,
unix_user,
@@ -238,6 +236,8 @@ async fn session_handler_with_db_connection(
)
.await;
Response::CompleteUserName(result)
} else {
Response::CompleteUserName(vec![])
}
}
Request::CreateDatabases(databases_names) => {
@@ -262,8 +262,8 @@ async fn session_handler_with_db_connection(
.await;
Response::DropDatabases(result)
}
Request::ListDatabases(database_names) => match database_names {
Some(database_names) => {
Request::ListDatabases(database_names) => {
if let Some(database_names) = database_names {
let result = list_databases(
database_names,
unix_user,
@@ -273,8 +273,7 @@ async fn session_handler_with_db_connection(
)
.await;
Response::ListDatabases(result)
}
None => {
} else {
let result = list_all_databases_for_user(
unix_user,
db_connection,
@@ -284,9 +283,9 @@ async fn session_handler_with_db_connection(
.await;
Response::ListAllDatabases(result)
}
},
Request::ListPrivileges(database_names) => match database_names {
Some(database_names) => {
}
Request::ListPrivileges(database_names) => {
if let Some(database_names) = database_names {
let privilege_data = get_databases_privilege_data(
database_names,
unix_user,
@@ -296,8 +295,7 @@ async fn session_handler_with_db_connection(
)
.await;
Response::ListPrivileges(privilege_data)
}
None => {
} else {
let privilege_data = get_all_database_privileges(
unix_user,
db_connection,
@@ -307,7 +305,7 @@ async fn session_handler_with_db_connection(
.await;
Response::ListAllPrivileges(privilege_data)
}
},
}
Request::ModifyPrivileges(database_privilege_diffs) => {
let result = apply_privilege_diffs(
BTreeSet::from_iter(database_privilege_diffs),
@@ -353,8 +351,8 @@ async fn session_handler_with_db_connection(
.await;
Response::SetUserPassword(result)
}
Request::ListUsers(db_users) => match db_users {
Some(db_users) => {
Request::ListUsers(db_users) => {
if let Some(db_users) = db_users {
let result = list_database_users(
db_users,
unix_user,
@@ -364,8 +362,7 @@ async fn session_handler_with_db_connection(
)
.await;
Response::ListUsers(result)
}
None => {
} else {
let result = list_all_database_users_for_unix_user(
unix_user,
db_connection,
@@ -375,7 +372,7 @@ async fn session_handler_with_db_connection(
.await;
Response::ListAllUsers(result)
}
},
}
Request::LockUsers(db_users) => {
let result = lock_database_users(
db_users,

View File

@@ -3,11 +3,13 @@ pub mod database_privilege_operations;
pub mod user_operations;
#[inline]
#[must_use]
pub fn quote_literal(s: &str) -> String {
format!("'{}'", s.replace('\'', r"\'"))
}
#[inline]
#[must_use]
pub fn quote_identifier(s: &str) -> String {
format!("`{}`", s.replace('`', r"\`"))
}

View File

@@ -53,16 +53,16 @@ pub async fn complete_database_name(
group_denylist: &GroupDenylist,
) -> CompleteDatabaseNameResponse {
let result = sqlx::query(
r#"
r"
SELECT CAST(`SCHEMA_NAME` AS CHAR(64)) AS `database`
FROM `information_schema`.`SCHEMATA`
WHERE `SCHEMA_NAME` NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys')
AND `SCHEMA_NAME` REGEXP ?
AND `SCHEMA_NAME` LIKE ?
"#,
",
)
.bind(create_user_group_matching_regex(unix_user, group_denylist))
.bind(format!("{}%", database_prefix))
.bind(format!("{database_prefix}%"))
.fetch_all(connection)
.await;
@@ -103,21 +103,21 @@ pub async fn create_databases(
)
.map_err(CreateDatabaseError::ValidationError)
{
results.insert(database_name.to_owned(), Err(err));
results.insert(database_name.clone(), Err(err));
continue;
}
match unsafe_database_exists(&database_name, &mut *connection).await {
Ok(true) => {
results.insert(
database_name.to_owned(),
database_name.clone(),
Err(CreateDatabaseError::DatabaseAlreadyExists),
);
continue;
}
Err(err) => {
results.insert(
database_name.to_owned(),
database_name.clone(),
Err(CreateDatabaseError::MySqlError(err.to_string())),
);
continue;
@@ -159,21 +159,21 @@ pub async fn drop_databases(
)
.map_err(DropDatabaseError::ValidationError)
{
results.insert(database_name.to_owned(), Err(err));
results.insert(database_name.clone(), Err(err));
continue;
}
match unsafe_database_exists(&database_name, &mut *connection).await {
Ok(false) => {
results.insert(
database_name.to_owned(),
database_name.clone(),
Err(DropDatabaseError::DatabaseDoesNotExist),
);
continue;
}
Err(err) => {
results.insert(
database_name.to_owned(),
database_name.clone(),
Err(DropDatabaseError::MySqlError(err.to_string())),
);
continue;
@@ -218,7 +218,7 @@ impl FromRow<'_, sqlx::mysql::MySqlRow> for DatabaseRow {
if s.is_empty() {
None
} else {
Some(s.split(',').map(|s| s.to_owned()).collect())
Some(s.split(',').map(std::borrow::ToOwned::to_owned).collect())
}
})
.unwrap_or_default()
@@ -258,12 +258,12 @@ pub async fn list_databases(
)
.map_err(ListDatabasesError::ValidationError)
{
results.insert(database_name.to_owned(), Err(err));
results.insert(database_name.clone(), Err(err));
continue;
}
let result = sqlx::query_as::<_, DatabaseRow>(
r#"
r"
SELECT
CAST(`information_schema`.`SCHEMATA`.`SCHEMA_NAME` AS CHAR(64)) AS `database`,
GROUP_CONCAT(DISTINCT CAST(`information_schema`.`TABLES`.`TABLE_NAME` AS CHAR(64)) SEPARATOR ',') AS `tables`,
@@ -281,7 +281,7 @@ pub async fn list_databases(
ON `information_schema`.`SCHEMATA`.`SCHEMA_NAME` = `mysql`.`db`.`DB`
WHERE `information_schema`.`SCHEMATA`.`SCHEMA_NAME` = ?
GROUP BY `information_schema`.`SCHEMATA`.`SCHEMA_NAME`
"#,
",
)
.bind(database_name.to_string())
@@ -289,9 +289,7 @@ pub async fn list_databases(
.await
.map_err(|err| ListDatabasesError::MySqlError(err.to_string()))
.and_then(|database| {
database
.map(Ok)
.unwrap_or_else(|| Err(ListDatabasesError::DatabaseDoesNotExist))
database.map_or_else(|| Err(ListDatabasesError::DatabaseDoesNotExist), Ok)
});
if let Err(err) = &result {
@@ -313,7 +311,7 @@ pub async fn list_all_databases_for_user(
group_denylist: &GroupDenylist,
) -> ListAllDatabasesResponse {
let result = sqlx::query_as::<_, DatabaseRow>(
r#"
r"
SELECT
CAST(`information_schema`.`SCHEMATA`.`SCHEMA_NAME` AS CHAR(64)) AS `database`,
GROUP_CONCAT(DISTINCT CAST(`information_schema`.`TABLES`.`TABLE_NAME` AS CHAR(64)) SEPARATOR ',') AS `tables`,
@@ -332,7 +330,7 @@ pub async fn list_all_databases_for_user(
WHERE `information_schema`.`SCHEMATA`.`SCHEMA_NAME` NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys')
AND `information_schema`.`SCHEMATA`.`SCHEMA_NAME` REGEXP ?
GROUP BY `information_schema`.`SCHEMATA`.`SCHEMA_NAME`
"#,
",
)
.bind(create_user_group_matching_regex(unix_user, group_denylist))
.fetch_all(connection)

View File

@@ -50,12 +50,11 @@ use crate::{
fn get_mysql_row_priv_field(row: &MySqlRow, position: usize) -> Result<bool, sqlx::Error> {
let field = DATABASE_PRIVILEGE_FIELDS[position];
let value = row.try_get(position)?;
match rev_yn(value) {
Some(val) => Ok(val),
_ => {
tracing::warn!(r#"Invalid value for privilege "{}": '{}'"#, field, value);
Ok(false)
}
if let Some(val) = rev_yn(value) {
Ok(val)
} else {
tracing::warn!(r#"Invalid value for privilege "{}": '{}'"#, field, value);
Ok(false)
}
}
@@ -147,7 +146,7 @@ pub async fn get_databases_privilege_data(
) -> ListPrivilegesResponse {
let mut results = BTreeMap::new();
for database_name in database_names.iter() {
for database_name in &database_names {
if let Err(err) = validate_db_or_user_request(
&DbOrUser::Database(database_name.clone()),
unix_user,
@@ -159,15 +158,22 @@ pub async fn get_databases_privilege_data(
continue;
}
if !unsafe_database_exists(database_name, connection)
.await
.unwrap()
{
results.insert(
database_name.to_owned(),
Err(ListPrivilegesError::DatabaseDoesNotExist),
);
continue;
match unsafe_database_exists(database_name, connection).await {
Ok(false) => {
results.insert(
database_name.to_owned(),
Err(ListPrivilegesError::DatabaseDoesNotExist),
);
continue;
}
Err(e) => {
results.insert(
database_name.to_owned(),
Err(ListPrivilegesError::MySqlError(e.to_string())),
);
continue;
}
Ok(true) => {}
}
let result = unsafe_get_database_privileges(database_name, connection)
@@ -185,13 +191,13 @@ pub async fn get_databases_privilege_data(
/// TODO: make this constant
fn get_all_db_privs_query() -> String {
format!(
indoc! {r#"
indoc! {r"
SELECT {} FROM `db` WHERE `db` IN
(SELECT DISTINCT CAST(`SCHEMA_NAME` AS CHAR(64)) AS `database`
FROM `information_schema`.`SCHEMATA`
WHERE `SCHEMA_NAME` NOT IN ('information_schema', 'performance_schema', 'mysql', 'sys')
AND `SCHEMA_NAME` REGEXP ?)
"#},
"},
DATABASE_PRIVILEGE_FIELDS
.iter()
.map(|field| quote_identifier(field))
@@ -234,25 +240,23 @@ async fn unsafe_apply_privilege_diff(
let question_marks =
std::iter::repeat_n("?", DATABASE_PRIVILEGE_FIELDS.len()).join(",");
sqlx::query(
format!("INSERT INTO `db` ({}) VALUES ({})", tables, question_marks).as_str(),
)
.bind(p.db.to_string())
.bind(p.user.to_string())
.bind(yn(p.select_priv))
.bind(yn(p.insert_priv))
.bind(yn(p.update_priv))
.bind(yn(p.delete_priv))
.bind(yn(p.create_priv))
.bind(yn(p.drop_priv))
.bind(yn(p.alter_priv))
.bind(yn(p.index_priv))
.bind(yn(p.create_tmp_table_priv))
.bind(yn(p.lock_tables_priv))
.bind(yn(p.references_priv))
.execute(connection)
.await
.map(|_| ())
sqlx::query(format!("INSERT INTO `db` ({tables}) VALUES ({question_marks})").as_str())
.bind(p.db.to_string())
.bind(p.user.to_string())
.bind(yn(p.select_priv))
.bind(yn(p.insert_priv))
.bind(yn(p.update_priv))
.bind(yn(p.delete_priv))
.bind(yn(p.create_priv))
.bind(yn(p.drop_priv))
.bind(yn(p.alter_priv))
.bind(yn(p.index_priv))
.bind(yn(p.create_tmp_table_priv))
.bind(yn(p.lock_tables_priv))
.bind(yn(p.references_priv))
.execute(connection)
.await
.map(|_| ())
}
DatabasePrivilegesDiff::Modified(p) => {
let changes = DATABASE_PRIVILEGE_FIELDS
@@ -274,25 +278,23 @@ async fn unsafe_apply_privilege_diff(
}
}
sqlx::query(
format!("UPDATE `db` SET {} WHERE `Db` = ? AND `User` = ?", changes).as_str(),
)
.bind(p.select_priv.map(change_to_yn))
.bind(p.insert_priv.map(change_to_yn))
.bind(p.update_priv.map(change_to_yn))
.bind(p.delete_priv.map(change_to_yn))
.bind(p.create_priv.map(change_to_yn))
.bind(p.drop_priv.map(change_to_yn))
.bind(p.alter_priv.map(change_to_yn))
.bind(p.index_priv.map(change_to_yn))
.bind(p.create_tmp_table_priv.map(change_to_yn))
.bind(p.lock_tables_priv.map(change_to_yn))
.bind(p.references_priv.map(change_to_yn))
.bind(p.db.to_string())
.bind(p.user.to_string())
.execute(connection)
.await
.map(|_| ())
sqlx::query(format!("UPDATE `db` SET {changes} WHERE `Db` = ? AND `User` = ?").as_str())
.bind(p.select_priv.map(change_to_yn))
.bind(p.insert_priv.map(change_to_yn))
.bind(p.update_priv.map(change_to_yn))
.bind(p.delete_priv.map(change_to_yn))
.bind(p.create_priv.map(change_to_yn))
.bind(p.drop_priv.map(change_to_yn))
.bind(p.alter_priv.map(change_to_yn))
.bind(p.index_priv.map(change_to_yn))
.bind(p.create_tmp_table_priv.map(change_to_yn))
.bind(p.lock_tables_priv.map(change_to_yn))
.bind(p.references_priv.map(change_to_yn))
.bind(p.db.to_string())
.bind(p.user.to_string())
.execute(connection)
.await
.map(|_| ())
}
DatabasePrivilegesDiff::Deleted(p) => {
sqlx::query("DELETE FROM `db` WHERE `Db` = ? AND `User` = ?")
@@ -433,23 +435,37 @@ pub async fn apply_privilege_diffs(
continue;
}
if !unsafe_database_exists(diff.get_database_name(), connection)
.await
.unwrap()
{
results.insert(
key,
Err(ModifyDatabasePrivilegesError::DatabaseDoesNotExist),
);
continue;
match unsafe_database_exists(diff.get_database_name(), connection).await {
Ok(false) => {
results.insert(
key,
Err(ModifyDatabasePrivilegesError::DatabaseDoesNotExist),
);
continue;
}
Err(e) => {
results.insert(
key,
Err(ModifyDatabasePrivilegesError::MySqlError(e.to_string())),
);
continue;
}
Ok(true) => {}
}
if !unsafe_user_exists(diff.get_user_name(), connection)
.await
.unwrap()
{
results.insert(key, Err(ModifyDatabasePrivilegesError::UserDoesNotExist));
continue;
match unsafe_user_exists(diff.get_user_name(), connection).await {
Ok(false) => {
results.insert(key, Err(ModifyDatabasePrivilegesError::UserDoesNotExist));
continue;
}
Err(e) => {
results.insert(
key,
Err(ModifyDatabasePrivilegesError::MySqlError(e.to_string())),
);
continue;
}
Ok(true) => {}
}
if let Err(err) = validate_diff(&diff, connection).await {

View File

@@ -34,13 +34,13 @@ pub(super) async fn unsafe_user_exists(
connection: &mut MySqlConnection,
) -> Result<bool, sqlx::Error> {
let result = sqlx::query(
r#"
r"
SELECT EXISTS(
SELECT 1
FROM `mysql`.`user`
WHERE `User` = ?
)
"#,
",
)
.bind(db_user)
.fetch_one(connection)
@@ -62,15 +62,15 @@ pub async fn complete_user_name(
group_denylist: &GroupDenylist,
) -> Vec<MySQLUser> {
let result = sqlx::query(
r#"
r"
SELECT `User` AS `user`
FROM `mysql`.`user`
WHERE `User` REGEXP ?
AND `User` LIKE ?
"#,
",
)
.bind(create_user_group_matching_regex(unix_user, group_denylist))
.bind(format!("{}%", user_prefix))
.bind(format!("{user_prefix}%"))
.fetch_all(connection)
.await;
@@ -236,12 +236,12 @@ const DATABASE_USER_LOCK_STATUS_QUERY_MARIADB: &str = r#"
AND `Host` = '%'
"#;
const DATABASE_USER_LOCK_STATUS_QUERY_MYSQL: &str = r#"
const DATABASE_USER_LOCK_STATUS_QUERY_MYSQL: &str = r"
SELECT `mysql`.`user`.`account_locked` = 'Y'
FROM `mysql`.`user`
WHERE `User` = ?
AND `Host` = '%'
"#;
";
// NOTE: this function is unsafe because it does no input validation.
async fn database_user_is_locked_unsafe(
@@ -430,14 +430,14 @@ JOIN `global_priv` ON
AND `user`.`Host` = `global_priv`.`Host`
"#;
const DB_USER_SELECT_STATEMENT_MYSQL: &str = r#"
const DB_USER_SELECT_STATEMENT_MYSQL: &str = r"
SELECT
`user`.`User`,
`user`.`Host`,
`user`.`authentication_string` != '' AS `has_password`,
`user`.`account_locked` = 'Y' AS `account_locked`
FROM `user`
"#;
";
pub async fn list_database_users(
db_users: Vec<MySQLUser>,
@@ -472,8 +472,10 @@ pub async fn list_database_users(
tracing::error!("Failed to list database user '{}': {:?}", &db_user, err);
}
if let Ok(Some(user)) = result.as_mut() {
append_databases_where_user_has_privileges(user, &mut *connection).await;
if let Ok(Some(user)) = result.as_mut()
&& let Err(err) = set_databases_where_user_has_privileges(user, &mut *connection).await
{
result = Err(err);
}
match result {
@@ -510,27 +512,33 @@ pub async fn list_all_database_users_for_unix_user(
if let Ok(users) = result.as_mut() {
for user in users {
append_databases_where_user_has_privileges(user, &mut *connection).await;
if let Err(mysql_error) =
set_databases_where_user_has_privileges(user, &mut *connection).await
{
return Err(ListAllUsersError::MySqlError(mysql_error.to_string()));
}
}
}
result
}
pub async fn append_databases_where_user_has_privileges(
/// This function sets the `databases` field of the given `DatabaseUser`
/// where the user has any privileges.
pub async fn set_databases_where_user_has_privileges(
db_user: &mut DatabaseUser,
connection: &mut MySqlConnection,
) {
) -> Result<(), sqlx::Error> {
let database_list = sqlx::query(
formatdoc!(
r#"
r"
SELECT `Db` AS `database`
FROM `db`
WHERE `User` = ? AND ({})
"#,
",
DATABASE_PRIVILEGE_FIELDS
.iter()
.map(|field| format!("`{}` = 'Y'", field))
.map(|field| format!("`{field}` = 'Y'"))
.join(" OR "),
)
.as_str(),
@@ -547,11 +555,11 @@ pub async fn append_databases_where_user_has_privileges(
);
}
db_user.databases = database_list
.map(|rows| {
rows.into_iter()
.map(|row| try_get_with_binary_fallback(&row, "database").unwrap())
.collect()
})
.unwrap_or_default();
db_user.databases = database_list.and_then(|rows| {
rows.into_iter()
.map(|row| try_get_with_binary_fallback(&row, "database"))
.collect::<Result<Vec<String>, sqlx::Error>>()
})?;
Ok(())
}

View File

@@ -71,21 +71,19 @@ impl Supervisor {
let config = ServerConfig::read_config_from_path(&config_path)
.context("Failed to read server configuration")?;
let group_deny_list = match &config.authorization.group_denylist_file {
Some(denylist_path) => {
let denylist = read_and_parse_group_denylist(denylist_path)
.context("Failed to read group denylist file")?;
tracing::debug!(
"Loaded group denylist with {} entries from {:?}",
denylist.len(),
denylist_path
);
Arc::new(RwLock::new(denylist))
}
None => {
tracing::debug!("No group denylist file specified, proceeding without a denylist");
Arc::new(RwLock::new(GroupDenylist::new()))
}
let group_deny_list = if let Some(denylist_path) = &config.authorization.group_denylist_file
{
let denylist = read_and_parse_group_denylist(denylist_path)
.context("Failed to read group denylist file")?;
tracing::debug!(
"Loaded group denylist with {} entries from {:?}",
denylist.len(),
denylist_path
);
Arc::new(RwLock::new(denylist))
} else {
tracing::debug!("No group denylist file specified, proceeding without a denylist");
Arc::new(RwLock::new(GroupDenylist::new()))
};
let mut watchdog_duration = None;
@@ -93,12 +91,13 @@ impl Supervisor {
#[cfg(target_os = "linux")]
let watchdog_task =
if systemd_mode && sd_notify::watchdog_enabled(true, &mut watchdog_micro_seconds) {
watchdog_duration = Some(Duration::from_micros(watchdog_micro_seconds));
let watchdog_duration_ = Duration::from_micros(watchdog_micro_seconds);
tracing::debug!(
"Systemd watchdog enabled with {} millisecond interval",
watchdog_micro_seconds.div_ceil(1000),
);
Some(spawn_watchdog_task(watchdog_duration.unwrap()))
watchdog_duration = Some(watchdog_duration_);
Some(spawn_watchdog_task(watchdog_duration_))
} else {
tracing::debug!("Systemd watchdog not enabled, skipping watchdog thread");
None
@@ -221,22 +220,20 @@ impl Supervisor {
let mut config = self.config.clone().lock_owned().await;
*config = new_config;
let group_deny_list = match &config.authorization.group_denylist_file {
Some(denylist_path) => {
let denylist = read_and_parse_group_denylist(denylist_path)
.context("Failed to read group denylist file")?;
let group_deny_list = if let Some(denylist_path) = &config.authorization.group_denylist_file
{
let denylist = read_and_parse_group_denylist(denylist_path)
.context("Failed to read group denylist file")?;
tracing::debug!(
"Loaded group denylist with {} entries from {:?}",
denylist.len(),
denylist_path
);
denylist
}
None => {
tracing::debug!("No group denylist file specified, proceeding without a denylist");
GroupDenylist::new()
}
tracing::debug!(
"Loaded group denylist with {} entries from {:?}",
denylist.len(),
denylist_path
);
denylist
} else {
tracing::debug!("No group denylist file specified, proceeding without a denylist");
GroupDenylist::new()
};
let mut group_deny_list_lock = self.group_deny_list.write().await;
*group_deny_list_lock = group_deny_list;
@@ -387,7 +384,7 @@ impl Supervisor {
}
}
_ = self.shutdown_cancel_token.cancelled() => {
() = self.shutdown_cancel_token.cancelled() => {
tracing::info!("Shutting down server");
self.shutdown().await?;
break;
@@ -427,7 +424,7 @@ fn spawn_status_notifier_task(task_tracker: TaskTracker) -> JoinHandle<()> {
let count = task_tracker.len();
let message = if count > 0 {
format!("Handling {} connections", count)
format!("Handling {count} connections")
} else {
"Waiting for connections".to_string()
};
@@ -453,7 +450,7 @@ async fn create_unix_listener_with_socket_path(
tracing::info!("Listening on socket {:?}", socket_path);
match fs::remove_file(socket_path.as_path()) {
Ok(_) => {}
Ok(()) => {}
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {}
Err(e) => return Err(e.into()),
}
@@ -470,7 +467,7 @@ async fn create_unix_listener_with_systemd_socket() -> anyhow::Result<TokioUnixL
.next()
.context("No file descriptors received from systemd")?;
debug_assert!(fd == 3, "Unexpected file descriptor from systemd: {}", fd);
debug_assert!(fd == 3, "Unexpected file descriptor from systemd: {fd}");
tracing::debug!(
"Received file descriptor from systemd with id: '{}', assuming socket",