-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Remove user from the storage setting or storage when user is deleted #30712
Conversation
lib/private/User/User.php
Outdated
@@ -227,6 +226,24 @@ public function delete() { | |||
// Delete the user's keys in preferences | |||
\OC::$server->getConfig()->deleteAllUserValues($this->getUID()); | |||
|
|||
//Delete external storage or remove user from applicableUsers list | |||
foreach (\OC::$server->getUserGlobalStoragesService()->getStorageForAllUsers() as $storageForAllUser) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did you try with getUserStoragesService()
instead ? this would be more direct and give you the whole list without the need to filter.
However one problem is that this service works with the user from the session, might need to refactor it in a way that allows creating/querying it for a given user.
lib/private/User/User.php
Outdated
if (in_array($this->getUID(), $applicableUsers, true)) { | ||
if (count($applicableUsers) === 1) { | ||
//As this storage is associated only with this user. | ||
\OC::$server->getGlobalStoragesService()->removeStorage($id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but actually you might be right, this removes storages created by an admin and applied only for a user, so maybe this approach is ok
I wonder if this logic could be put in a method of one of the services. But it seems the services don't know from each other yet. Does deleting a storage not work from the "UserGlobalStoragesService" ? |
Codecov Report
@@ Coverage Diff @@
## master #30712 +/- ##
============================================
+ Coverage 63.59% 63.72% +0.13%
- Complexity 18556 18563 +7
============================================
Files 1169 1169
Lines 69606 69631 +25
Branches 1264 1264
============================================
+ Hits 44267 44374 +107
+ Misses 24970 24888 -82
Partials 369 369
Continue to review full report at Codecov.
|
If we use "getUserGlobalStoragesService", then the problem happens when |
Yeah, Another approach would be to simply have two calls: one for the local storages, maybe It would also make it easier to write unit tests as you'd mostly write tests for these two methods. |
0743cee
to
f69b77c
Compare
lib/private/User/User.php
Outdated
@@ -227,6 +226,9 @@ public function delete() { | |||
// Delete the user's keys in preferences | |||
\OC::$server->getConfig()->deleteAllUserValues($this->getUID()); | |||
|
|||
//Delete external storage or remove user from applicableUsers list | |||
\OC::$server->getGlobalStoragesService()->deleteAllForUser($this->getUID()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't local storage gets deleted here. I mean https://github.com/owncloud/core/pull/30712/files#diff-3030ca4989f892c50dea24eaa3f1ae38R236
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, the home storage gets deleted later as part of user deletion
however home storage is untouched by the any of the storagesservice which only operate on external storage currently
f69b77c
to
cb58a3b
Compare
cb58a3b
to
d811617
Compare
@sharidas any update on this ? |
$storage = $this->makeStorageConfig($storageParams); | ||
$this->service->addStorage($storage); | ||
if (isset($storageParams['applicableUsers'])) { | ||
$this->assertTrue($this->service->deleteAllForUser($storageParams['applicableUsers'][0])); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please also verify that the "applicable" value was properly set after deleteAllForUser
and possibly other values. Checking for the return value is not enough to ensure the function is doing its job
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
d811617
to
e4edb74
Compare
*/ | ||
public function deleteAllForUser($userId) { | ||
$result = false; | ||
$mounts = $this->getStorageForAllUsers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here I'm wondering about scalability: if there are 10000 users and each have a mount, we're querying all possible mounts, even the personal mounts of irrelevant users
I wonder if we should split this in two parts:
- get all personal mounts of said user, then remove said storages
and - get all system mounts (no personal mounts) and then filter applicable users as you did below
@butonic does that make sense or is the current solution sufficient for real-life scenarios ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sharidas let's go with the proposed approach to play it safe. Here I'm assuming that we already have the necessary API calls to retrieve this info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two API's are found to get mounts for user:
getMountsForUser()
- https://github.com/owncloud/core/blob/master/lib/private/Files/Config/UserMountCache.php#L198 . When a regular user is mounted with SFTP storage, it shows the /user and SFTP storage folder as mount points.getMountsForUser()
- https://github.com/owncloud/core/blob/master/lib/private/Files/Config/MountProviderCollection.php#L74 . When tested a regular user with SFTP storage mounted, this shows only the SFTP folder.
Guess we can opt for the first one.
\array_shift($storageParams['applicableUsers']); | ||
$this->assertEquals([], \array_diff($storageParams['applicableUsers'], $finalApplicableUsers)); | ||
} else { | ||
$storages = \count($this->service->getAllStorages()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should also make sure that non-relevant storages were not deleted and are still present
for this, create a few unrelated storages and check for these
you could use the "store their id" technique after creation then requery them to see if they still exist and confirm that the correct ones are gone
0b9fd38
to
a228e95
Compare
* Deletes the external storages mounted to the user | ||
* @param $userId | ||
* @return bool | ||
* @since 10.0.8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
set to 10.0.10
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
lib/private/User/User.php
Outdated
// Delete all mount points for user | ||
\OC::$server->getUserStoragesService()->deleteAllMountsForUser($this); | ||
//Delete external storage or remove user from applicableUsers list | ||
\OC::$server->getGlobalStoragesService()->deleteAllForUser($this->getUID()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
be consistent: use either UID or user object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Prefer to use user object. Considering future usage.
4e584e1
to
7dd879f
Compare
I have created a new file in this PR, https://github.com/owncloud/core/pull/30712/files#diff-31407757e5ad52b7e7c4a81530bb4113. The reason why I created a new file is while playing with storageId, I found that |
86a229a
to
795a085
Compare
795a085
to
8e8ddf3
Compare
8e8ddf3
to
b50540a
Compare
@PVince81 review required. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, there's only one additional adjustment needed to avoid performance issue by reading too many configs that aren't needed
public function deleteAllForUser($user) { | ||
$userId = $user->getUID(); | ||
$result = false; | ||
$mounts = $this->getStorageForAllUsers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems this method returns not only admin mounts but also personal mounts as it uses DBConfigService::getAllMounts()
instead of getAdminMounts()
.
From reading the code further, it seems you'd need to call getAllStorages()
or getStorages()
which do call DBConfigService::getAdminMounts()
through StorageService::readConfig()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modified the PR, and updated the change to use getStorages()
https://github.com/owncloud/core/pull/30712/files#diff-16d6579da5930e07b8c14d76623559e8R197
Remove user from the storage if there are multiple users associated with the storage during deletion of the user. Else remove the storage when user is deleted, since the storage is only associated with the user being deleted. Signed-off-by: Sujith H <sharidasan@owncloud.com>
b50540a
to
3f576a5
Compare
@sharidas please backport |
@sharidas has this been backported? |
Remove user from the storage if there are multiple
users associated with the storage during deletion
of the user. Else remove the storage when user is
deleted, since the storage is only associated with
the user being deleted.
Signed-off-by: Sujith H sharidasan@owncloud.com
Description
Remove user from the external storage list when there are multiple users applicable users for the storage, during deletion of user. Else remove the storage as the user which is being deleted is the only storage associated with the user.
Related Issue
#30694
Motivation and Context
This change would help to clean up the external storage when a user is being deleted.
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Checklist: