| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
|
| |
SecurityManager: New functions MakeCookie() and CheckCookie(). These
functions work with cookies containing cookie creation and expire
time, the client's IP number, and a checksum hash of these values as
well as a secret (the lists (encrypted) admin password).
admin.py, admindb.py and private.py: isAuthenticated now uses these
new cookie functions.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
MailList.py:
Changed MailList.SetUserOption() to take a `save_list' keyword
argument (defaulting to true). When false, SetUserOption won't do
self.Save() after changing the option.
New function MailList.ApprovedAddMembers() (note plural) that takes
a list of prospective new list members (and possibly a list of
corresponding passwords), and does _all_ the necessary list changes
before saving the list configuration. Empty passwords are
substituted with randomly generated ones. Returns a dict with
{address: exception_tuple} entries -- exception_tuple is either None
or a two-element tuple containing the first exception type and value
raised when trying to add address. The exception traceback object
isn't included in the returned dict, because a) I don't think it is
very useful for the relevant exceptions, and b) using it wrongly
could cause some fuzz with Python's garbage collector -- i.e. we
would leak memory.
Changed MailList.ApprovedAddMember() to be a mere wrapper, calling
the new ApprovedAddMembers() function and reraising any exception in
the returned dict.
Also made the logic of the code doing subject prefixing a bit
clearer, and changed MailList.aside_new() so that list's config.db
files are saved with umask 007 (as they contain all list members'
passwords in clear text).
Utils.py:
New function MakeRandomPassword(length=4), used by
MailList.ApprovedAddMembers() whenever empty passwords are found.
The default random password length should possibly be made site
configurable.
Also, fixed an error in the _badchars regular expression -- the
final "," was probably meant to be inside the character set.
Cgi/admin.py:
Changed ChangeOptions() to use the new MailList.ApprovedAddMembers()
function.
|
| |
|
|
|
|
| |
unsubscribed addresses doesn't generate tracebacks. Failed
unsubscribes are listed on the top of the admin page generated after
submitting.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
address case matching. These changes require the DATA_FILE_VERSION to
be bumped, which should auto-update your config.db files. I sure hope
this works correctly! Details of changes:
MailList.GetUserSubscribedAddress(): New method. If the address is a
member, this returns the case-preserved address the user is subscribed
with. If not a member, None is returned.
MailList.GetUserCanonicalAddress(): New method. If the address is a
member, this returns the lowercased address the user is subscribed
with. If not a member, None is returned.
MailList.FindUser(): Wrote down, in a big comment, the constraints for
the dictionaries self.members, self.digest_members, self.passwords.
This wasn't always followed, but now it should be. FindUser() is now
also guaranteed to return the lowercased version of the subscribed
email address. This wasn't always the case. FindUser() also provides
a shortcut for the common case.
ApprovedAddMember(): Guarantee that passwords stored in self.passwords
are keyed off the lowercased address.
Deliverer.MailUserPassword(): Find the user's password using the
lowercased version of their address. However, be sure to use their
case-preserved address for the recipient of the password email.
Digester.SetUserDigest(): Fixed a fairly old bug where a user
switching from regular to digest membership (or vice versa) would get
their case-preserved address blown away. I don't think there's any
way to recover this information, but at least now we properly save it.
SecurityManager.ConfirmUserPassword(): Simplified address matching
stuff, since we now guarantee that FindUser() will return a lowercased
address, and that the passwords dictionary has lowercased keys.
FindUser() will return None if the address isn't found, and it also
has a built-in shortcut so that the more expensive
FindMatchingAddresses() isn't called in the common case. I eliminated
the case-insensitive password comparision that Ken rightly questioned
in his comment.
admin.py: In the list of members, display a member's case-preserved
address instead of their lowercased address. Also, obscure the URL in
the hyperlink (probably not terribly necessary).
handle_opts.py: When the password can't be found (when emailing it),
put the address we tried to find in the result message. Makes for
better debugging.
options.py: Use a better mechanism for finding if the member has a
case-preserved address different from their lowercased address.
|
| |
|
|
|
|
| |
made, we now change the `norcv' option to be `notmetoo'. This is
still backwards, but changing the sense of this option is to much work
right now. `norcv' is accepted as an alias for `notmetoo'.
|
| | |
|
| |
|
|
|
|
|
|
| |
user's address, which jumps you to their member info page.
Second, reorder the items in the table so that digest comes just
before plain. Didn't make sense to separate these two digest related
items.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
bottom" => "button at the bottom". Sounds somehow obscene the other
way, but nonetheless we'd like it to make sense.
While i was here i did a few *more* trivial things...
Using "not metoo" instead of "norcv" for member's status column
headings (and legend), to disambiguate from "nomail"! (I think i
recall "metoo" from things like /bin/mail, in any case, it's a lot
more descriptive of the intention.)
While i'm here i centered all the checkbuttons, which i think looks a
lot tidier.
|
| |
|
|
|
| |
changed the message so it only says it's at the bottom of the page
when it really is.
|
| |
|
|
| |
members table [and testing the emailing of this checkin message, as well].
|
| |
|
|
| |
`general' category page. The others are just too noisy.
|
| | |
|
| |
|
|
|
|
|
|
|
|
| |
calling CGI script was invoked with.
Uses (non-standard, but convenient) environment variable REQUEST_URI
when available, otherwise SCRIPT_NAME and PATH_INFO (which are part
of the CGI/1.1 spec) if available, or simply returns optional
argument `fallback' (which defaults to None).
Cgi/admin.py, Cgi/admindb.py: Use it when generating admin
authentication page.
|
| |
|
|
| |
extension needs to be added to script path.
|
| |
|
|
|
| |
catching blank lines, so we can (mostly) get rid of the special
treatment here.
|
| |
|
|
|
|
|
|
| |
EmailAddressError, and clean up logic.
ChangeOptions(): In the `subscribees' section, add a call to
ValidateEmail() so that invalid email addresses can't be added in the
Membership Management text window.
|
| |
|
|
| |
be an empty string.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
disabled. The problem: because cookies are disabled, the admin has to
authenticate for each access. We can't change this because otherwise
option values could leak.
So when the admin fills in the password and clicks `let me in...', the
form gets POSTed, and even those the variable to get details on is
given in the form's ACTION, cgi.py ignores any QUERY_STRING on a
POST. Maybe cgi.py should be fixed? In the meantime, we just watch
for the FieldStorage having a `request_login' field and a QUERY_STRING
environment variable. In that case, we manually parse out the query
string and use its value if available.
|
| |
|
|
|
|
| |
make it much more readable. First, use bare checkboxes and column
headers for what used to be the checkbox labels. Put a border around
the table. Add a legend for what the column headers mean.
|
| |
|
|
|
| |
the success notification specifies the address instead of any other
goo.
|
| |
|
|
| |
line in mass subscribe dialog. The old way didn't really work.
|
| |
|
|
| |
converter
|
| | |
|
| |
|
|
| |
int() -- it's safer.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
work like unix mail: username portions of addresses are
case-preserved for delivery only. All other address comparisons are
lowercase.
up'd data version in Defaults to 13
** MailList.py: added an __AddMember method that takes an address and
whether or not it is a digest address as args and populates the member
dictionary like this:
if string.lower(addr) == LCDomain(addr):
member_dict[addr] = 0
else:
member_dictp[string.lower(addr)] == LCDomain(addr)
added .GetDeliveryMembers() and .GetDigestDeliveryMembers() methods
for use by posting and digest delivery mechanisms.
changed a nested def portion in Post to use an explicit loop.
**Digester.py: uses .GetDigestDeliveryMembers instead of
.GetDigestMembers().
**Utils.py: address comparisons are lc.
**versions.py: populate the member dicts according to the above
formula.
**Cgi/admin.py: fixed a bug introduced from the first change to using
member dictionaries: all members were showing up as digest members
on the admin membership page. changed a dict.get to dict.has_key to
fix this.
NOTE: this code is tested only insofar as I posted and poked around on
the cgi's a bit, and let lists do the versions code. These changes
should be tested more, but I *have* to go now and wanted to check them
in before someone made it difficult to do so by changing stuff
tomarrow, cause i'm gone all day tomarrow.
scott
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
fix and one addition. Sorry, i realized that too late.
This change adds another list conifg variable "admin_notify_mchanges",
which is a boolean 0 or 1 and specifies whether or not the list admin
gets notifications of subscriptions and unsubscriptions.
The functions MailList.DeleteMember and MailList.ApprovedAddMember
trigger the delivery if it is turned on for the list or passed in as
an optional argument. This way, it is the duty of programs/code that
do mass subscriptions/unsubscriptions where this notification may not
be appropriate to specify that in the call to .DeleteMember or
.ApprovedAddMember.
There are 2 new templates, adminsubscribeack.txt and
adminunsubscribeack.txt which are used in sending these
notifications.
Defaults.py.in has a variable "DEFAULT_ADMIN_NOTIFY_MCHANGES" which is
set to 0 so that old lists will act the same by default, and the data
version is up'ed to 12. versions.py sets the variable if it's not
already there for a list. The config info for the admin cgi program
for this new variable is set right after the variable for immediate
notifications.
The second change is a fix where ApprovedAddMember was calling a
"self.Save()", which made mass subscribe situiations really far too
slow. I removed the .Save() from there and added it to the more outer
level code in the following places:
bin/convert_list
Mailman/ListAdmin.py
Mailman/MailCommandHandler.py
Mailman/Cgi/admin.py
Note that since AddMember can trigger a call to ApprovedAddMember, all
the places where AddMember is called needed a .Save() added as well.
I need to add a call to .Save() for Mailman/Cgi/subscribe.py as well
and will do that in a moment.
scott
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
tabbing between entry fields goes in the right sequence. (In the
process i separated out the formatting for the Submit button, and i'm
wondering whether it makes sense to put a copy of it above the table,
as well as below - it can be handy to not have to go to the end of the
page to submit. Unfortunately, it looks ugly hanging out up top!)
As ever, wrapped a bunch of long lines.
Trimmed some odd whitespace (extending beyond margin) at the end of a
line.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
dicts instead of lists, which optimizes Utils.FindMatchingAddresses
and general membership management, especially for large lists.
MailList.py now supplies .GetMembers() and .GetDigestMembers() to
supply the data in list form to anything that needs it that way.
An new install showed this worked fine with some cursory testing of
the cgi's and interactive poking around.
A detailed listing of the changes follows:
Mailman/Defaults.py.in: change data version to 11
Mailman/Digester.py: initvars now instantiates digest_members as {}
instead of []
lines 113-114 and 121-122 now use del
This change implements storing list members and digest members as
dicts instead of lists, which optimizes Utils.FindMatchingAddresses
and general membership management, especially for large lists.
MailList.py now supplies .GetMembers() and .GetDigestMembers() to
supply the data in list form to anything that needs it that way.
Though INSTALL shows up on the changed files section, a diff a few
seconds ago didn't show any differences in that file, so I hope nobody
changed it in the interim.
An new install showed this worked fine with some cursory testing of
the cgi's and interactive poking around.
A detailed listing of the changes follows:
Mailman/Defaults.py.in: change data version to 11
Mailman/Digester.py: initvars now instantiates digest_members as {}
instead of []
lines 113-114 and 121-122 now use del
list.[digest_]member instead of
list.[digest_]members.remove
when figuring who to actually send digests to,
use list.GetDigestMembers() instead of
list.digest_members.
Mailman/HTMLFormatter: now uses list.Get[Digest]Members to get
subscribers, and length of digested subscribers
and regular members
MailCommandHandler, SecurityManager,Cgi/handle_opts, Cgi/options: all
simple replacements of list.[digest_]members with
list.Get[Digest]Members().
Mailman/Cgi/admin.py: mostly simple replacements of
list.[digest_]members with the Get..() methods, however, the
membership management section now works much quicker and changes
digest->nodigest subscriptions via dictionary manipulations.
Mailman/versions.py: updates lists to use dicts and changed
list.[digest_]members to use the list.Get[Digest]Members() methods.
Mailman/Utils.py: added a function "GetPossibleMatchingAddresses"
which when fed an address, returns the list of addresses that "smart"
address matching would match.
changed FindMatchingAddresses(name, list) to use a new signature:
FindMatchingAddresses(name, *dicts), where dicts is a list of
dictionaries keyed by addresses. Just realized that this would better
be FindMatchingAddresses(name, dict, *dicts) so that it enforces
atleast 2 args... I'll make that change in a sec.
All uses of FindMatchingAddresses have been changed to fit the new
arguments.
scott
----:**-F1 cvs30458aaa 1:12PM 0.98 Mail (Text Fill)--L59--32%-------------------------------------------
?
|
| |
|
|
|
| |
2 spots changed: lines 220 and 401
scott
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
variable (admin_member_chunksize). this is not yet settable by means
of cgi, but you can set it at an interactive python session. This is
a start on making the membership management part of the admin cgi
scalable for really big lists.
details:
* up'd DATA_FILE_VERSION in Mailman/Defaults.py.in
* replaced ADMIN_MEMBER_CHUNKSIZE with DEFAULT_ADMIN_MEMBER_CHUNKSIZE in
Mailman/Defaults.py.in.
* added a list variable assignment in Mailman.MailList.InitVars
* added code to add the admin_member_chunksize attribute to a list
when versions change in Mailman/versions.py
* made admin.py format members according to
list.admin_member_chunksize instead of mm_cfg.ADMIN_MEMBER_CHUNKSIZE
scott
|
| |
|
|
| |
scott
|
| |
|
|
|
|
| |
listowners from unsubscribing digest members. I don't know how it got
back in the code!
scott
|
| |
|
|
| |
scott
|
| |
|
|
|
| |
Fixed a typo that prevented digestified users from unsubscribing via
the web.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
was in (which was largely my fault from before).
Before:
1) web_subscribe_requires_confirmation was showing in the
admin cgi, but not working.
2) all subscribes that required admin approval were going
through the confirmation process.
3) the code implementing the confirmation process was
distributed between the subscribe cgi and
MailCommandHandler, duplicated in places and disrupting
the previous interface to list.AddMember.
4) the open_subscribe variable was confusing because
it didn't pay any attention to confirmations.
Now, things are organized a little differently, but in a much cleaner
way. there is one variable that deals with subscription policy, called
"subscribe_policy". It's setting determines what happens with both
the web based and the mail based subscriptions. there are 4 options:
0 - open subscribe policy
1 - confirmation required
2 - admin approval required
3 - confirmation and then admin approval required
there is a site configuration variable in Defaults.py called
ALLOW_OPEN_SUBSCRIBE, which determines whether or not an open
subscribe policy is an option. If it's not, the admin cgi interface
does not present it as an option.
I have restored a slightly modified version of the
prior-to-confirmations interface for list.AddMember, where all you
have to code is:
try:
list.AddMember(email, digest, password)
except Errors.MMBadEmail:
except Errors.MMAlreadySubscribed:
[ ... all those other good things it used to check ...]
except Errors.MMSubscribeNeedsConfirmation:
# the confirmation has already been sent.
# so just report accordingly to whatever the ap is.
In addition, I have moved the code for processing a confirmation
request to MailList.py so that it can be used in both a confirmation
cgi (which does not yet exist, but will) and the mailcmd script.
it's interface is:
try:
list.ProcessConfirmation(cookie)
except Errors.MMBadConfirmation:
# the cookie doesn't correspond to anything
except Errors.MMNeedApproval:
# the list is set to approve+confirm subscribe_policy.
A listing of the changes to the files follows:
Mailman/Defaults.in: added ALLOW_OPEN_SUBSCRIBE,DEFAULT_SUBSCRIBE_POLICY
deleted DEFAULT_OPEN_SUBSCRIBE, changed
DATA_FILE_VERSION to 5
Mailman/Errors.py: added MMBadConfirmation and
MMSubscribeNeedsConfirmation
Mailman/MailCommandHandler.py: moved the confirmation code to
MailList.py and use the new (old)
list.AddMember interface
MailMan/MailList.py: added .ProcessConfirmation(cookie), changed
AddMember to fit new (old) interface.
deleted config info for open_subscribe
and replaced with config info for
subscribe_policy that acts according to
mm_cfg.ALLOW_OPEN_SUBSCRIBE. Also made
list.ApprovedAddMember's "noack"
argument just "ack" for simplicities
sake and made it default to None
instead of 0 so that if the ack
variable isn't passed, it sets it to
the value of the lists
.send_welcome_msg setting.
Mailman/versions.py: added handling for new data file format,
replacing open_subscribe with a reasonable value
for subscribe_policy based on a combination of
what open_subscribe is and what
mm_cfg.ALLOW_OPEN_SUBSCRIBE is set to.
Mailman/Cgi/admin.py: made the cgi handle the output and processing of
subscribe_policy based on the setting of
mm_cfg.ALLOW_OPEN_SUBSCRIBE.
removed erroneous processing of whether or not
to send an ack with mass subscription based on
new interface to list.ApprovedAddMember (this
processing is to be replaced with a good idea
from john -- making mass subscribe have it's own
option of whether or not to send welcome
messages).
Mailman/Cgi/subscribe.py: made backgrounds white, and made it use the
MailList.AddMember interface described
above.
Mailman/Makefile.in: looks like this part of that distclean patch from
NAGY didn't make it in yet (rm'ing mm_cfg.py as well
as Defaults.py)
scott
|
| |
|
|
| |
scott
|
| |
|
|
|
| |
welcome message as per the list config.
scott
|
| |
|
|
|
|
| |
error to be raised with MSIE on a MAC. I have simplified the
encodeing to simply be `hash(list_name)`.
scott
|
| |
|
|
|
|
|
| |
broken for lists that didn't use the default /mailman ScriptAlias.
admin.py now uses list.GetAbsoluteScriptURL('admin'), which should
apply to virtual hosts and other odd configurations
scott
|
| |
|
|
| |
doesn't exist (as in older versions of Apache).
|
| |
|
|
| |
driver.
|
| |
|
|
|
|
|
|
|
|
|
| |
the Mailman package (using the semi-bogus, but quickly implemented
from ... import style).
Moved the TQS LOGIN_PAGE to a templates file
Sundry "maillist" -> "mailing list"
Fix crypt imports
|
| | |
|
| |
|
|
|
|
|
|
|
| |
guess about the transient errors (ie, some people get them, some
people do not) is that sometimes the base64 encoding can cause \n's to
get in the string, which the mime stuff will treat as a newline. So I
replace \n w/ @ before putting it in the cookie, and do the reverse
before checking the cookie. Hopefully we won't hear about this
problem again.
|
|
|
handle logging to an error file, and no longer import paths. Also,
any checks for __main__ have been removed.
|