Beispiel #1
0
    def test_sendsimplemail_with_disabled_user(self):
        c.user = M.User.by_username('test-admin')
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendsimplemail(fromaddr=str(c.user._id),
                                      toaddr='*****@*****.**',
                                      text=u'This is a test',
                                      reply_to=g.noreply,
                                      subject=u'Test subject',
                                      message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: "Test Admin" <*****@*****.**>', body)

            c.user.disabled = True
            ThreadLocalORMSession.flush_all()
            mail_tasks.sendsimplemail(fromaddr=str(c.user._id),
                                      toaddr='*****@*****.**',
                                      text=u'This is a test',
                                      reply_to=g.noreply,
                                      subject=u'Test subject',
                                      message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 2)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: %s' % g.noreply, body)
Beispiel #2
0
    def test_email_sender_to_headers(self):
        c.user = M.User.by_username('test-admin')
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendsimplemail(fromaddr=str(c.user._id),
                                      toaddr='*****@*****.**',
                                      text=u'This is a test',
                                      reply_to=g.noreply,
                                      subject=u'Test subject',
                                      sender=u'*****@*****.**',
                                      message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: "Test Admin" <*****@*****.**>', body)
            assert_in('Sender: [email protected]', body)
            assert_in('To: [email protected]', body)

            _client.reset_mock()
            mail_tasks.sendmail(fromaddr=str(c.user._id),
                                destinations=[str(c.user._id)],
                                text=u'This is a test',
                                reply_to=u'*****@*****.**',
                                subject=u'Test subject',
                                sender=u'*****@*****.**',
                                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: "Test Admin" <*****@*****.**>', body)
            assert_in('Sender: [email protected]', body)
            assert_in('To: [email protected]', body)
Beispiel #3
0
    def test_email_references_header(self):
        c.user = M.User.by_username('test-admin')
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendsimplemail(fromaddr=str(c.user._id),
                                      toaddr='*****@*****.**',
                                      text=u'This is a test',
                                      reply_to=g.noreply,
                                      subject=u'Test subject',
                                      references=['a', 'b', 'c'],
                                      message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: "Test Admin" <*****@*****.**>', body)
            assert_in('References: <a> <b> <c>', body)

            _client.reset_mock()
            mail_tasks.sendmail(fromaddr=str(c.user._id),
                                destinations=[str(c.user._id)],
                                text=u'This is a test',
                                reply_to=g.noreply,
                                subject=u'Test subject',
                                references=u'ref',
                                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: "Test Admin" <*****@*****.**>', body)
            assert_in('References: <ref>', body)
Beispiel #4
0
    def test_sendsimplemail_with_disabled_user(self):
        c.user = M.User.by_username('test-admin')
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendsimplemail(
                fromaddr=str(c.user._id),
                toaddr='*****@*****.**',
                text=u'This is a test',
                reply_to=g.noreply,
                subject=u'Test subject',
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: "Test Admin" <*****@*****.**>', body)

            c.user.disabled = True
            ThreadLocalORMSession.flush_all()
            mail_tasks.sendsimplemail(
                fromaddr=str(c.user._id),
                toaddr='*****@*****.**',
                text=u'This is a test',
                reply_to=g.noreply,
                subject=u'Test subject',
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 2)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: %s' % g.noreply, body)
Beispiel #5
0
    def test_email_references_header(self):
        c.user = M.User.by_username('test-admin')
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendsimplemail(
                fromaddr=str(c.user._id),
                toaddr='*****@*****.**',
                text=u'This is a test',
                reply_to=g.noreply,
                subject=u'Test subject',
                references=['a', 'b', 'c'],
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: "Test Admin" <*****@*****.**>', body)
            assert_in('References: <a> <b> <c>', body)

            _client.reset_mock()
            mail_tasks.sendmail(
                fromaddr=str(c.user._id),
                destinations=[str(c.user._id)],
                text=u'This is a test',
                reply_to=g.noreply,
                subject=u'Test subject',
                references=u'ref',
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: "Test Admin" <*****@*****.**>', body)
            assert_in('References: <ref>', body)
Beispiel #6
0
    def test_email_sender_to_headers(self):
        c.user = M.User.by_username('test-admin')
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendsimplemail(
                fromaddr=str(c.user._id),
                toaddr='*****@*****.**',
                text=u'This is a test',
                reply_to=g.noreply,
                subject=u'Test subject',
                sender=u'*****@*****.**',
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: "Test Admin" <*****@*****.**>', body)
            assert_in('Sender: [email protected]', body)
            assert_in('To: [email protected]', body)

            _client.reset_mock()
            mail_tasks.sendmail(
                fromaddr=str(c.user._id),
                destinations=[str(c.user._id)],
                text=u'This is a test',
                reply_to=u'*****@*****.**',
                subject=u'Test subject',
                sender=u'*****@*****.**',
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')
            assert_in('From: "Test Admin" <*****@*****.**>', body)
            assert_in('Sender: [email protected]', body)
            assert_in('To: [email protected]', body)
Beispiel #7
0
def clone(
    cloned_from_path,
    cloned_from_name,
    cloned_from_url,
    copy_hooks=False):
    try:
        from allura import model as M
        c.app.repo.init_as_clone(
            cloned_from_path,
            cloned_from_name,
            cloned_from_url,
            copy_hooks)
        M.Notification.post_user(
            c.user, c.app.repo, 'created',
            text='Repository %s/%s created' % (
                c.project.shortname, c.app.config.options.mount_point))
        if not c.project.suppress_emails:
            sendmail(
                destinations=[str(c.user._id)],
                fromaddr=u'SourceForge.net <*****@*****.**>',
                reply_to=u'*****@*****.**',
                subject=u'SourceForge Repo Clone Complete',
                message_id=h.gen_message_id(),
                text=u''.join([
                    u'Your cloned repository %s in project %s is now ready for use.\n\n',
                    u'Old repository url: %s \n\n',
                    u'New repository checkout command: %s \n\n',
                    u'You and any other developers should do a fresh checkout using the ',
                    u'new repository location.\n'
                ]) % (c.app.config.options.mount_point, c.project.shortname, cloned_from_url, c.app.repo.clone_command('rw')))
    except:
        sendmail(
            destinations=['*****@*****.**'],
            fromaddr=u'SourceForge.net <*****@*****.**>',
            reply_to=u'*****@*****.**',
            subject=u'SourceForge Repo Clone Failure',
            message_id=h.gen_message_id(),
            text=u''.join([
                u'Forking/cloning repo %s in project %s from %s failed.\n',
                u'\n',
                u'%s',
            ]) % (c.app.config.options.mount_point, c.project.shortname, cloned_from_url, traceback.format_exc()))
        if not c.project.suppress_emails:
            sendmail(
                destinations=[str(c.user._id)],
                fromaddr=u'SourceForge.net <*****@*****.**>',
                reply_to=u'*****@*****.**',
                subject=u'SourceForge Repo Clone Failed',
                message_id=h.gen_message_id(),
                text=u''.join([
                    u'Forking/cloning repo %s in project %s from %s failed. ',
                    u'The SourceForge engineering team has been notified.\n',
                ]) % (c.app.config.options.mount_point, c.project.shortname, cloned_from_url))
Beispiel #8
0
    def send_digest(self, user_id, from_address, subject, notifications,
                    reply_to_address=None):
        if not notifications: return
        user = User.query.get(_id=ObjectId(user_id), disabled=False)
        if not user:
            log.debug("Skipping notification - enabled user %s not found " % user_id)
            return
        # Filter out notifications for which the user doesn't have read
        # permissions to the artifact.
        artifact = self.ref.artifact
        def perm_check(notification):
            return not (user and artifact) or \
                    security.has_access(artifact, 'read', user)()
        notifications = filter(perm_check, notifications)

        log.debug('Sending digest of notifications [%s] to user %s', ', '.join([n._id for n in notifications]), user_id)
        if reply_to_address is None:
            reply_to_address = from_address
        text = [ 'Digest of %s' % subject ]
        for n in notifications:
            text.append('From: %s' % n.from_address)
            text.append('Subject: %s' % (n.subject or '(no subject)'))
            text.append('Message-ID: %s' % n._id)
            text.append('')
            text.append(n.text or '-no text-')
        text.append(n.footer())
        text = '\n'.join(text)
        allura.tasks.mail_tasks.sendmail.post(
            destinations=[str(user_id)],
            fromaddr=from_address,
            reply_to=reply_to_address,
            subject=subject,
            message_id=h.gen_message_id(),
            text=text)
Beispiel #9
0
    def test_send_email_nonascii(self):
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendmail(fromaddr=u'"По" <*****@*****.**>',
                                destinations=['*****@*****.**'],
                                text=u'Громады стройные теснятся',
                                reply_to=g.noreply,
                                subject=u'По оживлённым берегам',
                                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')

            assert_equal(rcpts, ['*****@*****.**'])
            assert_in('Reply-To: %s' % g.noreply, body)

            # The address portion must not be encoded, only the name portion can be.
            # Also it is apparently not necessary to have the double-quote separators present
            # when the name portion is encoded.  That is, the encoding below is
            # just По and not "По"
            assert_in('From: =?utf-8?b?0J/Qvg==?= <*****@*****.**>', body)
            assert_in(
                'Subject: =?utf-8?b?0J/QviDQvtC20LjQstC70ZHQvdC90YvQvCDQsdC10YDQtdCz0LDQvA==?=',
                body)
            assert_in('Content-Type: text/plain; charset="utf-8"', body)
            assert_in('Content-Transfer-Encoding: base64', body)
            assert_in(b64encode(u'Громады стройные теснятся'.encode('utf-8')),
                      body)
Beispiel #10
0
 def post(self,
          text,
          message_id=None,
          parent_id=None,
          timestamp=None,
          ignore_security=False,
          **kw):
     if not ignore_security:
         require_access(self, 'post')
     if self.ref_id and self.artifact:
         self.artifact.subscribe()
     if message_id is None:
         message_id = h.gen_message_id()
     parent = parent_id and self.post_class().query.get(_id=parent_id)
     slug, full_slug = self.post_class().make_slugs(parent, timestamp)
     kwargs = dict(discussion_id=self.discussion_id,
                   full_slug=full_slug,
                   slug=slug,
                   thread_id=self._id,
                   parent_id=parent_id,
                   text=text,
                   status='pending')
     if timestamp is not None:
         kwargs['timestamp'] = timestamp
     if message_id is not None:
         kwargs['_id'] = message_id
     post = self.post_class()(**kwargs)
     if ignore_security or not self.is_spam(post) and has_access(
             self, 'unmoderated_post')():
         log.info('Auto-approving message from %s', c.user.username)
         file_info = kw.get('file_info', None)
         post.approve(file_info, notify=kw.get('notify', True))
     else:
         self.notify_moderators(post)
     return post
Beispiel #11
0
    def test_send_email_nonascii(self):
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendmail(
                fromaddr='"По" <*****@*****.**>',
                destinations=['*****@*****.**'],
                text='Громады стройные теснятся',
                reply_to=g.noreply,
                subject='По оживлённым берегам',
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')

            assert_equal(rcpts, ['*****@*****.**'])
            assert_in('Reply-To: %s' % g.noreply, body)

            # The address portion must not be encoded, only the name portion can be.
            # Also py2 and py3 vary in handling of double-quote separators when the name portion is encoded
            unquoted_cyrillic_No = '=?utf-8?b?0J/Qvg==?='  # По
            quoted_cyrillic_No = '=?utf-8?b?ItCf0L4i?='  # "По"
            assert ('From: {} <*****@*****.**>'.format(quoted_cyrillic_No) in body or
                    'From: {} <*****@*****.**>'.format(unquoted_cyrillic_No) in body), body
            assert_in(
                'Subject: =?utf-8?b?0J/QviDQvtC20LjQstC70ZHQvdC90YvQvCDQsdC10YDQtdCz0LDQvA==?=', body)
            assert_in('Content-Type: text/plain; charset="utf-8"', body)
            assert_in('Content-Transfer-Encoding: base64', body)
            assert_in(six.ensure_text(b64encode('Громады стройные теснятся'.encode('utf-8'))), body)
Beispiel #12
0
def send_system_mail_to_user(user_or_emailaddr, subject, text):
    '''
    Sends a standard email from the Allura system itself, to a user.
    This is a helper function around sendsimplemail() that generates a new task

    :param user_or_emailaddr: an email address (str) or a User object
    :param subject: subject of the email
    :param text: text of the email (markdown)
    '''
    if isinstance(user_or_emailaddr, basestring):
        toaddr = user_or_emailaddr
    else:
        toaddr = user_or_emailaddr._id

    email = {
        'toaddr': toaddr,
        'fromaddr': u'"{}" <{}>'.format(
            config['site_name'],
            config['forgemail.return_path']
        ),
        'sender': unicode(config['forgemail.return_path']),
        'reply_to': unicode(config['forgemail.return_path']),
        'message_id': h.gen_message_id(),
        'subject': subject,
        'text': text,
    }
    sendsimplemail.post(**email)
Beispiel #13
0
    def test_send_email_long_lines_use_quoted_printable(self):
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendsimplemail(fromaddr=u'"По" <*****@*****.**>',
                                      toaddr='*****@*****.**',
                                      text=(u'0123456789' * 100) + u'\n\n' +
                                      (u'Громады стро ' * 100),
                                      reply_to=g.noreply,
                                      subject=u'По оживлённым берегам',
                                      message_id=h.gen_message_id())
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')

            for line in body:
                assert_less(len(line), 991)

            # plain text
            assert_in(
                '012345678901234567890123456789012345678901234567890123456789012345678901234=',
                body)
            assert_in(
                '=D0=93=D1=80=D0=BE=D0=BC=D0=B0=D0=B4=D1=8B =D1=81=D1=82=D1=80=D0=BE =D0=93=',
                body)
            # html
            assert_in(
                '<div class=3D"markdown_content"><p>0123456789012345678901234567890123456789=',
                body)
            assert_in(
                '<p>=D0=93=D1=80=D0=BE=D0=BC=D0=B0=D0=B4=D1=8B =D1=81=D1=82=D1=80=D0=BE =D0=',
                body)
    def send_digest(self, user_id, from_address, subject, notifications,
                    reply_to_address=None):
        if not notifications: return
        user = User.query.get(_id=ObjectId(user_id), disabled=False)
        if not user:
            log.debug("Skipping notification - enabled user %s not found " % user_id)
            return
        # Filter out notifications for which the user doesn't have read
        # permissions to the artifact.
        artifact = self.ref.artifact
        def perm_check(notification):
            return not (user and artifact) or \
                    security.has_access(artifact, 'read', user)()
        notifications = filter(perm_check, notifications)

        log.debug('Sending digest of notifications [%s] to user %s', ', '.join([n._id for n in notifications]), user_id)
        if reply_to_address is None:
            reply_to_address = from_address
        text = [ 'Digest of %s' % subject ]
        for n in notifications:
            text.append('From: %s' % n.from_address)
            text.append('Subject: %s' % (n.subject or '(no subject)'))
            text.append('Message-ID: %s' % n._id)
            text.append('')
            text.append(n.text or '-no text-')
        text.append(n.footer())
        text = '\n'.join(text)
        allura.tasks.mail_tasks.sendmail.post(
            destinations=[str(user_id)],
            fromaddr=from_address,
            reply_to=reply_to_address,
            subject=subject,
            message_id=h.gen_message_id(),
            text=text)
Beispiel #15
0
    def send_user_mention_notification(self, mentioned_by, artifact):
        """Send user mention notification to {self} user.

        """
        tmpl = g.jinja2_env.get_template('allura:templates/mail/usermentions_email.md')
        subject = '[%s:%s] Your name was mentioned' % (
            c.project.shortname, c.app.config.options.mount_point)
        item_url = artifact.url()
        if artifact.type_s == 'Post':
            item_url = artifact.url_paginated()
        tmpl_context = {
            'site_domain': config['domain'],
            'base_url': config['base_url'],
            'user': c.user,
            'artifact_link': h.absurl(item_url),
            'artifact_linktext': artifact.link_text(),
            'mentioned_by': mentioned_by
        }
        allura.tasks.mail_tasks.sendsimplemail.post(
            toaddr=self.get_pref('email_address'),
            fromaddr=g.noreply,
            reply_to=g.noreply,
            message_id=h.gen_message_id(),
            subject=subject,
            text=tmpl.render(tmpl_context))
Beispiel #16
0
    def password_recovery_hash(self, email=None, **kw):
        provider = plugin.AuthenticationProvider.get(request)
        if not provider.forgotten_password_process:
            raise wexc.HTTPNotFound()
        if not email:
            redirect('/')
        user_record = M.User.by_email_address(email)
        hash = h.nonce(42)
        user_record.set_tool_data('AuthPasswordReset',
                                  hash=hash,
                                  hash_expiry=datetime.datetime.utcnow() +
                                  datetime.timedelta(seconds=int(config.get('auth.recovery_hash_expiry_period', 600))))

        log.info('Sending password recovery link to %s', email)
        text = '''
To reset your password on %s, please visit the following URL:

%s/auth/forgotten_password/%s

''' % (config['site_name'], config['base_url'], hash)

        allura.tasks.mail_tasks.sendmail.post(
            destinations=[email],
            fromaddr=config['forgemail.return_path'],
            reply_to=config['forgemail.return_path'],
            subject='Password recovery',
            message_id=h.gen_message_id(),
            text=text)

        flash('Email with instructions has been sent.')
        redirect('/')
Beispiel #17
0
    def test_send_email_nonascii(self):
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendmail(
                fromaddr=u'"По" <*****@*****.**>',
                destinations=['*****@*****.**'],
                text=u'Громады стройные теснятся',
                reply_to=g.noreply,
                subject=u'По оживлённым берегам',
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')

            assert_equal(rcpts, ['*****@*****.**'])
            assert_in('Reply-To: %s' % g.noreply, body)

            # The address portion must not be encoded, only the name portion can be.
            # Also it is apparently not necessary to have the double-quote separators present
            # when the name portion is encoded.  That is, the encoding below is
            # just По and not "По"
            assert_in('From: =?utf-8?b?0J/Qvg==?= <*****@*****.**>', body)
            assert_in(
                'Subject: =?utf-8?b?0J/QviDQvtC20LjQstC70ZHQvdC90YvQvCDQsdC10YDQtdCz0LDQvA==?=', body)
            assert_in('Content-Type: text/plain; charset="utf-8"', body)
            assert_in('Content-Transfer-Encoding: base64', body)
            assert_in(
                b64encode(u'Громады стройные теснятся'.encode('utf-8')), body)
Beispiel #18
0
 def post(self, text, message_id=None, parent_id=None,
          timestamp=None, ignore_security=False, is_meta=False, **kw):
     if not ignore_security:
         require_access(self, 'post')
     if self.ref_id and self.artifact:
         self.artifact.subscribe()
     if message_id is None:
         message_id = h.gen_message_id()
     parent = parent_id and self.post_class().query.get(_id=parent_id)
     slug, full_slug = self.post_class().make_slugs(parent, timestamp)
     kwargs = dict(
         discussion_id=self.discussion_id,
         full_slug=full_slug,
         slug=slug,
         thread_id=self._id,
         parent_id=parent_id,
         text=text,
         status='pending',
         is_meta=is_meta)
     if timestamp is not None:
         kwargs['timestamp'] = timestamp
     if message_id is not None:
         kwargs['_id'] = message_id
     post = self.post_class()(**kwargs)
     if ignore_security or not self.is_spam(post) and has_access(self, 'unmoderated_post')():
         log.info('Auto-approving message from %s', c.user.username)
         file_info = kw.get('file_info', None)
         post.approve(file_info, notify=kw.get('notify', True))
     else:
         self.notify_moderators(post)
     return post
Beispiel #19
0
    def process(self,
                project,
                tools,
                user,
                filename=None,
                send_email=True,
                with_attachments=False):
        export_filename = filename or project.bulk_export_filename()
        export_path = self.get_export_path(project.bulk_export_path(),
                                           export_filename)
        if not os.path.exists(export_path):
            os.makedirs(export_path)
        apps = [project.app_instance(tool) for tool in tools]
        exportable = self.filter_exportable(apps)
        results = [
            self.export(export_path, app, with_attachments)
            for app in exportable
        ]
        exported = self.filter_successful(results)
        if exported:
            zipdir(export_path,
                   os.path.join(os.path.dirname(export_path), export_filename))
        shutil.rmtree(export_path)

        if not user:
            log.info('No user. Skipping notification.')
            return
        if not send_email:
            return

        tmpl = g.jinja2_env.get_template(
            'allura:templates/mail/bulk_export.html')
        instructions = tg.config.get('bulk_export_download_instructions', '')
        instructions = instructions.format(
            project=project.shortname,
            filename=export_filename,
            c=c,
        )
        exported_names = [a.config.options.mount_point for a in exported]
        tmpl_context = {
            'instructions': instructions,
            'project': project,
            'tools': exported_names,
            'not_exported_tools': list(set(tools) - set(exported_names)),
        }

        email = {
            'toaddr': unicode(user._id),
            'fromaddr': unicode(tg.config['forgemail.return_path']),
            'sender': unicode(tg.config['forgemail.return_path']),
            'reply_to': unicode(tg.config['forgemail.return_path']),
            'message_id': h.gen_message_id(),
            'subject':
            u'Bulk export for project %s completed' % project.shortname,
            'text': tmpl.render(tmpl_context)
        }

        mail_tasks.sendsimplemail.post(**email)
Beispiel #20
0
    def password_recovery_hash(self, email=None, **kw):
        provider = plugin.AuthenticationProvider.get(request)
        if not provider.forgotten_password_process:
            raise wexc.HTTPNotFound()
        if not email:
            redirect('/')

        user_record = M.User.by_email_address(email)
        allow_non_primary_email_reset = asbool(
            config.get('auth.allow_non_primary_email_password_reset', True))

        if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
            flash('Enter email in correct format!', 'error')
            redirect('/auth/forgotten_password')

        if not allow_non_primary_email_reset:
            message = 'If the given email address is on record, '\
                      'a password reset email has been sent to the account\'s primary email address.'
            email_record = M.EmailAddress.get(
                email=provider.get_primary_email_address(
                    user_record=user_record),
                confirmed=True)
        else:
            message = 'A password reset email has been sent, if the given email address is on record in our system.'
            email_record = M.EmailAddress.get(email=email, confirmed=True)

        if user_record and email_record and email_record.confirmed:
            hash = h.nonce(42)
            user_record.set_tool_data(
                'AuthPasswordReset',
                hash=hash,
                hash_expiry=datetime.datetime.utcnow() +
                datetime.timedelta(seconds=int(
                    config.get('auth.recovery_hash_expiry_period', 600))))

            log.info('Sending password recovery link to %s',
                     email_record.email)
            subject = '%s Password recovery' % config['site_name']
            text = g.jinja2_env.get_template(
                'allura:templates/mail/forgot_password.txt').render(
                    dict(
                        user=user_record,
                        config=config,
                        hash=hash,
                    ))

            allura.tasks.mail_tasks.sendsimplemail.post(
                toaddr=email_record.email,
                fromaddr=config['forgemail.return_path'],
                reply_to=config['forgemail.return_path'],
                subject=subject,
                message_id=h.gen_message_id(),
                text=text)
        h.auditlog_user('Password recovery link sent to: %s',
                        email,
                        user=user_record)
        flash(message)
        redirect('/')
Beispiel #21
0
    def post(self,
             text,
             message_id=None,
             parent_id=None,
             notify=True,
             notification_text=None,
             timestamp=None,
             ignore_security=False,
             is_meta=False,
             subscribe=False,
             **kw):
        if not ignore_security:
            require_access(self, 'post')
        if subscribe:
            self.primary().subscribe()
        if message_id is None:
            message_id = h.gen_message_id()
        parent = parent_id and self.post_class().query.get(_id=parent_id)
        slug, full_slug = self.post_class().make_slugs(parent, timestamp)
        kwargs = dict(discussion_id=self.discussion_id,
                      full_slug=full_slug,
                      slug=slug,
                      thread_id=self._id,
                      parent_id=parent_id,
                      text=text,
                      status='pending',
                      is_meta=is_meta)
        if timestamp is not None:
            kwargs['timestamp'] = timestamp
        if message_id is not None:
            kwargs['_id'] = message_id
        post = self.post_class()(**kwargs)

        if ignore_security or is_meta:
            spammy = False
        else:
            spammy = self.is_spam(post)
        # unmoderated post -> autoapprove
        # unmoderated post but is spammy -> don't approve it, it goes into moderation
        # moderated post -> moderation
        # moderated post but is spammy -> mark as spam
        if ignore_security or (not spammy
                               and has_access(self, 'unmoderated_post')):
            log.info('Auto-approving message from %s', c.user.username)
            file_info = kw.get('file_info', None)
            post.approve(file_info,
                         notify=notify,
                         notification_text=notification_text)
        elif not has_access(self, 'unmoderated_post') and spammy:
            post.spam(
                submit_spam_feedback=False
            )  # no feedback since we're marking as spam automatically not manually
        else:
            self.notify_moderators(post)
        return post
Beispiel #22
0
 def reply(self):
     new_id = h.gen_message_id()
     slug, full_slug = self.make_slugs(self)
     new_args = dict(state(self).document,
                     _id=new_id,
                     slug=slug,
                     full_slug=full_slug,
                     parent_id=self._id,
                     timestamp=datetime.utcnow(),
                     author_id=c.user._id)
     return self.__class__(**new_args)
Beispiel #23
0
 def _post_email(self, mailfrom, rcpttos, subject, msg):
     '''msg is MIME message object'''
     msg['Message-ID'] = '<' + h.gen_message_id() + '>'
     msg['From'] = mailfrom
     msg['To'] = ', '.join(rcpttos)
     msg['Subject'] = subject
     mail_tasks.route_email(peer='127.0.0.1',
                            mailfrom=mailfrom,
                            rcpttos=rcpttos,
                            data=msg.as_string())
     M.artifact_orm_session.flush()
 def _post_email(self, mailfrom, rcpttos, subject, msg):
     '''msg is MIME message object'''
     msg['Message-ID'] = '<' + h.gen_message_id() + '>'
     msg['From'] = mailfrom
     msg['To'] = ', '.join(rcpttos)
     msg['Subject'] = subject
     mail_tasks.route_email(
         peer='127.0.0.1',
         mailfrom=mailfrom,
         rcpttos=rcpttos,
         data=msg.as_string())
     M.artifact_orm_session.flush()
Beispiel #25
0
 def reply(self):
     new_id = h.gen_message_id()
     slug, full_slug = self.make_slugs(self)
     new_args = dict(
         state(self).document,
         _id=new_id,
         slug=slug,
         full_slug=full_slug,
         parent_id=self._id,
         timestamp=datetime.utcnow(),
         author_id=c.user._id)
     return self.__class__(**new_args)
Beispiel #26
0
 def test_fromaddr_objectid_not_str(self):
     c.user = M.User.by_username('test-admin')
     with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
         mail_tasks.sendsimplemail(fromaddr=c.user._id,
                                   toaddr='*****@*****.**',
                                   text=u'This is a test',
                                   reply_to=g.noreply,
                                   subject=u'Test subject',
                                   message_id=h.gen_message_id())
         assert_equal(_client.sendmail.call_count, 1)
         return_path, rcpts, body = _client.sendmail.call_args[0]
         assert_in('From: "Test Admin" <*****@*****.**>', body)
Beispiel #27
0
    def password_recovery_hash(self, email=None, **kw):
        provider = plugin.AuthenticationProvider.get(request)
        if not provider.forgotten_password_process:
            raise wexc.HTTPNotFound()
        if not email:
            redirect("/")

        user_record = M.User.by_email_address(email)
        allow_non_primary_email_reset = asbool(config.get("auth.allow_non_primary_email_password_reset", True))

        if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
            flash("Enter email in correct format!", "error")
            redirect("/auth/forgotten_password")

        if not allow_non_primary_email_reset:
            message = (
                "If the given email address is on record, "
                "a password reset email has been sent to the account's primary email address."
            )
            email_record = M.EmailAddress.get(
                email=provider.get_primary_email_address(user_record=user_record), confirmed=True
            )
        else:
            message = "A password reset email has been sent, if the given email address is on record in our system."
            email_record = M.EmailAddress.get(email=email, confirmed=True)

        if user_record and email_record and email_record.confirmed:
            hash = h.nonce(42)
            user_record.set_tool_data(
                "AuthPasswordReset",
                hash=hash,
                hash_expiry=datetime.datetime.utcnow()
                + datetime.timedelta(seconds=int(config.get("auth.recovery_hash_expiry_period", 600))),
            )

            log.info("Sending password recovery link to %s", email_record.email)
            subject = "%s Password recovery" % config["site_name"]
            text = g.jinja2_env.get_template("allura:templates/mail/forgot_password.txt").render(
                dict(user=user_record, config=config, hash=hash)
            )

            allura.tasks.mail_tasks.sendsimplemail.post(
                toaddr=email_record.email,
                fromaddr=config["forgemail.return_path"],
                reply_to=config["forgemail.return_path"],
                subject=subject,
                message_id=h.gen_message_id(),
                text=text,
            )
        h.auditlog_user("Password recovery link sent to: %s", email, user=user_record)
        flash(message)
        redirect("/")
Beispiel #28
0
 def test_fromaddr_objectid_not_str(self):
     c.user = M.User.by_username('test-admin')
     with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
         mail_tasks.sendsimplemail(
             fromaddr=c.user._id,
             toaddr='*****@*****.**',
             text=u'This is a test',
             reply_to=g.noreply,
             subject=u'Test subject',
             message_id=h.gen_message_id())
         assert_equal(_client.sendmail.call_count, 1)
         return_path, rcpts, body = _client.sendmail.call_args[0]
         assert_in('From: "Test Admin" <*****@*****.**>', body)
Beispiel #29
0
 def test_send_email_with_disabled_destination_user(self):
     c.user = M.User.by_username('test-admin')
     destination_user = M.User.by_username('test-user-1')
     destination_user.preferences['email_address'] = '*****@*****.**'
     destination_user.disabled = True
     ThreadLocalORMSession.flush_all()
     with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
         mail_tasks.sendmail(fromaddr=str(c.user._id),
                             destinations=[str(destination_user._id)],
                             text=u'This is a test',
                             reply_to=g.noreply,
                             subject=u'Test subject',
                             message_id=h.gen_message_id())
         assert_equal(_client.sendmail.call_count, 0)
Beispiel #30
0
 def test_cc(self):
     c.user = M.User.by_username('test-admin')
     with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
         mail_tasks.sendsimplemail(fromaddr=str(c.user._id),
                                   toaddr='*****@*****.**',
                                   text=u'This is a test',
                                   reply_to=g.noreply,
                                   subject=u'Test subject',
                                   cc=u'*****@*****.**',
                                   message_id=h.gen_message_id())
         assert_equal(_client.sendmail.call_count, 1)
         return_path, rcpts, body = _client.sendmail.call_args[0]
         assert_in('CC: [email protected]', body)
         assert_in('*****@*****.**', rcpts)
Beispiel #31
0
 def test_send_email_with_disabled_destination_user(self):
     c.user = M.User.by_username('test-admin')
     destination_user = M.User.by_username('test-user-1')
     destination_user.preferences['email_address'] = '*****@*****.**'
     destination_user.disabled = True
     ThreadLocalORMSession.flush_all()
     with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
         mail_tasks.sendmail(
             fromaddr=str(c.user._id),
             destinations=[str(destination_user._id)],
             text=u'This is a test',
             reply_to=g.noreply,
             subject=u'Test subject',
             message_id=h.gen_message_id())
         assert_equal(_client.sendmail.call_count, 0)
Beispiel #32
0
 def test_cc(self):
     c.user = M.User.by_username('test-admin')
     with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
         mail_tasks.sendsimplemail(
             fromaddr=str(c.user._id),
             toaddr='*****@*****.**',
             text=u'This is a test',
             reply_to=g.noreply,
             subject=u'Test subject',
             cc=u'*****@*****.**',
             message_id=h.gen_message_id())
         assert_equal(_client.sendmail.call_count, 1)
         return_path, rcpts, body = _client.sendmail.call_args[0]
         assert_in('CC: [email protected]', body)
         assert_in('*****@*****.**', rcpts)
Beispiel #33
0
    def password_recovery_hash(self, email=None, **kw):
        provider = plugin.AuthenticationProvider.get(request)
        if not provider.forgotten_password_process:
            raise wexc.HTTPNotFound()
        if not email:
            redirect('/')

        user_record = M.User.by_email_address(email)
        allow_non_primary_email_reset = asbool(config.get('auth.allow_non_primary_email_password_reset', True))

        if not re.match(r"[^@]+@[^@]+\.[^@]+", email):
            flash('Enter email in correct format!','error')
            redirect('/auth/forgotten_password')

        if not allow_non_primary_email_reset:
            message = 'If the given email address is on record, '\
                      'a password reset email has been sent to the account\'s primary email address.'
            email_record = M.EmailAddress.get(email=provider.get_primary_email_address(user_record=user_record),
                                                    confirmed=True)
        else:
            message = 'A password reset email has been sent, if the given email address is on record in our system.'
            email_record = M.EmailAddress.get(email=email, confirmed=True)

        if user_record and email_record and email_record.confirmed:
            hash = h.nonce(42)
            user_record.set_tool_data('AuthPasswordReset',
                                      hash=hash,
                                      hash_expiry=datetime.datetime.utcnow() +
                                      datetime.timedelta(seconds=int(config.get('auth.recovery_hash_expiry_period', 600))))

            log.info('Sending password recovery link to %s', email_record.email)
            subject = '%s Password recovery' % config['site_name']
            text = g.jinja2_env.get_template('allura:templates/mail/forgot_password.txt').render(dict(
                user=user_record,
                config=config,
                hash=hash,
            ))

            allura.tasks.mail_tasks.sendsimplemail.post(
                toaddr=email_record.email,
                fromaddr=config['forgemail.return_path'],
                reply_to=config['forgemail.return_path'],
                subject=subject,
                message_id=h.gen_message_id(),
                text=text)
        h.auditlog_user('Password recovery link sent to: %s', email, user=user_record)
        flash(message)
        redirect('/')
Beispiel #34
0
    def process(self, project, tools, user, filename=None, send_email=True, with_attachments=False):
        export_filename = filename or project.bulk_export_filename()
        export_path = self.get_export_path(
            project.bulk_export_path(), export_filename)
        if not os.path.exists(export_path):
            os.makedirs(export_path)
        apps = [project.app_instance(tool) for tool in tools]
        exportable = self.filter_exportable(apps)
        results = [self.export(export_path, app, with_attachments) for app in exportable]
        exported = self.filter_successful(results)
        if exported:
            zipdir(export_path,
                   os.path.join(os.path.dirname(export_path), export_filename))
        shutil.rmtree(export_path)

        if not user:
            log.info('No user. Skipping notification.')
            return
        if not send_email:
            return

        tmpl = g.jinja2_env.get_template(
            'allura:templates/mail/bulk_export.html')
        instructions = tg.config.get('bulk_export_download_instructions', '')
        instructions = instructions.format(
            project=project.shortname,
            filename=export_filename,
            c=c,
        )
        exported_names = [a.config.options.mount_point for a in exported]
        tmpl_context = {
            'instructions': instructions,
            'project': project,
            'tools': exported_names,
            'not_exported_tools': list(set(tools) - set(exported_names)),
        }

        email = {
            'toaddr': unicode(user._id),
            'fromaddr': unicode(tg.config['forgemail.return_path']),
            'sender': unicode(tg.config['forgemail.return_path']),
            'reply_to': unicode(tg.config['forgemail.return_path']),
            'message_id': h.gen_message_id(),
            'subject': u'Bulk export for project %s completed' % project.shortname,
            'text': tmpl.render(tmpl_context)
        }

        mail_tasks.sendsimplemail.post(**email)
Beispiel #35
0
def parse_message(data):
    # Parse the email to its constituent parts

    # https://bugs.python.org/issue25545 says
    # > A unicode string has no RFC defintion as an email, so things do not work right...
    # > You do have to conditionalize your 2/3 code to use the bytes parser and generator if you are dealing with 8-bit
    # > messages. There's just no way around that.
    if six.PY2:
        parser = email.feedparser.FeedParser()
        parser.feed(data)
        msg = parser.close()
    else:
        # works the same as BytesFeedParser, and better than non-"Bytes" parsers for some messages
        parser = email.parser.BytesParser()
        msg = parser.parsebytes(data.encode('utf-8'))
    # Extract relevant data
    result = {}
    result['multipart'] = multipart = msg.is_multipart()
    result['headers'] = dict(msg)
    result['message_id'] = _parse_message_id(msg.get('Message-ID'))
    result['in_reply_to'] = _parse_message_id(msg.get('In-Reply-To'))
    result['references'] = _parse_message_id(msg.get('References'))
    if result['message_id'] == []:
        result['message_id'] = h.gen_message_id()
    else:
        result['message_id'] = result['message_id'][0]
    if multipart:
        result['parts'] = []
        for part in msg.walk():
            dpart = dict(headers=dict(part),
                         message_id=result['message_id'],
                         in_reply_to=result['in_reply_to'],
                         references=result['references'],
                         content_type=part.get_content_type(),
                         filename=part.get_filename(None),
                         payload=part.get_payload(decode=True))
            # payload is sometimes already unicode (due to being saved in mongo?)
            if part.get_content_maintype() == 'text':
                dpart['payload'] = six.ensure_text(dpart['payload'])
            result['parts'].append(dpart)
    else:
        result['payload'] = msg.get_payload(decode=True)
        # payload is sometimes already unicode (due to being saved in mongo?)
        if msg.get_content_maintype() == 'text':
            result['payload'] = six.ensure_text(result['payload'])

    return result
    def send_verification_link(self):
        self.nonce = sha256(os.urandom(10)).hexdigest()
        log.info('Sending verification link to %s', self._id)
        text = '''
To verify the email address %s belongs to the user %s,
please visit the following URL:

    %s
''' % (self._id, self.claimed_by_user().username, g.url('/auth/verify_addr', a=self.nonce))
        log.info('Verification email:\n%s', text)
        allura.tasks.mail_tasks.sendmail.post(
            destinations=[self._id],
            fromaddr=self._id,
            reply_to='',
            subject='Email address verification',
            message_id=h.gen_message_id(),
            text=text)
Beispiel #37
0
 def send_summary(self, user_id, from_address, subject, notifications):
     if not notifications: return
     text = ['Digest of %s' % subject]
     for n in notifications:
         text.append('From: %s' % n.from_address)
         text.append('Subject: %s' % (n.subject or '(no subject)'))
         text.append('Message-ID: %s' % n._id)
         text.append('')
         text.append(h.text.truncate(n.text or '-no text-', 128))
     text.append(n.footer())
     text = '\n'.join(text)
     allura.tasks.mail_tasks.sendmail.post(destinations=[str(user_id)],
                                           fromaddr=from_address,
                                           reply_to=from_address,
                                           subject=subject,
                                           message_id=h.gen_message_id(),
                                           text=text)
Beispiel #38
0
    def send_verification_link(self):
        self.nonce = sha256(os.urandom(10)).hexdigest()
        log.info('Sending verification link to %s', self._id)
        text = '''
To verify the email address %s belongs to the user %s,
please visit the following URL:

    %s
''' % (self._id, self.claimed_by_user().username, g.url('/auth/verify_addr', a=self.nonce))
        log.info('Verification email:\n%s', text)
        allura.tasks.mail_tasks.sendmail.post(
            destinations=[self._id],
            fromaddr=self._id,
            reply_to='',
            subject='Email address verification',
            message_id=h.gen_message_id(),
            text=text)
 def test_send_email_with_disabled_user(self):
     c.user = M.User.by_username('test-admin')
     c.user.disabled = True
     destination_user = M.User.by_username('test-user-1')
     destination_user.preferences['email_address'] = '*****@*****.**'
     ThreadLocalORMSession.flush_all()
     with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
         mail_tasks.sendmail(fromaddr=str(c.user._id),
                             destinations=[str(destination_user._id)],
                             text=u'This is a test',
                             reply_to=u'*****@*****.**',
                             subject=u'Test subject',
                             message_id=h.gen_message_id())
         assert_equal(_client.sendmail.call_count, 1)
         return_path, rcpts, body = _client.sendmail.call_args[0]
         body = body.split('\n')
         assert_in('From: [email protected]', body)
 def test_send_email_with_disabled_user(self):
     c.user = M.User.by_username('test-admin')
     c.user.disabled = True
     destination_user = M.User.by_username('test-user-1')
     destination_user.preferences['email_address'] = '*****@*****.**'
     ThreadLocalORMSession.flush_all()
     with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
         mail_tasks.sendmail(
             fromaddr=str(c.user._id),
             destinations=[ str(destination_user._id) ],
             text=u'This is a test',
             reply_to=u'*****@*****.**',
             subject=u'Test subject',
             message_id=h.gen_message_id())
         assert_equal(_client.sendmail.call_count, 1)
         return_path, rcpts, body = _client.sendmail.call_args[0]
         body = body.split('\n')
         assert_in('From: [email protected]', body)
Beispiel #41
0
    def send_claim_attempt(self):
        confirmed_email = self.find(dict(email=self.email, confirmed=True)).all()

        if confirmed_email:
            log.info('Sending claim attempt email to %s', self.email)
            text = g.jinja2_env.get_template('allura:templates/mail/claimed_existing_email.txt').render(dict(
                email=self,
                user=confirmed_email[0].claimed_by_user(),
                config=config
            ))

            allura.tasks.mail_tasks.sendsimplemail.post(
                toaddr=self.email,
                fromaddr=config['forgemail.return_path'],
                reply_to=config['forgemail.return_path'],
                subject=u'%s - Email address claim attempt' % config['site_name'],
                message_id=h.gen_message_id(),
                text=text)
Beispiel #42
0
 def send_summary(self, user_id, from_address, subject, notifications):
     if not notifications: return
     text = [ 'Digest of %s' % subject ]
     for n in notifications:
         text.append('From: %s' % n.from_address)
         text.append('Subject: %s' % (n.subject or '(no subject)'))
         text.append('Message-ID: %s' % n._id)
         text.append('')
         text.append(h.text.truncate(n.text or '-no text-', 128))
     text.append(n.footer())
     text = '\n'.join(text)
     allura.tasks.mail_tasks.sendmail.post(
         destinations=[str(user_id)],
         fromaddr=from_address,
         reply_to=from_address,
         subject=subject,
         message_id=h.gen_message_id(),
         text=text)
Beispiel #43
0
    def send_claim_attempt(self):
        confirmed_email = self.find(dict(email=self.email, confirmed=True)).all()

        if confirmed_email:
            log.info('Sending claim attempt email to %s', self.email)
            text = g.jinja2_env.get_template('allura:templates/mail/claimed_existing_email.txt').render(dict(
                email=self,
                user=confirmed_email[0].claimed_by_user(),
                config=config
            ))

            allura.tasks.mail_tasks.sendsimplemail.post(
                toaddr=self.email,
                fromaddr=config['forgemail.return_path'],
                reply_to=config['forgemail.return_path'],
                subject=u'%s - Email address claim attempt' % config['site_name'],
                message_id=h.gen_message_id(),
                text=text)
Beispiel #44
0
    def send_verification_link(self):
        self.set_nonce_hash()
        log.info('Sending verification link to %s', self.email)
        text = '''
To verify the email address %s belongs to the user %s,
please visit the following URL:

%s
''' % (self.email, self.claimed_by_user(include_pending=True).username,
        g.url('/auth/verify_addr', a=self.nonce))
        log.info('Verification email:\n%s', text)
        allura.tasks.mail_tasks.sendsimplemail.post(
            fromaddr=g.noreply,
            reply_to=g.noreply,
            toaddr=self.email,
            subject=u'%s - Email address verification' % config['site_name'],
            message_id=h.gen_message_id(),
            text=text)
Beispiel #45
0
    def send_verification_link(self):
        self.set_nonce_hash()
        log.info('Sending verification link to %s', self.email)
        text = '''
To verify the email address %s belongs to the user %s,
please visit the following URL:

%s
''' % (self.email,
       self.claimed_by_user(include_pending=True).username,
       g.url('/auth/verify_addr', a=self.nonce))
        log.info('Verification email:\n%s', text)
        allura.tasks.mail_tasks.sendsimplemail.post(
            fromaddr=g.noreply,
            reply_to=g.noreply,
            toaddr=self.email,
            subject=u'%s - Email address verification' % config['site_name'],
            message_id=h.gen_message_id(),
            text=text)
Beispiel #46
0
    def send_user_message(self, user, subject, message, cc):
        """Send a user message (email) to ``user``.

        """
        tmpl = g.jinja2_env.get_template('allura:ext/user_profile/templates/message.html')
        tmpl_context = {
            'message_text': message,
            'site_name': config['site_name'],
            'base_url': config['base_url'],
            'username': c.user.username,
        }
        allura.tasks.mail_tasks.sendsimplemail.post(
            toaddr=user.get_pref('email_address'),
            fromaddr=self.get_pref('email_address'),
            reply_to=self.get_pref('email_address'),
            message_id=h.gen_message_id(),
            subject=subject,
            text=tmpl.render(tmpl_context),
            cc=cc)
        self.sent_user_message_times.append(datetime.utcnow())
Beispiel #47
0
    def post(self, text, message_id=None, parent_id=None, notify=True,
             notification_text=None, timestamp=None, ignore_security=False,
             is_meta=False, **kw):
        if not ignore_security:
            require_access(self, 'post')
        if self.ref_id and self.artifact:
            self.artifact.subscribe()
        if message_id is None:
            message_id = h.gen_message_id()
        parent = parent_id and self.post_class().query.get(_id=parent_id)
        slug, full_slug = self.post_class().make_slugs(parent, timestamp)
        kwargs = dict(
            discussion_id=self.discussion_id,
            full_slug=full_slug,
            slug=slug,
            thread_id=self._id,
            parent_id=parent_id,
            text=text,
            status='pending',
            is_meta=is_meta)
        if timestamp is not None:
            kwargs['timestamp'] = timestamp
        if message_id is not None:
            kwargs['_id'] = message_id
        post = self.post_class()(**kwargs)

        # unmoderated post -> autoapprove
        # unmoderated post but is spammy -> don't approve it, it goes into moderation
        # moderated post -> moderation
        # moderated post but is spammy -> mark as spam
        spammy = self.is_spam(post)
        if ignore_security or (not spammy and has_access(self, 'unmoderated_post')):
            log.info('Auto-approving message from %s', c.user.username)
            file_info = kw.get('file_info', None)
            post.approve(file_info, notify=notify,
                         notification_text=notification_text)
        elif not has_access(self, 'unmoderated_post') and spammy:
            post.spam(submit_spam_feedback=False)  # no feedback since we're marking as spam automatically not manually
        else:
            self.notify_moderators(post)
        return post
Beispiel #48
0
    def test_send_email_long_lines_use_quoted_printable(self):
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendsimplemail(
                fromaddr=u'"По" <*****@*****.**>',
                toaddr='*****@*****.**',
                text=(u'0123456789' * 100) + u'\n\n' + (u'Громады стро ' * 100),
                reply_to=g.noreply,
                subject=u'По оживлённым берегам',
                message_id=h.gen_message_id())
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')

            for line in body:
                assert_less(len(line), 991)

            # plain text
            assert_in('012345678901234567890123456789012345678901234567890123456789012345678901234=', body)
            assert_in('=D0=93=D1=80=D0=BE=D0=BC=D0=B0=D0=B4=D1=8B =D1=81=D1=82=D1=80=D0=BE =D0=93=', body)
            # html
            assert_in('<div class=3D"markdown_content"><p>0123456789012345678901234567890123456789=', body)
            assert_in('<p>=D0=93=D1=80=D0=BE=D0=BC=D0=B0=D0=B4=D1=8B =D1=81=D1=82=D1=80=D0=BE =D0=', body)
Beispiel #49
0
    def send_user_message(self, user, subject, message, cc):
        """Send a user message (email) to ``user``.

        """
        tmpl = g.jinja2_env.get_template(
            'allura:ext/user_profile/templates/message.html')
        tmpl_context = {
            'message_text': message,
            'site_name': config['site_name'],
            'base_url': config['base_url'],
            'user': c.user,
        }
        allura.tasks.mail_tasks.sendsimplemail.post(
            toaddr=user.get_pref('email_address'),
            fromaddr=self.get_pref('email_address'),
            reply_to=self.get_pref('email_address'),
            message_id=h.gen_message_id(),
            subject=subject,
            text=tmpl.render(tmpl_context),
            cc=cc)
        self.sent_user_message_times.append(datetime.utcnow())
Beispiel #50
0
def parse_message(data):
    # Parse the email to its constituent parts
    parser = email.feedparser.FeedParser()
    parser.feed(data)
    msg = parser.close()
    # Extract relevant data
    result = {}
    result['multipart'] = multipart = msg.is_multipart()
    result['headers'] = dict(msg)
    result['message_id'] = _parse_message_id(msg.get('Message-ID'))
    result['in_reply_to'] = _parse_message_id(msg.get('In-Reply-To'))
    result['references'] = _parse_message_id(msg.get('References'))
    if result['message_id'] == []:
        result['message_id'] = h.gen_message_id()
    else:
        result['message_id'] = result['message_id'][0]
    if multipart:
        result['parts'] = []
        for part in msg.walk():
            dpart = dict(
                headers=dict(part),
                message_id=result['message_id'],
                in_reply_to=result['in_reply_to'],
                references=result['references'],
                content_type=part.get_content_type(),
                filename=part.get_filename(None),
                payload=part.get_payload(decode=True))
            charset = part.get_content_charset()
            # payload is sometimes already unicode (due to being saved in mongo?)
            if isinstance(dpart['payload'], six.binary_type) and charset:
                dpart['payload'] = dpart['payload'].decode(charset)
            result['parts'].append(dpart)
    else:
        result['payload'] = msg.get_payload(decode=True)
        charset = msg.get_content_charset()
        # payload is sometimes already unicode (due to being saved in mongo?)
        if isinstance(result['payload'], six.binary_type) and charset:
            result['payload'] = result['payload'].decode(charset)

    return result
    def test_send_email_ascii_with_user_lookup(self):
        c.user = M.User.by_username('test-admin')
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendmail(
                fromaddr=str(c.user._id),
                destinations=[ str(c.user._id) ],
                text=u'This is a test',
                reply_to=u'*****@*****.**',
                subject=u'Test subject',
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')

            assert_equal(rcpts, [c.user.get_pref('email_address')])
            assert_in('Reply-To: [email protected]', body)
            assert_in('From: "Test Admin" <*****@*****.**>', body)
            assert_in('Subject: Test subject', body)
            # plain
            assert_in('This is a test', body)
            # html
            assert_in('<div class="markdown_content"><p>This is a test</p></div>', body)
Beispiel #52
0
    def test_send_email_ascii_with_user_lookup(self):
        c.user = M.User.by_username('test-admin')
        with mock.patch.object(mail_tasks.smtp_client, '_client') as _client:
            mail_tasks.sendmail(
                fromaddr=str(c.user._id),
                destinations=[ str(c.user._id) ],
                text=u'This is a test',
                reply_to=u'*****@*****.**',
                subject=u'Test subject',
                message_id=h.gen_message_id())
            assert_equal(_client.sendmail.call_count, 1)
            return_path, rcpts, body = _client.sendmail.call_args[0]
            body = body.split('\n')

            assert_equal(rcpts, [c.user.get_pref('email_address')])
            assert_in('Reply-To: [email protected]', body)
            assert_in('From: "Test Admin" <*****@*****.**>', body)
            assert_in('Subject: Test subject', body)
            # plain
            assert_in('This is a test', body)
            # html
            assert_in('<div class="markdown_content"><p>This is a test</p></div>', body)
def parse_message(data):
    # Parse the email to its constituent parts
    parser = email.feedparser.FeedParser()
    parser.feed(data)
    msg = parser.close()
    # Extract relevant data
    result = {}
    result["multipart"] = multipart = msg.is_multipart()
    result["headers"] = dict(msg)
    result["message_id"] = _parse_message_id(msg.get("Message-ID"))
    result["in_reply_to"] = _parse_message_id(msg.get("In-Reply-To"))
    result["references"] = _parse_message_id(msg.get("References"))
    if result["message_id"] == []:
        result["message_id"] = h.gen_message_id()
    else:
        result["message_id"] = result["message_id"][0]
    if multipart:
        result["parts"] = []
        for part in msg.walk():
            dpart = dict(
                headers=dict(part),
                message_id=result["message_id"],
                in_reply_to=result["in_reply_to"],
                references=result["references"],
                content_type=part.get_content_type(),
                filename=part.get_filename(None),
                payload=part.get_payload(decode=True),
            )
            charset = part.get_content_charset()
            if charset:
                dpart["payload"] = dpart["payload"].decode(charset)
            result["parts"].append(dpart)
    else:
        result["payload"] = msg.get_payload(decode=True)
        charset = msg.get_content_charset()
        if charset:
            result["payload"] = result["payload"].decode(charset)
    return result
 def send_summary(self, user_id, from_address, subject, notifications):
     if not notifications:
         return
     log.debug(
         "Sending summary of notifications [%s] to user %s", ", ".join([n._id for n in notifications]), user_id
     )
     text = ["Digest of %s" % subject]
     for n in notifications:
         text.append("From: %s" % n.from_address)
         text.append("Subject: %s" % (n.subject or "(no subject)"))
         text.append("Message-ID: %s" % n._id)
         text.append("")
         text.append(h.text.truncate(n.text or "-no text-", 128))
     text.append(n.footer())
     text = "\n".join(text)
     allura.tasks.mail_tasks.sendmail.post(
         destinations=[str(user_id)],
         fromaddr=from_address,
         reply_to=from_address,
         subject=subject,
         message_id=h.gen_message_id(),
         text=text,
     )
def test_gen_messageid_with_id_set():
    oid = ObjectId()
    assert re.match(r'*****@*****.**' % str(oid), h.gen_message_id(oid))
def test_gen_messageid():
    assert re.match(r'[0-9a-zA-Z]*[email protected]', h.gen_message_id())
Beispiel #57
0
def test_gen_messageid():
    assert re.match(r'[0-9a-zA-Z]*[email protected]', h.gen_message_id())
Beispiel #58
0
def test_gen_messageid_with_id_set():
    oid = ObjectId()
    assert re.match(r'*****@*****.**' % str(oid),
                    h.gen_message_id(oid))