Example #1
0
 def _setValue(self, mlist, property, val, doc):
     # If we're changing the list's preferred language, change the I18N
     # context as well
     if property == 'preferred_language':
         i18n.set_language(val)
         doc.set_language(val)
     GUIBase._setValue(self, mlist, property, val, doc)
Example #2
0
 def __refuse(self, request, recip, comment, origmsg=None, lang=None):
     # As this message is going to the requestor, try to set the language
     # to his/her language choice, if they are a member.  Otherwise use the
     # list's preferred language.
     realname = self.real_name
     if lang is None:
         lang = self.getMemberLanguage(recip)
     text = Utils.maketext(
         'refuse.txt',
         {'listname' : realname,
          'request'  : request,
          'reason'   : comment,
          'adminaddr': self.GetOwnerEmail(),
         }, lang=lang, mlist=self)
     otrans = i18n.get_translation()
     i18n.set_language(lang)
     try:
         # add in original message, but not wrap/filled
         if origmsg:
             text = NL.join(
                 [text,
                  '---------- ' + _('Original Message') + ' ----------',
                  str(origmsg)
                  ])
         subject = _('Request to mailing list %(realname)s rejected')
     finally:
         i18n.set_translation(otrans)
     msg = Message.UserNotification(recip, self.GetOwnerEmail(),
                                    subject, text, lang)
     msg.send(self)
Example #3
0
def subscription_prompt(mlist, doc, cookie, userdesc):
    email = userdesc.address
    password = userdesc.password
    digest = userdesc.digest
    lang = userdesc.language
    name = Utils.uncanonstr(userdesc.fullname, lang)
    i18n.set_language(lang)
    doc.set_language(lang)
    title = _('Anmeldung abschließen')
    doc.SetTitle(title)

    form = Form(mlist.GetScriptURL('confirm', 1))
    table = Table(border=0)
    table.AddRow([Bold(FontAttr(title, size='+2'))])

    listname = mlist.real_name
    # This is the normal, no-confirmation required results text.
    #
    # We do things this way so we don't have to reformat this paragraph, which
    # would mess up translations.  If you modify this text for other reasons,
    # please refill the paragraph, and clean up the logic.
    result = _("<br>Um die Anmeldung der Email-Adresse <strong>" + email +
               "</strong> " +
               """<br>zur Mailingliste <strong>%(listname)s</strong>
    abzuschlie&szlig;en, klicken Sie bitte unten auf "Anmeldung best&auml;tigen".
    """) + '<p><br>'
    table.AddRow([result])
    table.AddRow([Hidden('cookie', cookie)])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)

    table.AddRow([SubmitButton('submit', 'Anmeldung best&auml;tigen')])
    form.AddItem(table)
    doc.AddItem(form)
Example #4
0
    def html_foot(self):
        # avoid i18n side-effects
        mlist = self.maillist
        otrans = i18n.get_translation()
        i18n.set_language(mlist.preferred_language)
        # Convenience
        def quotetime(s):
            return html_quote(i18n.ctime(s), self.lang)
        try:
            d = {"lastdate": quotetime(self.lastdate),
                 "archivedate": quotetime(self.archivedate),
                 "listinfo": mlist.GetScriptURL('listinfo', absolute=1),
                 "version": self.version,
                 "listname": html_quote(mlist.real_name, self.lang),
                 }
            i = {"thread": _("thread"),
                 "subject": _("subject"),
                 "author": _("author"),
                 "date": _("date")
                 }
        finally:
            i18n.set_translation(otrans)

        for t in i.keys():
            cap = t[0].upper() + t[1:]
            if self.type == cap:
                d["%s_ref" % (t)] = ""
            else:
                d["%s_ref" % (t)] = ('<a href="%s.html#start">[ %s ]</a>'
                                     % (t, i[t]))
        return quick_maketext(
            'archidxfoot.html', d,
            mlist=mlist)
Example #5
0
    def decode_headers(self):
        """MIME-decode headers.

        If the email, subject, or author attributes contain non-ASCII
        characters using the encoded-word syntax of RFC 2047, decoded versions
        of those attributes are placed in the self.decoded (a dictionary).

        If the list's charset differs from the header charset, an attempt is
        made to decode the headers as Unicode.  If that fails, they are left
        undecoded.
        """
        author = self.decode_charset(self.author)
        subject = self.decode_charset(self.subject)
        if author:
            self.decoded['author'] = author
            email = self.decode_charset(self.email)
            if email:
                self.decoded['email'] = email
        if subject:
            if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS:
                otrans = i18n.get_translation()
                try:
                    i18n.set_language(self._lang)
                    atmark = unicode(_(' at '), Utils.GetCharSet(self._lang))
                    subject = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
                                     '\g<1>' + atmark + '\g<2>', subject)
                finally:
                    i18n.set_translation(otrans)
            self.decoded['subject'] = subject
        self.decoded['stripped'] = self.strip_subject(subject or self.subject)
Example #6
0
    def decode_headers(self):
        """MIME-decode headers.

        If the email, subject, or author attributes contain non-ASCII
        characters using the encoded-word syntax of RFC 2047, decoded versions
        of those attributes are placed in the self.decoded (a dictionary).

        If the list's charset differs from the header charset, an attempt is
        made to decode the headers as Unicode.  If that fails, they are left
        undecoded.
        """
        author = self.decode_charset(self.author)
        subject = self.decode_charset(self.subject)
        if author:
            self.decoded['author'] = author
            email = self.decode_charset(self.email)
            if email:
                self.decoded['email'] = email
        if subject:
            if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS:
                otrans = i18n.get_translation()
                try:
                    i18n.set_language(self._lang)
                    atmark = unicode(_(' at '), Utils.GetCharSet(self._lang))
                    subject = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
                              '\g<1>' + atmark + '\g<2>', subject)
                finally:
                    i18n.set_translation(otrans)
            self.decoded['subject'] = subject
        self.decoded['stripped'] = self.strip_subject(subject or self.subject)
Example #7
0
 def sendProbe(self, member, msg):
     listname = self.real_name
     # Put together the substitution dictionary.
     d = {
         "listname": listname,
         "address": member,
         "optionsurl": self.GetOptionsURL(member, absolute=True),
         "owneraddr": self.GetOwnerEmail(),
     }
     text = Utils.maketext("probe.txt", d, lang=self.getMemberLanguage(member), mlist=self)
     # Calculate the VERP'd sender address for bounce processing of the
     # probe message.
     token = self.pend_new(Pending.PROBE_BOUNCE, member, msg)
     probedict = {"bounces": self.internal_name() + "-bounces", "token": token}
     probeaddr = "%s@%s" % ((mm_cfg.VERP_PROBE_FORMAT % probedict), self.host_name)
     # Calculate the Subject header, in the member's preferred language
     ulang = self.getMemberLanguage(member)
     otrans = i18n.get_translation()
     i18n.set_language(ulang)
     try:
         subject = _("%(listname)s mailing list probe message")
     finally:
         i18n.set_translation(otrans)
     outer = Message.UserNotification(member, probeaddr, subject, lang=ulang)
     outer.set_type("multipart/mixed")
     text = MIMEText(text, _charset=Utils.GetCharSet(ulang))
     outer.attach(text)
     outer.attach(MIMEMessage(msg))
     # Turn off further VERP'ing in the final delivery step.  We set
     # probe_token for the OutgoingRunner to more easily handling local
     # rejects of probe messages.
     outer.send(self, envsender=probeaddr, verp=False, probe_token=token)
Example #8
0
def unsubscription_confirm(mlist, doc, cookie):
    # See the comment in admin.py about the need for the signal
    # handler.
    def sigterm_handler(signum, frame, mlist=mlist):
        mlist.Unlock()
        sys.exit(0)

    mlist.Lock()
    try:
        try:
            # Do this in two steps so we can get the preferred language for
            # the user who is unsubscribing.
            op, addr = mlist.pend_confirm(cookie, expunge=False)
            lang = mlist.getMemberLanguage(addr)
            i18n.set_language(lang)
            doc.set_language(lang)
            op, addr = mlist.ProcessConfirmation(cookie)
        except Errors.NotAMemberError:
            bad_confirmation(doc, _('''Invalid confirmation string.  It is
            possible that you are attempting to confirm a request for an
            address that has already been unsubscribed.'''))
        else:
            # The response
            listname = mlist.real_name
            title = _('Unsubscription request confirmed')
            listinfourl = mlist.GetScriptURL('listinfo', absolute=1)
            doc.SetTitle(title)
            doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
            doc.AddItem(_("""\
            You have successfully unsubscribed from the %(listname)s mailing
            list.  You can now <a href="%(listinfourl)s">visit the list's main
            information page</a>."""))
        mlist.Save()
    finally:
        mlist.Unlock()
Example #9
0
    def html_foot(self):
        # avoid i18n side-effects
        mlist = self.maillist
        otrans = i18n.get_translation()
        i18n.set_language(mlist.preferred_language)

        # Convenience
        def quotetime(s):
            return html_quote(i18n.ctime(s), self.lang)

        try:
            d = {
                "lastdate": quotetime(self.lastdate),
                "archivedate": quotetime(self.archivedate),
                "listinfo": mlist.GetScriptURL('listinfo', absolute=1),
                "version": self.version,
                "listname": html_quote(mlist.real_name, self.lang),
            }
            i = {
                "thread": _("thread"),
                "subject": _("subject"),
                "author": _("author"),
                "date": _("date")
            }
        finally:
            i18n.set_translation(otrans)

        for t in i.keys():
            cap = t[0].upper() + t[1:]
            if self.type == cap:
                d["%s_ref" % (t)] = ""
            else:
                d["%s_ref" % (t)] = ('<a href="%s.html#start">[ %s ]</a>' %
                                     (t, i[t]))
        return quick_maketext('archidxfoot.html', d, mlist=mlist)
 def __refuse(self, request, recip, comment, origmsg=None, lang=None):
     # As this message is going to the requestor, try to set the language
     # to his/her language choice, if they are a member.  Otherwise use the
     # list's preferred language.
     realname = self.real_name
     if lang is None:
         lang = self.getMemberLanguage(recip)
     text = Utils.maketext('refuse.txt', {
         'listname': realname,
         'request': request,
         'reason': comment,
         'adminaddr': self.GetOwnerEmail(),
     },
                           lang=lang,
                           mlist=self)
     otrans = i18n.get_translation()
     i18n.set_language(lang)
     try:
         # add in original message, but not wrap/filled
         if origmsg:
             text = NL.join([
                 text,
                 '---------- ' + _('Original Message') + ' ----------',
                 str(origmsg)
             ])
         subject = _('Request to mailing list %(realname)s rejected')
     finally:
         i18n.set_translation(otrans)
     msg = Message.UserNotification(recip, self.GetOwnerEmail(), subject,
                                    text, lang)
     msg.send(self)
Example #11
0
 def _setValue(self, mlist, property, val, doc):
     # If we're changing the list's preferred language, change the I18N
     # context as well
     if property == 'preferred_language':
         i18n.set_language(val)
         doc.set_language(val)
     GUIBase._setValue(self, mlist, property, val, doc)
Example #12
0
 def SendUnsubscribeAck(self, addr, lang):
     realname = self.real_name
     i18n.set_language(lang)
     msg = Message.UserNotification(
         self.GetMemberAdminEmail(addr), self.GetBouncesEmail(),
         _('You have been unsubscribed from the %(realname)s mailing list'),
         Utils.wrap(self.goodbye_msg), lang)
     msg.send(self, verp=mm_cfg.VERP_PERSONALIZED_DELIVERIES)
Example #13
0
 def SendUnsubscribeAck(self, addr, lang):
     realname = self.real_name
     i18n.set_language(lang)
     msg = Message.UserNotification(
         self.GetMemberAdminEmail(addr), self.GetBouncesEmail(),
         _('You have been unsubscribed from the %(realname)s mailing list'),
         Utils.wrap(self.goodbye_msg), lang)
     msg.send(self, verp=mm_cfg.VERP_PERSONALIZED_DELIVERIES)
Example #14
0
def addrchange_confirm(mlist, doc, cookie):
    # See the comment in admin.py about the need for the signal
    # handler.
    def sigterm_handler(signum, frame, mlist=mlist):
        mlist.Unlock()
        sys.exit(0)

    mlist.Lock()
    try:
        try:
            # Do this in two steps so we can get the preferred language for
            # the user who is unsubscribing.
            op, oldaddr, newaddr, globally = mlist.pend_confirm(cookie,
                                                                expunge=False)
            lang = mlist.getMemberLanguage(oldaddr)
            i18n.set_language(lang)
            doc.set_language(lang)
            op, oldaddr, newaddr = mlist.ProcessConfirmation(cookie)
        except Errors.NotAMemberError:
            bad_confirmation(
                doc,
                _('''Invalid confirmation string.  It is
            possible that you are attempting to confirm a request for an
            address that has already been unsubscribed.'''))
        except Errors.MembershipIsBanned:
            owneraddr = mlist.GetOwnerEmail()
            realname = mlist.real_name
            doc.addError(
                _("""%(newaddr)s is banned from subscribing to the
            %(realname)s list.  If you think this restriction is erroneous,
            please contact the list owners at %(owneraddr)s."""))
        except Errors.MMAlreadyAMember:
            realname = mlist.real_name
            bad_confirmation(
                doc,
                _("""%(newaddr)s is already a member of
            the %(realname)s list.  It is possible that you are attempting
            to confirm a request for an address that has already been
            subscribed."""))
        else:
            # The response
            listname = mlist.real_name
            title = _('Change of address request confirmed')
            optionsurl = mlist.GetOptionsURL(newaddr, absolute=1)
            doc.SetTitle(title)
            doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
            doc.AddItem(
                _("""\
            You have successfully changed your address on the %(listname)s
            mailing list from <b>%(oldaddr)s</b> to <b>%(newaddr)s</b>.  You
            can now <a href="%(optionsurl)s">proceed to your membership
            login page</a>."""))
        mlist.Save()
    finally:
        mlist.Unlock()
Example #15
0
def addrchange_prompt(mlist, doc, cookie, oldaddr, newaddr, globally):
    title = _('Confirm change of address request')
    doc.SetTitle(title)
    lang = mlist.getMemberLanguage(oldaddr)
    i18n.set_language(lang)
    doc.set_language(lang)

    form = Form(mlist.GetScriptURL('confirm', 1))
    table = Table(border=0, width='100%')
    table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
    table.AddCellInfo(table.GetCurrentRowIndex(),
                      0,
                      colspan=2,
                      bgcolor=mm_cfg.WEB_HEADER_COLOR)

    listname = mlist.real_name
    fullname = mlist.getMemberName(oldaddr)
    if fullname is None:
        fullname = _('<em>Not available</em>')
    else:
        fullname = Utils.websafe(Utils.uncanonstr(fullname, lang))
    if globally:
        globallys = _('globally')
    else:
        globallys = ''
    table.AddRow([
        _("""Your confirmation is required in order to complete the
    change of address request for the mailing list <em>%(listname)s</em>.  You
    are currently subscribed with

    <ul><li><b>Real name:</b> %(fullname)s
        <li><b>Old email address:</b> %(oldaddr)s
    </ul>

    and you have requested to %(globallys)s change your email address to

    <ul><li><b>New email address:</b> %(newaddr)s
    </ul>

    Hit the <em>Change address</em> button below to complete the confirmation
    process.

    <p>Or hit <em>Cancel and discard</em> to cancel this change of address
    request.""") + '<p><hr>'
    ])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
    table.AddRow([Hidden('cookie', cookie)])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
    table.AddRow([
        SubmitButton('submit', _('Change address')),
        SubmitButton('cancel', _('Cancel and discard'))
    ])

    form.AddItem(table)
    doc.AddItem(form)
Example #16
0
def subscription_cancel(mlist, doc, cookie):
    mlist.Lock()
    try:
        # Discard this cookie
        userdesc = mlist.pend_confirm(cookie)[1]
    finally:
        mlist.Unlock()
    lang = userdesc.language
    i18n.set_language(lang)
    doc.set_language(lang)
    doc.AddItem(_('You have canceled your subscription request.'))
Example #17
0
def subscription_cancel(mlist, doc, cookie):
    mlist.Lock()
    try:
        # Discard this cookie
        userdesc = mlist.pend_confirm(cookie)[1]
    finally:
        mlist.Unlock()
    lang = userdesc.language
    i18n.set_language(lang)
    doc.set_language(lang)
    doc.AddItem(_('You have canceled your subscription request.'))
def main():
    cgidata = cgi.FieldStorage()
    language = cgidata.getvalue('language')
    parts = Utils.GetPathPieces()
    i18n.set_language(language)
    openidreg_overview(language)   
    if (cgidata.has_key("action") and cgidata.has_key("listname") and cgidata.has_key("reg-pw") and cgidata.has_key("reg-email")):
             if (cgidata["action"].value == "display"):
                result = test(cgidata["listname"].value, cgidata["reg-pw"].value, cgidata["reg-email"].value)
                display_page(result)
    else:
             print "<B> Fields are blank, please enter correct Username , Password and choose your list </B>"
    FormatOpenIDLogin()
Example #19
0
def main():
    # Trick out pygettext since we want to mark template_data as translatable,
    # but we don't want to actually translate it here.
    def _(s):
        return s

    template_data = (
        ('listinfo.html', _('General list information page')),
        ('subscribe.html', _('Subscribe results page')),
        ('options.html', _('User specific options page')),
        ('subscribeack.txt', _('Welcome email text file')),
        ('masthead.txt', _('Digest masthead')),
        ('postheld.txt', _('User notice of held post')),
        ('approve.txt', _('User notice of held subscription')),
        ('refuse.txt', _('Notice of post refused by moderator')),
        ('invite.txt', _('Invitation to join list')),
        ('verify.txt', _('Request to confirm subscription')),
        ('unsub.txt', _('Request to confirm unsubscription')),
        ('nomoretoday.txt', _('User notice of autoresponse limit')),
        ('postack.txt', _('User post acknowledgement')),
        ('disabled.txt', _('Subscription disabled by bounce warning')),
        ('admlogin.html', _('Admin/moderator login page')),
        ('private.html', _('Private archive login page')),
        ('userpass.txt', _('On demand password reminder')),
    )

    _ = i18n._
    doc = Document()

    # Set up the system default language
    i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
    doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)

    parts = Utils.GetPathPieces()
    if not parts:
        doc.AddItem(Header(2, _("List name is required.")))
        print doc.Format()
        return

    listname = parts[0].lower()
    try:
        mlist = MailList.MailList(listname, lock=0)
    except Errors.MMListError, e:
        # Avoid cross-site scripting attacks
        safelistname = Utils.websafe(listname)
        doc.AddItem(Header(2, _('No such list <em>%(safelistname)s</em>')))
        # Send this with a 404 status.
        print 'Status: 404 Not Found'
        print doc.Format()
        syslog('error', 'edithtml: No such list "%s": %s', listname, e)
        return
Example #20
0
    def SendSubscribeAck(self, name, password, digest, text=""):
        pluser = self.getMemberLanguage(name)
        # Need to set this here to get the proper l10n of the Subject:
        i18n.set_language(pluser)
        if self.welcome_msg:
            welcome = Utils.wrap(self.welcome_msg) + "\n"
        else:
            welcome = ""
        if self.umbrella_list:
            addr = self.GetMemberAdminEmail(name)
            umbrella = Utils.wrap(
                _(
                    """\
Note: Since this is a list of mailing lists, administrative
notices like the password reminder will be sent to
your membership administrative address, %(addr)s."""
                )
            )
        else:
            umbrella = ""
        # get the text from the template
        text += Utils.maketext(
            "subscribeack.txt",
            {
                "real_name": self.real_name,
                "host_name": self.host_name,
                "welcome": welcome,
                "umbrella": umbrella,
                "emailaddr": self.GetListEmail(),
                "listinfo_url": self.GetScriptURL("listinfo", absolute=True),
                "optionsurl": self.GetOptionsURL(name, absolute=True),
                "password": password,
                "user": self.getMemberCPAddress(name),
            },
            lang=pluser,
            mlist=self,
        )
        if digest:
            digmode = _(" (Digest mode)")
        else:
            digmode = ""
        realname = self.real_name
        msg = Message.UserNotification(
            self.GetMemberAdminEmail(name),
            self.GetRequestEmail(),
            _('Welcome to the "%(realname)s" mailing list%(digmode)s'),
            text,
            pluser,
        )
        msg["X-No-Archive"] = "yes"
        msg.send(self, verp=mm_cfg.VERP_PERSONALIZED_DELIVERIES)
    def as_html(self):
        """Different attributes that can be used when generating a html file from a template for the archives."""	
        d = self.__dict__.copy()
        # avoid i18n side-effects
        otrans = i18n.get_translation()
        i18n.set_language(self._lang)
        try:
            d["prev"], d["prev_wsubj"] = self._get_prev()
            d["next"], d["next_wsubj"] = self._get_next()

            d["email_html"] = self.quote(self.email)
            d["title"] = self.quote(self.subject)
            d["subject_html"] = self.quote(self.subject)
            # TK: These two _url variables are used to compose a response
            # from the archive web page.  So, ...
            # Possibly remove since not used??
            d["subject_url"] = url_quote('Re: ' + self.subject)
            d["in_reply_to_url"] = url_quote(self._message_id)
            if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS:
                # Point the mailto url back to the list
                author = re.sub('@', _(' at '), self.author)
                emailurl = self._mlist.GetListEmail()
            else:
                author = self.author
                emailurl = self.email
            d["author_html"] = self.quote(author)
            d["email_url"] = url_quote(emailurl)
            d["datestr_html"] = self.quote(i18n.ctime(int(self.date)))
            d["body"] = self._get_body()
            d['listurl'] = self._mlist.GetScriptURL('listinfo', absolute=1)
            d['listname'] = self._mlist.real_name
            d['encoding'] = ''
            try:
                # This should work after a couple of emails has been send and the thread 
                # address has been set, but to not get an error in the beginning the error 
                # is caught and an already existing address is provided. Is for dlists.
                d['thread_addr'] = self.thread_addr
                d['thread_addr_at'] = re.sub('@', _(' at '), self.thread_addr)
            except:
                d['thread_addr'] = d["email_url"]
                d['thread_addr_at'] = d["email_url"]
        finally:
            i18n.set_translation(otrans)

        charset = Utils.GetCharSet(self._lang)
        d["encoding"] = html_charset % charset

        self._add_decoded(d)
        return quick_maketext(
             'article.html', d,
             lang=self._lang, mlist=self._mlist)
Example #22
0
 def _dispose(self, mlist, msg, msgdata):
     # Support clobber_date, i.e. setting the date in the archive to the
     # received date, not the (potentially bogus) Date: header of the
     # original message.
     clobber = 0
     originaldate = msg.get('date')
     receivedtime = formatdate(msgdata['received_time'])
     if not originaldate:
         clobber = 1
     elif mm_cfg.ARCHIVER_CLOBBER_DATE_POLICY == 1:
         clobber = 1
     elif mm_cfg.ARCHIVER_CLOBBER_DATE_POLICY == 2:
         # what's the timestamp on the original message?
         tup = parsedate_tz(originaldate)
         now = time.time()
         try:
             if not tup:
                 clobber = 1
             elif abs(now - mktime_tz(tup)) > \
                      mm_cfg.ARCHIVER_ALLOWABLE_SANE_DATE_SKEW:
                 clobber = 1
         except (ValueError, OverflowError):
             # The likely cause of this is that the year in the Date: field
             # is horribly incorrect, e.g. (from SF bug # 571634):
             # Date: Tue, 18 Jun 0102 05:12:09 +0500
             # Obviously clobber such dates.
             clobber = 1
     if clobber:
         del msg['date']
         del msg['x-original-date']
         msg['Date'] = receivedtime
         if originaldate:
             msg['X-Original-Date'] = originaldate
     # Always put an indication of when we received the message.
     msg['X-List-Received-Date'] = receivedtime
     # Now try to get the list lock
     try:
         mlist.Lock(timeout=mm_cfg.LIST_LOCK_TIMEOUT)
     except LockFile.TimeOutError:
         # oh well, try again later
         return 1
     try:
         # Archiving should be done in the list's preferred language, not
         # the sender's language.
         i18n.set_language(mlist.preferred_language)
         mlist.ArchiveMail(msg)
         mlist.Save()
     finally:
         mlist.Unlock()
Example #23
0
def addrchange_confirm(mlist, doc, cookie):
    # See the comment in admin.py about the need for the signal
    # handler.
    def sigterm_handler(signum, frame, mlist=mlist):
        mlist.Unlock()
        sys.exit(0)

    mlist.Lock()
    try:
        try:
            # Do this in two steps so we can get the preferred language for
            # the user who is unsubscribing.
            op, oldaddr, newaddr, globally = mlist.pend_confirm(
                cookie, expunge=False)
            lang = mlist.getMemberLanguage(oldaddr)
            i18n.set_language(lang)
            doc.set_language(lang)
            op, oldaddr, newaddr = mlist.ProcessConfirmation(cookie)
        except Errors.NotAMemberError:
            bad_confirmation(doc, _('''Invalid confirmation string.  It is
            possible that you are attempting to confirm a request for an
            address that has already been unsubscribed.'''))
        except Errors.MembershipIsBanned:
            owneraddr = mlist.GetOwnerEmail()
            realname = mlist.real_name
            doc.addError(_("""%(newaddr)s is banned from subscribing to the
            %(realname)s list.  If you think this restriction is erroneous,
            please contact the list owners at %(owneraddr)s."""))
        except Errors.MMAlreadyAMember:
            realname = mlist.real_name
            bad_confirmation(doc, _("""%(newaddr)s is already a member of
            the %(realname)s list.  It is possible that you are attempting
            to confirm a request for an address that has already been
            subscribed."""))
        else:
            # The response
            listname = mlist.real_name
            title = _('Change of address request confirmed')
            optionsurl = mlist.GetOptionsURL(newaddr, absolute=1)
            doc.SetTitle(title)
            doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
            doc.AddItem(_("""\
            You have successfully changed your address on the %(listname)s
            mailing list from <b>%(oldaddr)s</b> to <b>%(newaddr)s</b>.  You
            can now <a href="%(optionsurl)s">proceed to your membership
            login page</a>."""))
        mlist.Save()
    finally:
        mlist.Unlock()
Example #24
0
def addrchange_prompt(mlist, doc, cookie, oldaddr, newaddr, globally):
    title = _('Confirm change of address request')
    doc.SetTitle(title)
    lang = mlist.getMemberLanguage(oldaddr)
    i18n.set_language(lang)
    doc.set_language(lang)

    form = Form(mlist.GetScriptURL('confirm', 1))
    table = Table(border=0, width='100%')
    table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0,
                      colspan=2, bgcolor=mm_cfg.WEB_HEADER_COLOR)

    listname = mlist.real_name
    fullname = mlist.getMemberName(oldaddr)
    if fullname is None:
        fullname = _('<em>Not available</em>')
    else:
        fullname = Utils.websafe(Utils.uncanonstr(fullname, lang))
    if globally:
        globallys = _('globally')
    else:
        globallys = ''
    table.AddRow([_("""Your confirmation is required in order to complete the
    change of address request for the mailing list <em>%(listname)s</em>.  You
    are currently subscribed with

    <ul><li><b>Real name:</b> %(fullname)s
        <li><b>Old email address:</b> %(oldaddr)s
    </ul>

    and you have requested to %(globallys)s change your email address to

    <ul><li><b>New email address:</b> %(newaddr)s
    </ul>

    Hit the <em>Change address</em> button below to complete the confirmation
    process.

    <p>Or hit <em>Cancel and discard</em> to cancel this change of address
    request.""") + '<p><hr>'])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
    table.AddRow([Hidden('cookie', cookie)])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
    table.AddRow([SubmitButton('submit', _('Change address')),
                  SubmitButton('cancel', _('Cancel and discard'))])

    form.AddItem(table)
    doc.AddItem(form)
Example #25
0
    def SendHostileSubscriptionNotice(self, listname, address):
        # Some one was invited to one list but tried to confirm to a different
        # list.  We inform both list owners of the bogosity, but be careful
        # not to reveal too much information.
        selfname = self.internal_name()
        syslog("mischief", "%s was invited to %s but confirmed to %s", address, listname, selfname)
        # First send a notice to the attacked list
        msg = Message.OwnerNotification(
            self,
            _("Hostile subscription attempt detected"),
            Utils.wrap(
                _(
                    """%(address)s was invited to a different mailing
list, but in a deliberate malicious attempt they tried to confirm the
invitation to your list.  We just thought you'd like to know.  No further
action by you is required."""
                )
            ),
        )
        msg.send(self)
        # Now send a notice to the invitee list
        try:
            # Avoid import loops
            from Mailman.MailList import MailList

            mlist = MailList(listname, lock=False)
        except Errors.MMListError:
            # Oh well
            return
        otrans = i18n.get_translation()
        i18n.set_language(mlist.preferred_language)
        try:
            msg = Message.OwnerNotification(
                mlist,
                _("Hostile subscription attempt detected"),
                Utils.wrap(
                    _(
                        """You invited %(address)s to your list, but in a
deliberate malicious attempt, they tried to confirm the invitation to a
different list.  We just thought you'd like to know.  No further action by you
is required."""
                    )
                ),
            )
            msg.send(mlist)
        finally:
            i18n.set_translation(otrans)
Example #26
0
 def _onefile(self, msg, msgdata):
     # Do some common sanity checking on the message metadata.  It's got to
     # be destined for a particular mailing list.  This switchboard is used
     # to shunt off badly formatted messages.  We don't want to just trash
     # them because they may be fixable with human intervention.  Just get
     # them out of our site though.
     #
     # Find out which mailing list this message is destined for.
     listname = msgdata.get('listname')
     if not listname:
         listname = mm_cfg.MAILMAN_SITE_LIST
     mlist = self._open_list(listname)
     if not mlist:
         syslog('error',
                'Dequeuing message destined for missing list: %s',
                listname)
         self._shunt.enqueue(msg, msgdata)
         return
     # Now process this message, keeping track of any subprocesses that may
     # have been spawned.  We'll reap those later.
     #
     # We also want to set up the language context for this message.  The
     # context will be the preferred language for the user if a member of
     # the list, or the list's preferred language.  However, we must take
     # special care to reset the defaults, otherwise subsequent messages
     # may be translated incorrectly.  BAW: I'm not sure I like this
     # approach, but I can't think of anything better right now.
     otranslation = i18n.get_translation()
     sender = msg.get_sender()
     if mlist:
         lang = mlist.getMemberLanguage(sender)
     else:
         lang = mm_cfg.DEFAULT_SERVER_LANGUAGE
     i18n.set_language(lang)
     msgdata['lang'] = lang
     try:
         keepqueued = self._dispose(mlist, msg, msgdata)
     finally:
         i18n.set_translation(otranslation)
     # Keep tabs on any child processes that got spawned.
     kids = msgdata.get('_kids')
     if kids:
         self._kids.update(kids)
     if keepqueued:
         self._switchboard.enqueue(msg, msgdata)
Example #27
0
def heldmsg_confirm(mlist, doc, cookie):
    # See the comment in admin.py about the need for the signal
    # handler.
    def sigterm_handler(signum, frame, mlist=mlist):
        mlist.Unlock()
        sys.exit(0)

    mlist.Lock()
    try:
        try:
            # Do this in two steps so we can get the preferred language for
            # the user who posted the message.
            subject = 'n/a'
            op, id = mlist.pend_confirm(cookie)
            ign, sender, msgsubject, ign, ign, ign = mlist.GetRecord(id)
            lang = mlist.getMemberLanguage(sender)
            subject = Utils.websafe(
                Utils.oneline(msgsubject, Utils.GetCharSet(lang)))
            i18n.set_language(lang)
            doc.set_language(lang)
            # Discard the message
            mlist.HandleRequest(id, mm_cfg.DISCARD,
                                _('Sender discarded message via web.'))
        except (Errors.LostHeldMessage, KeyError):
            bad_confirmation(
                doc,
                _('''The held message with the Subject:
            header <em>%(subject)s</em> could not be found.  The most likely
            reason for this is that the list moderator has already approved or
            rejected the message.  You were not able to cancel it in
            time.'''))
        else:
            # The response
            listname = mlist.real_name
            title = _('Posted message canceled')
            doc.SetTitle(title)
            doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
            doc.AddItem(
                _('''\
            You have successfully canceled the posting of your message with
            the Subject: header <em>%(subject)s</em> to the mailing list
            %(listname)s.'''))
        mlist.Save()
    finally:
        mlist.Unlock()
Example #28
0
 def _onefile(self, msg, msgdata):
     # Do some common sanity checking on the message metadata.  It's got to
     # be destined for a particular mailing list.  This switchboard is used
     # to shunt off badly formatted messages.  We don't want to just trash
     # them because they may be fixable with human intervention.  Just get
     # them out of our site though.
     #
     # Find out which mailing list this message is destined for.
     listname = msgdata.get('listname')
     if not listname:
         listname = mm_cfg.MAILMAN_SITE_LIST
     mlist = self._open_list(listname)
     if not mlist:
         syslog('error', 'Dequeuing message destined for missing list: %s',
                listname)
         self._shunt.enqueue(msg, msgdata)
         return
     # Now process this message, keeping track of any subprocesses that may
     # have been spawned.  We'll reap those later.
     #
     # We also want to set up the language context for this message.  The
     # context will be the preferred language for the user if a member of
     # the list, or the list's preferred language.  However, we must take
     # special care to reset the defaults, otherwise subsequent messages
     # may be translated incorrectly.  BAW: I'm not sure I like this
     # approach, but I can't think of anything better right now.
     otranslation = i18n.get_translation()
     sender = msg.get_sender()
     if mlist:
         lang = mlist.getMemberLanguage(sender)
     else:
         lang = mm_cfg.DEFAULT_SERVER_LANGUAGE
     i18n.set_language(lang)
     msgdata['lang'] = lang
     try:
         keepqueued = self._dispose(mlist, msg, msgdata)
     finally:
         i18n.set_translation(otranslation)
     # Keep tabs on any child processes that got spawned.
     kids = msgdata.get('_kids')
     if kids:
         self._kids.update(kids)
     if keepqueued:
         self._switchboard.enqueue(msg, msgdata)
Example #29
0
    def html_TOC(self):
        mlist = self.maillist
        listname = mlist.internal_name()
        mbox = os.path.join(mlist.archive_dir() + '.mbox', listname + '.mbox')
        d = {
            "listname": mlist.real_name,
            "listinfo": mlist.GetScriptURL('listinfo', absolute=1),
            "fullarch": '../%s.mbox/%s.mbox' % (listname, listname),
            "size": sizeof(mbox, mlist.preferred_language),
            'meta': '',
        }
        # Avoid i18n side-effects
        otrans = i18n.get_translation()
        i18n.set_language(mlist.preferred_language)
        try:
            if not self.archives:
                d["noarchive_msg"] = _(
                    '<P>Currently, there are no archives. </P>')
                d["archive_listing_start"] = ""
                d["archive_listing_end"] = ""
                d["archive_listing"] = ""
            else:
                d["noarchive_msg"] = ""
                d["archive_listing_start"] = quick_maketext(
                    'archliststart.html',
                    lang=mlist.preferred_language,
                    mlist=mlist)
                d["archive_listing_end"] = quick_maketext('archlistend.html',
                                                          mlist=mlist)

                accum = []
                for a in self.archives:
                    accum.append(self.html_TOC_entry(a))
                d["archive_listing"] = EMPTYSTRING.join(accum)
        finally:
            i18n.set_translation(otrans)
        # The TOC is always in the charset of the list's preferred language
        d['meta'] += html_charset % Utils.GetCharSet(mlist.preferred_language)
        # The site can disable public access to the mbox file.
        if mm_cfg.PUBLIC_MBOX:
            template = 'archtoc.html'
        else:
            template = 'archtocnombox.html'
        return quick_maketext(template, d, mlist=mlist)
Example #30
0
    def html_TOC(self):
        mlist = self.maillist
        listname = mlist.internal_name()
        mbox = os.path.join(mlist.archive_dir()+'.mbox', listname+'.mbox')
        d = {"listname": mlist.real_name,
             "listinfo": mlist.GetScriptURL('listinfo', absolute=1),
             "fullarch": '../%s.mbox/%s.mbox' % (listname, listname),
             "size": sizeof(mbox, mlist.preferred_language),
             'meta': '',
             }
        # Avoid i18n side-effects
        otrans = i18n.get_translation()
        i18n.set_language(mlist.preferred_language)
        try:
            if not self.archives:
                d["noarchive_msg"] = _(
                    '<P>Currently, there are no archives. </P>')
                d["archive_listing_start"] = ""
                d["archive_listing_end"] = ""
                d["archive_listing"] = ""
            else:
                d["noarchive_msg"] = ""
                d["archive_listing_start"] = quick_maketext(
                    'archliststart.html',
                    lang=mlist.preferred_language,
                    mlist=mlist)
                d["archive_listing_end"] = quick_maketext(
                    'archlistend.html',
                    mlist=mlist)

                accum = []
                for a in self.archives:
                    accum.append(self.html_TOC_entry(a))
                d["archive_listing"] = EMPTYSTRING.join(accum)
        finally:
            i18n.set_translation(otrans)
        # The TOC is always in the charset of the list's preferred language
        d['meta'] += html_charset % Utils.GetCharSet(mlist.preferred_language)
        # The site can disable public access to the mbox file.
        if mm_cfg.PUBLIC_MBOX:
            template = 'archtoc.html'
        else:
            template = 'archtocnombox.html'
        return quick_maketext(template, d, mlist=mlist)
Example #31
0
 def HoldSubscription(self, addr, fullname, password, digest, lang):
     # Assure that the database is open for writing
     self.__opendb()
     # Get the next unique id
     id = self.__nextid()
     # Save the information to the request database. for held subscription
     # entries, each record in the database will be one of the following
     # format:
     #
     # the time the subscription request was received
     # the subscriber's address
     # the subscriber's selected password (TBD: is this safe???)
     # the digest flag
     # the user's preferred language
     data = time.time(), addr, fullname, password, digest, lang
     self.__db[id] = (SUBSCRIPTION, data)
     #
     # TBD: this really shouldn't go here but I'm not sure where else is
     # appropriate.
     syslog('vette', '%s: held subscription request from %s',
            self.internal_name(), addr)
     # Possibly notify the administrator in default list language
     if self.admin_immed_notify:
         ## cpanel patch: is the str() handling still needed?
         i18n.set_language(self.preferred_language)
         realname = str(self.real_name)
         subject = _(
             'New subscription request to list %(realname)s from %(addr)s')
         text = Utils.maketext(
             'subauth.txt', {
                 'username': addr,
                 'listname': self.real_name,
                 'hostname': self.host_name,
                 'admindb_url': self.GetScriptURL('admindb', absolute=1),
             },
             mlist=self)
         # This message should appear to come from the <list>-owner so as
         # to avoid any useless bounce processing.
         owneraddr = self.GetOwnerEmail()
         msg = Message.UserNotification(owneraddr, owneraddr, subject, text,
                                        self.preferred_language)
         msg.send(self, **{'tomoderators': 1})
         # Restore the user's preferred language.
         i18n.set_language(lang)
Example #32
0
    def SendSubscribeAck(self, name, password, digest, text=''):
        pluser = self.getMemberLanguage(name)
        # Need to set this here to get the proper l10n of the Subject:
        i18n.set_language(pluser)
        if self.welcome_msg:
            welcome = Utils.wrap(self.welcome_msg) + '\n'
        else:
            welcome = ''
        if self.umbrella_list:
            addr = self.GetMemberAdminEmail(name)
            umbrella = Utils.wrap(
                _('''\
Note: Since this is a list of mailing lists, administrative
notices like the password reminder will be sent to
your membership administrative address, %(addr)s.'''))
        else:
            umbrella = ''
        # get the text from the template
        text += Utils.maketext(
            'subscribeack.txt', {
                'real_name': self.real_name,
                'host_name': self.host_name,
                'welcome': welcome,
                'umbrella': umbrella,
                'emailaddr': self.GetListEmail(),
                'listinfo_url': self.GetScriptURL('listinfo', absolute=True),
                'optionsurl': self.GetOptionsURL(name, absolute=True),
                'password': password,
                'user': self.getMemberCPAddress(name),
            },
            lang=pluser,
            mlist=self)
        if digest:
            digmode = _(' (Digest mode)')
        else:
            digmode = ''
        realname = self.real_name
        msg = Message.UserNotification(
            self.GetMemberAdminEmail(name), self.GetRequestEmail(),
            _('Welcome to the "%(realname)s" mailing list%(digmode)s'), text,
            pluser)
        msg['X-No-Archive'] = 'yes'
        msg.send(self, verp=mm_cfg.VERP_PERSONALIZED_DELIVERIES)
Example #33
0
 def HoldSubscription(self, addr, fullname, password, digest, lang):
     # Assure that the database is open for writing
     self.__opendb()
     # Get the next unique id
     id = self.__nextid()
     # Save the information to the request database. for held subscription
     # entries, each record in the database will be one of the following
     # format:
     #
     # the time the subscription request was received
     # the subscriber's address
     # the subscriber's selected password (TBD: is this safe???)
     # the digest flag
     # the user's preferred language
     data = time.time(), addr, fullname, password, digest, lang
     self.__db[id] = (SUBSCRIPTION, data)
     #
     # TBD: this really shouldn't go here but I'm not sure where else is
     # appropriate.
     syslog('vette', '%s: held subscription request from %s',
            self.internal_name(), addr)
     # Possibly notify the administrator in default list language
     if self.admin_immed_notify:
         ## cpanel patch: is the str() handling still needed?
         i18n.set_language(self.preferred_language)
         realname = str(self.real_name)
         subject = _(
             'New subscription request to list %(realname)s from %(addr)s')
         text = Utils.maketext(
             'subauth.txt',
             {'username'   : addr,
              'listname'   : self.real_name,
              'hostname'   : self.host_name,
              'admindb_url': self.GetScriptURL('admindb', absolute=1),
              }, mlist=self)
         # This message should appear to come from the <list>-owner so as
         # to avoid any useless bounce processing.
         owneraddr = self.GetOwnerEmail()
         msg = Message.UserNotification(owneraddr, owneraddr, subject, text,
                                        self.preferred_language)
         msg.send(self, **{'tomoderators': 1})
         # Restore the user's preferred language.
         i18n.set_language(lang)
Example #34
0
 def sendProbe(self, member, msg):
     listname = self.real_name
     # Put together the substitution dictionary.
     d = {
         'listname': listname,
         'address': member,
         'optionsurl': self.GetOptionsURL(member, absolute=True),
         'owneraddr': self.GetOwnerEmail(),
     }
     text = Utils.maketext('probe.txt',
                           d,
                           lang=self.getMemberLanguage(member),
                           mlist=self)
     # Calculate the VERP'd sender address for bounce processing of the
     # probe message.
     token = self.pend_new(Pending.PROBE_BOUNCE, member, msg)
     probedict = {
         'bounces': self.internal_name() + '-bounces',
         'token': token,
     }
     probeaddr = '%s@%s' % (
         (mm_cfg.VERP_PROBE_FORMAT % probedict), self.host_name)
     # Calculate the Subject header, in the member's preferred language
     ulang = self.getMemberLanguage(member)
     otrans = i18n.get_translation()
     i18n.set_language(ulang)
     try:
         subject = _('%(listname)s mailing list probe message')
     finally:
         i18n.set_translation(otrans)
     outer = Message.UserNotification(member,
                                      probeaddr,
                                      subject,
                                      lang=ulang)
     outer.set_type('multipart/mixed')
     text = MIMEText(text, _charset=Utils.GetCharSet(ulang))
     outer.attach(text)
     outer.attach(MIMEMessage(msg))
     # Turn off further VERP'ing in the final delivery step.  We set
     # probe_token for the OutgoingRunner to more easily handling local
     # rejects of probe messages.
     outer.send(self, envsender=probeaddr, verp=False, probe_token=token)
Example #35
0
def heldmsg_confirm(mlist, doc, cookie):
    # See the comment in admin.py about the need for the signal
    # handler.
    def sigterm_handler(signum, frame, mlist=mlist):
        mlist.Unlock()
        sys.exit(0)

    mlist.Lock()
    try:
        try:
            # Do this in two steps so we can get the preferred language for
            # the user who posted the message.
            subject = 'n/a'
            op, id = mlist.pend_confirm(cookie)
            ign, sender, msgsubject, ign, ign, ign = mlist.GetRecord(id)
            lang = mlist.getMemberLanguage(sender)
            subject = Utils.websafe(Utils.oneline(msgsubject,
                                                  Utils.GetCharSet(lang)))
            i18n.set_language(lang)
            doc.set_language(lang)
            # Discard the message
            mlist.HandleRequest(id, mm_cfg.DISCARD,
                                _('Sender discarded message via web.'))
        except (Errors.LostHeldMessage, KeyError):
            bad_confirmation(doc, _('''The held message with the Subject:
            header <em>%(subject)s</em> could not be found.  The most likely
            reason for this is that the list moderator has already approved or
            rejected the message.  You were not able to cancel it in
            time.'''))
        else:
            # The response
            listname = mlist.real_name
            title = _('Posted message canceled')
            doc.SetTitle(title)
            doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
            doc.AddItem(_('''\
            You have successfully canceled the posting of your message with
            the Subject: header <em>%(subject)s</em> to the mailing list
            %(listname)s.'''))
        mlist.Save()
    finally:
        mlist.Unlock()
Example #36
0
    def as_html(self):
        d = self.__dict__.copy()
        # avoid i18n side-effects
        otrans = i18n.get_translation()
        i18n.set_language(self._lang)
        try:
            d["prev"], d["prev_wsubj"] = self._get_prev()
            d["next"], d["next_wsubj"] = self._get_next()

            d["email_html"] = self.quote(self.email)
            d["title"] = self.quote(self.subject)
            d["subject_html"] = self.quote(self.subject)
            d["message_id"] = self.quote(self._message_id)
            # TK: These two _url variables are used to compose a response
            # from the archive web page.  So, ...
            d["subject_url"] = url_quote('Re: ' + self.subject)
            d["in_reply_to_url"] = url_quote(self._message_id)
            if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS:
                # Point the mailto url back to the list
                author = re.sub('@', _(' at '), self.author)
                emailurl = self._mlist.GetListEmail()
            else:
                author = self.author
                emailurl = self.email
            d["author_html"] = self.quote(author)
            d["email_url"] = url_quote(emailurl)
            d["datestr_html"] = self.quote(i18n.ctime(int(self.date)))
            d["body"] = self._get_body()
            d['listurl'] = self._mlist.GetScriptURL('listinfo', absolute=1)
            d['listname'] = self._mlist.real_name
            d['encoding'] = ''
        finally:
            i18n.set_translation(otrans)

        charset = Utils.GetCharSet(self._lang)
        d["encoding"] = html_charset % charset

        self._add_decoded(d)
        return quick_maketext('article.html',
                              d,
                              lang=self._lang,
                              mlist=self._mlist)
Example #37
0
    def html_head(self):
        # avoid i18n side-effects
        mlist = self.maillist
        otrans = i18n.get_translation()
        i18n.set_language(mlist.preferred_language)

        # Convenience
        def quotetime(s):
            return html_quote(i18n.ctime(s), self.lang)

        try:
            d = {
                "listname": html_quote(mlist.real_name, self.lang),
                "archtype": self.type,
                "archive": self.volNameToDesc(self.archive),
                "listinfo": mlist.GetScriptURL('listinfo', absolute=1),
                "firstdate": quotetime(self.firstdate),
                "lastdate": quotetime(self.lastdate),
                "size": self.size,
            }
            i = {
                "thread": _("thread"),
                "subject": _("subject"),
                "author": _("author"),
                "date": _("date"),
            }
        finally:
            i18n.set_translation(otrans)

        for t in i.keys():
            cap = t[0].upper() + t[1:]
            if self.type == cap:
                d["%s_ref" % (t)] = ""
                d["archtype"] = i[t]
            else:
                d["%s_ref" % (t)] = ('<a href="%s.html#start">[ %s ]</a>' %
                                     (t, i[t]))
        if self.charset:
            d["encoding"] = html_charset % self.charset
        else:
            d["encoding"] = ""
        return quick_maketext('archidxhead.html', d, mlist=mlist)
    def as_html(self):
        d = self.__dict__.copy()
        # avoid i18n side-effects
        otrans = i18n.get_translation()
        i18n.set_language(self._lang)
        try:
            d["prev"], d["prev_wsubj"] = self._get_prev()
            d["next"], d["next_wsubj"] = self._get_next()

            d["email_html"] = self.quote(self.email)
            d["title"] = self.quote(self.subject)
            d["subject_html"] = self.quote(self.subject)
            d["message_id"] = self.quote(self._message_id)
            # TK: These two _url variables are used to compose a response
            # from the archive web page.  So, ...
            d["subject_url"] = url_quote('Re: ' + self.subject)
            d["in_reply_to_url"] = url_quote(self._message_id)
            if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS:
                # Point the mailto url back to the list
                author = re.sub('@', _(' at '), self.author)
                emailurl = self._mlist.GetListEmail()
            else:
                author = self.author
                emailurl = self.email
            d["author_html"] = self.quote(author)
            d["email_url"] = url_quote(emailurl)
            d["datestr_html"] = self.quote(i18n.ctime(int(self.date)))
            d["body"] = self._get_body()
            d['listurl'] = self._mlist.GetScriptURL('listinfo', absolute=1)
            d['listname'] = self._mlist.real_name
            d['encoding'] = ''
        finally:
            i18n.set_translation(otrans)

        charset = Utils.GetCharSet(self._lang)
        d["encoding"] = html_charset % charset

        self._add_decoded(d)
        return quick_maketext(
             'article.html', d,
             lang=self._lang, mlist=self._mlist)
Example #39
0
    def html_head(self):
        # avoid i18n side-effects
        mlist = self.maillist
        otrans = i18n.get_translation()
        i18n.set_language(mlist.preferred_language)
        # Convenience
        def quotetime(s):
            return html_quote(i18n.ctime(s), self.lang)
        try:
            d = {"listname": html_quote(mlist.real_name, self.lang),
                 "archtype": self.type,
                 "archive":  self.volNameToDesc(self.archive),
                 "listinfo": mlist.GetScriptURL('listinfo', absolute=1),
                 "firstdate": quotetime(self.firstdate),
                 "lastdate": quotetime(self.lastdate),
                 "size": self.size,
                 }
            i = {"thread": _("thread"),
                 "subject": _("subject"),
                 "author": _("author"),
                 "date": _("date"),
                 }
        finally:
            i18n.set_translation(otrans)

        for t in i.keys():
            cap = t[0].upper() + t[1:]
            if self.type == cap:
                d["%s_ref" % (t)] = ""
                d["archtype"] = i[t]
            else:
                d["%s_ref" % (t)] = ('<a href="%s.html#start">[ %s ]</a>'
                                     % (t, i[t]))
        if self.charset:
            d["encoding"] = html_charset % self.charset
        else:
            d["encoding"] = ""
        return quick_maketext(
            'archidxhead.html', d,
            mlist=mlist)
Example #40
0
def unsubscription_prompt(mlist, doc, cookie, addr):
    title = _('Confirm unsubscription request')
    doc.SetTitle(title)
    lang = mlist.getMemberLanguage(addr)
    i18n.set_language(lang)
    doc.set_language(lang)

    form = Form(mlist.GetScriptURL('confirm', 1))
    table = Table(border=0, width='100%')
    table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0,
                      colspan=2, bgcolor=mm_cfg.WEB_HEADER_COLOR)

    listname = mlist.real_name
    fullname = mlist.getMemberName(addr)
    if fullname is None:
        fullname = _('<em>Not available</em>')
    else:
        fullname = Utils.uncanonstr(fullname, lang)
    table.AddRow([_("""Your confirmation is required in order to complete the
    unsubscription request from the mailing list <em>%(listname)s</em>.  You
    are currently subscribed with

    <ul><li><b>Real name:</b> %(fullname)s
        <li><b>Email address:</b> %(addr)s
    </ul>

    Hit the <em>Unsubscribe</em> button below to complete the confirmation
    process.

    <p>Or hit <em>Cancel and discard</em> to cancel this unsubscription
    request.""") + '<p><hr>'])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
    table.AddRow([Hidden('cookie', cookie)])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
    table.AddRow([SubmitButton('submit', _('Unsubscribe')),
                  SubmitButton('cancel', _('Cancel and discard'))])

    form.AddItem(table)
    doc.AddItem(form)
Example #41
0
def reenable_confirm(mlist, doc, cookie):
    # See the comment in admin.py about the need for the signal
    # handler.
    def sigterm_handler(signum, frame, mlist=mlist):
        mlist.Unlock()
        sys.exit(0)

    mlist.Lock()
    try:
        try:
            # Do this in two steps so we can get the preferred language for
            # the user who is unsubscribing.
            op, listname, addr = mlist.pend_confirm(cookie, expunge=False)
            lang = mlist.getMemberLanguage(addr)
            i18n.set_language(lang)
            doc.set_language(lang)
            op, addr = mlist.ProcessConfirmation(cookie)
        except Errors.NotAMemberError:
            bad_confirmation(
                doc,
                _('''Invalid confirmation string.  It is
            possible that you are attempting to confirm a request for an
            address that has already been unsubscribed.'''))
        else:
            # The response
            listname = mlist.real_name
            title = _('Membership re-enabled.')
            optionsurl = mlist.GetOptionsURL(addr, absolute=1)
            doc.SetTitle(title)
            doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
            doc.AddItem(
                _("""\
            You have successfully re-enabled your membership in the
            %(listname)s mailing list.  You can now <a
            href="%(optionsurl)s">visit your member options page</a>.
            """))
        mlist.Save()
    finally:
        mlist.Unlock()
Example #42
0
def main():
    # Trick out pygettext since we want to mark template_data as translatable,
    # but we don't want to actually translate it here.
    def _(s):
        return s

    template_data = (
        ('listinfo.html',    _('General list information page')),
        ('subscribe.html',   _('Subscribe results page')),
        ('options.html',     _('User specific options page')),
        ('subscribeack.txt', _('Welcome email text file')),
        ('masthead.txt',     _('Digest masthead')),
        )

    _ = i18n._
    doc = Document()

    # Set up the system default language
    i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
    doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)

    parts = Utils.GetPathPieces()
    if not parts:
        doc.AddItem(Header(2, _("List name is required.")))
        print doc.Format()
        return

    listname = parts[0].lower()
    try:
        mlist = MailList.MailList(listname, lock=0)
    except Errors.MMListError, e:
        # Avoid cross-site scripting attacks
        safelistname = Utils.websafe(listname)
        doc.AddItem(Header(2, _('No such list <em>%(safelistname)s</em>')))
        # Send this with a 404 status.
        print 'Status: 404 Not Found'
        print doc.Format()
        syslog('error', 'No such list "%s": %s', listname, e)
        return
Example #43
0
def send_digests(mlist, mboxfp):
    # Set the digest volume and time
    if mlist.digest_last_sent_at:
        bump = False
        # See if we should bump the digest volume number
        timetup = time.localtime(mlist.digest_last_sent_at)
        now = time.localtime(time.time())
        freq = mlist.digest_volume_frequency
        if freq == 0 and timetup[0] < now[0]:
            # Yearly
            bump = True
        elif freq == 1 and timetup[1] <> now[1]:
            # Monthly, but we take a cheap way to calculate this.  We assume
            # that the clock isn't going to be reset backwards.
            bump = True
        elif freq == 2 and (timetup[1] % 4 <> now[1] % 4):
            # Quarterly, same caveat
            bump = True
        elif freq == 3:
            # Once again, take a cheap way of calculating this
            weeknum_last = int(time.strftime('%W', timetup))
            weeknum_now = int(time.strftime('%W', now))
            if weeknum_now > weeknum_last or timetup[0] > now[0]:
                bump = True
        elif freq == 4 and timetup[7] <> now[7]:
            # Daily
            bump = True
        if bump:
            mlist.bump_digest_volume()
    mlist.digest_last_sent_at = time.time()
    # Wrapper around actually digest crafter to set up the language context
    # properly.  All digests are translated to the list's preferred language.
    otranslation = i18n.get_translation()
    i18n.set_language(mlist.preferred_language)
    try:
        send_i18n_digests(mlist, mboxfp)
    finally:
        i18n.set_translation(otranslation)
Example #44
0
 def as_text(self):
     d = self.__dict__.copy()
     # We need to guarantee a valid From_ line, even if there are
     # bososities in the headers.
     if not d.get('fromdate', '').strip():
         d['fromdate'] = time.ctime(time.time())
     if not d.get('email', '').strip():
         d['email'] = '*****@*****.**'
     if not d.get('datestr', '').strip():
         d['datestr'] = time.ctime(time.time())
     #
     headers = ['From %(email)s  %(fromdate)s',
              'From: %(email)s (%(author)s)',
              'Date: %(datestr)s',
              'Subject: %(subject)s']
     if d['_in_reply_to']:
         headers.append('In-Reply-To: %(_in_reply_to)s')
     if d['_references']:
         headers.append('References: %(_references)s')
     if d['_message_id']:
         headers.append('Message-ID: %(_message_id)s')
     body = EMPTYSTRING.join(self.body)
     cset = Utils.GetCharSet(self._lang)
     # Coerce the body to Unicode and replace any invalid characters.
     if not isinstance(body, types.UnicodeType):
         body = unicode(body, cset, 'replace')
     if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS:
         otrans = i18n.get_translation()
         try:
             i18n.set_language(self._lang)
             atmark = unicode(_(' at '), cset)
             body = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
                           '\g<1>' + atmark + '\g<2>', body)
         finally:
             i18n.set_translation(otrans)
     # Return body to character set of article.
     body = body.encode(cset, 'replace')
     return NL.join(headers) % d + '\n\n' + body + '\n'
def send_digests(mlist, mboxfp):
    # Set the digest volume and time
    if mlist.digest_last_sent_at:
        bump = False
        # See if we should bump the digest volume number
        timetup = time.localtime(mlist.digest_last_sent_at)
        now = time.localtime(time.time())
        freq = mlist.digest_volume_frequency
        if freq == 0 and timetup[0] < now[0]:
            # Yearly
            bump = True
        elif freq == 1 and timetup[1] <> now[1]:
            # Monthly, but we take a cheap way to calculate this.  We assume
            # that the clock isn't going to be reset backwards.
            bump = True
        elif freq == 2 and (timetup[1] % 4 <> now[1] % 4):
            # Quarterly, same caveat
            bump = True
        elif freq == 3:
            # Once again, take a cheap way of calculating this
            weeknum_last = int(time.strftime('%W', timetup))
            weeknum_now = int(time.strftime('%W', now))
            if weeknum_now > weeknum_last or timetup[0] > now[0]:
                bump = True
        elif freq == 4 and timetup[7] <> now[7]:
            # Daily
            bump = True
        if bump:
            mlist.bump_digest_volume()
    mlist.digest_last_sent_at = time.time()
    # Wrapper around actually digest crafter to set up the language context
    # properly.  All digests are translated to the list's preferred language.
    otranslation = i18n.get_translation()
    i18n.set_language(mlist.preferred_language)
    try:
        send_i18n_digests(mlist, mboxfp)
    finally:
        i18n.set_translation(otranslation)
Example #46
0
 def as_text(self):
     d = self.__dict__.copy()
     # We need to guarantee a valid From_ line, even if there are
     # bososities in the headers.
     if not d.get('fromdate', '').strip():
         d['fromdate'] = time.ctime(time.time())
     if not d.get('email', '').strip():
         d['email'] = '*****@*****.**'
     if not d.get('datestr', '').strip():
         d['datestr'] = time.ctime(time.time())
     #
     headers = [
         'From %(email)s  %(fromdate)s', 'From: %(email)s (%(author)s)',
         'Date: %(datestr)s', 'Subject: %(subject)s'
     ]
     if d['_in_reply_to']:
         headers.append('In-Reply-To: %(_in_reply_to)s')
     if d['_references']:
         headers.append('References: %(_references)s')
     if d['_message_id']:
         headers.append('Message-ID: %(_message_id)s')
     body = EMPTYSTRING.join(self.body)
     cset = Utils.GetCharSet(self._lang)
     # Coerce the body to Unicode and replace any invalid characters.
     if not isinstance(body, types.UnicodeType):
         body = unicode(body, cset, 'replace')
     if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS:
         otrans = i18n.get_translation()
         try:
             i18n.set_language(self._lang)
             atmark = unicode(_(' at '), cset)
             body = re.sub(r'([-+,.\w]+)@([-+.\w]+)',
                           '\g<1>' + atmark + '\g<2>', body)
         finally:
             i18n.set_translation(otrans)
     # Return body to character set of article.
     body = body.encode(cset, 'replace')
     return NL.join(headers) % d + '\n\n' + body + '\n'
def main():
    parts = Utils.GetPathPieces()
    if not parts:
        listinfo_overview()
        return

    listname = parts[0].lower()
    try:
        mlist = MailList.MailList(listname, lock=0)
    except Errors.MMListError as e:
        # Avoid cross-site scripting attacks
        safelistname = Utils.websafe(listname)
        # Send this with a 404 status.
        print('Status: 404 Not Found')
        listinfo_overview(_('No such list <em>%(safelistname)s</em>'))
        syslog('error', 'listinfo: No such list "%s": %s', listname, e)
        return

    # See if the user want to see this page in other language
    cgidata = cgi.FieldStorage()
    try:
        language = cgidata.getfirst('language')
    except TypeError:
        # Someone crafted a POST with a bad Content-Type:.
        doc = Document()
        doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
        doc.AddItem(Header(2, _("Error")))
        doc.AddItem(Bold(_('Invalid options to CGI script.')))
        # Send this with a 400 status.
        print('Status: 400 Bad Request')
        print(doc.Format())
        return

    if not Utils.IsLanguage(language):
        language = mlist.preferred_language
    i18n.set_language(language)
    list_listinfo(mlist, language)
Example #48
0
    def SendHostileSubscriptionNotice(self, listname, address):
        # Some one was invited to one list but tried to confirm to a different
        # list.  We inform both list owners of the bogosity, but be careful
        # not to reveal too much information.
        selfname = self.internal_name()
        syslog('mischief', '%s was invited to %s but confirmed to %s', address,
               listname, selfname)
        # First send a notice to the attacked list
        msg = Message.OwnerNotification(
            self, _('Hostile subscription attempt detected'),
            Utils.wrap(
                _("""%(address)s was invited to a different mailing
list, but in a deliberate malicious attempt they tried to confirm the
invitation to your list.  We just thought you'd like to know.  No further
action by you is required.""")))
        msg.send(self)
        # Now send a notice to the invitee list
        try:
            # Avoid import loops
            from Mailman.MailList import MailList
            mlist = MailList(listname, lock=False)
        except Errors.MMListError:
            # Oh well
            return
        otrans = i18n.get_translation()
        i18n.set_language(mlist.preferred_language)
        try:
            msg = Message.OwnerNotification(
                mlist, _('Hostile subscription attempt detected'),
                Utils.wrap(
                    _("""You invited %(address)s to your list, but in a
deliberate malicious attempt, they tried to confirm the invitation to a
different list.  We just thought you'd like to know.  No further action by you
is required.""")))
            msg.send(mlist)
        finally:
            i18n.set_translation(otrans)
from Mailman import i18n
from Mailman.htmlformat import *
from Mailman.Logging.Syslog import syslog
from Mailman import DlistUtils  # Added to support dlists

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from urlparse import urlparse

import time
import Cookie
import cgitb
import sys

# Set up i18n
_ = i18n._
i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)




def main():
    parts = Utils.GetPathPieces()
    if not parts:
        listinfo_overview()
        return

    listname = parts[0].lower()
    try:
        mlist = MailList.MailList(listname, lock=0)
    except Errors.MMListError, e:
        # Avoid cross-site scripting attacks
Example #50
0
def subscription_confirm(mlist, doc, cookie, cgidata):
    # See the comment in admin.py about the need for the signal
    # handler.
    def sigterm_handler(signum, frame, mlist=mlist):
        mlist.Unlock()
        sys.exit(0)

    listname = mlist.real_name
    mlist.Lock()
    try:
        try:
            # Some pending values may be overridden in the form.  email of
            # course is hardcoded. ;)
            lang = cgidata.getvalue('language')
            if not Utils.IsLanguage(lang):
                lang = mlist.preferred_language
            i18n.set_language(lang)
            doc.set_language(lang)
            if cgidata.has_key('digests'):
                try:
                    digest = int(cgidata.getvalue('digests'))
                except ValueError:
                    digest = None
            else:
                digest = None
            userdesc = mlist.pend_confirm(cookie, expunge=False)[1]
            fullname = cgidata.getvalue('realname', None)
            if fullname is not None:
                fullname = Utils.canonstr(fullname, lang)
            overrides = UserDesc(fullname=fullname, digest=digest, lang=lang)
            userdesc += overrides
            op, addr, pw, digest, lang = mlist.ProcessConfirmation(
                cookie, userdesc)
        except Errors.MMNeedApproval:
            title = _('Awaiting moderator approval')
            doc.SetTitle(title)
            doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
            doc.AddItem(_("""\
            You have successfully confirmed your subscription request to the
            mailing list %(listname)s, however final approval is required from
            the list moderator before you will be subscribed.  Your request
            has been forwarded to the list moderator, and you will be notified
            of the moderator's decision."""))
        except Errors.NotAMemberError:
            bad_confirmation(doc, _('''Invalid confirmation string.  It is
            possible that you are attempting to confirm a request for an
            address that has already been unsubscribed.'''))
        except Errors.MMAlreadyAMember:
            doc.addError(_("You are already a member of this mailing list!"))
        except Errors.MembershipIsBanned:
            owneraddr = mlist.GetOwnerEmail()
            doc.addError(_("""You are currently banned from subscribing to
            this list.  If you think this restriction is erroneous, please
            contact the list owners at %(owneraddr)s."""))
        except Errors.HostileSubscriptionError:
            doc.addError(_("""\
            You were not invited to this mailing list.  The invitation has
            been discarded, and both list administrators have been
            alerted."""))
        else:
            # Use the user's preferred language
            i18n.set_language(lang)
            doc.set_language(lang)
            # The response
            listname = mlist.real_name
            title = _('Subscription request confirmed')
            optionsurl = mlist.GetOptionsURL(addr, absolute=1)
            doc.SetTitle(title)
            doc.AddItem(Header(3, Bold(FontAttr(title, size='+2'))))
            doc.AddItem(_('''\
            You have successfully confirmed your subscription request for
            "%(addr)s" to the %(listname)s mailing list.  A separate
            confirmation message will be sent to your email address, along
            with your password, and other useful information and links.

            <p>You can now
            <a href="%(optionsurl)s">proceed to your membership login
            page</a>.'''))
        mlist.Save()
    finally:
        mlist.Unlock()
Example #51
0
def heldmsg_prompt(mlist, doc, cookie, id):
    title = _('Cancel held message posting')
    doc.SetTitle(title)
    form = Form(mlist.GetScriptURL('confirm', 1))
    table = Table(border=0, width='100%')
    table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0,
                      colspan=2, bgcolor=mm_cfg.WEB_HEADER_COLOR)
    # Blarg.  The list must be locked in order to interact with the ListAdmin
    # database, even for read-only.  See the comment in admin.py about the
    # need for the signal handler.
    def sigterm_handler(signum, frame, mlist=mlist):
        mlist.Unlock()
        sys.exit(0)
    # Get the record, but watch for KeyErrors which mean the admin has already
    # disposed of this message.
    mlist.Lock()
    try:
        try:
            data = mlist.GetRecord(id)
        except KeyError:
            data = None
    finally:
        mlist.Unlock()

    if data is None:
        bad_confirmation(doc, _("""The held message you were referred to has
        already been handled by the list administrator."""))
        return

    # Unpack the data and present the confirmation message
    ign, sender, msgsubject, givenreason, ign, ign = data
    # Now set the language to the sender's preferred.
    lang = mlist.getMemberLanguage(sender)
    i18n.set_language(lang)
    doc.set_language(lang)

    subject = Utils.websafe(Utils.oneline(msgsubject, Utils.GetCharSet(lang)))
    reason = Utils.websafe(_(givenreason))
    listname = mlist.real_name
    table.AddRow([_('''Your confirmation is required in order to cancel the
    posting of your message to the mailing list <em>%(listname)s</em>:

    <ul><li><b>Sender:</b> %(sender)s
        <li><b>Subject:</b> %(subject)s
        <li><b>Reason:</b> %(reason)s
    </ul>

    Hit the <em>Cancel posting</em> button to discard the posting.

    <p>Or hit the <em>Continue awaiting approval</em> button to continue to
    allow the list moderator to approve or reject the message.''')
                    + '<p><hr>'])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
    table.AddRow([Hidden('cookie', cookie)])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
    table.AddRow([SubmitButton('submit', _('Cancel posting')),
                  SubmitButton('cancel', _('Continue awaiting approval'))])

    form.AddItem(table)
    doc.AddItem(form)
Example #52
0
def reenable_prompt(mlist, doc, cookie, list, member):
    title = _('Re-enable mailing list membership')
    doc.SetTitle(title)
    form = Form(mlist.GetScriptURL('confirm', 1))
    table = Table(border=0, width='100%')
    table.AddRow([Center(Bold(FontAttr(title, size='+1')))])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0,
                      colspan=2, bgcolor=mm_cfg.WEB_HEADER_COLOR)

    lang = mlist.getMemberLanguage(member)
    i18n.set_language(lang)
    doc.set_language(lang)

    realname = mlist.real_name
    info = mlist.getBounceInfo(member)
    if not info:
        listinfourl = mlist.GetScriptURL('listinfo', absolute=1)
        # They've already be unsubscribed
        table.AddRow([_("""We're sorry, but you have already been unsubscribed
        from this mailing list.  To re-subscribe, please visit the
        <a href="%(listinfourl)s">list information page</a>.""")])
        return

    date = time.strftime('%A, %B %d, %Y',
                         time.localtime(time.mktime(info.date + (0,)*6)))
    daysleft = int(info.noticesleft *
                   mlist.bounce_you_are_disabled_warnings_interval /
                   mm_cfg.days(1))
    # BAW: for consistency this should be changed to 'fullname' or the above
    # 'fullname's should be changed to 'username'.  Don't want to muck with
    # the i18n catalogs though.
    username = mlist.getMemberName(member)
    if username is None:
        username = _('<em>not available</em>')
    else:
        username = Utils.websafe(Utils.uncanonstr(username, lang))

    table.AddRow([_("""Your membership in the %(realname)s mailing list is
    currently disabled due to excessive bounces.  Your confirmation is
    required in order to re-enable delivery to your address.  We have the
    following information on file:

    <ul><li><b>Member address:</b> %(member)s
        <li><b>Member name:</b> %(username)s
        <li><b>Last bounce received on:</b> %(date)s
        <li><b>Approximate number of days before you are permanently removed
               from this list:</b> %(daysleft)s
    </ul>

    Hit the <em>Re-enable membership</em> button to resume receiving postings
    from the mailing list.  Or hit the <em>Cancel</em> button to defer
    re-enabling your membership.
    """)])

    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
    table.AddRow([Hidden('cookie', cookie)])
    table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2)
    table.AddRow([SubmitButton('submit', _('Re-enable membership')),
                  SubmitButton('cancel', _('Cancel'))])

    form.AddItem(table)
    doc.AddItem(form)
Example #53
0
from Mailman import mm_cfg
from Mailman import Utils
from Mailman import MailList
from Mailman import Message
from Mailman import Errors
from Mailman import i18n
from Mailman.htmlformat import *
from Mailman.Logging.Syslog import syslog
from Mailman.Utils import sha_new
from Mailman.UserDesc import UserDesc

from Mailman.tornado import template

# Set up i18n
_ = i18n._
i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)

def auto_version (resource):
    """Intended to be invoked from inside tornado templates, given a resource
    names such as /static/ctl.js this will return something like
    /static/ctl.v201211010141551.css to version it. For this to work we need a
    working url rewrite rule in apache or equivalent to strip out the
    timestamp.

    It is assumed that static resources that need to be versioned are
    available at the first level inside the PREFIX Directory"""

    if mm_cfg.SSO_ENVIRONMENT == mm_cfg.SSO_DEV:
        return resource

    absname   = os.path.abspath(os.path.join(mm_cfg.VAR_PREFIX, resource[1:]))
Example #54
0
if not os.getuid():
    os.setregid(gid, gid)
    os.setreuid(uid, uid)

signal.signal(signal.SIGHUP, signal.SIG_IGN)

if ( os.getuid() is not uid ) or ( os.getgid() is not gid):
    sys.exit(0)

opts, args = getopt.getopt(sys.argv[1:], 'f')
for o, a in opts:
    if o == '-f' and os.fork():
        sys.exit(0)

i18n.set_language('fr')
mysql = connectDB()
lock = Lock()

#-------------------------------------------------------------------------------
# server
#
server = FastXMLRPCServer((SRV_HOST, SRV_PORT), BasicAuthXMLRPCRequestHandler)

# index.php
server.register_function(get_lists)
server.register_function(subscribe)
server.register_function(unsubscribe)
# members.php
server.register_function(get_members)
# trombi.php
Example #55
0
    def __init__(self,
                 message=None,
                 sequence=0,
                 keepHeaders=[],
                 lang=mm_cfg.DEFAULT_SERVER_LANGUAGE,
                 mlist=None):
        self.__super_init(message, sequence, keepHeaders)
        self.prev = None
        self.next = None
        # Trim Re: from the subject line
        i = 0
        while i != -1:
            result = REpat.match(self.subject)
            if result:
                i = result.end(0)
                self.subject = self.subject[i:]
            else:
                i = -1
        # Useful to keep around
        self._lang = lang
        self._mlist = mlist

        if mm_cfg.ARCHIVER_OBSCURES_EMAILADDRS:
            # Avoid i18n side-effects.  Note that the language for this
            # article (for this list) could be different from the site-wide
            # preferred language, so we need to ensure no side-effects will
            # occur.  Think what happens when executing bin/arch.
            otrans = i18n.get_translation()
            try:
                i18n.set_language(lang)
                if self.author == self.email:
                    self.author = self.email = re.sub('@', _(' at '),
                                                      self.email)
                else:
                    self.email = re.sub('@', _(' at '), self.email)
            finally:
                i18n.set_translation(otrans)

        # Snag the content-* headers.  RFC 1521 states that their values are
        # case insensitive.
        ctype = message.get('Content-Type', 'text/plain')
        cenc = message.get('Content-Transfer-Encoding', '')
        self.ctype = ctype.lower()
        self.cenc = cenc.lower()
        self.decoded = {}
        cset = Utils.GetCharSet(mlist.preferred_language)
        cset_out = Charset(cset).output_charset or cset
        if isinstance(cset_out, unicode):
            # email 3.0.1 (python 2.4) doesn't like unicode
            cset_out = cset_out.encode('us-ascii')
        charset = message.get_content_charset(cset_out)
        if charset:
            charset = charset.lower().strip()
            if charset[0] == '"' and charset[-1] == '"':
                charset = charset[1:-1]
            if charset[0] == "'" and charset[-1] == "'":
                charset = charset[1:-1]
            try:
                body = message.get_payload(decode=True)
            except binascii.Error:
                body = None
            if body and charset != Utils.GetCharSet(self._lang):
                # decode body
                try:
                    body = unicode(body, charset)
                except (UnicodeError, LookupError):
                    body = None
            if body:
                self.body = [l + "\n" for l in body.splitlines()]

        self.decode_headers()
Example #56
0
    return s.replace('\000', ' ')


def sizeof(filename, lang):
    try:
        size = os.path.getsize(filename)
    except OSError, e:
        # ENOENT can happen if the .mbox file was moved away or deleted, and
        # an explicit mbox file name was given to bin/arch.
        if e.errno <> errno.ENOENT: raise
        return _('size not available')
    if size < 1000:
        # Avoid i18n side-effects
        otrans = i18n.get_translation()
        try:
            i18n.set_language(lang)
            out = _(' %(size)i bytes ')
        finally:
            i18n.set_translation(otrans)
        return out
    elif size < 1000000:
        return ' %d KB ' % (size / 1000)
    # GB?? :-)
    return ' %d MB ' % (size / 1000000)


html_charset = '<META http-equiv="Content-Type" ' \
               'content="text/html; charset=%s">'


def CGIescape(arg, lang=None):
Example #57
0
from Mailman import Message
from Mailman import i18n
from Mailman.Handlers.Moderate import ModeratedMemberPost
from Mailman.ListAdmin import HELDMSG
from Mailman.ListAdmin import readMessage
from Mailman.Cgi import Auth
from Mailman.htmlformat import *
from Mailman.Logging.Syslog import syslog

EMPTYSTRING = ''
NL = '\n'

# Set up i18n.  Until we know which list is being requested, we use the
# server's default.
_ = i18n._
i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)

EXCERPT_HEIGHT = 10
EXCERPT_WIDTH = 76



def helds_by_sender(mlist):
    heldmsgs = mlist.GetHeldMessageIds()
    bysender = {}
    for id in heldmsgs:
        sender = mlist.GetRecord(id)[1]
        bysender.setdefault(sender, []).append(id)
    return bysender

Example #58
0
import cgi
import sys
import errno
import shutil

from Mailman import mm_cfg
from Mailman import Utils
from Mailman import MailList
from Mailman import Errors
from Mailman import i18n
from Mailman.htmlformat import *
from Mailman.Logging.Syslog import syslog

# Set up i18n
_ = i18n._
i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)


def main():
    doc = Document()
    doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)

    cgidata = cgi.FieldStorage()
    try:
        cgidata.getfirst('password', '')
    except TypeError:
        # Someone crafted a POST with a bad Content-Type:.
        doc.AddItem(Header(2, _("Error")))
        doc.AddItem(Bold(_('Invalid options to CGI script.')))
        # Send this with a 400 status.
        print 'Status: 400 Bad Request'
def main():
    # Trick out pygettext since we want to mark template_data as translatable,
    # but we don't want to actually translate it here.
    def _(s):
        return s

    template_data = (
        ('listinfo.html', _('General list information page')),
        ('subscribe.html', _('Subscribe results page')),
        ('options.html', _('User specific options page')),
        ('subscribeack.txt', _('Welcome email text file')),
        ('masthead.txt', _('Digest masthead')),
        ('postheld.txt', _('User notice of held post')),
        ('approve.txt', _('User notice of held subscription')),
        ('refuse.txt', _('Notice of post refused by moderator')),
        ('invite.txt', _('Invitation to join list')),
        ('verify.txt', _('Request to confirm subscription')),
        ('unsub.txt', _('Request to confirm unsubscription')),
        ('nomoretoday.txt', _('User notice of autoresponse limit')),
        ('postack.txt', _('User post acknowledgement')),
        ('disabled.txt', _('Subscription disabled by bounce warning')),
        ('admlogin.html', _('Admin/moderator login page')),
        ('private.html', _('Private archive login page')),
        ('userpass.txt', _('On demand password reminder')),
    )

    _ = i18n._
    doc = Document()

    # Set up the system default language
    i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)
    doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)

    parts = Utils.GetPathPieces()
    if not parts:
        doc.AddItem(Header(2, _("List name is required.")))
        print(doc.Format())
        return

    listname = parts[0].lower()
    try:
        mlist = MailList.MailList(listname, lock=0)
    except Errors.MMListError as e:
        # Avoid cross-site scripting attacks
        safelistname = Utils.websafe(listname)
        doc.AddItem(Header(2, _('No such list <em>%(safelistname)s</em>')))
        # Send this with a 404 status.
        print('Status: 404 Not Found')
        print(doc.Format())
        syslog('error', 'edithtml: No such list "%s": %s', listname, e)
        return

    # Now that we have a valid list, set the language to its default
    i18n.set_language(mlist.preferred_language)
    doc.set_language(mlist.preferred_language)

    # Must be authenticated to get any farther
    cgidata = cgi.FieldStorage()
    try:
        cgidata.getfirst('adminpw', '')
    except TypeError:
        # Someone crafted a POST with a bad Content-Type:.
        doc.AddItem(Header(2, _("Error")))
        doc.AddItem(Bold(_('Invalid options to CGI script.')))
        # Send this with a 400 status.
        print('Status: 400 Bad Request')
        print(doc.Format())
        return

    # CSRF check
    safe_params = ['VARHELP', 'adminpw', 'admlogin']
    params = list(cgidata.keys())
    if set(params) - set(safe_params):
        csrf_checked = csrf_check(mlist, cgidata.getfirst('csrf_token'))
    else:
        csrf_checked = True
    # if password is present, void cookie to force password authentication.
    if cgidata.getfirst('adminpw'):
        os.environ['HTTP_COOKIE'] = ''
        csrf_checked = True

    # Editing the html for a list is limited to the list admin and site admin.
    if not mlist.WebAuthenticate((mm_cfg.AuthListAdmin, mm_cfg.AuthSiteAdmin),
                                 cgidata.getfirst('adminpw', '')):
        if 'admlogin' in cgidata:
            # This is a re-authorization attempt
            msg = Bold(FontSize('+1', _('Authorization failed.'))).Format()
            remote = os.environ.get(
                'HTTP_FORWARDED_FOR',
                os.environ.get(
                    'HTTP_X_FORWARDED_FOR',
                    os.environ.get('REMOTE_ADDR', 'unidentified origin')))
            syslog('security',
                   'Authorization failed (edithtml): list=%s: remote=%s',
                   listname, remote)
        else:
            msg = ''
        Auth.loginpage(mlist, 'admin', msg=msg)
        return

    realname = mlist.real_name
    if len(parts) > 1:
        template_name = parts[1]
        for (template, info) in template_data:
            if template == template_name:
                template_info = _(info)
                doc.SetTitle(
                    _('%(realname)s -- Edit html for %(template_info)s'))
                break
        else:
            # Avoid cross-site scripting attacks
            safetemplatename = Utils.websafe(template_name)
            doc.SetTitle(_('Edit HTML : Error'))
            doc.AddItem(Header(2, _("%(safetemplatename)s: Invalid template")))
            doc.AddItem(mlist.GetMailmanFooter())
            print(doc.Format())
            return
    else:
        doc.SetTitle(_('%(realname)s -- HTML Page Editing'))
        doc.AddItem(Header(1, _('%(realname)s -- HTML Page Editing')))
        doc.AddItem(Header(2, _('Select page to edit:')))
        template_list = UnorderedList()
        for (template, info) in template_data:
            l = Link(mlist.GetScriptURL('edithtml') + '/' + template, _(info))
            template_list.AddItem(l)
        doc.AddItem(FontSize("+2", template_list))
        doc.AddItem(mlist.GetMailmanFooter())
        print(doc.Format())
        return

    try:
        if list(cgidata.keys()):
            if csrf_checked:
                ChangeHTML(mlist, cgidata, template_name, doc)
            else:
                doc.addError(
                    _('The form lifetime has expired. (request forgery check)')
                )
        FormatHTML(mlist, doc, template_name, template_info)
    finally:
        doc.AddItem(mlist.GetMailmanFooter())
        print(doc.Format())