tape: impl access permission for media content list
This commit is contained in:
		@ -4,7 +4,7 @@ use anyhow::{bail, format_err, Error};
 | 
				
			|||||||
use serde::{Serialize, Deserialize};
 | 
					use serde::{Serialize, Deserialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use proxmox::{
 | 
					use proxmox::{
 | 
				
			||||||
    api::{api, Router, SubdirMap},
 | 
					    api::{api, Router, SubdirMap, RpcEnvironment, Permission},
 | 
				
			||||||
    list_subdirs_api_method,
 | 
					    list_subdirs_api_method,
 | 
				
			||||||
    tools::Uuid,
 | 
					    tools::Uuid,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -12,8 +12,13 @@ use proxmox::{
 | 
				
			|||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    config::{
 | 
					    config::{
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
 | 
					        cached_user_info::CachedUserInfo,
 | 
				
			||||||
 | 
					        acl::{
 | 
				
			||||||
 | 
					            PRIV_TAPE_AUDIT,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    api2::types::{
 | 
					    api2::types::{
 | 
				
			||||||
 | 
					        Authid,
 | 
				
			||||||
        BACKUP_ID_SCHEMA,
 | 
					        BACKUP_ID_SCHEMA,
 | 
				
			||||||
        BACKUP_TYPE_SCHEMA,
 | 
					        BACKUP_TYPE_SCHEMA,
 | 
				
			||||||
        MEDIA_POOL_NAME_SCHEMA,
 | 
					        MEDIA_POOL_NAME_SCHEMA,
 | 
				
			||||||
@ -65,13 +70,20 @@ use crate::{
 | 
				
			|||||||
            type: MediaListEntry,
 | 
					            type: MediaListEntry,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    access: {
 | 
				
			||||||
 | 
					        description: "List of registered backup media filtered by Tape.Audit privileges on pool",
 | 
				
			||||||
 | 
					        permission: &Permission::Anybody,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
)]
 | 
					)]
 | 
				
			||||||
/// List pool media
 | 
					/// List pool media
 | 
				
			||||||
pub async fn list_media(
 | 
					pub async fn list_media(
 | 
				
			||||||
    pool: Option<String>,
 | 
					    pool: Option<String>,
 | 
				
			||||||
    update_status: bool,
 | 
					    update_status: bool,
 | 
				
			||||||
    update_status_changer: Option<String>,
 | 
					    update_status_changer: Option<String>,
 | 
				
			||||||
 | 
					    rpcenv: &mut dyn RpcEnvironment,
 | 
				
			||||||
) -> Result<Vec<MediaListEntry>, Error> {
 | 
					) -> Result<Vec<MediaListEntry>, Error> {
 | 
				
			||||||
 | 
					    let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
 | 
				
			||||||
 | 
					    let user_info = CachedUserInfo::new()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let (config, _digest) = config::media_pool::config()?;
 | 
					    let (config, _digest) = config::media_pool::config()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -102,6 +114,11 @@ pub async fn list_media(
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let privs = user_info.lookup_privs(&auth_id, &["tape", "pool", pool_name]);
 | 
				
			||||||
 | 
					        if (privs & PRIV_TAPE_AUDIT) == 0  {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let config: MediaPoolConfig = config.lookup("pool", pool_name)?;
 | 
					        let config: MediaPoolConfig = config.lookup("pool", pool_name)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let changer_name = None; // does not matter here
 | 
					        let changer_name = None; // does not matter here
 | 
				
			||||||
@ -150,30 +167,33 @@ pub async fn list_media(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let inventory = Inventory::load(status_path)?;
 | 
					    let inventory = Inventory::load(status_path)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if pool.is_none() {
 | 
					    let privs = user_info.lookup_privs(&auth_id, &["tape", "pool"]);
 | 
				
			||||||
 | 
					    if (privs & PRIV_TAPE_AUDIT) != 0  {
 | 
				
			||||||
 | 
					        if pool.is_none() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for media_id in inventory.list_unassigned_media() {
 | 
					            for media_id in inventory.list_unassigned_media() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let (mut status, location) = inventory.status_and_location(&media_id.label.uuid);
 | 
					                let (mut status, location) = inventory.status_and_location(&media_id.label.uuid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if status == MediaStatus::Unknown {
 | 
					                if status == MediaStatus::Unknown {
 | 
				
			||||||
                status = MediaStatus::Writable;
 | 
					                    status = MediaStatus::Writable;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                list.push(MediaListEntry {
 | 
				
			||||||
 | 
					                    uuid: media_id.label.uuid.clone(),
 | 
				
			||||||
 | 
					                    ctime: media_id.label.ctime,
 | 
				
			||||||
 | 
					                    label_text: media_id.label.label_text.to_string(),
 | 
				
			||||||
 | 
					                    location,
 | 
				
			||||||
 | 
					                    status,
 | 
				
			||||||
 | 
					                    catalog: true, // empty, so we do not need a catalog
 | 
				
			||||||
 | 
					                    expired: false,
 | 
				
			||||||
 | 
					                    media_set_uuid: None,
 | 
				
			||||||
 | 
					                    media_set_name: None,
 | 
				
			||||||
 | 
					                    media_set_ctime: None,
 | 
				
			||||||
 | 
					                    seq_nr: None,
 | 
				
			||||||
 | 
					                    pool: None,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            list.push(MediaListEntry {
 | 
					 | 
				
			||||||
                uuid: media_id.label.uuid.clone(),
 | 
					 | 
				
			||||||
                ctime: media_id.label.ctime,
 | 
					 | 
				
			||||||
                label_text: media_id.label.label_text.to_string(),
 | 
					 | 
				
			||||||
                location,
 | 
					 | 
				
			||||||
                status,
 | 
					 | 
				
			||||||
                catalog: true, // empty, so we do not need a catalog
 | 
					 | 
				
			||||||
                expired: false,
 | 
					 | 
				
			||||||
                media_set_uuid: None,
 | 
					 | 
				
			||||||
                media_set_name: None,
 | 
					 | 
				
			||||||
                media_set_ctime: None,
 | 
					 | 
				
			||||||
                seq_nr: None,
 | 
					 | 
				
			||||||
                pool: None,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -190,6 +210,11 @@ pub async fn list_media(
 | 
				
			|||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let privs = user_info.lookup_privs(&auth_id, &["tape", "pool", &media_set_label.pool]);
 | 
				
			||||||
 | 
					        if (privs & PRIV_TAPE_AUDIT) == 0  {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (_status, location) = inventory.status_and_location(uuid);
 | 
					        let (_status, location) = inventory.status_and_location(uuid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let media_set_name = inventory.generate_media_set_name(&media_set_label.uuid, None)?;
 | 
					        let media_set_name = inventory.generate_media_set_name(&media_set_label.uuid, None)?;
 | 
				
			||||||
@ -349,11 +374,18 @@ pub struct MediaContentListFilter {
 | 
				
			|||||||
            type: MediaContentEntry,
 | 
					            type: MediaContentEntry,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    access: {
 | 
				
			||||||
 | 
					        description: "List content filtered by Tape.Audit privilege on pool",
 | 
				
			||||||
 | 
					        permission: &Permission::Anybody,
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
)]
 | 
					)]
 | 
				
			||||||
/// List media content
 | 
					/// List media content
 | 
				
			||||||
pub fn list_content(
 | 
					pub fn list_content(
 | 
				
			||||||
    filter: MediaContentListFilter,
 | 
					    filter: MediaContentListFilter,
 | 
				
			||||||
 | 
					    rpcenv: &mut dyn RpcEnvironment,
 | 
				
			||||||
) -> Result<Vec<MediaContentEntry>, Error> {
 | 
					) -> Result<Vec<MediaContentEntry>, Error> {
 | 
				
			||||||
 | 
					    let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
 | 
				
			||||||
 | 
					    let user_info = CachedUserInfo::new()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let (config, _digest) = config::media_pool::config()?;
 | 
					    let (config, _digest) = config::media_pool::config()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -373,6 +405,11 @@ pub fn list_content(
 | 
				
			|||||||
            if &set.pool != pool { continue; }
 | 
					            if &set.pool != pool { continue; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let privs = user_info.lookup_privs(&auth_id, &["tape", "pool", &set.pool]);
 | 
				
			||||||
 | 
					        if (privs & PRIV_TAPE_AUDIT) == 0  {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if let Some(ref media_uuid) = filter.media {
 | 
					        if let Some(ref media_uuid) = filter.media {
 | 
				
			||||||
            if &media_id.label.uuid != media_uuid { continue; }
 | 
					            if &media_id.label.uuid != media_uuid { continue; }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user