Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support copy&pasting files with administrator privileges #880

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

tomasmatus
Copy link
Member

Allows administrator to paste files into directories owned by a different user.

@tomasmatus
Copy link
Member Author

tomasmatus commented Dec 16, 2024

Adjusted for design mockups from Garrett:

image

default selected value is the same as destination directory owner, other options include the current logged-in user, root, and if permissions matches on all files there also is an option to keep original permission (should it be different from any of the three mentioned earlier)

image

Copy link
Member

@martinpitt martinpitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I had an initial look for things which are independent of the visual design.

Wrt. that, I still don't understand why uploading and pasting look so dramatically different -- IMHO either both should use an Alert or a Modal. It's not clear to me how #551 handled that, but it surely must have the same problem of dropping a dragged file into a non-user directory? But that's primarily @garrett 's decision.

Thanks!

src/dialogs/copyPasteOwnership.tsx Outdated Show resolved Hide resolved
...clipboard.files.map(file => dstPath + file.name),
], { superuser: "try" });
} catch (err) {
const e = err as cockpit.BasicError;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error handling is a bit tricky here. It could theoretically happen that the cp works, but the chown fails (not very likely, but think of "target user is unknown or invalid"). Or that the cp fails but already copied half of the files. So similar to #845 this needs to do some cleanup here -- best to remove everything you may have copied already.

What pains me is that upload, drag and drop, and now here pasting essentially do the same things and all have the same issues. This really could use some factorization of the cp/chown/chmod bits which all three reuse.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added error handling for this but I'm not sure how I could test it. If you have an idea how to deterministically fail cp or chown I'm all ears as the code coverage doesn't look great on this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some ideas to make these commands fail:

  • For a cp, can you create a directory, remove write permissions and cp a file to it?
  • For chown, can you try to chown to a user that doesn't exist?

Comment on lines +85 to +127
if (selectedOwner === undefined) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that would be the code path if you aren't admin, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm seems like "make ts happy", the modal won't ever open when the user is not an admin. It will just show "permission denied" alert.

src/menu.tsx Show resolved Hide resolved
test/check-application Outdated Show resolved Hide resolved
@tomasmatus tomasmatus force-pushed the copy-paste-nonowned branch from 4cf4968 to 5323e45 Compare January 3, 2025 11:05
@garrett
Copy link
Member

garrett commented Jan 8, 2025

Issues:

  1. Why is this a warning?
  2. There is no explanation why this is showing up.

I was thinking something like this:

image

"Files being pasted have a different owner. By default, ownership will be changed to match the destination directory."

Also: The dropdown should have the "username:username" -> "username" collapsing, like the user:group being the same does elsewhere, to be consistent.

Anyway, this is so that there's a explanation of what's going on, and that the default is almost always what is wanted, so someone can just click "Paste" to continue.

If the ownership matches between the files and destination, then we can skip this dialog, provided there's some kind of visual change to show that files have been pasted (which should happen after this too). Nautilus has the file(s) highlighted afterward, for example.

Copy link
Member

@garrett garrett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requested changes are above. (I really wish GitHub would fix their broken UI and allow for reviews to take place without having to look at the code. Not every review needs to look at the code.)

@garrett
Copy link
Member

garrett commented Jan 8, 2025

Here's an updated set of mockups with the various states.

image

It shows the collapsing when user and group are the same and it shows that the original owner has a special note in the dropdown options. It still defaults to the directory being pasted into, but it also quickly allows someone to select the original owner without having to think about it.

@tomasmatus tomasmatus force-pushed the copy-paste-nonowned branch 4 times, most recently from 4e29ac6 to 367e694 Compare January 14, 2025 12:22
Map guarantees that Map.keys() are in the same order as they were
insterted.
Comment on lines +56 to +58
} catch (err) {
const e = err as cockpit.BasicError;
addAlert(e.message, AlertVariant.danger, `${new Date().getTime()}`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 3 added lines are not executed by any test.

Comment on lines +61 to +68
try {
await cockpit.spawn([
"rm",
"-rf",
...clipboard.files.map(file => dstPath + "/" + file.name)
], { superuser: "try" });
} catch (ex) {
console.warn(`Failed to clean up copied files in ${dstPath}`, ex);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 8 added lines are not executed by any test.

position="top"
title={_("Paste as owner")}
isOpen
onClose={() => dialogResult.resolve()}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test.

...clipboard.files.map(file => clipboard.path + file.name),
path
])
.catch(err => addAlert(err.message, AlertVariant.danger, `${new Date().getTime()}`));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test.

@@ -183,7 +197,7 @@ export function get_menu_items(
{
id: "copy-item",
title: _("Copy"),
onClick: () => setClipboard(selected.map(s => path + s.name)),
onClick: () => setClipboard({ path, files: selected }),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This added line is not executed by any test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants