Ejemplo n.º 1
0
    def test_dict_operations(self):
        # test dict operations and acquisition wrapping

        # Create a conversation. In this case we doesn't assign it to an
        # object, as we just want to check the Conversation object API.
        conversation = IConversation(self.portal.doc1)

        # Add a comment. Note: in real life, we always create comments via the
        # factory to allow different factories to be swapped in

        comment1 = createObject('plone.Comment')
        comment1.text = 'Comment text'

        new_id1 = conversation.addComment(comment1)

        comment2 = createObject('plone.Comment')
        comment2.text = 'Comment text'

        new_id2 = conversation.addComment(comment2)

        # check if get returns a comment object, and None if the key
        # can not be found
        self.assertTrue(IComment.providedBy(conversation.get(new_id1)))
        self.assertTrue(IComment.providedBy(conversation.get(new_id2)))
        self.assertEqual(conversation.get(123), None)

        # check if keys return the ids of all comments
        self.assertEqual(len(conversation.keys()), 2)
        self.assertTrue(new_id1 in conversation.keys())
        self.assertTrue(new_id2 in conversation.keys())
        self.assertFalse(123 in conversation.keys())

        # check if items returns (key, comment object) pairs
        self.assertEqual(len(conversation.items()), 2)
        self.assertTrue((new_id1, comment1) in conversation.items())
        self.assertTrue((new_id2, comment2) in conversation.items())

        # check if values returns the two comment objects
        self.assertEqual(len(conversation.values()), 2)
        self.assertTrue(comment1 in conversation.values())
        self.assertTrue(comment2 in conversation.values())

        # check if comment ids are in iterkeys
        self.assertTrue(new_id1 in conversation.iterkeys())
        self.assertTrue(new_id2 in conversation.iterkeys())
        self.assertFalse(123 in conversation.iterkeys())

        # check if comment objects are in itervalues
        self.assertTrue(comment1 in conversation.itervalues())
        self.assertTrue(comment2 in conversation.itervalues())

        # check if iteritems returns (key, comment object) pairs
        self.assertTrue((new_id1, comment1) in conversation.iteritems())
        self.assertTrue((new_id2, comment2) in conversation.iteritems())
    def test_dict_operations(self):
        # test dict operations and acquisition wrapping

        # Create a conversation. In this case we doesn't assign it to an
        # object, as we just want to check the Conversation object API.
        conversation = IConversation(self.portal.doc1)

        # Add a comment. Note: in real life, we always create comments via the
        # factory to allow different factories to be swapped in

        comment1 = createObject('plone.Comment')
        comment1.text = 'Comment text'

        new_id1 = conversation.addComment(comment1)

        comment2 = createObject('plone.Comment')
        comment2.text = 'Comment text'

        new_id2 = conversation.addComment(comment2)

        # check if get returns a comment object, and None if the key
        # can not be found
        self.assertTrue(IComment.providedBy(conversation.get(new_id1)))
        self.assertTrue(IComment.providedBy(conversation.get(new_id2)))
        self.assertEqual(conversation.get(123), None)

        # check if keys return the ids of all comments
        self.assertEqual(len(conversation.keys()), 2)
        self.assertTrue(new_id1 in conversation.keys())
        self.assertTrue(new_id2 in conversation.keys())
        self.assertFalse(123 in conversation.keys())

        # check if items returns (key, comment object) pairs
        self.assertEqual(len(conversation.items()), 2)
        self.assertTrue((new_id1, comment1) in conversation.items())
        self.assertTrue((new_id2, comment2) in conversation.items())

        # check if values returns the two comment objects
        self.assertEqual(len(conversation.values()), 2)
        self.assertTrue(comment1 in conversation.values())
        self.assertTrue(comment2 in conversation.values())

        # check if comment ids are in iterkeys
        self.assertTrue(new_id1 in conversation.iterkeys())
        self.assertTrue(new_id2 in conversation.iterkeys())
        self.assertFalse(123 in conversation.iterkeys())

        # check if comment objects are in itervalues
        self.assertTrue(comment1 in conversation.itervalues())
        self.assertTrue(comment2 in conversation.itervalues())

        # check if iteritems returns (key, comment object) pairs
        self.assertTrue((new_id1, comment1) in conversation.iteritems())
        self.assertTrue((new_id2, comment2) in conversation.iteritems())
Ejemplo n.º 3
0
    def handleComment(self, action):
        context = aq_inner(self.context)

        # Check if conversation is enabled on this content object
        if not self.__parent__.restrictedTraverse(
                '@@conversation_view').enabled():
            raise Unauthorized(
                'Discussion is not enabled for this content object.')

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

        # Validate Captcha
        registry = queryUtility(IRegistry)
        settings = registry.forInterface(IDiscussionSettings, check=False)
        portal_membership = getToolByName(self.context, 'portal_membership')
        captcha_enabled = settings.captcha != 'disabled'
        anonymous_comments = settings.anonymous_comments
        anon = portal_membership.isAnonymousUser()
        if captcha_enabled and anonymous_comments and anon:
            if 'captcha' not in data:
                data['captcha'] = u''
            captcha = CaptchaValidator(self.context, self.request, None,
                                       ICaptcha['captcha'], None)
            captcha.validate(data['captcha'])

        # Create comment
        comment = self.create_comment(data)

        # Add comment to conversation
        conversation = IConversation(self.__parent__)
        if data['in_reply_to']:
            # Add a reply to an existing comment
            conversation_to_reply_to = conversation.get(data['in_reply_to'])
            replies = IReplies(conversation_to_reply_to)
            comment_id = replies.addComment(comment)
        else:
            # Add a comment to the conversation
            comment_id = conversation.addComment(comment)

        # Redirect after form submit:
        # If a user posts a comment and moderation is enabled, a message is
        # shown to the user that his/her comment awaits moderation. If the user
        # has 'review comments' permission, he/she is redirected directly
        # to the comment.
        can_review = getSecurityManager().checkPermission(
            'Review comments', context)
        workflowTool = getToolByName(context, 'portal_workflow')
        comment_review_state = workflowTool.getInfoFor(comment, 'review_state',
                                                       None)
        if comment_review_state == 'pending' and not can_review:
            # Show info message when comment moderation is enabled
            IStatusMessage(self.context.REQUEST).addStatusMessage(
                _('Your comment awaits moderator approval.'), type='info')
            self.request.response.redirect(self.action)
        else:
            # Redirect to comment (inside a content object page)
            self.request.response.redirect(self.action + '#' + str(comment_id))
Ejemplo n.º 4
0
    def handleComment(self, action):
        context = aq_inner(self.context)

        # Check if conversation is enabled on this content object
        if not self.__parent__.restrictedTraverse(
            '@@conversation_view').enabled():
            raise Unauthorized("Discussion is not enabled for this content "
                               "object.")

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

        # Validate Captcha
        registry = queryUtility(IRegistry)
        settings = registry.forInterface(IDiscussionSettings, check=False)
        portal_membership = getToolByName(self.context, 'portal_membership')
        if settings.captcha != 'disabled' and \
        settings.anonymous_comments and \
        portal_membership.isAnonymousUser():
            if not 'captcha' in data:
                data['captcha'] = u""
            captcha = CaptchaValidator(self.context,
                                       self.request,
                                       None,
                                       ICaptcha['captcha'],
                                       None)
            captcha.validate(data['captcha'])

        # some attributes are not always set
        author_name = u""

        # Create comment
        comment = createObject('plone.Comment')

        # Set comment mime type to current setting in the discussion registry
        comment.mime_type = settings.text_transform

        # Set comment attributes (including extended comment form attributes)
        for attribute in self.fields.keys():
            setattr(comment, attribute, data[attribute])
        # Make sure author_name is properly encoded
        if 'author_name' in data:
            author_name = data['author_name']
            if isinstance(author_name, str):
                author_name = unicode(author_name, 'utf-8')

        # Set comment author properties for anonymous users or members
        can_reply = getSecurityManager().checkPermission('Reply to item',
                                                         context)
        portal_membership = getToolByName(self.context, 'portal_membership')
        if portal_membership.isAnonymousUser() and \
           settings.anonymous_comments:
            # Anonymous Users
            comment.author_name = author_name
            comment.author_email = u""
            comment.user_notification = None
            comment.creation_date = datetime.utcnow()
            comment.modification_date = datetime.utcnow()
        elif not portal_membership.isAnonymousUser() and can_reply:
            # Member
            member = portal_membership.getAuthenticatedMember()
            username = member.getUserName()
            email = member.getProperty('email')
            fullname = member.getProperty('fullname')
            if not fullname or fullname == '':
                fullname = member.getUserName()
            # memberdata is stored as utf-8 encoded strings
            elif isinstance(fullname, str):
                fullname = unicode(fullname, 'utf-8')
            if email and isinstance(email, str):
                email = unicode(email, 'utf-8')
            comment.creator = username
            comment.author_username = username
            comment.author_name = fullname
            comment.author_email = email
            comment.creation_date = datetime.utcnow()
            comment.modification_date = datetime.utcnow()
        else:  # pragma: no cover
            raise Unauthorized("Anonymous user tries to post a comment, but "
                "anonymous commenting is disabled. Or user does not have the "
                "'reply to item' permission.")

        # Add comment to conversation
        conversation = IConversation(self.__parent__)
        if data['in_reply_to']:
            # Add a reply to an existing comment
            conversation_to_reply_to = conversation.get(data['in_reply_to'])
            replies = IReplies(conversation_to_reply_to)
            comment_id = replies.addComment(comment)
        else:
            # Add a comment to the conversation
            comment_id = conversation.addComment(comment)

        # Redirect after form submit:
        # If a user posts a comment and moderation is enabled, a message is
        # shown to the user that his/her comment awaits moderation. If the user
        # has 'review comments' permission, he/she is redirected directly
        # to the comment.
        can_review = getSecurityManager().checkPermission('Review comments',
                                                          context)
        workflowTool = getToolByName(context, 'portal_workflow')
        comment_review_state = workflowTool.getInfoFor(
            comment, 
            'review_state', 
            None
        )
        if comment_review_state == 'pending' and not can_review:
            # Show info message when comment moderation is enabled
            IStatusMessage(self.context.REQUEST).addStatusMessage(
                _("Your comment awaits moderator approval."),
                type="info")
            self.request.response.redirect(self.action)
        else:
            # Redirect to comment (inside a content object page)
            self.request.response.redirect(self.action + '#' + str(comment_id))
Ejemplo n.º 5
0
    def __call__(self, site, msg):
        recipient = email.Utils.parseaddr(msg.get('To'))[1]

        settings = getSettings()
        if settings is None or settings.sender is None:
            # Cannot handle email unless we have a dedicated address for it
            return False 

        if recipient.lower() != settings.sender.strip().lower():
            # It is not addressed to us
            return False

        sender = msg.get('From')
        sender = email.Utils.parseaddr(sender)[1].lower()

        # Drop privileges to the right user
        acl_users = getToolByName(site, 'acl_users')
        pm = getToolByName(site, 'portal_membership')
        props = getToolByName(site, 'portal_properties').site_properties
        user = None
        if props.getProperty('use_email_as_login'):
            # If email logins are used, the user's email might be his id
            user = pm.getMemberById(sender)
            if user is not None:
                if user.getProperty('email') == sender:
                    user = user.getUser()
                else:
                    user = None

        if user is None:
            potential = pm.searchMembers('email', sender)
            # Email might match more than one user, check for exact match
            for u in potential:
                if sender == u['email']:
                    user = pm.getMemberById(u['username']).getUser()
                    break

        if user is None:
            raise NotFoundError(_("Sender is not a valid user"))

        newSecurityManager(None, user.__of__(acl_users))

        # Find relevant comment
        subject = msg.get('subject', '').strip()
        if not subject:
            raise NotFoundError(_("Subject is blank"))

        subject = decodeheader(subject)
        pat = re.compile('[^[]*\[([^#]+)(#([^\]]+))?\]')
        m = pat.match(subject)
        if m is None:
            raise NotFoundError(_("Unable to match a question"))
        
        questionid = m.groups()[0]
        commentid = m.groups()[2] # Might be None

        question = uuidToObject(questionid)
        if question is None:
            raise NotFoundError(_("Unable to match a question"))

        can_reply = getSecurityManager().checkPermission(
            'Reply to item', question)

        if not can_reply:
            raise PermissionError(_("Insufficient privileges"))

        comment = createObject('plone.Comment')

        member = pm.getAuthenticatedMember()
        address = member.getProperty('email')
        fullname = member.getProperty('fullname')
        if not fullname or fullname == '':
            fullname = member.getUserName()
        elif isinstance(fullname, str):
            fullname = unicode(fullname, 'utf-8')

        if address and isinstance(address, str):
            address = unicode(address, 'utf-8')

        comment.creator = member.getUserName()
        comment.author_username = comment.creator
        comment.author_name = fullname
        comment.author_email = address
        comment.creation_date = datetime.utcnow()
        comment.modification_date = comment.creation_date

        # Walk the message and get the inline component
        for part in msg.walk():
            if part.is_multipart():
                # Ignore multipart envelope if it exists
                continue
            if part.get_filename() is not None:
                # Ignore attachments
                continue

            content_type = part.get_content_type()

            if content_type not in ('text/plain', 'text/html'):
                # Skip non text/html parts
                continue

            payload = part.get_payload(decode=1)
            if content_type == 'text/html':
                transforms = getToolByName(site, 'portal_transforms')
                transform = transforms.convertTo('text/plain',
                    payload, context=site, mimetype='text/html')
                if transform:
                    payload = transform.getData().strip()
                else:
                    raise PermanentError(_(u"Could not convert html email"))

            comment.text = payload.strip()
            break # Get out of the for loop

        # Add comment to conversation
        conversation = IConversation(question)
        if commentid is not None:
            # Add a reply to an existing comment
            conversation_to_reply_to = conversation.get(commentid)
            replies = IReplies(conversation_to_reply_to)
            comment_id = replies.addComment(comment)
        else:
            # Add a comment to the conversation
            comment_id = conversation.addComment(comment)

        return True
Ejemplo n.º 6
0
    def handleComment(self, action):
        context = aq_inner(self.context)

        # Check if conversation is enabled on this content object
        if not self.__parent__.restrictedTraverse(
            '@@conversation_view',
        ).enabled():
            raise Unauthorized(
                'Discussion is not enabled for this content object.',
            )

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

        # Validate Captcha
        registry = queryUtility(IRegistry)
        settings = registry.forInterface(IDiscussionSettings, check=False)
        portal_membership = getToolByName(self.context, 'portal_membership')
        captcha_enabled = settings.captcha != 'disabled'
        anonymous_comments = settings.anonymous_comments
        anon = portal_membership.isAnonymousUser()
        if captcha_enabled and anonymous_comments and anon:
            if 'captcha' not in data:
                data['captcha'] = u''
            captcha = CaptchaValidator(self.context,
                                       self.request,
                                       None,
                                       ICaptcha['captcha'],
                                       None)
            captcha.validate(data['captcha'])

        # Create comment
        comment = self.create_comment(data)

        # Add comment to conversation
        conversation = IConversation(self.__parent__)
        if data['in_reply_to']:
            # Add a reply to an existing comment
            conversation_to_reply_to = conversation.get(data['in_reply_to'])
            replies = IReplies(conversation_to_reply_to)
            comment_id = replies.addComment(comment)
        else:
            # Add a comment to the conversation
            comment_id = conversation.addComment(comment)

        # Redirect after form submit:
        # If a user posts a comment and moderation is enabled, a message is
        # shown to the user that his/her comment awaits moderation. If the user
        # has 'review comments' permission, he/she is redirected directly
        # to the comment.
        can_review = getSecurityManager().checkPermission('Review comments',
                                                          context)
        workflowTool = getToolByName(context, 'portal_workflow')
        comment_review_state = workflowTool.getInfoFor(
            comment,
            'review_state',
            None,
        )
        if comment_review_state == 'pending' and not can_review:
            # Show info message when comment moderation is enabled
            IStatusMessage(self.context.REQUEST).addStatusMessage(
                _('Your comment awaits moderator approval.'),
                type='info')
            self.request.response.redirect(self.action)
        else:
            # Redirect to comment (inside a content object page)
            self.request.response.redirect(self.action + '#' + str(comment_id))
Ejemplo n.º 7
0
    def handleComment(self, action):
        context = aq_inner(self.context)

        # Check if conversation is enabled on this content object
        if not self.__parent__.restrictedTraverse(
                '@@conversation_view').enabled():
            raise Unauthorized("Discussion is not enabled for this content "
                               "object.")

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

        # Validate Captcha
        registry = queryUtility(IRegistry)
        settings = registry.forInterface(IDiscussionSettings, check=False)
        portal_membership = getToolByName(self.context, 'portal_membership')
        if settings.captcha != 'disabled' and \
        settings.anonymous_comments and \
        portal_membership.isAnonymousUser():
            if not 'captcha' in data:
                data['captcha'] = u""
            captcha = CaptchaValidator(self.context, self.request, None,
                                       ICaptcha['captcha'], None)
            captcha.validate(data['captcha'])

        # some attributes are not always set
        author_name = u""

        # Create comment
        comment = createObject('plone.Comment')

        # Set comment mime type to current setting in the discussion registry
        comment.mime_type = settings.text_transform

        # Set comment attributes (including extended comment form attributes)
        for attribute in self.fields.keys():
            setattr(comment, attribute, data[attribute])
        # Make sure author_name is properly encoded
        if 'author_name' in data:
            author_name = data['author_name']
            if isinstance(author_name, str):
                author_name = unicode(author_name, 'utf-8')

        # Set comment author properties for anonymous users or members
        can_reply = getSecurityManager().checkPermission(
            'Reply to item', context)
        portal_membership = getToolByName(self.context, 'portal_membership')
        if portal_membership.isAnonymousUser() and \
           settings.anonymous_comments:
            # Anonymous Users
            comment.author_name = author_name
            comment.author_email = u""
            comment.user_notification = None
            comment.creation_date = datetime.utcnow()
            comment.modification_date = datetime.utcnow()
        elif not portal_membership.isAnonymousUser() and can_reply:
            # Member
            member = portal_membership.getAuthenticatedMember()
            username = member.getUserName()
            email = member.getProperty('email')
            fullname = member.getProperty('fullname')
            if not fullname or fullname == '':
                fullname = member.getUserName()
            # memberdata is stored as utf-8 encoded strings
            elif isinstance(fullname, str):
                fullname = unicode(fullname, 'utf-8')
            if email and isinstance(email, str):
                email = unicode(email, 'utf-8')
            comment.creator = username
            comment.author_username = username
            comment.author_name = fullname
            comment.author_email = email
            comment.creation_date = datetime.utcnow()
            comment.modification_date = datetime.utcnow()
        else:  # pragma: no cover
            raise Unauthorized(
                "Anonymous user tries to post a comment, but "
                "anonymous commenting is disabled. Or user does not have the "
                "'reply to item' permission.")

        # Add comment to conversation
        conversation = IConversation(self.__parent__)
        if data['in_reply_to']:
            # Add a reply to an existing comment
            conversation_to_reply_to = conversation.get(data['in_reply_to'])
            replies = IReplies(conversation_to_reply_to)
            comment_id = replies.addComment(comment)
        else:
            # Add a comment to the conversation
            comment_id = conversation.addComment(comment)

        # Redirect after form submit:
        # If a user posts a comment and moderation is enabled, a message is
        # shown to the user that his/her comment awaits moderation. If the user
        # has 'review comments' permission, he/she is redirected directly
        # to the comment.
        can_review = getSecurityManager().checkPermission(
            'Review comments', context)
        workflowTool = getToolByName(context, 'portal_workflow')
        comment_review_state = workflowTool.getInfoFor(comment, 'review_state')
        if comment_review_state == 'pending' and not can_review:
            # Show info message when comment moderation is enabled
            IStatusMessage(self.context.REQUEST).addStatusMessage(
                _("Your comment awaits moderator approval."), type="info")
            self.request.response.redirect(self.action)
        else:
            # Redirect to comment (inside a content object page)
            self.request.response.redirect(self.action + '#' + str(comment_id))