~systers/systers/stable

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
# A DlistMembership extends the regular member adaptor to back certain
# attributes with a database.
# Additionally, this implements support for loose matching.
#
# original code by Ellen, separated into child class by Andy


from OldStyleMemberships import OldStyleMemberships as oldm
from Mailman import DlistUtils
from Mailman import mm_cfg
from Mailman.Logging.Syslog import syslog
from Mailman import MemberAdaptor

ISREGULAR = 1
ISDIGEST = 2


class DlistMemberships(oldm):

    def __init__(self, mlist):
        oldm.__init__(self, mlist)
        self.__mlist = mlist

    def __get_cp_member(self, member):
        # First try strict matching
        result, type = self.__get_cp_member_strict(member)
        if result:
            return result, type
        # Now try loose email matching if this list permits it
        try:
            if self.__mlist.loose_email_matching:
                return self.__get_cp_member_loose(member)
        except:
            pass
        return None, None

    # Name changed from __get_cp_member by Ellen
    def __get_cp_member_strict(self, member):
        """Does the member name exactly match the subscribed name?"""
        lcmember = member.lower()
        missing = []
        val = self.__mlist.members.get(lcmember, missing)
        if val is not missing:
            if isinstance(val, StringType):
                return val, ISREGULAR
            else:
                return lcmember, ISREGULAR
        val = self.__mlist.digest_members.get(lcmember, missing)
        if val is not missing:
            if isinstance(val, StringType):
                return val, ISDIGEST
            else:
                return lcmember, ISDIGEST
        return None, None

    def __get_cp_member_loose(self, member):
        """Check if the provided member email address loosely matches any list membership.
        This should only be called if the list permits loose matching.
        We could save time in the future by adding matches to the alias database."""
        lcmember = member.lower()
        try:
            at_split = lcmember.split('@')
            if len(at_split) != 2:
                return None, None
            local = at_split[0]
            domain = at_split[1]

            # Check if member argument is narrower than actual membership;
            # e.g., robin@eng.sun.com vs. robin@sun.com
            domain_split = domain.split('.')[1:]
            while len(domain_split) > 1:
                substring = local + '@' + string.join(domain_split, '.')
                result, type = self.__get_cp_member_strict(substring)
                if result:
                    return result, type
                domain_split = domain_split[1:]

            # e.g., robin@sun.com vs. robin@eng.sun.com
            regstring = local + '@.*\.' + domain
            try:
                regexp = re.compile(regstring)
            except:
                syslog('info', 'OldStyleMemberships.__get_cp_member_loose: error in re.compile')
                syslog('error', 'OldStyleMemberships.__get_cp_member_loose: error in re.compile')
            for mem in self.__mlist.members.keys():
                if regexp.match(mem):
                    val = self.__mlist.members.get(mem)
                    if isinstance(val, StringType):
                        return val, ISREGULAR
                    else:
                        return mem, ISREGULAR
            for mem in self.__mlist.digest_members.keys():
                if regexp.match(mem):
                    val = self.__mlist.members.get(mem)
                    if isinstance(val, StringType):
                        return val, ISREGULAR
                    else:
                        return mem, ISREGULAR
        # Email address in bad format
        except Error, e:
            syslog('info', 'OldStyleMemberships.__get_cp_member_loose: Error in OldStyleMemberships.__get_cp_member_loose')
            syslog('info', e)
            pass

        return None, None

    # override to strip whitespace off passwords
    def authenticateMember(self, member, response):
        secret = self.getMemberPassword(member).strip()
        if secret == response.strip():
            return secret
        return 0

    def addNewMember(self, member, **kws):
        if kws.has_key("affect_dlist_database"):
            affect_dlist_database = kws["affect_dlist_database"]
            del kws["affect_dlist_database"]
        else:
            affect_dlist_database = True
        if kws.has_key("digest"):
            digest = kws["digest"]
        else:
            digest = False
        oldm.addNewMember(self, member, **kws)
        if affect_dlist_database:
            if DlistUtils.enabled(self.__mlist):
                DlistUtils.subscribeToList(self.__mlist, member)
                if digest:
                    DlistUtils.setDigest(self.__mlist, member, 1)

    def removeMember(self, member, affect_dlist_database=1):
        oldm.removeMember(self, member)
        memberkey = member.lower()
        if affect_dlist_database and DlistUtils.enabled(self.__mlist):
            DlistUtils.unsubscribeFromList(self.__mlist, memberkey)

    def changeMemberAddress(self, member, newaddress, nodelete=1):
        oldm.changeMemberAddress(self, member, newaddress, nodelete)
        memberkey = member.lower()
        if DlistUtils.enabled(self.__mlist):
            DlistUtils.changeAddress(self.__mlist, memberkey, newaddress)

    def setDeliveryStatus(self, member, status):
        oldm.setDeliveryStatus(self, member, status)
        memberkey = member.lower()
        enabled = (status == MemberAdaptor.ENABLED)
        if DlistUtils.enabled(self.__mlist):
            DlistUtils.setDisable(self.__mlist, member, (not enabled))

    def setMemberOption(self, member, flag, value):
        oldm.setMemberOption(self, member, flag, value)
        if flag == mm_cfg.Digests and DlistUtils.enabled(self.__mlist):
            DlistUtils.setDigest(self.__mlist, member, value)