summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorviega1998-06-14 01:00:28 +0000
committerviega1998-06-14 01:00:28 +0000
commit73e488770ae493feeaf08ac9d21bd14eccdb2da2 (patch)
tree950823c4949a13fcf3b3dcb82df1310bbe6be6ba
parent8dfd4643c7d8216cfbf6e180ed7b868715b9e775 (diff)
downloadmailman-73e488770ae493feeaf08ac9d21bd14eccdb2da2.tar.gz
mailman-73e488770ae493feeaf08ac9d21bd14eccdb2da2.tar.zst
mailman-73e488770ae493feeaf08ac9d21bd14eccdb2da2.zip
-rwxr-xr-xcgi/admin840
-rwxr-xr-xcgi/admindb225
-rwxr-xr-xcgi/archives81
-rwxr-xr-xcgi/edithtml160
-rwxr-xr-xcgi/handle_opts199
-rwxr-xr-xcgi/listinfo172
-rwxr-xr-xcgi/options120
-rwxr-xr-xcgi/private222
-rwxr-xr-xcgi/roster108
-rwxr-xr-xcgi/subscribe180
10 files changed, 58 insertions, 2249 deletions
diff --git a/cgi/admin b/cgi/admin
index 706cdcea7..5e32818ec 100755
--- a/cgi/admin
+++ b/cgi/admin
@@ -16,840 +16,14 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-"""Process and produce the list-administration options forms.
-To run stand-alone for debugging, set env var PATH_INFO to name of list
-and, optionally, options category."""
+import paths
-__version__ = "$Revision: 732 $"
+def admin():
+ import Mailman.Cgi.admin
+ Mailman.Cgi.admin.main()
-import sys
-import os, cgi, string, crypt, types, time
-import paths # path hacking
-import mm_utils, maillist, mm_cfg, mm_err, mm_mailcmd, Cookie
-from htmlformat import *
+from Mailman.runcgi import *
+wrap_func(admin)
-try:
- sys.stderr = mm_utils.StampedLogger("error", label = 'admin',
- manual_reprime=1, nofail=0)
-except IOError:
- pass # Oh well - SOL on redirect, errors show thru.
-
-CATEGORIES = [('general', "General Options"),
- ('members', "Membership Management"),
- ('privacy', "Privacy Options"),
- ('nondigest', "Regular-member (non-digest) Options"),
- ('digest', "Digest-member Options"),
- ('bounce', "Bounce Options"),
- ('archive', "Archival Options"),
- ('gateway', "Mail-News and News-Mail gateways")]
-
-
-LOGIN_PAGE = """
-<html>
-<head>
- <title>%(listname)s Administrative Authentication</title>
-</head>
-<body bgcolor="#ffffff">
-<FORM METHOD=POST ACTION="%(path)s">
-%(message)s
- <TABLE WIDTH="100%%" BORDER="0" CELLSPACING="4" CELLPADDING="5">
- <TR>
- <TD COLSPAN="2" WIDTH="100%%" BGCOLOR="#99CCFF" ALIGN="CENTER">
- <B><FONT COLOR="#000000" SIZE="+1">%(listname)s Administrative
- Authentication</FONT></B>
- </TD>
- </TR>
- <tr>
- <TD> <div ALIGN="Right"> List Administrative Password: </div> </TD>
- <TD> <INPUT TYPE=password NAME=adminpw SIZE=30></TD>
- </tr>
- <tr>
- <td colspan=2 align=middle> <INPUT TYPE=SUBMIT name="request_login">
- </td>
- </tr>
- </TABLE>
-</FORM>
-"""
-
-# " <- icky emacs font-lock bug workaround
-
-SECRET="monty"
-
-def isAuthenticated(list, password=None, SECRET="SECRET"):
- import base64, md5
- if password is not None: # explicit login
- try:
- list.ConfirmAdminPassword(password)
- except mm_err.MMBadPasswordError:
- AddErrorMessage(doc, 'Error: Incorrect admin password.')
- return 0
- except:
- print "Content-type: text/html\n"
-
- print "<p><h3>We're sorry, we hit a bug!</h3>\n"
- print "If you would like to help us identify the problem, please "
- print "email a copy of this page to the webmaster for this site"
- print 'with a description of what happened. Thanks!'
- print "\n<PRE>"
- try:
- import traceback
- sys.stderr = sys.stdout
- traceback.print_exc()
- except:
- print "[failed to get traceback]"
- print "\n\n</PRE>"
-
- token = md5.new(SECRET + list_name + SECRET).digest()
- token = base64.encodestring(token)
- token = string.strip(token)
- c = Cookie.Cookie()
- cookie_key = list_name + "-admin"
- c[cookie_key] = token
- c[cookie_key]['expires'] = mm_cfg.ADMIN_COOKIE_LIFE
- print c # Output the cookie
- return 1
- if os.environ.has_key('HTTP_COOKIE'):
- c = Cookie.Cookie( os.environ['HTTP_COOKIE'] )
- if c.has_key(list_name + "-admin"):
- try:
- inp = base64.decodestring(c[list_name + "-admin"].value)
- check = md5.new(SECRET+list_name+SECRET).digest()
- except Error: # the decodestring may return incorrect padding?
- raise 'Decode failed'
- return 0
- if inp == check:
- return 1
- else:
- return 0
- return 0
-
-
-def main():
- """Process and produce list options form.
-
- CGI input indicates that we're returning from submission of some new
- settings, which is processed before producing the new version."""
- global list_name, list_info, doc
- doc = Document()
-
- try:
- path = os.environ['PATH_INFO']
- except KeyError:
- path = ""
- list_info = mm_utils.GetPathPieces(path)
- # How many ../'s we need to get back to http://host/mailman
-
- if len(list_info) == 0:
- FormatAdminOverview()
- return
-
- list_name = string.lower(list_info[0])
-
- lst = maillist.MailList(list_name)
-
- try:
- if not (lst and lst._ready):
- FormatAdminOverview(error="List <em>%s</em> not found."
- % list_name)
- return
-
- if len(list_info) == 1:
- category = 'general'
- category_suffix = ''
- else:
- category = list_info[1]
- category_suffix = category
-
- if category not in map(lambda x: x[0], CATEGORIES):
- category = 'general'
- global cgi_data
- cgi_data = cgi.FieldStorage()
- is_auth = 0
- if cgi_data.has_key("adminpw"):
- is_auth = isAuthenticated(lst, cgi_data["adminpw"].value)
- message = FontAttr("Sorry, wrong password. Try again.",
- color="ff5060", size="+1").Format()
- else:
- is_auth = isAuthenticated(lst)
- message = ""
- if not is_auth:
- print "Content-type: text/html\n\n"
- print LOGIN_PAGE % ({"listname": list_name,
- "path": os.environ.get("REQUEST_URI", "/mailman/admin"),
- "message": message})
- return
-
- if len(cgi_data.keys()):
- if cgi_data.has_key('VARHELP'):
- FormatOptionHelp(doc, cgi_data['VARHELP'].value, lst)
- print doc.Format(bgcolor="#ffffff")
- return
- if (cgi_data.has_key('bounce_matching_headers')):
- try:
- pairs = lst.parse_matching_header_opt()
- except mm_err.MMBadConfigError, line:
- AddErrorMessage(doc,
- 'Warning: bad matching-header line'
- ' (does it have the colon?)<ul> %s </ul>',
- line)
-
- if not lst.digestable and len(lst.digest_members):
- AddErrorMessage(doc,
- 'Warning: you have digest members,'
- ' but digests are turned off.'
- ' Those people will not receive mail.')
- if not lst.nondigestable and len(lst.members):
- AddErrorMessage(doc,
- 'Warning: you have lst members,'
- ' but non-digestified mail is turned'
- ' off. They will receive mail until'
- ' you fix this problem.')
- if len(cgi_data.keys()):
- ChangeOptions(lst, category, cgi_data, doc)
- FormatConfiguration(doc, lst, category, category_suffix)
- print doc.Format(bgcolor="#ffffff")
-
- finally:
- lst.Unlock()
-
-# Form Production:
-
-def FormatAdminOverview(error=None):
- "Present a general welcome and itemize the (public) lists."
- doc = Document()
- legend = "%s maillists - Admin Links" % mm_cfg.DEFAULT_HOST_NAME
- doc.SetTitle(legend)
-
- table = Table(border=0, width="100%")
- table.AddRow([Center(Header(2, legend))])
- table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0,
- colspan=2, bgcolor="#99ccff")
-
- advertised = []
- names = mm_utils.list_names()
- names.sort()
- for n in names:
- l = maillist.MailList(n, lock=0)
- if l.advertised: advertised.append(l)
-
- if error:
- greeting = FontAttr(error, color="ff5060", size="+1")
- else:
- greeting = "Welcome!"
-
- if not advertised:
- welcome_items = (greeting,
- "<p>"
- " There currently are no publicly-advertised ",
- Link(mm_cfg.MAILMAN_URL, "mailman"),
- " maillists on %s." % mm_cfg.DEFAULT_HOST_NAME,
- )
- else:
-
- welcome_items = (
- greeting,
- "<p>"
- " Below is the collection of publicly-advertised ",
- Link(mm_cfg.MAILMAN_URL, "mailman"),
- " maillists on %s." % mm_cfg.DEFAULT_HOST_NAME,
- (' Click on a list name to visit the configuration pages'
- ' for that list.'
- )
- )
-
- welcome_items = (welcome_items +
- (" To visit the administrators configuration page for"
- " an unadvertised list, open a URL similar to this"
- +
- (" one, but with a '/' and the %slist name appended.<p>"
- % ((error and "the right ") or ""))
- +
- " General list information can be found at ",
- Link(os.path.join('../'* mm_utils.GetNestingLevel(),
- "listinfo/"), "the maillist overview page"),
- "."
- "<p>(Send questions and comments to ",
- Link("mailto:%s" % mm_cfg.MAILMAN_OWNER,
- mm_cfg.MAILMAN_OWNER),
- ".)<p>"
- )
- )
-
- table.AddRow([apply(Container, welcome_items)])
- table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0, colspan=2)
-
- if advertised:
- table.AddRow([Italic("List"), Italic("Description")])
- for l in advertised:
- table.AddRow([Link(l.GetRelativeScriptURL('admin'),
- Bold(l.real_name)),l.description])
-
- doc.AddItem(table)
-
- print doc.Format(bgcolor="#ffffff")
-
-def FormatConfiguration(doc, lst, category, category_suffix):
- """Produce the overall doc, *except* any processing error messages."""
- for k, v in CATEGORIES:
- if k == category: label = v
-
- doc.SetTitle('%s Administration' % lst.real_name)
- doc.AddItem(Center(Header(2, ('%s Maillist Configuration - %s Section'
- % (lst.real_name, label)))))
- doc.AddItem('<hr>')
-
- links_table = Table(valign="top")
-
- links_table.AddRow([Center(Bold("Configuration Categories")),
- Center(Bold("Other Administrative Activities"))])
- other_links = UnorderedList()
- link = Link(lst.GetRelativeScriptURL('admindb'),
- 'Tend to pending administrative requests.')
- other_links.AddItem(link)
- link = Link(lst.GetRelativeScriptURL('listinfo'),
- 'Go to the general list information page.')
- other_links.AddItem(link)
- link = Link(lst.GetRelativeScriptURL('edithtml'),
- 'Edit the HTML for the public list pages.')
- other_links.AddItem(link)
-
- these_links = UnorderedList()
- for k, v in CATEGORIES:
- if k == category:
- these_links.AddItem("<b> =&gt; " + v + " &lt;= </b>")
- else:
- these_links.AddItem(Link("%s/%s" %
- (lst.GetRelativeScriptURL('admin'),k),v))
-
- links_table.AddRow([these_links, other_links])
- links_table.AddRowInfo(max(links_table.GetCurrentRowIndex(), 0),
- valign="top")
-
- doc.AddItem(links_table)
- doc.AddItem('<hr>')
- if category_suffix:
- form = Form("%s/%s" % (lst.GetRelativeScriptURL('admin'),
- category_suffix))
- else:
- form = Form(lst.GetRelativeScriptURL('admin'))
- doc.AddItem(form)
-
- form.AddItem("Make your changes, below, and then submit it all at the"
- " bottom. (You can also change your password there,"
- " as well.)<p>")
-
- form.AddItem(FormatOptionsSection(category, lst))
-
- form.AddItem(Center(FormatPasswordStuff()))
-
- form.AddItem(lst.GetMailmanFooter())
-
-def FormatOptionsSection(category, lst):
- """Produce the category-specific options table."""
- if category == 'members':
- # Special case for members section.
- return FormatMembershipOptions(lst)
-
- options = GetConfigOptions(lst, category)
-
- big_table = Table(cellspacing=3, cellpadding=4)
-
- # Get and portray the text label for the category.
- for k, v in CATEGORIES:
- if k == category: label = v
- big_table.AddRow([Center(Header(2, label))])
- big_table.AddCellInfo(max(big_table.GetCurrentRowIndex(), 0), 0,
- colspan=2, bgcolor="#99ccff")
-
- def ColHeader(big_table = big_table):
- big_table.AddRow([Center(Bold('Description')), Center(Bold('Value'))])
- big_table.AddCellInfo(max(big_table.GetCurrentRowIndex(), 0), 0,
- width="15%")
- big_table.AddCellInfo(max(big_table.GetCurrentRowIndex(), 0), 1,
- width="85%")
- did_col_header = 0
-
- for item in options:
- if type(item) == types.StringType:
- # The very first banner option (string in an options list) is
- # treated as a general description, while any others are
- # treated as section headers - centered and italicized...
- if did_col_header:
- item = "<center><i>" + item + "</i></center>"
- big_table.AddRow([item])
- big_table.AddCellInfo(max(big_table.GetCurrentRowIndex(), 0),
- 0, colspan=2)
- if not did_col_header:
- # Do col header after very first string descr, if any...
- ColHeader()
- did_col_header = 1
- else:
- if not did_col_header:
- # ... but do col header before anything else.
- ColHeader()
- did_col_header = 1
- AddOptionsTableItem(big_table, item, category, lst)
- big_table.AddRow(['<br>'])
- big_table.AddCellInfo(big_table.GetCurrentRowIndex(), 0, colspan=2)
- return big_table
-
-def AddOptionsTableItem(table, item, category, lst, nodetails=0):
- """Add a row to an options table with the item description and value."""
- try:
- got = GetItemCharacteristics(item)
- varname, kind, params, dependancies, descr, elaboration = got
- except ValueError, msg:
- lst.LogMsg("error", "admin: %s", msg)
- return Italic("<malformed option>")
- descr = GetItemGuiDescr(lst, category, varname, descr,
- elaboration, nodetails)
- val = GetItemGuiValue(lst, kind, varname, params)
- table.AddRow([descr, val])
- table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 1,
- bgcolor="#cccccc")
- table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0,
- bgcolor="#cccccc")
-
-def FormatOptionHelp(doc, varref, lst):
- item = bad = None
- reflist = string.split(varref, '/')
- if len(reflist) == 2:
- category, varname = reflist
- options = GetConfigOptions(lst, category)
- for i in options:
- if i and i[0] == varname:
- item = i
- break
- if not item:
- bad = ("Option %s/%s not found. %s"
- % (category, varname, os.environ['PATH_INFO']))
- else:
- try:
- got = GetItemCharacteristics(item)
- varname, kind, params, dependancies, descr, elaboration = got
- except ValueError, msg:
- bad = msg
- if not bad and not elaboration:
- bad = "Option %s has no extended help." % varname
- if bad:
- AddErrorMessage(doc, bad)
- return
-
- header = Table(width="100%")
- legend = ('%s Maillist Configuration Help<br><em>%s</em> Option'
- % (lst.real_name, varname))
- header.AddRow([Center(Header(3, legend))])
- header.AddCellInfo(max(header.GetCurrentRowIndex(), 0), 0,
- colspan=2, bgcolor="#99ccff")
- doc.SetTitle("Mailman %s List Option Help" % varname)
- doc.AddItem(header)
- doc.AddItem("<b>%s</b> (%s): %s<p>" % (varname, category, item[4]))
- doc.AddItem("%s<p>" % item[5])
-
- form = Form(os.path.join(lst.GetRelativeScriptURL('admin'), category))
- valtab = Table(cellspacing=3, cellpadding=4)
- AddOptionsTableItem(valtab, item, category, lst, nodetails=1)
- form.AddItem(valtab)
- # XXX I don't think we want to be able to set options from two places,
- # since they'll go out of sync.
- #form.AddItem(Center(FormatPasswordStuff()))
- doc.AddItem(Center(form))
-
-def GetItemCharacteristics(table_entry):
- """Break out the components of an item description from its table entry:
- 0 option-var name
- 1 type
- 2 entry size
- 3 ?dependancies?
- 4 Brief description
- 5 Optional description elaboration"""
- if len(table_entry) == 5:
- elaboration = None
- varname, kind, params, dependancies, descr = table_entry
- elif len(table_entry) == 6:
- varname, kind, params, dependancies, descr, elaboration = table_entry
- else:
- raise ValueError, ("Badly formed options entry:\n %s"
- % table_entry)
- return (varname, kind, params, dependancies, descr, elaboration)
-
-def GetItemGuiValue(lst, kind, varname, params):
- """Return a representation of an item's settings."""
- if kind == mm_cfg.Radio or kind == mm_cfg.Toggle:
- return RadioButtonArray(varname, params, getattr(lst, varname))
- elif (kind == mm_cfg.String or kind == mm_cfg.Email or
- kind == mm_cfg.Host or kind == mm_cfg.Number):
- return TextBox(varname, getattr(lst, varname), params)
- elif kind == mm_cfg.Text:
- if params:
- r, c = params
- else:
- r, c = None, None
- val = getattr(lst, varname)
- if not val:
- val = ''
- return TextArea(varname, val, r, c)
- elif kind == mm_cfg.EmailList:
- if params:
- r, c = params
- else:
- r, c = None, None
- res = string.join(getattr(lst, varname), '\n')
- return TextArea(varname, res, r, c, wrap='off')
-
-def GetItemGuiDescr(lst, category, varname, descr, elaboration, nodetails):
- """Return a representation of an item's description, with link to
- elaboration if any."""
- descr = '<div ALIGN="right">' + descr
- if not nodetails and elaboration:
- ref = "../" * (mm_utils.GetNestingLevel()-1) + list_name + "/"
- ref = ref + '?VARHELP=' + category + "/" + varname
- descr = Container(descr,
- Link(ref, " (Details)", target="MMHelp"),
- "</div>")
- else:
- descr = descr + "</div>"
- return descr
-
-def FormatMembershipOptions(lst):
- container = Container()
- header = Table(width="100%")
- header.AddRow([Center(Header(2, "Membership Management"))])
- header.AddCellInfo(max(header.GetCurrentRowIndex(), 0), 0,
- colspan=2, bgcolor="#99ccff")
- container.AddItem(header)
- user_table = Table(width="90%")
- user_table.AddRow([Center(Header(4, "Membership List"))])
- user_table.AddCellInfo(user_table.GetCurrentRowIndex(),
- user_table.GetCurrentCellIndex(),
- bgcolor="#cccccc", colspan=8)
-
- members = {}
- digests = {}
- for member in lst.members:
- members[member] = 1
- for member in lst.digest_members:
- digests[member] = 1
- all = lst.members + lst.digest_members
- if len(all) > mm_cfg.ADMIN_MEMBER_CHUNKSIZE:
- chunks = mm_utils.chunkify(all)
- if not cgi_data.has_key("chunk"):
- chunk = 0
- else:
- chunk = string.atoi(cgi_data["chunk"].value)
- all = chunks[chunk]
- footer = ("<p><em>To View other sections, "
- "click on the appropriate range listed below</em>")
- chunk_indices = range(len(chunks))
- chunk_indices.remove(chunk)
- buttons = []
- pi = os.environ["PATH_INFO"]
- for ci in chunk_indices:
- start, end = chunks[ci][0], chunks[ci][-1]
- buttons.append("<a href=/mailman/admin%s?chunk=%d> from %s to %s </a>" % \
- ( pi, ci, start, end))
- buttons = apply(UnorderedList, tuple(buttons))
- footer = footer + buttons.Format() + "<p>"
- else:
- all.sort()
- footer = "<p>"
- for member in all:
- cells = [member + "<input type=hidden name=user value=%s>" % (member),
- "subscribed " +CheckBox(member + "_subscribed", "on", 1).Format(),
- ]
- if members.get(member):
- cells.append("digest " + CheckBox(member + "_digest", "off", 0).Format())
- else:
- cells.append("digest " + CheckBox(member + "_digest", "on", 1).Format())
- for opt in ("hide", "nomail", "ack", "norcv", "plain"):
- if lst.GetUserOption(member, mm_mailcmd.option_info[opt]):
- value = "on"
- checked = 1
- else:
- value = "off"
- checked = 0
- box = CheckBox("%s_%s" % (member, opt), value, checked)
- cells.append("%s %s" % (opt, box.Format()))
- user_table.AddRow(cells)
- container.AddItem(Center(user_table))
- container.AddItem(footer)
- t = Table(width="90%")
- t.AddRow([Center(Header(4, "Mass Subscribe Members"))])
- t.AddCellInfo(t.GetCurrentRowIndex(),
- t.GetCurrentCellIndex(),
- bgcolor="#cccccc", colspan=8)
- container.AddItem(Center(t))
- container.AddItem(Center(TextArea(name='subscribees', rows=10,cols=60,wrap=None)))
- container.AddItem(Center("<em> Enter One address per line</em><p>"))
- return container
-
-def FormatPasswordStuff():
- submit = Table(bgcolor="#99ccff",
- border=0, cellspacing=0, cellpadding=2, width="100%")
- submit.AddRow([Bold(SubmitButton('submit', 'Submit Your Changes'))])
- submit.AddCellInfo(submit.GetCurrentRowIndex(), 0, align="middle")
- change_pw_table = Table(bgcolor="#99cccc", border=0,
- cellspacing=0, cellpadding=2, width="90%")
- change_pw_table.AddRow([Bold(Center('To Change The Administrator Password')),
- '<div ALIGN="right"> Enter the new password: </div>',
- PasswordBox('newpw'),])
- change_pw_table.AddCellInfo(0, 0, align="middle", colspan=2)
- change_pw_table.AddRow(['<div ALIGN="right"> Enter the current password </div>',
- PasswordBox('adminpw'),
- '<div ALIGN="right">Again to confirm it:</div>',
- PasswordBox('confirmpw')])
- password_stuff = Container()
- password_stuff.AddItem(change_pw_table)
- password_stuff.AddItem("<p>")
- password_stuff.AddItem(submit)
- return password_stuff
-
-# XXX klm - looks like turn_on_moderation is orphaned.
-turn_on_moderation = 0
-
-# Options processing
-
-def GetValidValue(lst, prop, my_type, val, dependant):
- if my_type == mm_cfg.Radio or my_type == mm_cfg.Toggle:
- if type(val) <> types.IntType:
- try:
- # XXX Security!?
- val = eval(val)
- except:
- pass
- # Don't know what to do here...
- return val
- elif my_type == mm_cfg.String or my_type == mm_cfg.Text:
- return val
- elif my_type == mm_cfg.Email:
- try:
- valid = mm_utils.ValidEmail(val)
- if valid:
- return val
- except:
- pass
- # Revert to the old value.
- return getattr(lst, prop)
- elif my_type == mm_cfg.EmailList:
- def SafeValidAddr(addr):
- import mm_utils
- try:
- valid = mm_utils.ValidEmail(addr)
- if valid:
- return 1
- else:
- return 0
- except:
- return 0
-
- val = filter(SafeValidAddr,
- map(string.strip, string.split(val, '\n')))
- if dependant and len(val):
- # Wait till we've set everything to turn it on,
- # as we don't want to clobber our special case.
- # XXX klm - looks like turn_on_moderation is orphaned?
- turn_on_moderation = 1
- return val
- elif my_type == mm_cfg.Host:
- return val
-##
-## This code is sendmail dependant, so we'll just live w/o
-## the error checking for now.
-##
-## # Shouldn't have to read in the whole file.
-## file = open('/etc/sendmail.cf', 'r')
-## lines = string.split(file.read(), '\n')
-## file.close()
-## def ConfirmCWEntry(item):
-## return item[0:2] == 'Cw'
-## lines = filter(ConfirmCWEntry, lines)
-## if not len(lines):
-## # Revert to the old value.
-## return getattr(list, prop)
-## for line in lines:
-## if string.lower(string.strip(line[2:])) == string.lower(val):
-## return val
-## return getattr(list, prop)
- elif my_type == mm_cfg.Number:
- try:
- num = eval(val)
- if num < 0:
- return getattr(lst, prop)
- return num
- except:
- return getattr(lst, prop)
- else:
- # Should never get here...
- return val
-
-
-def ChangeOptions(lst, category, cgi_info, document):
- dirty = 0
- confirmed = 0
- if cgi_info.has_key('newpw'):
- if cgi_info.has_key('confirmpw'):
- if cgi_info.has_key('adminpw'):
- try:
- lst.ConfirmAdminPassword(cgi_info['adminpw'].value)
- confirmed = 1
- except mm_err.MMBadPasswordError:
- m = "Error: incorrect administrator password"
- document.AddItem(Header(3, Italic(FontAttr(m, color="ff5060"))))
- confirmed = 0
- if confirmed:
- new = cgi_info['newpw'].value
- confirm = cgi_info['confirmpw'].value
- if new == confirm:
- lst.password = crypt.crypt(new, mm_utils.GetRandomSeed())
- dirty = 1
- else:
- m = 'Error: Passwords did not match.'
- document.AddItem(Header(3, Italic(FontAttr(m, color="ff5060"))))
-
- else:
- m = 'Error: You must type in your new password twice.'
- document.AddItem(
- Header(3, Italic(FontAttr(m, color="ff5060"))))
- #
- # for some reason, the login page mangles important values for the list
- # such as .real_name so we only process these changes if the category
- # is not "members" and the request is not from the login page
- # -scott 19980515
- #
- if category != 'members' and not cgi_info.has_key("request_login") and\
- len(cgi_info.keys()) > 1:
- opt_list = GetConfigOptions(lst, category)
- for item in opt_list:
- if len(item) < 5:
- continue
- property, kind, args, deps, desc = (item[0], item[1], item[2],
- item[3], item[4])
- if not cgi_info.has_key(property):
- if (kind <> mm_cfg.Text and
- kind <> mm_cfg.String and
- kind <> mm_cfg.EmailList):
- continue
- else:
- val = ''
- else:
- val = cgi_info[property].value
- value = GetValidValue(lst, property, kind, val, deps)
- if getattr(lst, property) != value:
- setattr(lst, property, value)
- dirty = 1
- #
- # mass subscription processing for members category
- #
- if cgi_info.has_key('subscribees'):
- name_text = cgi_info['subscribees'].value
- name_text = string.replace(name_text, '\r', '')
- names = string.split(name_text, '\n')
- if '' in names:
- names.remove('')
- subscribe_success = []
- subscribe_errors = []
- for new_name in map(string.strip,names):
- digest = 0
- if not lst.digestable:
- digest = 0
- if not lst.nondigestable:
- digest = 1
- try:
- lst.ApprovedAddMember(new_name, (mm_utils.GetRandomSeed() +
- mm_utils.GetRandomSeed()), digest)
- subscribe_success.append(new_name)
- except mm_err.MMAlreadyAMember:
- subscribe_errors.append((new_name, 'Already a member'))
-
- except mm_err.MMBadEmailError:
- subscribe_errors.append((new_name, "Bad/Invalid email address"))
- except mm_err.MMHostileAddress:
- subscribe_errors.append((new_name, "Hostile Address (illegal characters)"))
- if subscribe_success:
- document.AddItem(Header(5, "Successfully Subscribed:"))
- document.AddItem(apply(UnorderedList, tuple((subscribe_success))))
- document.AddItem("<p>")
- if subscribe_errors:
- document.AddItem(Header(5, "Error Subscribing:"))
- items = map(lambda x: "%s -- %s" % (x[0], x[1]), subscribe_errors)
- document.AddItem(apply(UnorderedList, tuple((items))))
- document.AddItem("<p>")
- #
- # do the user options for members category
- #
- if cgi_info.has_key('user'):
- user = cgi_info["user"]
- if type(user) is type([]):
- users = []
- for ui in range(len(user)):
- users.append(user[ui].value)
- else:
- users = [user.value]
- for user in users:
- if not cgi_info.has_key('%s_subscribed' % (user)):
- lst.DeleteMember(user)
- dirty = 1
- continue
- if not cgi_info.has_key("%s_digest" % (user)):
- if user in lst.digest_members:
- list.digest_members.remove(user)
- dirty = 1
- if user not in lst.members:
- lst.members.append(user)
- dirty = 1
- else:
- if user not in lst.digest_members:
- lst.digest_members.append(user)
- dirty = 1
- if user in lst.members:
- lst.members.remove(user)
- dirty = 1
-
- for opt in ("hide", "nomail", "ack", "norcv", "plain"):
- if cgi_info.has_key("%s_%s" % (user, opt)):
- lst.SetUserOption(user, mm_mailcmd.option_info[opt], 1)
- dirty = 1
- else:
- lst.SetUserOption(user, mm_mailcmd.option_info[opt], 0)
- dirty = 1
-
-
- if dirty:
- lst.Save()
-
-def AddErrorMessage(doc, errmsg, *args):
- doc.AddItem(Header(3, Italic(FontAttr(errmsg % args,
- color="#ff66cc"))))
-
-
-_config_info = None
-def GetConfigOptions(lst, category):
- global _config_info
- if _config_info == None:
- _config_info = lst.GetConfigInfo()
- return _config_info[category]
-
-if __name__ == "__main__":
- try:
- main()
- except KeyboardInterrupt:
- print "Interrupted!"
- raise SystemExit, 0
- except mm_err.MMUnknownListError, msg:
- FormatAdminOverview(error="List <em>%s</em> not found." % list_name)
- except:
- print "Content-type: text/html\n"
-
- print "<p><h3>We're sorry, we hit a bug!</h3>\n"
- print "If you would like to help us identify the problem, please "
- print "email a copy of this page to the webmaster for this site"
- print 'with a description of what happened. Thanks!'
- print "\n<PRE>"
- try:
- import traceback
- sys.stderr = sys.stdout
- traceback.print_exc()
- except:
- print "[failed to get traceback]"
- print "\n\n</PRE>"
+ \ No newline at end of file
diff --git a/cgi/admindb b/cgi/admindb
index caefc4e27..c6b5bc25e 100755
--- a/cgi/admindb
+++ b/cgi/admindb
@@ -16,225 +16,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-"""Produce and process the pending-approval items for a list."""
+import paths
-import sys
-import os, cgi, string, crypt, types
-import paths # path hacking
-import mm_utils, maillist, mm_err, htmlformat
+def admindb():
+ import Mailman.Cgi.admindb
-try:
- sys.stderr = mm_utils.StampedLogger("error", label = 'admindb',
- manual_reprime=1, nofail=0)
-except IOError:
- pass # Oh well - SOL on redirect, errors show thru.
-
-
-doc = htmlformat.Document()
-
-path = os.environ['PATH_INFO']
-list_info = mm_utils.GetPathPieces(path)
-
-
-if len(list_info) < 1:
- doc.SetTitle("Admindb Error")
- doc.AddItem(htmlformat.Header(2, "Invalid options to CGI script."))
- print doc.Format(bgcolor="#ffffff")
- sys.exit(0)
-list_name = string.lower(list_info[0])
-
-try:
- list = maillist.MailList(list_name)
-except:
- msg = "%s: No such list." % list_name
- doc.SetTitle("Admindb Error - %s" % msg)
- doc.AddItem(htmlformat.Header(2, msg))
- print doc.Format(bgcolor="#ffffff")
- sys.exit(0)
-
-if not list._ready:
- msg = "%s: No such list." % list_name
- doc.SetTitle("Admindb Error - %s" % msg)
- doc.AddItem(htmlformat.Header(2, msg))
- print doc.Format(bgcolor="#ffffff")
- sys.exit(0)
-
-# Note, these 2 functions use i only to count the number of times to
-# go around. We always operate on the first element of the list
-# because we're going to delete the element after we operate on it.
-
-def SubscribeAll():
- for i in range(len(list.requests['add_member'])):
- comment_key = 'comment-%d' % list.requests['add_member'][0][0]
- if form.has_key(comment_key):
- list.HandleRequest(('add_member', 0), 1, form[comment_key].value)
- else:
- list.HandleRequest(('add_member', 0), 1)
-
-def SubscribeNone():
- for i in range(len(list.requests['add_member'])):
- comment_key = 'comment-%d' % list.requests['add_member'][0][0]
- if form.has_key(comment_key):
- list.HandleRequest(('add_member', 0), 0, form[comment_key].value)
- else:
- list.HandleRequest(('add_member', 0), 0)
-
-def PrintHeader(str, error=0):
- if error:
- it = htmlformat.FontAttr(str, color="ff5060")
- else:
- it = str
- doc.AddItem(htmlformat.Header(3, htmlformat.Italic(it)))
- doc.AddItem('<hr>')
-
-def HandleRequests(doc):
- if not form.has_key('adminpw'):
- PrintHeader('You need to supply the admin password '
- 'to answer requests.', error=1)
- return
- try:
- list.ConfirmAdminPassword(form['adminpw'].value)
- except:
- PrintHeader('Incorrect admin password.', error=1)
- return
- ignore_subscribes = 0
- if form.has_key('subscribe_all'):
- ignore_subscribes = 1
- SubscribeAll()
- elif form.has_key('subscribe_none'):
- ignore_subscribes = 1
- SubscribeNone()
- for k in form.keys():
- try:
- # XXX Security?!
- v = eval(form[k].value)
- request_id = eval(k)
- except: # For stuff like adminpw
- continue
- if type(request_id) <> types.IntType:
- continue
- try:
- request = list.GetRequest(request_id)
- except mm_err.MMBadRequestId:
- continue # You've already changed the database. No biggie.
- if ignore_subscribes and request[0] == 'add_member':
- # We already handled this request.
- continue
- comment_key = 'comment-%d' % request_id
- if form.has_key(comment_key):
- list.HandleRequest(request, v, form[comment_key].value)
- else:
- list.HandleRequest(request, v)
- list.Save()
- PrintHeader('Database Updated...')
-
-
-def PrintAddMemberRequest(val, table):
- table.AddRow([
- val[3],
- htmlformat.RadioButtonArray(val[0], ("Refuse", "Subscribe")),
- htmlformat.TextBox("comment-%d" % val[0], size=50)
- ])
-
-def PrintPostRequest(val, form):
- t = htmlformat.Table(cellspacing=10)
- t.AddRow([
- htmlformat.FontSize("+1",
- htmlformat.Bold('Post held because: ')),
- val[3]])
- t.AddRow([
- htmlformat.FontSize("+1",
- htmlformat.Bold('Action to take on this post:')),
- htmlformat.RadioButtonArray(val[0], ("Approve", "Reject",
- "Discard (eg, spam)")),
- htmlformat.SubmitButton('submit', 'Submit All Data')
- ])
- t.AddRow([
- htmlformat.FontSize("+1",
- htmlformat.Bold('If you reject this post, '
- 'explain (optional):')),
- htmlformat.TextBox("comment-%d" % val[0], size=50)])
-
- cur_row = t.GetCurrentRowIndex()
- cur_col = t.GetCurrentCellIndex()
- t.AddCellInfo(cur_row, cur_col, colspan=3)
-
- t.AddRow([
- htmlformat.FontSize("+1",
- htmlformat.Bold('Contents:'))])
- form.AddItem(t)
- form.AddItem(htmlformat.Preformatted(val[2][1]))
- form.AddItem('<p>')
-
-
-def PrintRequests(doc):
- # The only types of requests we know about are add_member and post.
- # Anything else that might have gotten in here somehow we'll just
- # ignore (This should never happen unless someone is hacking at
- # the code).
-
- doc.AddItem(htmlformat.Header(2, "Administrative requests for "
- "'%s' mailing list" % list.real_name))
- doc.AddItem(htmlformat.FontSize("+1", htmlformat.Link(
- list.GetRelativeScriptURL('admin'), htmlformat.Italic(
- 'View or edit the list configuration information'))))
- doc.AddItem('<p><hr>')
- if not list.RequestsPending():
- doc.AddItem(htmlformat.Header(3,'There are no pending requests.'))
- doc.AddItem(list.GetMailmanFooter())
- return
- form = htmlformat.Form(list.GetRelativeScriptURL('admindb'))
- doc.AddItem(form)
- form.AddItem('Admin password: ')
- form.AddItem(htmlformat.PasswordBox('adminpw'))
- form.AddItem('<p>')
- if list.requests.has_key('add_member'):
-## form.AddItem('<hr>')
-## t = htmlformat.Table(cellspacing=10)
-## t.AddRow([
-## htmlformat.SubmitButton('submit', 'Submit All Data'),
-## htmlformat.SubmitButton('subscribe_all', 'Subscribe Everybody'),
-## htmlformat.SubmitButton('subscribe_none', 'Refuse Everybody')
-## ])
-## form.AddItem(t)
- form.AddItem('<hr>')
- form.AddItem(htmlformat.Center(
- htmlformat.Header(2, 'Subscription Requests')))
- t = htmlformat.Table(border=2)
- t.AddRow([
- htmlformat.Bold('Email'),
- htmlformat.Bold('Descision'),
- htmlformat.Bold('Reasoning for subscription refusal (optional)')])
- for request in list.requests['add_member']:
- PrintAddMemberRequest(request, t)
-
- form.AddItem(t)
- t = htmlformat.Table(cellspacing=10)
- t.AddRow([
- htmlformat.SubmitButton('submit', 'Submit All Data'),
- htmlformat.SubmitButton('subscribe_all', 'Subscribe Everybody'),
- htmlformat.SubmitButton('subscribe_none', 'Refuse Everybody')
- ])
- form.AddItem(t)
-
- # Print submitit buttons...
- if list.requests.has_key('post'):
- for request in list.requests['post']:
- form.AddItem('<hr>')
- form.AddItem(htmlformat.Center(htmlformat.Header(2, "Held Message")))
- PrintPostRequest(request, form)
- doc.AddItem(list.GetMailmanFooter())
-
-try:
- form = cgi.FieldStorage()
- if len(form.keys()):
- doc.SetTitle("%s Admindb Results" % list.real_name)
- HandleRequests(doc)
- else:
- doc.SetTitle("%s Admindb" % list.real_name)
- PrintRequests(doc)
- text = doc.Format(bgcolor="#ffffff")
- print text
- sys.stdout.flush()
-finally:
- list.Unlock()
+from Mailman.runcgi import *
+wrap_func(admindb)
diff --git a/cgi/archives b/cgi/archives
index 3640e0166..782cdcd20 100755
--- a/cgi/archives
+++ b/cgi/archives
@@ -1,4 +1,4 @@
-#! /usr/bin/env/python
+#! /usr/bin/env python
#
# Copyright (C) 1998 by the Free Software Foundation, Inc.
#
@@ -16,79 +16,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-# This script is being deprecated, in favor hookups for an external archiver.
+import paths
-# We don't need to lock in this script, because we're never going to change
-# data.
+def archives():
+ import Mailman.Cgi.archives
-import sys
-import os, types, posix, string
-import paths # path hacking
-import mm_utils, maillist, htmlformat
-
-try:
- sys.stderr = mm_utils.StampedLogger("error", label = 'archives',
- manual_reprime=1, nofail=0)
-except IOError:
- pass # Oh well - SOL on redirect, errors show thru.
-
-
-print "Content-type: text/html"
-print
-
-path = os.environ['PATH_INFO']
-list_info = mm_utils.GetPathPieces(path)
-
-if len(list_info) < 1:
- print "<h2>Invalid options to CGI script.</h2>"
- sys.exit(0)
-
-list_name = string.lower(list_info[0])
-
-try:
- list = maillist.MailList(list_name)
-except:
- print "<h2>%s: No such list.</h2>" % list_name
- sys.exit(0)
-
-if not list._ready:
- print "<h2>%s: No such list.</h2>" % list_name
- sys.exit(0)
-
-def GetArchiveList(list):
- archive_list = htmlformat.UnorderedList()
-
- def ArchiveFilter(str):
- if str[:7] <> 'volume_':
- return 0
- try:
- x = eval(str[7:])
- if type(x) <> types.IntType:
- return 0
- if x < 1:
- return 0
- return 1
- except:
- return 0
- try:
- dir_listing = filter(ArchiveFilter, os.listdir(list.archive_directory))
- except posix.error:
- return "<h3><em>No archives are currently available.</em></h3>"
- if not len(dir_listing):
- return "<h3><em>No archives are currently available.</em></h3>"
- for dir in dir_listing:
- link = htmlformat.Link(os.path.join(list._base_archive_url, dir),
- "Volume %s" % dir[7:])
- archive_list.AddItem(link)
-
- return archive_list.Format()
-
-
-
-
-replacements = list.GetStandardReplacements()
-replacements['<mm-archive-list>'] = GetArchiveList(list)
-
-# Just doing print list.ParseTags(...) calls ParseTags twice???
-text = list.ParseTags('archives.html', replacements)
-print text
+from Mailman.runcgi import *
+wrap_func(archives)
diff --git a/cgi/edithtml b/cgi/edithtml
index 509bf25a7..7b6574da2 100755
--- a/cgi/edithtml
+++ b/cgi/edithtml
@@ -16,160 +16,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-"""Script which implements admin editing of the list's html templates."""
+import paths
-import sys
-import os, cgi, string, crypt, types
-import paths # path hacking
-import mm_utils, maillist, mm_cfg
-import htmlformat
+def edithtml():
+ import Mailman.Cgi.edithtml
-try:
- sys.stderr = mm_utils.StampedLogger("error", label = 'edithtml',
- manual_reprime=1, nofail=0)
-except IOError:
- pass # Oh well - SOL on redirect, errors show thru.
-
-
-#Editable templates. We should also be able to edit the archive index, which
-#currently isn't a working template, but will be soon.
-
-template_data = (('listinfo.html', 'General list information page'),
- ('subscribe.html', 'Subscribe results page'),
- ('options.html', 'User specific options page'),
- ('handle_opts.html', 'Changing user options results page'),
- ('archives.html', 'Archives index page')
- )
-
-
-def InitDocument():
- return htmlformat.HeadlessDocument()
-
-doc = InitDocument()
-
-path = os.environ['PATH_INFO']
-list_info = mm_utils.GetPathPieces(path)
-
-if len(list_info) < 1:
- doc.AddItem(htmlformat.Header(2, "Invalid options to CGI script."))
- print doc.Format()
- sys.exit(0)
-
-list_name = string.lower(list_info[0])
-
-try:
- list = maillist.MailList(list_name, lock=0)
-except:
- doc.AddItem(htmlformat.Header(2, "%s : No such list" % list_name))
- print doc.Format()
- sys.exit(0)
-
-if not list._ready:
- doc.AddItem(htmlformat.Header(2, "%s : No such list" % list_name))
- print doc.Format()
- sys.exit(0)
-
-
-if len(list_info) > 1:
- template_name = list_info[1]
- for (template, info) in template_data:
- if template == template_name:
- template_info = info
- doc.SetTitle('%s -- Edit html for %s' %
- (list.real_name, template_info))
- break
- else:
- doc.SetTitle('Edit HTML : Error')
- doc.AddItem(htmlformat.Header(2, "%s: Invalid template" % template_name))
- doc.AddItem(list.GetMailmanFooter())
- print doc.Format()
- sys.exit(0)
-else:
- doc.SetTitle('%s -- HTML Page Editing' % list.real_name)
- doc.AddItem(htmlformat.Header(1, '%s -- HTML Page Editing' % list.real_name))
- doc.AddItem(htmlformat.Header(2, 'Select page to edit:'))
- template_list = htmlformat.UnorderedList()
- for (template, info) in template_data:
- l = htmlformat.Link(os.path.join(list.GetRelativeScriptURL('edithtml'),
- template), info)
-
- template_list.AddItem(l)
- doc.AddItem(htmlformat.FontSize("+2", template_list))
- doc.AddItem(list.GetMailmanFooter())
- print doc.Format()
- sys.exit(0)
-
-
-def FormatHTML(doc):
- doc.AddItem(htmlformat.Header(1,'%s:' % list.real_name))
- doc.AddItem(htmlformat.Header(1, template_info))
-
- doc.AddItem('<hr>')
-
- link = htmlformat.Link(list.GetRelativeScriptURL('admin'),
- 'View or edit the list configuration information.')
- doc.AddItem(htmlformat.FontSize("+1", link))
- doc.AddItem('<p>')
-
- doc.AddItem('<hr>')
-
- form = htmlformat.Form(os.path.join(list.GetRelativeScriptURL('edithtml'),
- template_name))
- doc.AddItem(form)
-
- password_table = htmlformat.Table()
- password_table.AddRow(['Enter the admin password to edit html:',
- htmlformat.PasswordBox('adminpw')])
- password_table.AddRow(['When you are done making changes...',
- htmlformat.SubmitButton('submit', 'Submit Changes')])
-
- form.AddItem(password_table)
-
- text = mm_utils.QuoteHyperChars(list.SnarfHTMLTemplate(template_name))
- form.AddItem(htmlformat.TextArea('html_code', text, rows=40, cols=75))
-
-def ChangeHTML(list, cgi_info, template_name, doc):
- if not cgi_info.has_key('html_code'):
- doc.AddItem(htmlformat.Header(3,"Can't have empty html page."))
- doc.AddItem(htmlformat.Header(3,"HTML Unchanged."))
- doc.AddItem('<hr>')
- return
- code = cgi_info['html_code'].value
- f = open(os.path.join(list._template_dir, template_name), 'w')
- f.write(code)
- f.close()
- doc.AddItem(htmlformat.Header(3, 'HTML successfully updated.'))
- doc.AddItem('<hr>')
-
-try:
- cgi_data = cgi.FieldStorage()
- if len(cgi_data.keys()):
- if not cgi_data.has_key('adminpw'):
- m = 'Error: You must supply the admin password to edit html.'
- doc.AddItem(htmlformat.Header(3,
- htmlformat.Italic(
- htmlformat.FontAttr(
- m, color="ff5060"))))
- doc.AddItem('<hr>')
- else:
- try:
- list.ConfirmAdminPassword(cgi_data['adminpw'].value)
- ChangeHTML(list, cgi_data, template_name, doc)
- except:
- m = 'Error: Incorrect admin password.'
- doc.AddItem(htmlformat.Header(3,
- htmlformat.Italic(
- htmlformat.FontAttr(
- m, color="ff5060"))))
- doc.AddItem('<hr>')
-
-
-
- FormatHTML(doc)
-
-finally:
- try:
- doc.AddItem(list.GetMailmanFooter())
- print doc.Format()
- except:
- pass
+from Mailman.runcgi import *
+wrap_func(edithtml)
diff --git a/cgi/handle_opts b/cgi/handle_opts
index 45a98858c..f43fb99ef 100755
--- a/cgi/handle_opts
+++ b/cgi/handle_opts
@@ -16,199 +16,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-"""Process input to user options form."""
+import paths
-import sys
-import os, cgi, string
-import paths # path hacking
-import mm_utils, maillist, mm_err, mm_cfg, htmlformat
+def handle_opts():
+ import Mailman.Cgi.handle_opts
-try:
- sys.stderr = mm_utils.StampedLogger("error", label = 'handle_opts',
- manual_reprime=1, nofail=0)
-except IOError:
- pass # Oh well - SOL on redirect, errors show thru.
-
-
-doc = htmlformat.Document()
-
-path = os.environ['PATH_INFO']
-list_info = mm_utils.GetPathPieces(path)
-
-if len(list_info) < 2:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("Invalid options to CGI script."))
- print doc.Format(bgcolor="#ffffff")
- sys.exit(0)
-
-list_name = string.lower(list_info[0])
-user = list_info[1]
-
-if len(list_info) < 2:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("Invalid options to CGI script."))
- print doc.Format(bgcolor="#ffffff")
- sys.exit(0)
-
-try:
- list = maillist.MailList(list_name)
-except:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("%s: No such list." % list_name))
- print doc.Format(bgcolor="#ffffff")
- sys.exit(0)
-
-if not list._ready:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("%s: No such list." % list_name))
- print doc.Format(bgcolor="#ffffff")
- list.Unlock()
- sys.exit(0)
-
-
-def PrintResults(results):
- replacements = list.GetStandardReplacements()
- replacements['<mm-results>'] = results
- replacements['<mm-operation>'] = operation
- output = list.ParseTags('handle_opts.html', replacements)
-
- doc.AddItem(output)
- print doc.Format(bgcolor="#ffffff")
- list.Unlock()
- sys.exit(0)
-
-form = cgi.FieldStorage()
-
-error = 0
-operation = ""
-
-if string.lower(user) not in list.members + list.digest_members:
- PrintResults("%s not a member!<p>" % user)
-
-if form.has_key("unsub"):
- operation = "Unsubscribe"
- if not form.has_key("upw"):
- PrintResults("You must give your password to unsubscribe.<p>")
- else:
- try:
- pw = form["upw"].value
- if list.ConfirmUserPassword(user, pw):
- list.DeleteMember(user, "web cmd")
- except mm_err.MMListNotReady:
- PrintResults("List is not functional.")
- except mm_err.MMNoSuchUserError:
- PrintResults("You seem to already be not a member.<p>")
- except mm_err.MMBadUserError:
- PrintResults("Your account has gone awry - "
- "please contact the list administrator!<p>")
- except mm_err.MMBadPasswordError:
- PrintResults("That password was incorrect.<p>")
-# except:
-# PrintResults('''An unknown error occured. <p>
-#Please send mail to <a href=%s>%s</a> explaining
-#exactly what you did to get this error.<p>''' % (mm_cfg.MAILMAN_OWNER,
-# mm_cfg.MAILMAN_OWNER))
-
- PrintResults("You have been unsubscribed.<p>")
-elif form.has_key("emailpw"):
- try:
- list.MailUserPassword(user)
- PrintResults("A reminder of your password "
- "has been emailed to you.<p>")
- except mm_err.MMBadUserError:
- PrintResults("Your password entry has not been found. The list "
- "manager is being notified.<p>")
-
-elif form.has_key("changepw"):
- if (form.has_key('opw')
- and form.has_key('newpw')
- and form.has_key('confpw')):
- try:
- list.ConfirmUserPassword(user, form['opw'].value)
- list.ChangeUserPassword(user,
- form['newpw'].value, form['confpw'].value)
- except mm_err.MMListNotReady:
- PrintResults("The list is currently not funcitonal.")
- except mm_err.MMNotAMemberError:
- PrintResults("You seem to no longer be a list member.")
- except mm_err.MMBadPasswordError:
- PrintResults("The old password you supplied was incorrect.")
- except mm_err.MMPasswordsMustMatch:
- PrintResults("Passwords must match.")
- except:
- PrintResults('''An unknown error occured. <p>
-Please send mail to <a href=%s>%s</a> explaining
-exactly what you did to get this error.<p>''' % (mm_cfg.MAILMAN_OWNER, mm_cfg.MAILMAN_OWNER))
-
-
- PrintResults("Your password has been changed.")
- else:
- PrintResults("You must supply your old password,"
- " and your new password twice.")
-
-else:
- # If keys don't exist, set them to whatever they were. (essentially a noop)
- if form.has_key("digest"):
- digest_value = eval(form["digest"].value)
- else:
- digest_value = list.GetUserOption(user, mm_cfg.Digests)
- if form.has_key("mime"):
- mime = eval(form["mime"].value)
- else:
- mime = list.GetUserOption(user, mm_cfg.DisableMime)
- if form.has_key("dontreceive"):
- dont_receive = eval(form["dontreceive"].value)
- else:
- dont_receive = list.GetUserOption(user, mm_cfg.DontReceiveOwnPosts)
- if form.has_key("ackposts"):
- ack_posts = eval(form["ackposts"].value)
- else:
- ack_posts = list.GetUserOption(user, mm_cfg.AcknowlegePosts)
- if form.has_key("disablemail"):
- disable_mail = eval(form["disablemail"].value)
- else:
- disable_mail = list.GetUserOption(user, mm_cfg.DisableDelivery)
- if form.has_key("conceal"):
- conceal = eval(form["conceal"].value)
- else:
- conceal = list.GetUserOption(user, mm_cfg.ConcealSubscription)
-
- if not form.has_key("digpw"):
- PrintResults("You must supply a password to change options.")
- try:
- list.ConfirmUserPassword(user, form['digpw'].value)
- except mm_err.MMAlreadyDigested:
- pass
- except mm_err.MMAlreadyUndigested:
- pass
- except mm_err.MMMustDigestError:
- PrintResults("List only accepts digest members.")
- except mm_err.MMCantDigestError:
- PrintResults("List doesn't accept digest members.")
- except mm_err.MMNotAMemberError:
- PrintResults("%s isn't subscribed to this list." % mail.GetSender())
- except mm_err.MMListNotReady:
- PrintResults("List is not functional.")
- except mm_err.MMNoSuchUserError:
- PrintResults("%s is not subscribed to this list." %mail.GetSender())
- except mm_err.MMBadPasswordError:
- PrintResults("You gave the wrong password.")
- except:
- PrintResults('''An unknown error occured. <p>
-Please send mail to <a href=%s>%s</a> explaining
-exactly what you did to get this error.<p>''' % (mm_cfg.MAILMAN_OWNER))
-
-
- list.SetUserOption(user, mm_cfg.DisableDelivery, disable_mail)
- list.SetUserOption(user, mm_cfg.DontReceiveOwnPosts, dont_receive)
- list.SetUserOption(user, mm_cfg.AcknowlegePosts, ack_posts)
- list.SetUserOption(user, mm_cfg.DisableMime, mime)
- try:
- list.SetUserDigest(user, digest_value)
- except (mm_err.MMAlreadyDigested, mm_err.MMAlreadyUndigested):
- pass
- list.SetUserOption(user, mm_cfg.ConcealSubscription, conceal)
- PrintResults("You have successfully set your options.")
-
-
-list.Unlock() \ No newline at end of file
+from Mailman.runcgi import *
+wrap_func(handle_opts)
diff --git a/cgi/listinfo b/cgi/listinfo
index b32cfbfd1..cdb6976a6 100755
--- a/cgi/listinfo
+++ b/cgi/listinfo
@@ -16,171 +16,11 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-"""Produce listinfo page, primary web entry-point to maillists.
+import paths
-Errors are redirected to logs/errors."""
+def listinfo():
+ import Mailman.Cgi.listinfo
+ Mailman.Cgi.listinfo.main()
-# No lock needed in this script, because we don't change data.
-
-import sys
-import os, string
-from regsub import gsub
-import paths # path hacking
-import mm_utils, maillist, mm_cfg
-from htmlformat import *
-
-try:
- sys.stderr = mm_utils.StampedLogger("error", label = 'listinfo',
- manual_reprime=1, nofail=0)
-except IOError:
- pass # Oh well - SOL on redirect, errors show thru.
-
-def main():
- try:
- path = os.environ['PATH_INFO']
- except KeyError:
- path = ""
-
- list_info = mm_utils.GetPathPieces(path)
-
- if len(list_info) == 0:
- FormatListinfoOverview()
- return
-
- list_name = string.lower(list_info[0])
-
- try:
- list = maillist.MailList(list_name, lock=0)
- except:
- list = None
-
- if not (list and list._ready):
- FormatListinfoOverview(error="List <em>%s</em> not found." % list_name)
- return
-
- FormatListListinfo(list)
-
-def FormatListinfoOverview(error=None):
- "Present a general welcome and itemize the (public) lists for this host."
- doc = Document()
- legend = "%s maillists" % mm_cfg.DEFAULT_HOST_NAME
- doc.SetTitle(legend)
-
- table = Table(border=0, width="100%")
- table.AddRow([Center(Header(2, legend))])
- table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0,
- colspan=2, bgcolor="#99ccff")
-
- advertised = []
- names = mm_utils.list_names()
- names.sort()
-
- # XXX We need a portable way to determine the host by which we are being
- # visited! An absolute URL would do...
- if os.environ.has_key('HTTP_HOST'):
- http_host = os.environ['HTTP_HOST']
- else:
- http_host = None
-
- for n in names:
- l = maillist.MailList(n, lock = 0)
- if l.advertised:
- if (http_host
- and (string.find(http_host, l.host_name) == -1
- and string.find(l.host_name, http_host) == -1)):
- # List is for different identity for this host - skip it.
- continue
- else:
- advertised.append(l)
-
- if error:
- greeting = FontAttr(error, color="ff5060", size="+1")
- else:
- greeting = "Welcome!"
-
- if not advertised:
- welcome_items = (greeting,
- "<p>"
- " There currently are no publicly-advertised ",
- Link(mm_cfg.MAILMAN_URL, "mailman"),
- " maillists on %s." % mm_cfg.DEFAULT_HOST_NAME,
- )
- else:
-
- welcome_items = (
- greeting,
- "<p>"
- " Below is the collection of publicly-advertised ",
- Link(mm_cfg.MAILMAN_URL, "mailman"),
- " maillists on %s." % mm_cfg.DEFAULT_HOST_NAME,
- (' Click on a list name to visit the info page'
- ' for that list. There you can learn more about the list,'
- ' subscribe to it, or find the roster of current subscribers.'),
- )
-
- welcome_items = (welcome_items +
- (" To visit the info page for an unadvertised list,"
- " open a URL similar to this one, but with a '/' and"
- +
- (" the %slist name appended."
- % ((error and "right ") or ""))
- +
- '<p> List administrators, you can visit ',
- Link(os.path.join('../' * mm_utils.GetNestingLevel(),
- 'admin/'), "the list admin overview page"),
- " to find the management interface for your list."
- "<p>(Send questions or comments to ",
- Link("mailto:%s" % mm_cfg.MAILMAN_OWNER,
- mm_cfg.MAILMAN_OWNER),
- ".)<p>"))
-
- table.AddRow([apply(Container, welcome_items)])
- table.AddCellInfo(max(table.GetCurrentRowIndex(), 0), 0, colspan=2)
-
- if advertised:
- table.AddRow([Italic("List"), Italic("Description")])
- for l in advertised:
- table.AddRow([Link(l.GetRelativeScriptURL('listinfo'),
- Bold(l.real_name)), l.description])
-
- doc.AddItem(table)
-
- print doc.Format(bgcolor="#ffffff")
-
-def FormatListListinfo(list):
- "Expand the listinfo template against the list's settings, and print."
-
- doc = HeadlessDocument()
-
- replacements = list.GetStandardReplacements()
-
- if not list.digestable or not list.nondigestable:
- replacements['<mm-digest-radio-button>'] = ""
- replacements['<mm-undigest-radio-button>'] = ""
- else:
- replacements['<mm-digest-radio-button>'] = list.FormatDigestButton()
- replacements['<mm-undigest-radio-button>'] = \
- list.FormatUndigestButton()
- replacements['<mm-plain-digests-button>'] = list.FormatPlainDigestsButton()
- replacements['<mm-mime-digests-button>'] = list.FormatMimeDigestsButton()
- replacements['<mm-subscribe-box>'] = list.FormatBox('email')
- replacements['<mm-subscribe-button>'] = list.FormatButton('email-button',
- text='Subscribe')
- replacements['<mm-new-password-box>'] = list.FormatSecureBox('pw')
- replacements['<mm-confirm-password>'] = list.FormatSecureBox('pw-conf')
- replacements['<mm-subscribe-form-start>'] = \
- list.FormatFormStart('subscribe')
- replacements['<mm-roster-form-start>'] = list.FormatFormStart('roster')
- replacements['<mm-editing-options>'] = list.FormatEditingOption()
- replacements['<mm-info-button>'] = SubmitButton('UserOptions',
- 'Edit Options').Format()
- replacements['<mm-roster-option>'] = list.FormatRosterOptionForUser()
-
- # Do the expansion.
- doc.AddItem(list.ParseTags('listinfo.html', replacements))
-
- print doc.Format()
-
-
-if __name__ == "__main__":
- main()
+from Mailman.runcgi import *
+wrap_func(listinfo)
diff --git a/cgi/options b/cgi/options
index 2dcf3d666..60cabfd9d 100755
--- a/cgi/options
+++ b/cgi/options
@@ -16,120 +16,10 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-"""Produce user options form, from list options.html template.
+import paths
-Takes listname/userid in PATH_INFO, expecting an `obscured' userid. Depending
-on the mm_utils.{O,Uno}bscureEmail utilities tolerance, will work fine with an
-unobscured ids as well.
+def options():
+ import Mailman.Cgi.options
-"""
-
-# We don't need to lock in this script, because we're never going to change
-# data.
-
-import sys
-import os, string
-import paths # path hacking
-import mm_utils, maillist, htmlformat, mm_cfg
-
-try:
- sys.stderr = mm_utils.StampedLogger("error", label = 'options',
- manual_reprime=1, nofail=0)
-except IOError:
- pass # Oh well - SOL on redirect, errors show thru.
-
-doc = htmlformat.HeadlessDocument()
-
-try:
- path = os.environ['PATH_INFO']
-except KeyError:
- path = ""
-list_info = mm_utils.GetPathPieces(path)
-
-if len(list_info) < 2:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("Invalid options to CGI script."))
- print doc.Format()
- sys.exit(0)
-
-list_name = string.lower(list_info[0])
-user = mm_utils.UnobscureEmail(list_info[1])
-
-try:
- list = maillist.MailList(list_name)
-except:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("%s: No such list." % list_name ))
- print doc.Format()
- sys.exit(0)
-
-if not list._ready:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("%s: No such list." % list_name ))
- print doc.Format()
- list.Unlock()
- sys.exit(0)
-
-if string.lower(user) not in list.members + list.digest_members:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("%s: No such member %s."
- % (list_name, `user`)))
- doc.AddItem(list.GetMailmanFooter())
- print doc.Format()
- list.Unlock()
- sys.exit(0)
-
-# Re-obscure the user's address for the page banner if obscure_addresses set.
-if list.obscure_addresses:
- presentable_user = mm_utils.ObscureEmail(user, for_text=1)
-else:
- presentable_user = user
-
-replacements = list.GetStandardReplacements()
-replacements['<mm-digest-radio-button>'] = list.FormatOptionButton(
- mm_cfg.Digests, 1, user)
-replacements['<mm-undigest-radio-button>'] = list.FormatOptionButton(
- mm_cfg.Digests, 0, user)
-replacements['<mm-plain-digests-button>'] = list.FormatOptionButton(
- mm_cfg.DisableMime, 1, user)
-replacements['<mm-mime-digests-button>'] = list.FormatOptionButton(
- mm_cfg.DisableMime, 0, user)
-replacements['<mm-delivery-enable-button>'] = list.FormatOptionButton(
- mm_cfg.DisableDelivery, 0, user)
-replacements['<mm-delivery-disable-button>'] = list.FormatOptionButton(
- mm_cfg.DisableDelivery, 1, user)
-replacements['<mm-disabled-notice>'] = list.FormatDisabledNotice(user)
-replacements['<mm-dont-ack-posts-button>'] = list.FormatOptionButton(
- mm_cfg.AcknowlegePosts, 0, user)
-replacements['<mm-ack-posts-button>'] = list.FormatOptionButton(
- mm_cfg.AcknowlegePosts, 1, user)
-replacements['<mm-receive-own-mail-button>'] = list.FormatOptionButton(
- mm_cfg.DontReceiveOwnPosts, 0, user)
-replacements['<mm-dont-receive-own-mail-button>'] = list.FormatOptionButton(
- mm_cfg.DontReceiveOwnPosts, 1, user)
-replacements['<mm-public-subscription-button>'] = list.FormatOptionButton(
- mm_cfg.ConcealSubscription, 0, user)
-replacements['<mm-hide-subscription-button>'] = list.FormatOptionButton(
- mm_cfg.ConcealSubscription, 1, user)
-
-replacements['<mm-digest-submit>'] = list.FormatButton('setdigest',
- 'Submit My Changes')
-replacements['<mm-unsubscribe-button>'] = list.FormatButton('unsub', 'Unsubscribe')
-replacements['<mm-digest-pw-box>'] = list.FormatSecureBox('digpw')
-replacements['<mm-unsub-pw-box>'] = list.FormatSecureBox('upw')
-replacements['<mm-old-pw-box>'] = list.FormatSecureBox('opw')
-replacements['<mm-new-pass-box>'] = list.FormatSecureBox('newpw')
-replacements['<mm-confirm-pass-box>'] = list.FormatSecureBox('confpw')
-replacements['<mm-change-pass-button>'] = list.FormatButton('changepw',
- "Change My Password")
-replacements['<mm-form-start>'] = list.FormatFormStart('handle_opts', user)
-replacements['<mm-user>'] = user
-replacements['<mm-presentable-user>'] = presentable_user
-replacements['<mm-email-my-pw>'] = list.FormatButton('emailpw',
- 'Email My Password To Me')
-
-
-doc.AddItem(list.ParseTags('options.html', replacements))
-print doc.Format()
-
-list.Unlock() \ No newline at end of file
+from Mailman.runcgi import *
+wrap_func(options)
diff --git a/cgi/private b/cgi/private
index facca81bc..b2c4301ac 100755
--- a/cgi/private
+++ b/cgi/private
@@ -1,4 +1,4 @@
-#! /usr/bin/env python -u
+#! /usr/bin/env python
#
# Copyright (C) 1998 by the Free Software Foundation, Inc.
#
@@ -16,219 +16,11 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-"""Provide a password-interface wrapper around a hierarchy of web pages.
+import paths
-Currently this is organized to obtain passwords for mailman maillist
-subscribers.
+def private():
+ import Mailman.Cgi.private
+ Mailman.Cgi.private.main()
- - Set the ROOT variable to point to the root of your archives private
- hierarchy. The script will look there for the private archive files.
- - Put the ../misc/Cookie.py script in ../../cgi-bin (where the wrapper
- executables are).
-"""
-
-import sys, os, string, re
-import paths # path hacking
-import maillist, mm_err, mm_utils
-import Cookie
-
-sys.stderr = sys.stdout
-
-ROOT = "/local/pipermail/private/"
-SECRET = "secret" # XXX used for hashing
-
-PAGE = '''
-<html>
-<head>
- <title>%(listname)s Private Archives Authentication</title>
-</head>
-<body>
-<FORM METHOD=POST ACTION="%(basepath)s/%(path)s">
- <TABLE WIDTH="100%" BORDER="0" CELLSPACING="4" CELLPADDING="5">
- <TR>
- <TD COLSPAN="2" WIDTH="100%" BGCOLOR="#99CCFF" ALIGN="CENTER">
- <B><FONT COLOR="#000000" SIZE="+1">%(listname)s Private Archives
- Authentication</FONT></B>
- </TD>
- </TR>
- <tr>
- <td COLSPAN="2"> <P>%(message)s </td>
- <tr>
- </tr>
- <TD> <div ALIGN="Right">Address: </div></TD>
- <TD> <INPUT TYPE=TEXT NAME=username SIZE=30> </TD>
- <tr>
- </tr>
- <TD> <div ALIGN="Right"> Password: </div> </TD>
- <TD> <INPUT TYPE=password NAME=password SIZE=30></TD>
- <tr>
- </tr>
- <td></td>
- <td> <INPUT TYPE=SUBMIT>
- </td>
- </tr>
- </TABLE>
-</FORM>
-'''
-
-login_attempted = 0
-_list = None
-
-name_pat = re.compile(r"""
-(?: / (?: \d{4} q \d\. )? # Match "/", and, optionally, 1998q1."
- ( [^/]* ) /? # The SIG name
- /[^/]*$ # The trailing 12345.html portion
-) | (?:
- / ( [^/.]* ) # Match matrix-sig
- (?:\.html)? # Optionally match .html
- /? # Optionally match a trailing slash
- $ # Must match to end of string
-
-)
-""", re.VERBOSE)
-
-def getListName(path):
- match = name_pat.search(path)
- if match is None: return
- if match.group(1): return match.group(1)
- if match.group(2): return match.group(2)
- raise ValueError, "Can't identify SIG name"
-
-
-def GetListobj(list_name):
- """Return an unlocked instance of the named maillist, if found."""
- global _list
- if _list:
- return _list
- try:
- _list = maillist.MailList(list_name)
- except mm_err.MMUnknownListError:
- _list = None
- return None
- if _list.Locked():
- _list.Unlock()
- return _list
-
-def isAuthenticated(list_name):
- if os.environ.has_key('HTTP_COOKIE'):
- c = Cookie.Cookie( os.environ['HTTP_COOKIE'] )
- if c.has_key(list_name):
- # The user has a token like 'c++-sig=AE23446AB...'; verify
- # that it's correct.
- token = c[list_name].value
- import base64, md5
- if base64.decodestring(token) != md5.new(SECRET
- + list_name
- + SECRET).digest():
- return 0
- return 1
-
- # No corresponding cookie. OK, then check for username, password
- # CGI variables
- import cgi
- v = cgi.FieldStorage()
- username = password = None
- if v.has_key('username'):
- username = v['username']
- if type(username) == type([]): username = username[0]
- username = username.value
- if v.has_key('password'):
- password = v['password']
- if type(password) == type([]): password = password[0]
- password = password.value
-
- if username is None or password is None: return 0
-
- # Record that this is a login attempt, so if it fails the form can
- # be displayed with an appropriate message.
- global login_attempted
- login_attempted=1
-
- listobj = GetListobj(list_name)
- if not listobj:
- print '\n<P>A list named,', repr(list_name), "was not found."
- return 0
-
- try:
- listobj.ConfirmUserPassword( username, password)
- except (mm_err.MMBadUserError, mm_err.MMBadPasswordError):
- return 1
-
- import base64, md5
- token = md5.new(SECRET + list_name + SECRET).digest()
- token = base64.encodestring(token)
- token = string.strip(token)
- c = Cookie.Cookie()
- c[list_name] = token
- print c # Output the cookie
- return 1
-
-
-def true_path(path):
- "Ensure that the path is safe by removing .."
- path = string.split(path, '/')
- for i in range(len(path)):
- if path[i] == ".": path[i] = "" # ./ is just redundant
- elif path[i] == "..":
- # Remove any .. components
- path[i] = ""
- j=i-1
- while j>0 and path[j] == "": j=j-1
- path[j] = ""
-
- path = filter(None, path)
- return string.join(path, '/')
-
-def processPage(page):
- """Change any URLs that start with ../ to work properly when output from
- /cgi-bin/private"""
- # Escape any % signs not followed by (
- page = re.sub('%([^(])', r'%%\1', page)
-
- # Convert references like HREF="../doc" to just /doc.
- page = re.sub('([\'="])../', r'\1/', page)
-
- return page
-
-def main():
- path = os.environ.get('PATH_INFO', "/index.html")
- true_filename = os.path.join(ROOT, true_path(path) )
- list_name = getListName(path)
-
- if os.path.isdir(true_filename):
- true_filename = true_filename + '/index.html'
-
- if not isAuthenticated(list_name):
- # Output the password form
- page = processPage( PAGE )
-
- listobj = GetListobj(list_name)
- if login_attempted:
- message = ("Your email address or password were incorrect."
- " Please try again.")
- else:
- message = ("Please enter your %s subscription email address."
- " and password " % listobj.real_name)
- while path and path[0] == '/': path=path[1:] # Remove leading /'s
- basepath = os.path.split(listobj.GetBaseArchiveURL())[0]
- listname = listobj.real_name
- print '\n\n', page % vars()
- sys.exit(0)
-
- print '\n\n'
- # Authorization confirmed... output the desired file
- try:
- f = open(true_filename, 'r')
- except IOError:
- print "<H3>Archive File Not Found</H3>"
- print "No file", path
- else:
- while (1):
- data = f.read(16384)
- if data == "": break
- sys.stdout.write(data)
- f.close()
-
-if __name__ == '__main__':
- print 'Content-type: text/html'
- main()
+from Mailman.runcgi import *
+wrap_func(private)
diff --git a/cgi/roster b/cgi/roster
index 65435e914..56944f24a 100755
--- a/cgi/roster
+++ b/cgi/roster
@@ -16,107 +16,11 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-"""Produce subscriber roster, using listinfo form data, roster.html template.
+import paths
-Takes listname in PATH_INFO."""
+def roster():
+ import Mailman.Cgi.roster
+ Mailman.Cgi.roster.main()
-
-# We don't need to lock in this script, because we're never going to change
-# data.
-
-import sys
-import os, string
-import cgi
-import paths # path hacking
-import mm_utils, maillist, htmlformat, mm_cfg, mm_err
-
-try:
- sys.stderr = mm_utils.StampedLogger("error", label = 'roster',
- manual_reprime=1, nofail=0)
-except IOError:
- pass # Oh well - SOL on redirect, errors show thru.
-
-
-def main():
- doc = htmlformat.HeadlessDocument()
- form = cgi.FieldStorage()
- list = get_list()
-
- bad = ""
- # These nested conditionals constituted a cascading authentication
- # check, yielding a
- if not list.private_roster:
- # No privacy.
- bad = ""
- else:
- auth_req = ("%s subscriber list requires authentication."
- % list.real_name)
- if not form.has_key("roster-pw"):
- bad = auth_req
- else:
- pw = form['roster-pw'].value
- # Just the admin password is sufficient - check it early.
- if not list.ValidAdminPassword(pw):
- if not form.has_key('roster-email'):
- # No admin password and no user id, nogo.
- bad = auth_req
- else:
- id = form['roster-email'].value
- if list.private_roster == 1:
- # Private list - members visible.
- try:
- list.ConfirmUserPassword(id, pw)
- except (mm_err.MMBadUserError,
- mm_err.MMBadPasswordError):
- bad = ("%s subscriber authentication failed."
- % list.real_name)
- else:
- # Anonymous list - admin-only visible
- # - and we already tried admin password, above.
- bad = ("%s admin authentication failed."
- % list.real_name)
- if bad:
- doc = error_page_doc(bad)
- doc.AddItem(list.GetMailmanFooter())
- print doc.Format()
- sys.exit(0)
-
- replacements = list.GetStandardReplacements()
-
- doc.AddItem(list.ParseTags('roster.html', replacements))
- print doc.Format()
-
-def get_list():
- "Return list or bail out with error page."
-
- list_info = mm_utils.GetPathPieces(os.environ['PATH_INFO'])
- if len(list_info) != 1:
- error_page("Invalid options to CGI script.")
- sys.exit(0)
- list_name = string.lower(list_info[0])
- try:
- list = maillist.MailList(list_name, lock = 0)
- except mm_err.MMUnknownListError:
- error_page("%s: No such list.", list_name)
- sys.exit(0)
- if not list._ready:
- error_page("%s: No such list.", list_name)
- sys.exit(0)
- list.Unlock()
- return list
-
-def error_page(errmsg, *args):
- print apply(error_page_doc, (errmsg,) + args).Format()
-
-def error_page_doc(errmsg, *args):
- """Produce a simple error-message page on stdout and exit.
-
- Optional arg justreturn means just return the doc, don't print it."""
- doc = htmlformat.Document()
- doc.SetTitle("Error")
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold(errmsg % args))
- return doc
-
-if __name__ == "__main__":
- main()
+from Mailman.runcgi import *
+wrap_func(roster)
diff --git a/cgi/subscribe b/cgi/subscribe
index 38c1601bf..6fe5a7c68 100755
--- a/cgi/subscribe
+++ b/cgi/subscribe
@@ -16,180 +16,12 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-"""Process listinfo form submission, ie subscriptions or roster requests."""
+import paths
-import sys
-import os, cgi, string
-from regsub import gsub
-import paths # path hacking
-import mm_utils, maillist, mm_err, mm_message, mm_cfg, mm_pending, htmlformat
+def subscribe():
+ import Mailman.Cgi.subscribe
-try:
- sys.stderr = mm_utils.StampedLogger("error", label = 'subscribe',
- manual_reprime=1, nofail=0)
-except IOError:
- pass # Oh well - SOL on redirect, errors show thru.
+from Mailman.runcgi import *
+wrap_func(subscribe)
-doc = htmlformat.Document()
-
-path = os.environ['PATH_INFO']
-list_info = mm_utils.GetPathPieces(path)
-list_name = string.lower(list_info[0])
-
-if len(list_info) < 1:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("Invalid options to CGI script."))
- print doc.Format()
- sys.exit(0)
-
-try:
- list = maillist.MailList(list_name)
-except:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("%s: No such list." % list_name ))
- print doc.Format()
- sys.exit(0)
-
-
-if not list._ready:
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("%s: No such list." % list_name ))
- print doc.Format()
- list.Unlock()
- sys.exit(0)
-
-form = cgi.FieldStorage()
-
-error = 0
-results = ''
-
-def call_script(which, pathinfo):
- "A little bit of a hack to call one of the scripts..."
- os.environ['PATH_INFO'] = string.join(pathinfo, '/')
- file = os.path.join(mm_cfg.SCRIPTS_DIR, which)
- list.Unlock()
- execfile(file)
- sys.exit(0)
-
-#######
-# Preliminaries done, actual processing of the form input below.
-
-if (form.has_key("UserOptions")
- or (form.has_key("info") and not form.has_key("email"))):
- # Go to user options section.
- if not form.has_key("info"):
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("You must supply your email address."))
- doc.AddItem(list.GetMailmanFooter())
- print doc.Format()
- list.Unlock()
- sys.exit(0)
- addr = form['info'].value
- member = list.FindUser(addr)
- if not list.FindUser(addr):
- doc.AddItem(htmlformat.Header(2, "Error"))
- doc.AddItem(htmlformat.Bold("%s has no subscribed addr <i>%s</i>."
- % (list.real_name, addr)))
- doc.AddItem(list.GetMailmanFooter())
- print doc.Format()
- list.Unlock()
- sys.exit(0)
- call_script('options', [list._internal_name, member])
-if not form.has_key("email"):
- error = 1
- results = results + "You must supply a valid email address.<br>"
-else:
- email = form["email"].value
-if not form.has_key("pw") or not form.has_key("pw-conf"):
- error = 1
- results = results + "You must supply a valid password, and confirm it.<br>"
-else:
- pw = form["pw"].value
- pwc = form["pw-conf"].value
-
-if not error and (pw <> pwc):
- error = 1
- results = results + "Your passwords did not match.<br>"
-
-if form.has_key("digest"):
- digest = eval(form["digest"].value)
-
-if not list.digestable:
- digest = 0
-elif not list.nondigestable:
- digest = 1
-
-
-def PrintResults():
- replacements = list.GetStandardReplacements()
- replacements['<mm-results>'] = results
- output = list.ParseTags('subscribe.html', replacements)
-
- doc.AddItem(output)
- print doc.Format()
- list.Unlock()
- sys.exit(0)
-
-if error:
- PrintResults()
-
-else:
- try:
- results = results + ("Confirmation from your email address is "
- "required, to prevent anyone from covertly "
- "subscribing you. Instructions are being "
- "sent to you at %s." % email)
- if os.environ.has_key('REMOTE_HOST'):
- remote = os.environ['REMOTE_HOST']
- elif os.environ.has_key('REMOTE_ADDR'):
- remote = os.environ['REMOTE_ADDR']
- else:
- remote = "."
- if digest:
- digesting = " digest"
- else:
- digesting = ""
- cookie = mm_pending.gencookie()
- mm_pending.add2pending(email, pw, digest, cookie)
- list.SendTextToUser(subject = "%s -- confirmation of subscription -- request %d" % \
- (list.real_name, cookie),
- recipient = email,
- sender = list.GetRequestEmail(),
- text = mm_pending.VERIFY_FMT % ({"email": email,
- "listaddress": list.GetListEmail(),
- "listname": list.real_name,
- "cookie": cookie,
- "requestor": remote,
- "request_addr": list.GetRequestEmail()}),
-
- add_headers = ["Reply-to: %s"
- % list.GetRequestEmail(),
- "Errors-To: %s"
- % list.GetAdminEmail()])
- except mm_err.MMBadEmailError:
- results = results + ("Mailman won't accept the given email "
- "address as a valid address. (Does it "
- "have an @ in it???)<p>")
- except mm_err.MMListNotReady:
- results = results + ("The list is not fully functional, and "
- "can not accept subscription requests.<p>")
-#
-# deprecating this, it might be useful if we decide to
-# allow approved based subscriptions without confirmation
-#
-## except mm_err.MMNeedApproval, x:
-## results = results + ("Subscription was <em>deferred</em> "
-## "because:<br> %s<p>Your request must "
-## "be approved by the list admin. "
-## "You will receive email informing you "
-## "of the moderator's descision when they "
-## "get to your request.<p>" % x)
- except mm_err.MMHostileAddress:
- results = results + ("Your subscription is not allowed because "
- "the email address you gave is insecure.<p>")
- except mm_err.MMAlreadyAMember:
- results = results + "You are already subscribed!<p>"
-
-
-PrintResults()
-list.Unlock() \ No newline at end of file
+ \ No newline at end of file