~abompard/mailman/subpolicy

« back to all changes in this revision

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

  • Committer: Barry Warsaw
  • Date: 2015-04-07 02:06:28 UTC
  • mfrom: (7313.2.6 lp1423756)
  • mto: This revision was merged to the branch mainline in revision 7323.
  • Revision ID: barry@list.org-20150407020628-fkwphij7to9lc8gy
 * Domains now have a list of owners, which are ``IUser`` objects, instead of
   the single ``contact_address`` they used to have.  ``IUser`` objects now
   also have a ``is_server_owner`` flag (defaulting to False) to indicate
   whether they have superuser privileges.  Give by Abhliash Raj, with fixes
   and refinements by Barry Warsaw.  (LP: #1423756)

 * Domains can now optionally be created with owners; domain owners can be
   added after the fact; domain owners can be deleted.  Also, users now have
   an ``is_server_owner`` flag as part of their representation, which defaults
   to False, and can be PUT and PATCH'd.  Given by Abhilash Raj, with fixes
   and refinements by Barry Warsaw.  (LP: #1423756)

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
from mailman.interfaces.domain import (
29
29
    BadDomainSpecificationError, DomainCreatedEvent, DomainCreatingEvent,
30
30
    DomainDeletedEvent, DomainDeletingEvent, IDomain, IDomainManager)
 
31
from mailman.interfaces.user import IUser
 
32
from mailman.interfaces.usermanager import IUserManager
31
33
from mailman.model.mailinglist import MailingList
32
34
from urllib.parse import urljoin, urlparse
33
35
from sqlalchemy import Column, Integer, Unicode
 
36
from sqlalchemy.orm import relationship
34
37
from zope.event import notify
35
38
from zope.interface import implementer
 
39
from zope.component import getUtility
36
40
 
37
41
 
38
42
 
44
48
 
45
49
    id = Column(Integer, primary_key=True)
46
50
 
47
 
    mail_host = Column(Unicode) # TODO: add index?
 
51
    mail_host = Column(Unicode)
48
52
    base_url = Column(Unicode)
49
53
    description = Column(Unicode)
50
 
    contact_address = Column(Unicode)
 
54
    owners = relationship('User',
 
55
                          secondary='domain_owner',
 
56
                          backref='domains')
51
57
 
52
58
    def __init__(self, mail_host,
53
59
                 description=None,
54
60
                 base_url=None,
55
 
                 contact_address=None):
 
61
                 owners=None):
56
62
        """Create and register a domain.
57
63
 
58
64
        :param mail_host: The host name for the email interface.
63
69
            scheme.  If not given, it will be constructed from the
64
70
            `mail_host` using the http protocol.
65
71
        :type base_url: string
66
 
        :param contact_address: The email address to contact a human for this
67
 
            domain.  If not given, postmaster@`mail_host` will be used.
68
 
        :type contact_address: string
 
72
        :param owners: Optional owners of this domain.
 
73
        :type owners: sequence of `IUser` or string emails.
69
74
        """
70
75
        self.mail_host = mail_host
71
76
        self.base_url = (base_url
72
77
                         if base_url is not None
73
78
                         else 'http://' + mail_host)
74
79
        self.description = description
75
 
        self.contact_address = (contact_address
76
 
                                if contact_address is not None
77
 
                                else 'postmaster@' + mail_host)
 
80
        if owners is not None:
 
81
            self.add_owners(owners)
78
82
 
79
83
    @property
80
84
    def url_host(self):
103
107
    def __repr__(self):
104
108
        """repr(a_domain)"""
105
109
        if self.description is None:
106
 
            return ('<Domain {0.mail_host}, base_url: {0.base_url}, '
107
 
                    'contact_address: {0.contact_address}>').format(self)
 
110
            return ('<Domain {0.mail_host}, base_url: {0.base_url}>').format(
 
111
                self)
108
112
        else:
109
113
            return ('<Domain {0.mail_host}, {0.description}, '
110
 
                    'base_url: {0.base_url}, '
111
 
                    'contact_address: {0.contact_address}>').format(self)
 
114
                    'base_url: {0.base_url}>').format(self)
 
115
 
 
116
    def add_owner(self, owner):
 
117
        """See `IDomain`."""
 
118
        user_manager = getUtility(IUserManager)
 
119
        if IUser.providedBy(owner):
 
120
            user = owner
 
121
        else:
 
122
            user = user_manager.get_user(owner)
 
123
        # BAW 2015-04-06: Make sure this path is tested.
 
124
        if user is None:
 
125
            user = user_manager.create_user(owner)
 
126
        self.owners.append(user)
 
127
 
 
128
    def add_owners(self, owners):
 
129
        """See `IDomain`."""
 
130
        # BAW 2015-04-06: This should probably be more efficient by inlining
 
131
        # add_owner().
 
132
        for owner in owners:
 
133
            self.add_owner(owner)
 
134
 
 
135
    def remove_owner(self, owner):
 
136
        """See `IDomain`."""
 
137
        user_manager = getUtility(IUserManager)
 
138
        self.owners.remove(user_manager.get_user(owner))
112
139
 
113
140
 
114
141
 
121
148
            mail_host,
122
149
            description=None,
123
150
            base_url=None,
124
 
            contact_address=None):
 
151
            owners=None):
125
152
        """See `IDomainManager`."""
126
153
        # Be sure the mail_host is not already registered.  This is probably
127
154
        # a constraint that should (also) be maintained in the database.
129
156
            raise BadDomainSpecificationError(
130
157
                'Duplicate email host: %s' % mail_host)
131
158
        notify(DomainCreatingEvent(mail_host))
132
 
        domain = Domain(mail_host, description, base_url, contact_address)
 
159
        domain = Domain(mail_host, description, base_url, owners)
133
160
        store.add(domain)
134
161
        notify(DomainCreatedEvent(domain))
135
162
        return domain