changeset 458:faa4c8467291

web: Improve upload workflow. - Add 'upload' and 'wikiupload' permissions, and check for them. - Fix the message about what the syntax is for using files in pages. - Fix uploading files to endpoint pages.
author Ludovic Chabant <ludovic@chabant.com>
date Wed, 10 Jan 2018 22:52:42 -0800
parents 038b22935250
children 6c8f90e47338
files wikked/auth.py wikked/templates/upload-file.html wikked/views/edit.py wikked/webimpl/edit.py
diffstat 4 files changed, 45 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/wikked/auth.py	Wed Jan 10 22:51:39 2018 -0800
+++ b/wikked/auth.py	Wed Jan 10 22:52:42 2018 -0800
@@ -14,12 +14,14 @@
 PERM_HISTORY = 2**4
 PERM_REVERT = 2**5
 PERM_SEARCH = 2**6
+PERM_UPLOAD = 2**7
 # Site-wide premissions.
-PERM_INDEX = 2**7
-PERM_LIST = 2**8
-PERM_LISTREFRESH = 2**9
-PERM_WIKIHISTORY = 2**10
-PERM_USERS = 2**11
+PERM_INDEX = 2**8
+PERM_LIST = 2**9
+PERM_LISTREFRESH = 2**10
+PERM_WIKIHISTORY = 2**11
+PERM_WIKIUPLOAD = 2**12
+PERM_USERS = 2**13
 
 PERM_NAMES = {
         # Page permissions.
@@ -31,11 +33,13 @@
         'history': PERM_HISTORY,
         'revert': PERM_REVERT,
         'search': PERM_SEARCH,
+        'upload': PERM_UPLOAD,
         # Site-wide permissions.
         'index': PERM_INDEX,
         'list': PERM_LIST,
         'listrefresh': PERM_LISTREFRESH,
         'wikihistory': PERM_WIKIHISTORY,
+        'wikiupload': PERM_WIKIUPLOAD,
         'users': PERM_USERS,
         # Aliases
         'write': PERM_EDIT,
@@ -47,9 +51,9 @@
 
 DEFAULT_USER_ROLES = {
         'reader': (PERM_READ | PERM_HISTORY),
-        'contributor': (PERM_READ | PERM_EDIT | PERM_HISTORY),
+        'contributor': (PERM_READ | PERM_EDIT | PERM_HISTORY | PERM_UPLOAD),
         'editor': (PERM_READ | PERM_EDIT | PERM_CREATE | PERM_DELETE |
-                   PERM_HISTORY | PERM_REVERT),
+                   PERM_HISTORY | PERM_REVERT | PERM_UPLOAD | PERM_WIKIUPLOAD),
         'admin': 0xffff
         }
 
--- a/wikked/templates/upload-file.html	Wed Jan 10 22:51:39 2018 -0800
+++ b/wikked/templates/upload-file.html	Wed Jan 10 22:52:42 2018 -0800
@@ -8,9 +8,13 @@
         {% if success %}
         <h2>File Uploaded!</h2>
         <section>
-            <p>The file is accessible with the following syntax: <code>{%raw%}{{file: {%endraw%}{{success.example}}{%raw%}}}{%endraw%}</code></p>
+            <p>The file URL is accessible with the following syntax: <code>[[file: {{success.example}}]]</code></p>
+            <p>Media files can be embedded easily in a page:</p>
+            <p><ul>
+                <li>Image: <code>[[image: {{success.example}}]]</code></li>
+            </ul></p>
             {% if success.is_page_specific %}
-            <p><strong>Note</strong>: this syntax is valid only on <a href="{{get_read_url(for_page)}}">the current page</a>.</p>
+            <p><strong>Note</strong>: these syntaxes are only valid on <a href="{{get_read_url(for_page)}}">the current page</a>.</p>
             {% endif %}
         </section>
         {% else %}
--- a/wikked/views/edit.py	Wed Jan 10 22:51:39 2018 -0800
+++ b/wikked/views/edit.py	Wed Jan 10 22:52:42 2018 -0800
@@ -98,27 +98,28 @@
 @requires_permission('create')
 def upload_file():
     p = request.args.get('p')
+    p_url = url_from_viewarg(p)
     data = {
         'post_back': url_for('upload_file', p=p),
-        'for_page': p
+        'for_page': p_url
     }
     add_auth_data(data)
-    add_navigation_data(p, data)
+    add_navigation_data(p_url, data)
 
     if request.method == 'GET':
         return render_template('upload-file.html', **data)
 
     if request.method == 'POST':
-        wiki = get_wiki()
-        user = current_user.get_id() or request.remote_addr
-
         for_url = None
         is_page_specific = (request.form.get('is_page_specific') == 'true')
         if is_page_specific:
-            for_url = p
+            for_url = p_url
 
+        wiki = get_wiki()
+        user = current_user.get_id()
         res = do_upload_file(
             wiki, user, request.files.get('file'),
+            commit_user=(user or request.remote_addr),
             for_url=for_url)
 
         data['success'] = {
--- a/wikked/webimpl/edit.py	Wed Jan 10 22:51:39 2018 -0800
+++ b/wikked/webimpl/edit.py	Wed Jan 10 22:52:42 2018 -0800
@@ -2,12 +2,14 @@
 import logging
 import urllib.parse
 from werkzeug.utils import secure_filename
+from wikked.auth import PERM_UPLOAD, PERM_WIKIUPLOAD
 from wikked.page import Page, PageData
 from wikked.formatter import PageFormatter, FormattingContext
 from wikked.resolver import PageResolver
 from wikked.utils import PageNotFoundError
 from wikked.webimpl import (
-        get_page_or_raise, get_page_meta, make_page_title)
+    get_page_or_raise, get_page_meta, make_page_title,
+    UserPermissionError)
 
 
 logger = logging.getLogger(__name__)
@@ -107,20 +109,31 @@
     return dummy.text
 
 
-def do_upload_file(wiki, user, reqfile, for_url=None, submit=True):
+def do_upload_file(wiki, user, reqfile, for_url=None, commit_user=False,
+                   submit=True):
     if not reqfile:
         raise Exception("No file was specified.")
     if not reqfile.filename:
         raise Exception("No file name was specified.")
 
-    # TODO: check permissions for the user.
+    # Check permissions for the user.
+    if for_url:
+        for_page = get_page_or_raise(wiki, for_url,
+                                     fields=['url', 'local_meta'])
+        if not wiki.auth.hasPagePermission(for_page, user, PERM_UPLOAD):
+            raise UserPermissionError(
+                "You don't have permission to upload files to this page.")
+    else:
+        if not wiki.auth.hasPermission(user, PERM_WIKIUPLOAD):
+            raise UserPermissionError(
+                "You don't have permission to upload files.")
 
     filename = secure_filename(reqfile.filename)
 
-    files_dir = os.path.join(wiki.root, '_files')
-    upload_dir = files_dir
+    upload_dir = os.path.join(wiki.root, '_files')
     if for_url:
-        upload_dir = os.path.join(wiki.root, for_url)
+        fs_info = wiki.fs.findPageInfo(for_url)
+        upload_dir, _ = os.path.splitext(fs_info.path)
 
     path = os.path.join(upload_dir, filename)
     path = os.path.normpath(path)
@@ -134,14 +147,14 @@
     # Commit the file to the source-control.
     if submit:
         commit_meta = {
-            'author': user,
+            'author': commit_user,
             'message': "Uploaded '%s'." % filename}
         wiki.scm.commit([path], commit_meta)
 
     if for_url:
         example = './%s' % filename
     else:
-        example = os.path.relpath(path, files_dir)
+        example = filename
     result = {
         'example': example
     }