| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
main(): Set up a signal handler to catch SIGTERM, and unlock the
mailing list when this happens. This has the side effect of aborting
any changes to the MailList object that this web hit may have made.
This is necessary due to semantics of Apache's mod_cgi: when the
browser closes the socket, eventually Apache receives a SIGPIPE (on
output to the closed socket). This causes Apache to SIGTERM the cgi
process, wait three seconds, then SIGKILL it. We want to be able to
clean up the locks, so the best we can do is try to unlock the list on
the SIGTERM. Once we get SIGKILLed, there's nothing we can do.
This change also moves the Save() call into the try: block so that the
finally: block /only/ unlocks the list. Thus, the list gets unlocked
in most situations. There are still race conditions where 1) the
config.db file could be corrupted; 2) list locks could still be
unreleased. Given the semantics of signals in Python, the interaction
of Apache's mod_cgi, and other factors, this is the best we can do,
and it should be better than the old situation.
XXX What do other web servers or cgi execution environments do?
|
| |
|
|
|
|
|
|
|
|
| |
"Regular-member (non-digest) Options" -> "Regular delivery
(non-digest) Options"
"Digest-member Options" -> "Digest Options"
change_options(): Support for pseudo-variables _new_volume and
_send_digest_now.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
redesign of the admin page. From the NEWS file:
- Redesign of the membership management page. The page is now
split into three subcategories (Membership List, Mass
Subscription, and Mass Removal). The Membership List
subcategory now supports searching for member addresses by
regular expression, and if necessary, it groups member addresses
first alphabetically, and then by chunks.
Mass Subscription and Mass Removal now alternatively support
file upload, with one address per line.
|
| |
|
|
|
| |
(hostname) and fix the mailto:mailman_owner link to do interpolation
explicitly, since Link() does not do that.
|
| | |
|
| |
|
|
|
|
|
|
|
|
| |
membership_options(): We have to urllib.quote() the value attribute on
the hidden input tag, otherwise it is impossible to unsubscribe
addresses with quotes in them (which are valid RFC822 addresses).
change_options(): Be sure to urllib.unquote() the user value field,
undoing the effects of membership_options() and allowing
unsubscription of addresses with quotes in them.
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
CATEGORIES: Move back to module scope, and mark as translatable, but
fake out the translator so the strings don't get translated at import
time (they will be passed through _() later).
At global scope, set the language to the server's default, at least
until we know which list the request is being made on.
main(): Significant cleanups and code re-org. Don't lock the list
until absolutely necessary. Use the new preferred route for setting
the language (don't use os.environ['LANG'], instead use
i18n.set_language()). Move as much out of the locking try/finally as
possible, including the checks for authorization, logout, and
varhelp. Also, set the language on the document (so the resulting
html has the proper charset).
FormatAdminOverview() -> admin_overview()
admin_overview(): Code re-org. Set the document's language to the
server's default (since the overview isn't list specific). Don't set
os.environ['LANG'] anymore.
FormatOptionHelp() -> option_help()
option_help(): Similar changes as above. Also, allow
get_item_characteristics() to do the unpacking of the item records.
FormatConfiguration() -> show_results()
show_results(): Be sure to send the category values through _() for
translating. Mark a few more strings as translatable.
FormatOptionsSection() -> show_variables()
ColHeader() -> column_header()
AddOptionsTableItem() -> add_options_table_item()
GetItemCharacteristics() -> get_item_characteristics()
GetItemGuiValue() -> get_item_gui_value()
GetItemGuiDescr() -> get_item_gui_description()
FormatMembershipOptions() -> membership_options()
FormatSubmit() -> submit_button()
GetValidValue() -> get_valid_value()
ChangeOptions() -> change_options()
AddErrorMessage() -> add_error_message()
change_options(): Watch specifically for changes to
`preferred_language' attribute, and do the appropriate
i18n.set_language() call if found.
|
| |
|
|
|
|
|
|
| |
Drop the use of the crypt stuff in favor of sha.
Some i18n updates.
A few other Python 2.0 features used where appropriate.
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
| |
bomb with tracebacks if PATH_INFO environment variable wasn't defined.
Fixed this by making them all use Utils.GetPathPieces() and "doing
something sensible" when that returned a false value.
Also, edithtml is now hidden behind a login screen, so there's no need
to enter the list password to edit the html. You can't even get to
the list of files to edit unless you've admin authenticated. Closes
SF bug #114091, Jitterbug PR# 24.
|
| |
|
|
| |
#101554.
|
| |
|
|
| |
list's archives.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
cgi.FieldStorage constructor keep_blank_values=1. Without this, it
isn't possible to set a text field to the empty string. However, this
breaks admin password changing on the General page because the test
was for key presence. We now also check that the key's value is
non-empty (meaning empty admin passwords are no longer allowed).
Also, when changing the admin password, make sure that the new
password isn't empty, and string.strip() the new and confirm
password.
Finally, use AddErrorMessage() more consistently.
AddErrorMessage(): make the tag (i.e. "Warning: ") settable via
arguments.
|
| |
|
|
|
| |
keep_blank_values to 1 in order to be able to, e.g. set the msg_footer
to the empty string!
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
the usability of the web interface, closing SF bug #114126, Jitterbug
PR#148. Specifically,
- There is now a submit button on the details page, and you can use
that page to change options. This should work better now that
details by default don't pop open a new window, however this is a
warning at the bottom of the page about synchronization issues.
- Details pages now include the standard footer too.
- Volatile config variables (e.g. _mass_catchup) have a note saying
that setting the value performs an action, but doesn't change
permanent state.
ChangeOptions(): The above change uncovered what I believe is a bug,
where if the form data is missing a property found on the category's
options, it would be skipped /unless/ the type of the property were
Text, String, or EmailList. I don't understand why that special case
was there, so I changed this logic to always skip the property if it
isn't found in the form data. Otherwise submitting from a details
page could cause some confusing behavior.
GetConfigOptions(): I don't think the caching of mlist.GetConfigInfo()
is worth it. The lookups should be plenty fast.
|
| |
|
|
|
|
|
|
| |
mode for the user. Although we have to kludge in the `force' flag,
this is much better because it handles placing digest->nondigest users
on the `one_last_digest' list.
Fixes SF bug #114089 / Jitterbug PR# 166.
|
| |
|
|
|
|
|
|
|
|
|
| |
rest of the error message in black, italics. More readable, and makes
the warning stand out better.
main(): Improve the digestable/nondigestable sanity checks to use the
better error message output format, and to perform the tests after the
options have been changed (otherwise the warnings might not be still
applicable). Also added a warning when a list has disabled digest
deliver and non-digest delivery!
|
| |
|
|
|
| |
calling mlist.CheckValues() after the options have been changed (but
before the values are printed).
|
| |
|
|
| |
Dan.
|
| |
|
|
|
|
|
|
|
| |
to SF Bug #110753. Specifically,
FormatAdminOverview(), FormatConfiguration(), FormatOptionHelp(),
GetItemGuiDescr(): Use Utils.ScriptURL() instead of GetNestingLevel(),
and GetScriptURL() instead of GetRelativeScriptURL(). Also fix usage
of GetOptionsURL() for new interface.
|
| | |
|
| |
|
|
|
|
|
|
|
| |
main(): Use the new Mailman.Cgi.Auth module for performing the
authentication stuff. Also, added a `Logout' link in the "Other
Adminstrative Activities" section. This is a magic category that ends
up calling ZapCookie() and re-displaying the login page.
FormatConfiguration(): Added a link to the Logout category.
|
| |
|
|
|
|
| |
handles all the tasks of authentication. It returns 1 if auth
succeeded, 0 if it failed. On failure it also prints the admin login
page, so main() should just exit.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I.e. these are selections that can be presented in an admin page, but
don't directly affect the value of a saved list attribute. This is
used for a "Mass Catchup" button in the gateway category. Volatile
property convention is that the name starts with an underscore.
Specifically,
GetItemGuiValue(): For Radios and Toggles, only do a getattr() of
varname if the name does not start with an underscore. Otherwise
default the checked value to 0. This is bogus because it would be
better to take the default value from the property description, but
that's too much of an API change for now.
ChangeOptions(): If the property name starts with an underscore, do
something different. This has to check for specific volatile
parameters, of which the only one currently is `_mass_catchup'. If
that's the property and the value is true, then set usenet_watermark
to None, which is the signal to gate_news to do a mass catchup
(i.e. set the watermark to the last article currently on the server).
Note that the GatewayManager category used to always do a mass catchup
when gateway_to_mail was toggled. This isn't always the right thing,
so this change allows the admin to explicitly do a catch up.
|
| |
|
|
| |
lines in the mass subscribe field.
|
| |
|
|
| |
syslog() interface.
|
| |
|
|
|
|
|
|
|
| |
- The page title now contains the category label
- Slight changes to the H2 header at the top of the page
- I didn't like the => <= indicators, so these are gone, and the
currently selected page is rendnered in <em></em> tags.
|
| |
|
|
| |
to access the admin interface for a non-existent list.
|
| |
|
|
| |
warning on every page, put it on the admin login page.
|
| |
|
|
|
|
|
|
|
|
|
| |
take effect unless your browser supports cookies.
ChangeOptions(): Is called from within a try...finally in main(), with
the finally clause doing a (unconditional) mlist.Save(). Thus,
there's no need for ChangeOptions() to _also_ do a Save() -- meaning
the `dirty' housekeeping variable is superfluous, and therefore has
been removed.
All calls to mlist.SetUserOption() are now made with keyword
argument "save_list=0".
|
| |
|
|
|
|
| |
direction), mlist.usenet_watermark is set to None. This tells
gate_news to mass catchup the newsgroup, which avoids list flooding
when gating from Usenet is turned back on.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
mailing list. In all cases, catch the base exception class
MMListError, and output HTML indicating the specified list doesn't
exist. A more detail message gets printed to logs/error (the str() of
the actual exception details).
Also:
admin.py - Don't catch MMBadConfigError around
mlist.parse_matching_header_opt() since this method doesn't ever
raise that exception. Actually, that exception isn't raised
anywhere in Mailman, so it's been removed.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
AddOptionsTableItem(): nodetails => detailsp (with bit flip on default
value).
FormatOptionHelp(): All options now have details. If a config
attribute doesn't have an explicit details string, then the normal
description is used as the details. This simplifies the logic a bit
here and makes for a more consistent UI. Also, always include a link
back to the category options page (on the quest for no dead ends!)
GetItemGuiDescr(): Always include the "(Details)" link because now
they /all/ have details.
|
| |
|
|
| |
the top of this function.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`multipart/form-data' if the category is autoreply (so far the only
admin category with file uploads).
GetItemGuiValue(): added support for the FileUpload widget. This sets
up both the TextArea and FileUpload widget, with some explanatory text
in between.
GetItemGuiDescr(): I've been persuaded. Don't pop up help text in
a separate window by default.
ChangeOptions(): Kludge in support for file upload widgets. If
there's a config variable called 'something_upload' then it's value is
used in preference to the 'something' config variable yanked off the
CGI information.
|
| | |
|
| |
|
|
| |
`obscure'
|
| |
|
|
| |
value here doesn't do anything.
|
| |
|
|
|
| |
by anything other than letter case. This is a QND (quick 'n' dirty)
security patch when using an external archiver.
|
| | |
|
| | |
|
| |
|
|
|
|
|
| |
programming constructs. Could still use a lot more work.
main(): Most importantly, in the finally clause make sure the mailing
list is both Saved and Unlock()d.
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* New method WebAuthenticate(). Takes up to three keyword arguments:
user-address, password and cookie-suffix. If password is supplied
(and authenticates OK), issue a cookie -- otherwise try to do
authentication based on cookies.
* MakeCookie(): Changed to actually return a finished Cookie object.
Takes one (non-optional) argument; the created cookie's name.
Fixed bug in setting of cookie's path.
* CheckCookie(): Now takes cookie's name as single argument, and can
raise various MMAuthenticationErrors if that cookie doesn't
authenticate OK.
admin.py: Do explicit re-authentication when changing list admin
password.
admin.py, admindb.py and private.py: Removed isAuthenticated()
function -- use MailList.WebAuthenticate() instead. This removed
the need to import Cookie, so now we don't.
|