-use anyhow::{format_err, Error};
+use anyhow::{bail, format_err, Error};
use serde_json::Value;
-use proxmox::api::{api, ApiMethod, Router, RpcEnvironment};
+use proxmox::api::{api, ApiMethod, Permission, Router, RpcEnvironment};
use proxmox::api::router::SubdirMap;
use proxmox::{list_subdirs_api_method, sortable};
use crate::api2::types::*;
use crate::api2::pull::do_sync_job;
+use crate::api2::config::sync::{check_sync_job_modify_access, check_sync_job_read_access};
+
+use crate::config::cached_user_info::CachedUserInfo;
use crate::config::sync::{self, SyncJobStatus, SyncJobConfig};
use crate::server::UPID;
use crate::server::jobstate::{Job, JobState};
type: Array,
items: { type: sync::SyncJobStatus },
},
+ access: {
+ description: "Limited to sync jobs where user has Datastore.Audit on target datastore, and Remote.Audit on source remote.",
+ permission: &Permission::Anybody,
+ },
)]
/// List all sync jobs
pub fn list_sync_jobs(
mut rpcenv: &mut dyn RpcEnvironment,
) -> Result<Vec<SyncJobStatus>, Error> {
+ let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
+ let user_info = CachedUserInfo::new()?;
+
let (config, digest) = sync::config()?;
let mut list: Vec<SyncJobStatus> = config
} else {
true
}
+ })
+ .filter(|job: &SyncJobStatus| {
+ let as_config: SyncJobConfig = job.clone().into();
+ check_sync_job_read_access(&user_info, &auth_id, &as_config)
}).collect();
for job in &mut list {
schema: JOB_ID_SCHEMA,
}
}
- }
+ },
+ access: {
+ description: "User needs Datastore.Backup on target datastore, and Remote.Read on source remote. Additionally, remove_vanished requires Datastore.Prune, and any owner other than the user themselves requires Datastore.Modify",
+ permission: &Permission::Anybody,
+ },
)]
/// Runs the sync jobs manually.
fn run_sync_job(
_info: &ApiMethod,
rpcenv: &mut dyn RpcEnvironment,
) -> Result<String, Error> {
+ let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
+ let user_info = CachedUserInfo::new()?;
let (config, _digest) = sync::config()?;
let sync_job: SyncJobConfig = config.lookup("sync", &id)?;
- let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
+ if !check_sync_job_modify_access(&user_info, &auth_id, &sync_job) {
+ bail!("permission check failed");
+ }
let job = Job::new("syncjob", &id)?;