summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2007-06-09 18:16:29 -0400
committerBarry Warsaw2007-06-09 18:16:29 -0400
commit5bc4941f0b749830d5e4feb57be5f172e77e0631 (patch)
treeac56f0b3ed7398673d97bcf737c8ea9143704ef6
parent3231fd628f6eea30bd6e2be56eb419ed0008d954 (diff)
downloadmailman-5bc4941f0b749830d5e4feb57be5f172e77e0631.tar.gz
mailman-5bc4941f0b749830d5e4feb57be5f172e77e0631.tar.zst
mailman-5bc4941f0b749830d5e4feb57be5f172e77e0631.zip
Repair the usermanager.txt and listmanager.txt doc tests. These repairs were
necessary to deal with the simplified user model. Eradicate more references to rosters and roster sets. Give Users a repr. Also give them a belongs_to() link to Preferences, but change the user manager to not give a user preferences by default (the lookup schema should properly handle users with no preferences now). Also, when creating a user, set their real_name to the empty string if no real_name argument was given to create_user(). Update the IUserManager interface's create_user() method to match the implementation.
-rw-r--r--Mailman/database/listmanager.py1
-rw-r--r--Mailman/database/model/user.py7
-rw-r--r--Mailman/database/usermanager.py11
-rw-r--r--Mailman/docs/listmanager.txt7
-rw-r--r--Mailman/docs/usermanager.txt163
-rw-r--r--Mailman/interfaces/usermanager.py12
6 files changed, 121 insertions, 80 deletions
diff --git a/Mailman/database/listmanager.py b/Mailman/database/listmanager.py
index de8abbd58..83c913ffb 100644
--- a/Mailman/database/listmanager.py
+++ b/Mailman/database/listmanager.py
@@ -54,7 +54,6 @@ class ListManager(object):
def delete(self, mlist):
# Delete the wrapped backing data. XXX It's kind of icky to reach
# into the MailList object this way.
- mlist._data.delete_rosters()
mlist._data.delete()
mlist._data = None
diff --git a/Mailman/database/model/user.py b/Mailman/database/model/user.py
index d646606a9..06fb1f6f3 100644
--- a/Mailman/database/model/user.py
+++ b/Mailman/database/model/user.py
@@ -24,6 +24,7 @@ from Mailman.database.model import Address
from Mailman.interfaces import IUser
ADDRESS_KIND = 'Mailman.database.model.address.Address'
+PREFERENCE_KIND = 'Mailman.database.model.profile.Preferences'
@@ -33,10 +34,14 @@ class User(Entity):
has_field('real_name', Unicode)
has_field('password', Unicode)
# Relationships
- has_many('addresses', of_kind=ADDRESS_KIND)
+ has_many('addresses', of_kind=ADDRESS_KIND)
+ belongs_to('preferences', of_kind=PREFERENCE_KIND)
# Options
using_options(shortnames=True)
+ def __repr__(self):
+ return '<User "%s" at %#x>' % (self.real_name, id(self))
+
def link(self, address):
if address.user is not None:
raise Errors.AddressAlreadyLinkedError(address)
diff --git a/Mailman/database/usermanager.py b/Mailman/database/usermanager.py
index ed0b552a8..95e4949ea 100644
--- a/Mailman/database/usermanager.py
+++ b/Mailman/database/usermanager.py
@@ -37,16 +37,9 @@ class UserManager(object):
def create_user(self, address=None, real_name=None):
user = User()
- # Users always have preferences
- user.preferences = Preferences()
- user.preferences.user = user
- if real_name:
- user.real_name = real_name
+ user.real_name = (real_name if real_name is not None else '')
if address:
- kws = dict(address=address)
- if real_name:
- kws['real_name'] = real_name
- user.link(Address(**kws))
+ user.link(Address(address=address, real_name=user.real_name))
return user
def delete_user(self, user):
diff --git a/Mailman/docs/listmanager.txt b/Mailman/docs/listmanager.txt
index 9e237f02f..03943a237 100644
--- a/Mailman/docs/listmanager.txt
+++ b/Mailman/docs/listmanager.txt
@@ -54,17 +54,12 @@ you will get an exception.
Deleting a mailing list
-----------------------
-Deleting an existing mailing list also deletes its rosters and roster sets.
-
- >>> sorted(r.name for r in config.user_manager.rosters)
- ['', '_xtest@example.com moderators', '_xtest@example.com owners']
+Use the list manager to delete a mailing list.
>>> mgr.delete(mlist)
>>> flush()
>>> sorted(mgr.names)
[]
- >>> sorted(r.name for r in config.user_manager.rosters)
- ['']
Attempting to access attributes of the deleted mailing list raises an
exception:
diff --git a/Mailman/docs/usermanager.txt b/Mailman/docs/usermanager.txt
index f79bff8c6..389c68956 100644
--- a/Mailman/docs/usermanager.txt
+++ b/Mailman/docs/usermanager.txt
@@ -1,100 +1,141 @@
-The user manager and rosters
-============================
+The user manager
+================
-The IUserManager is how you create, delete, and roster objects. Rosters
-manage collections of users. The Mailman system instantiates an IUserManager
-for you based on the configuration variable MANAGERS_INIT_FUNCTION. The
-instance is accessible on the global config object.
+The IUserManager is how you create, delete, and manage users. The Mailman
+system instantiates an IUserManager for you based on the configuration
+variable MANAGERS_INIT_FUNCTION. The instance is accessible on the global
+config object.
>>> from Mailman.configuration import config
+ >>> from Mailman.database import flush
>>> from Mailman.interfaces import IUserManager
>>> mgr = config.user_manager
>>> IUserManager.providedBy(mgr)
True
-The default roster
-------------------
+Creating users
+--------------
-The user manager always contains at least one roster, the 'null' roster or
-'all inclusive roster'.
+There are several ways you can create a user object. The simplest is to
+create a 'blank' user by not providing an address or real name at creation
+time. This user will have an empty string as their real name, but will not
+have a password or preferences.
- >>> sorted(roster.name for roster in mgr.rosters)
- ['']
+ >>> from Mailman.interfaces import IUser
+ >>> user = mgr.create_user()
+ >>> flush()
+ >>> IUser.providedBy(user)
+ True
+ >>> sorted(address.address for address in user.addresses)
+ []
+ >>> user.real_name
+ ''
+ >>> print user.preferences
+ None
+ >>> print user.password
+ None
+A user can be assigned a real name.
-Adding rosters
---------------
+ >>> user.real_name = 'Anne Person'
+ >>> flush()
+ >>> sorted(user.real_name for user in mgr.users)
+ ['Anne Person']
-You create a roster to hold users. The only thing a roster needs is a name,
-basically just an identifying string.
+A user can be assigned a password.
- >>> from Mailman.database import flush
- >>> from Mailman.interfaces import IRoster
- >>> roster = mgr.create_roster('roster-1')
- >>> IRoster.providedBy(roster)
- True
- >>> roster.name
- 'roster-1'
+ >>> user.password = 'secret'
>>> flush()
+ >>> sorted(user.password for user in mgr.users)
+ ['secret']
-If you try to create a roster with the same name as an existing roster, you
-will get an exception.
+You can also create a user with an address to start out with.
- >>> roster_dup = mgr.create_roster('roster-1')
- Traceback (most recent call last):
- ...
- RosterExistsError: roster-1
+ >>> user_2 = mgr.create_user('bperson@example.com')
+ >>> flush()
+ >>> IUser.providedBy(user_2)
+ True
+ >>> sorted(address.address for address in user_2.addresses)
+ ['bperson@example.com']
+ >>> sorted(user.real_name for user in mgr.users)
+ ['', 'Anne Person']
+As above, you can assign a real name to such users.
-Deleting a roster
------------------
+ >>> user_2.real_name = 'Ben Person'
+ >>> flush()
+ >>> sorted(user.real_name for user in mgr.users)
+ ['Anne Person', 'Ben Person']
-Delete the roster, and you can then create it again.
+You can also create a user with just a real name.
- >>> mgr.delete_roster(roster)
+ >>> user_3 = mgr.create_user(real_name='Claire Person')
>>> flush()
- >>> roster = mgr.create_roster('roster-1')
+ >>> IUser.providedBy(user_3)
+ True
+ >>> sorted(address.address for address in user.addresses)
+ []
+ >>> sorted(user.real_name for user in mgr.users)
+ ['Anne Person', 'Ben Person', 'Claire Person']
+
+Finally, you can create a user with both an address and a real name.
+
+ >>> user_4 = mgr.create_user('dperson@example.com', 'Dan Person')
>>> flush()
- >>> roster.name
- 'roster-1'
+ >>> IUser.providedBy(user_3)
+ True
+ >>> sorted(address.address for address in user_4.addresses)
+ ['dperson@example.com']
+ >>> sorted(address.real_name for address in user_4.addresses)
+ ['Dan Person']
+ >>> sorted(user.real_name for user in mgr.users)
+ ['Anne Person', 'Ben Person', 'Claire Person', 'Dan Person']
-Retrieving a roster
--------------------
+Deleting users
+--------------
-When a roster exists, you can ask the user manager for it and you will always
-get the same object back.
+You delete users by going through the user manager. The deleted user is no
+longer available through the user manager iterator.
- >>> roster_2 = mgr.get_roster('roster-1')
- >>> roster_2.name
- 'roster-1'
- >>> roster is roster_2
- True
+ >>> mgr.delete_user(user)
+ >>> flush()
+ >>> sorted(user.real_name for user in mgr.users)
+ ['Ben Person', 'Claire Person', 'Dan Person']
-Trying to get a roster that does not yet exist returns None.
- >>> print mgr.get_roster('no roster')
- None
+Finding users
+-------------
+You can ask the user manager to find the IUser that controls a particular
+email address. You'll get back the original user object if it's found. Note
+that the .get_user() method takes a string email address, not an IAddress
+object.
-Iterating over all the rosters
-------------------------------
+ >>> address = list(user_4.addresses)[0]
+ >>> found_user = mgr.get_user(address.address)
+ >>> found_user
+ <User "Dan Person" at ...>
+ >>> found_user is user_4
+ True
-Once you've created a bunch of rosters, you can use the user manager to
-iterate over all the rosters.
+If the address is not in the user database or does not have a user associated
+with it, you will get None back.
- >>> roster_2 = mgr.create_roster('roster-2')
- >>> roster_3 = mgr.create_roster('roster-3')
- >>> roster_4 = mgr.create_roster('roster-4')
+ >>> print mgr.get_user('zperson@example.com')
+ None
+ >>> user_4.unlink(address)
>>> flush()
- >>> sorted(roster.name for roster in mgr.rosters)
- ['', 'roster-1', 'roster-2', 'roster-3', 'roster-4']
+ >>> print mgr.get_user(address.address)
+ None
-Cleaning up
------------
+Clean up
+--------
- >>> for roster in mgr.rosters:
- ... mgr.delete_roster(roster)
+ >>> for user in mgr.users:
+ ... mgr.delete_user(user)
>>> flush()
+ >>> list(mgr.users)
+ []
diff --git a/Mailman/interfaces/usermanager.py b/Mailman/interfaces/usermanager.py
index 38dd06dfa..d239ea5b3 100644
--- a/Mailman/interfaces/usermanager.py
+++ b/Mailman/interfaces/usermanager.py
@@ -33,8 +33,16 @@ class IUserManager(Interface):
IUsers in all IRosters.
"""
- def create_user():
- """Create and return an IUser."""
+ def create_user(address=None, real_name=None):
+ """Create and return an IUser.
+
+ When address is given, an IAddress is also created and linked to the
+ new IUser object. It is an error if the address already exists.
+
+ When real_name is given, the IUser's real_name is set to this string.
+ If an IAddress is also created and linked, its real_name is set to the
+ same string.
+ """
def delete_user(user):
"""Delete the given IUser."""