1# Copyright (C) 2002-2018 by the Free Software Foundation, Inc. 2# 3# This program is free software; you can redistribute it and/or 4# modify it under the terms of the GNU General Public License 5# as published by the Free Software Foundation; either version 2 6# of the License, or (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program; if not, write to the Free Software 15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 17""" 18 subscribe [password] [digest|nodigest] [address=<address>] 19 Subscribe to this mailing list. Your password must be given to 20 unsubscribe or change your options, but if you omit the password, one 21 will be generated for you. You may be periodically reminded of your 22 password. 23 24 The next argument may be either: `nodigest' or `digest' (no quotes!). 25 If you wish to subscribe an address other than the address you sent 26 this request from, you may specify `address=<address>' (no brackets 27 around the email address, and no quotes!) 28""" 29 30from email.Utils import parseaddr 31from email.Header import decode_header, make_header 32 33from Mailman import Utils 34from Mailman import Errors 35from Mailman.UserDesc import UserDesc 36from Mailman.i18n import _ 37 38STOP = 1 39 40 41 42def gethelp(mlist): 43 return _(__doc__) 44 45 46 47def process(res, args): 48 mlist = res.mlist 49 digest = None 50 password = None 51 address = None 52 realname = None 53 # Parse the args 54 argnum = 0 55 for arg in args: 56 if arg.lower().startswith('address='): 57 address = arg[8:] 58 elif argnum == 0: 59 password = arg 60 elif argnum == 1: 61 if arg.lower() not in ('digest', 'nodigest'): 62 res.results.append(_('Bad digest specifier: %(arg)s')) 63 return STOP 64 if arg.lower() == 'digest': 65 digest = 1 66 else: 67 digest = 0 68 else: 69 res.results.append(_('Usage:')) 70 res.results.append(gethelp(mlist)) 71 return STOP 72 argnum += 1 73 # Fix the password/digest issue 74 if (digest is None 75 and password and password.lower() in ('digest', 'nodigest')): 76 if password.lower() == 'digest': 77 digest = 1 78 else: 79 digest = 0 80 password = None 81 # Fill in empty defaults 82 if digest is None: 83 digest = mlist.digest_is_default 84 if password is None: 85 password = Utils.MakeRandomPassword() 86 if address is None: 87 realname, address = parseaddr(res.msg['from']) 88 if not address: 89 # Fall back to the sender address 90 address = res.msg.get_sender() 91 if not address: 92 res.results.append(_('No valid address found to subscribe')) 93 return STOP 94 # Watch for encoded names 95 try: 96 h = make_header(decode_header(realname)) 97 # BAW: in Python 2.2, use just unicode(h) 98 realname = h.__unicode__() 99 except UnicodeError: 100 realname = u'' 101 # Coerce to byte string if uh contains only ascii 102 try: 103 realname = realname.encode('us-ascii') 104 except UnicodeError: 105 pass 106 # Create the UserDesc record and do a non-approved subscription 107 listowner = mlist.GetOwnerEmail() 108 userdesc = UserDesc(address, realname, password, digest) 109 remote = res.msg.get_sender() 110 try: 111 mlist.AddMember(userdesc, remote) 112 except Errors.MembershipIsBanned: 113 res.results.append(_("""\ 114The email address you supplied is banned from this mailing list. 115If you think this restriction is erroneous, please contact the list 116owners at %(listowner)s.""")) 117 return STOP 118 except Errors.MMBadEmailError: 119 res.results.append(_("""\ 120Mailman won't accept the given email address as a valid address. 121(E.g. it must have an @ in it.)""")) 122 return STOP 123 except Errors.MMHostileAddress: 124 res.results.append(_("""\ 125Your subscription is not allowed because 126the email address you gave is insecure.""")) 127 return STOP 128 except Errors.MMAlreadyAMember: 129 res.results.append(_('You are already subscribed!')) 130 return STOP 131 except Errors.MMAlreadyPending: 132 res.results.append( 133 _('You already have a subscription pending confirmation')) 134 return STOP 135 except Errors.MMCantDigestError: 136 res.results.append( 137 _('No one can subscribe to the digest of this list!')) 138 return STOP 139 except Errors.MMMustDigestError: 140 res.results.append(_('This list only supports digest subscriptions!')) 141 return STOP 142 except Errors.MMSubscribeNeedsConfirmation: 143 # We don't need to respond /and/ send a confirmation message. 144 res.respond = 0 145 except Errors.MMNeedApproval: 146 res.results.append(_("""\ 147Your subscription request has been forwarded to the list administrator 148at %(listowner)s for review.""")) 149 else: 150 # Everything is a-ok 151 res.results.append(_('Subscription request succeeded.')) 152