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

Merged
merged 2 commits into from
Feb 10, 2025

Conversation

tomasmatus
Copy link
Member

@tomasmatus tomasmatus commented Dec 16, 2024

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


Files now allow administrators to copy&paste files into directories owned by different users and select ownership of pasted files.

@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!

@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.

garrett
garrett previously requested changes Jan 8, 2025
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 5 times, most recently from 367e694 to 6633d7c Compare January 14, 2025 12:32
martinpitt
martinpitt previously approved these changes Jan 16, 2025
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!

Comment on lines 77 to 109
// also add current ownership if it is same for all files (shallow check)
const firstFile = clipboard.files[0];
const firstOwnerStr = `${firstFile.user}:${firstFile.group}`;
if (clipboard.files.every(file => file.user === firstFile.user && file.group === firstFile.group)) {
candidates.add(firstOwnerStr);
}
Copy link
Member

Choose a reason for hiding this comment

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

Hmm -- why the restriction to "same for all files"? It's harder to present in the UI (we can't give a definitive owner), but keeping the restrictions is especially useful if there are different owners -- i.e. you want to copy / move an entire hierarchy someplace else.

It shouldn't be too hard to add a ClipboardInfo.mixed_owners: boolean and showing that in the UI as "first owner (and others)" or so. Fine as follow-up material of course.

@martinpitt
Copy link
Member

@tomasmatus FYI, to fix the pixel tests, please push a rebase. (This has been on the pilot board for ages, but it's difficult)

@martinpitt
Copy link
Member

Thanks for #921! This needs a rebase now.

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! Next round. This gets close enough that @garrett can do the final UI review in parallel.

Allows administrator to paste files into directories owned
by a different user.
martinpitt
martinpitt previously approved these changes Feb 4, 2025
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.

Sorry for the bad useInit() advice in my previous round. There's a little cleanup, but it's harmless. Thanks for bearing with me -- this is non-trivial file handling with tons of corner cases, and it's genuinely hard.

Looks good to me now! @garrett can you please do the final design review?

Comment on lines +142 to +143
// @ts-expect-error superuser.js is not typed
useEvent(superuser, "changed");
Copy link
Member

Choose a reason for hiding this comment

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

I just realized that I misread that the previous time -- this modal is a short-lived thing, it's unlikely that the superuser status changes underneath it. However, modals don't actually block the superuser widget.

However, this is still a no-op -- with that, the modal gets re-rendered on superuser changes, but useInit() doesn't re-run. I'd say let's not make this overly complicated and just drop this useEvent().

@garrett
Copy link
Member

garrett commented Feb 4, 2025

This seems mostly fine to me. I did spot a few issues:

  1. It gives me the option to paste in a directory where I do not have access. It does result in an error, but it would be nice if it could catch it first, either by removing the option for pasting as a specific owner or by at least showing an error helper text when the option is selected.
  2. The dropdown styling has a regression (there's no padding to the left), but this is not related to the PR.

I think this is good to land as-is, and we should consider # 1 as a possible followup and look to our PF overrides for fixing # 2 again.

@garrett
Copy link
Member

garrett commented Feb 4, 2025

Oh, it looks like PF6 had yet another regression on form select again:

image
https://v5-archive.patternfly.org/components/forms/form-select

While custom selects are not balanced correctly (they have questionable design issues), they at least have some space in front:

image
https://v5-archive.patternfly.org/components/menus/select

Form selects are just wrong and inconsistent. Again.

Zoomed in comparison to make it more obvious; the top is form select, the bottom is custom select:

image

But this is irrelevant for this PR; it's not a blocker. It's something that should be addressed again in an overide to fix the left padding on form-select specifically, to be consistent with the custom select (and input, and other form related elements, etc.)

@jelly jelly dismissed garrett’s stale review February 7, 2025 13:16

The review comments are follow up or unrelated PF regressions.

@martinpitt
Copy link
Member

martinpitt commented Feb 7, 2025

It gives me the option to paste in a directory where I do not have access. It does result in an error, but it would be nice if it could catch it first

This is the whole raison d'être of this PR. It tries to do exactly that (with test -w and such), so if that is broken, this needs to be looked at. I retract my +1 until that happens. Thanks for spotting! @tomasmatus can you reproduce that? If not, @garrett do you have some more precise steps?

@martinpitt martinpitt dismissed their stale review February 7, 2025 13:21

see above

src/menu.tsx Outdated

try {
// check for write access to destination directory
await cockpit.spawn(["test", "-w", path]);
Copy link
Member

Choose a reason for hiding this comment

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

This gives an empty error dialog when it fails, because there is an empty Exception. So ideally this is moved to a separate try/catch or you make the catch else aware of that

Reproducer:

As limited user, copy a file from your home and paste it in /home or /

Copy link
Member

Choose a reason for hiding this comment

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

Thanks! so that's the part which we need to fix in this PR.

@jelly
Copy link
Member

jelly commented Feb 7, 2025

It gives me the option to paste in a directory where I do not have access. It does result in an error, but it would be nice if it could catch it first

This is the whole raison d'être of this PR. It tries to do exactly that (with test -w and such), so if that is broken, this needs to be looked at. I retract my +1 until that happens. Thanks for spotting! @tomasmatus can you reproduce that? If not, @garrett do you have some more precise steps?

I believe the step is:

  • Log in as limited user
  • Copy a file from your home dir
  • Paste it in /
  • The menu entry is not disabled

This was already the case before the PR. We discussed in standup to have the access bits available as fsinfo but that takes some time. Created cockpit-project/cockpit#21596 for discussion there.

@martinpitt
Copy link
Member

OK, so the error as non-admin user isn't a regression. Let's just fix the empty error message then.

@tomasmatus
Copy link
Member Author

I don't remember why I needed the test -w call. It might have been because I did both test -r for source files and test -w for destination directory where time-of-check vs time-of-use error was brought up. I feel like it's fine to have cp fail and then open the admin modal if it does and user has admin perms.

Comment on lines +148 to +149
if (window.debugging === "all" || window.debugging?.includes("files")) {
console.debug("files:", ...args);
Copy link
Contributor

Choose a reason for hiding this comment

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

These 2 added lines are not executed by any test.

Comment on lines +74 to +75
} 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 2 added lines are not executed by any test.


// add option to keep the same permissions on mixed permissions files
if (uniqueOwners.length > 1) {
const dots = uniqueOwners.length > 2 ? ", ..." : "";
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.

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.

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 for fixing this!

@tomasmatus tomasmatus merged commit 5497760 into cockpit-project:main Feb 10, 2025
28 checks passed
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.

6 participants