~barry/mailman/events-and-web

« back to all changes in this revision

Viewing changes to src/mailman/model/bans.py

  • Committer: Barry Warsaw
  • Date: 2012-10-16 22:40:12 UTC
  • Revision ID: barry@list.org-20121016224012-xxrd5zgkwdrmh9y4
Database
--------
 * The `ban` table now uses list-ids to cross-reference the mailing list,
   since these cannot change even if the mailing list is moved or renamed.

Interfaces
----------
 * The `IBanManager` is no longer a global utility.  Instead, you adapt an
   `IMailingList` to an `IBanManager` to manage the bans for a specific
   mailing list.  To manage the global bans, adapt ``None``.

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
 
43
43
    id = Int(primary=True)
44
44
    email = Unicode()
45
 
    mailing_list = Unicode()
 
45
    list_id = Unicode()
46
46
 
47
 
    def __init__(self, email, mailing_list):
 
47
    def __init__(self, email, list_id):
48
48
        super(Ban, self).__init__()
49
49
        self.email = email
50
 
        self.mailing_list = mailing_list
 
50
        self.list_id = list_id
51
51
 
52
52
 
53
53
 
55
55
class BanManager:
56
56
    """See `IBanManager`."""
57
57
 
 
58
    def __init__(self, mailing_list=None):
 
59
        self._list_id = (None if mailing_list is None
 
60
                         else mailing_list.list_id)
 
61
 
58
62
    @dbconnection
59
 
    def ban(self, store, email, mailing_list=None):
 
63
    def ban(self, store, email):
60
64
        """See `IBanManager`."""
61
 
        bans = store.find(Ban, email=email, mailing_list=mailing_list)
 
65
        bans = store.find(Ban, email=email, list_id=self._list_id)
62
66
        if bans.count() == 0:
63
 
            ban = Ban(email, mailing_list)
 
67
            ban = Ban(email, self._list_id)
64
68
            store.add(ban)
65
69
 
66
70
    @dbconnection
67
 
    def unban(self, store, email, mailing_list=None):
 
71
    def unban(self, store, email):
68
72
        """See `IBanManager`."""
69
 
        ban = store.find(Ban, email=email, mailing_list=mailing_list).one()
 
73
        ban = store.find(Ban, email=email, list_id=self._list_id).one()
70
74
        if ban is not None:
71
75
            store.remove(ban)
72
76
 
73
77
    @dbconnection
74
 
    def is_banned(self, store, email, mailing_list=None):
 
78
    def is_banned(self, store, email):
75
79
        """See `IBanManager`."""
76
 
        # A specific mailing list ban is being checked, however the email
77
 
        # address could be banned specifically, or globally.
78
 
        if mailing_list is not None:
79
 
            # Try specific bans first.
80
 
            bans = store.find(Ban, email=email, mailing_list=mailing_list)
 
80
        list_id = self._list_id
 
81
        if list_id is None:
 
82
            # The client is asking for global bans.  Look up bans on the
 
83
            # specific email address first.
 
84
            bans = store.find(Ban, email=email, list_id=None)
 
85
            if bans.count() > 0:
 
86
                return True
 
87
            # And now look for global pattern bans.
 
88
            bans = store.find(Ban, list_id=None)
 
89
            for ban in bans:
 
90
                if (ban.email.startswith('^') and
 
91
                    re.match(ban.email, email, re.IGNORECASE) is not None):
 
92
                    return True
 
93
        else:
 
94
            # This is a list-specific ban.
 
95
            bans = store.find(Ban, email=email, list_id=list_id)
81
96
            if bans.count() > 0:
82
97
                return True
83
98
            # Try global bans next.
84
 
            bans = store.find(Ban, email=email, mailing_list=None)
 
99
            bans = store.find(Ban, email=email, list_id=None)
85
100
            if bans.count() > 0:
86
101
                return True
87
102
            # Now try specific mailing list bans, but with a pattern.
88
 
            bans = store.find(Ban, mailing_list=mailing_list)
 
103
            bans = store.find(Ban, list_id=list_id)
89
104
            for ban in bans:
90
105
                if (ban.email.startswith('^') and
91
106
                    re.match(ban.email, email, re.IGNORECASE) is not None):
92
107
                    return True
93
108
            # And now try global pattern bans.
94
 
            bans = store.find(Ban, mailing_list=None)
95
 
            for ban in bans:
96
 
                if (ban.email.startswith('^') and
97
 
                    re.match(ban.email, email, re.IGNORECASE) is not None):
98
 
                    return True
99
 
        else:
100
 
            # The client is asking for global bans.  Look up bans on the
101
 
            # specific email address first.
102
 
            bans = store.find(Ban, email=email, mailing_list=None)
103
 
            if bans.count() > 0:
104
 
                return True
105
 
            # And now look for global pattern bans.
106
 
            bans = store.find(Ban, mailing_list=None)
 
109
            bans = store.find(Ban, list_id=None)
107
110
            for ban in bans:
108
111
                if (ban.email.startswith('^') and
109
112
                    re.match(ban.email, email, re.IGNORECASE) is not None):