diff --git a/plinth/modules/featherwiki/privileged.py b/plinth/modules/featherwiki/privileged.py index aac342b16..33e27b615 100644 --- a/plinth/modules/featherwiki/privileged.py +++ b/plinth/modules/featherwiki/privileged.py @@ -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/featherwiki/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 diff --git a/plinth/modules/featherwiki/views.py b/plinth/modules/featherwiki/views.py index 7692028c0..27006d779 100644 --- a/plinth/modules/featherwiki/views.py +++ b/plinth/modules/featherwiki/views.py @@ -1,8 +1,6 @@ # SPDX-License-Identifier: AGPL-3.0-or-later """Django views for Feather Wiki.""" -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 featherwiki +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,15 @@ class UploadWikiView(SuccessMessageMixin, FormView): def form_valid(self, form): """Add the wiki file on valid form submission.""" - multipart_file = self.request.FILES['featherwiki-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['featherwiki-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('featherwiki:index')) return super().form_valid(form) @@ -144,10 +134,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('featherwiki:index'))