split some logic out of KeyValueDatabase::load_or_create

This method did _a lot_ of things at the same time. In order to use
`KeyValueDatabase` for the migrate-db command, we need to be able to
open a db without attempting to apply all the migrations and without
spawning a bunch of unrelated background tasks.

The state after this refactor is still not great, but it's enough to do
a migration tool.
This commit is contained in:
Benjamin Lee 2024-09-08 16:31:51 -07:00 committed by Charles Hall
parent 059dfe54e3
commit 279c6472c5
No known key found for this signature in database
GPG key ID: 7B8E0645816E07CF
3 changed files with 127 additions and 103 deletions

View file

@ -23,19 +23,27 @@ use hyper_util::{
};
use reqwest::dns::{Addrs, Name, Resolve, Resolving};
use ruma::{
api::federation::discovery::ServerSigningKeys, serde::Base64, DeviceId,
MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomAliasId, OwnedRoomId,
OwnedServerName, OwnedUserId, RoomAliasId, RoomVersionId, ServerName,
UserId,
api::federation::discovery::ServerSigningKeys,
events::{
push_rules::PushRulesEventContent,
room::message::RoomMessageEventContent, GlobalAccountDataEvent,
GlobalAccountDataEventType,
},
push::Ruleset,
serde::Base64,
DeviceId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomAliasId,
OwnedRoomId, OwnedServerName, OwnedUserId, RoomAliasId, RoomVersionId,
ServerName, UserId,
};
use tokio::sync::{broadcast, Mutex, RwLock, Semaphore};
use tracing::{error, Instrument};
use tracing::{error, warn, Instrument};
use trust_dns_resolver::TokioAsyncResolver;
use crate::{
api::server_server::FedDest,
observability::FilterReloadHandles,
service::media::MediaFileKey,
services,
utils::on_demand_hashmap::{OnDemandHashMap, TokenSet},
Config, Error, Result,
};
@ -406,6 +414,66 @@ impl Service {
&self.config.emergency_password
}
/// If the emergency password option is set, attempts to set the emergency
/// password and push rules for the @grapevine account.
///
/// If an error occurs, it is logged.
pub(crate) fn set_emergency_access(&self) {
let inner = || -> Result<bool> {
let admin_bot = self.admin_bot_user_id.as_ref();
services().users.set_password(
admin_bot,
self.emergency_password().as_deref(),
)?;
let (ruleset, res) = match self.emergency_password() {
Some(_) => (Ruleset::server_default(admin_bot), Ok(true)),
None => (Ruleset::new(), Ok(false)),
};
services().account_data.update(
None,
admin_bot,
GlobalAccountDataEventType::PushRules.to_string().into(),
&serde_json::to_value(&GlobalAccountDataEvent {
content: PushRulesEventContent {
global: ruleset,
},
})
.expect("to json value always works"),
)?;
res
};
match inner() {
Ok(pwd_set) => {
if pwd_set {
warn!(
"The Grapevine account emergency password is set! \
Please unset it as soon as you finish admin account \
recovery!"
);
services().admin.send_message(
RoomMessageEventContent::text_plain(
"The Grapevine account emergency password is set! \
Please unset it as soon as you finish admin \
account recovery!",
),
);
}
}
Err(error) => {
error!(
%error,
"Could not set the configured emergency password for the \
Grapevine user",
);
}
};
}
pub(crate) fn supported_room_versions(&self) -> Vec<RoomVersionId> {
self.stable_room_versions.clone()
}