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,
|
cached_user_info::CachedUserInfo,
|
||||||
acl::{
|
acl::{
|
||||||
PRIV_DATASTORE_BACKUP,
|
PRIV_DATASTORE_BACKUP,
|
||||||
|
PRIV_DATASTORE_MODIFY,
|
||||||
PRIV_TAPE_READ,
|
PRIV_TAPE_READ,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -105,6 +106,10 @@ pub const ROUTER: Router = Router::new()
|
||||||
type: Userid,
|
type: Userid,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
owner: {
|
||||||
|
type: Authid,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
returns: {
|
returns: {
|
||||||
|
@ -123,6 +128,7 @@ pub fn restore(
|
||||||
drive: String,
|
drive: String,
|
||||||
media_set: String,
|
media_set: String,
|
||||||
notify_user: Option<Userid>,
|
notify_user: Option<Userid>,
|
||||||
|
owner: Option<Authid>,
|
||||||
rpcenv: &mut dyn RpcEnvironment,
|
rpcenv: &mut dyn RpcEnvironment,
|
||||||
) -> Result<Value, Error> {
|
) -> Result<Value, Error> {
|
||||||
|
|
||||||
|
@ -134,6 +140,18 @@ pub fn restore(
|
||||||
bail!("no permissions on /datastore/{}", store);
|
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]);
|
let privs = user_info.lookup_privs(&auth_id, &["tape", "drive", &drive]);
|
||||||
if (privs & PRIV_TAPE_READ) == 0 {
|
if (privs & PRIV_TAPE_READ) == 0 {
|
||||||
bail!("no permissions on /tape/drive/{}", drive);
|
bail!("no permissions on /tape/drive/{}", drive);
|
||||||
|
@ -222,6 +240,7 @@ pub fn restore(
|
||||||
&datastore,
|
&datastore,
|
||||||
&auth_id,
|
&auth_id,
|
||||||
¬ify_user,
|
¬ify_user,
|
||||||
|
&owner,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,6 +271,7 @@ pub fn request_and_restore_media(
|
||||||
datastore: &DataStore,
|
datastore: &DataStore,
|
||||||
authid: &Authid,
|
authid: &Authid,
|
||||||
notify_user: &Option<Userid>,
|
notify_user: &Option<Userid>,
|
||||||
|
owner: &Option<Authid>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
|
||||||
let media_set_uuid = match media_id.media_set_label {
|
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
|
/// Restore complete media content and catalog
|
||||||
|
|
|
@ -27,6 +27,7 @@ use proxmox_backup::{
|
||||||
api2::{
|
api2::{
|
||||||
self,
|
self,
|
||||||
types::{
|
types::{
|
||||||
|
Authid,
|
||||||
DATASTORE_SCHEMA,
|
DATASTORE_SCHEMA,
|
||||||
DRIVE_NAME_SCHEMA,
|
DRIVE_NAME_SCHEMA,
|
||||||
MEDIA_LABEL_SCHEMA,
|
MEDIA_LABEL_SCHEMA,
|
||||||
|
@ -868,6 +869,10 @@ async fn backup(mut param: Value) -> Result<(), Error> {
|
||||||
type: Userid,
|
type: Userid,
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
owner: {
|
||||||
|
type: Authid,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
"output-format": {
|
"output-format": {
|
||||||
schema: OUTPUT_FORMAT,
|
schema: OUTPUT_FORMAT,
|
||||||
optional: true,
|
optional: true,
|
||||||
|
|
|
@ -51,5 +51,15 @@ Ext.define('PBS.TapeManagement.TapeRestoreWindow', {
|
||||||
skipEmptyText: true,
|
skipEmptyText: true,
|
||||||
renderer: Ext.String.htmlEncode,
|
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