1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
==========
Moderation
==========
Posts by members and non-members are subject to moderation checks during
incoming processing. Different situations can cause such posts to be held for
moderator approval.
>>> mlist = create_list('test@example.com')
Members and nonmembers have a *moderation action* which can shortcut the
normal moderation checks. The built-in chain does just a few checks first,
such as seeing if the message has a matching `Approved:` header, or if the
emergency flag has been set on the mailing list, or whether a mail loop has
been detected.
After those, the moderation action for the sender is checked. Members
generally have a `defer` action, meaning the normal moderation checks are
done, but it is also common for first-time posters to have a `hold` action,
meaning that their messages are held for moderator approval for a while.
Nonmembers almost always have a `hold` action, though some mailing lists may
choose to set this default action to `discard`, meaning their posts would be
immediately thrown away.
XXX What about default nonmember actions when the poster has not been
registered as a nonmember?
Member moderation
=================
Posts by list members are moderated if the member's moderation action is not
deferred. The default setting for the moderation action of new members is
determined by the mailing list's settings. By default, a mailing list is not
set to moderate new member postings.
>>> from mailman.app.membership import add_member
>>> from mailman.interfaces.member import DeliveryMode
>>> member = add_member(mlist, 'anne@example.com', 'Anne', 'aaa',
... DeliveryMode.regular, 'en')
>>> member
<Member: Anne <anne@example.com> on test@example.com as MemberRole.member>
>>> print member.moderation_action
Action.defer
In order to find out whether the message is held or accepted, we can subscribe
to Zope events that are triggered on each case.
::
>>> from mailman.chains.base import ChainNotification
>>> def on_chain(event):
... if isinstance(event, ChainNotification):
... print event
... print event.chain
... print 'Subject:', event.msg['subject']
... print 'Hits:'
... for hit in event.msgdata.get('rule_hits', []):
... print ' ', hit
... print 'Misses:'
... for miss in event.msgdata.get('rule_misses', []):
... print ' ', miss
>>> import zope.event
>>> zope.event.subscribers.append(on_chain)
Anne's post to the mailing list runs through the incoming runner's default
built-in chain. No rules hit and so the message is accepted.
::
>>> msg = message_from_string("""\
... From: anne@example.com
... To: test@example.com
... Subject: aardvark
...
... This is a test.
... """)
>>> from mailman.core.chains import process
>>> process(mlist, msg, {}, 'built-in')
<mailman.chains.accept.AcceptNotification ...>
<mailman.chains.accept.AcceptChain ...>
Subject: aardvark
Hits:
Misses:
approved
emergency
loop
moderation
administrivia
implicit-dest
max-recipients
max-size
news-moderation
no-subject
suspicious-header
However, when Anne's moderation action is set to `hold`, her post is held for
moderator approval.
::
>>> from mailman.interfaces.action import Action
>>> member.moderation_action = Action.hold
>>> msg = message_from_string("""\
... From: anne@example.com
... To: test@example.com
... Subject: badger
...
... This is a test.
... """)
>>> process(mlist, msg, {}, 'built-in')
<mailman.chains.hold.HoldNotification ...>
<mailman.chains.hold.HoldChain ...>
Subject: badger
Hits:
moderation
Misses:
approved
emergency
loop
The list's member moderation action can also be set to `discard`...
::
>>> member.moderation_action = Action.discard
>>> msg = message_from_string("""\
... From: anne@example.com
... To: test@example.com
... Subject: cougar
...
... This is a test.
... """)
>>> process(mlist, msg, {}, 'built-in')
<mailman.chains.discard.DiscardNotification ...>
<mailman.chains.discard.DiscardChain ...>
Subject: cougar
Hits:
moderation
Misses:
approved
emergency
loop
... or `reject`.
>>> member.moderation_action = Action.reject
>>> msg = message_from_string("""\
... From: anne@example.com
... To: test@example.com
... Subject: dingo
...
... This is a test.
... """)
>>> process(mlist, msg, {}, 'built-in')
<mailman.chains.reject.RejectNotification ...>
<mailman.chains.reject.RejectChain ...>
Subject: dingo
Hits:
moderation
Misses:
approved
emergency
loop
Nonmembers
==========
XXX
.. Clean up
>>> zope.event.subscribers.remove(on_chain)
|