Questions in regard to the database operations
Hi!
My name is Emanuel Danci and I am the GSoC student working on integrating the Systers` feature, dynamic sublists - http://systers.org/systers-dev/doku.php/good_to_know?s%5B%5D=postgresql , with Mm 3.0 and I have 2 questions in regard to how the database works.
First of all, how is the aliases set populated in time? Second of all, when a user is unsubscribed, is all the data related to him/her deleted (his/hers preferences, the info related to the address etc) ? Thank you, Emanuel
Hi Emanuel,
On Jun 25, 2012, at 04:51 AM, Danci Emanuel wrote:
First of all, how is the aliases set populated in time?
I'm guessing you mean the mailing list's "acceptable aliases", i.e. addresses which are not the list's posting address, but will still be accepted if it appears in a recipient header (To or CC) instead of being rejected as "implicitly addressed".
At the lowest level, you adapt a mailing list into an IAcceptableAliasSet, and then you .add() or .remove() addresses from that object.
Of course, all this is plumbed through the REST API. A good description of how this works is available here:
http://packages.python.org/mailman/src/mailman/rest/docs/configuration.html#...
Second of all, when a user is unsubscribed, is all the data related to him/her deleted (his/hers preferences, the info related to the address etc) ?
In order to understand what happens when a user is unsubscribed, it's important to review the data model. Mailman has "addresses", "users", and "members". An address is essentially a known email address, which may be verified or not, and which may or may not be linked to a user. Users aren't much more than a user id, but may have various other pieces of information associated with it (e.g. a password). Both addresses and users may have "display names" and preferences. Neither of these objects are directly associated with a mailing list.
Addresses can be subscribed to mailing lists. This "subscription" is represented by member objects. Or put another way, a member is an address associated with a mailing list with a given role. Because addresses can be linked to users, this is how a user gets subscribed to a mailing list. Note that if a user has a "preferred address", the user record can be associated with the mailing list as well, but this is a convenience shortcut. Members also have preferences.
So what happens when someone unsubscribes from a mailing list? All that happens is that the relevant member record gets deleted. The member's preferences also get deleted, but that's it. Neither the address nor the user is touched.
Hope that helps! -Barry
Thanks for the clarifications, Barry!
I still want to ask you something. As far as I am aware, I also have to implement the aliases feature as Systers see it, meaning that a user, after gets registered can post messages to a mailing list from more than one address. So, just to make sure, do you think that these addresses could be added directly to the address table and then all the addresses (aliases) linked to the same user? This - http://systers.org/systers-dev/doku.php/systers_database_in_postgresql?s[]=database is the current database schema implemented by Systes, so basically I am looking a solution to replace the 'alias' table.
Furthermore, in regard to the user removal, if the address and the user records remain
in the database, how can we know if a user has been unsubscribed from the list?
I am asking this, because in order to successfully implement the dlists, we need to
keep account of the unsubscribed users, so that we wont send any unwanted emails to them. In the aforementioned Systers
schema, this is done by setting the 'deleted' flag
to true.
Thanks again, Emanuel
From: Barry Warsaw <barry@list.org> To: mailman-developers@python.org Cc: Danci Emanuel <danci_emanuel@yahoo.com> Sent: Monday, June 25, 2012 4:42 PM Subject: Re: [Mailman-Developers] Questions in regard to the database operations
Hi Emanuel,
On Jun 25, 2012, at 04:51 AM, Danci Emanuel wrote:
First of all, how is the aliases set populated in time?
I'm guessing you mean the mailing list's "acceptable aliases", i.e. addresses which are not the list's posting address, but will still be accepted if it appears in a recipient header (To or CC) instead of being rejected as "implicitly addressed".
At the lowest level, you adapt a mailing list into an IAcceptableAliasSet, and then you .add() or .remove() addresses from that object.
Of course, all this is plumbed through the REST API. A good description of how this works is available here:
http://packages.python.org/mailman/src/mailman/rest/docs/configuration.html#...
Second of all, when a user is unsubscribed, is all the data related to him/her deleted (his/hers preferences, the info related to the address etc) ?
In order to understand what happens when a user is unsubscribed, it's important to review the data model. Mailman has "addresses", "users", and "members". An address is essentially a known email address, which may be verified or not, and which may or may not be linked to a user. Users aren't much more than a user id, but may have various other pieces of information associated with it (e.g. a password). Both addresses and users may have "display names" and preferences. Neither of these objects are directly associated with a mailing list.
Addresses can be subscribed to mailing lists. This "subscription" is represented by member objects. Or put another way, a member is an address associated with a mailing list with a given role. Because addresses can be linked to users, this is how a user gets subscribed to a mailing list. Note that if a user has a "preferred address", the user record can be associated with the mailing list as well, but this is a convenience shortcut. Members also have preferences.
So what happens when someone unsubscribes from a mailing list? All that happens is that the relevant member record gets deleted. The member's preferences also get deleted, but that's it. Neither the address nor the user is touched.
Hope that helps! -Barry
On Jun 25, 2012, at 08:02 AM, Danci Emanuel wrote:
I still want to ask you something. As far as I am aware, I also have to implement the aliases feature as Systers see it, meaning that a user, after gets registered can post messages to a mailing list from more than one address.
Ah, so this is totally different than "acceptable aliases" and the IAcceptableAliasSet interface. What I described earlier is a mailing list feature which lets you set up a posting address alias in your MTA.
For example, let's say you create a mailing list for your security team and you call it security-team@example.com. For convenience, you want to allow people to post to security@example.com and so you set up an alias in your MTA's configuration file (e.g. /etc/aliases) which points security -> security-team.
When people post to security@example.com, it gets forwarded to security-team@example.com, but Mailman will not see the list's posting address in the To header. Without security@example.com being added to the mailing list's acceptable_aliases, these posts will be rejected with an "implicit destination" error.
But none of that really applies to your use case. ;)
So, just to make sure, do you think that these addresses could be added directly to the address table and then all the addresses (aliases) linked to the same user? This - http://systers.org/systers-dev/doku.php/systers_database_in_postgresql?s[]=database is the current database schema implemented by Systes, so basically I am looking a solution to replace the 'alias' table.
Remember the model I described earlier, regarding addresses, users, and members? Using this model, you can register multiple address objects and link them to the same user. E.g. you could register all of the following:
anne@example.com aperson@example.com anne.x.person@example.com
(Let's assume too that all three have been validated.)
and link those addresses to the user record representing Anne Person. When Anne subscribes to a mailing list, such as security-team@example.com, she chooses one of those three addresses to subscribe using the 'member' role. This is the address that will receive postings to the list.
So if she subscribes anne@example.com, then when new messages are posted to the mailing list, only anne@example.com will receive copies.
However, Anne can *post* to the mailing list with any of her three validated and linked email addresses, and no further moderation approval is necessary. This is one of the big advantages of the mm3 model over the mm2 model. We now *know* that all three of those addresses are associated with Anne, so any of her addresses are allowed for posting. However, she will only receive copies of list posts to the addresses she's explicitly subscribed, IOW she won't receive three copies of list postings unless she wants to.
In summary, the mm3 model directly supports the Systers model, as I understand it. All the internal APIs are there to add additional addresses, verify them, link them to users, and subscribe them to mailing lists. All you have to work out is the social and procedural ways of getting those additional addresses into the system, verified, and linked to the user.
Furthermore, in regard to the user removal, if the address and the user records remain in the database, how can we know if a user has been unsubscribed from the list?
You know because there will be no member record linking any of the user's addresses to the mailing list. There are various ways using the internal API to check this. Probably the easiest is to use something like the following:
from zope.component import getUtility from mailman.interfaces.member import MemberRole from mailman.interfaces.subscriptions import ISubscriptionService from mailman.interfaces.usermanager import IUserManager
service = getUtility(ISubscriptionService) manager = getUtility(IUserManager)
# Find the user record for the user linked to this email address. anne = manager.get_user('anne@example.com') if anne is None: # not found
# Search for all of Anne's subscriptions on the security team, but ignore # any where she is a list admin or moderator. for member in service.find_members(anne.user_id, 'security-team@example.com', MemberRole.member): # Iterate over all of Anne's memberships on this mailing list.
I am asking this, because in order to successfully implement the dlists, we need to keep account of the unsubscribed users, so that we won
t send any unwanted emails to them. In the aforementioned Systers
schema, this is done by setting the 'deleted' flag to true.
Although you can easily tell whether someone is subscribed to a mailing list or not, you can't really tell if they were once subscribed but now are not. mm3 just doesn't keep a record of that.
Now, there are a couple of ways we could allow a plugin to know that. One thing to do is to add an event which gets triggered when an unsubscription occurs. Then your plugin could register interest in that event and record it in whatever local database it uses. That would be pretty easy to add.
Another way to do it would be to not actually unsubscribe the member, but instead to disable delivery of the member. It would have the same effect of inhibiting delivery of list posts, but it would keep the member record in the database. Each IMember has a "delivery status" flag which contains an enum value indicating whether delivery is enabled or disabled (the latter with various possible reasons).
If you used this approach, you'd have to amend the .find_members() code above to check member.delivery_status.
Cheers, -Barry
Thank you very much for the clarifications, Barry! Now everything is clear!
In regard to the aliases, based on you suggestions I will find a proper way to link the addresses (aliases) to a certain user hence solving the problem elegantly with the already existing 'resources'.
As for the latter problem, I still have something in mind. If we were to choose the
second option (the one which implies setting the flag "delivery_status" to the proper
value) does this not mean that we will have to keep the users preferences alive, without deleting them? I am thinking about a solution to avoid keeping the user
s
preferences, but please correct me if I am wrong. Could not we add a flag to the
'user' table (e.g: unsubscribed, deleted), flag that will hold the value 1 if the user
is unsubscribed and 0 otherwise. Although your solution will work as a wonder, if I
got everything wright, adding the flag to the 'user' table will save us some memory.
Do you think I should add that flag to the 'user' table, or should I just adapt the code so
that the "delivery_status" will be properly changed when a user is unsubscribed?
Thanks again,
Emanuel
From: Barry Warsaw <barry@list.org> To: Danci Emanuel <danci_emanuel@yahoo.com> Cc: mailman-developers@python.org Sent: Monday, June 25, 2012 9:39 PM Subject: Re: [Mailman-Developers] Questions in regard to the database operations
On Jun 25, 2012, at 08:02 AM, Danci Emanuel wrote:
I still want to ask you something. As far as I am aware, I also have to implement the aliases feature as Systers see it, meaning that a user, after gets registered can post messages to a mailing list from more than one address.
Ah, so this is totally different than "acceptable aliases" and the IAcceptableAliasSet interface. What I described earlier is a mailing list feature which lets you set up a posting address alias in your MTA.
For example, let's say you create a mailing list for your security team and you call it security-team@example.com. For convenience, you want to allow people to post to security@example.com and so you set up an alias in your MTA's configuration file (e.g. /etc/aliases) which points security -> security-team.
When people post to security@example.com, it gets forwarded to security-team@example.com, but Mailman will not see the list's posting address in the To header. Without security@example.com being added to the mailing list's acceptable_aliases, these posts will be rejected with an "implicit destination" error.
But none of that really applies to your use case. ;)
So, just to make sure, do you think that these addresses could be added directly to the address table and then all the addresses (aliases) linked to the same user? This - http://systers.org/systers-dev/doku.php/systers_database_in_postgresql?s[]=database is the current database schema implemented by Systes, so basically I am looking a solution to replace the 'alias' table.
Remember the model I described earlier, regarding addresses, users, and members? Using this model, you can register multiple address objects and link them to the same user. E.g. you could register all of the following:
anne@example.com aperson@example.com anne.x.person@example.com
(Let's assume too that all three have been validated.)
and link those addresses to the user record representing Anne Person. When Anne subscribes to a mailing list, such as security-team@example.com, she chooses one of those three addresses to subscribe using the 'member' role. This is the address that will receive postings to the list.
So if she subscribes anne@example.com, then when new messages are posted to the mailing list, only anne@example.com will receive copies.
However, Anne can *post* to the mailing list with any of her three validated and linked email addresses, and no further moderation approval is necessary. This is one of the big advantages of the mm3 model over the mm2 model. We now *know* that all three of those addresses are associated with Anne, so any of her addresses are allowed for posting. However, she will only receive copies of list posts to the addresses she's explicitly subscribed, IOW she won't receive three copies of list postings unless she wants to.
In summary, the mm3 model directly supports the Systers model, as I understand it. All the internal APIs are there to add additional addresses, verify them, link them to users, and subscribe them to mailing lists. All you have to work out is the social and procedural ways of getting those additional addresses into the system, verified, and linked to the user.
Furthermore, in regard to the user removal, if the address and the user records remain in the database, how can we know if a user has been unsubscribed from the list?
You know because there will be no member record linking any of the user's addresses to the mailing list. There are various ways using the internal API to check this. Probably the easiest is to use something like the following:
from zope.component import getUtility from mailman.interfaces.member import MemberRole from mailman.interfaces.subscriptions import ISubscriptionService from mailman.interfaces.usermanager import IUserManager
service = getUtility(ISubscriptionService) manager = getUtility(IUserManager)
# Find the user record for the user linked to this email address. anne = manager.get_user('anne@example.com') if anne is None: # not found
# Search for all of Anne's subscriptions on the security team, but ignore # any where she is a list admin or moderator. for member in service.find_members(anne.user_id, 'security-team@example.com', MemberRole.member): # Iterate over all of Anne's memberships on this mailing list.
I am asking this, because in order to successfully implement the dlists, we need to keep account of the unsubscribed users, so that we won
t send any unwanted emails to them. In the aforementioned Systers
schema, this is done by setting the 'deleted' flag to true.
Although you can easily tell whether someone is subscribed to a mailing list or not, you can't really tell if they were once subscribed but now are not. mm3 just doesn't keep a record of that.
Now, there are a couple of ways we could allow a plugin to know that. One thing to do is to add an event which gets triggered when an unsubscription occurs. Then your plugin could register interest in that event and record it in whatever local database it uses. That would be pretty easy to add.
Another way to do it would be to not actually unsubscribe the member, but instead to disable delivery of the member. It would have the same effect of inhibiting delivery of list posts, but it would keep the member record in the database. Each IMember has a "delivery status" flag which contains an enum value indicating whether delivery is enabled or disabled (the latter with various possible reasons).
If you used this approach, you'd have to amend the .find_members() code above to check member.delivery_status.
Cheers, -Barry
On Jun 25, 2012, at 03:30 PM, Danci Emanuel wrote:
As for the latter problem, I still have something in mind. If we were to choose the second option (the one which implies setting the flag "delivery_status" to the proper value) does this not mean that we will have to keep the user`s preferences alive, without deleting them?
Here's how preferences work.
There is an IPreferences interface which describes the kind of things that are "preferences". Members, users, and addresses all can have a pointer to a preferences record. There are also some system default preference values. When we look up a preference on a member, the search order goes like this:
- member
- address
- user
- system
meaning, if the member doesn't have a preference set, we fall back to the subscribed address, then to the user linked to that address, and finally the system default. At each level, the object only has a preference record if explicitly created. Usually, they don't have preferences (meaning the system default takes over).
When a member record is deleted, only that member's preferences are deleted. If either the address and user associated with that member has a preferences record, it *has* to stick around because an address or user can be subscribed to many mailing lists. E.g. You could decide that you want all your postings to be acknowledged. You'd set that on your user record and then all your subscriptions would automatically inherit it.
I don't see much savings in trying not to delete a member's preferences when being unsubscribed. It's just a row in the database, and probably not a very big one at that. Plus, it'll usually be empty anyway.
Cheers, -Barry
Thanks for all the explanations, Barry! Now everything is much more clear!
Indeed, is not necessary for us to save every bit of space, so I will go with the second option that you presented initially, by setting the "delivery_status" flag to the appropriate value.
Thanks again for you help! Emanuel
From: Barry Warsaw <barry@list.org> To: Danci Emanuel <danci_emanuel@yahoo.com> Cc: "mailman-developers@python.org" <mailman-developers@python.org> Sent: Tuesday, June 26, 2012 3:54 AM Subject: Re: [Mailman-Developers] Questions in regard to the database operations
On Jun 25, 2012, at 03:30 PM, Danci Emanuel wrote:
As for the latter problem, I still have something in mind. If we were to choose the second option (the one which implies setting the flag "delivery_status" to the proper value) does this not mean that we will have to keep the user`s preferences alive, without deleting them?
Here's how preferences work.
There is an IPreferences interface which describes the kind of things that are "preferences". Members, users, and addresses all can have a pointer to a preferences record. There are also some system default preference values. When we look up a preference on a member, the search order goes like this:
- member
- address
- user
- system
meaning, if the member doesn't have a preference set, we fall back to the subscribed address, then to the user linked to that address, and finally the system default. At each level, the object only has a preference record if explicitly created. Usually, they don't have preferences (meaning the system default takes over).
When a member record is deleted, only that member's preferences are deleted. If either the address and user associated with that member has a preferences record, it *has* to stick around because an address or user can be subscribed to many mailing lists. E.g. You could decide that you want all your postings to be acknowledged. You'd set that on your user record and then all your subscriptions would automatically inherit it.
I don't see much savings in trying not to delete a member's preferences when being unsubscribed. It's just a row in the database, and probably not a very big one at that. Plus, it'll usually be empty anyway.
Cheers, -Barry
On 26 Jun 2012, at 01:54, Barry Warsaw wrote:
On Jun 25, 2012, at 03:30 PM, Danci Emanuel wrote:
As for the latter problem, I still have something in mind. If we were to choose the second option (the one which implies setting the flag "delivery_status" to the proper value) does this not mean that we will have to keep the user`s preferences alive, without deleting them?
Here's how preferences work.
There is an IPreferences interface which describes the kind of things that are "preferences". Members, users, and addresses all can have a pointer to a preferences record. There are also some system default preference values. When we look up a preference on a member, the search order goes like this:
- member
- address
- user
- system
Do you mean "membership"? If I (a user) am a member of a list, then I have a membership record. But, the member is the user. If the term "member record" is used to describe a membership record, things are going to get confusing, I think. Or, perhaps it's a subscription (but still not a subscriber) record?
To be more explicit, I'd expect a "members" table to simply list references to users.
Whereas a "subscriptions" or "memberships" table would include references to members, as well as information about the subscription (preferred mailing address, start date, permission type, subject line munging, etc, etc).
My guess is that the link to users is implied, though?
meaning, if the member doesn't have a preference set, we fall back to the subscribed address, then to the user linked to that address, and finally the system default. At each level, the object only has a preference record if explicitly created. Usually, they don't have preferences (meaning the system default takes over).
When a member record is deleted, only that member's preferences are deleted. If either the address and user associated with that member has a preferences record, it *has* to stick around because an address or user can be subscribed to many mailing lists. E.g. You could decide that you want all your postings to be acknowledged. You'd set that on your user record and then all your subscriptions would automatically inherit it.
I don't see much savings in trying not to delete a member's preferences when being unsubscribed. It's just a row in the database, and probably not a very big one at that. Plus, it'll usually be empty anyway.
Cheers, -Barry
Mailman-Developers mailing list Mailman-Developers@python.org http://mail.python.org/mailman/listinfo/mailman-developers Mailman FAQ: http://wiki.list.org/x/AgA3 Searchable Archives: http://www.mail-archive.com/mailman-developers%40python.org/ Unsubscribe: http://mail.python.org/mailman/options/mailman-developers/iane%40sussex.ac.u...
Security Policy: http://wiki.list.org/x/QIA9
-- Ian Eiloart Postmaster, University of Sussex +44 (0) 1273 87-3148
Hi Barry!
I am back with some questions in regard to the aliases. After a persons becomes a member of a particular list, subscribing with its primary email address (the address at which he/she will receive the replies), how can that person add the additional email addresses (aliases) to the database?
Thanks, Emanuel
Hi again Danci. Keep the great questions coming! :)
On Jun 27, 2012, at 08:19 AM, Danci Emanuel wrote:
I am back with some questions in regard to the aliases. After a persons becomes a member of a particular list, subscribing with its primary email address (the address at which he/she will receive the replies), how can that person add the additional email addresses (aliases) to the database?
Yes. Subscriptions (i.e. memberships) are completely separate from addresses, which again are separate from users. Users and addresses can each be added separately at any time. Many of the doctests in src/mailman/model/docs illustrate this. In mm3 terminology, these separately added users and addresses are "unlinked".
Usually addresses and users are linked, and an address can point to exactly one user, while users can point to many addresses.
Members link a mailing list to either a user or an address, but not both. A user can be linked only if it has a preferred address, in which case message delivery will be to that preferred address. This allows a user to subscribe to many mailing lists with their preferred address, and then change their preferred address in one swoop to change all of their deliveries.
So, to answer your second question, the way a user adds additional addresses is fairly simple. Given an IUser object, you can just call the .register() method to both register a new email and to link that to the user. The address will be unverified though, so in order to accept postings from that new email, it has to be verified (which through the internal API is just setting a flag).
Does that answer the question?
Cheers, -Barry
On Jun 27, 2012, at 10:23 AM, Ian Eiloart wrote:
There is an IPreferences interface which describes the kind of things that are "preferences". Members, users, and addresses all can have a pointer to a preferences record. There are also some system default preference values. When we look up a preference on a member, the search order goes like this:
- member
- address
- user
- system
Do you mean "membership"? If I (a user) am a member of a list, then I have a membership record.
It means that you-the-user or you-an-address-you-control is linked to the mailing list through the member record.
But, the member is the user.
Not really. It's perfectly valid for a member record to link a mailing list to an address which is not associated with any user record. Members link addresses to mailing lists. The shortcut of linking a user to a mailing list is only valid if that user has a preferred address.
If the term "member record" is used to describe a membership record, things are going to get confusing, I think. Or, perhaps it's a subscription (but still not a subscriber) record?
Member records represent subscriptions to mailing lists as a recipient of messages sent to the list. But they also represent other mailing list roles, such as list-owners and list-moderators. So let's say anne@example.com is a member of a mailing list, and the list owner. Her address record will be linked to two member records, one with role "member" and the other with role "owner".
This might seem confusing at first, but I've lived with this terminology for a long time, after many clarifying steps, and I think this works the best. Once you understand the relationship of users, addresses, members, and mailing lists, it shouldn't be confusing.
To be more explicit, I'd expect a "members" table to simply list references to users.
It can't because of the types of relationships we want to support, such as:
- A user subscribing multiple addresses to a mailing list.
- A user serving more than one role for a mailing list.
- Subscribing non-user addresses to mailing list, e.g. mailbots
- Subscribing a user's preferred address, which can easily be changed system-wide.
Memberships link addresses to mailing lists. They *can* link a user to a mailing list, but only if that user has a preferred address.
Whereas a "subscriptions" or "memberships" table would include references to members, as well as information about the subscription (preferred mailing address, start date, permission type, subject line munging, etc, etc).
I'm not sure what a "member" would be if not essentially equivalent to a subscription. IOW, when you say "expect a members table to simply list references to users", I don't see how that's useful as an independent concept.
My guess is that the link to users is implied, though?
In the case where a member links an address to a mailing list, and that address is linked to a user, then you're correct. :).
Through queries (hidden behind other interfaces, such as the IRoster) we can always find the list of users that are subscribed to a mailing list, although of course user-less addresses won't show up there.
Stephen did a pretty good job of explaining all this very succinctly. A diagram would help, but I suck at ascii art. ;)
http://packages.python.org/mailman/src/mailman/docs/8-miles-high.html#user-m...
Contributions welcome of course!
Cheers, -Barry
On 27 Jun 2012, at 23:57, Barry Warsaw wrote:
On Jun 27, 2012, at 10:23 AM, Ian Eiloart wrote:
There is an IPreferences interface which describes the kind of things that are "preferences". Members, users, and addresses all can have a pointer to a preferences record. There are also some system default preference values. When we look up a preference on a member, the search order goes like this:
- member
- address
- user
- system
Do you mean "membership"? If I (a user) am a member of a list, then I have a membership record.
It means that you-the-user or you-an-address-you-control is linked to the mailing list through the member record.
I guess it's too late for me to be talking about this because it's all coded. But, if there's a choice in the UI, I just think that in the real world, we'd talk about "members" of an organisation being people, or other organisations. It might be that the only information you have about a member is their email address, so that works too.
Then we'd talk about "membership" or "subscription" records, which would tell you who the member was, and various things about their membership (like when it started, communication preferences, and so on). So, I just think "membership" would be a more natural description of that record, and therefore slightly easier for newcomers to understand.
But, the member is the user.
Not really. It's perfectly valid for a member record to link a mailing list to an address which is not associated with any user record. Members link addresses to mailing lists. The shortcut of linking a user to a mailing list is only valid if that user has a preferred address.
If the term "member record" is used to describe a membership record, things are going to get confusing, I think. Or, perhaps it's a subscription (but still not a subscriber) record?
Member records represent subscriptions to mailing lists as a recipient of messages sent to the list. But they also represent other mailing list roles, such as list-owners and list-moderators. So let's say anne@example.com is a member of a mailing list, and the list owner. Her address record will be linked to two member records, one with role "member" and the other with role "owner".
This might seem confusing at first, but I've lived with this terminology for a long time, after many clarifying steps, and I think this works the best. Once you understand the relationship of users, addresses, members, and mailing lists, it shouldn't be confusing.
To be more explicit, I'd expect a "members" table to simply list references to users.
It can't because of the types of relationships we want to support, such as:
- A user subscribing multiple addresses to a mailing list.
- A user serving more than one role for a mailing list.
- Subscribing non-user addresses to mailing list, e.g. mailbots
- Subscribing a user's preferred address, which can easily be changed system-wide.
Memberships link addresses to mailing lists. They *can* link a user to a mailing list, but only if that user has a preferred address.
Whereas a "subscriptions" or "memberships" table would include references to members, as well as information about the subscription (preferred mailing address, start date, permission type, subject line munging, etc, etc).
I'm not sure what a "member" would be if not essentially equivalent to a subscription. IOW, when you say "expect a members table to simply list references to users", I don't see how that's useful as an independent concept.
My guess is that the link to users is implied, though?
In the case where a member links an address to a mailing list, and that address is linked to a user, then you're correct. :).
Through queries (hidden behind other interfaces, such as the IRoster) we can always find the list of users that are subscribed to a mailing list, although of course user-less addresses won't show up there.
Stephen did a pretty good job of explaining all this very succinctly. A diagram would help, but I suck at ascii art. ;)
http://packages.python.org/mailman/src/mailman/docs/8-miles-high.html#user-m...
Contributions welcome of course!
Cheers, -Barry
-- Ian Eiloart Postmaster, University of Sussex +44 (0) 1273 87-3148
Hi Barry!
Yes, in terms of how the back-end works, it answers it. But, I am interested also in the following aspect. Lets say that a users subscribes to a list with his/her preferred address. Afterwards, how can that user, who does not have access to the back end of the mailing list, add other email addresses from which he/she can send emails to the list? This is related strictly how a user would do it, not necessarily how the code works in this case.
Thanks, Emanuel
From: Barry Warsaw <barry@list.org> To: Danci Emanuel <danci_emanuel@yahoo.com> Cc: "mailman-developers@python.org" <mailman-developers@python.org> Sent: Thursday, June 28, 2012 1:43 AM Subject: Re: [Mailman-Developers] Questions in regard to the database operations
Hi again Danci. Keep the great questions coming! :)
On Jun 27, 2012, at 08:19 AM, Danci Emanuel wrote:
I am back with some questions in regard to the aliases. After a persons becomes a member of a particular list, subscribing with its primary email address (the address at which he/she will receive the replies), how can that person add the additional email addresses (aliases) to the database?
Yes. Subscriptions (i.e. memberships) are completely separate from addresses, which again are separate from users. Users and addresses can each be added separately at any time. Many of the doctests in src/mailman/model/docs illustrate this. In mm3 terminology, these separately added users and addresses are "unlinked".
Usually addresses and users are linked, and an address can point to exactly one user, while users can point to many addresses.
Members link a mailing list to either a user or an address, but not both. A user can be linked only if it has a preferred address, in which case message delivery will be to that preferred address. This allows a user to subscribe to many mailing lists with their preferred address, and then change their preferred address in one swoop to change all of their deliveries.
So, to answer your second question, the way a user adds additional addresses is fairly simple. Given an IUser object, you can just call the .register() method to both register a new email and to link that to the user. The address will be unverified though, so in order to accept postings from that new email, it has to be verified (which through the internal API is just setting a flag).
Does that answer the question?
Cheers, -Barry
On Jun 28, 2012, at 04:17 PM, Danci Emanuel wrote:
Yes, in terms of how the back-end works, it answers it. But, I am interested also in the following aspect. Lets say that a users subscribes to a list with his/her preferred address. Afterwards, how can that user, who does not have access to the back end of the mailing list, add other email addresses from which he/she can send emails to the list? This is related strictly how a user would do it, not necessarily how the code works in this case.
There are two ways that I see. The first would be to use Postorius (i.e. the web ui) to log in and then add a new email address to your account. Postorius would then take care of making the right calls to the REST API, and initiating the core to do the email validation. Because you logged in, Postorius would know your user id so it would know what user to link your new address to.
The other way to do this would be through the email API. This is not yet implemented because we haven't really worked out the exact protocol for adding a new address to an existing account. You probably have to send the "add email" command from an address that's already known and validated to Mailman. Then, you could probably send a password in cleartext :( or gpg sign your message to prove you own the account, and thus the user id to add the address to. Alternatively, we would have to send a confirmation message to both addresses, and only if we get positive responses to both would be validate the new address and link it to the original address.
-Barry
[1] We probably need to define a site-wide email command alias.
participants (4)
-
Barry Warsaw
-
Barry Warsaw
-
Danci Emanuel
-
Ian Eiloart