1# Copyright (C) 2007-2020 by the Free Software Foundation, Inc.
2#
3# This file is part of GNU Mailman.
4#
5# GNU Mailman is free software: you can redistribute it and/or modify it under
6# the terms of the GNU General Public License as published by the Free
7# Software Foundation, either version 3 of the License, or (at your option)
8# any later version.
9#
10# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13# more details.
14#
15# You should have received a copy of the GNU General Public License along with
16# GNU Mailman.  If not, see <https://www.gnu.org/licenses/>.
17
18"""Interfaces for the pending database.
19
20The pending database contains events that must be confirmed by the user.  It
21maps these events to a unique hash that can be used as a token for end user
22confirmation.
23"""
24
25from public import public
26from zope.interface import Attribute, Interface
27
28
29@public
30class IPendable(Interface):
31    """A pendable object."""
32
33    PEND_TYPE = Attribute(
34        """The type of this pendable.
35
36        Subclasses must define this attribute, and it must be a unique string;
37        it's used to efficiently search for all pendables of the given type.
38        The PEND_TYPE "type" is reserved.
39        """)
40
41    def keys():
42        """The keys of the pending event data, all of which are strings."""
43
44    def values():
45        """The values of the pending event data, all of which are strings."""
46
47    def items():
48        """The key/value pairs of the pending event data.
49
50        Both the keys and values must be strings.
51        """
52
53
54@public
55class IPended(Interface):
56    """A pended event, tied to a token."""
57
58    token = Attribute("""The pended token.""")
59
60    expiration_date = Attribute("""The expiration date of the pended event.""")
61
62
63@public
64class IPendedKeyValue(Interface):
65    """A pended key/value pair."""
66
67    key = Attribute("""The pended key.""")
68
69    value = Attribute("""The pended value.""")
70
71
72@public
73class IPendings(Interface):
74    """Interface to pending database."""
75
76    def add(pendable, lifetime=None):
77        """Create a new entry in the pending database, returning a token.
78
79        :param pendable: The IPendable instance to add.
80        :param lifetime: The amount of time, as a `datetime.timedelta` that
81            the pended item should remain in the database.  When None is
82            given, a system default maximum lifetime is used.
83        :return: A token string for inclusion in urls and email confirmations.
84        """
85
86    def confirm(token, *, expunge=True):
87        """Return the IPendable matching the token.
88
89        :param token: The token string for the IPendable given by the `.add()`
90            method, or None if there is no record associated with the token.
91        :param expunge: A flag indicating whether the pendable record should
92            also be removed from the database or not.
93        :return: The matching IPendable or None if no match was found.
94        """
95
96    def evict():
97        """Remove all pended items whose lifetime has expired."""
98
99    def find(mlist=None, pend_type=None, confirm=True):
100        """Search for the pendables matching the given criteria.
101
102        :param mlist: The mailing list object that the pendables must be
103            related to, or None.  The default returns all pendables regardless
104            of which mailing list they are related to.
105        :type mlist: IMailingList or None.
106        :param pend_type: The type of the pendables that are looked for, or
107            None.  This corresponds to the `PEND_TYPE` attribute.  The default
108            returns all pending types.
109        :param confirm: A flag indicating whether the found pendings should be
110            "confirmed" or not.  See ``confirm()`` for details.
111        :return: An iterator over 2-tuples of the form (token, pendable).
112            When ``confirm`` is False, ``pendable`` is None.
113        """
114
115    def __iter__():
116        """An iterator over all pendables.
117
118        Each element is a 2-tuple of the form (token, dict).
119        """
120
121    count = Attribute('The number of pendables in the pendings database.')
122