Giter VIP home page Giter VIP logo

Comments (3)

tisto avatar tisto commented on July 18, 2024 2

@datakurre thank you, Asko! Turned out it was sufficient to patch the comment security to make it work for now. Will look into a refactoring later...

from collective.ploneboard.

datakurre avatar datakurre commented on July 18, 2024

@tisto I recall, I wrote it in an email when there was a GSOC project for this :-)

Anyway, I tried to find all the relevant components (our actual use-case was attaching an audio file recorded with audiorecorderwidget...). Unfortunately, you need to translate venusianconfiguration into zcml:

  1. Schema with attachment field
  2. Browser layer for most of the required overrides
  3. Schema extender adapter to include attachment field in comment forms
  4. Some patch for comment rendering to include attachment download link with the comment (I decided to patch Comment.getText
  5. Patch Comment to allow restricted (browser) access to attachment to actually make the attachment download link work
  6. Patch Comment edit form to save the attachment (because Comment edit form is customized to not support extended schema)
class IAttachment(model.Schema):
    attachment = NamedBlobFile(
        title=_('Attachment'),
        required=False
    )


class ICommentWithAttachmentLayer(IDiscussionLayer):
    """Marker interface that defines a browser layer."""


@configure.adapter.factory()
@adapter(Interface, ICommentWithAttachmentLayer, CommentForm)
@implementer(IFormExtender)
class CommentWithAttachmentExtender(extensible.FormExtender):
    fields = Fields(IAttachment)

    def update(self):
        self.add(IAttachment, prefix='')


@configure.monkey.patch.replacement(
    description='Patch comment to render additional fields',
    class_='plone.app.discussion.comment.Comment',
    original='getText',
    preserveOriginal=True)
def getText(self, targetMimetype=None):
    if targetMimetype is not None:
        return self._old_getText(targetMimetype)

    output = self._old_getText(targetMimetype)

    # Get attachment file
    try:
        has_attachment = bool(aq_base(self).attachment)
    except AttributeError:
        return output
    if not has_attachment:
        return output

    if not isinstance(output, unicode):
        output = output.decode('utf-8', 'ignore')

    if output:
        output += u"""
<a 
       src="{0:s}/@@download/attachment/{1:s}">Attachment</a>
""".format(self.absolute_url(), self.audio.filename)
    else:
        output += u"""
<a 
       src="{0:s}/@@download/attachment/{1:s}">Attachment</a>
""".format(self.absolute_url(), self.attachment.filename)

    return output


# Patch Comment security to allow access for audio attachment
###

# a) The first option is to allow access or all sub objects, which means that
#    anyone, who can see the comment object, can see all its (non protected)
#    attributes
Comment.__allow_access_to_unprotected_subobjects__ = 1

# b) Would be to either provide __allow_access_to_unprotected_subobjects__
#    function with check for all possible fields or configure permission
#    for the audio field. Unfortunately, the permission on the field would
#    work only if the field value is acquisition aware, which NamedBlob
#    is not, and therefore the following would not work (and would also
#    prevent option a) from working by making the subobject protected.


class EditCommentWithAttachmentForm(EditCommentForm):
    def updateWidgets(self):
        super(EditCommentWithAttachmentForm, self).updateWidgets()
        self.widgets['attachment'].value = self.context.attachment

    def _redirect(self, target=''):
        super(EditAudioCommentForm, self)._redirect(target)

        can_edit = getSecurityManager().checkPermission(
            'Edit comments', self.context)
        mtool = getToolByName(self.context, 'portal_membership')
        if mtool.isAnonymousUser() or not can_edit:
            return

        data, errors = self.extractData()
        if errors:
            return

        # Update audio
        self.context.attachment = data['attachment']


@configure.browser.page.class_(
    for_=IComment,
    name='edit-comment',
    layer=ICommentWithAttachmentLayer,
    permission='plone.app.discussion.EditComments')
class EditCommentWithAttachmentFormView(FormWrapper):
    form = EditCommentWithAttachmentForm

from collective.ploneboard.

datakurre avatar datakurre commented on July 18, 2024

You were already close then :) And security model being the issue is just a good thing.

from collective.ploneboard.

Related Issues (8)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.