diff options
Diffstat (limited to 'src')
27 files changed, 215 insertions, 145 deletions
diff --git a/src/mailman/app/lifecycle.py b/src/mailman/app/lifecycle.py index 46b0e9709..e82bc1e28 100644 --- a/src/mailman/app/lifecycle.py +++ b/src/mailman/app/lifecycle.py @@ -38,6 +38,7 @@ from mailman.interfaces.domain import ( BadDomainSpecificationError, IDomainManager) from mailman.interfaces.listmanager import IListManager from mailman.interfaces.member import MemberRole +from mailman.interfaces.usermanager import IUserManager from mailman.utilities.modules import call_name @@ -61,13 +62,13 @@ def create_list(fqdn_listname, owners=None): call_name(config.mta.incoming).create(mlist) # Create any owners that don't yet exist, and subscribe all addresses as # owners of the mailing list. - usermgr = config.db.user_manager + user_manager = getUtility(IUserManager) for owner_address in owners: - addr = usermgr.get_address(owner_address) + addr = user_manager.get_address(owner_address) if addr is None: # XXX Make this use an IRegistrar instead, but that requires # sussing out the IDomain stuff. For now, fake it. - user = usermgr.create_user(owner_address) + user = user_manager.create_user(owner_address) addr = list(user.addresses)[0] addr.subscribe(mlist, MemberRole.owner) return mlist diff --git a/src/mailman/app/membership.py b/src/mailman/app/membership.py index 411083694..5f58b66d5 100644 --- a/src/mailman/app/membership.py +++ b/src/mailman/app/membership.py @@ -27,15 +27,16 @@ __all__ = [ from email.utils import formataddr +from zope.component import getUtility from mailman import Utils from mailman import i18n from mailman.app.notifications import send_goodbye_message -from mailman.config import config from mailman.core import errors from mailman.email.message import OwnerNotification from mailman.email.validate import validate from mailman.interfaces.member import AlreadySubscribedError, MemberRole +from mailman.interfaces.usermanager import IUserManager _ = i18n._ @@ -72,21 +73,22 @@ def add_member(mlist, address, realname, password, delivery_mode, language): raise errors.MembershipIsBanned(pattern) # Do the actual addition. First, see if there's already a user linked # with the given address. - user = config.db.user_manager.get_user(address) + user_manager = getUtility(IUserManager) + user = user_manager.get_user(address) if user is None: # A user linked to this address does not yet exist. Is the address # itself known but just not linked to a user? - address_obj = config.db.user_manager.get_address(address) + address_obj = user_manager.get_address(address) if address_obj is None: # Nope, we don't even know about this address, so create both the # user and address now. - user = config.db.user_manager.create_user(address, realname) + user = user_manager.create_user(address, realname) # Do it this way so we don't have to flush the previous change. address_obj = list(user.addresses)[0] else: # The address object exists, but it's not linked to a user. # Create the user and link it now. - user = config.db.user_manager.create_user() + user = user_manager.create_user() user.real_name = (realname if realname else address_obj.real_name) user.link(address_obj) # Since created the user, then the member, and set preferences on the @@ -138,7 +140,7 @@ def delete_member(mlist, address, admin_notif=None, userack=None): send_goodbye_message(mlist, address, language) # ...and to the administrator. if admin_notif: - user = config.db.user_manager.get_user(address) + user = getUtility(IUserManager).get_user(address) realname = user.real_name subject = _('$mlist.real_name unsubscription notification') text = Utils.maketext( diff --git a/src/mailman/app/registrar.py b/src/mailman/app/registrar.py index 1d84c7e52..e623fa031 100644 --- a/src/mailman/app/registrar.py +++ b/src/mailman/app/registrar.py @@ -40,6 +40,7 @@ from mailman.interfaces.listmanager import IListManager from mailman.interfaces.member import MemberRole from mailman.interfaces.pending import IPendable from mailman.interfaces.registrar import IRegistrar +from mailman.interfaces.usermanager import IUserManager @@ -105,17 +106,17 @@ class Registrar: # We are going to end up with an IAddress for the verified address # and an IUser linked to this IAddress. See if any of these objects # currently exist in our database. - usermgr = config.db.user_manager - addr = (usermgr.get_address(address) + user_manager = getUtility(IUserManager) + addr = (user_manager.get_address(address) if address is not missing else None) - user = (usermgr.get_user(address) + user = (user_manager.get_user(address) if address is not missing else None) # If there is neither an address nor a user matching the confirmed # record, then create the user, which will in turn create the address # and link the two together if addr is None: assert user is None, 'How did we get a user but not an address?' - user = usermgr.create_user(address, real_name) + user = user_manager.create_user(address, real_name) # Because the database changes haven't been flushed, we can't use # IUserManager.get_address() to find the IAddress just created # under the hood. Instead, iterate through the IUser's addresses, @@ -126,7 +127,7 @@ class Registrar: else: raise AssertionError('Could not find expected IAddress') elif user is None: - user = usermgr.create_user() + user = user_manager.create_user() user.real_name = real_name user.link(addr) else: diff --git a/src/mailman/bin/list_members.py b/src/mailman/bin/list_members.py index d22b2593b..e715bfdcb 100644 --- a/src/mailman/bin/list_members.py +++ b/src/mailman/bin/list_members.py @@ -20,12 +20,12 @@ import sys from email.Utils import formataddr from zope.component import getUtility -from mailman.config import config from mailman.core import errors from mailman.email.validate import is_valid from mailman.i18n import _ from mailman.interfaces.listmanager import IListManager from mailman.interfaces.members import DeliveryStatus +from mailman.interfaces.usermanager import IUserManager from mailman.options import SingleMailingListOptions @@ -153,17 +153,18 @@ def main(): dmembers = set(mlist.digest_members.members) fullnames = options.options.fullnames + user_manager = getUtility(IUserManager) if options.options.invalid: all = sorted(member.address.address for member in rmembers + dmembers) for address in all: - user = config.db.user_manager.get_user(address) + user = user_manager.get_user(address) name = (user.real_name if fullnames and user else u'') if options.options.invalid and not is_valid(address): print >> fp, formataddr((safe(name), address)) return if options.options.regular: for address in sorted(member.address.address for member in rmembers): - user = config.db.user_manager.get_user(address) + user = user_manager.get_user(address) name = (user.real_name if fullnames and user else u'') # Filter out nomails if (options.options.nomail and @@ -172,7 +173,7 @@ def main(): print >> fp, formataddr((safe(name), address)) if options.options.digest: for address in sorted(member.address.address for member in dmembers): - user = config.db.user_manager.get_user(address) + user = user_manager.get_user(address) name = (user.real_name if fullnames and user else u'') # Filter out nomails if (options.options.nomail and diff --git a/src/mailman/bin/set_members.py b/src/mailman/bin/set_members.py index cdd11c56f..001e5e1d3 100644 --- a/src/mailman/bin/set_members.py +++ b/src/mailman/bin/set_members.py @@ -18,6 +18,8 @@ import csv import optparse +from zope.component import getUtility + from mailman import Message from mailman import Utils from mailman import i18n @@ -27,7 +29,8 @@ from mailman.app.notifications import ( send_admin_subscription_notice, send_welcome_message) from mailman.configuration import config from mailman.initialize import initialize -from mailman.interfaces import DeliveryMode +from mailman.interfaces.members import DeliveryMode +from mailman.interfaces.usermanager import IUserManager from mailman.version import MAILMAN_VERSION @@ -165,7 +168,7 @@ def main(): real_name, delivery_mode = member_data[address] member = mlist.members.get_member(address) member.preferences.delivery_mode = delivery_mode - user = config.db.user_manager.get_user(address) + user = getUtility(IUserManager).get_user(address) user.real_name = real_name for address in add_members: print _('adding address: $address') diff --git a/src/mailman/chains/hold.py b/src/mailman/chains/hold.py index 5f98bceea..943e4455f 100644 --- a/src/mailman/chains/hold.py +++ b/src/mailman/chains/hold.py @@ -30,6 +30,7 @@ import logging from email.mime.message import MIMEMessage from email.mime.text import MIMEText from email.utils import formatdate, make_msgid +from zope.component import getUtility from zope.interface import implements from mailman import i18n @@ -41,6 +42,7 @@ from mailman.config import config from mailman.email.message import UserNotification from mailman.interfaces.autorespond import IAutoResponseSet, Response from mailman.interfaces.pending import IPendable +from mailman.interfaces.usermanager import IUserManager log = logging.getLogger('mailman.vette') @@ -76,9 +78,10 @@ def autorespond_to_sender(mlist, sender, lang=None): # Unlimited. return True # Get an IAddress from an email address. - address = config.db.user_manager.get_address(sender) + user_manager = getUtility(IUserManager) + address = user_manager.get_address(sender) if address is None: - address = config.db.user_manager.create_address(sender) + address = user_manager.create_address(sender) response_set = IAutoResponseSet(mlist) todays_count = response_set.todays_count(address, Response.hold) if todays_count < max_autoresponses_per_day: diff --git a/src/mailman/commands/docs/join.txt b/src/mailman/commands/docs/join.txt index 8e4922151..695750e01 100644 --- a/src/mailman/commands/docs/join.txt +++ b/src/mailman/commands/docs/join.txt @@ -78,7 +78,9 @@ When the message has a From field, that address will be subscribed. Anne is not yet a member because she must confirm her subscription request first. - >>> print config.db.user_manager.get_user('anne@example.com') + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> print getUtility(IUserManager).get_user('anne@example.com') None Mailman has sent her the confirmation message. @@ -125,7 +127,7 @@ list. >>> registrar.confirm(token) True - >>> user = config.db.user_manager.get_user('anne@example.com') + >>> user = getUtility(IUserManager).get_user('anne@example.com') >>> print user.real_name Anne Person >>> list(user.addresses) @@ -151,7 +153,7 @@ Joining a second list Anne of course, is still registered. - >>> print config.db.user_manager.get_user('anne@example.com') + >>> print getUtility(IUserManager).get_user('anne@example.com') <User "Anne Person" at ...> But she is not a member of the mailing list. diff --git a/src/mailman/config/configure.zcml b/src/mailman/config/configure.zcml index d9d1c04bf..9a1922c69 100644 --- a/src/mailman/config/configure.zcml +++ b/src/mailman/config/configure.zcml @@ -36,4 +36,9 @@ provides="mailman.interfaces.listmanager.IListManager" /> + <utility + factory="mailman.database.usermanager.UserManager" + provides="mailman.interfaces.usermanager.IUserManager" + /> + </configure> diff --git a/src/mailman/database/__init__.py b/src/mailman/database/__init__.py index 3120780b7..a489cb60f 100644 --- a/src/mailman/database/__init__.py +++ b/src/mailman/database/__init__.py @@ -39,7 +39,6 @@ from mailman.config import config from mailman.database.messagestore import MessageStore from mailman.database.pending import Pendings from mailman.database.requests import Requests -from mailman.database.usermanager import UserManager from mailman.database.version import Version from mailman.interfaces.database import IDatabase, SchemaVersionMismatchError from mailman.utilities.string import expand @@ -55,7 +54,6 @@ class StockDatabase: def __init__(self): self.url = None - self.user_manager = None self.message_store = None self.pendings = None self.requests = None @@ -67,7 +65,6 @@ class StockDatabase: # the database at the same time. with Lock(os.path.join(config.LOCK_DIR, 'dbcreate.lck')): self._create(debug) - self.user_manager = UserManager() self.message_store = MessageStore() self.pendings = Pendings() self.requests = Requests() diff --git a/src/mailman/database/usermanager.py b/src/mailman/database/usermanager.py index 3b0c8b534..0101bc8a5 100644 --- a/src/mailman/database/usermanager.py +++ b/src/mailman/database/usermanager.py @@ -24,6 +24,7 @@ __all__ = [ 'UserManager', ] + from zope.interface import implements from mailman.config import config diff --git a/src/mailman/docs/addresses.txt b/src/mailman/docs/addresses.txt index 0c0be9505..5388a3cc8 100644 --- a/src/mailman/docs/addresses.txt +++ b/src/mailman/docs/addresses.txt @@ -7,7 +7,9 @@ those addresses, such as their registration date, and whether and when they've been validated. Addresses may be linked to the users that Mailman knows about. Addresses are subscribed to mailing lists though members. - >>> usermgr = config.db.user_manager + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) Creating addresses @@ -16,13 +18,13 @@ Creating addresses Addresses are created directly through the user manager, which starts out with no addresses. - >>> sorted(address.address for address in usermgr.addresses) + >>> sorted(address.address for address in user_manager.addresses) [] Creating an unlinked email address is straightforward. - >>> address_1 = usermgr.create_address('aperson@example.com') - >>> sorted(address.address for address in usermgr.addresses) + >>> address_1 = user_manager.create_address('aperson@example.com') + >>> sorted(address.address for address in user_manager.addresses) [u'aperson@example.com'] However, such addresses have no real name. @@ -32,11 +34,11 @@ However, such addresses have no real name. You can also create an email address object with a real name. - >>> address_2 = usermgr.create_address( + >>> address_2 = user_manager.create_address( ... 'bperson@example.com', 'Ben Person') - >>> sorted(address.address for address in usermgr.addresses) + >>> sorted(address.address for address in user_manager.addresses) [u'aperson@example.com', u'bperson@example.com'] - >>> sorted(address.real_name for address in usermgr.addresses) + >>> sorted(address.real_name for address in user_manager.addresses) [u'', u'Ben Person'] The str() of the address is the RFC 2822 preferred originator format, while @@ -50,35 +52,36 @@ the repr() carries more information. You can assign real names to existing addresses. >>> address_1.real_name = 'Anne Person' - >>> sorted(address.real_name for address in usermgr.addresses) + >>> sorted(address.real_name for address in user_manager.addresses) [u'Anne Person', u'Ben Person'] These addresses are not linked to users, and can be seen by searching the user manager for an associated user. - >>> print usermgr.get_user('aperson@example.com') + >>> print user_manager.get_user('aperson@example.com') None - >>> print usermgr.get_user('bperson@example.com') + >>> print user_manager.get_user('bperson@example.com') None You can create email addresses that are linked to users by using a different interface. - >>> user_1 = usermgr.create_user('cperson@example.com', u'Claire Person') + >>> user_1 = user_manager.create_user( + ... 'cperson@example.com', u'Claire Person') >>> sorted(address.address for address in user_1.addresses) [u'cperson@example.com'] - >>> sorted(address.address for address in usermgr.addresses) + >>> sorted(address.address for address in user_manager.addresses) [u'aperson@example.com', u'bperson@example.com', u'cperson@example.com'] - >>> sorted(address.real_name for address in usermgr.addresses) + >>> sorted(address.real_name for address in user_manager.addresses) [u'Anne Person', u'Ben Person', u'Claire Person'] And now you can find the associated user. - >>> print usermgr.get_user('aperson@example.com') + >>> print user_manager.get_user('aperson@example.com') None - >>> print usermgr.get_user('bperson@example.com') + >>> print user_manager.get_user('bperson@example.com') None - >>> usermgr.get_user('cperson@example.com') + >>> user_manager.get_user('cperson@example.com') <User "Claire Person" at ...> @@ -87,10 +90,10 @@ Deleting addresses You can remove an unlinked address from the user manager. - >>> usermgr.delete_address(address_1) - >>> sorted(address.address for address in usermgr.addresses) + >>> user_manager.delete_address(address_1) + >>> sorted(address.address for address in user_manager.addresses) [u'bperson@example.com', u'cperson@example.com'] - >>> sorted(address.real_name for address in usermgr.addresses) + >>> sorted(address.real_name for address in user_manager.addresses) [u'Ben Person', u'Claire Person'] Deleting a linked address does not delete the user, but it does unlink the @@ -101,12 +104,12 @@ address from the user. >>> user_1.controls('cperson@example.com') True >>> address_3 = list(user_1.addresses)[0] - >>> usermgr.delete_address(address_3) + >>> user_manager.delete_address(address_3) >>> sorted(address.address for address in user_1.addresses) [] >>> user_1.controls('cperson@example.com') False - >>> sorted(address.address for address in usermgr.addresses) + >>> sorted(address.address for address in user_manager.addresses) [u'bperson@example.com'] @@ -116,7 +119,7 @@ Registration and validation Addresses have two dates, the date the address was registered on and the date the address was validated on. Neither date is set by default. - >>> address_4 = usermgr.create_address( + >>> address_4 = user_manager.create_address( ... 'dperson@example.com', 'Dan Person') >>> print address_4.registered_on None @@ -147,7 +150,7 @@ Subscriptions Addresses get subscribed to mailing lists, not users. When the address is subscribed, a role is specified. - >>> address_5 = usermgr.create_address( + >>> address_5 = user_manager.create_address( ... 'eperson@example.com', 'Elly Person') >>> mlist = create_list('_xtext@example.com') @@ -187,7 +190,7 @@ Mailman preserves the case of addresses and uses the case preserved version when sending the user a message, but it treats addresses that are different in case equivalently in all other situations. - >>> address_6 = usermgr.create_address( + >>> address_6 = user_manager.create_address( ... 'FPERSON@example.com', 'Frank Person') The str() of such an address prints the RFC 2822 preferred originator format @@ -211,15 +214,15 @@ case-preserved version are available on attributes of the IAddress object. Because addresses are case-insensitive for all other purposes, you cannot create an address that differs only in case. - >>> usermgr.create_address('fperson@example.com') + >>> user_manager.create_address('fperson@example.com') Traceback (most recent call last): ... ExistingAddressError: FPERSON@example.com - >>> usermgr.create_address('fperson@EXAMPLE.COM') + >>> user_manager.create_address('fperson@EXAMPLE.COM') Traceback (most recent call last): ... ExistingAddressError: FPERSON@example.com - >>> usermgr.create_address('FPERSON@example.com') + >>> user_manager.create_address('FPERSON@example.com') Traceback (most recent call last): ... ExistingAddressError: FPERSON@example.com @@ -227,7 +230,7 @@ create an address that differs only in case. You can get the address using either the lower cased version or case-preserved version. In fact, searching for an address is case insensitive. - >>> print usermgr.get_address('fperson@example.com').address + >>> print user_manager.get_address('fperson@example.com').address fperson@example.com - >>> print usermgr.get_address('FPERSON@example.com').address + >>> print user_manager.get_address('FPERSON@example.com').address fperson@example.com diff --git a/src/mailman/docs/autorespond.txt b/src/mailman/docs/autorespond.txt index 02a4e3acd..5d37927fa 100644 --- a/src/mailman/docs/autorespond.txt +++ b/src/mailman/docs/autorespond.txt @@ -28,7 +28,11 @@ automatic response when messages are held for approval, or when it receives an email command. You can find out how many responses for a particular address have already been sent today. - >>> address = config.db.user_manager.create_address('aperson@example.com') + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> address = getUtility(IUserManager).create_address( + ... 'aperson@example.com') + >>> from mailman.interfaces.autorespond import Response >>> response_set.todays_count(address, Response.hold) 0 @@ -99,7 +103,8 @@ When another response is sent today, that becomes the last one sent. If there's been no response sent to a particular address, None is returned. - >>> address = config.db.user_manager.create_address('bperson@example.com') + >>> address = getUtility(IUserManager).create_address( + ... 'bperson@example.com') >>> response_set.todays_count(address, Response.command) 0 >>> print response_set.last_response(address, Response.command) diff --git a/src/mailman/docs/lifecycle.txt b/src/mailman/docs/lifecycle.txt index 4a4958f6d..ee4657f1d 100644 --- a/src/mailman/docs/lifecycle.txt +++ b/src/mailman/docs/lifecycle.txt @@ -103,11 +103,14 @@ However, all addresses are linked to users. If you create a mailing list with owner addresses that are already known to the system, they won't be created again. - >>> usermgr = config.db.user_manager - >>> user_a = usermgr.get_user('aperson@example.com') - >>> user_b = usermgr.get_user('bperson@example.com') - >>> user_c = usermgr.get_user('cperson@example.com') - >>> user_d = usermgr.get_user('dperson@example.com') + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) + + >>> user_a = user_manager.get_user('aperson@example.com') + >>> user_b = user_manager.get_user('bperson@example.com') + >>> user_c = user_manager.get_user('cperson@example.com') + >>> user_d = user_manager.get_user('dperson@example.com') >>> user_a.real_name = 'Anne Person' >>> user_b.real_name = 'Bart Person' >>> user_c.real_name = 'Caty Person' diff --git a/src/mailman/docs/membership.txt b/src/mailman/docs/membership.txt index 26cdd2aea..ef1675593 100644 --- a/src/mailman/docs/membership.txt +++ b/src/mailman/docs/membership.txt @@ -62,8 +62,10 @@ the list's moderators. We can add new owners or moderators to this list by assigning roles to users. First we have to create the user, because there are no users in the user database yet. - >>> usermgr = config.db.user_manager - >>> user_1 = usermgr.create_user('aperson@example.com', 'Anne Person') + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) + >>> user_1 = user_manager.create_user('aperson@example.com', 'Anne Person') >>> print user_1.real_name Anne Person >>> sorted(address.address for address in user_1.addresses) @@ -99,7 +101,7 @@ her a moderator. Nor does it make her a member of the list. We can add Ben as a moderator of the list, by creating a different member role for him. - >>> user_2 = usermgr.create_user('bperson@example.com', 'Ben Person') + >>> user_2 = user_manager.create_user('bperson@example.com', 'Ben Person') >>> print user_2.real_name Ben Person >>> address_2 = list(user_2.addresses)[0] @@ -136,7 +138,8 @@ delivery. Without a preference, Mailman will fall back first to the address's preference, then the user's preference, then the list's preference. Start without any member preference to see the system defaults. - >>> user_3 = usermgr.create_user('cperson@example.com', 'Claire Person') + >>> user_3 = user_manager.create_user( + ... 'cperson@example.com', 'Claire Person') >>> print user_3.real_name Claire Person >>> address_3 = list(user_3.addresses)[0] diff --git a/src/mailman/docs/registration.txt b/src/mailman/docs/registration.txt index ff6466f82..de9c29cb4 100644 --- a/src/mailman/docs/registration.txt +++ b/src/mailman/docs/registration.txt @@ -91,10 +91,12 @@ returned. There should be no records in the user manager for this address yet. - >>> usermgr = config.db.user_manager - >>> print usermgr.get_user('aperson@example.com') + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) + >>> print user_manager.get_user('aperson@example.com') None - >>> print usermgr.get_address('aperson@example.com') + >>> print user_manager.get_address('aperson@example.com') None But this address is waiting for confirmation. @@ -185,10 +187,10 @@ extracts the token and uses that to confirm the pending registration. Now, there is an IAddress in the database matching the address, as well as an IUser linked to this address. The IAddress is verified. - >>> found_address = usermgr.get_address('aperson@example.com') + >>> found_address = user_manager.get_address('aperson@example.com') >>> found_address <Address: Anne Person <aperson@example.com> [verified] at ...> - >>> found_user = usermgr.get_user('aperson@example.com') + >>> found_user = user_manager.get_user('aperson@example.com') >>> found_user <User "Anne Person" at ...> >>> found_user.controls(found_address.address) @@ -222,19 +224,19 @@ If an address is in the system, but that address is not linked to a user yet and the address is not yet validated, then no user is created until the confirmation step is completed. - >>> usermgr.create_address('cperson@example.com') + >>> user_manager.create_address('cperson@example.com') <Address: cperson@example.com [not verified] at ...> >>> token = registrar.register('cperson@example.com', 'Claire Person') - >>> print usermgr.get_user('cperson@example.com') + >>> print user_manager.get_user('cperson@example.com') None >>> filebase = switchboard.files[0] >>> qmsg, qdata = switchboard.dequeue(filebase) >>> switchboard.finish(filebase) >>> registrar.confirm(token) True - >>> usermgr.get_user('cperson@example.com') + >>> user_manager.get_user('cperson@example.com') <User "Claire Person" at ...> - >>> usermgr.get_address('cperson@example.com') + >>> user_manager.get_address('cperson@example.com') <Address: cperson@example.com [verified] at ...> Even if the address being registered has already been verified, the @@ -257,9 +259,9 @@ mind about registering. When discarded, no IAddress or IUser is created. >>> registrar.discard(token) >>> print pendingdb.confirm(token) None - >>> print usermgr.get_address('eperson@example.com') + >>> print user_manager.get_address('eperson@example.com') None - >>> print usermgr.get_user('eperson@example.com') + >>> print user_manager.get_user('eperson@example.com') None @@ -270,10 +272,11 @@ When a new address for an existing user is registered, there isn't too much different except that the new address will still need to be verified before it can be used. - >>> dperson = usermgr.create_user('dperson@example.com', 'Dave Person') + >>> dperson = user_manager.create_user( + ... 'dperson@example.com', 'Dave Person') >>> dperson <User "Dave Person" at ...> - >>> address = usermgr.get_address('dperson@example.com') + >>> address = user_manager.get_address('dperson@example.com') >>> address.verified_on = datetime.now() >>> from operator import attrgetter @@ -287,7 +290,7 @@ can be used. >>> switchboard.finish(filebase) >>> registrar.confirm(token) True - >>> user = usermgr.get_user('david.person@example.com') + >>> user = user_manager.get_user('david.person@example.com') >>> user is dperson True >>> user diff --git a/src/mailman/docs/requests.txt b/src/mailman/docs/requests.txt index 4a04017aa..0396c48d1 100644 --- a/src/mailman/docs/requests.txt +++ b/src/mailman/docs/requests.txt @@ -681,7 +681,12 @@ Frank Person is now a member of the mailing list. <Language [en] English (USA)> >>> print member.delivery_mode DeliveryMode.regular - >>> user = config.db.user_manager.get_user(member.address.address) + + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) + + >>> user = user_manager.get_user(member.address.address) >>> print user.real_name Frank Person >>> print user.password @@ -697,14 +702,16 @@ unsubscription holds can send the list's moderators an immediate notification. >>> mlist.admin_immed_notify = False >>> from mailman.interfaces.member import MemberRole - >>> user_1 = config.db.user_manager.create_user('gperson@example.com') + >>> user_1 = user_manager.create_user('gperson@example.com') >>> address_1 = list(user_1.addresses)[0] >>> address_1.subscribe(mlist, MemberRole.member) <Member: gperson@example.com on alist@example.com as MemberRole.member> - >>> user_2 = config.db.user_manager.create_user('hperson@example.com') + + >>> user_2 = user_manager.create_user('hperson@example.com') >>> address_2 = list(user_2.addresses)[0] >>> address_2.subscribe(mlist, MemberRole.member) <Member: hperson@example.com on alist@example.com as MemberRole.member> + >>> id_5 = moderator.hold_unsubscription(mlist, 'gperson@example.com') >>> requests.get_request(id_5) is not None True diff --git a/src/mailman/docs/usermanager.txt b/src/mailman/docs/usermanager.txt index 3c5369b84..856221952 100644 --- a/src/mailman/docs/usermanager.txt +++ b/src/mailman/docs/usermanager.txt @@ -8,10 +8,8 @@ variable MANAGERS_INIT_FUNCTION. The instance is accessible on the global config object. >>> from mailman.interfaces.usermanager import IUserManager - >>> from zope.interface.verify import verifyObject - >>> usermgr = config.db.user_manager - >>> verifyObject(IUserManager, usermgr) - True + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) Creating users @@ -23,9 +21,11 @@ time. This user will have an empty string as their real name, but will not have a password. >>> from mailman.interfaces.user import IUser - >>> user = usermgr.create_user() + >>> from zope.interface.verify import verifyObject + >>> user = user_manager.create_user() >>> verifyObject(IUser, user) True + >>> sorted(address.address for address in user.addresses) [] >>> user.real_name @@ -41,51 +41,51 @@ The user has preferences, but none of them will be specified. A user can be assigned a real name. >>> user.real_name = 'Anne Person' - >>> sorted(user.real_name for user in usermgr.users) + >>> sorted(user.real_name for user in user_manager.users) [u'Anne Person'] A user can be assigned a password. >>> user.password = 'secret' - >>> sorted(user.password for user in usermgr.users) + >>> sorted(user.password for user in user_manager.users) [u'secret'] You can also create a user with an address to start out with. - >>> user_2 = usermgr.create_user('bperson@example.com') + >>> user_2 = user_manager.create_user('bperson@example.com') >>> verifyObject(IUser, user_2) True >>> sorted(address.address for address in user_2.addresses) [u'bperson@example.com'] - >>> sorted(user.real_name for user in usermgr.users) + >>> sorted(user.real_name for user in user_manager.users) [u'', u'Anne Person'] As above, you can assign a real name to such users. >>> user_2.real_name = 'Ben Person' - >>> sorted(user.real_name for user in usermgr.users) + >>> sorted(user.real_name for user in user_manager.users) [u'Anne Person', u'Ben Person'] You can also create a user with just a real name. - >>> user_3 = usermgr.create_user(real_name='Claire Person') + >>> user_3 = user_manager.create_user(real_name='Claire Person') >>> verifyObject(IUser, user_3) True >>> sorted(address.address for address in user.addresses) [] - >>> sorted(user.real_name for user in usermgr.users) + >>> sorted(user.real_name for user in user_manager.users) [u'Anne Person', u'Ben Person', u'Claire Person'] Finally, you can create a user with both an address and a real name. - >>> user_4 = usermgr.create_user('dperson@example.com', 'Dan Person') + >>> user_4 = user_manager.create_user('dperson@example.com', 'Dan Person') >>> verifyObject(IUser, user_3) True >>> sorted(address.address for address in user_4.addresses) [u'dperson@example.com'] >>> sorted(address.real_name for address in user_4.addresses) [u'Dan Person'] - >>> sorted(user.real_name for user in usermgr.users) + >>> sorted(user.real_name for user in user_manager.users) [u'Anne Person', u'Ben Person', u'Claire Person', u'Dan Person'] @@ -95,8 +95,8 @@ Deleting users You delete users by going through the user manager. The deleted user is no longer available through the user manager iterator. - >>> usermgr.delete_user(user) - >>> sorted(user.real_name for user in usermgr.users) + >>> user_manager.delete_user(user) + >>> sorted(user.real_name for user in user_manager.users) [u'Ben Person', u'Claire Person', u'Dan Person'] @@ -109,7 +109,7 @@ that the .get_user() method takes a string email address, not an IAddress object. >>> address = list(user_4.addresses)[0] - >>> found_user = usermgr.get_user(address.address) + >>> found_user = user_manager.get_user(address.address) >>> found_user <User "Dan Person" at ...> >>> found_user is user_4 @@ -118,8 +118,8 @@ object. If the address is not in the user database or does not have a user associated with it, you will get None back. - >>> print usermgr.get_user('zperson@example.com') + >>> print user_manager.get_user('zperson@example.com') None >>> user_4.unlink(address) - >>> print usermgr.get_user(address.address) + >>> print user_manager.get_user(address.address) None diff --git a/src/mailman/docs/users.txt b/src/mailman/docs/users.txt index ef4f3062b..26788a2e5 100644 --- a/src/mailman/docs/users.txt +++ b/src/mailman/docs/users.txt @@ -6,9 +6,11 @@ Users are entities that represent people. A user has a real name and a password. Optionally a user may have some preferences and a set of addresses they control. A user also knows which mailing lists they are subscribed to. -See usermanager.txt for examples of how to create, delete, and find users. +See `usermanager.txt`_ for examples of how to create, delete, and find users. - >>> usermgr = config.db.user_manager + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) User data @@ -16,21 +18,21 @@ User data Users may have a real name and a password. - >>> user_1 = usermgr.create_user() + >>> user_1 = user_manager.create_user() >>> user_1.password = 'my password' >>> user_1.real_name = 'Zoe Person' - >>> sorted(user.real_name for user in usermgr.users) + >>> sorted(user.real_name for user in user_manager.users) [u'Zoe Person'] - >>> sorted(user.password for user in usermgr.users) + >>> sorted(user.password for user in user_manager.users) [u'my password'] The password and real name can be changed at any time. >>> user_1.real_name = 'Zoe X. Person' >>> user_1.password = 'another password' - >>> sorted(user.real_name for user in usermgr.users) + >>> sorted(user.real_name for user in user_manager.users) [u'Zoe X. Person'] - >>> sorted(user.password for user in usermgr.users) + >>> sorted(user.password for user in user_manager.users) [u'another password'] @@ -55,7 +57,7 @@ address on a user object. You can also create the address separately and then link it to the user. - >>> address_1 = usermgr.create_address('zperson@example.net') + >>> address_1 = user_manager.create_address('zperson@example.net') >>> user_1.link(address_1) >>> sorted(address.address for address in user_1.addresses) [u'zperson@example.com', u'zperson@example.net', u'zperson@example.org'] @@ -64,7 +66,7 @@ You can also create the address separately and then link it to the user. But don't try to link an address to more than one user. - >>> another_user = usermgr.create_user() + >>> another_user = user_manager.create_user() >>> another_user.link(address_1) Traceback (most recent call last): ... @@ -80,13 +82,13 @@ You can also ask whether a given user controls a given address. Given a text email address, the user manager can find the user that controls that address. - >>> usermgr.get_user('zperson@example.com') is user_1 + >>> user_manager.get_user('zperson@example.com') is user_1 True - >>> usermgr.get_user('zperson@example.net') is user_1 + >>> user_manager.get_user('zperson@example.net') is user_1 True - >>> usermgr.get_user('zperson@example.org') is user_1 + >>> user_manager.get_user('zperson@example.org') is user_1 True - >>> print usermgr.get_user('bperson@example.com') + >>> print user_manager.get_user('bperson@example.com') None Addresses can also be unlinked from a user. @@ -94,7 +96,7 @@ Addresses can also be unlinked from a user. >>> user_1.unlink(address_1) >>> user_1.controls('zperson@example.net') False - >>> print usermgr.get_user('aperson@example.net') + >>> print user_manager.get_user('aperson@example.net') None But don't try to unlink the address from a user it's not linked to. @@ -159,9 +161,9 @@ membership role. >>> user_1.link(address_1) >>> sorted(address.address for address in user_1.addresses) [u'zperson@example.com', u'zperson@example.net', u'zperson@example.org'] - >>> com = usermgr.get_address('zperson@example.com') - >>> org = usermgr.get_address('zperson@example.org') - >>> net = usermgr.get_address('zperson@example.net') + >>> com = user_manager.get_address('zperson@example.com') + >>> org = user_manager.get_address('zperson@example.org') + >>> net = user_manager.get_address('zperson@example.net') >>> from mailman.app.lifecycle import create_list >>> mlist_1 = create_list('xtest_1@example.com') @@ -197,3 +199,10 @@ membership role. zperson@example.net xtest_3@example.com MemberRole.moderator zperson@example.org xtest_2@example.com MemberRole.member zperson@example.org xtest_2@example.com MemberRole.owner + + +Cross references +================ + +.. _`usermanager.txt`: usermanager.html + diff --git a/src/mailman/interfaces/database.py b/src/mailman/interfaces/database.py index 826657b0a..2cf56e800 100644 --- a/src/mailman/interfaces/database.py +++ b/src/mailman/interfaces/database.py @@ -84,9 +84,6 @@ class IDatabase(Interface): def abort(): """Abort the current transaction.""" - user_manager = Attribute( - """The IUserManager instance provided by the database layer.""") - message_store = Attribute( """The IMessageStore instance provided by the database layer.""") diff --git a/src/mailman/pipeline/decorate.py b/src/mailman/pipeline/decorate.py index 3941c6509..c6b613fda 100644 --- a/src/mailman/pipeline/decorate.py +++ b/src/mailman/pipeline/decorate.py @@ -29,12 +29,14 @@ import re import logging from email.MIMEText import MIMEText +from zope.component import getUtility from zope.interface import implements from mailman.config import config from mailman.email.message import Message from mailman.i18n import _ from mailman.interfaces.handler import IHandler +from mailman.interfaces.usermanager import IUserManager from mailman.utilities.string import expand @@ -54,7 +56,7 @@ def process(mlist, msg, msgdata): assert len(recips) == 1, ( 'The number of intended recipients must be exactly 1') recipient = recips[0].lower() - user = config.db.user_manager.get_user(recipient) + user = getUtility(IUserManager).get_user(recipient) member = mlist.members.get_member(recipient) d['user_address'] = recipient if user is not None and member is not None: diff --git a/src/mailman/pipeline/docs/acknowledge.txt b/src/mailman/pipeline/docs/acknowledge.txt index bde84349f..3b8316cab 100644 --- a/src/mailman/pipeline/docs/acknowledge.txt +++ b/src/mailman/pipeline/docs/acknowledge.txt @@ -21,9 +21,12 @@ acknowledgment. Subscribe a user to the mailing list. - >>> usermgr = config.db.user_manager + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) + >>> from mailman.interfaces.member import MemberRole - >>> user_1 = usermgr.create_user('aperson@example.com') + >>> user_1 = user_manager.create_user('aperson@example.com') >>> address_1 = list(user_1.addresses)[0] >>> address_1.subscribe(mlist, MemberRole.member) <Member: aperson@example.com on _xtest@example.com as MemberRole.member> @@ -74,7 +77,7 @@ Similarly if the original sender is specified in the message metadata, and that sender is a member but not one who has requested acknowledgments, none will be sent. - >>> user_2 = usermgr.create_user('dperson@example.com') + >>> user_2 = user_manager.create_user('dperson@example.com') >>> address_2 = list(user_2.addresses)[0] >>> address_2.subscribe(mlist, MemberRole.member) <Member: dperson@example.com on _xtest@example.com as MemberRole.member> diff --git a/src/mailman/pipeline/docs/avoid-duplicates.txt b/src/mailman/pipeline/docs/avoid-duplicates.txt index aef50aa6e..9b44d0ebe 100644 --- a/src/mailman/pipeline/docs/avoid-duplicates.txt +++ b/src/mailman/pipeline/docs/avoid-duplicates.txt @@ -12,11 +12,14 @@ recipients from the list of recipients that earlier handler modules Create some members we're going to use. + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) + + >>> address_a = user_manager.create_address('aperson@example.com') + >>> address_b = user_manager.create_address('bperson@example.com') + >>> from mailman.interfaces.member import MemberRole - >>> address_a = config.db.user_manager.create_address( - ... 'aperson@example.com') - >>> address_b = config.db.user_manager.create_address( - ... 'bperson@example.com') >>> member_a = address_a.subscribe(mlist, MemberRole.member) >>> member_b = address_b.subscribe(mlist, MemberRole.member) >>> # This is the message metadata dictionary as it would be produced by diff --git a/src/mailman/pipeline/docs/calc-recips.txt b/src/mailman/pipeline/docs/calc-recips.txt index e787e650d..ef8c0e2b7 100644 --- a/src/mailman/pipeline/docs/calc-recips.txt +++ b/src/mailman/pipeline/docs/calc-recips.txt @@ -12,13 +12,16 @@ modules and depends on a host of factors. Recipients are calculate from the list members, so add a bunch of members to start out with. First, create a bunch of addresses... - >>> usermgr = config.db.user_manager - >>> address_a = usermgr.create_address('aperson@example.com') - >>> address_b = usermgr.create_address('bperson@example.com') - >>> address_c = usermgr.create_address('cperson@example.com') - >>> address_d = usermgr.create_address('dperson@example.com') - >>> address_e = usermgr.create_address('eperson@example.com') - >>> address_f = usermgr.create_address('fperson@example.com') + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) + + >>> address_a = user_manager.create_address('aperson@example.com') + >>> address_b = user_manager.create_address('bperson@example.com') + >>> address_c = user_manager.create_address('cperson@example.com') + >>> address_d = user_manager.create_address('dperson@example.com') + >>> address_e = user_manager.create_address('eperson@example.com') + >>> address_f = user_manager.create_address('fperson@example.com') ...then subscribe these addresses to the mailing list as members... diff --git a/src/mailman/pipeline/docs/file-recips.txt b/src/mailman/pipeline/docs/file-recips.txt index 2c9d7724f..3401e7492 100644 --- a/src/mailman/pipeline/docs/file-recips.txt +++ b/src/mailman/pipeline/docs/file-recips.txt @@ -81,9 +81,12 @@ However, if the sender of the original message is a member of the list and their address is in the include file, the sender's address is /not/ included in the recipients list. - >>> from mailman.interfaces.member import MemberRole - >>> address_1 = config.db.user_manager.create_address( + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> address_1 = getUtility(IUserManager).create_address( ... 'cperson@example.com') + + >>> from mailman.interfaces.member import MemberRole >>> address_1.subscribe(mlist, MemberRole.member) <Member: cperson@example.com on _xtest@example.com as MemberRole.member> diff --git a/src/mailman/pipeline/replybot.py b/src/mailman/pipeline/replybot.py index 5a560bcbf..e7834eb2c 100644 --- a/src/mailman/pipeline/replybot.py +++ b/src/mailman/pipeline/replybot.py @@ -28,6 +28,7 @@ __all__ = [ import logging import datetime +from zope.component import getUtility from zope.interface import implements from mailman import Utils @@ -37,6 +38,7 @@ from mailman.i18n import _ from mailman.interfaces.autorespond import ( ALWAYS_REPLY, IAutoResponseSet, Response, ResponseAction) from mailman.interfaces.handler import IHandler +from mailman.interfaces.usermanager import IUserManager from mailman.utilities.datetime import today from mailman.utilities.string import expand @@ -91,9 +93,10 @@ class Replybot: # = 0 means always automatically respond, as does an "X-Ack: yes" # header (useful for debugging). response_set = IAutoResponseSet(mlist) - address = config.db.user_manager.get_address(msg.sender) + user_manager = getUtility(IUserManager) + address = user_manager.get_address(msg.sender) if address is None: - address = config.db.user_manager.create_address(msg.sender) + address = user_manager.create_address(msg.sender) grace_period = mlist.autoresponse_grace_period if grace_period > ALWAYS_REPLY and ack <> 'yes': last = response_set.last_response(address, response_type) diff --git a/src/mailman/queue/docs/digester.txt b/src/mailman/queue/docs/digester.txt index bb2c05819..c61f0fe3d 100644 --- a/src/mailman/queue/docs/digester.txt +++ b/src/mailman/queue/docs/digester.txt @@ -476,9 +476,13 @@ digests, or MIME digests. >>> len(get_queue_messages('virgin')) 0 + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user_manager = getUtility(IUserManager) + >>> from mailman.interfaces.member import DeliveryMode, MemberRole >>> def subscribe(email, mode): - ... address = config.db.user_manager.create_address(email) + ... address = user_manager.create_address(email) ... member = address.subscribe(mlist, MemberRole.member) ... member.preferences.delivery_mode = mode ... return member diff --git a/src/mailman/rules/docs/moderation.txt b/src/mailman/rules/docs/moderation.txt index 401e46605..335dd4f5b 100644 --- a/src/mailman/rules/docs/moderation.txt +++ b/src/mailman/rules/docs/moderation.txt @@ -27,8 +27,11 @@ moderation rule can't match. Let's add the message author as a non-moderated member. - >>> user = config.db.user_manager.create_user( + >>> from mailman.interfaces.usermanager import IUserManager + >>> from zope.component import getUtility + >>> user = getUtility(IUserManager).create_user( ... 'aperson@example.org', 'Anne Person') + >>> address = list(user.addresses)[0] >>> from mailman.interfaces.member import MemberRole >>> member = address.subscribe(mlist, MemberRole.member) |
