views: block upload when MAX_DOCUMENTS_PER_USER limit is reached (#41491)

This commit is contained in:
Benjamin Dauvergne 2020-04-08 23:36:56 +02:00
parent f243035c56
commit ac96816391
3 changed files with 76 additions and 10 deletions

View File

@ -34,6 +34,7 @@ from django.contrib.auth import views as auth_views
from django.utils.http import quote
from django.utils.translation import ugettext as _
from django.utils.decorators import method_decorator
from django.utils.functional import cached_property
from django.conf import settings
from django_tables2 import SingleTableMixin
@ -53,7 +54,22 @@ class Logger(object):
self.logger = logging.getLogger(__name__)
class CommonUpload(Logger, CreateView):
class Documents(object):
def get_queryset(self):
return models.UserDocument.objects \
.filter(user=self.request.user) \
.select_related('document', 'user')
@cached_property
def count(self):
return self.get_queryset().filter(origin__isnull=True).count()
@cached_property
def full(self):
return self.count >= settings.FARGO_MAX_DOCUMENTS_PER_USER
class CommonUpload(Logger, Documents, CreateView):
form_class = forms.UploadForm
model = models.UserDocument
template_name = 'fargo/upload.html'
@ -77,20 +93,18 @@ class Upload(CommonUpload):
homepage = reverse('home')
return self.request.GET.get(REDIRECT_FIELD_NAME, homepage)
def dispatch(self, request, *args, **kwargs):
if self.full:
return HttpResponseRedirect(self.get_success_url())
return super(Upload, self).dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
if 'cancel' in request.POST:
return HttpResponseRedirect(self.get_success_url())
return super(Upload, self).post(request, *args, **kwargs)
class Documents(object):
def get_queryset(self):
return models.UserDocument.objects \
.filter(user=self.request.user) \
.select_related('document', 'user')
class Homepage(Documents, SingleTableMixin, CommonUpload):
class Homepage(SingleTableMixin, CommonUpload):
'''Show documents of users, eventually paginate and sort them.'''
template_name = 'fargo/home.html'
form_class = forms.UploadForm
@ -108,8 +122,17 @@ class Homepage(Documents, SingleTableMixin, CommonUpload):
max_size = ctx['max_portfolio_size'] = settings.FARGO_MAX_DOCUMENT_BOX_SIZE
ctx['occupancy_ratio'] = float(occupancy) / max_size
ctx['occupancy_ratio_percent'] = float(occupancy) * 100.0 / max_size
ctx['max_documents_per_user'] = settings.FARGO_MAX_DOCUMENTS_PER_USER
ctx['full'] = self.full
ctx['count'] = self.count
return ctx
def post(self, request, *args, **kwargs):
if self.full:
return HttpResponseRedirect('')
return super(CommonUpload, self).post(request, *args, **kwargs)
class PickView(object):
def dispatch(self, request, *args, **kwargs):

View File

@ -44,6 +44,16 @@
<div class="cell">
<h2>{% if site_title %}{{ site_title }}{% else %}{% trans "Portfolio" %}{% endif %}</h2>
<div id="user-files">
{% if count %}
<div id="user-files-count">
{% blocktrans count documents_count=count trimmed %}
You have {{ documents_count }} document stored.
{% plural %}
You have {{ documents_count }} documents stored.
{% endblocktrans %}
</div>
{% endif %}
{% if not table.page %}
<div class="table-container">
{% endif %}
@ -51,7 +61,18 @@
{% if not table.page %}
</div>
{% endif %}
{% if full %}
<div class="infonotice">
{% blocktrans count max_documents_per_user=max_documents_per_user trimmed %}
The limit of {{ max_documents_per_user }} document per user is reached.
You cannot add any more documents.
{% plural %}
The limit of {{ max_documents_per_user }} documents per user is reached.
You cannot add any more documents.
{% endblocktrans %}
</div>
{% else %}
<form id="send-file" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.non_field_errors }}
@ -70,6 +91,7 @@
</div>
<button>{% trans "Upload a new document" %}</button>
</form>
{% endif %}
</div>
</div>
{% endblock %}

View File

@ -129,3 +129,24 @@ def test_delete(app, john_doe, jane_doe):
resp = app.get('/')
assert 'monfichier.txt' not in resp.text
resp = app.get(delete_url, status=404)
def test_max_documents_per_user(app, private_settings, john_doe):
private_settings.FARGO_MAX_DOCUMENTS_PER_USER = 1
login(app, user=john_doe)
response1 = app.get('/')
assert len(response1.forms) == 2
form = response1.form
form['content'] = Upload('monfichier.pdf', b'coin', 'application/pdf')
response2 = form.submit().follow()
assert 'monfichier.pdf' in response2.text
assert len(response2.forms) == 0
response2 = form.submit().follow()
assert 'monfichier.pdf' in response2.text
assert len(response2.forms) == 0
assert UserDocument.objects.count() == 1
response = app.get('/upload/')
assert response.location == '/'