Exemple #1
0
def upload_attachment(request, bookid, version=None):
    try:
        book = models.Book.objects.get(url_title__iexact=bookid)
    except models.Book.DoesNotExist:
        return views.ErrorPage(
            request, "errors/book_does_not_exist.html", {"book_name": bookid})

    user = request.user
    book_security = security.get_security_for_book(user, book)
    can_upload_attachment = book_security.has_perm('edit.upload_attachment')

    if (not user.is_superuser and not can_upload_attachment and book.owner != user):
        raise PermissionDenied

    book_version = book.get_version(version)
    stat = models.BookStatus.objects.filter(book=book)[0]

    with transaction.atomic():
        file_data = request.FILES['files[]']
        att = models.Attachment(
            version=book_version,
            # must remove this reference
            created=datetime.datetime.now(),
            book=book,
            status=stat
        )
        att.save()

        attName, attExt = os.path.splitext(file_data.name)
        att.attachment.save(
            '{}{}'.format(booktype_slugify(attName), attExt),
            file_data,
            save=False
        )
        att.save()

    response_data = {
        "files": [{
            "url": "http://127.0.0.1/",
            "thumbnail_url": "http://127.0.0.1/",
            "name": "boot.png",
            "type": "image/png",
            "size": 172728,
            "delete_url": "",
            "delete_type": "DELETE"
        }]
    }

    # add cliendID and sputnikID to request object
    # this will allow us to use sputnik and addMessageToChannel
    request.clientID = request.POST['clientID']
    request.sputnikID = "%s:%s" % (request.session.session_key, request.clientID)
    send_notification(request, book.id, book_version.get_version(),
                      "notification_new_attachment_uploaded", att.get_name())

    if "application/json" in request.META['HTTP_ACCEPT']:
        return HttpResponse(json.dumps(response_data),
                            content_type="application/json")
    else:
        return HttpResponse(json.dumps(response_data), content_type="text/html")
Exemple #2
0
def upload_attachment(request, bookid, version=None):
    try:
        book = models.Book.objects.get(url_title__iexact=bookid)
    except models.Book.DoesNotExist:
        return views.ErrorPage(
            request, "errors/book_does_not_exist.html", {"book_name": bookid})

    user = request.user
    book_security = security.get_security_for_book(user, book)
    can_upload_attachment = book_security.has_perm('edit.upload_attachment')

    if (not user.is_superuser and not can_upload_attachment and book.owner != user):
        raise PermissionDenied

    book_version = book.get_version(version)
    stat = models.BookStatus.objects.filter(book=book)[0]

    with transaction.atomic():
        file_data = request.FILES['files[]']
        att = models.Attachment(
            version=book_version,
            # must remove this reference
            created=datetime.datetime.now(),
            book=book,
            status=stat
        )
        att.save()

        attName, attExt = os.path.splitext(file_data.name)
        att.attachment.save(
            '{}{}'.format(booktype_slugify(attName), attExt),
            file_data,
            save=False
        )
        att.save()

    response_data = {
        "files": [{
            "url": "http://127.0.0.1/",
            "thumbnail_url": "http://127.0.0.1/",
            "name": "boot.png",
            "type": "image/png",
            "size": 172728,
            "delete_url": "",
            "delete_type": "DELETE"
        }]
    }

    # add cliendID and sputnikID to request object
    # this will allow us to use sputnik and addMessageToChannel
    request.clientID = request.POST['clientID']
    request.sputnikID = "%s:%s" % (request.session.session_key, request.clientID)
    send_notification(request, book.id, book_version.get_version(),
                      "notification_new_attachment_uploaded", att.get_name())

    if "application/json" in request.META['HTTP_ACCEPT']:
        return HttpResponse(json.dumps(response_data),
                            content_type="application/json")
    else:
        return HttpResponse(json.dumps(response_data), content_type="text/html")
Exemple #3
0
    def test_has_perm(self):
        # security for common user
        sec = security.get_security_for_book(self.user, self.bookrole.book)

        # common user, should have rights from book
        self.assertTrue(sec.has_perm('%s.%s' % (APP_NAME, CODE_NAME)),
                        "If user doesn't have that role, this should be False")
Exemple #4
0
    def has_perm(cls, book=None, request=None):
        if cls.required_permission:
            book_security = security.get_security_for_book(request.user, book)
            return book_security.has_perm(cls.required_permission)

        # if there no required permission, then True
        return True
Exemple #5
0
    def test_user_security_is_bookowner(self):
        # let's create a book and set it to the role
        # so we can scope permissions just for that book
        book = factory_models.BookFactory(owner=self.user)

        sec = security.get_security_for_book(self.user, book)

        self.assertTrue(sec.is_book_owner())
    def test_user_security_is_not_bookowner(self):
        # let's create a book and set it to the role
        # so we can scope permissions just for that book
        book = factory_models.BookFactory(owner=self.superuser)

        sec = security.get_security_for_book(self.user, book)

        self.assertFalse(sec.is_book_owner())
    def test_has_perm(self):
        # security for common user
        sec = security.get_security_for_book(self.user, self.bookrole.book)

        # common user, should have rights from book
        self.assertTrue(
            sec.has_perm('%s.%s' % (APP_NAME, CODE_NAME)),
            "If user doesn't have that role, this should be False")
Exemple #8
0
    def render_to_response(self, context, **response_kwargs):
        book = self.object
        book_security = security.get_security_for_book(self.request.user, book)
        book_permissions = security.get_user_permissions(self.request.user, book)

        return self.render_json_response({
            'admin': book_security.is_admin(),
            'permissions': book_permissions,
        })
Exemple #9
0
    def render_to_response(self, context, **response_kwargs):
        book = self.object
        book_security = security.get_security_for_book(self.request.user, book)
        book_permissions = security.get_user_permissions(self.request.user, book)

        return self.render_json_response({
            'admin': book_security.is_admin(),
            'permissions': book_permissions,
        })
Exemple #10
0
    def has_object_permission(self, request, view, obj):
        """Takes the list of required permissions from the view and
        check if user has them all"""

        required_perms = self.get_required_perms(view)
        if not required_perms:
            return True

        book_security = security.get_security_for_book(request.user, obj)
        perms_list = [book_security.has_perm(x) for x in required_perms]

        return all(perms_list)
Exemple #11
0
    def test_user_security_is_admin(self):
        # let's create a book and set it to the role
        # so we can scope permissions just for that book
        book = factory_models.BookFactory()
        self.bookrole.book = book

        # also put user as member of that role
        self.bookrole.members.add(self.superuser)
        self.bookrole.save()

        sec = security.get_security_for_book(self.superuser, book)

        self.assertTrue(sec.is_admin())
Exemple #12
0
    def test_user_security_is_admin(self):
        # let's create a book and set it to the role
        # so we can scope permissions just for that book
        book = factory_models.BookFactory()
        self.bookrole.book = book

        # also put user as member of that role
        self.bookrole.members.add(self.superuser)
        self.bookrole.save()

        sec = security.get_security_for_book(self.superuser, book)

        self.assertTrue(sec.is_admin())
Exemple #13
0
    def post(self, *args, **kwargs):
        request = self.request
        book = self.object = self.get_object()
        title = request.POST.get("title", "")
        book_security = security.get_security_for_book(request.user, book)
        book_permissions = security.get_user_permissions(request.user, book)
        self.template_name = "reader/book_delete_error.html"

        if (book_security.has_perm('edit.delete_book') and title.strip() == book.title.strip()):
            remove_book(book)
            self.template_name = "reader/book_delete_redirect.html"
            messages.success(request, _('Book successfully deleted.'))

        return self.render_to_response(context=self.get_context_data())
Exemple #14
0
    def post(self, *args, **kwargs):
        request = self.request
        book = self.object = self.get_object()
        title = request.POST.get("title", "")
        book_security = security.get_security_for_book(request.user, book)
        book_permissions = security.get_user_permissions(request.user, book)
        self.template_name = "reader/book_delete_error.html"

        if (book_security.has_perm('edit.delete_book') and title.strip() == book.title.strip()):
            remove_book(book)
            self.template_name = "reader/book_delete_redirect.html"
            messages.success(request, _('Book successfully deleted.'))

        return self.render_to_response(context=self.get_context_data())
Exemple #15
0
    def post(self, request, *args, **kwargs):
        book = self.get_object()
        self.object = book
        self.get_context_data(**kwargs)
        book_security = security.get_security_for_book(request.user, book)

        if not book_security.has_perm('edit.history_revert'):
            raise PermissionDenied

        revision = get_object_or_404(
            models.ChapterHistory,
            revision=request.POST["revert"],
            chapter=self.chapter,
            chapter__version=book.version.id
        )

        history = logChapterHistory(
            chapter=self.chapter,
            content=revision.content,
            user=request.user,
            comment=_("Reverted to revision %s.") % revision.revision,
            revision=self.chapter.revision + 1
        )

        if history:
            logBookHistory(
                book=book,
                version=book.version.id,
                chapter=self.chapter,
                chapter_history=history,
                user=request.user,
                args={},
                kind='chapter_save'
            )

        self.chapter.revision += 1
        self.chapter.content = revision.content
        try:
            self.chapter.save()
            messages.success(request, _('Chapter revision successfully reverted.'))
        except:
            messages.warning(request, _('Chapter revision could not be reverted.'))

        url = "{0}#history/{1}".format(
            reverse('edit:editor', args=[book.url_title]),
            self.chapter.url_title
        )
        return HttpResponseRedirect(url)
Exemple #16
0
    def post(self, request, *args, **kwargs):
        book = self.get_object()
        self.object = book
        self.get_context_data(**kwargs)
        book_security = security.get_security_for_book(request.user, book)

        if not book_security.has_perm('edit.history_revert'):
            raise PermissionDenied

        revision = get_object_or_404(
            models.ChapterHistory,
            revision=request.POST["revert"],
            chapter=self.chapter,
            chapter__version=book.version.id
        )

        history = logChapterHistory(
            chapter=self.chapter,
            content=revision.content,
            user=request.user,
            comment=_("Reverted to revision %s.") % revision.revision,
            revision=self.chapter.revision + 1
        )

        if history:
            logBookHistory(
                book=book,
                version=book.version.id,
                chapter=self.chapter,
                chapter_history=history,
                user=request.user,
                args={},
                kind='chapter_save'
            )

        self.chapter.revision += 1
        self.chapter.content = revision.content
        try:
            self.chapter.save()
            messages.success(request, _('Chapter revision successfully reverted.'))
        except:
            messages.warning(request, _('Chapter revision could not be reverted.'))

        url = "{0}#history/{1}".format(
            reverse('edit:editor', args=[book.url_title]),
            self.chapter.url_title
        )
        return HttpResponseRedirect(url)
Exemple #17
0
    def get_context_data(self, **kwargs):
        book = self.object
        content = None
        book_version = book.get_version(self.kwargs.get('version', None))
        context = super(DraftChapterView, self).get_context_data(**kwargs)

        # check permissions
        book_security = security.get_security_for_book(self.request.user, book)
        can_edit = book_security.can_edit()
        can_view_draft = book_security.has_perm('reader.can_view_draft')

        if (book.hidden and not can_edit) or not can_view_draft:
            context['has_permission'] = False
            return context

        if 'chapter' in self.kwargs:
            try:
                content = get_object_or_404(Chapter, version=book_version,
                                            url_title=self.kwargs['chapter'])
            except Http404:
                self.not_found = True
                context = dict(
                    not_found_object=_("Chapter"),
                    object_name=self.kwargs['chapter']
                )
                return context

        toc_items = BookToc.objects.filter(
            version=book_version).order_by("-weight")

        for chapter in toc_items:
            if not content and chapter.is_chapter():
                content = chapter.chapter
                break

        context['content'] = content
        context['toc_items'] = toc_items
        context['book_version'] = book_version.get_version()
        context['can_edit'] = (
            self.request.user.is_authenticated() and
            book.version == book_version
        )

        return context
Exemple #18
0
def remote_message_send(request, message, bookid):
    """
    Called when user is sending message to chat channel L{bookid}.

    @type request: C{django.http.HttpRequest}
    @param request: Client Request object
    @type message: C{dict}
    @param message: Message object
    @type bookid: C{string}
    @param bookid: Unique Book id
    """

    try:
        book = Book.objects.get(id=int(bookid))
    except Book.DoesNotExist:
        raise ObjectDoesNotExist
    except Book.MultipleObjectsReturned:
        raise ObjectDoesNotExist

    book_security = security.get_security_for_book(request.user, book)
    has_permission = book_security.can_edit()

    if not has_permission:
        raise PermissionDenied

    # get chat thread
    chat_thread, _ = ChatThread.objects.get_or_create(book=book)
    # create message
    chat_message = ChatMessage()
    chat_message.thread = chat_thread
    chat_message.sender = request.user
    chat_message.text = message["message"]
    chat_message.save()

    sputnik.addMessageToChannel(
        request, "/chat/%s/" % bookid, {
            "command": "message_received",
            "email": request.user.email,
            "from": request.user.username,
            "important": message["important"],
            "message": message["message"]
        })
    return {}
Exemple #19
0
    def get_context_data(self, **kwargs):
        book = self.object
        context = super(FullView, self).get_context_data(**kwargs)

        has_permission = security.get_security_for_book(self.request.user, book).has_perm(
            'reader.can_view_full_page')

        if not has_permission:
            context['has_permission'] = has_permission
            return context

        book_version = book.get_version(self.kwargs.get('version', None))
        toc_items = BookToc.objects.filter(
            version=book_version).order_by("-weight")

        context['book_version'] = book_version.get_version()
        context['toc_items'] = toc_items

        return context
Exemple #20
0
    def get_context_data(self, **kwargs):
        book = self.object
        context = super(FullView, self).get_context_data(**kwargs)

        has_permission = security.get_security_for_book(
            self.request.user, book).has_perm('reader.can_view_full_page')

        if not has_permission:
            context['has_permission'] = has_permission
            return context

        book_version = book.get_version(self.kwargs.get('version', None))
        toc_items = BookToc.objects.filter(
            version=book_version).order_by("-weight")

        context['book_version'] = book_version.get_version()
        context['toc_items'] = toc_items

        return context
Exemple #21
0
    def get_context_data(self, **kwargs):
        book = self.object
        content = None
        book_version = book.get_version(self.kwargs.get('version', None))
        context = super(DraftChapterView, self).get_context_data(**kwargs)

        # check permissions
        book_security = security.get_security_for_book(self.request.user, book)
        can_edit = book_security.can_edit()
        can_view_draft = book_security.has_perm('reader.can_view_draft')

        if (book.hidden and not can_edit) or not can_view_draft:
            context['has_permission'] = False
            return context

        if 'chapter' in self.kwargs:
            try:
                content = get_object_or_404(Chapter,
                                            version=book_version,
                                            url_title=self.kwargs['chapter'])
            except Http404:
                self.not_found = True
                context = dict(not_found_object=_("Chapter"),
                               object_name=self.kwargs['chapter'])
                return context

        toc_items = BookToc.objects.filter(
            version=book_version).order_by("-weight")

        for chapter in toc_items:
            if not content and chapter.is_chapter():
                content = chapter.chapter
                break

        context['content'] = content
        context['toc_items'] = toc_items
        context['book_version'] = book_version.get_version()
        context['can_edit'] = (self.request.user.is_authenticated()
                               and book.version == book_version)

        return context
Exemple #22
0
def remote_message_send(request, message, bookid):
    """
    Called when user is sending message to chat channel L{bookid}.

    @type request: C{django.http.HttpRequest}
    @param request: Client Request object
    @type message: C{dict}
    @param message: Message object
    @type bookid: C{string}
    @param bookid: Unique Book id
    """

    try:
        book = Book.objects.get(id=int(bookid))
    except Book.DoesNotExist:
        raise ObjectDoesNotExist
    except Book.MultipleObjectsReturned:
        raise ObjectDoesNotExist

    book_security = security.get_security_for_book(request.user, book)
    has_permission = book_security.can_edit()

    if not has_permission:
        raise PermissionDenied

    # get chat thread
    chat_thread, _ = ChatThread.objects.get_or_create(book=book)
    # create message
    chat_message = ChatMessage()
    chat_message.thread = chat_thread
    chat_message.sender = request.user
    chat_message.text = message["message"]
    chat_message.save()

    sputnik.addMessageToChannel(request, "/chat/%s/" % bookid,
                                {"command": "message_received",
                                 "email": request.user.email,
                                 "from": request.user.username,
                                 "important": message["important"],
                                 "message": message["message"]})
    return {}
Exemple #23
0
    def dispatch(self, request, *args, **kwargs):
        # try to create security instance
        try:
            if self.security_bridge is Security:
                self.security = get_security(request.user)
            elif self.security_bridge is BookSecurity:
                book = Book.objects.get(url_title__iexact=kwargs['bookid'])
                self.security = get_security_for_book(request.user, book)
            elif self.security_bridge is GroupSecurity:
                group = BookiGroup.objects.get(url_name=kwargs['groupid'])
                self.security = get_security_for_group(request.user, group)
        except (BookiGroup.DoesNotExist, Book.DoesNotExist):
            raise Http404
        except KeyError as e:
            raise Exception('{bridge} bridge requires "{key}" in request'.format(bridge=self.security_bridge,
                                                                                 key=e.message))

        # hook for checking permissions
        self.check_permissions(request, *args, **kwargs)

        return super(SecurityMixin, self).dispatch(request, *args, **kwargs)
Exemple #24
0
    def dispatch(self, request, *args, **kwargs):
        # try to create security instance
        try:
            if self.security_bridge is Security:
                self.security = get_security(request.user)
            elif self.security_bridge is BookSecurity:
                book = Book.objects.get(url_title__iexact=kwargs['bookid'])
                self.security = get_security_for_book(request.user, book)
            elif self.security_bridge is GroupSecurity:
                group = BookiGroup.objects.get(url_name=kwargs['groupid'])
                self.security = get_security_for_group(request.user, group)
        except (BookiGroup.DoesNotExist, Book.DoesNotExist):
            raise Http404
        except KeyError as e:
            raise Exception('{bridge} bridge requires "{key}" in request'.format(bridge=self.security_bridge,
                                                                                 key=e.message))

        # hook for checking permissions
        self.check_permissions(request, *args, **kwargs)

        return super(SecurityMixin, self).dispatch(request, *args, **kwargs)
Exemple #25
0
 def test_get_security_for_book(self):
     # let's test helper for retrieving BookSecurity instance
     self.assertEqual(
         security.BookSecurity(self.user, self.bookrole.book).__class__,
         security.get_security_for_book(self.user,
                                        self.bookrole.book).__class__)
Exemple #26
0
 def test_get_security_for_book(self):
     # let's test helper for retrieving BookSecurity instance
     self.assertEqual(security.BookSecurity(self.user, self.bookrole.book).__class__,
                      security.get_security_for_book(self.user, self.bookrole.book).__class__)
Exemple #27
0
def upload_cover(request, bookid, version=None):
    try:
        book = models.Book.objects.get(url_title__iexact=bookid)
    except models.Book.DoesNotExist:
        return views.ErrorPage(request, "errors/book_does_not_exist.html",
                               {"book_name": bookid})

    can_upload_cover = security.get_security_for_book(request.user, book).has_perm('edit.upload_cover')

    if (not request.user.is_superuser and not can_upload_cover and book.owner != request.user):
        raise PermissionDenied

    with transaction.atomic():
        file_data = request.FILES['files[]']
        title = request.POST.get('title', '')
        try:
            filename = unidecode.unidecode(file_data.name)
        except:
            filename = uuid.uuid1().hex

        h = hashlib.sha1()
        h.update(filename)
        h.update(title)
        h.update(str(datetime.datetime.now()))

        license = models.License.objects.get(
            abbrevation=request.POST.get('license', ''))

        cover = models.BookCover(
            book=book,
            user=request.user,
            cid=h.hexdigest(),
            title=title,
            filename=filename[:250],
            width=0,
            height=0,
            unit=request.POST.get('unit', 'mm'),
            booksize=request.POST.get('booksize', ''),
            cover_type=request.POST.get('type', ''),
            creator=request.POST.get('creator', '')[:40],
            license=license,
            notes=request.POST.get('notes', '')[:500],
            approved=False,
            is_book=False,
            is_ebook=True,
            is_pdf=False,
            created=datetime.datetime.now()
        )
        cover.save()

        # now save the attachment
        cover.attachment.save(filename, file_data, save=False)
        cover.save()

    response_data = {
        "files": [{
            "url": "http://127.0.0.1/",
            "thumbnail_url": "http://127.0.0.1/",
            "name": "boot.png",
            "type": "image/png",
            "size": 172728,
            "delete_url": "",
            "delete_type": "DELETE"
        }]
    }

    # add cliendID and sputnikID to request object
    # this will allow us to use sputnik and addMessageToChannel
    request.clientID = request.POST['clientID']
    request.sputnikID = "%s:%s" % (request.session.session_key, request.clientID)
    send_notification(request, book.id, book.get_version(version).get_version(),
                      "notification_new_cover_uploaded", cover.title)

    if "application/json" in request.META['HTTP_ACCEPT']:
        return HttpResponse(json.dumps(response_data),
                            content_type="application/json")
    else:
        return HttpResponse(json.dumps(response_data), content_type="text/html")
Exemple #28
0
def upload_cover(request, bookid, version=None):
    try:
        book = models.Book.objects.get(url_title__iexact=bookid)
    except models.Book.DoesNotExist:
        return views.ErrorPage(request, "errors/book_does_not_exist.html",
                               {"book_name": bookid})

    can_upload_cover = security.get_security_for_book(request.user, book).has_perm('edit.upload_cover')

    if (not request.user.is_superuser and not can_upload_cover and book.owner != request.user):
        raise PermissionDenied

    with transaction.atomic():
        file_data = request.FILES['files[]']
        title = request.POST.get('title', '')
        try:
            filename = unidecode.unidecode(file_data.name)
        except:
            filename = uuid.uuid1().hex

        h = hashlib.sha1()
        h.update(filename)
        h.update(title)
        h.update(str(datetime.datetime.now()))

        license = models.License.objects.get(
            abbrevation=request.POST.get('license', ''))

        cover = models.BookCover(
            book=book,
            user=request.user,
            cid=h.hexdigest(),
            title=title,
            filename=filename[:250],
            width=0,
            height=0,
            unit=request.POST.get('unit', 'mm'),
            booksize=request.POST.get('booksize', ''),
            cover_type=request.POST.get('type', ''),
            creator=request.POST.get('creator', '')[:40],
            license=license,
            notes=request.POST.get('notes', '')[:500],
            approved=False,
            is_book=False,
            is_ebook=True,
            is_pdf=False,
            created=datetime.datetime.now()
        )
        cover.save()

        # now save the attachment
        cover.attachment.save(filename, file_data, save=False)
        cover.save()

    response_data = {
        "files": [{
            "url": "http://127.0.0.1/",
            "thumbnail_url": "http://127.0.0.1/",
            "name": "boot.png",
            "type": "image/png",
            "size": 172728,
            "delete_url": "",
            "delete_type": "DELETE"
        }]
    }

    # add cliendID and sputnikID to request object
    # this will allow us to use sputnik and addMessageToChannel
    request.clientID = request.POST['clientID']
    request.sputnikID = "%s:%s" % (request.session.session_key, request.clientID)
    send_notification(request, book.id, book.get_version(version).get_version(),
                      "notification_new_cover_uploaded", cover.title)

    if "application/json" in request.META['HTTP_ACCEPT']:
        return HttpResponse(json.dumps(response_data),
                            content_type="application/json")
    else:
        return HttpResponse(json.dumps(response_data), content_type="text/html")