Coverage for src/couchers/tasks.py: 100%
58 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-11-21 04:21 +0000
« prev ^ index » next coverage.py v7.5.0, created at 2024-11-21 04:21 +0000
1import logging
3from sqlalchemy.sql import func
5from couchers import email, urls
6from couchers.config import config
7from couchers.constants import SIGNUP_EMAIL_TOKEN_VALIDITY
8from couchers.crypto import urlsafe_secure_token
9from couchers.db import session_scope
10from couchers.models import (
11 Cluster,
12 ClusterRole,
13 ClusterSubscription,
14 EventCommunityInviteRequest,
15 Node,
16 User,
17)
18from couchers.sql import couchers_select as select
19from couchers.templates.v2 import send_simple_pretty_email
20from couchers.utils import now
22logger = logging.getLogger(__name__)
25def send_signup_email(session, flow):
26 logger.info(f"Sending signup email to {flow.email=}:")
28 # whether we've sent an email at all yet
29 email_sent_before = flow.email_sent
30 if flow.email_verified:
31 # we just send a link to continue, not a verification link
32 signup_link = urls.signup_link(token=flow.flow_token)
33 elif flow.email_token and flow.token_is_valid:
34 # if the verification email was sent and still is not expired, just resend the verification email
35 signup_link = urls.signup_link(token=flow.email_token)
36 else:
37 # otherwise send a fresh email with new token
38 token = urlsafe_secure_token()
39 flow.email_verified = False
40 flow.email_token = token
41 flow.email_token_expiry = now() + SIGNUP_EMAIL_TOKEN_VALIDITY
42 signup_link = urls.signup_link(token=flow.email_token)
44 flow.email_sent = True
46 send_simple_pretty_email(
47 session,
48 flow.email,
49 "Finish signing up for Couchers.org",
50 "signup_verify" if not email_sent_before else "signup_continue",
51 template_args={"flow": flow, "signup_link": signup_link},
52 )
55def send_email_changed_confirmation_to_new_email(session, user):
56 """
57 Send an email to user's new email address requesting confirmation of email change
58 """
59 logger.info(
60 f"Sending email changed (confirmation) email to {user=}'s new email address, (old email: {user.email}, new email: {user.new_email=})"
61 )
63 confirmation_link = urls.change_email_link(confirmation_token=user.new_email_token)
64 send_simple_pretty_email(
65 session,
66 user.new_email,
67 "Confirm your new email for Couchers.org",
68 "email_changed_confirmation_new_email",
69 template_args={"user": user, "confirmation_link": confirmation_link},
70 )
73def send_content_report_email(session, content_report):
74 logger.info("Sending content report email")
75 email.enqueue_system_email(
76 session,
77 config["REPORTS_EMAIL_RECIPIENT"],
78 "content_report",
79 template_args={
80 "report": content_report,
81 "author_user_user_link": urls.user_link(username=content_report.author_user.username),
82 "reporting_user_user_link": urls.user_link(username=content_report.reporting_user.username),
83 },
84 )
87def maybe_send_reference_report_email(session, reference):
88 if reference.should_report:
89 logger.info("Sending reference report email")
90 email.enqueue_system_email(
91 session,
92 config["REPORTS_EMAIL_RECIPIENT"],
93 "reference_report",
94 template_args={
95 "reference": reference,
96 "from_user_user_link": urls.user_link(username=reference.from_user.username),
97 "to_user_user_link": urls.user_link(username=reference.to_user.username),
98 },
99 )
102def maybe_send_contributor_form_email(session, form):
103 if form.should_notify:
104 email.enqueue_system_email(
105 session,
106 config["CONTRIBUTOR_FORM_EMAIL_RECIPIENT"],
107 "contributor_form",
108 template_args={"form": form, "user_link": urls.user_link(username=form.user.username)},
109 )
112def send_event_community_invite_request_email(session, request: EventCommunityInviteRequest):
113 email.enqueue_system_email(
114 session,
115 config["MODS_EMAIL_RECIPIENT"],
116 "event_community_invite_request",
117 template_args={
118 "event_link": urls.event_link(occurrence_id=request.occurrence.id, slug=request.occurrence.event.slug),
119 "user_link": urls.user_link(username=request.user.username),
120 "view_link": urls.console_link(page="api/org.couchers.admin.Admin"),
121 },
122 )
125def send_account_deletion_report_email(session, reason):
126 logger.info("Sending account deletion report email")
127 email.enqueue_system_email(
128 session,
129 config["REPORTS_EMAIL_RECIPIENT"],
130 "account_deletion_report",
131 template_args={
132 "reason": reason,
133 },
134 )
137def enforce_community_memberships():
138 """
139 Go through all communities and make sure every user in the polygon is also a member
140 """
141 with session_scope() as session:
142 for node in session.execute(select(Node)).scalars().all():
143 existing_users = select(ClusterSubscription.user_id).where(
144 ClusterSubscription.cluster == node.official_cluster
145 )
146 users_needing_adding = (
147 session.execute(
148 select(User)
149 .where(User.is_visible)
150 .where(func.ST_Contains(node.geom, User.geom))
151 .where(~User.id.in_(existing_users))
152 )
153 .scalars()
154 .all()
155 )
156 for user in users_needing_adding:
157 node.official_cluster.cluster_subscriptions.append(
158 ClusterSubscription(
159 user=user,
160 role=ClusterRole.member,
161 )
162 )
163 session.commit()
166def enforce_community_memberships_for_user(session, user):
167 """
168 Adds a given user to all the communities they belong in based on their location.
169 """
170 cluster_ids = (
171 session.execute(
172 select(Cluster.id)
173 .join(Node, Node.id == Cluster.parent_node_id)
174 .where(Cluster.is_official_cluster)
175 .where(func.ST_Contains(Node.geom, user.geom))
176 )
177 .scalars()
178 .all()
179 )
181 for cluster_id in cluster_ids:
182 session.add(
183 ClusterSubscription(
184 user=user,
185 cluster_id=cluster_id,
186 role=ClusterRole.member,
187 )
188 )
189 session.commit()