Пример #1
0
def sendmail(fromaddr, destinations, text, reply_to, subject,
             message_id, in_reply_to=None, sender=None, references=None):
    from allura import model as M
    addrs_plain = []
    addrs_html = []
    addrs_multi = []
    if fromaddr is None:
        fromaddr = g.noreply
    elif '@' not in fromaddr:
        log.warning('Looking up user with fromaddr: %s', fromaddr)
        user = M.User.query.get(_id=ObjectId(fromaddr), disabled=False)
        if not user:
            log.warning('Cannot find user with ID: %s', fromaddr)
            fromaddr = g.noreply
        else:
            fromaddr = user.email_address_header()
    # Divide addresses based on preferred email formats
    for addr in destinations:
        if mail_util.isvalid(addr):
            addrs_plain.append(addr)
        else:
            try:
                user = M.User.query.get(_id=ObjectId(addr), disabled=False)
                if not user:
                    log.warning('Cannot find user with ID: %s', addr)
                    continue
            except:
                log.exception('Error looking up user with ID: %r' % addr)
                continue
            addr = user.email_address_header()
            if not addr and user.email_addresses:
                addr = user.email_addresses[0]
                log.warning(
                    'User %s has not set primary email address, using %s',
                    user._id, addr)
            if not addr:
                log.error(
                    "User %s (%s) has not set any email address, can't deliver",
                    user._id, user.username)
                continue
            if user.get_pref('email_format') == 'plain':
                addrs_plain.append(addr)
            elif user.get_pref('email_format') == 'html':
                addrs_html.append(addr)
            else:
                addrs_multi.append(addr)
    htmlparser = HTMLParser.HTMLParser()
    plain_msg = mail_util.encode_email_part(htmlparser.unescape(text), 'plain')
    html_text = g.forge_markdown(email=True).convert(text)
    html_msg = mail_util.encode_email_part(html_text, 'html')
    multi_msg = mail_util.make_multipart_message(plain_msg, html_msg)
    smtp_client.sendmail(
        addrs_multi, fromaddr, reply_to, subject, message_id,
        in_reply_to, multi_msg, sender=sender, references=references)
    smtp_client.sendmail(
        addrs_plain, fromaddr, reply_to, subject, message_id,
        in_reply_to, plain_msg, sender=sender, references=references)
    smtp_client.sendmail(
        addrs_html, fromaddr, reply_to, subject, message_id,
        in_reply_to, html_msg, sender=sender, references=references)
Пример #2
0
def sendmail(fromaddr, destinations, text, reply_to, subject,
             message_id, in_reply_to=None, sender=None, references=None, metalink=None):
    '''
    Send an email to the specified list of destinations with respect to the preferred email format specified by user.
    It is best for broadcast messages.

    :param fromaddr: ObjectId or str(ObjectId) of user, or email address str

    '''
    from allura import model as M
    addrs_plain = []
    addrs_multi = []
    if fromaddr is None:
        fromaddr = g.noreply
    elif not isinstance(fromaddr, basestring) or '@' not in fromaddr:
        log.warning('Looking up user with fromaddr: %s', fromaddr)
        user = M.User.query.get(_id=ObjectId(fromaddr), disabled=False, pending=False)
        if not user:
            log.warning('Cannot find user with ID: %s', fromaddr)
            fromaddr = g.noreply
        else:
            fromaddr = user.email_address_header()
    # Divide addresses based on preferred email formats
    for addr in destinations:
        if mail_util.isvalid(addr):
            addrs_plain.append(addr)
        else:
            try:
                user = M.User.query.get(_id=ObjectId(addr), disabled=False, pending=False)
                if not user:
                    log.warning('Cannot find user with ID: %s', addr)
                    continue
            except:
                log.exception('Error looking up user with ID: %r' % addr)
                continue
            addr = user.email_address_header()
            if not addr and user.email_addresses:
                addr = user.email_addresses[0]
                log.warning(
                    'User %s has not set primary email address, using %s',
                    user._id, addr)
            if not addr:
                log.error(
                    "User %s (%s) has not set any email address, can't deliver",
                    user._id, user.username)
                continue
            if user.get_pref('email_format') == 'plain':
                addrs_plain.append(addr)
            else:
                addrs_multi.append(addr)

    multi_msg, plain_msg = create_multipart_msg(text, metalink)
    smtp_client.sendmail(
        addrs_multi, fromaddr, reply_to, subject, message_id,
        in_reply_to, multi_msg, sender=sender, references=references)
    smtp_client.sendmail(
        addrs_plain, fromaddr, reply_to, subject, message_id,
        in_reply_to, plain_msg, sender=sender, references=references)
Пример #3
0
def sendmail(fromaddr, destinations, text, reply_to, subject,
             message_id, in_reply_to=None, sender=None):
    from allura import model as M
    addrs_plain = []
    addrs_html = []
    addrs_multi = []
    if fromaddr is None:
        fromaddr = u'*****@*****.**'
    elif '@' not in fromaddr:
        log.warning('Looking up user with fromaddr: %s', fromaddr)
        user = M.User.query.get(_id=ObjectId(fromaddr), disabled=False)
        if not user:
            log.warning('Cannot find user with ID: %s', fromaddr)
            fromaddr = u'*****@*****.**'
        else:
            fromaddr = user.email_address_header()
    # Divide addresses based on preferred email formats
    for addr in destinations:
        if mail_util.isvalid(addr):
            addrs_plain.append(addr)
        else:
            try:
                user = M.User.query.get(_id=ObjectId(addr), disabled=False)
                if not user:
                    log.warning('Cannot find user with ID: %s', addr)
                    continue
            except:
                log.exception('Error looking up user with ID: %r' % addr)
                continue
            addr = user.email_address_header()
            if not addr and user.email_addresses:
                addr = user.email_addresses[0]
                log.warning('User %s has not set primary email address, using %s',
                            user._id, addr)
            if not addr:
                log.error("User %s (%s) has not set any email address, can't deliver",
                          user._id, user.username)
                continue
            if user.get_pref('email_format') == 'plain':
                addrs_plain.append(addr)
            elif user.get_pref('email_format') == 'html':
                addrs_html.append(addr)
            else:
                addrs_multi.append(addr)
    htmlparser = HTMLParser.HTMLParser()
    plain_msg = mail_util.encode_email_part(htmlparser.unescape(text), 'plain')
    html_text = g.forge_markdown(email=True).convert(text)
    html_msg = mail_util.encode_email_part(html_text, 'html')
    multi_msg = mail_util.make_multipart_message(plain_msg, html_msg)
    smtp_client.sendmail(
        addrs_multi, fromaddr, reply_to, subject, message_id,
        in_reply_to, multi_msg, sender=sender)
    smtp_client.sendmail(
        addrs_plain, fromaddr, reply_to, subject, message_id,
        in_reply_to, plain_msg, sender=sender)
    smtp_client.sendmail(
        addrs_html, fromaddr, reply_to, subject, message_id,
        in_reply_to, html_msg, sender=sender)
Пример #4
0
    def _update_emails(self, user, admin=False, form_params={}):
        # not using **kw in method signature, to ensure 'admin' can't be passed in via a form submit
        kw = form_params
        addr = kw.pop('addr', None)
        new_addr = kw.pop('new_addr', None)
        primary_addr = kw.pop('primary_addr', None)
        provider = plugin.AuthenticationProvider.get(request)
        for i, (old_a, data) in enumerate(zip(user.email_addresses, addr
                                              or [])):
            obj = user.address_object(old_a)
            if data.get('delete') or not obj:
                if not admin and (not kw.get('password')
                                  or not provider.validate_password(
                                      user, kw.get('password'))):
                    flash(
                        'You must provide your current password to delete an email',
                        'error')
                    return
                if primary_addr == user.email_addresses[i]:
                    if select_new_primary_addr(user, ignore_emails=primary_addr) is None \
                            and asbool(config.get('auth.require_email_addr', False)):
                        flash(
                            'You must have at least one verified email address.',
                            'error')
                        return
                    else:
                        # clear it now, a new one will get set below
                        user.set_pref('email_address', None)
                        primary_addr = None
                        user.set_tool_data('AuthPasswordReset',
                                           hash='',
                                           hash_expiry='')
                h.auditlog_user('Email address deleted: %s',
                                user.email_addresses[i],
                                user=user)
                del user.email_addresses[i]
                if obj:
                    obj.delete()
        if new_addr.get('claim') or new_addr.get('addr'):
            user.set_tool_data('AuthPasswordReset', hash='',
                               hash_expiry='')  # Clear password reset token
            claimed_emails_limit = config.get(
                'user_prefs.maximum_claimed_emails', None)
            if claimed_emails_limit and len(
                    user.email_addresses) >= int(claimed_emails_limit):
                flash(
                    'You cannot claim more than %s email addresses.' %
                    claimed_emails_limit, 'error')
                return
            if not admin and (not kw.get('password')
                              or not provider.validate_password(
                                  user, kw.get('password'))):
                flash(
                    'You must provide your current password to claim new email',
                    'error')
                return

            claimed_emails = M.EmailAddress.find({
                'email': new_addr['addr']
            }).all()

            if any(email.claimed_by_user_id == user._id
                   for email in claimed_emails):
                flash('Email address already claimed', 'error')

            elif mail_util.isvalid(new_addr['addr']):
                em = M.EmailAddress.create(new_addr['addr'])
                if em:
                    user.email_addresses.append(em.email)
                    em.claimed_by_user_id = user._id

                    confirmed_emails = filter(lambda email: email.confirmed,
                                              claimed_emails)
                    if not confirmed_emails:
                        if not admin:
                            em.send_verification_link()
                        else:
                            AuthController()._verify_addr(em)
                    else:
                        em.send_claim_attempt()

                    if not admin:
                        user.set_tool_data('AuthPasswordReset',
                                           hash='',
                                           hash_expiry='')
                        flash(
                            'A verification email has been sent.  Please check your email and click to confirm.'
                        )

                    h.auditlog_user('New email address: %s',
                                    new_addr['addr'],
                                    user=user)
                else:
                    flash('Email address %s is invalid' % new_addr['addr'],
                          'error')
            else:
                flash('Email address %s is invalid' % new_addr['addr'],
                      'error')
        if not primary_addr and not user.get_pref(
                'email_address') and user.email_addresses:
            primary_addr = select_new_primary_addr(user)
        if primary_addr:
            if user.get_pref('email_address') != primary_addr:
                if not admin and (not kw.get('password')
                                  or not provider.validate_password(
                                      user, kw.get('password'))):
                    flash(
                        'You must provide your current password to change primary address',
                        'error')
                    return
                h.auditlog_user('Primary email changed: %s => %s',
                                user.get_pref('email_address'),
                                primary_addr,
                                user=user)
            user.set_pref('email_address', primary_addr)
            user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')
Пример #5
0
    def _update_emails(self, user, admin=False, form_params={}):
        # not using **kw in method signature, to ensure 'admin' can't be passed in via a form submit
        kw = form_params
        addr = kw.pop('addr', None)
        new_addr = kw.pop('new_addr', None)
        primary_addr = kw.pop('primary_addr', None)
        provider = plugin.AuthenticationProvider.get(request)
        for i, (old_a, data) in enumerate(zip(user.email_addresses, addr or [])):
            obj = user.address_object(old_a)
            if data.get('delete') or not obj:
                if not admin and (not kw.get('password') or not provider.validate_password(user, kw.get('password'))):
                    flash('You must provide your current password to delete an email', 'error')
                    return
                if primary_addr == user.email_addresses[i]:
                    if select_new_primary_addr(user, ignore_emails=primary_addr) is None \
                            and asbool(config.get('auth.require_email_addr', False)):
                        flash('You must have at least one verified email address.', 'error')
                        return
                    else:
                        # clear it now, a new one will get set below
                        user.set_pref('email_address', None)
                        primary_addr = None
                        user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')
                h.auditlog_user('Email address deleted: %s', user.email_addresses[i], user=user)
                del user.email_addresses[i]
                if obj:
                    obj.delete()
        if new_addr.get('claim') or new_addr.get('addr'):
            user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')  # Clear password reset token
            claimed_emails_limit = config.get('user_prefs.maximum_claimed_emails', None)
            if claimed_emails_limit and len(user.email_addresses) >= int(claimed_emails_limit):
                flash('You cannot claim more than %s email addresses.' % claimed_emails_limit, 'error')
                return
            if not admin and (not kw.get('password') or not provider.validate_password(user, kw.get('password'))):
                flash('You must provide your current password to claim new email', 'error')
                return

            claimed_emails = M.EmailAddress.find({'email': new_addr['addr']}).all()

            if any(email.claimed_by_user_id == user._id for email in claimed_emails):
                flash('Email address already claimed', 'error')

            elif mail_util.isvalid(new_addr['addr']):
                em = M.EmailAddress.create(new_addr['addr'])
                if em:
                    user.email_addresses.append(em.email)
                    em.claimed_by_user_id = user._id

                    confirmed_emails = filter(lambda email: email.confirmed, claimed_emails)
                    if not confirmed_emails:
                        if not admin:
                            em.send_verification_link()
                        else:
                            AuthController()._verify_addr(em)
                    else:
                        em.send_claim_attempt()

                    if not admin:
                        user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')
                        flash('A verification email has been sent.  Please check your email and click to confirm.')

                    h.auditlog_user('New email address: %s', new_addr['addr'], user=user)
                else:
                    flash('Email address %s is invalid' % new_addr['addr'], 'error')
            else:
                flash('Email address %s is invalid' % new_addr['addr'], 'error')
        if not primary_addr and not user.get_pref('email_address') and user.email_addresses:
            primary_addr = select_new_primary_addr(user)
        if primary_addr:
            if user.get_pref('email_address') != primary_addr:
                if not admin and (not kw.get('password') or not provider.validate_password(user, kw.get('password'))):
                    flash('You must provide your current password to change primary address', 'error')
                    return
                h.auditlog_user(
                    'Primary email changed: %s => %s',
                    user.get_pref('email_address'),
                    primary_addr,
                    user=user)
            user.set_pref('email_address', primary_addr)
            user.set_tool_data('AuthPasswordReset', hash='', hash_expiry='')