a reader connection should not be allowed to read arbitrary chunks in the datastore, but only those that were previously registered by opening the corresponding index files. this mechanism is needed to allow unprivileged users (that don't have full READ permissions on the whole datastore) access to their own backups via a reader environment. Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
105 lines
2.5 KiB
Rust
105 lines
2.5 KiB
Rust
use std::sync::{Arc,RwLock};
|
|
use std::collections::HashSet;
|
|
|
|
use serde_json::{json, Value};
|
|
|
|
use proxmox::api::{RpcEnvironment, RpcEnvironmentType};
|
|
|
|
use crate::api2::types::Userid;
|
|
use crate::backup::*;
|
|
use crate::server::formatter::*;
|
|
use crate::server::WorkerTask;
|
|
|
|
//use proxmox::tools;
|
|
|
|
/// `RpcEnvironmet` implementation for backup reader service
|
|
#[derive(Clone)]
|
|
pub struct ReaderEnvironment {
|
|
env_type: RpcEnvironmentType,
|
|
result_attributes: Value,
|
|
user: Userid,
|
|
pub debug: bool,
|
|
pub formatter: &'static OutputFormatter,
|
|
pub worker: Arc<WorkerTask>,
|
|
pub datastore: Arc<DataStore>,
|
|
pub backup_dir: BackupDir,
|
|
allowed_chunks: Arc<RwLock<HashSet<[u8;32]>>>,
|
|
}
|
|
|
|
impl ReaderEnvironment {
|
|
pub fn new(
|
|
env_type: RpcEnvironmentType,
|
|
user: Userid,
|
|
worker: Arc<WorkerTask>,
|
|
datastore: Arc<DataStore>,
|
|
backup_dir: BackupDir,
|
|
) -> Self {
|
|
|
|
|
|
Self {
|
|
result_attributes: json!({}),
|
|
env_type,
|
|
user,
|
|
worker,
|
|
datastore,
|
|
debug: false,
|
|
formatter: &JSON_FORMATTER,
|
|
backup_dir,
|
|
allowed_chunks: Arc::new(RwLock::new(HashSet::new())),
|
|
}
|
|
}
|
|
|
|
pub fn log<S: AsRef<str>>(&self, msg: S) {
|
|
self.worker.log(msg);
|
|
}
|
|
|
|
pub fn debug<S: AsRef<str>>(&self, msg: S) {
|
|
if self.debug { self.worker.log(msg); }
|
|
}
|
|
|
|
|
|
pub fn register_chunk(&self, digest: [u8;32]) {
|
|
let mut allowed_chunks = self.allowed_chunks.write().unwrap();
|
|
allowed_chunks.insert(digest);
|
|
}
|
|
|
|
pub fn check_chunk_access(&self, digest: [u8;32]) -> bool {
|
|
self.allowed_chunks.read().unwrap().contains(&digest)
|
|
}
|
|
}
|
|
|
|
impl RpcEnvironment for ReaderEnvironment {
|
|
|
|
fn result_attrib_mut(&mut self) -> &mut Value {
|
|
&mut self.result_attributes
|
|
}
|
|
|
|
fn result_attrib(&self) -> &Value {
|
|
&self.result_attributes
|
|
}
|
|
|
|
fn env_type(&self) -> RpcEnvironmentType {
|
|
self.env_type
|
|
}
|
|
|
|
fn set_user(&mut self, _user: Option<String>) {
|
|
panic!("unable to change user");
|
|
}
|
|
|
|
fn get_user(&self) -> Option<String> {
|
|
Some(self.user.to_string())
|
|
}
|
|
}
|
|
|
|
impl AsRef<ReaderEnvironment> for dyn RpcEnvironment {
|
|
fn as_ref(&self) -> &ReaderEnvironment {
|
|
self.as_any().downcast_ref::<ReaderEnvironment>().unwrap()
|
|
}
|
|
}
|
|
|
|
impl AsRef<ReaderEnvironment> for Box<dyn RpcEnvironment> {
|
|
fn as_ref(&self) -> &ReaderEnvironment {
|
|
self.as_any().downcast_ref::<ReaderEnvironment>().unwrap()
|
|
}
|
|
}
|