tiddlywiki: Avoid writing duplicate temporary files

Tests:

- Raise an error by editing code in create, upload, rename and delete
operations. Notice that the details error messages are shown with a drop-down.

- Upload a wiki and it works. The name is as expected.

- Upload the wiki again notice that the duplicate wiki error is shown.

Signed-off-by: Joseph Nuthalapati <njoseph@riseup.net>
[sunil: Use new utility for uploading]
[sunil: Better error message display in the UI]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Veiko Aasa <veiko17@disroot.org>
This commit is contained in:
Joseph Nuthalapati 2024-08-30 17:13:49 +05:30 committed by Veiko Aasa
parent ad09964e18
commit 876cace107
No known key found for this signature in database
GPG Key ID: 478539CAE680674E
2 changed files with 20 additions and 39 deletions

View File

@ -4,9 +4,9 @@
import pathlib
import re
import shutil
import tempfile
import urllib.request
from plinth import action_utils
from plinth.actions import privileged
EMPTY_WIKI_FILE = 'https://ftp.freedombox.org/pub/tiddlywiki/empty.html'
@ -51,20 +51,11 @@ def create_wiki(file_name: str):
@privileged
def add_wiki_file(upload_file: str):
def add_wiki_file(file_name: str, temporary_file_path: str):
"""Add an uploaded wiki file."""
upload_file_path = pathlib.Path(upload_file)
temp_dir = tempfile.gettempdir()
if not upload_file_path.is_relative_to(temp_dir):
raise Exception('Uploaded file is not in expected temp directory.')
file_name = _normalize_wiki_file_name(upload_file_path.name)
file_path = wiki_dir / file_name
if file_path.exists():
raise ValueError('Wiki exists')
shutil.move(upload_file_path, file_path)
_set_ownership(file_path)
action_utils.move_uploaded_file(temporary_file_path, wiki_dir, file_name,
allow_overwrite=False, user='www-data',
group='www-data', permissions=0o644)
@privileged

View File

@ -1,8 +1,6 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
"""Django views for TiddlyWiki."""
import tempfile
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.shortcuts import redirect
@ -14,6 +12,7 @@ from django.views.generic import FormView
from plinth import app as app_module
from plinth import views
from plinth.modules import tiddlywiki
from plinth.views import messages_error
from . import privileged
from .forms import CreateWikiForm, RenameWikiForm, UploadWikiForm
@ -56,9 +55,9 @@ class CreateWikiView(SuccessMessageMixin, FormView):
except ValueError:
messages.error(self.request, DUPLICATE_FILE_ERROR)
except Exception as error:
messages.error(
self.request, "{0} {1}".format(
_('An error occurred while creating the wiki.'), error))
messages_error(self.request,
_('An error occurred while creating the wiki.'),
error)
return super().form_valid(form)
@ -86,9 +85,9 @@ class RenameWikiView(SuccessMessageMixin, FormView):
except ValueError:
messages.error(self.request, DUPLICATE_FILE_ERROR)
except Exception as error:
messages.error(
self.request, "{0} {1}".format(
_('An error occurred while renaming the wiki.'), error))
messages_error(self.request,
_('An error occurred while renaming the wiki.'),
error)
return super().form_valid(form)
@ -109,24 +108,16 @@ class UploadWikiView(SuccessMessageMixin, FormView):
def form_valid(self, form):
"""Add the wiki file on valid form submission."""
multipart_file = self.request.FILES['tiddlywiki-file']
try:
with tempfile.TemporaryDirectory() as temp_dir:
wiki_file_name = temp_dir + '/' + multipart_file.name
with open(wiki_file_name, 'wb+') as wiki_file:
for chunk in multipart_file.chunks():
wiki_file.write(chunk)
privileged.add_wiki_file(wiki_file_name)
uploaded_file = self.request.FILES['tiddlywiki-file']
privileged.add_wiki_file(uploaded_file.name,
uploaded_file.temporary_file_path())
self.success_message = _('Wiki file added.')
except ValueError:
except FileExistsError:
messages.error(self.request, DUPLICATE_FILE_ERROR)
except Exception as error:
messages.error(
self.request, "{0} {1}".format(_('Failed to add wiki file.'),
error))
messages_error(self.request, _('Failed to add wiki file.'), error)
return redirect(reverse_lazy('tiddlywiki:index'))
return super().form_valid(form)
@ -144,10 +135,9 @@ def delete(request, name):
privileged.delete_wiki(name)
messages.success(request, _('{name} deleted.').format(name=name))
except Exception as error:
messages.error(
request,
_('Could not delete {name}: {error}').format(
name=name, error=error))
messages_error(request,
_('Could not delete {name}').format(name=name),
error)
return redirect(reverse_lazy('tiddlywiki:index'))