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

fix: update re-share if shared-by user has been revoked #43025

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

luka-nextcloud
Copy link
Contributor

Summary

TODO

  • ...

Checklist

@luka-nextcloud
Copy link
Contributor Author

Another effected case by this issue:

  1. UserA share Folder1 to UserB
  2. UserB share Folder1 to UserC
  3. UserA revoke UserB
  4. UserA try to update sharing permission of UserC
    -> Error: Could not get proper share mount for . Failing since else the next calls are called with null

@luka-nextcloud luka-nextcloud force-pushed the bugfix/error-on-reshare-after-transfer-ownership branch 2 times, most recently from c298bf1 to 0828727 Compare February 5, 2024 18:28
@luka-nextcloud
Copy link
Contributor Author

@artonge I've updated as you requested, please check again.

Copy link
Contributor

@artonge artonge left a comment

Choose a reason for hiding this comment

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

Can you add comments to clarify what each if group does?

I am also wondering if we could find this shares with the following query:

SELECT
	f.fileid,
	f.path,
	f.storage,
	s.id as share_id,
	s.uid_owner as share_owner,
	s.uid_initiator as share_initiator,
	s.share_with as share_recipient
FROM
	oc_filecache f
	JOIN oc_share s ON f.fileid = s.file_source
	AND s.uid_initiator NOT IN (
		SELECT
			user_id
		FROM
			oc_mounts m
		WHERE
			f.storage = m.storage_id
	)

If so, then we could have a background job to remove them every hour or so like https://github.com/nextcloud/server/blob/master/apps/files_sharing/lib/DeleteOrphanedSharesJob.php, which might be easier than the current solution.

lib/private/Share20/Manager.php Outdated Show resolved Hide resolved
lib/private/Share20/Manager.php Show resolved Hide resolved
lib/private/Share20/Manager.php Outdated Show resolved Hide resolved
@luka-nextcloud
Copy link
Contributor Author

Can you add comments to clarify what each if group does?

I am also wondering if we could find this shares with the following query:

SELECT
	f.fileid,
	f.path,
	f.storage,
	s.id as share_id,
	s.uid_owner as share_owner,
	s.uid_initiator as share_initiator,
	s.share_with as share_recipient
FROM
	oc_filecache f
	JOIN oc_share s ON f.fileid = s.file_source
	AND s.uid_initiator NOT IN (
		SELECT
			user_id
		FROM
			oc_mounts m
		WHERE
			f.storage = m.storage_id
	)

If so, then we could have a background job to remove them every hour or so like https://github.com/nextcloud/server/blob/master/apps/files_sharing/lib/DeleteOrphanedSharesJob.php, which might be easier than the current solution.

@artonge It only works if the shared-by user refreshes his files list after his share has revoked. So, I don't think this query would do the job.

@luka-nextcloud luka-nextcloud force-pushed the bugfix/error-on-reshare-after-transfer-ownership branch 3 times, most recently from 007d650 to df7160f Compare April 1, 2024 08:13
@susnux susnux added this to the Nextcloud 30 milestone Apr 18, 2024
@luka-nextcloud luka-nextcloud force-pushed the bugfix/error-on-reshare-after-transfer-ownership branch from df7160f to 73fb85b Compare May 30, 2024 12:15
apps/files_sharing/lib/Command/FixBrokenShares.php Outdated Show resolved Hide resolved
apps/files_sharing/lib/Command/FixBrokenShares.php Outdated Show resolved Hide resolved
apps/files_sharing/lib/Command/FixBrokenShares.php Outdated Show resolved Hide resolved
apps/files_sharing/lib/OrphanHelper.php Outdated Show resolved Hide resolved
@skjnldsv skjnldsv removed their request for review June 3, 2024 08:07
@luka-nextcloud luka-nextcloud force-pushed the bugfix/error-on-reshare-after-transfer-ownership branch from 7e64905 to cf9b02a Compare June 4, 2024 18:39
apps/files_sharing/lib/OrphanHelper.php Outdated Show resolved Hide resolved
apps/files_sharing/lib/Command/FixBrokenShares.php Outdated Show resolved Hide resolved
lib/private/Share20/Manager.php Outdated Show resolved Hide resolved
@come-nc
Copy link
Contributor

come-nc commented Jun 10, 2024

Tests are failing

@luka-nextcloud luka-nextcloud force-pushed the bugfix/error-on-reshare-after-transfer-ownership branch 3 times, most recently from 323ffb4 to 0d42361 Compare June 17, 2024 08:23
Signed-off-by: Luka Trovic <luka@nextcloud.com>
@luka-nextcloud luka-nextcloud force-pushed the bugfix/error-on-reshare-after-transfer-ownership branch from 0d42361 to 032be69 Compare June 17, 2024 15:11
@luka-nextcloud
Copy link
Contributor Author

@come-nc Could you please review again? All checks have passed now.


public function __construct(
IDBConnection $connection,
IRootFolder $rootFolder
IRootFolder $rootFolder,
IUserMountCache $userMountCache
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
IUserMountCache $userMountCache
IUserMountCache $userMountCache,


foreach ($sharesInFolder as $shares) {
foreach ($shares as $child) {
$this->deleteShare($child);
Copy link
Contributor

Choose a reason for hiding this comment

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

For subfiles you did not check that the user still has access to it, I think?

Comment on lines 1129 to 1152
// If the user has another shares, we don't delete the shares by this user
if ($share->getShareType() === IShare::TYPE_USER) {
$groupShares = $this->getSharedWith($share->getSharedWith(), IShare::TYPE_GROUP, $node, -1, 0);

if (count($groupShares) !== 0) {
return;
}

// Check shares of parent folders
try {
$parentNode = $node->getParent();
while ($parentNode) {
$groupShares = $this->getSharedWith($share->getSharedWith(), IShare::TYPE_GROUP, $parentNode, -1, 0);
$userShares = $this->getSharedWith($share->getSharedWith(), IShare::TYPE_USER, $parentNode, -1, 0);

if (count($groupShares) !== 0 || count($userShares) !== 0) {
return;
}

$parentNode = $parentNode->getParent();
}
} catch (NotFoundException) {
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of doing all this to check if the user still has access to the file or not, does it not make more sense to directly check if the user has access to the file? We must have some tooling for that, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@come-nc I cannot find another way to check this logic. Could you provide some suggestions?

Copy link
Contributor

Choose a reason for hiding this comment

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

Get the user folder of the user and use getFirstNodeById would work I think.

Copy link
Contributor

Choose a reason for hiding this comment

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

(Note that this would only work after deleting the share)

Signed-off-by: Luka Trovic <luka@nextcloud.com>
@come-nc
Copy link
Contributor

come-nc commented Jun 24, 2024

@luka-nextcloud After talking with Robin, actually the ownership transfer is supposed to update the owner of the share so there should be no problem in the first place?

@luka-nextcloud
Copy link
Contributor Author

@come-nc Does it mean that these changes are enough for this issue?

image

image

@come-nc
Copy link
Contributor

come-nc commented Jun 25, 2024

@come-nc Does it mean that these changes are enough for this issue?

image

image

No, the second diff looks like it will cause trouble by arbitrary changing sharedBy of shares.

I lost track of what you are trying to fix, can you explain how to reproduce your problem? Why do you remove the exception handling removing invalid shares in OwnershipTransferService?

@luka-nextcloud
Copy link
Contributor Author

@come-nc

  • Reproduce steps:
  1. UserA share Folder1 to UserB
  2. UserB share Folder1 to UserC
  3. UserA deleted sharing to UserB
  4. UserA transfer Folder1 to UserD
    -> UserC lost access to Folder1. When UserC open sharing tab of Folder1, the error message Error: Could not get proper share mount for . Failing since else the next calls are called with null returned.
  • Issue occurred because the sharing of UserB to UserC was not deleted or updated after UserA deleted sharing to UserB. Then, when UserA transfering Folder1 to UserD, that re-share record cannot be transferred because it throws GenericShareException error.

@come-nc
Copy link
Contributor

come-nc commented Jun 27, 2024

@come-nc

  • Reproduce steps:
  1. UserA share Folder1 to UserB
  2. UserB share Folder1 to UserC
  3. UserA deleted sharing to UserB
  4. UserA transfer Folder1 to UserD
    -> UserC lost access to Folder1. When UserC open sharing tab of Folder1, the error message Error: Could not get proper share mount for . Failing since else the next calls are called with null returned.
  • Issue occurred because the sharing of UserB to UserC was not deleted or updated after UserA deleted sharing to UserB. Then, when UserA transfering Folder1 to UserD, that re-share record cannot be transferred because it throws GenericShareException error.

UserC already loses access to Folder1 after step 3, right?
At that point the sharing tab shows no error?

@luka-nextcloud
Copy link
Contributor Author

@come-nc

UserC already loses access to Folder1 after step 3, right?

No, UserC didn't lose access to Folder1 after step3. This is the issue we are trying to fix.

At that point the sharing tab shows no error?

No error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3. to review Waiting for reviews bug
Projects
Status: 👀 In review
Development

Successfully merging this pull request may close these issues.

[Bug]: Sub folder shares were broken on ownership transfer
4 participants