mirror of https://github.com/zulip/zulip.git
upload: Remove old per-user quota feature.
We'll replace this primarily with per-realm quotas (plus the simple per-file limit of settings.MAX_FILE_UPLOAD_SIZE, 25 MiB by default). We do want per-user quotas too, but they'll need some more management apparatus around them so an admin has a practical way to set them differently for different users. And the error handling in this existing code is rather confused. Just clear this feature out entirely for now; then we'll build the per-realm version more cleanly, and then we can later add back per-realm quotas modelled after that. The migration to actually remove the field is in a subsequent commit. Based in part on work by Vishnu Ks (hackerkid).
This commit is contained in:
parent
0fcf0c5052
commit
55cf54c087
|
@ -59,28 +59,17 @@ zrequire('upload');
|
|||
$("#compose-error-msg").text('');
|
||||
}
|
||||
|
||||
function assert_side_effects(msg, check_html=false) {
|
||||
function assert_side_effects(msg) {
|
||||
assert($("#compose-send-status").hasClass("alert-error"));
|
||||
assert(!$("#compose-send-status").hasClass("alert-info"));
|
||||
assert.equal($("#compose-send-button").prop("disabled"), false);
|
||||
if (check_html) {
|
||||
assert.equal($("#compose-error-msg").html(), msg);
|
||||
} else {
|
||||
assert.equal($("#compose-error-msg").text(), msg);
|
||||
}
|
||||
assert.equal($("#compose-error-msg").text(), msg);
|
||||
}
|
||||
|
||||
function test(err, file, msg) {
|
||||
setup_test();
|
||||
upload.uploadError(err, file);
|
||||
// The text function and html function in zjquery is not in sync
|
||||
// with each other. QuotaExceeded changes html while all other errors
|
||||
// changes body.
|
||||
if (err === 'QuotaExceeded') {
|
||||
assert_side_effects(msg, true);
|
||||
} else {
|
||||
assert_side_effects(msg);
|
||||
}
|
||||
assert_side_effects(msg);
|
||||
}
|
||||
|
||||
var msg_prefix = 'translated: ';
|
||||
|
@ -88,17 +77,13 @@ zrequire('upload');
|
|||
var msg_2 = 'Unable to upload that many files at once.';
|
||||
var msg_3 = '"foobar.txt" was too large; the maximum file size is 25MiB.';
|
||||
var msg_4 = 'Sorry, the file was too large.';
|
||||
var msg_5 = 'Upload would exceed your maximum quota. You can delete old attachments to ' +
|
||||
'free up space. <a href="#settings/uploaded-files">translated: Click here</a>';
|
||||
|
||||
var msg_6 = 'An unknown error occurred.';
|
||||
var msg_5 = 'An unknown error occurred.';
|
||||
|
||||
test('BrowserNotSupported', {}, msg_prefix + msg_1);
|
||||
test('TooManyFiles', {}, msg_prefix + msg_2);
|
||||
test('FileTooLarge', {name: 'foobar.txt'}, msg_prefix + msg_3);
|
||||
test('REQUEST ENTITY TOO LARGE', {}, msg_prefix + msg_4);
|
||||
test('QuotaExceeded', {}, msg_prefix + msg_5);
|
||||
test('Do-not-match-any-case', {}, msg_prefix + msg_6);
|
||||
test('Do-not-match-any-case', {}, msg_prefix + msg_5);
|
||||
}());
|
||||
|
||||
(function test_upload_finish() {
|
||||
|
|
|
@ -104,8 +104,6 @@ function _setup_page() {
|
|||
zuliprc: 'zuliprc',
|
||||
flaskbotrc: 'flaskbotrc',
|
||||
timezones: moment.tz.names(),
|
||||
upload_quota: attachments_ui.bytes_to_size(page_params.upload_quota),
|
||||
total_uploads_size: attachments_ui.bytes_to_size(page_params.total_uploads_size),
|
||||
});
|
||||
|
||||
$(".settings-box").html(settings_tab);
|
||||
|
|
|
@ -57,12 +57,6 @@ exports.uploadError = function (err, file) {
|
|||
case 'REQUEST ENTITY TOO LARGE':
|
||||
msg = i18n.t("Sorry, the file was too large.");
|
||||
break;
|
||||
case 'QuotaExceeded':
|
||||
var translation_part1 = i18n.t('Upload would exceed your maximum quota. You can delete old attachments to free up space.');
|
||||
var translation_part2 = i18n.t('Click here');
|
||||
msg = translation_part1 + ' <a href="#settings/uploaded-files">' + translation_part2 + '</a>';
|
||||
$("#compose-error-msg").html(msg);
|
||||
return;
|
||||
default:
|
||||
msg = i18n.t("An unknown error occurred.");
|
||||
break;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<div id="attachments-settings" class="settings-section" data-name="uploaded-files">
|
||||
<div class='tip'>{{#tr this}}You are currently using __total_uploads_size__ of __upload_quota__ upload space.{{/tr}}</div>
|
||||
<input id="upload_file_search" class="search" type="text" placeholder="{{t 'Search uploads...' }}" aria-label="{{t 'Search uploads...' }}"/>
|
||||
<div class="clear-float"></div>
|
||||
<div class="alert" id="delete-upload-status"></div>
|
||||
|
|
|
@ -362,12 +362,7 @@
|
|||
|
||||
// Pass any errors to the error option
|
||||
if (xhr.status < 200 || xhr.status > 299) {
|
||||
if (this.responseText.includes("Upload would exceed your maximum quota.")) {
|
||||
var errorString = "QuotaExceeded";
|
||||
on_error(errorString, xhr.status);
|
||||
} else {
|
||||
on_error(xhr.statusText, xhr.status);
|
||||
}
|
||||
on_error(xhr.statusText, xhr.status);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ from zerver.lib.actions import (
|
|||
get_status_dict, streams_to_dicts_sorted,
|
||||
default_stream_groups_to_dicts_sorted
|
||||
)
|
||||
from zerver.lib.upload import get_total_uploads_size_for_user
|
||||
from zerver.lib.user_groups import user_groups_in_realm_serialized
|
||||
from zerver.tornado.event_queue import request_event_queue, get_user_events
|
||||
from zerver.models import Client, Message, Realm, UserPresence, UserProfile, \
|
||||
|
@ -116,12 +115,6 @@ def fetch_initial_state_data(user_profile: UserProfile,
|
|||
if want('attachments'):
|
||||
state['attachments'] = user_attachments(user_profile)
|
||||
|
||||
if want('upload_quota'):
|
||||
state['upload_quota'] = user_profile.quota
|
||||
|
||||
if want('total_uploads_size'):
|
||||
state['total_uploads_size'] = get_total_uploads_size_for_user(user_profile)
|
||||
|
||||
if want('hotspots'):
|
||||
state['hotspots'] = get_next_hotspots(user_profile)
|
||||
|
||||
|
|
|
@ -181,22 +181,6 @@ def upload_image_to_s3(
|
|||
|
||||
key.set_contents_from_string(contents, headers=headers) # type: ignore # https://github.com/python/typeshed/issues/1552
|
||||
|
||||
def get_total_uploads_size_for_user(user: UserProfile) -> int:
|
||||
uploads = Attachment.objects.filter(owner=user)
|
||||
total_quota = uploads.aggregate(Sum('size'))['size__sum']
|
||||
|
||||
# In case user has no uploads
|
||||
if (total_quota is None):
|
||||
total_quota = 0
|
||||
return total_quota
|
||||
|
||||
def within_upload_quota(user: UserProfile, uploaded_file_size: int) -> bool:
|
||||
total_quota = get_total_uploads_size_for_user(user)
|
||||
if (total_quota + uploaded_file_size > user.quota):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def get_file_info(request: HttpRequest, user_file: File) -> Tuple[Text, int, Optional[Text]]:
|
||||
|
||||
uploaded_file_name = user_file.name
|
||||
|
|
|
@ -2651,7 +2651,7 @@ class FetchQueriesTest(ZulipTestCase):
|
|||
client_gravatar=False,
|
||||
)
|
||||
|
||||
self.assert_length(queries, 29)
|
||||
self.assert_length(queries, 28)
|
||||
|
||||
expected_counts = dict(
|
||||
alert_words=0,
|
||||
|
@ -2674,11 +2674,9 @@ class FetchQueriesTest(ZulipTestCase):
|
|||
realm_user_groups=2,
|
||||
stream=2,
|
||||
subscription=5,
|
||||
total_uploads_size=1,
|
||||
update_display_settings=0,
|
||||
update_global_notifications=0,
|
||||
update_message_flags=5,
|
||||
upload_quota=0,
|
||||
zulip_version=0,
|
||||
)
|
||||
|
||||
|
|
|
@ -154,11 +154,9 @@ class HomeTest(ZulipTestCase):
|
|||
"subscriptions",
|
||||
"test_suite",
|
||||
"timezone",
|
||||
"total_uploads_size",
|
||||
"twenty_four_hour_time",
|
||||
"unread_msgs",
|
||||
"unsubscribed",
|
||||
"upload_quota",
|
||||
"use_websockets",
|
||||
"user_id",
|
||||
"zulip_version",
|
||||
|
@ -185,7 +183,7 @@ class HomeTest(ZulipTestCase):
|
|||
with patch('zerver.lib.cache.cache_set') as cache_mock:
|
||||
result = self._get_home_page(stream='Denmark')
|
||||
|
||||
self.assert_length(queries, 42)
|
||||
self.assert_length(queries, 41)
|
||||
self.assert_length(cache_mock.call_args_list, 7)
|
||||
|
||||
html = result.content.decode('utf-8')
|
||||
|
@ -250,7 +248,7 @@ class HomeTest(ZulipTestCase):
|
|||
with queries_captured() as queries2:
|
||||
result = self._get_home_page()
|
||||
|
||||
self.assert_length(queries2, 35)
|
||||
self.assert_length(queries2, 34)
|
||||
|
||||
# Do a sanity check that our new streams were in the payload.
|
||||
html = result.content.decode('utf-8')
|
||||
|
|
|
@ -389,35 +389,6 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
|
|||
result = self.client_post("/json/user_uploads", {'f1': fp})
|
||||
assert sanitize_name(expected) in result.json()['uri']
|
||||
|
||||
def test_upload_size_quote(self) -> None:
|
||||
"""
|
||||
User quote for uploading should not be exceeded
|
||||
"""
|
||||
self.login(self.example_email("hamlet"))
|
||||
|
||||
d1 = StringIO("zulip!")
|
||||
d1.name = "dummy_1.txt"
|
||||
result = self.client_post("/json/user_uploads", {'file': d1})
|
||||
d1_path_id = re.sub('/user_uploads/', '', result.json()['uri'])
|
||||
d1_attachment = Attachment.objects.get(path_id = d1_path_id)
|
||||
self.assert_json_success(result)
|
||||
|
||||
"""
|
||||
Below we set size quota to the limit without 1 upload(1GB - 11 bytes).
|
||||
"""
|
||||
d1_attachment.size = UserProfile.DEFAULT_UPLOADS_QUOTA - 11
|
||||
d1_attachment.save()
|
||||
|
||||
d2 = StringIO("zulip!")
|
||||
d2.name = "dummy_2.txt"
|
||||
result = self.client_post("/json/user_uploads", {'file': d2})
|
||||
self.assert_json_success(result)
|
||||
|
||||
d3 = StringIO("zulip!")
|
||||
d3.name = "dummy_3.txt"
|
||||
result = self.client_post("/json/user_uploads", {'file': d3})
|
||||
self.assert_json_error(result, "Upload would exceed your maximum quota.")
|
||||
|
||||
def test_cross_realm_file_access(self) -> None:
|
||||
|
||||
def create_user(email: Text, realm_id: Text) -> UserProfile:
|
||||
|
|
|
@ -8,7 +8,7 @@ from django.utils.translation import ugettext as _
|
|||
from zerver.lib.request import has_request_variables, REQ
|
||||
from zerver.lib.response import json_success, json_error
|
||||
from zerver.lib.upload import upload_message_image_from_request, get_local_file_path, \
|
||||
get_signed_upload_url, get_realm_for_filename, within_upload_quota
|
||||
get_signed_upload_url, get_realm_for_filename
|
||||
from zerver.lib.validator import check_bool
|
||||
from zerver.models import UserProfile, validate_attachment_request
|
||||
from django.conf import settings
|
||||
|
@ -55,8 +55,6 @@ def upload_file_backend(request: HttpRequest, user_profile: UserProfile) -> Http
|
|||
if settings.MAX_FILE_UPLOAD_SIZE * 1024 * 1024 < file_size:
|
||||
return json_error(_("Uploaded file is larger than the allowed limit of %s MB") % (
|
||||
settings.MAX_FILE_UPLOAD_SIZE))
|
||||
if not within_upload_quota(user_profile, file_size):
|
||||
return json_error(_("Upload would exceed your maximum quota."))
|
||||
|
||||
if not isinstance(user_file.name, str):
|
||||
# It seems that in Python 2 unicode strings containing bytes are
|
||||
|
|
Loading…
Reference in New Issue