fix: route forge_admin through hive-priv; auto-recover matrix passwords
forge_admin() spawned nixos-container run hive-forge directly from the
hive-core process. nixos-container run uses nsenter to enter the container
namespaces, which requires root. hive-core is unprivileged, so every call
failed with: nsenter: stat of /proc/<pid>/ns/user failed: Permission denied
Fix: add RunForgeAdmin { args } to PrivRequest. hive-priv (root) handles
it by spawning nixos-container run hive-forge -- runuser -u forgejo --
forgejo --work-path /var/lib/forgejo admin <args>. forge_admin() now calls
priv_client::run_forge_admin().
matrix: ensure_user_for hit M_USER_IN_USE then failed when the stored
password file was missing (state dirs wiped but homeserver kept accounts).
Previously required manual hivectl matrix reset-password <name>.
Fix: add auto_reset_password() — calls the admin API (PUT
/_synapse/admin/v2/users/@<name>:<server> with the hive admin token) to
set a new random password, then proceeds with login. Falls back to the
existing manual-recovery error if the admin token is unavailable.
Closes #1234
This commit is contained in:
parent
3830b13b03
commit
34bc4c0b06
5 changed files with 147 additions and 47 deletions
|
|
@ -95,44 +95,15 @@ pub async fn is_present() -> bool {
|
|||
/// forgejo user (the only uid with write access to the state dir).
|
||||
/// Returns stdout on success; bails with stderr context on failure.
|
||||
async fn forge_admin(args: &[&str]) -> Result<String> {
|
||||
let mut cmd = Command::new("nixos-container");
|
||||
// `runuser` (util-linux, always present in a NixOS container)
|
||||
// beats `sudo` here — sudo isn't installed unless `security.sudo`
|
||||
// is enabled, and we don't want to depend on that.
|
||||
//
|
||||
// `--work-path` is mandatory: without it, the admin CLI defaults
|
||||
// WorkPath to `dirname(executable)` (a RO nix-store path), then
|
||||
// looks for `<WorkPath>/custom/conf/app.ini` which doesn't
|
||||
// exist, falls back to defaults, and F3 init tries to mkdir
|
||||
// under the nix store and fatals. The systemd unit sets
|
||||
// WORK_PATH for the daemon; we mirror it here for the CLI.
|
||||
cmd.args([
|
||||
"run",
|
||||
FORGE_CONTAINER,
|
||||
"--",
|
||||
"runuser",
|
||||
"-u",
|
||||
"forgejo",
|
||||
"--",
|
||||
"forgejo",
|
||||
"--work-path",
|
||||
"/var/lib/forgejo",
|
||||
"admin",
|
||||
]);
|
||||
cmd.args(args);
|
||||
let out = cmd
|
||||
.output()
|
||||
.await
|
||||
.context("invoke nixos-container run hive-forge -- forgejo admin")?;
|
||||
if !out.status.success() {
|
||||
anyhow::bail!(
|
||||
"forgejo admin {} failed ({}): {}",
|
||||
args.join(" "),
|
||||
out.status,
|
||||
String::from_utf8_lossy(&out.stderr).trim(),
|
||||
);
|
||||
}
|
||||
Ok(String::from_utf8_lossy(&out.stdout).into_owned())
|
||||
// Route through hive-priv (root helper) because `nixos-container run`
|
||||
// uses nsenter to enter the container's namespaces, which requires root.
|
||||
// hive-c0re runs as the unprivileged `hive-core` user and cannot call
|
||||
// nsenter directly — doing so produces:
|
||||
// nsenter: stat of /proc/<pid>/ns/user failed: Permission denied
|
||||
let (stdout, _stderr) = crate::priv_client::run_forge_admin(args).await.with_context(
|
||||
|| format!("forgejo admin {} (via hive-priv)", args.join(" ")),
|
||||
)?;
|
||||
Ok(stdout)
|
||||
}
|
||||
|
||||
/// Pull the access token out of forgejo's success message. Format
|
||||
|
|
|
|||
Loading…
Reference in a new issue