-
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
[full-ci] Prevent creation of empty files/folders for accounts having no available quota #40567
Conversation
Actually using |
💥 Acceptance tests pipeline apiFilesExt-mariadb10.2-php7.4 failed. The build has been cancelled. |
Double-check the type because the core/lib/private/legacy/helper.php Line 613 in c4f8cd1
It's probably better to handle the false case there, before the calculations.
|
From what I can see, this is rather because https://github.com/owncloud/core/blob/master/lib/private/Files/Storage/Local.php#L314 returns So converting it to |
The interface says it should return either an int or false, so if it's returning a float then, technically, it's a bug in the implementation. I don't know why the
The alternative would be to change the interface so it returns a float instead of an int, but we'll have to check that using a float is properly supported in all the places where this method is used. Seems a lot of work. |
I was actually wrong, the float (double) type seems rather to come from I've therefore added the conversion to int there, before returning the free space as limited by the quota. |
The problem might not be really in the wrapper but something inside. When the wrapper is created, the quota is gotten from core/lib/private/legacy/util.php Line 375 in e4c8e50
computerFileSize could be a float (the returning type hint of the computerFileSize method is also wrong because it can return float, int and false).
Note that the problem with the At this point, it might be easier to use |
Need to check what happens with the tests |
Wonder if this could have potential side-effects/edge-cases:
|
User home seems to be correctly created, I guess because it gets initialized at an early stage as to what we are checking now. However, this seems indeed to break the skeleton files creation as folders' structure gets correctly created but with empty files inside, which looks bad. I wonder however which use case would bite us here..I guess only in case the Admin creates DB user having 0 quota assigned or in case of newly created LDAP users where the default quota / quota attribute is set to 0. Both seem unlikely to happen. |
This would be okay as this is also the current behaviour. I was fearing that the exception might interrupt some process, but I guess it's fine if it is implemented in the DAV-Layer instead of in the Quota Wrapper. |
I think the "block" only happens when accessing through webdav because the check are placed in our dav connector. Access through other channels (view, nodes, storage, etc) would still allow to create folders. However, the file quota applies at stream level. Basically, when the skeleton files are copied, the folders are created because we aren't accessing through webdav, but the files can't be written due to the quota being applied in the stream. I assume this is an acceptable behavior. Note that apps could still create folders by themselves in the FS following the same mechanism that core is using. |
Changed it to return |
@jvillafanez do you maybe have an idea why https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/external-storage.feature#L89 is currently failing? AFAICT uploading to external storages when no quota is set should still work (and it still does with this PR), so not sure why the test expects now a 507 instead of a 201. |
I think it's because of the new check you've set for the file. |
This branch is 10 commits ahead, 100 commits behind owncloud:master. https://github.com/pako81/core/tree/prevent_empty_folders This is now a long way behind master - it would be good to rebase and get fresh CI results. I put |
https://drone.owncloud.com/owncloud/core/37767/41/13
https://drone.owncloud.com/owncloud/core/37767/90/13
I will adjust those tests so that they expect the new behavior... |
https://drone.owncloud.com/owncloud/core/37769/90/13
I need to look again at exactly what happens when a user with not enough quota uploads a file to a destination that is in an "external storage" (rather than in their own storage, or into a received share that is someone else's storage) |
Upload should succeed as "external storages" are not counted against user's quota. |
decouples test from implementation details
@jvillafanez would be fine like this? Apparently, we now have some acceptance tests related to the new chunking algorithm which are failing. |
Technically yes. We need to check if there is any side effect. Not sure if the failing tests are related to that change or not. |
https://drone.owncloud.com/owncloud/core/37947/41/13
The various failing test scenarios are when Alice starts a new chunking upload. Similar for https://drone.owncloud.com/owncloud/core/37947/88/13 and https://drone.owncloud.com/owncloud/core/37947/89/13 It looks like the code changes are now rejecting some chunked uploads with 405 "method not allowed" |
Debugged this a bit w @pako81. Somehow the server thinks that the chunking directory does already exist. But the folder seems not to be created in the storage. |
You'll probably need to ensure the mounted folder exists before returning the mount, the same way it's done with a custom |
We are back to the case where only the @jvillafanez we still have the issue that something seems to be not correct when returning the datadir mountpoint in ChunkLocationProvider.php in case |
\mkdir($cacheDir, 0770, true); | ||
} | ||
return [ | ||
new MountPoint(Local::class, $cacheDir, ['datadir' => $dataDir, $loader]) |
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.
new MountPoint(Local::class, $cacheDir, ['datadir' => $cacheDir, $loader])
It should be 'datadir' => $cacheDir
instead of 'datadir' => $dataDir
. I don't know if this is causing the error in the tests
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.
Yes, initially tried with 'datadir' => $cacheDir
as well - no difference. The test still fails locally for me with:
Scenario: Upload a file to external storage while quota is set on home storage # /home/core/tests/acceptance/features/apiMain/external-storage.feature:89
Given user "Alice" has been created with default attributes and small skeleton files # FeatureContext::userHasBeenCreatedWithDefaultAttributes()
And the quota of user "Alice" has been set to "1 B" # FeatureContext::theQuotaOfUserHasBeenSetTo()
When user "Alice" uploads file "filesForUpload/textfile.txt" to filenames based on "/local_storage/testquota.txt" with all mechanisms using the WebDAV API # FeatureContext::userUploadsAFileToWithAllMechanisms()
Then the HTTP status code of all upload responses should be "201" # FeatureContext::theHTTPStatusCodeOfAllUploadResponsesShouldBe()
Response did not return expected status code
Failed asserting that 507 matches expected 201.
And as "Alice" the files uploaded to "/local_storage/testquota.txt" with all mechanisms should exist # FeatureContext::filesUploadedToWithAllMechanismsShouldExist()
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.
Which is because we are still getting through
throw new SabreInsufficientStorage('Creation of empty directories is forbidden in case of no available quota'); |
The other, simplified, approach which had all tests passing was b8e3458, where ChunkLocationProvider.php was not touched.
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.
Isn't this because the class Home is extending the Local one
https://github.com/owncloud/core/blob/master/lib/private/Files/Storage/Home.php#L32
so basically there is no way to differentiate in this case and we always end up at not passing this check
if ($free == 0 && ($targetStorage->instanceOfStorage('\OCP\Files\IHomeStorage') === true)) { |
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.
I don't think it's like that. A local storage isn't a home storage.
It might be that we're pointing exactly at the root of the mount, so maybe the target storage is the home storage with a relative path of /user/files/uploads
instead of what we're expecting (local storage with relative path of ''
- basically the root of the mount)
Kudos, SonarCloud Quality Gate passed! |
@jvillafanez @phil-davis should we go ahead and merge this? |
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.
I assume it works, haven't tested it
I have again manually tested all the steps from the top post with the new code in place and did not observe any unexpected behaviour. |
Tests with desktop client 3.2.0 on Windows 10:
|
Description
Prevent creation of empty files/folders for accounts having no available quota
Related Issue
Motivation and Context
Until now it was possible for users having 0 quota or who already reached the limit of their assigned quota to still create empty files/folders, which generates confusion. The PR fixes this behaviour.
How Has This Been Tested?
Manually:
Test 1. :
admin
assign quota0 B
to useruser1
user1
over WebUI and try to create empty files or folders: an errorCould not create..
is returnedTest 2. :
user1
who has a valid quota assigned create a folderfor guests
and share it with full permissions with guest userguest@owncloud.com
admin
assign now quota0 B
to useruser1
guest@owncloud.com
, enter the folderfor guests
and try to create empty files or (sub)folders: an errorCould not create..
is returnedTest 3. :
user1
having i.e. 10MB quota assigned and already using 100% of the available spaceTest 4. :
admin
assign quota0 B
to useruser1
user1
via desktop client to his personal storage: sync client returns a 403 Forbidden toMKCOL
andPUT
operations when trying to respectively create empty folders and files.Types of changes
Checklist: