Fixes #1542
[redakcja.git] / apps / wiki / views.py
index b137a54..f707892 100644 (file)
@@ -5,14 +5,14 @@ import logging
 from django.conf import settings
 from django.core.urlresolvers import reverse
 from django import http
 from django.conf import settings
 from django.core.urlresolvers import reverse
 from django import http
-from django.http import Http404
+from django.http import Http404, HttpResponseForbidden
 from django.middleware.gzip import GZipMiddleware
 from django.utils.decorators import decorator_from_middleware
 from django.utils.encoding import smart_unicode
 from django.middleware.gzip import GZipMiddleware
 from django.utils.decorators import decorator_from_middleware
 from django.utils.encoding import smart_unicode
+from django.utils.formats import localize
 from django.utils.translation import ugettext as _
 from django.views.decorators.http import require_POST, require_GET
 from django.utils.translation import ugettext as _
 from django.views.decorators.http import require_POST, require_GET
-from django.views.generic.simple import direct_to_template
-from django.shortcuts import get_object_or_404
+from django.shortcuts import get_object_or_404, render
 
 from catalogue.models import Book, Chunk
 import nice_diff
 
 from catalogue.models import Book, Chunk
 import nice_diff
@@ -46,6 +46,8 @@ def editor(request, slug, chunk=None, template_name='wiki/document_details.html'
                 return http.HttpResponseRedirect(reverse("catalogue_create_missing", args=[slug]))
         else:
             raise Http404
                 return http.HttpResponseRedirect(reverse("catalogue_create_missing", args=[slug]))
         else:
             raise Http404
+    if not chunk.book.accessible(request):
+        return HttpResponseForbidden("Not authorized.")
 
     access_time = datetime.now()
     last_books = request.session.get("wiki_last_books", {})
 
     access_time = datetime.now()
     last_books = request.session.get("wiki_last_books", {})
@@ -59,13 +61,14 @@ def editor(request, slug, chunk=None, template_name='wiki/document_details.html'
         del last_books[oldest_key]
     request.session['wiki_last_books'] = last_books
 
         del last_books[oldest_key]
     request.session['wiki_last_books'] = last_books
 
-    return direct_to_template(request, template_name, extra_context={
+    return render(request, template_name, {
         'chunk': chunk,
         'forms': {
             "text_save": forms.DocumentTextSaveForm(user=request.user, prefix="textsave"),
             "text_revert": forms.DocumentTextRevertForm(prefix="textrevert"),
             "pubmark": forms.DocumentPubmarkForm(prefix="pubmark"),
         },
         'chunk': chunk,
         'forms': {
             "text_save": forms.DocumentTextSaveForm(user=request.user, prefix="textsave"),
             "text_revert": forms.DocumentTextRevertForm(prefix="textrevert"),
             "pubmark": forms.DocumentPubmarkForm(prefix="pubmark"),
         },
+        'can_pubmark': request.user.has_perm('catalogue.can_pubmark'),
         'REDMINE_URL': settings.REDMINE_URL,
     })
 
         'REDMINE_URL': settings.REDMINE_URL,
     })
 
@@ -77,6 +80,8 @@ def editor_readonly(request, slug, chunk=None, template_name='wiki/document_deta
         revision = request.GET['revision']
     except (Chunk.MultipleObjectsReturned, Chunk.DoesNotExist, KeyError):
         raise Http404
         revision = request.GET['revision']
     except (Chunk.MultipleObjectsReturned, Chunk.DoesNotExist, KeyError):
         raise Http404
+    if not chunk.book.accessible(request):
+        return HttpResponseForbidden("Not authorized.")
 
     access_time = datetime.now()
     last_books = request.session.get("wiki_last_books", {})
 
     access_time = datetime.now()
     last_books = request.session.get("wiki_last_books", {})
@@ -90,7 +95,7 @@ def editor_readonly(request, slug, chunk=None, template_name='wiki/document_deta
         del last_books[oldest_key]
     request.session['wiki_last_books'] = last_books
 
         del last_books[oldest_key]
     request.session['wiki_last_books'] = last_books
 
-    return direct_to_template(request, template_name, extra_context={
+    return render(request, template_name, {
         'chunk': chunk,
         'revision': revision,
         'readonly': True,
         'chunk': chunk,
         'revision': revision,
         'readonly': True,
@@ -102,6 +107,8 @@ def editor_readonly(request, slug, chunk=None, template_name='wiki/document_deta
 @decorator_from_middleware(GZipMiddleware)
 def text(request, chunk_id):
     doc = get_object_or_404(Chunk, pk=chunk_id)
 @decorator_from_middleware(GZipMiddleware)
 def text(request, chunk_id):
     doc = get_object_or_404(Chunk, pk=chunk_id)
+    if not doc.book.accessible(request):
+        return HttpResponseForbidden("Not authorized.")
 
     if request.method == 'POST':
         form = forms.DocumentTextSaveForm(request.POST, user=request.user, prefix="textsave")
 
     if request.method == 'POST':
         form = forms.DocumentTextSaveForm(request.POST, user=request.user, prefix="textsave")
@@ -118,6 +125,8 @@ def text(request, chunk_id):
                 parent = None
             stage = form.cleaned_data['stage_completed']
             tags = [stage] if stage else []
                 parent = None
             stage = form.cleaned_data['stage_completed']
             tags = [stage] if stage else []
+            publishable = (form.cleaned_data['publishable'] and
+                    request.user.has_perm('catalogue.can_pubmark'))
             doc.commit(author=author,
                        text=text,
                        parent=parent,
             doc.commit(author=author,
                        text=text,
                        parent=parent,
@@ -125,6 +134,7 @@ def text(request, chunk_id):
                        tags=tags,
                        author_name=form.cleaned_data['author_name'],
                        author_email=form.cleaned_data['author_email'],
                        tags=tags,
                        author_name=form.cleaned_data['author_name'],
                        author_email=form.cleaned_data['author_email'],
+                       publishable=publishable,
                        )
             revision = doc.revision()
             return JSONResponse({
                        )
             revision = doc.revision()
             return JSONResponse({
@@ -160,6 +170,8 @@ def revert(request, chunk_id):
     form = forms.DocumentTextRevertForm(request.POST, prefix="textrevert")
     if form.is_valid():
         doc = get_object_or_404(Chunk, pk=chunk_id)
     form = forms.DocumentTextRevertForm(request.POST, prefix="textrevert")
     if form.is_valid():
         doc = get_object_or_404(Chunk, pk=chunk_id)
+        if not doc.book.accessible(request):
+            return HttpResponseForbidden("Not authorized.")
 
         revision = form.cleaned_data['revision']
 
 
         revision = form.cleaned_data['revision']
 
@@ -189,12 +201,12 @@ def gallery(request, directory):
     try:
         base_url = ''.join((
                         smart_unicode(settings.MEDIA_URL),
     try:
         base_url = ''.join((
                         smart_unicode(settings.MEDIA_URL),
-                        smart_unicode(settings.FILEBROWSER_DIRECTORY),
+                        smart_unicode(settings.IMAGE_DIR),
                         smart_unicode(directory)))
 
         base_dir = os.path.join(
                     smart_unicode(settings.MEDIA_ROOT),
                         smart_unicode(directory)))
 
         base_dir = os.path.join(
                     smart_unicode(settings.MEDIA_ROOT),
-                    smart_unicode(settings.FILEBROWSER_DIRECTORY),
+                    smart_unicode(settings.IMAGE_DIR),
                     smart_unicode(directory))
 
         def map_to_url(filename):
                     smart_unicode(directory))
 
         def map_to_url(filename):
@@ -205,6 +217,10 @@ def gallery(request, directory):
 
         images = [map_to_url(f) for f in map(smart_unicode, os.listdir(base_dir)) if is_image(f)]
         images.sort()
 
         images = [map_to_url(f) for f in map(smart_unicode, os.listdir(base_dir)) if is_image(f)]
         images.sort()
+
+        if not request.user.is_authenticated():
+            return HttpResponseForbidden("Not authorized.")
+
         return JSONResponse(images)
     except (IndexError, OSError):
         logger.exception("Unable to fetch gallery")
         return JSONResponse(images)
     except (IndexError, OSError):
         logger.exception("Unable to fetch gallery")
@@ -223,6 +239,9 @@ def diff(request, chunk_id):
         revB = None
 
     doc = get_object_or_404(Chunk, pk=chunk_id)
         revB = None
 
     doc = get_object_or_404(Chunk, pk=chunk_id)
+    if not doc.book.accessible(request):
+        return HttpResponseForbidden("Not authorized.")
+
     # allow diff from the beginning
     if revA:
         docA = doc.at_revision(revA).materialize()
     # allow diff from the beginning
     if revA:
         docA = doc.at_revision(revA).materialize()
@@ -237,6 +256,8 @@ def diff(request, chunk_id):
 @never_cache
 def revision(request, chunk_id):
     doc = get_object_or_404(Chunk, pk=chunk_id)
 @never_cache
 def revision(request, chunk_id):
     doc = get_object_or_404(Chunk, pk=chunk_id)
+    if not doc.book.accessible(request):
+        return HttpResponseForbidden("Not authorized.")
     return http.HttpResponse(str(doc.revision()))
 
 
     return http.HttpResponse(str(doc.revision()))
 
 
@@ -244,14 +265,16 @@ def revision(request, chunk_id):
 def history(request, chunk_id):
     # TODO: pagination
     doc = get_object_or_404(Chunk, pk=chunk_id)
 def history(request, chunk_id):
     # TODO: pagination
     doc = get_object_or_404(Chunk, pk=chunk_id)
+    if not doc.book.accessible(request):
+        return HttpResponseForbidden("Not authorized.")
 
     changes = []
 
     changes = []
-    for change in doc.history().order_by('-created_at'):
+    for change in doc.history().reverse():
         changes.append({
                 "version": change.revision,
                 "description": change.description,
                 "author": change.author_str(),
         changes.append({
                 "version": change.revision,
                 "description": change.description,
                 "author": change.author_str(),
-                "date": change.created_at,
+                "date": localize(change.created_at),
                 "publishable": _("Publishable") + "\n" if change.publishable else "",
                 "tag": ',\n'.join(unicode(tag) for tag in change.tags.all()),
             })
                 "publishable": _("Publishable") + "\n" if change.publishable else "",
                 "tag": ',\n'.join(unicode(tag) for tag in change.tags.all()),
             })
@@ -264,6 +287,8 @@ def pubmark(request, chunk_id):
     form = forms.DocumentPubmarkForm(request.POST, prefix="pubmark")
     if form.is_valid():
         doc = get_object_or_404(Chunk, pk=chunk_id)
     form = forms.DocumentPubmarkForm(request.POST, prefix="pubmark")
     if form.is_valid():
         doc = get_object_or_404(Chunk, pk=chunk_id)
+        if not doc.book.accessible(request):
+            return HttpResponseForbidden("Not authorized.")
 
         revision = form.cleaned_data['revision']
         publishable = form.cleaned_data['publishable']
 
         revision = form.cleaned_data['revision']
         publishable = form.cleaned_data['publishable']