Fix a typo in rest/membership.rst.
[mailman.git] / src / mailman / interfaces / user.py
blobabf3f82f3cbd78102b6796d2d6685036db347a5b
1 # Copyright (C) 2007-2023 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
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.
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.
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/>.
18 """Interface describing the basics of a user."""
20 from mailman.interfaces.address import AddressError
21 from public import public
22 from zope.interface import Attribute, Interface
25 @public
26 class UnverifiedAddressError(AddressError):
27 """Unverified address cannot be used as a user's preferred address."""
30 @public
31 class PasswordChangeEvent:
32 """Event which gets triggered when a user changes their password."""
34 def __init__(self, user):
35 self.user = user
37 def __str__(self):
38 return '<{} {}>'.format(
39 self.__class__.__name__, self.user.display_name)
42 @public
43 class IUser(Interface):
44 """A basic user."""
46 display_name = Attribute(
47 """This user's display name.""")
49 password = Attribute(
50 """This user's password information.""")
52 user_id = Attribute(
53 """The user's unique, random identifier as a UUID.""")
55 created_on = Attribute(
56 """The date and time at which this user was created.""")
58 addresses = Attribute(
59 """An iterator over all the `IAddresses` controlled by this user.""")
61 preferred_address = Attribute(
62 """The user's preferred `IAddress`. This must be validated.""")
64 memberships = Attribute(
65 """A roster of this user's memberships.""")
67 is_server_owner = Attribute(
68 """Boolean flag indicating whether the user is a server owner.""")
70 def register(email, display_name=None):
71 """Register the given email address and link it to this user.
73 :param email: The text email address to register.
74 :type email: str
75 :param display_name: The user's display name. If not given the empty
76 string is used.
77 :type display_name: str
78 :return: The address object linked to the user. If the associated
79 address object already existed (unlinked to a user) then the
80 `display_name` parameter is ignored.
81 :rtype: `IAddress`
82 :raises AddressAlreadyLinkedError: if this `IAddress` is already
83 linked to another user.
84 """
86 def link(address):
87 """Link this user to the given IAddress.
89 Raises AddressAlreadyLinkedError if this IAddress is already linked to
90 another user.
91 """
93 def unlink(address):
94 """Unlink this IAddress from the user.
96 Raises AddressNotLinkedError if this address is not linked to this
97 user, either because it's not linked to any user or it's linked to
98 some other user.
99 """
101 def controls(email):
102 """Determine whether this user controls the given email address.
104 :param email: The text email address to register.
105 :type email: str
106 :return: True if the user controls the given email address.
107 :rtype: bool
110 preferences = Attribute(
111 """This user's preferences.""")
113 def absorb(user):
114 """Merge the given user to ourself.
116 All IAddresses linked to `user` are relinked to ourself. A
117 memberships associated with `user` are changed to be memberships
118 with ourself. See `IPreferences.absorb()`.
120 The user's `display_name`, `password`, and `is_server_owner` settings
121 are absorbed into ours, but only if ours is unset and the given user's
122 values are set.
124 After being absorbed, the given user and its preferences are
125 deleted.
127 It is not an error if `user` is ourself, but it is a no-op.
129 :param user: The user to merge into ourself.
130 :type user: IUser
131 :raises TypeError: if `user` is not a user.