ui: tape/Restore: let the user choose an owner
so that the tape backup can be restored as any user, given the current logged in user has the correct permission. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
This commit is contained in:
parent
5a5ee0326e
commit
e36135031d
|
@ -40,6 +40,7 @@ use crate::{
|
|||
cached_user_info::CachedUserInfo,
|
||||
acl::{
|
||||
PRIV_DATASTORE_BACKUP,
|
||||
PRIV_DATASTORE_MODIFY,
|
||||
PRIV_TAPE_READ,
|
||||
},
|
||||
},
|
||||
|
@ -105,6 +106,10 @@ pub const ROUTER: Router = Router::new()
|
|||
type: Userid,
|
||||
optional: true,
|
||||
},
|
||||
owner: {
|
||||
type: Authid,
|
||||
optional: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
returns: {
|
||||
|
@ -123,6 +128,7 @@ pub fn restore(
|
|||
drive: String,
|
||||
media_set: String,
|
||||
notify_user: Option<Userid>,
|
||||
owner: Option<Authid>,
|
||||
rpcenv: &mut dyn RpcEnvironment,
|
||||
) -> Result<Value, Error> {
|
||||
|
||||
|
@ -134,6 +140,18 @@ pub fn restore(
|
|||
bail!("no permissions on /datastore/{}", store);
|
||||
}
|
||||
|
||||
if let Some(ref owner) = owner {
|
||||
let correct_owner = owner == &auth_id
|
||||
|| (owner.is_token()
|
||||
&& !auth_id.is_token()
|
||||
&& owner.user() == auth_id.user());
|
||||
|
||||
// same permission as changing ownership after syncing
|
||||
if !correct_owner && privs & PRIV_DATASTORE_MODIFY == 0 {
|
||||
bail!("no permission to restore as '{}'", owner);
|
||||
}
|
||||
}
|
||||
|
||||
let privs = user_info.lookup_privs(&auth_id, &["tape", "drive", &drive]);
|
||||
if (privs & PRIV_TAPE_READ) == 0 {
|
||||
bail!("no permissions on /tape/drive/{}", drive);
|
||||
|
@ -222,6 +240,7 @@ pub fn restore(
|
|||
&datastore,
|
||||
&auth_id,
|
||||
¬ify_user,
|
||||
&owner,
|
||||
)?;
|
||||
}
|
||||
|
||||
|
@ -252,6 +271,7 @@ pub fn request_and_restore_media(
|
|||
datastore: &DataStore,
|
||||
authid: &Authid,
|
||||
notify_user: &Option<Userid>,
|
||||
owner: &Option<Authid>,
|
||||
) -> Result<(), Error> {
|
||||
|
||||
let media_set_uuid = match media_id.media_set_label {
|
||||
|
@ -284,7 +304,9 @@ pub fn request_and_restore_media(
|
|||
}
|
||||
}
|
||||
|
||||
restore_media(worker, &mut drive, &info, Some((datastore, authid)), false)
|
||||
let restore_owner = owner.as_ref().unwrap_or(authid);
|
||||
|
||||
restore_media(worker, &mut drive, &info, Some((datastore, restore_owner)), false)
|
||||
}
|
||||
|
||||
/// Restore complete media content and catalog
|
||||
|
|
|
@ -27,6 +27,7 @@ use proxmox_backup::{
|
|||
api2::{
|
||||
self,
|
||||
types::{
|
||||
Authid,
|
||||
DATASTORE_SCHEMA,
|
||||
DRIVE_NAME_SCHEMA,
|
||||
MEDIA_LABEL_SCHEMA,
|
||||
|
@ -868,6 +869,10 @@ async fn backup(mut param: Value) -> Result<(), Error> {
|
|||
type: Userid,
|
||||
optional: true,
|
||||
},
|
||||
owner: {
|
||||
type: Authid,
|
||||
optional: true,
|
||||
},
|
||||
"output-format": {
|
||||
schema: OUTPUT_FORMAT,
|
||||
optional: true,
|
||||
|
|
|
@ -51,5 +51,15 @@ Ext.define('PBS.TapeManagement.TapeRestoreWindow', {
|
|||
skipEmptyText: true,
|
||||
renderer: Ext.String.htmlEncode,
|
||||
},
|
||||
{
|
||||
xtype: 'pbsUserSelector',
|
||||
name: 'owner',
|
||||
fieldLabel: gettext('Owner'),
|
||||
emptyText: gettext('Current User'),
|
||||
value: null,
|
||||
allowBlank: true,
|
||||
skipEmptyText: true,
|
||||
renderer: Ext.String.htmlEncode,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue