1 # -*- coding: utf-8 -*-
2 # Copyright (C) 1998-2022 by the Free Software Foundation, Inc.
4 # This file is part of Postorius.
6 # Postorius is free software: you can redistribute it and/or modify it under
7 # the terms of the GNU General Public License as published by the Free
8 # Software Foundation, either version 3 of the License, or (at your option)
11 # Postorius is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 # You should have received a copy of the GNU General Public License along with
17 # Postorius. If not, see <http://www.gnu.org/licenses/>.
20 Authentication and authorization-related utilities.
23 from allauth
.account
.models
import EmailAddress
25 from postorius
.models
import Domain
, List
28 ALL_ROSTER
= ['owner', 'moderator', 'member', 'nomember']
31 def user_is_in_list_roster(user
, mailing_list
, roster
):
32 """Checks if a user is in a MailingList roster.
34 :param user: User to check access permissions for.
35 :type user: django.contrib.auth.model.User
36 :param mailing_list: MailingList to check permissions for.
37 :type mailing_list: postorius.models.List
38 :param roster: Access permissions required.
41 if not user
.is_authenticated
:
43 addresses
= set(email
.lower() for email
in
44 EmailAddress
.objects
.filter(
45 user
=user
, verified
=True).values_list(
47 if roster
not in ALL_ROSTER
:
48 raise ValueError(f
'{roster} is a valid List Roster.')
50 roster_addresses
= set(
52 for member
in mailing_list
.get_roster(roster
, fields
=['email'])])
53 if addresses
& roster_addresses
:
54 return True # At least one address is in the roster
58 def set_list_access_props(user
, mlist
, owner
=True, moderator
=True):
59 """Update user's access permissions of a MailingList.
61 :param user: The user to check permissions for.
62 :type user: django.contrib.auth.model.User
63 :param mlist: MailingList to check permissions for.
64 :type mlist: postorius.models.List
65 :param owner: Set is_list_owner.
67 :param moderator: Set is_list_moderator.
70 # If given a mailinglist id, get the List object instead.
71 if isinstance(mlist
, str):
72 mlist
= List
.objects
.get_or_404(mlist
)
73 # If not already set, check if the user is in list ownership roster.
74 if (not hasattr(user
, 'is_list_owner')) and owner
:
75 user
.is_list_owner
= user_is_in_list_roster(user
, mlist
, 'owner')
76 # If not already set, check if the user is in list moderator roster.
77 if not hasattr(user
, 'is_list_moderator') and moderator
:
78 user
.is_list_moderator
= user_is_in_list_roster(
79 user
, mlist
, 'moderator')
82 def set_domain_access_props(user
, domain
):
83 """Update user's access permissions for a domain.
85 :param user: The user to check permissions for.
86 :type user: django.contrib.auth.model.User
87 :param domain: Domain to check permissions for.
88 :type domain: postorius.models.Domain
90 # TODO: This is very slow as it involves first iterating over every domain
91 # owner and then each of their addresses. Create an API in Core to
93 if isinstance(domain
, str):
94 domain
= Domain
.objects
.get_or_404(domain
)
96 for owner
in domain
.owners
:
97 owner_addresses
.extend(owner
.addresses
)
98 owner_addresses
= set([each
.email
for each
in owner_addresses
])
99 user_addresses
= set(EmailAddress
.objects
.filter(
100 user
=user
, verified
=True).values_list("email", flat
=True))
101 user
.is_domain_owner
= owner_addresses
& user_addresses