summaryrefslogtreecommitdiff
path: root/modules/Cgi/admin.py
diff options
context:
space:
mode:
authorbwarsaw1998-06-19 19:33:41 +0000
committerbwarsaw1998-06-19 19:33:41 +0000
commit9a7f36b1a8820a8abf8046755dd1d0ad5a201d0e (patch)
treeb4b51ff26957d8b402cad1e84df7f745d3245cf0 /modules/Cgi/admin.py
parent99f721f65906e4f2d1036da3a886426aa0ec5aea (diff)
downloadmailman-9a7f36b1a8820a8abf8046755dd1d0ad5a201d0e.tar.gz
mailman-9a7f36b1a8820a8abf8046755dd1d0ad5a201d0e.tar.zst
mailman-9a7f36b1a8820a8abf8046755dd1d0ad5a201d0e.zip
Diffstat (limited to 'modules/Cgi/admin.py')
-rwxr-xr-xmodules/Cgi/admin.py832
1 files changed, 0 insertions, 832 deletions
diff --git a/modules/Cgi/admin.py b/modules/Cgi/admin.py
deleted file mode 100755
index 423f14189..000000000
--- a/modules/Cgi/admin.py
+++ /dev/null
@@ -1,832 +0,0 @@
-#! /usr/bin/env python
-#
-# Copyright (C) 1998 by the Free Software Foundation, Inc.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# 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."""
-
-__version__ = "$Revision: 742 $"
-
-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 *
-
-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.replace(token, "\n", "@")
- 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"):
- inp = base64.decodestring(string.replace(
- c[list_name + "-admin"].value, "@", "\n"))
- check = md5.new(SECRET+list_name+SECRET).digest()
- 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])
-
- try:
- lst = maillist.MailList(list_name)
- except mm_err.MMUnknownListError:
- lst = None
- 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:
- if lst:
- 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]
-